From fac4274803b97c7caf20ac474cbd21c47142b3fb Mon Sep 17 00:00:00 2001 From: Sora Suegami <31360991+SoraSuegami@users.noreply.github.com> Date: Sun, 3 Nov 2024 09:46:25 +0900 Subject: [PATCH] feat: Body Parsing With Audit Fixes (#59) * feat: email_auth body parsing circuit working with tests * fix: minor test changes * chore: update dependencies * (wip) chore: pass github workflow * Add a verifier contract * Update proving key url * feat: add body parsing * chore: update * chore: separated body parsing tests * fix: refactring in recipent_enabled test * fix: minor * chore: update relayer * fix: updated command regex * chore: changed max_command_bytes to 605 * Update verifier * feat: sha precompute test * chore: update relayer utils version * feat: command update + relayer changes * Fix circuit name in core.py * chore: update version * chore: update circuit test * chore: update relayer-uitls dep * Update verifier * Change the max header/body sizes in the body-parsing circuits. * Add test circuits for body parsing * Update verifier * Fixing integration test * Update emails for integration tests * Update yarn.lock * Fix scripts and email for integration test * chore: update circuit test * Integration test worked * fix: body parsing test * feat: complete flow * Replace subject with command. * Fix compile errors in relayer * Remove skipped_command_bytes * Merge audit-fix into body-parsing * Add IGroth16Verifier * Recover skipped_commad_bytes * Apply audit-fixes to the body-parsing circuit. * Fix relayer * Disable auto script tests in contracts * Update verifier and proving key * Feat/fix zksync impl (#60) * Fix yarn zkbuild * Fix yarn zktest * Fix integration test except for eml files * comment out specific zksync lines * Update test emails for zksync * Update integration test for zksync * Update bytecode hash * Update proof.json path * Update publicInputFile path * Update bytecode hash * Update docs for integration tests for zksync * Update package.json in contracts * Let functions in EmailAccountRecoveryZKSync be virtual * fix: subject template parsing * Add requestGuardian to SimpleWallet * Fix scripts * Fix scripts * Update READMEs * Fix circuit package.json * Fix typo and remove unnecessary file * Remove space from invitation code * chore: refactor * WIP: Add custom errors * Update .env.example * Split up handle_email fn; Remove code duplication * Custom errors for email * Rebase solve conflicts of body-parser refacor * Rebase solve conflicts of body-parser refacor * Rebase fixes * Acknowledgement as replies in email thread * Add Re: to subject for reply emails * Update email templates UI * Add cloud build to build on gcp * Bump relayer version * fix: add command in email templates * feat: add CONTRIBUTING.md & CODING_GUIDELINES.md * chore: move md files * feat: add github workflows * chore: remove abis * chore: update github actions and add PR template * fix: github action * Remove hard-coded file_paths; Fix clippy warnings * Move util files from ether-email-auth to utils repo * Fix relayer-utils version to refactor commit * Force db initialization on startup * AI generated doc comments * Prevent duplicates by checking if it is a valid reply * Add AI generated comments * Rename func to extract_template_vals_from_command * Exclude abi folder as workspace member * Ignore abis for fmt * Add github actions to build docker image * ui: Update email template UI - powered by zk email is odd that theyre different sizes - the social icons at the bottom look squished - Update the email template from The Zk team Aayush to The ZK Email Team - Check vertical padding in the mail * feat: GPU prover (#66) * feat: use GPU for proving * chore: update Dockerfile * chore: cleanup * chore: update params.zip * chore: update circom_proofgen.sh * chore: update * fix: regex json path * chore: update k8s manifest * feat: use GPU for proving * chore: add comment in example env * feat: keep modal warm * ui: update email template design * chore: cleanup * chore: update dockerignore * chore: update dockerignore * chore: update k8s manifest * Add an invalid utf8 test email * Update circom_tester * Fix circom version * Fix circom version * Make test cases as a function named files * Add test cases for DKIM registries * Add test cases for EmailAccountRecovery * Add general test cases * Update proxy bytecode hash * Add more events * Fix circom version to 2.1.9 in github action * audit fixes * Fix email_auth_with_recipient * Add send_email.py for test * Add upgrade test * Update circom tests * Fix recipient test * Fix circom import in email_auth.circom * Fix arg name in removePrefix * Update dependencies * Fix interfaces to call EmailVerifier. * Change the regex of forced_subject * change the positon dependency in forced_subject * Add "ZK" to the relayer's email subjects * Fix force_subject regex error * Integration test on base worked. * update version * Update integration test emails * Fix zksync intergation test * Not hardcode proxyBytecodeHash in EmailAccountRecoveryZKSync * Update prover * Update README and call args for RecoveryControllerZKSync * Change forced_subject to accept "Re: " * Update zk-email circuits/contracts versions * Add RequestGuardianSimpleWallet script * add test_forced_subject_regex * Update test emails for integration tests * Remove console from EmailAuth * remove console.log * Use PROXY_BYTECODE_HASH in .env * Use default bytes32 value if PROXY_BYTECODE_HASH is not set * if PROXY_BYTECODE_HASH it not set the script will revert * Update verifier * Update versions * relayer update * Update prover with gpus * Update prover * chore: node version >=18 * chore: prover * Revert "Update prover" This reverts commit 9b3e29c0003f0ab61737ee01b803281227ec21cc. * Revert "Update prover with gpus" This reverts commit b00f205a7b89086c0606259c6cb48959920a8a5e. * Update prover version * chore: change gpu * Update dkim registries * Update integration test * Update scripts to use useroverriable registry * E2E test with user overridable dkim registry worked. * Remove DeployCommonScript * Fix integration test for foundry * Fix IntegrationZKSync * Update dependency * Update yarn.lock * chore: update * chore: update version & Cargo.lock * Remove ForwardDKIMRegistry and Add scripts for UseroverridableDKIMRegistry * Fix relayer * Remove ForwardDKIMRegistry.sol * Update yarn.lock * Update yarn.lock * Fix clippy bug * Fix integration test for zksync era-test-node * Remove code which relates to ForwardDKIMRegistry * Abstract Verifier as IVerifier * Update test signature for test_Dfinity_Oracle_Response * Fix script test errors * chore: update * Update circuit depndencies * chore: update version * downgrade typescript * Format * Remove setEnv from DeployRecoveryController * Specify commits in zk-email-verify * Update version * Remove testRequestGuardianNotOwner and add verifier test case for upgrading * Fix test_Revert_IfSignatureIsInvalid * Update zk-email/contracts repo hash * Update zk-regex and circuit tests * update zk-email/circuit and contract * Update verifier and integration tests * Update prover * Use wasm&cpu for the prover temporarily. * Fix chain.rs for updates of Useroverridable dkim registry * Fix the forced subject * Update versions * Add gas limit param (#75) * Send cycles to call the dkim canister function * remove warning * fix warning * Add string utils to ether-email-auth (#76) * Add string utils to ether-email-auth * Install solidity string utils * Feat/audit fix 2024 09 gpus (#77) * update prover * Fix prover * update local_setup.sh * Update circom_proofgen.sh * Disable logger temporary * Fix dockerfile and scripts * Update zk-email/contracts * Fix script * Feat/deploy via oz defender (#73) * forge install: openzeppelin-foundry-upgrades v0.3.6 * forge install: openzeppelin-contracts-upgradeable v5.1.0 * Test OZ Defender WIP * Add package.json * Add unsafeSkipAllChecks * Remove @openzeppelin/upgrades-core * remove OZ upgradeable submodule * Finish updating scripts * Clean up * Remove vm.setEnv from script * Remove use of setEnv in deployment script --------- Co-authored-by: wshino Co-authored-by: SoraSuegami * update version * Use the address from deployerPrivateKey if no initialOwner is provided. * Fix BaseDeployScript * Update integration test * Feat/improve alerts (#72) * Send mail if contract call failed * Apply cargo fmt * Add logic to mail a user error email to system user's address * Revert send_email function to private * Add more info for error in recover function * Add PROVER_ADDRESS to yaml files for kubernetes * Fix env name * Add env * Remove duplicate tr * Apply cargo fmt * Fix cargo clippy warnings * Add metrics and alerts as file * Add support section (#78) * Feat/add emergency docs (#71) * Add doc for emergency * Rename emergency.md -> upgrade.md * Feat/e2e zksync (#79) * Update missing libraries in README.md and remove defender import * Remove OZ Defender dependencies * remove console in StringUtils * Import StringUtils in CommandUtils * Feat/fix zksync commands (#80) * Update testcases which uses era-test-node * Fix LLVM problems * Update foundry.toml * Update zkbuild and zktest commands * Update README.md * Add install era-test-node in README.md * Export a circuit with body parsing and the recipient feature. * Push the missing circuit * Add one more circuit test * Separate tests for the recipient --------- Co-authored-by: shreyas-londhe Co-authored-by: Aditya Bisht Co-authored-by: Aditya Bisht <44467788+Bisht13@users.noreply.github.com> Co-authored-by: wshino Co-authored-by: Yush G Co-authored-by: Dimitri Co-authored-by: Shubham Gupta Co-authored-by: John Guilding <54913924+JohnGuilding@users.noreply.github.com> --- .dockerignore | 1 + .github/pull_request_template.md | 28 + .github/workflows/build-fmt.yml | 64 + .github/workflows/build-img.yml | 51 + .github/workflows/build-test-fmt.yml | 55 - .github/workflows/unit-tests.yml | 42 +- .gitignore | 8 + Cargo.lock | 1510 ++++---- Cargo.toml | 2 +- Full.Dockerfile | 66 + README.md | 66 +- Relayer.Dockerfile | 4 +- docs/upgrade.md | 43 + infrastructure/README.md | 42 + ...e_Check_for_AR_Relayer_(Base_Sepolia).json | 46 + ...Check_for_AR_Relayer_(ZKsync_Sepolia).json | 46 + ...Uptime_Check_for_Email_Wallet_Relayer.json | 46 + infrastructure/alerts/apply_alert.sh | 29 + .../logging_user_error-from-prover_[SUM].json | 40 + ...user_error-handling-email-event_[SUM].json | 41 + ...gging_user_error-handling-email_[SUM].json | 41 + infrastructure/metrics/apply_metric.sh | 35 + .../contract-call-reverted-with-data.json | 16 + infrastructure/metrics/error-from-prover.json | 14 + .../metrics/error-handling-email-event.json | 14 + .../metrics/error-handling-email.json | 14 + kubernetes/cloudbuild-base.yml | 19 + kubernetes/cloudbuild-relayer.yml | 21 + kubernetes/cronjob.yml | 51 + kubernetes/relayer.staging.yml | 163 + kubernetes/relayer.yml | 49 +- libs/rapidsnark.Dockerfile | 22 - package.json | 4 +- packages/circuits/README.md | 12 +- packages/circuits/helpers/email_auth.ts | 48 +- packages/circuits/helpers/recipient.ts | 20 +- packages/circuits/package.json | 30 +- packages/circuits/scripts/dev-setup.ts | 44 +- packages/circuits/scripts/gen_input.ts | 53 +- packages/circuits/scripts/verify_proofs.ts | 69 - packages/circuits/src/email_auth.circom | 2 +- .../circuits/src/email_auth_legacy.circom | 5 + .../src/email_auth_legacy_template.circom | 206 + .../circuits/src/email_auth_template.circom | 147 +- .../src/email_auth_with_body_parsing.circom | 5 + ..._with_body_parsing_with_qp_encoding.circom | 5 + .../src/email_auth_with_recipient.circom | 5 + packages/circuits/src/regexes/command.json | 16 + .../circuits/src/regexes/command_regex.circom | 1366 +++++++ .../circuits/src/regexes/forced_subject.json | 8 + .../src/regexes/forced_subject_regex.circom | 656 ++++ .../circuits/src/regexes/invitation_code.json | 2 +- .../src/regexes/invitation_code_regex.circom | 89 +- .../regexes/invitation_code_with_prefix.json | 2 +- .../invitation_code_with_prefix_regex.circom | 112 +- packages/circuits/src/utils/bytes2ints.circom | 1 + packages/circuits/src/utils/constants.circom | 1 - .../circuits/email_auth_with_recipient.circom | 4 +- .../tests/circuits/test_email_auth.circom | 5 + .../test_email_auth_with_recipient.circom | 5 + .../circuits/test_forced_subject_regex.circom | 5 + .../tests/emai_auth_legacy_recipient.test.ts | 377 ++ .../tests/emai_auth_recipient.test.ts | 209 + packages/circuits/tests/email_auth.test.ts | 999 +++-- .../circuits/tests/email_auth_legacy.test.ts | 536 +++ .../tests/emails/email_auth_invalid_test1.eml | 98 + .../email_auth_legacy_invalid_test1.eml | 87 + .../email_auth_legacy_invalid_test2.eml | 83 + .../tests/emails/email_auth_legacy_test1.eml | 85 + .../tests/emails/email_auth_legacy_test2.eml | 85 + .../tests/emails/email_auth_legacy_test3.eml | 85 + .../tests/emails/email_auth_legacy_test4.eml | 85 + .../tests/emails/email_auth_legacy_test5.eml | 87 + .../tests/emails/email_auth_legacy_test6.eml | 88 + .../tests/emails/email_auth_test1.eml | 159 +- .../tests/emails/email_auth_test2.eml | 159 +- .../tests/emails/email_auth_test3.eml | 159 +- .../tests/emails/email_auth_test4.eml | 159 +- .../tests/emails/email_auth_test5.eml | 159 +- .../tests/emails/email_auth_test6.eml | 160 +- .../tests/emails/email_auth_test7.eml | 159 +- .../tests/forced_subject_regex.test.ts | 216 ++ .../tests/invitation_code_regex.test.ts | 336 +- .../circuits/tests/recipient_enabled.test.ts | 292 -- packages/circuits/tests/script/send_email.py | 53 + packages/contracts/.env.example | 23 + packages/contracts/.env.sample | 15 - .../missing_library_dependencies.json | 14 + packages/contracts/README.md | 270 +- packages/contracts/foundry.toml | 19 +- packages/contracts/package.json | 29 +- packages/contracts/remappings.txt | 4 +- .../contracts/script/BaseDeployScript.sol | 196 + packages/contracts/script/ChangeOwners.s.sol | 3 - .../ChangeSourceInForwardDKIMRegistry.s.sol | 30 - packages/contracts/script/DeployCommons.s.sol | 116 - .../DeployEmailAuthWithCreate2ZKSync.s.sol | 30 +- .../script/DeployForwardDKIMRegistry.s.sol | 49 - .../script/DeployRecoveryController.s.sol | 173 +- .../DeployRecoveryControllerZKSync.s.sol | 177 +- .../contracts/script/DeploySimpleWallet.s.sol | 53 +- ...ctivateDKIMPublicKeyHashSimpleWallet.s.sol | 68 + .../contracts/script/RenounceOwners.s.sol | 1 - .../script/RequestGuardianSimpleWallet.sol | 56 + .../RevokeDKIMPublicKeyHashSimpleWallet.s.sol | 68 + .../SetDKIMPublicKeyHashSimpleWallet.s.sol | 68 + packages/contracts/script/Upgrades.s.sol | 72 +- .../contracts/src/EmailAccountRecovery.sol | 95 +- .../src/EmailAccountRecoveryZKSync.sol | 59 +- packages/contracts/src/EmailAuth.sol | 143 +- .../src/interfaces/IGroth16Verifier.sol | 11 + .../contracts/src/interfaces/IVerifier.sol | 21 + .../{SubjectUtils.sol => CommandUtils.sol} | 39 +- .../contracts/src/libraries/StringUtils.sol | 73 + .../src/utils/ECDSAOwnedDKIMRegistry.sol | 12 +- .../src/utils/ForwardDKIMRegistry.sol | 80 - .../contracts/src/utils/Groth16Verifier.sol | 680 ++-- packages/contracts/src/utils/Verifier.sol | 58 +- .../src/utils/ZKSyncCreate2Factory.sol | 4 +- .../contracts/test/DKIMRegistryUpgrade.t.sol | 40 +- ...tRecovery_acceptanceSubjectTemplates.t.sol | 8 +- ...mailAccountRecovery_completeRecovery.t.sol | 14 +- .../EmailAccountRecovery_general.t.sol | 19 + ...mailAccountRecovery_handleAcceptance.t.sol | 258 +- .../EmailAccountRecovery_handleRecovery.t.sol | 201 +- ...untRecovery_recoverySubjectTemplates.t.sol | 10 +- .../EmailAccountRecovery_rejectRecovery.t.sol | 22 +- ...EmailAccountRecovery_requestGuardian.t.sol | 81 +- ...countRecoveryZKSync_completeRecovery.t.sol | 72 +- ...countRecoveryZKSync_handleAcceptance.t.sol | 36 +- ...AccountRecoveryZKSync_handleRecovery.t.sol | 76 +- ...AccountRecoveryZKSync_rejectRecovery.t.sol | 18 +- ...ccountRecoveryZKSync_requestGuardian.t.sol | 18 - .../EmailAccountRecoveryZKSync_transfer.t.sol | 12 +- .../EmailAccountRecoveryZKSync_withdraw.t.sol | 6 +- ...ryZkSync_acceptanceCommandTemplates.t.sol} | 8 +- ...veryZkSync_recoveryCommandTemplates.t.sol} | 12 +- packages/contracts/test/EmailAuth.t.sol | 243 +- .../EmailAuthWithUserOverrideableDkim.t.sol | 139 +- packages/contracts/test/Integration.t.sol | 101 +- .../contracts/test/IntegrationZKSync.t.sol | 113 +- packages/contracts/test/emails/300/accept.eml | 177 +- .../contracts/test/emails/300/recovery.eml | 177 +- .../contracts/test/emails/8453/accept.eml | 177 +- .../contracts/test/emails/8453/recovery.eml | 176 +- .../test/helpers/DeploymentHelper.sol | 71 +- .../test/helpers/RecoveryController.sol | 40 +- .../test/helpers/RecoveryControllerZKSync.sol | 43 +- .../contracts/test/helpers/SimpleWallet.sol | 26 +- .../contracts/test/helpers/StructHelper.sol | 12 +- .../StringUtils/StringUtils_hexToBytes.t.sol | 246 ++ .../StringUtils_hexToBytes32.t.sol | 252 ++ .../fuzz/StringUtils_fuzz_hexToBytes.t.sol | 72 + .../fuzz/StringUtils_fuzz_hexToBytes32.t.sol | 48 + ...eOwners.t.sol => ChangeOwnersScript.t.sol} | 33 +- ...ChangeSignerInECDSAOwnedDKIMRegistry.t.sol | 35 - ...SignerInECDSAOwnedDKIMRegistryScript.t.sol | 56 + .../ChangeSourceInForwardDKIMRegistry.t.sol | 40 - .../contracts/test/script/DeployCommons.t.sol | 28 - .../script/DeployRecoveryController.t.sol | 54 - .../DeployRecoveryControllerScript.t.sol | 67 + ...t.t.sol => DeploySimpleWalletScript.t.sol} | 39 +- .../test/script/RenounceOwners.t.sol | 39 - .../test/script/RenounceOwnersScript.t.sol | 59 + packages/contracts/test/script/Upgrades.t.sol | 73 - .../ECDSAOwnedDKIMRegistry/changeSigner.t.sol | 48 + .../computeSignedMsg.t.sol | 46 + .../isDKIMPublicKeyHashValid.t.sol | 103 + .../revokeDKIMPublicKeyHash.t.sol | 335 ++ .../setDKIMPublicKeyHash.t.sol} | 167 +- packages/contracts/test/utils/Verifier.t.sol | 45 + packages/prover/Dockerfile | 83 +- packages/prover/circom_proofgen.sh | 26 +- packages/prover/core.py | 5 + packages/prover/local_setup.sh | 27 +- packages/prover/modal_server.py | 7 +- packages/relayer/.env.example | 17 +- packages/relayer/CODING_GUIDELINES.md | 98 + packages/relayer/CONTRIBUTING.md | 116 + packages/relayer/Cargo.toml | 15 +- packages/relayer/README.md | 5 +- packages/relayer/build.rs | 15 +- .../eml_templates/acceptance_request.html | 615 ++- .../eml_templates/acceptance_success.html | 604 ++- .../eml_templates/acknowledgement.html | 601 ++- .../eml_templates/credential_not_present.html | 611 ++- packages/relayer/eml_templates/error.html | 604 ++- .../eml_templates/error_for_admin.html | 264 ++ .../guardian_already_exists.html | 605 ++- .../eml_templates/guardian_not_set.html | 601 ++- .../eml_templates/recovery_request.html | 612 ++- .../eml_templates/recovery_success.html | 604 ++- .../src/abis/ecdsa_owned_dkim_registry.rs | 2333 ----------- .../src/abis/email_account_recovery.rs | 1512 -------- packages/relayer/src/abis/email_auth.rs | 736 ++-- packages/relayer/src/abis/mod.rs | 11 +- .../abis/user_overridable_dkim_registry.rs | 3421 +++++++++++++++++ packages/relayer/src/chain.rs | 509 ++- packages/relayer/src/config.rs | 27 +- packages/relayer/src/core.rs | 870 +++-- packages/relayer/src/database.rs | 366 +- packages/relayer/src/lib.rs | 78 +- packages/relayer/src/modules/dkim.rs | 207 +- packages/relayer/src/modules/mail.rs | 325 +- packages/relayer/src/modules/mod.rs | 2 + .../relayer/src/modules/web_server/mod.rs | 4 + .../src/modules/web_server/relayer_errors.rs | 223 ++ .../src/modules/web_server/rest_api.rs | 805 ++-- .../relayer/src/modules/web_server/server.rs | 200 +- packages/relayer/src/{utils => }/strings.rs | 9 +- packages/relayer/src/utils/mod.rs | 7 - .../relayer/src/utils/subject_templates.rs | 236 -- packages/relayer/src/utils/utils.rs | 99 - rust-toolchain | 2 +- rustfmt.toml | 4 + yarn.lock | 1782 ++++----- 216 files changed, 22342 insertions(+), 15192 deletions(-) create mode 100644 .github/pull_request_template.md create mode 100644 .github/workflows/build-fmt.yml create mode 100644 .github/workflows/build-img.yml delete mode 100644 .github/workflows/build-test-fmt.yml create mode 100644 Full.Dockerfile create mode 100644 docs/upgrade.md create mode 100644 infrastructure/README.md create mode 100644 infrastructure/alerts/Uptime_Check_for_AR_Relayer_(Base_Sepolia).json create mode 100644 infrastructure/alerts/Uptime_Check_for_AR_Relayer_(ZKsync_Sepolia).json create mode 100644 infrastructure/alerts/Uptime_Check_for_Email_Wallet_Relayer.json create mode 100755 infrastructure/alerts/apply_alert.sh create mode 100644 infrastructure/alerts/logging_user_error-from-prover_[SUM].json create mode 100644 infrastructure/alerts/logging_user_error-handling-email-event_[SUM].json create mode 100644 infrastructure/alerts/logging_user_error-handling-email_[SUM].json create mode 100755 infrastructure/metrics/apply_metric.sh create mode 100644 infrastructure/metrics/contract-call-reverted-with-data.json create mode 100644 infrastructure/metrics/error-from-prover.json create mode 100644 infrastructure/metrics/error-handling-email-event.json create mode 100644 infrastructure/metrics/error-handling-email.json create mode 100644 kubernetes/cloudbuild-base.yml create mode 100644 kubernetes/cloudbuild-relayer.yml create mode 100644 kubernetes/cronjob.yml create mode 100644 kubernetes/relayer.staging.yml delete mode 100644 libs/rapidsnark.Dockerfile delete mode 100644 packages/circuits/scripts/verify_proofs.ts create mode 100644 packages/circuits/src/email_auth_legacy.circom create mode 100644 packages/circuits/src/email_auth_legacy_template.circom create mode 100644 packages/circuits/src/email_auth_with_body_parsing.circom create mode 100644 packages/circuits/src/email_auth_with_body_parsing_with_qp_encoding.circom create mode 100644 packages/circuits/src/email_auth_with_recipient.circom create mode 100644 packages/circuits/src/regexes/command.json create mode 100644 packages/circuits/src/regexes/command_regex.circom create mode 100644 packages/circuits/src/regexes/forced_subject.json create mode 100644 packages/circuits/src/regexes/forced_subject_regex.circom create mode 100644 packages/circuits/tests/circuits/test_email_auth.circom create mode 100644 packages/circuits/tests/circuits/test_email_auth_with_recipient.circom create mode 100644 packages/circuits/tests/circuits/test_forced_subject_regex.circom create mode 100644 packages/circuits/tests/emai_auth_legacy_recipient.test.ts create mode 100644 packages/circuits/tests/emai_auth_recipient.test.ts create mode 100644 packages/circuits/tests/email_auth_legacy.test.ts create mode 100644 packages/circuits/tests/emails/email_auth_invalid_test1.eml create mode 100644 packages/circuits/tests/emails/email_auth_legacy_invalid_test1.eml create mode 100644 packages/circuits/tests/emails/email_auth_legacy_invalid_test2.eml create mode 100644 packages/circuits/tests/emails/email_auth_legacy_test1.eml create mode 100644 packages/circuits/tests/emails/email_auth_legacy_test2.eml create mode 100644 packages/circuits/tests/emails/email_auth_legacy_test3.eml create mode 100644 packages/circuits/tests/emails/email_auth_legacy_test4.eml create mode 100644 packages/circuits/tests/emails/email_auth_legacy_test5.eml create mode 100644 packages/circuits/tests/emails/email_auth_legacy_test6.eml create mode 100644 packages/circuits/tests/forced_subject_regex.test.ts delete mode 100644 packages/circuits/tests/recipient_enabled.test.ts create mode 100644 packages/circuits/tests/script/send_email.py create mode 100644 packages/contracts/.env.example delete mode 100644 packages/contracts/.env.sample create mode 100644 packages/contracts/.zksolc-libraries-cache/missing_library_dependencies.json create mode 100644 packages/contracts/script/BaseDeployScript.sol delete mode 100644 packages/contracts/script/ChangeSourceInForwardDKIMRegistry.s.sol delete mode 100644 packages/contracts/script/DeployCommons.s.sol delete mode 100644 packages/contracts/script/DeployForwardDKIMRegistry.s.sol create mode 100644 packages/contracts/script/ReactivateDKIMPublicKeyHashSimpleWallet.s.sol create mode 100644 packages/contracts/script/RequestGuardianSimpleWallet.sol create mode 100644 packages/contracts/script/RevokeDKIMPublicKeyHashSimpleWallet.s.sol create mode 100644 packages/contracts/script/SetDKIMPublicKeyHashSimpleWallet.s.sol create mode 100644 packages/contracts/src/interfaces/IGroth16Verifier.sol create mode 100644 packages/contracts/src/interfaces/IVerifier.sol rename packages/contracts/src/libraries/{SubjectUtils.sol => CommandUtils.sol} (82%) create mode 100644 packages/contracts/src/libraries/StringUtils.sol delete mode 100644 packages/contracts/src/utils/ForwardDKIMRegistry.sol create mode 100644 packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_general.t.sol rename packages/contracts/test/EmailAccountRecoveryZkSync/{EmailAccountRecoveryZkSync_acceptanceSubjectTemplates.t.sol => EmailAccountRecoveryZkSync_acceptanceCommandTemplates.t.sol} (78%) rename packages/contracts/test/EmailAccountRecoveryZkSync/{EmailAccountRecoveryZkSync_recoverySubjectTemplates.t.sol => EmailAccountRecoveryZkSync_recoveryCommandTemplates.t.sol} (79%) create mode 100644 packages/contracts/test/libraries/StringUtils/StringUtils_hexToBytes.t.sol create mode 100644 packages/contracts/test/libraries/StringUtils/StringUtils_hexToBytes32.t.sol create mode 100644 packages/contracts/test/libraries/StringUtils/fuzz/StringUtils_fuzz_hexToBytes.t.sol create mode 100644 packages/contracts/test/libraries/StringUtils/fuzz/StringUtils_fuzz_hexToBytes32.t.sol rename packages/contracts/test/script/{ChangeOwners.t.sol => ChangeOwnersScript.t.sol} (53%) delete mode 100644 packages/contracts/test/script/ChangeSignerInECDSAOwnedDKIMRegistry.t.sol create mode 100644 packages/contracts/test/script/ChangeSignerInECDSAOwnedDKIMRegistryScript.t.sol delete mode 100644 packages/contracts/test/script/ChangeSourceInForwardDKIMRegistry.t.sol delete mode 100644 packages/contracts/test/script/DeployCommons.t.sol delete mode 100644 packages/contracts/test/script/DeployRecoveryController.t.sol create mode 100644 packages/contracts/test/script/DeployRecoveryControllerScript.t.sol rename packages/contracts/test/script/{DeploySimpleWallet.t.sol => DeploySimpleWalletScript.t.sol} (58%) delete mode 100644 packages/contracts/test/script/RenounceOwners.t.sol create mode 100644 packages/contracts/test/script/RenounceOwnersScript.t.sol delete mode 100644 packages/contracts/test/script/Upgrades.t.sol create mode 100644 packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/changeSigner.t.sol create mode 100644 packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/computeSignedMsg.t.sol create mode 100644 packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/isDKIMPublicKeyHashValid.t.sol create mode 100644 packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/revokeDKIMPublicKeyHash.t.sol rename packages/contracts/test/utils/{ECDSAOwnedDKIMRegistry.t.sol => ECDSAOwnedDKIMRegistry/setDKIMPublicKeyHash.t.sol} (63%) create mode 100644 packages/contracts/test/utils/Verifier.t.sol create mode 100644 packages/relayer/CODING_GUIDELINES.md create mode 100644 packages/relayer/CONTRIBUTING.md create mode 100644 packages/relayer/eml_templates/error_for_admin.html delete mode 100644 packages/relayer/src/abis/ecdsa_owned_dkim_registry.rs delete mode 100644 packages/relayer/src/abis/email_account_recovery.rs create mode 100644 packages/relayer/src/abis/user_overridable_dkim_registry.rs create mode 100644 packages/relayer/src/modules/web_server/relayer_errors.rs rename packages/relayer/src/{utils => }/strings.rs (69%) delete mode 100644 packages/relayer/src/utils/mod.rs delete mode 100644 packages/relayer/src/utils/subject_templates.rs delete mode 100644 packages/relayer/src/utils/utils.rs create mode 100644 rustfmt.toml diff --git a/.dockerignore b/.dockerignore index 5961d58c..18eb0a1b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -26,6 +26,7 @@ packages/contracts/test/build_integration/*.json packages/contracts/test/build_integration/*.zkey packages/contracts/test/build_integration/*.wasm packages/contracts/test/build_integration/*.txt +packages/contracts/test/EmailAccountRecoveryZkSync # NFT Relayer packages/nft_relayer/sendgrid.env diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..8b688cb0 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,28 @@ +## Description + + + + +## Type of change + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] This change requires a documentation update + +## How Has This Been Tested? + + +- [ ] Test A +- [ ] Test B + +## Checklist: + +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] New and existing unit tests pass locally with my changes +- [ ] Any dependent changes have been merged and published in downstream modules \ No newline at end of file diff --git a/.github/workflows/build-fmt.yml b/.github/workflows/build-fmt.yml new file mode 100644 index 00000000..0cb1b536 --- /dev/null +++ b/.github/workflows/build-fmt.yml @@ -0,0 +1,64 @@ +name: Build and Format + +on: [push] + +jobs: + build-and-format: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - run: rustup show + + - name: Install rustfmt and clippy + run: | + rustup component add rustfmt + rustup component add clippy + + - uses: Swatinem/rust-cache@v2 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: "yarn" + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly-0079a1146b79a4aeda58b0258215bedb1f92700b + + - name: Build contracts + working-directory: packages/contracts + run: yarn build + + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@main + with: + # this might remove tools that are actually needed, + # if set to "true" but frees about 6 GB + tool-cache: false + + # all of these default to true, but feel free to set to + # "false" if necessary for your workflow + android: true + dotnet: true + haskell: true + large-packages: true + docker-images: true + swap-storage: true + + - name: Build and check for warnings + env: + RUSTFLAGS: "-D warnings" + run: cargo build --release + + - name: Check formatting + run: cargo fmt -- --check + + - name: Run clippy + run: cargo clippy -- -D warnings diff --git a/.github/workflows/build-img.yml b/.github/workflows/build-img.yml new file mode 100644 index 00000000..2e578f91 --- /dev/null +++ b/.github/workflows/build-img.yml @@ -0,0 +1,51 @@ +name: Build and Push Docker Image + +on: + push: + branches: + - refactor + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Log in to the Container registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=sha,prefix= + type=raw,value=latest + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: . + file: ./Full.Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/build-test-fmt.yml b/.github/workflows/build-test-fmt.yml deleted file mode 100644 index 17f94353..00000000 --- a/.github/workflows/build-test-fmt.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: Build-Test-Fmt - -on: - [push] - -jobs: - build-test-fmt: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - run: rustup show - - - uses: Swatinem/rust-cache@v2 - - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: "yarn" - - - name: Install dependencies - run: yarn install --frozen-lockfile - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly-0079a1146b79a4aeda58b0258215bedb1f92700b - - - name: Run tests - working-directory: packages/contracts - run: yarn build - - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@main - with: - # this might remove tools that are actually needed, - # if set to "true" but frees about 6 GB - tool-cache: false - - # all of these default to true, but feel free to set to - # "false" if necessary for your workflow - android: true - dotnet: true - haskell: true - large-packages: true - docker-images: true - swap-storage: true - - - name: Build - run: cargo build --release - - - name: Test - run: cargo test --release diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 29740de9..f816a17c 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -1,4 +1,4 @@ -name: unit-tests +name: Unit Tests on: [push] @@ -21,8 +21,8 @@ jobs: override: true components: rustfmt, clippy - - name: Download circom (Linux) - run: git clone https://github.com/iden3/circom.git && cd circom && cargo build --release && cargo install --path circom + - name: Download circom v2.1.9 (Linux) + run: wget https://github.com/iden3/circom/releases/download/v2.1.9/circom-linux-amd64 -O /usr/local/bin/circom && chmod +x /usr/local/bin/circom - name: Print circom version run: circom --version @@ -47,7 +47,7 @@ jobs: uses: actions/setup-node@v3 with: node-version: 18 - + - name: Install yarn run: npm install -g yarn @@ -62,3 +62,37 @@ jobs: - name: Run tests working-directory: packages/contracts run: yarn test + + - name: Run script tests + working-directory: packages/contracts + run: yarn test:script + + relayer: + name: relayer + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install yarn + run: npm install -g yarn + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1.2.0 + with: + version: nightly-0079a1146b79a4aeda58b0258215bedb1f92700b + + - name: Build contracts + working-directory: packages/contracts + run: yarn build + + - name: Run tests + working-directory: packages/relayer + run: cargo test diff --git a/.gitignore b/.gitignore index 0ee936ed..09588c48 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,7 @@ packages/nft_relayer/logs sql_database.db .sqlx .ic.pem +config.json # Relayer packages/relayer/sendgrid.env @@ -57,6 +58,10 @@ sql_database.db .sqlx .ic.pem +# ABIs +packages/relayer/src/abis/* +!packages/realyer/src/abis/mod.rs + # Prover packages/prover/build/* packages/prover/params/*.zkey @@ -80,6 +85,9 @@ book # Vs code settings .vscode +# Editor settings +.idea + # For zksync zkout .cache diff --git a/Cargo.lock b/Cargo.lock index 558dfa58..6a2da296 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "Inflector" @@ -14,18 +14,18 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aes" @@ -83,15 +83,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95" [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" @@ -101,9 +101,9 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "ascii" @@ -171,6 +171,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener 5.3.1", + "event-listener-strategy", + "pin-project-lite", +] + [[package]] name = "async-native-tls" version = "0.5.0" @@ -185,13 +196,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] @@ -232,14 +243,14 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" @@ -253,8 +264,8 @@ dependencies = [ "bytes", "futures-util", "http 0.2.12", - "http-body", - "hyper", + "http-body 0.4.6", + "hyper 0.14.31", "itoa", "matchit", "memchr", @@ -266,7 +277,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 0.1.2", "tokio", "tower", "tower-layer", @@ -283,7 +294,7 @@ dependencies = [ "bytes", "futures-util", "http 0.2.12", - "http-body", + "http-body 0.4.6", "mime", "rustversion", "tower-layer", @@ -303,17 +314,17 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -433,8 +444,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" dependencies = [ "arrayref", - "arrayvec 0.7.4", - "constant_time_eq 0.3.0", + "arrayvec 0.7.6", + "constant_time_eq 0.3.1", ] [[package]] @@ -455,20 +466,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "bls12_381" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3c196a77437e7cc2fb515ce413a6401291578b5afc8ecb29a3c7ab957f05941" -dependencies = [ - "digest 0.9.0", - "ff 0.12.1", - "group 0.12.1", - "pairing 0.22.0", - "rand_core", - "subtle", -] - [[package]] name = "bs58" version = "0.5.1" @@ -499,9 +496,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" dependencies = [ "serde", ] @@ -529,9 +526,9 @@ dependencies = [ [[package]] name = "cached" -version = "0.46.1" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c8c50262271cdf5abc979a5f76515c234e764fa025d1ba4862c0f0bcda0e95" +checksum = "a8466736fe5dbcaf8b8ee24f9bbefe43c884dc3e9ff7178da70f55bffca1133c" dependencies = [ "ahash", "hashbrown 0.14.5", @@ -542,50 +539,46 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.7" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ "serde", ] [[package]] name = "candid" -version = "0.9.11" +version = "0.10.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465c1ce01d8089ee5b49ba20d3a9da15a28bba64c35cdff2aa256d37e319625d" +checksum = "6c30ee7f886f296b6422c0ff017e89dd4f831521dfdcc76f3f71aae1ce817222" dependencies = [ "anyhow", "binread", "byteorder", "candid_derive", - "codespan-reporting", - "crc32fast", - "data-encoding", "hex", + "ic_principal", "leb128", "num-bigint", "num-traits", - "num_enum 0.6.1", "paste", "pretty", "serde", "serde_bytes", - "sha2 0.10.8", "stacker", "thiserror", ] [[package]] name = "candid_derive" -version = "0.6.4" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201ea498d901add0822653ac94cb0f8a92f9b1758a5273f4dafbb6673c9a5020" +checksum = "3de398570c386726e7a59d9887b68763c481477f9a043fb998a2e09d428df1a9" dependencies = [ "lazy_static", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] @@ -605,7 +598,7 @@ checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", - "semver 1.0.23", + "semver", "serde", "serde_json", "thiserror", @@ -613,13 +606,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.2" +version = "1.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47de7e88bbbd467951ae7f5a6f34f70d1b4d9cfce53d5fd70f74ebe118b3db56" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" dependencies = [ "jobserver", "libc", - "once_cell", + "shlex", ] [[package]] @@ -630,8 +623,8 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfdkim" -version = "0.3.0" -source = "git+https://github.com/SoraSuegami/dkim.git#93829027f03a7442392a37b4635471d8b7f49e6b" +version = "0.3.3" +source = "git+https://github.com/zkemail/cfdkim.git#3b1cfd75e2afad12fbc1e8ece50e93e51415118b" dependencies = [ "base64 0.21.7", "chrono", @@ -668,11 +661,11 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "charset" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e9079d1a12a2cc2bffb5db039c43661836ead4082120d5844f02555aca2d46" +checksum = "f1f927b07c74ba84c7e5fe4db2baeb3e996ab2688992e39ac68ce3220a677c7e" dependencies = [ - "base64 0.13.1", + "base64 0.22.1", "encoding_rs", ] @@ -707,16 +700,6 @@ dependencies = [ "inout", ] -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - [[package]] name = "coins-bip32" version = "0.8.7" @@ -813,9 +796,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.12.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" +checksum = "0121754e84117e65f9d90648ee6aa4882a6e63110307ab73967a4c5e7e69e586" dependencies = [ "cfg-if", "cpufeatures", @@ -838,9 +821,9 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "constant_time_eq" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" [[package]] name = "core-foundation" @@ -854,15 +837,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -995,7 +978,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] @@ -1045,7 +1028,7 @@ checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] @@ -1125,9 +1108,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "dunce" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "ecdsa" @@ -1200,9 +1183,9 @@ dependencies = [ "base16ct", "crypto-bigint", "digest 0.10.7", - "ff 0.13.0", + "ff", "generic-array", - "group 0.13.0", + "group", "pem-rfc7468", "pkcs8", "rand_core", @@ -1223,9 +1206,9 @@ dependencies = [ [[package]] name = "email_address" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1019fa28f600f5b581b7a603d515c3f1635da041ca211b5055804788673abfe" +checksum = "e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449" [[package]] name = "ena" @@ -1435,10 +1418,10 @@ dependencies = [ "proc-macro2", "quote", "regex", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", - "syn 2.0.71", + "syn 2.0.82", "toml", "walkdir", ] @@ -1456,7 +1439,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] @@ -1465,7 +1448,7 @@ version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" dependencies = [ - "arrayvec 0.7.4", + "arrayvec 0.7.6", "bytes", "cargo_metadata", "chrono", @@ -1474,15 +1457,15 @@ dependencies = [ "ethabi", "generic-array", "k256", - "num_enum 0.7.2", + "num_enum", "once_cell", "open-fastrlp", "rand", "rlp", "serde", "serde_json", - "strum 0.26.3", - "syn 2.0.71", + "strum", + "syn 2.0.82", "tempfile", "thiserror", "tiny-keccak", @@ -1497,8 +1480,8 @@ checksum = "e79e5973c26d4baf0ce55520bd732314328cabe53193286671b47144145b9649" dependencies = [ "chrono", "ethers-core", - "reqwest", - "semver 1.0.23", + "reqwest 0.11.27", + "semver", "serde", "serde_json", "thiserror", @@ -1522,7 +1505,7 @@ dependencies = [ "futures-locks", "futures-util", "instant", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", "thiserror", @@ -1554,7 +1537,7 @@ dependencies = [ "jsonwebtoken", "once_cell", "pin-project", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", "thiserror", @@ -1607,7 +1590,7 @@ dependencies = [ "path-slash", "rayon", "regex", - "semver 1.0.23", + "semver", "serde", "serde_json", "solang-parser", @@ -1659,12 +1642,13 @@ dependencies = [ [[package]] name = "fancy-regex" -version = "0.11.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2" +checksum = "531e46835a22af56d1e3b66f04844bed63158bc094a628bec1d321d9b4c44bf2" dependencies = [ "bit-set", - "regex", + "regex-automata", + "regex-syntax", ] [[package]] @@ -1678,19 +1662,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" - -[[package]] -name = "ff" -version = "0.12.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core", - "subtle", -] +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "ff" @@ -1739,9 +1713,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.30" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ "crc32fast", "miniz_oxide", @@ -1749,9 +1723,9 @@ dependencies = [ [[package]] name = "flume" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" dependencies = [ "futures-core", "futures-sink", @@ -1798,21 +1772,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "function_name" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1ab577a896d09940b5fe12ec5ae71f9d8211fff62c919c03a3750a9901e98a7" -dependencies = [ - "function_name-proc-macro", -] - -[[package]] -name = "function_name-proc-macro" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673464e1e314dd67a0fd9544abc99e8eb28d0c7e3b69b033bcff9b2d00b87333" - [[package]] name = "funty" version = "2.0.0" @@ -1821,9 +1780,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -1836,9 +1795,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -1846,15 +1805,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -1874,9 +1833,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-locks" @@ -1890,26 +1849,26 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-timer" @@ -1923,9 +1882,9 @@ dependencies = [ [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -1974,9 +1933,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "glob" @@ -2022,7 +1981,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cdf7b487d864c2939b23902291a5041bc4a84418268f25fda1c8d4e15ad8fa" dependencies = [ "graphql_query_derive", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", ] @@ -2055,24 +2014,13 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "rand_core", - "subtle", -] - [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff 0.13.0", + "ff", "rand_core", "subtle", ] @@ -2089,7 +2037,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.2.6", + "indexmap 2.6.0", "slab", "tokio", "tokio-util", @@ -2104,40 +2052,19 @@ checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" [[package]] name = "halo2curves" -version = "0.4.0" -source = "git+https://github.com/privacy-scaling-explorations/halo2curves.git?rev=81a078254518a7a4b7c69fab120621deaace9389#81a078254518a7a4b7c69fab120621deaace9389" -dependencies = [ - "blake2b_simd", - "ff 0.13.0", - "group 0.13.0", - "lazy_static", - "maybe-rayon", - "num-bigint", - "num-traits", - "pairing 0.23.0", - "pasta_curves", - "paste", - "rand", - "rand_core", - "static_assertions", - "subtle", -] - -[[package]] -name = "halo2curves" -version = "0.6.1" -source = "git+https://github.com/privacy-scaling-explorations/halo2curves.git#d34e9e46f7daacd194739455de3b356ca6c03206" +version = "0.7.0" +source = "git+https://github.com/privacy-scaling-explorations/halo2curves.git#8771fe5a5d54fc03e74dbc8915db5dad3ab46a83" dependencies = [ "blake2", "digest 0.10.7", - "ff 0.13.0", - "group 0.13.0", + "ff", + "group", "halo2derive", "lazy_static", "num-bigint", "num-integer", "num-traits", - "pairing 0.23.0", + "pairing", "pasta_curves", "paste", "rand", @@ -2152,7 +2079,7 @@ dependencies = [ [[package]] name = "halo2derive" version = "0.1.0" -source = "git+https://github.com/privacy-scaling-explorations/halo2curves.git#d34e9e46f7daacd194739455de3b356ca6c03206" +source = "git+https://github.com/privacy-scaling-explorations/halo2curves.git#8771fe5a5d54fc03e74dbc8915db5dad3ab46a83" dependencies = [ "num-bigint", "num-integer", @@ -2192,6 +2119,12 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + [[package]] name = "hashers" version = "1.0.1" @@ -2231,6 +2164,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -2255,6 +2194,11 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hmac-sha256" +version = "1.1.7" +source = "git+https://github.com/zkemail/rust-hmac-sha256.git#e98ae695d2600c98b57de4b1ad1e0bfb7895f458" + [[package]] name = "home" version = "0.5.9" @@ -2308,11 +2252,34 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "pin-project-lite", +] + [[package]] name = "httparse" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -2322,9 +2289,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.30" +version = "0.14.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" dependencies = [ "bytes", "futures-channel", @@ -2332,7 +2299,7 @@ dependencies = [ "futures-util", "h2", "http 0.2.12", - "http-body", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -2344,6 +2311,25 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -2352,10 +2338,28 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http 0.2.12", - "hyper", - "rustls", + "hyper 0.14.31", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper 1.5.0", + "hyper-util", + "rustls 0.23.15", + "rustls-pki-types", "tokio", - "tokio-rustls", + "tokio-rustls 0.26.0", + "tower-service", + "webpki-roots 0.26.6", ] [[package]] @@ -2365,17 +2369,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper", + "hyper 0.14.31", "native-tls", "tokio", "tokio-native-tls", ] +[[package]] +name = "hyper-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.5.0", + "pin-project-lite", + "socket2 0.5.7", + "tokio", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2396,30 +2419,32 @@ dependencies = [ [[package]] name = "ic-agent" -version = "0.30.2" +version = "0.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "263d5c7b295ba69eac0692e6f6b35a01ca323889d10612c0f8c8fd223b0bfec5" +checksum = "3fd3fdf5e5c4f4a9fe5ca612f0febd22dcb161d2f2b75b0142326732be5e4978" dependencies = [ + "async-lock", "backoff", "cached", "candid", "ed25519-consensus", "futures-util", "hex", - "http 0.2.12", - "http-body", + "http 1.1.0", + "http-body 1.0.1", "ic-certification", "ic-transport-types", "ic-verify-bls-signature", "k256", "leb128", - "pem 2.0.1", + "p256", + "pem 3.0.4", "pkcs8", "rand", "rangemap", - "reqwest", - "ring 0.16.20", - "rustls-webpki", + "reqwest 0.12.8", + "ring 0.17.8", + "rustls-webpki 0.102.8", "sec1", "serde", "serde_bytes", @@ -2435,9 +2460,9 @@ dependencies = [ [[package]] name = "ic-certification" -version = "1.3.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c04340437a32c8b9c80d36f09715909c1e0a755327503a2e2906dcd662ba4e" +checksum = "e64ee3d8b6e81b51f245716d3e0badb63c283c00f3c9fb5d5219afc30b5bf821" dependencies = [ "hex", "serde", @@ -2447,9 +2472,9 @@ dependencies = [ [[package]] name = "ic-transport-types" -version = "0.30.2" +version = "0.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b2be3fc4f0641a8c3967fbc8ab52b08bc6d13bf65fb2460b090710374be49b1" +checksum = "875dc4704780383112e8e8b5063a1b98de114321d0c7d3e7f635dcf360a57fba" dependencies = [ "candid", "hex", @@ -2464,33 +2489,65 @@ dependencies = [ [[package]] name = "ic-utils" -version = "0.30.2" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbd6fac62c95df9f963c8a941431d86308c864ba1e9001da75843d79a355fb68" +checksum = "2fa832296800758c9c921dd1704985ded6b3e6fbc3aee409727eb1f00d69a595" dependencies = [ "async-trait", "candid", + "futures-util", "ic-agent", "once_cell", - "semver 1.0.23", + "semver", "serde", "serde_bytes", - "strum 0.24.1", - "strum_macros 0.24.3", + "sha2 0.10.8", + "strum", + "strum_macros", "thiserror", "time", + "tokio", ] [[package]] name = "ic-verify-bls-signature" -version = "0.1.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583b1c03380cf86059160cc6c91dcbf56c7b5f141bf3a4f06bc79762d775fac4" +checksum = "d420b25c0091059f6c3c23a21427a81915e6e0aca3b79e0d403ed767f286a3b9" dependencies = [ - "bls12_381", + "hex", + "ic_bls12_381", "lazy_static", - "pairing 0.22.0", - "sha2 0.9.9", + "pairing", + "rand", + "sha2 0.10.8", +] + +[[package]] +name = "ic_bls12_381" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22c65787944f32af084dffd0c68c1e544237b76e215654ddea8cd9f527dd8b69" +dependencies = [ + "digest 0.10.7", + "ff", + "group", + "pairing", + "rand_core", + "subtle", +] + +[[package]] +name = "ic_principal" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1762deb6f7c8d8c2bdee4b6c5a47b60195b74e9b5280faa5ba29692f8e17429c" +dependencies = [ + "crc32fast", + "data-encoding", + "serde", + "sha2 0.10.8", + "thiserror", ] [[package]] @@ -2589,12 +2646,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.0", ] [[package]] @@ -2629,17 +2686,17 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] name = "is-terminal" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" dependencies = [ - "hermit-abi", + "hermit-abi 0.4.0", "libc", "windows-sys 0.52.0", ] @@ -2662,6 +2719,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -2692,18 +2758,18 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -2724,9 +2790,9 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", "ecdsa", @@ -2818,19 +2884,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" - -[[package]] -name = "libloading" -version = "0.6.7" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883" -dependencies = [ - "cfg-if", - "winapi", -] +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libm" @@ -2898,13 +2954,13 @@ dependencies = [ [[package]] name = "mailparse" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d096594926cab442e054e047eb8c1402f7d5b2272573b97ba68aa40629f9757" +checksum = "3da03d5980411a724e8aaf7b61a7b5e386ec55a7fb49ee3d0ff79efc7e5e7c7e" dependencies = [ "charset", "data-encoding", - "quoted_printable 0.5.0", + "quoted_printable 0.5.1", ] [[package]] @@ -2934,16 +2990,6 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" -[[package]] -name = "maybe-rayon" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" -dependencies = [ - "cfg-if", - "rayon", -] - [[package]] name = "md-5" version = "0.10.6" @@ -2967,29 +3013,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] -name = "minimal-lexical" -version = "0.2.1" +name = "minicov" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - +checksum = "5c71e683cd655513b99affab7d317deb690528255a0d5f717f1024093c12b169" +dependencies = [ + "cc", + "walkdir", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "0.8.11" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3015,47 +3072,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" -[[package]] -name = "neon" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28e15415261d880aed48122e917a45e87bb82cf0260bb6db48bbab44b7464373" -dependencies = [ - "neon-build", - "neon-macros", - "neon-runtime", - "semver 0.9.0", - "smallvec", -] - -[[package]] -name = "neon-build" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bac98a702e71804af3dacfde41edde4a16076a7bbe889ae61e56e18c5b1c811" - -[[package]] -name = "neon-macros" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7288eac8b54af7913c60e0eb0e2a7683020dffa342ab3fd15e28f035ba897cf" -dependencies = [ - "quote", - "syn 1.0.109", - "syn-mid", -] - -[[package]] -name = "neon-runtime" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4676720fa8bb32c64c3d9f49c47a47289239ec46b4bdb66d0913cc512cb0daca" -dependencies = [ - "cfg-if", - "libloading", - "smallvec", -] - [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -3156,50 +3172,29 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] [[package]] name = "num_enum" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" -dependencies = [ - "num_enum_derive 0.6.1", -] - -[[package]] -name = "num_enum" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" -dependencies = [ - "num_enum_derive 0.7.2", -] - -[[package]] -name = "num_enum_derive" -version = "0.6.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 2.0.71", + "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] @@ -3213,7 +3208,7 @@ dependencies = [ "getrandom", "http 0.2.12", "rand", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", "serde_path_to_error", @@ -3233,18 +3228,18 @@ dependencies = [ [[package]] name = "object" -version = "0.36.1" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" @@ -3258,7 +3253,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" dependencies = [ - "arrayvec 0.7.4", + "arrayvec 0.7.6", "auto_impl", "bytes", "ethereum-types", @@ -3279,9 +3274,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.64" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ "bitflags 2.6.0", "cfg-if", @@ -3300,7 +3295,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] @@ -3311,9 +3306,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.102" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -3328,12 +3323,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] -name = "pairing" -version = "0.22.0" +name = "p256" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ - "group 0.12.1", + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2 0.10.8", ] [[package]] @@ -3342,7 +3340,7 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" dependencies = [ - "group 0.13.0", + "group", ] [[package]] @@ -3351,7 +3349,7 @@ version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ - "arrayvec 0.7.4", + "arrayvec 0.7.6", "bitvec", "byte-slice-cast", "impl-trait-for-tuples", @@ -3365,7 +3363,7 @@ version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -3373,9 +3371,9 @@ dependencies = [ [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -3420,7 +3418,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.2", + "redox_syscall 0.5.7", "smallvec", "windows-targets 0.52.6", ] @@ -3443,8 +3441,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" dependencies = [ "blake2b_simd", - "ff 0.13.0", - "group 0.13.0", + "ff", + "group", "lazy_static", "rand", "static_assertions", @@ -3496,11 +3494,11 @@ dependencies = [ [[package]] name = "pem" -version = "2.0.1" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b13fe415cdf3c8e44518e18a7c95a13431d9bdf6d15367d82b23c377fdd441a" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "serde", ] @@ -3521,9 +3519,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.11" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", "thiserror", @@ -3532,9 +3530,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.11" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" +checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" dependencies = [ "pest", "pest_generator", @@ -3542,22 +3540,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.11" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" +checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] name = "pest_meta" -version = "2.7.11" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" +checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" dependencies = [ "once_cell", "pest", @@ -3571,7 +3569,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.2.6", + "indexmap 2.6.0", ] [[package]] @@ -3614,7 +3612,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] @@ -3637,22 +3635,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] @@ -3690,17 +3688,17 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "poseidon-rs" -version = "0.0.10" -source = "git+https://github.com/SoraSuegami/poseidon-rs.git?branch=master#15aa98d045e531806e39e48ba5a0b999f5de5d8d" +version = "1.0.0" +source = "git+https://github.com/zkemail/poseidon-rs.git#fe5ce2634c27326219d4faf75beb73b40a0beb7d" dependencies = [ "getrandom", - "halo2curves 0.6.1", + "halo2curves", "once_cell", "serde", "thiserror", @@ -3714,9 +3712,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "precomputed-hash" @@ -3737,12 +3738,21 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.20" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +checksum = "910d41a655dac3b764f1ade94821093d3610248694320cd072303a8eedcf221d" dependencies = [ "proc-macro2", - "syn 2.0.71", + "syn 2.0.82", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", ] [[package]] @@ -3761,28 +3771,18 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - -[[package]] -name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.21.1", + "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] @@ -3805,9 +3805,9 @@ dependencies = [ [[package]] name = "psm" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +checksum = "aa37f80ca58604976033fae9515a8a2989fc13797d953f7c04fb8fa36a11f205" dependencies = [ "cc", ] @@ -3824,11 +3824,59 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" +[[package]] +name = "quinn" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls 0.23.15", + "socket2 0.5.7", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" +dependencies = [ + "bytes", + "rand", + "ring 0.17.8", + "rustc-hash", + "rustls 0.23.15", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" +dependencies = [ + "libc", + "once_cell", + "socket2 0.5.7", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -3841,9 +3889,9 @@ checksum = "5a3866219251662ec3b26fc217e3e05bf9c4f84325234dfb96bf0bf840889e49" [[package]] name = "quoted_printable" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ec282e887b434b68c18fe5c121d38e72a5cf35119b59e54ec5b992ea9c8eb0" +checksum = "640c9bd8497b02465aeef5375144c26062e0dcd5939dfcbb0f5db76cb8c17c73" [[package]] name = "radium" @@ -3933,27 +3981,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.2" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", @@ -3962,9 +4001,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -3974,9 +4013,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -3985,13 +4024,13 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "relayer" -version = "1.1.0" +version = "1.0.0" dependencies = [ "anyhow", "async-imap", @@ -4003,9 +4042,8 @@ dependencies = [ "chrono", "dotenv", "ethers", - "ff 0.13.0", + "ff", "file-rotate", - "function_name", "futures", "graphql_client", "handlebars", @@ -4021,7 +4059,8 @@ dependencies = [ "rand", "regex", "relayer-utils", - "reqwest", + "reqwest 0.11.27", + "rustc-hex", "serde", "serde_json", "sled", @@ -4030,44 +4069,47 @@ dependencies = [ "slog-json", "slog-term", "sqlx", + "thiserror", "tiny_http", "tokio", "tower-http", - "uuid 1.10.0", + "uuid 1.11.0", "webbrowser", ] [[package]] name = "relayer-utils" -version = "0.1.0" -source = "git+https://github.com/zkemail/relayer-utils?rev=2c3e9b8#2c3e9b80ae043cd038cd5c55279c60b1578587f7" +version = "0.4.2" +source = "git+https://github.com/zkemail/relayer-utils.git#298a0f90c49b232fd749a4a361c4999a83c713c4" dependencies = [ "anyhow", - "base64 0.21.7", + "base64 0.22.1", "cfdkim", "ethers", - "fancy-regex", "file-rotate", - "halo2curves 0.4.0", + "halo2curves", "hex", + "hmac-sha256", "itertools 0.10.5", + "js-sys", "lazy_static", - "neon", + "mailparse", "num-bigint", - "num-traits", - "once_cell", "poseidon-rs", + "rand", "rand_core", + "regex", + "reqwest 0.11.27", "rsa", "serde", + "serde-wasm-bindgen", "serde_json", - "serde_regex", - "sha2 0.10.8", "slog", "slog-async", "slog-json", "slog-term", - "tokio", + "wasm-bindgen", + "wasm-bindgen-futures", "zk-regex-apis", ] @@ -4084,9 +4126,9 @@ dependencies = [ "futures-util", "h2", "http 0.2.12", - "http-body", - "hyper", - "hyper-rustls", + "http-body 0.4.6", + "hyper 0.14.31", + "hyper-rustls 0.24.2", "hyper-tls", "ipnet", "js-sys", @@ -4096,16 +4138,59 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls", - "rustls-pemfile", + "rustls 0.21.12", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 0.1.2", "system-configuration", "tokio", "tokio-native-tls", - "tokio-rustls", + "tokio-rustls 0.24.1", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.25.4", + "winreg", +] + +[[package]] +name = "reqwest" +version = "0.12.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.5.0", + "hyper-rustls 0.27.3", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls 0.23.15", + "rustls-pemfile 2.2.0", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "tokio", + "tokio-rustls 0.26.0", "tokio-util", "tower-service", "url", @@ -4113,8 +4198,8 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", - "winreg", + "webpki-roots 0.26.6", + "windows-registry", ] [[package]] @@ -4226,6 +4311,12 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" + [[package]] name = "rustc-hex" version = "2.1.0" @@ -4234,18 +4325,18 @@ checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.23", + "semver", ] [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags 2.6.0", "errno", @@ -4262,10 +4353,24 @@ checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring 0.17.8", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.23.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" +dependencies = [ + "once_cell", + "ring 0.17.8", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -4275,6 +4380,21 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -4285,11 +4405,22 @@ dependencies = [ "untrusted 0.9.0", ] +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring 0.17.8", + "rustls-pki-types", + "untrusted 0.9.0", +] + [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "ryu" @@ -4333,7 +4464,7 @@ version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -4341,11 +4472,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4398,9 +4529,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.6.0", "core-foundation", @@ -4411,9 +4542,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" dependencies = [ "core-foundation-sys", "libc", @@ -4425,15 +4556,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.23" @@ -4443,12 +4565,6 @@ dependencies = [ "serde", ] -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "send_wrapper" version = "0.4.0" @@ -4463,9 +4579,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.204" +version = "1.0.211" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "1ac55e59090389fb9f0dd9e0f3c09615afed1d19094284d0b200441f13550793" dependencies = [ "serde_derive", ] @@ -4502,22 +4618,23 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.211" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "54be4f245ce16bc58d57ef2716271d0d4519e0f6defa147f6e081005bcb278ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -4532,16 +4649,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_regex" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf" -dependencies = [ - "regex", - "serde", -] - [[package]] name = "serde_repr" version = "0.1.19" @@ -4550,14 +4657,14 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] name = "serde_spanned" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -4630,6 +4737,12 @@ dependencies = [ "keccak", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -4802,9 +4915,9 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f895e3734318cc55f1fe66258926c9b910c124d47520339efecbb6c59cec7c1f" +checksum = "7bba3a93db0cc4f7bdece8bb09e77e2e785c20bfebf79eb8340ed80708048790" dependencies = [ "nom", "unicode_categories", @@ -4845,7 +4958,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.2.6", + "indexmap 2.6.0", "log", "memchr", "once_cell", @@ -5009,15 +5122,15 @@ dependencies = [ [[package]] name = "stacker" -version = "0.1.15" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +checksum = "799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b" dependencies = [ "cc", "cfg-if", "libc", "psm", - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -5062,32 +5175,13 @@ dependencies = [ "unicode-properties", ] -[[package]] -name = "strum" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" - [[package]] name = "strum" version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" dependencies = [ - "strum_macros 0.26.4", -] - -[[package]] -name = "strum_macros" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 1.0.109", + "strum_macros", ] [[package]] @@ -5100,7 +5194,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] @@ -5125,8 +5219,8 @@ dependencies = [ "fs2", "hex", "once_cell", - "reqwest", - "semver 1.0.23", + "reqwest 0.11.27", + "semver", "serde", "serde_json", "sha2 0.10.8", @@ -5148,9 +5242,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.71" +version = "2.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" +checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" dependencies = [ "proc-macro2", "quote", @@ -5158,21 +5252,19 @@ dependencies = [ ] [[package]] -name = "syn-mid" -version = "0.5.4" +name = "sync_wrapper" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea305d57546cc8cd04feb14b62ec84bf17f50e3f7b12560d7bfa9265f39d9ed" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sync_wrapper" -version = "0.1.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] [[package]] name = "system-configuration" @@ -5209,14 +5301,15 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.10.1" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", - "fastrand 2.1.0", + "fastrand 2.1.1", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5230,33 +5323,24 @@ dependencies = [ "winapi", ] -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - [[package]] name = "thiserror" -version = "1.0.62" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.62" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] @@ -5338,32 +5422,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.0" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot 0.12.3", "pin-project-lite", "signal-hook-registry", "socket2 0.5.7", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] @@ -5382,15 +5465,26 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls", + "rustls 0.21.12", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls 0.23.15", + "rustls-pki-types", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite", @@ -5405,18 +5499,18 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls", + "rustls 0.21.12", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", "tungstenite", - "webpki-roots", + "webpki-roots 0.25.4", ] [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -5427,58 +5521,36 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.14" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.15", + "toml_edit", ] [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.2.6", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap 2.2.6", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1" -dependencies = [ - "indexmap 2.2.6", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.13", + "winnow", ] [[package]] @@ -5507,7 +5579,7 @@ dependencies = [ "futures-core", "futures-util", "http 0.2.12", - "http-body", + "http-body 0.4.6", "pin-project-lite", "tower-layer", "tower-service", @@ -5515,15 +5587,15 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -5545,7 +5617,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] @@ -5631,7 +5703,7 @@ dependencies = [ "httparse", "log", "rand", - "rustls", + "rustls 0.21.12", "sha1", "thiserror", "url", @@ -5652,9 +5724,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "uint" @@ -5676,48 +5748,48 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-properties" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "unicode_categories" @@ -5792,9 +5864,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" [[package]] name = "vcpkg" @@ -5804,9 +5876,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "void" @@ -5847,11 +5919,12 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", + "once_cell", "serde", "serde_json", "wasm-bindgen-macro", @@ -5859,24 +5932,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.42" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ "cfg-if", "js-sys", @@ -5886,9 +5959,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5896,31 +5969,32 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "wasm-bindgen-test" -version = "0.3.42" +version = "0.3.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9bf62a58e0780af3e852044583deee40983e5886da43a271dd772379987667b" +checksum = "d381749acb0943d357dcbd8f0b100640679883fcdeeef04def49daf8d33a5426" dependencies = [ "console_error_panic_hook", "js-sys", + "minicov", "scoped-tls", "wasm-bindgen", "wasm-bindgen-futures", @@ -5929,20 +6003,20 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.42" +version = "0.3.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f89739351a2e03cb94beb799d47fb2cac01759b40ec441f7de39b00cbf7ef0" +checksum = "c97b2ef2c8d627381e51c071c2ab328eac606d3f69dd82bcbca20a9e389d95f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] name = "wasm-streams" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" +checksum = "4e072d4e72f700fb3443d8fe94a39315df013eef1104903cdb0a2abd322bbecd" dependencies = [ "futures-util", "js-sys", @@ -5953,9 +6027,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", @@ -5984,13 +6058,22 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +[[package]] +name = "webpki-roots" +version = "0.26.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "whoami" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" dependencies = [ - "redox_syscall 0.4.1", + "redox_syscall 0.5.7", "wasite", ] @@ -6018,11 +6101,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6040,6 +6123,36 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -6067,6 +6180,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -6247,18 +6369,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "0.6.13" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -6313,6 +6426,7 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] @@ -6324,7 +6438,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.82", ] [[package]] @@ -6355,11 +6469,11 @@ dependencies = [ [[package]] name = "zk-regex-apis" -version = "2.1.0" -source = "git+https://github.com/zkemail/zk-regex.git?branch=main#279d77f774623b4ca50cf4322985f51f60c5a603" +version = "2.2.0" +source = "git+https://github.com/zkemail/zk-regex.git#3319327ef3599989071ab2ea3cb9340a2c48b354" dependencies = [ "fancy-regex", - "itertools 0.10.5", + "itertools 0.13.0", "js-sys", "serde", "serde-wasm-bindgen", @@ -6390,9 +6504,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.12+zstd.1.5.6" +version = "2.0.13+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4e40c320c3cb459d9a9ff6de98cff88f4751ee9275d140e2be94a2b74e4c13" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index 9fd16a34..fc094365 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,4 @@ [workspace] members = ["packages/relayer"] -exclude = ["node_modules/*"] +exclude = ["node_modules/*", "packages/relayer/src/abis"] resolver = "2" diff --git a/Full.Dockerfile b/Full.Dockerfile new file mode 100644 index 00000000..bb07d4e7 --- /dev/null +++ b/Full.Dockerfile @@ -0,0 +1,66 @@ +# Use the latest official Rust image as the base +FROM rust:latest + +# Use bash as the shell +SHELL ["/bin/bash", "-c"] + +# Install NVM, Node.js, and Yarn +RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash \ + && . $HOME/.nvm/nvm.sh \ + && nvm install 18 \ + && nvm alias default 18 \ + && nvm use default \ + && npm install -g yarn + +# Set the working directory +WORKDIR /relayer + +# Pre-configure Git to avoid common issues and increase clone verbosity +RUN git config --global advice.detachedHead false \ + && git config --global core.compression 0 \ + && git config --global protocol.version 2 \ + && git config --global http.postBuffer 1048576000 \ + && git config --global fetch.verbose true + +# Copy project files +COPY . . + +# Remove the packages/relayer directory +RUN rm -rf packages/relayer + +# Install Yarn dependencies with retry mechanism +RUN . $HOME/.nvm/nvm.sh && nvm use default && yarn || \ + (sleep 5 && yarn) || \ + (sleep 10 && yarn) + +# Install Foundry +RUN curl -L https://foundry.paradigm.xyz | bash \ + && source $HOME/.bashrc \ + && foundryup + +# Verify Foundry installation +RUN source $HOME/.bashrc && forge --version + +# Set the working directory for contracts +WORKDIR /relayer/packages/contracts + +# Install Yarn dependencies for contracts +RUN source $HOME/.nvm/nvm.sh && nvm use default && yarn + +# Build the contracts using Foundry +RUN source $HOME/.bashrc && forge build + +# Copy the project files +COPY packages/relayer /relayer/packages/relayer + +# Set the working directory for the Rust project +WORKDIR /relayer/packages/relayer + +# Build the Rust project with caching +RUN cargo build + +# Expose port +EXPOSE 4500 + +# Set the default command +CMD ["cargo", "run"] diff --git a/README.md b/README.md index 83c14a93..aca5b9e5 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ One issue with existing applications on Ethereum is that all users who execute t Our ether email-auth SDK solves this issue: it allows users to execute any transaction on-chain simply by sending an email. Using the SDK, a developer can build a smart contract with the following features without new ZKP circuits. -1. (Authorization) The contract can authorize any message in the Subject of the email that the user sends with a DKIM signature generated by an email provider, e.g., Gmail. +1. (Authorization) The contract can authorize any message in the email body that the user sends with a DKIM signature generated by an email provider, e.g., Gmail. 2. (Authentication) The contract can authenticate that the given Ethereum address corresponds to the email address in the From field of the email. 3. (Privacy) No on-chain information reveals the user's email address itself. In other words, any adversary who learns only public data cannot estimate the corresponding email address from the Ethereum address. @@ -19,10 +19,10 @@ Using the ether email-auth SDK, we construct a library and tools for any smart a In addition to a user and a smart contract employing our SDK, there is a permissionless server called Relayer. The Relayer connects the off-chain world, where the users are, with the on-chain world, where the contracts reside, without compromising security. Specifically, the user, the Relayer, and the contract collaborate as follows: -1. (Off-chain) The user sends the Relayer an email containing a message to the contract in the Subject. -2. (Off-chain) The Relayer generates **an email-auth message for the given email, consisting of data about the Subject, an Ethereum address corresponding to the user's email address, a ZK proof of the email, and so on**. +1. (Off-chain) The user sends the Relayer an email containing a message called command. +2. (Off-chain) The Relayer generates **an email-auth message for the given email, consisting of data about the command, an Ethereum address corresponding to the user's email address, a ZK proof of the email, and so on**. 3. (Off-chain -> On-chain) The Relayer broadcasts an Ethereum transaction to call the contract with the email-auth message. -4. (On-chain) After verifying the given email-auth message, the contract executes application-specific logic depending on the message in the Subject and the user's Ethereum address. +4. (On-chain) After verifying the given email-auth message, the contract executes application-specific logic according to the command in that message for an Ethereum account derived from the user's email address. 5. (On-chain -> Off-chain) The Relayer sends the user an email to report the execution result of the contract. ![Architecture Flow](./docs/images/architecture-flow.png) @@ -35,38 +35,41 @@ That CREATE2 salt is called account salt, which is published on-chain. **As long as the account code is hidden, no adversary can learn the user's email address from on-chain data.** ### Invitation Code -An invitation code is a hex string of the account code along with a prefix, contained in any field of the email header to be inherited by its reply, e.g., Subject. +An invitation code is a hex string of the account code along with a prefix, contained in the email body and inherited by the user's reply. By confirming that a user sends an email with the invitation code, the contract can ensure that the account code is available to that user. It ensures the user’s liveness even when a malicious relayer or another user generates the user's account code because it prevents them from withholding the account code. **It suggests that the contract must check if the given email sent by the user contains the invitation code before confirming that user’s account for the first time.** Notably, the email-auth message, which represents data in the user's email along with its ZK proof, has a boolean field `isCodeExist` such that the value is true if the invitation code is in the email. -However, the Subject message in the email-auth message masks characters for the invitation code. +However, a command in the email-auth message masks characters for the invitation code. **Consequently, no information beyond the existence of the invitation code is disclosed.** -### Subject Template -A subject template defines the expected format of the message in the Subject for each application. -**It allows developers to constrain that message to be in the application-specific format without new ZKP circuits.** +### Command Template +Each application defines expected formats for a command in the email body as command templates. +**To define the command templates, a developer does not need to write any ZKP circuits.** -Specifically, the subject template is an array of strings, each of which has some fixed strings without space and the following variable parts: +Specifically, the command template is an array of strings, each of which has some fixed strings without space and the following variable parts: - `"{string}"`: a string. Its Solidity type is `string`. - `"{uint}"`: a decimal string of the unsigned integer. Its Solidity type is `uint256`. - `"{int}"`: a decimal string of the signed integer. Its Solidity type is `int256`. - `"{decimals}"`: a decimal string of the decimals. Its Solidity type is `uint256`. Its decimal size is fixed to 18. E.g., “2.7” ⇒ `abi.encode(2.7 * (10**18))`. -- `"{ethAddr}"`: a hex string of the Ethereum address. Its Solidity type is `address`. Its value MUST satisfy the checksum of the Ethereum address. +- `"{ethAddr}"`: a hex string of the Ethereum address. Its Solidity type is `address`. Its value MUST be either 0x+lowercase, 0x+uppercase, or 0x+checksumed addresses. ## Package Components There are four significant packages in this repo: ### `circuits` Package -It has a main circom circuit for verifying the email along with its DKIM signature, revealing a Subject message that masks an email address and an invitation code, and deriving an account salt from the email address in the From field and the given account code, which should match with the invitation code if it exists in the email. -The circuit is agnostic to application contexts such as subject templates. +It has a main circom circuit for verifying the email along with its DKIM signature, revealing a command message that masks an email address and an invitation code, and deriving an account salt from the email address in the From field and the given account code, which should match with the invitation code if it exists in the email. +The circuit is agnostic to application specifications such as command templates. **Therefore, a developer does not need to make new circuits.** -In a nutshell, our circuit 1) verifies the given RSA signature for the given email header and the RSA public key, 2) exposes the string in the Subject field except for the invitation code and the email address that appears in the Subject, and 3) computes the account salt derived from the email address in the From field and the given account code, which must be the same as the invitation code if it exists. -In this way, it allows our on-chain verifier to authenticate the email sender and authorize the message in the Subject while protecting privacy. +In a nutshell, our circuit 1) verifies the given RSA signature for the given email header and the RSA public key, 2) exposes a substring between predefined prefix and suffix as a command from the email body while masking the invitation code and email address, and 3) computes the account salt derived from the email address in the From field and the given account code, which must match the invitation code, if present. +This allows our on-chain verifier to authenticate the email sender and authorize the command in the email body while protecting privacy. For detailed setup instructions, see [here](./packages/circuits/README.md). +### Infrastructure Package +For detailed instructions on how to manage infrastructure metrics and alerts in Google Cloud Platform (GCP), please refer to the [Infrastructure Management Scripts](./infrastructure/README.md) documentation. + ### `contracts` Package It has Solidity contracts that help smart contracts based on our SDK verify the email-auth message. Among them, there are three significant contracts: verifier, DKIM registry, and email-auth contracts. @@ -81,11 +84,11 @@ If you use the common trusted custodians for all users, you can deploy a new DKI If each user should be able to modify the registered public keys, a new DKIM registry contract needs to be deployed for each user. The email-auth contract in `EmailAuth.sol` is a contract for each email user. -Its contract Ethereum address is derived from 1) its initial owner address, 2) an address of a controller contract that can define the supported subject templates and 3) the account salt, i.e., the hash of the user's email address and one account code held by the user, through CREATE2. +Its contract Ethereum address is derived from 1) its initial owner address, 2) an address of a controller contract that can define the supported command templates and 3) the account salt, i.e., the hash of the user's email address and one account code held by the user, through CREATE2. It provides a function `authEmail` to verify the email-auth message by calling the verifier and the DKIM registry contracts. Your application contract can employ those contracts in the following manner: -1. For a new email user, the application contract deploys (a proxy of) the email-auth contract. Subsequently, the application contract sets the addresses of the verifier and the DKIM registry contracts and some subject templates for your application to the email-auth contract. Here, the email-auth contract registers the application contract as a controller contract that has permissions to modify the subject templates. +1. For a new email user, the application contract deploys (a proxy of) the email-auth contract. Subsequently, the application contract sets the addresses of the verifier and the DKIM registry contracts and some command templates for your application to the email-auth contract. Here, the email-auth contract registers the application contract as a controller contract that has permissions to modify the command templates. 2. Given a new email-auth message from the email user, the application contract calls the `authEmail` function in the email-auth contract for that user. If it returns no error, the application contract can execute any processes based on the message in the email-auth message. For detailed setup instructions, see [here](./packages/contracts/README.md). @@ -108,7 +111,7 @@ Our SDK only performs the verification of the email-auth message. Here, we present a list of security notes that you should check. - As described in the Subsection of "Invitation Code", for each email user, your application contract must ensure that the value of `isCodeExist` in the first email-auth message is true. -- The application contract can configure multiple subject templates for the same email-auth contract. However, the Relayer can choose any of the configured templates, as long as the message in the Subject matches with the chosen template. For example, if there are two templates "Send {decimals} {string}" and "Send {string}", the message "Send 1.23 ETH" matches with both templates. We recommend defining the subject templates without such ambiguities. +- The application contract can configure multiple command templates for the same email-auth contract. However, the Relayer can choose any of the configured templates, as long as the message in the command matches with the chosen template. For example, if there are two templates "Send {decimals} {string}" and "Send {string}", the message "Send 1.23 ETH" matches with both templates. We recommend defining the command templates without such ambiguities. - To protect the privacy of the users' email addresses, you should carefully design not only the contracts but also the Relayer server, which stores the users' account codes. For example, an adversary can breach that privacy by exploiting an API provided by the Relayer that returns the Ethereum address for the given email address and its stored account code. Additionally, if any Relayer's API returns an error when no account code is stored for the given email address, the adversary can learn which email addresses are registered. ## Application: Email-based Account Recovery @@ -147,16 +150,16 @@ Our SDK cannot ensure security and privacy in the entire process without your ca Specifically, you can integrate the email-based account recovery into your smart accounts in the following steps. 1. (Contracts 1/6) First, you build a new controller contract with imports of the `EmailAccountRecovery` abstract contract in `EmailAccountRecovery.sol`. Your Solidity compiler will require you to implement the following seven functions: `isActivated`, -`acceptanceSubjectTemplates`, `recoverySubjectTemplates`, `extractRecoveredAccountFromAcceptanceSubject`, `extractRecoveredAccountFromRecoverySubject`, `acceptGuardian`, `processRecovery`, and `completeRecovery`. -2. (Contracts 2/6) You define expected subject templates for two types of emails sent from guardians, one for accepting the role of the guardian, and the other for confirming the account recovery. You can implement the former and latter subject templates in the `acceptanceSubjectTemplates` and `recoverySubjectTemplates` functions, respectively. This is an example of the subject templates: - - Template in `acceptanceSubjectTemplates`: `"Accept guardian request for {ethAddr}"`, where the value of `"{ethAddr}"` represents the account address. - - Template in `recoverySubjectTemplates`: `"Set the new signer of {ethAddr} to {ethAddr}"`, where the values of the first and second `"{ethAddr}"`, respectively, represent the account address and the new owner address. -3. (Contracts 3/6) You also define how to extract an account address to be recovered from the subject parameters for the templates in `acceptanceSubjectTemplates` and `recoverySubjectTemplates`, respectively. +`acceptanceCommandTemplates`, `recoveryCommandTemplates`, `extractRecoveredAccountFromAcceptanceCommand`, `extractRecoveredAccountFromRecoveryCommand`, `acceptGuardian`, `processRecovery`, and `completeRecovery`. +2. (Contracts 2/6) You define expected command templates for two types of emails sent from guardians, one for accepting the role of the guardian, and the other for confirming the account recovery. You can implement the former and latter command templates in the `acceptanceCommandTemplates` and `recoveryCommandTemplates` functions, respectively. This is an example of the command templates: + - Template in `acceptanceCommandTemplates`: `"Accept guardian request for {ethAddr}"`, where the value of `"{ethAddr}"` represents the account address. + - Template in `recoveryCommandTemplates`: `"Set the new signer of {ethAddr} to {ethAddr}"`, where the values of the first and second `"{ethAddr}"`, respectively, represent the account address and the new owner address. +3. (Contracts 3/6) You also define how to extract an account address to be recovered from the command parameters for the templates in `acceptanceCommandTemplates` and `recoveryCommandTemplates`, respectively. 3. (Contracts 4/6) Before implementing the remaining functions in `EmailAccountRecovery`, you implement a requesting function into the controller that allows the account owner to request a guardian, which is expected to be called by the account owner directly. Our SDK **does not** specify any interface or implementation of this function. For example, the function can simply take as input a new guardian's email-auth contract address computed by CREATE2, and store it as a guardian candidate. If you want to set a timelock for each guardian, the requesting function can additionally take the timelock length as input. -4. (Contracts 5/6) You implement the `acceptGuardian` and `processRecovery` functions into the controller. These two functions are, respectively, called by the controller itself after verifying the email-auth messages for accepting a guardian and processing a recovery. Each of them takes as input the guardian's email-auth contract address, an index of the chosen subject template, the values for the variable parts of the message in the Subject, and the email nullifier. You can assume these arguments are already verified. For example, the `acceptGuardian` function stores the given guardian's address as the confirmed guardian, and the `processRecovery` function stores the given new owner's address or sets a timelock. +4. (Contracts 5/6) You implement the `acceptGuardian` and `processRecovery` functions into the controller. These two functions are, respectively, called by the controller itself after verifying the email-auth messages for accepting a guardian and processing a recovery. Each of them takes as input the guardian's email-auth contract address, an index of the chosen command template, the values for the variable parts of the message in the command, and the email nullifier. You can assume these arguments are already verified. For example, the `acceptGuardian` function stores the given guardian's address as the confirmed guardian, and the `processRecovery` function stores the given new owner's address or sets a timelock. 5. (Contracts 6/6) You finally implement the `completeRecovery` function into the controller. It should rotate the owner's address in the smart account if some required conditions hold. This function can be called by anyone, but is assumed to be called by the Relayer and can take as input arbitrary bytes. -6. (Frontend 1/3) Next, you build a frontend for the account recovery. You prepare a page where the account owner configures guardians. It requests the account owner to input the account address (`account_eth_addr`) and the guardian's email address (`guardian_email_addr`), generates a random account code (`account_code`), constructs an expected subject (`subject`) for the subject template whose index is `template_idx` in the output of the `acceptanceSubjectTemplates()` function. It then requests the account owner to call the requesting function in the controller contract. After that, it calls the Relayer's `acceptanceRequest` API with `guardian_email_addr`, `account_code`, `template_idx`, and the address of the controller contract `controller_eth_addr`. -7. (Frontend 2/3) You also prepare a page where the account owner requests guardians to recover the account. It requests the account owner to input the account address (`account_eth_addr`) and the guardian's email address (`guardian_email_addr`), and constructs an expected subject (`subject`) for the subject template whose index is `template_idx` in the output of the `recoverySubjectTemplates()` function. It calls the Relayer's `recoveryRequest` API with those data and `controller_eth_addr`. +6. (Frontend 1/3) Next, you build a frontend for the account recovery. You prepare a page where the account owner configures guardians. It requests the account owner to input the account address (`account_eth_addr`) and the guardian's email address (`guardian_email_addr`), generates a random account code (`account_code`), constructs an expected command (`command`) for the command template whose index is `template_idx` in the output of the `acceptanceCommandTemplates()` function. It then requests the account owner to call the requesting function in the controller contract. After that, it calls the Relayer's `acceptanceRequest` API with `guardian_email_addr`, `account_code`, `template_idx`, and the address of the controller contract `controller_eth_addr`. +7. (Frontend 2/3) You also prepare a page where the account owner requests guardians to recover the account. It requests the account owner to input the account address (`account_eth_addr`) and the guardian's email address (`guardian_email_addr`), and constructs an expected command (`command`) for the command template whose index is `template_idx` in the output of the `recoveryCommandTemplates()` function. It calls the Relayer's `recoveryRequest` API with those data and `controller_eth_addr`. 8. (Frontend 3/3) It simulates off-chain if the `completeRecovery` function in the smart account will return no error at regular time intervals. When it stands, the frontend calls the Relayer's `completeRequest` API with sending `account_eth_addr`, `controller_eth_addr`, and a calldata for the `completeRecovery` function `complete_calldata`. We show some important points to implement the email-based account recovery for your smart accounts securely. @@ -166,4 +169,13 @@ We show some important points to implement the email-based account recovery for For detailed implementation, see [docs/getting-started.md](./docs/getting-started.md). -Regarding the contract addresses already deployed on Base Sepolia, see [here](./docs/deployed-contracts.md). \ No newline at end of file +Regarding the contract addresses already deployed on Base Sepolia, see [here](./docs/deployed-contracts.md). + +## Support and Contact + +We prioritize the security and user experience of ZK Email. If you encounter any issues or have questions, please contact us at: + +- **Support Email**: [team@zk.email](mailto:team@zk.email) +- **Telegram groups**: [t.me/zkemail](https://t.me/zkemail) + +Our team will respond quickly to help resolve any problems. \ No newline at end of file diff --git a/Relayer.Dockerfile b/Relayer.Dockerfile index fd362f3b..1dafb15e 100644 --- a/Relayer.Dockerfile +++ b/Relayer.Dockerfile @@ -1,5 +1,5 @@ # Use the base image -FROM bisht13/ar-relayer-base:latest +FROM bisht13/relayer-base # Copy the project files COPY packages/relayer /relayer/packages/relayer @@ -14,4 +14,4 @@ RUN cargo build EXPOSE 4500 # Set the default command -CMD ["cargo", "run"] \ No newline at end of file +CMD ["cargo", "run"] diff --git a/docs/upgrade.md b/docs/upgrade.md new file mode 100644 index 00000000..66f82ca2 --- /dev/null +++ b/docs/upgrade.md @@ -0,0 +1,43 @@ +# Upgrading Contracts + +Sometimes, we need to fix problems in our smart contracts. We can do this by upgrading contracts that use ERC1967Proxy. Here's how to do it: + +## Upgrading the Verifier + +1. Change the code in this file: + `packages/contracts/src/utils/Verifier.sol` + +2. Add this to your `.env` file: + ``` + VERIFIER={DEPLOYED_VERIFIER_PROXY_ADDRESS} + ``` + +3. Run this command: + ``` + source .env + forge script script/Upgrades.s.sol:Upgrades --rpc-url $RPC_URL --chain-id $CHAIN_ID --etherscan-api-key $ETHERSCAN_API_KEY --broadcast --verify -vvvv + ``` + +## Upgrading Other Contracts + +You can also upgrade ECDSAOwnedDKIMRegistry and UserOverrideableDKIMRegistry: + +### For ECDSAOwnedDKIMRegistry: +1. Change the code in: + `packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol` + +2. Add to `.env`: + ``` + ECDSA_DKIM={DEPLOYED_ECDSA_DKIM_PROXY_ADDRESS} + ``` + +### For UserOverrideableDKIMRegistry: +1. Change the code in: + `@zk-email/contracts/UserOverrideableDKIMRegistry.sol` + +2. Add to `.env`: + ``` + DKIM={DEPLOYED_USEROVERRIDEABLE_DKIM_PROXY_ADDRESS} + ``` + +Remember to be careful when changing these contracts. Always test your changes before using them. diff --git a/infrastructure/README.md b/infrastructure/README.md new file mode 100644 index 00000000..e62de821 --- /dev/null +++ b/infrastructure/README.md @@ -0,0 +1,42 @@ + +# Infrastructure Management Scripts + +This document provides instructions on how to use the provided scripts to apply metrics and alerts to your Google Cloud Platform (GCP) environment. + +## Prerequisites + +- Ensure you have the [Google Cloud SDK](https://cloud.google.com/sdk) installed and authenticated. +- Make sure `jq` is installed for JSON processing. + +## Applying Metrics + +To apply a specific metric from a JSON file, use the `apply_metric.sh` script. This script reads the metric configuration from the specified JSON file and applies it to your GCP project. + +### Usage + +```bash +cd /path/to/your/project/infrastructure/metrics +./apply_metric.sh metric_file.json +``` + +- Replace `/path/to/your/project` with the root directory of your project. +- Replace `metric_file.json` with the path to the metric JSON file in the metrics directory. + +## Applying Alerts + +To apply a specific alert policy from a JSON file, use the `apply_alert.sh` script. This script reads the alert policy configuration from the specified JSON file and applies it to your GCP project. + +### Usage + +```bash +cd /path/to/your/project/infrastructure/alerts +./apply_alert.sh alert_file.json +``` + +- Replace `/path/to/your/project` with the root directory of your project. +- Replace `alert_file.json` with the path to your alert policy JSON file in the alerts directory. + +## Additional Notes + +- Ensure that you have the necessary permissions to apply metrics and alerts in your GCP project. +- If you encounter any errors, refer to the script logs for more details. diff --git a/infrastructure/alerts/Uptime_Check_for_AR_Relayer_(Base_Sepolia).json b/infrastructure/alerts/Uptime_Check_for_AR_Relayer_(Base_Sepolia).json new file mode 100644 index 00000000..337ff318 --- /dev/null +++ b/infrastructure/alerts/Uptime_Check_for_AR_Relayer_(Base_Sepolia).json @@ -0,0 +1,46 @@ +{ + "alertStrategy": { + "autoClose": "604800s", + "notificationPrompts": [ + "OPENED" + ] + }, + "combiner": "OR", + "conditions": [ + { + "conditionThreshold": { + "aggregations": [ + { + "alignmentPeriod": "300s", + "perSeriesAligner": "ALIGN_FRACTION_TRUE" + } + ], + "comparison": "COMPARISON_LT", + "duration": "0s", + "filter": "resource.type = \"uptime_url\" AND resource.labels.host = \"auth-base-sepolia-staging.prove.email\" AND metric.type = \"monitoring.googleapis.com/uptime_check/check_passed\"", + "thresholdValue": 0.9, + "trigger": { + "count": 1 + } + }, + "displayName": "Uptime Check URL - Check passed", + "name": "projects/zkairdrop/alertPolicies/14540598362673761778/conditions/9717783705450711541" + } + ], + "displayName": "Uptime Check for AR Relayer (Base Sepolia)", + "documentation": { + "content": "Uptime check failed for account recovery relayer (Base Sepolia).", + "mimeType": "text/markdown", + "subject": "Uptime Check Failed for AR Base Sepolia Relayer" + }, + "enabled": true, + "name": "projects/zkairdrop/alertPolicies/14540598362673761778", + "notificationChannels": [ + "projects/zkairdrop/notificationChannels/8151570453739639273", + "projects/zkairdrop/notificationChannels/7073288447352854381", + "projects/zkairdrop/notificationChannels/2385336445405127098", + "projects/zkairdrop/notificationChannels/17871058532858569683", + "projects/zkairdrop/notificationChannels/13717630568524701111" + ], + "severity": "WARNING" +} \ No newline at end of file diff --git a/infrastructure/alerts/Uptime_Check_for_AR_Relayer_(ZKsync_Sepolia).json b/infrastructure/alerts/Uptime_Check_for_AR_Relayer_(ZKsync_Sepolia).json new file mode 100644 index 00000000..387e43c5 --- /dev/null +++ b/infrastructure/alerts/Uptime_Check_for_AR_Relayer_(ZKsync_Sepolia).json @@ -0,0 +1,46 @@ +{ + "alertStrategy": { + "autoClose": "604800s", + "notificationPrompts": [ + "OPENED" + ] + }, + "combiner": "OR", + "conditions": [ + { + "conditionThreshold": { + "aggregations": [ + { + "alignmentPeriod": "300s", + "perSeriesAligner": "ALIGN_FRACTION_TRUE" + } + ], + "comparison": "COMPARISON_LT", + "duration": "0s", + "filter": "resource.type = \"uptime_url\" AND resource.labels.host = \"auth-zksync-sepolia-staging.prove.email\" AND metric.type = \"monitoring.googleapis.com/uptime_check/check_passed\"", + "thresholdValue": 0.9, + "trigger": { + "count": 1 + } + }, + "displayName": "Uptime Check URL - Check passed", + "name": "projects/zkairdrop/alertPolicies/1785328578980889069/conditions/12793827239849115908" + } + ], + "displayName": "Uptime Check for AR Relayer (ZKsync Sepolia)", + "documentation": { + "content": "Uptime check failed for account recovery relayer (ZKsync Sepolia).", + "mimeType": "text/markdown", + "subject": "Uptime Check Failed for AR ZKsync Sepolia Relayer" + }, + "enabled": true, + "name": "projects/zkairdrop/alertPolicies/1785328578980889069", + "notificationChannels": [ + "projects/zkairdrop/notificationChannels/13717630568524701111", + "projects/zkairdrop/notificationChannels/17871058532858569683", + "projects/zkairdrop/notificationChannels/2385336445405127098", + "projects/zkairdrop/notificationChannels/7073288447352854381", + "projects/zkairdrop/notificationChannels/8151570453739639273" + ], + "severity": "WARNING" +} \ No newline at end of file diff --git a/infrastructure/alerts/Uptime_Check_for_Email_Wallet_Relayer.json b/infrastructure/alerts/Uptime_Check_for_Email_Wallet_Relayer.json new file mode 100644 index 00000000..1b9974cc --- /dev/null +++ b/infrastructure/alerts/Uptime_Check_for_Email_Wallet_Relayer.json @@ -0,0 +1,46 @@ +{ + "alertStrategy": { + "autoClose": "604800s", + "notificationPrompts": [ + "OPENED" + ] + }, + "combiner": "OR", + "conditions": [ + { + "conditionThreshold": { + "aggregations": [ + { + "alignmentPeriod": "300s", + "perSeriesAligner": "ALIGN_FRACTION_TRUE" + } + ], + "comparison": "COMPARISON_LT", + "duration": "0s", + "filter": "resource.type = \"uptime_url\" AND resource.labels.host = \"relayerapi.emailwallet.org\" AND metric.type = \"monitoring.googleapis.com/uptime_check/check_passed\"", + "thresholdValue": 0.9, + "trigger": { + "count": 1 + } + }, + "displayName": "Uptime Check URL - Check passed", + "name": "projects/zkairdrop/alertPolicies/8542470102587481494/conditions/1395222843874964873" + } + ], + "displayName": "Uptime Check for Email Wallet Relayer", + "documentation": { + "content": "Uptime check failed for email wallet relayer.", + "mimeType": "text/markdown", + "subject": "Uptime Check Failed for Email Wallet" + }, + "enabled": true, + "name": "projects/zkairdrop/alertPolicies/8542470102587481494", + "notificationChannels": [ + "projects/zkairdrop/notificationChannels/13717630568524701111", + "projects/zkairdrop/notificationChannels/2385336445405127098", + "projects/zkairdrop/notificationChannels/7073288447352854381", + "projects/zkairdrop/notificationChannels/8151570453739639273", + "projects/zkairdrop/notificationChannels/17871058532858569683" + ], + "severity": "WARNING" +} \ No newline at end of file diff --git a/infrastructure/alerts/apply_alert.sh b/infrastructure/alerts/apply_alert.sh new file mode 100755 index 00000000..6b5002fe --- /dev/null +++ b/infrastructure/alerts/apply_alert.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# Check if a file name is provided +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +FILE_NAME=$1 + +# Check if the file exists +if [ ! -f "$FILE_NAME" ]; then + echo "Error: File '$FILE_NAME' does not exist." + exit 1 +fi + +# Extract the display name from the JSON file +DISPLAY_NAME=$(jq -r '.displayName' "$FILE_NAME") + +# Create the alert policy using gcloud +gcloud alpha monitoring policies create --policy-from-file="$FILE_NAME" + +# Check if gcloud was successful +if [ $? -eq 0 ]; then + echo "Alert policy '$DISPLAY_NAME' applied successfully." +else + echo "Error applying alert policy '$DISPLAY_NAME'." + exit 1 +fi \ No newline at end of file diff --git a/infrastructure/alerts/logging_user_error-from-prover_[SUM].json b/infrastructure/alerts/logging_user_error-from-prover_[SUM].json new file mode 100644 index 00000000..33992920 --- /dev/null +++ b/infrastructure/alerts/logging_user_error-from-prover_[SUM].json @@ -0,0 +1,40 @@ +{ + "alertStrategy": { + "autoClose": "1800s", + "notificationPrompts": [ + "OPENED", + "CLOSED" + ] + }, + "combiner": "OR", + "conditions": [ + { + "conditionThreshold": { + "aggregations": [ + { + "alignmentPeriod": "60s", + "crossSeriesReducer": "REDUCE_SUM", + "perSeriesAligner": "ALIGN_COUNT" + } + ], + "comparison": "COMPARISON_GT", + "duration": "0s", + "filter": "metric.type=\"logging.googleapis.com/user/error-from-prover\" AND resource.type=\"k8s_container\"", + "trigger": { + "count": 1 + } + }, + "displayName": "logging/user/error-from-prover [SUM]" + } + ], + "displayName": "logging/user/error-from-prover [SUM]", + "documentation": { + "content": "This error happens when the prover get some error", + "mimeType": "text/markdown" + }, + "enabled": true, + "notificationChannels": [ + "projects/zkairdrop/notificationChannels/16929435408944174030" + ], + "severity": "ERROR" +} \ No newline at end of file diff --git a/infrastructure/alerts/logging_user_error-handling-email-event_[SUM].json b/infrastructure/alerts/logging_user_error-handling-email-event_[SUM].json new file mode 100644 index 00000000..5eb0067f --- /dev/null +++ b/infrastructure/alerts/logging_user_error-handling-email-event_[SUM].json @@ -0,0 +1,41 @@ +{ + "alertStrategy": { + "autoClose": "1800s", + "notificationPrompts": [ + "OPENED", + "CLOSED" + ] + }, + "combiner": "OR", + "conditions": [ + { + "conditionThreshold": { + "aggregations": [ + { + "alignmentPeriod": "60s", + "crossSeriesReducer": "REDUCE_SUM", + "perSeriesAligner": "ALIGN_COUNT" + } + ], + "comparison": "COMPARISON_GT", + "duration": "0s", + "filter": "resource.type = \"k8s_container\" AND metric.type = \"logging.googleapis.com/user/error-handling-email-event\" AND resource.type=\"k8s_container\"", + "trigger": { + "count": 1 + } + }, + "displayName": "logging/user/error-handling-email-event [SUM]" + } + ], + "displayName": "logging/user/error-handling-email-event [SUM]", + "documentation": { + "content": "This error happens when the relayer get in trouble about sending mail", + "mimeType": "text/markdown", + "subject": "error-handling-email-event" + }, + "enabled": true, + "notificationChannels": [ + "projects/zkairdrop/notificationChannels/16929435408944174030" + ], + "severity": "WARNING" +} \ No newline at end of file diff --git a/infrastructure/alerts/logging_user_error-handling-email_[SUM].json b/infrastructure/alerts/logging_user_error-handling-email_[SUM].json new file mode 100644 index 00000000..8434fd60 --- /dev/null +++ b/infrastructure/alerts/logging_user_error-handling-email_[SUM].json @@ -0,0 +1,41 @@ +{ + "alertStrategy": { + "autoClose": "1800s", + "notificationPrompts": [ + "OPENED", + "CLOSED" + ] + }, + "combiner": "OR", + "conditions": [ + { + "conditionThreshold": { + "aggregations": [ + { + "alignmentPeriod": "60s", + "crossSeriesReducer": "REDUCE_SUM", + "perSeriesAligner": "ALIGN_COUNT" + } + ], + "comparison": "COMPARISON_GT", + "duration": "0s", + "filter": "resource.type = \"k8s_container\" AND metric.type = \"logging.googleapis.com/user/error-handling-email\" AND resource.type=\"k8s_container\"", + "trigger": { + "count": 1 + } + }, + "displayName": "logging/user/error-handling-email [SUM]" + } + ], + "displayName": "logging/user/error-handling-email [SUM]", + "documentation": { + "content": "This error happens when the relayer got the contract call error or the zkregx errors.", + "mimeType": "text/markdown", + "subject": "error-handling-email" + }, + "enabled": true, + "notificationChannels": [ + "projects/zkairdrop/notificationChannels/16929435408944174030" + ], + "severity": "WARNING" +} \ No newline at end of file diff --git a/infrastructure/metrics/apply_metric.sh b/infrastructure/metrics/apply_metric.sh new file mode 100755 index 00000000..d4619a11 --- /dev/null +++ b/infrastructure/metrics/apply_metric.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# Check if a file name is provided +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +FILE_NAME=$1 + +# Check if the file exists +if [ ! -f "$FILE_NAME" ]; then + echo "Error: File '$FILE_NAME' does not exist." + exit 1 +fi + +# Extract the metric name using jq +METRIC_NAME=$(jq -r '.name' "$FILE_NAME") + +# Check if jq was successful +if [ -z "$METRIC_NAME" ]; then + echo "Error: Could not extract metric name from '$FILE_NAME'." + exit 1 +fi + +# Apply the metric using gcloud +gcloud logging metrics create "$METRIC_NAME" --config-from-file="$FILE_NAME" + +# Check if gcloud was successful +if [ $? -eq 0 ]; then + echo "Metric '$METRIC_NAME' applied successfully." +else + echo "Error applying metric '$METRIC_NAME'." + exit 1 +fi \ No newline at end of file diff --git a/infrastructure/metrics/contract-call-reverted-with-data.json b/infrastructure/metrics/contract-call-reverted-with-data.json new file mode 100644 index 00000000..a2f500df --- /dev/null +++ b/infrastructure/metrics/contract-call-reverted-with-data.json @@ -0,0 +1,16 @@ +{ + "createTime": "2024-10-30T08:54:25.988017294Z", + "description": "The error of relayer calling contract in ar-base-sepolia", + "filter": "resource.type=\"k8s_container\"\nresource.labels.container_name=\"relayer-container\"\nresource.labels.namespace_name=\"ar-base-sepolia\"\n\"Contract call reverted with data\"\n", + "metricDescriptor": { + "description": "The error of relayer calling contract in ar-base-sepolia", + "metricKind": "DELTA", + "name": "projects/zkairdrop/metricDescriptors/logging.googleapis.com/user/contract-call-reverted-with-data", + "type": "logging.googleapis.com/user/contract-call-reverted-with-data", + "unit": "1", + "valueType": "INT64" + }, + "name": "contract-call-reverted-with-data", + "resourceName": "projects/zkairdrop/metrics/contract-call-reverted-with-data", + "updateTime": "2024-10-30T08:54:25.988017294Z" +} \ No newline at end of file diff --git a/infrastructure/metrics/error-from-prover.json b/infrastructure/metrics/error-from-prover.json new file mode 100644 index 00000000..4b800bad --- /dev/null +++ b/infrastructure/metrics/error-from-prover.json @@ -0,0 +1,14 @@ +{ + "createTime": "2024-10-30T09:37:19.291096099Z", + "filter": "SEARCH(\"`ether-email-auth-prover`\")\nseverity=ERROR", + "metricDescriptor": { + "metricKind": "DELTA", + "name": "projects/zkairdrop/metricDescriptors/logging.googleapis.com/user/error-from-prover", + "type": "logging.googleapis.com/user/error-from-prover", + "unit": "1", + "valueType": "INT64" + }, + "name": "error-from-prover", + "resourceName": "projects/zkairdrop/metrics/error-from-prover", + "updateTime": "2024-10-30T09:37:19.291096099Z" +} \ No newline at end of file diff --git a/infrastructure/metrics/error-handling-email-event.json b/infrastructure/metrics/error-handling-email-event.json new file mode 100644 index 00000000..7b0cedd2 --- /dev/null +++ b/infrastructure/metrics/error-handling-email-event.json @@ -0,0 +1,14 @@ +{ + "createTime": "2024-10-30T09:19:28.911872031Z", + "filter": "resource.type=\"k8s_container\"\nresource.labels.container_name=\"relayer-container\"\nresource.labels.namespace_name=\"ar-base-sepolia\"\n\"Error handling email event:\"\n", + "metricDescriptor": { + "metricKind": "DELTA", + "name": "projects/zkairdrop/metricDescriptors/logging.googleapis.com/user/error-handling-email-event", + "type": "logging.googleapis.com/user/error-handling-email-event", + "unit": "1", + "valueType": "INT64" + }, + "name": "error-handling-email-event", + "resourceName": "projects/zkairdrop/metrics/error-handling-email-event", + "updateTime": "2024-10-30T09:19:28.911872031Z" +} \ No newline at end of file diff --git a/infrastructure/metrics/error-handling-email.json b/infrastructure/metrics/error-handling-email.json new file mode 100644 index 00000000..53b73e58 --- /dev/null +++ b/infrastructure/metrics/error-handling-email.json @@ -0,0 +1,14 @@ +{ + "createTime": "2024-10-30T09:14:37.273651500Z", + "filter": "resource.type=\"k8s_container\"\nresource.labels.container_name=\"relayer-container\"\nresource.labels.namespace_name=\"ar-base-sepolia\"\n\"Error handling email:\"\n", + "metricDescriptor": { + "metricKind": "DELTA", + "name": "projects/zkairdrop/metricDescriptors/logging.googleapis.com/user/error-handling-email", + "type": "logging.googleapis.com/user/error-handling-email", + "unit": "1", + "valueType": "INT64" + }, + "name": "error-handling-email", + "resourceName": "projects/zkairdrop/metrics/error-handling-email", + "updateTime": "2024-10-30T09:14:37.273651500Z" +} \ No newline at end of file diff --git a/kubernetes/cloudbuild-base.yml b/kubernetes/cloudbuild-base.yml new file mode 100644 index 00000000..0bd58620 --- /dev/null +++ b/kubernetes/cloudbuild-base.yml @@ -0,0 +1,19 @@ +steps: + # Build the base container image + - name: 'gcr.io/cloud-builders/docker' + args: + [ + 'build', + '-t', + 'us-central1-docker.pkg.dev/zkairdrop/ether-email-auth/relayer-base:v1', + '-f', + 'Base.Dockerfile', + '.', + ] + # Push the base container image to Artifact Registry + - name: 'gcr.io/cloud-builders/docker' + args: + [ + 'push', + 'us-central1-docker.pkg.dev/zkairdrop/ether-email-auth/relayer-base:v1', + ] diff --git a/kubernetes/cloudbuild-relayer.yml b/kubernetes/cloudbuild-relayer.yml new file mode 100644 index 00000000..baab474d --- /dev/null +++ b/kubernetes/cloudbuild-relayer.yml @@ -0,0 +1,21 @@ +options: + machineType: 'N1_HIGHCPU_32' +steps: + # Build the base container image + - name: 'gcr.io/cloud-builders/docker' + args: + [ + 'build', + '-t', + 'us-central1-docker.pkg.dev/zkairdrop/ether-email-auth/relayer:v2', + '-f', + 'Relayer.Dockerfile', + '.', + ] + # Push the base container image to Artifact Registry + - name: 'gcr.io/cloud-builders/docker' + args: + [ + 'push', + 'us-central1-docker.pkg.dev/zkairdrop/ether-email-auth/relayer:v2', + ] diff --git a/kubernetes/cronjob.yml b/kubernetes/cronjob.yml new file mode 100644 index 00000000..94af6abd --- /dev/null +++ b/kubernetes/cronjob.yml @@ -0,0 +1,51 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: cronjob-service-account + namespace: ar-base-sepolia +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + namespace: ar-base-sepolia + name: deployment-restart-role +rules: + - apiGroups: ["apps", "extensions"] + resources: ["deployments"] + verbs: ["get", "list", "watch", "update", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: deployment-restart-rolebinding + namespace: ar-base-sepolia +subjects: + - kind: ServiceAccount + name: cronjob-service-account + namespace: ar-base-sepolia +roleRef: + kind: Role + name: deployment-restart-role + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: restart-deployment + namespace: ar-base-sepolia +spec: + schedule: "0 * * * *" + jobTemplate: + spec: + template: + spec: + serviceAccountName: cronjob-service-account + containers: + - name: kubectl + image: bitnami/kubectl:latest + command: + - /bin/sh + - -c + - | + kubectl rollout restart deployment relayer-email-auth --namespace ar-base-sepolia + restartPolicy: OnFailure diff --git a/kubernetes/relayer.staging.yml b/kubernetes/relayer.staging.yml new file mode 100644 index 00000000..5e2916cc --- /dev/null +++ b/kubernetes/relayer.staging.yml @@ -0,0 +1,163 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: relayer-config-email-auth + namespace: ar-base-sepolia-staging + labels: + app: relayer +data: + EMAIL_ACCOUNT_RECOVERY_VERSION_ID: "" + CHAIN_RPC_PROVIDER: "" + CHAIN_RPC_EXPLORER: "" + CHAIN_ID: "" + WEB_SERVER_ADDRESS: "" + REGEX_JSON_DIR_PATH: "" + EMAIL_TEMPLATES_PATH: "" + CANISTER_ID: "" + IC_REPLICA_URL: "" + JSON_LOGGER: "" + PEM_PATH: "" + SMTP_SERVER: "" + +--- +apiVersion: v1 +kind: Secret +metadata: + name: relayer-secret-email-auth + namespace: ar-base-sepolia-staging + labels: + app: relayer +type: Opaque +data: + PRIVATE_KEY: + DATABASE_URL: + PROVER_ADDRESS: + ICPEM: + ERROR_EMAIL_ADDR: +--- +apiVersion: v1 +kind: Secret +metadata: + name: relayer-smtp-secret + namespace: ar-base-sepolia-staging + labels: + app: relayer +type: Opaque +data: + SMTP_LOGIN_ID: + SMTP_LOGIN_PASSWORD: + SMTP_DOMAIN_NAME: + SERVER_HOST: + SERVER_PORT: + JSON_LOGGER: + +--- +apiVersion: v1 +kind: Secret +metadata: + name: relayer-imap-secret + namespace: ar-base-sepolia-staging + labels: + app: relayer +type: Opaque +data: + RELAYER_ENDPOINT: + IMAP_LOGIN_ID: + IMAP_LOGIN_PASSWORD: + IMAP_PORT: + IMAP_DOMAIN_NAME: + SERVER_HOST: + AUTH_TYPE: + JSON_LOGGER: + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: relayer-email-auth + namespace: ar-base-sepolia-staging + labels: + app: relayer +spec: + selector: + matchLabels: + app: relayer + template: + metadata: + labels: + app: relayer + spec: + containers: + - name: relayer-container + image: us-central1-docker.pkg.dev/zkairdrop/ether-email-auth/relayer:v2 + ports: + - containerPort: 4500 + envFrom: + - configMapRef: + name: relayer-config-email-auth + - secretRef: + name: relayer-secret-email-auth + livenessProbe: + httpGet: + path: /api/echo + port: 4500 + initialDelaySeconds: 60 + periodSeconds: 30 + readinessProbe: + httpGet: + path: /api/echo + port: 4500 + initialDelaySeconds: 60 + periodSeconds: 30 + volumeMounts: + - name: pem-volume + mountPath: "/relayer/packages/relayer/.ic.pem" + subPath: ".ic.pem" + - name: smtp-container + image: bisht13/relayer-smtp-new:latest + ports: + - containerPort: 8080 + envFrom: + - secretRef: + name: relayer-smtp-secret + - name: imap-container + image: bisht13/relayer-imap-new:latest + envFrom: + - secretRef: + name: relayer-imap-secret + volumes: + - name: pem-volume + secret: + secretName: relayer-secret-email-auth + items: + - key: ICPEM + path: ".ic.pem" +--- +apiVersion: v1 +kind: Service +metadata: + name: relayer-svc-email-auth + namespace: ar-base-sepolia-staging +spec: + selector: + app: relayer + ports: + - protocol: TCP + port: 443 + targetPort: 4500 + type: ClusterIP + +--- +apiVersion: v1 +kind: Service +metadata: + name: relayer-smtp-svc + namespace: ar-base-sepolia-staging +spec: + selector: + app: relayer + ports: + - protocol: TCP + port: 443 + targetPort: 8080 + type: ClusterIP diff --git a/kubernetes/relayer.yml b/kubernetes/relayer.yml index 4a5b6448..e0f54ec5 100644 --- a/kubernetes/relayer.yml +++ b/kubernetes/relayer.yml @@ -11,12 +11,13 @@ data: CHAIN_RPC_EXPLORER: "" CHAIN_ID: "" WEB_SERVER_ADDRESS: "" - CIRCUITS_DIR_PATH: "" + REGEX_JSON_DIR_PATH: "" EMAIL_TEMPLATES_PATH: "" CANISTER_ID: "" IC_REPLICA_URL: "" JSON_LOGGER: "" PEM_PATH: "" + SMTP_SERVER: "" --- apiVersion: v1 @@ -30,15 +31,9 @@ type: Opaque data: PRIVATE_KEY: DATABASE_URL: - IMAP_DOMAIN_NAME: - IMAP_PORT: - AUTH_TYPE: - SMTP_DOMAIN_NAME: - LOGIN_ID: - LOGIN_PASSWORD: PROVER_ADDRESS: ICPEM: - + ERROR_EMAIL_ADDR: --- apiVersion: v1 kind: Secret @@ -94,14 +89,14 @@ spec: spec: containers: - name: relayer-container - image: bisht13/relayer-new-0:latest + image: bisht13/ar-relayer-base-3:latest ports: - containerPort: 4500 envFrom: - configMapRef: - name: relayer-config + name: relayer-config-email-auth - secretRef: - name: relayer-secret + name: relayer-secret-email-auth livenessProbe: httpGet: path: /api/echo @@ -119,7 +114,7 @@ spec: mountPath: "/relayer/packages/relayer/.ic.pem" subPath: ".ic.pem" - name: smtp-container - image: bisht13/relayer-smtp-new:latest + image: bisht13/relayer-smtp:latest ports: - containerPort: 8080 envFrom: @@ -131,12 +126,6 @@ spec: - secretRef: name: relayer-imap-secret volumes: - - name: pem-volume - secret: - secretName: relayer-secret - items: - - key: ICPEM - path: ".ic.pem" - name: pem-volume secret: secretName: relayer-secret-email-auth @@ -144,6 +133,30 @@ spec: - key: ICPEM path: ".ic.pem" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: relayer-imap + namespace: ar-base-sepolia + labels: + app: relayer +spec: + selector: + matchLabels: + app: relayer-imap + template: + metadata: + labels: + app: relayer-imap + spec: + containers: + - name: imap-container + image: bisht13/relayer-imap-new:latest + envFrom: + - secretRef: + name: relayer-imap-secret + --- apiVersion: v1 kind: Service diff --git a/libs/rapidsnark.Dockerfile b/libs/rapidsnark.Dockerfile deleted file mode 100644 index b1c3f656..00000000 --- a/libs/rapidsnark.Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ - -FROM ubuntu:20.04 - -ARG DEBIAN_FRONTEND=noninteractive - -# Install Node.js, Yarn and required dependencies -RUN apt-get update \ - && apt-get install -y curl git gnupg build-essential cmake libgmp-dev libsodium-dev nasm \ - && curl --silent --location https://deb.nodesource.com/setup_12.x | bash - \ - && apt-get install -y nodejs - -RUN git clone https://github.com/iden3/rapidsnark.git /rapidsnark -WORKDIR /rapidsnark -RUN npm install -RUN git submodule init -RUN git submodule update -RUN npx task createFieldSources -RUN npx task buildPistache -RUN apt-get install -y -RUN npx task buildProver - -ENTRYPOINT ["/rapidsnark/build/prover"] diff --git a/package.json b/package.json index 360cdbb4..bf833b3a 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "version": "1.0.0", "description": "Smart contracts to auth messages via emails", "engines": { - "node": "18" + "node": ">=18" }, "scripts": { "test": "yarn workspaces -pt run test", @@ -41,4 +41,4 @@ ] ] } -} \ No newline at end of file +} diff --git a/packages/circuits/README.md b/packages/circuits/README.md index 74f58d13..f76f3ac0 100644 --- a/packages/circuits/README.md +++ b/packages/circuits/README.md @@ -60,6 +60,14 @@ The `email_auth.circom` makes constraints and computes the public output as foll 12. Let `embedded_code` be an integer parsing `code_str` as a hex string. 13. If `is_code_exist` is 1, assert that `embedded_code` is equal to `account_code`. 14. Let `account_salt` be `PoseidonHash(from_addr|0..0, account_code, 0)`. -15. Let `masked_subject` be a string that removes `code_str`, the prefix of the invitation code, and one email address from `subject`, if they appear in `subject`. +15. Let `masked_subject` be a string that removes the invitation code with the prefix `code_str` and one email address from `subject`, if they appear in `subject`. -Note that the email address in the subject is assumbed not to overlap with the invitation code. \ No newline at end of file +Note that the email address in the subject is assumbed not to overlap with the invitation code. + + +#### `email_auth_with_body_parsing_with_qp_encoding.circom` +A circuit to verify that a message in the email body, called command, is authorized by a user of an account salt, derived from an email address in the From field and a random field value called account code. +This is basically the same as the `email_auth.circom` described above except for the following features: +- Instead of `subject_idx`, it additionally takes as a private input a padded email body `padded_cleaned_body` and an index of the command in the email body `command_idx`. +- It extracts a substring `command` between a prefix `(
]*>)"` and a suffix `
` from `padded_cleaned_body`. +- It outputs `masked_command` instead of `masked_subject`, which removes the invitation code with the prefix and one email address from `command`. \ No newline at end of file diff --git a/packages/circuits/helpers/email_auth.ts b/packages/circuits/helpers/email_auth.ts index 55db6762..4103af76 100644 --- a/packages/circuits/helpers/email_auth.ts +++ b/packages/circuits/helpers/email_auth.ts @@ -2,22 +2,38 @@ import fs from "fs"; import { promisify } from "util"; const relayerUtils = require("@zk-email/relayer-utils"); -export async function genEmailAuthInput( - emailFilePath: string, - accountCode: string +export async function genEmailCircuitInput( + emailFilePath: string, + accountCode: string, + options?: { + shaPrecomputeSelector?: string; + maxHeaderLength?: number; + maxBodyLength?: number; + ignoreBodyHashCheck?: boolean; + } ): Promise<{ - padded_header: string[]; - public_key: string[]; - signature: string[]; - padded_header_len: string; - account_code: string; - from_addr_idx: number; - subject_idx: number; - domain_idx: number; - timestamp_idx: number; - code_idx: number; + padded_header: string[]; + public_key: string[]; + signature: string[]; + padded_header_len: string; + account_code: string; + from_addr_idx: number; + subject_idx: number; + domain_idx: number; + timestamp_idx: number; + code_idx: number; + body_hash_idx: number; + precomputed_sha: string[]; + padded_body: string[]; + padded_body_len: string; + command_idx: number; + padded_cleaned_body: string[]; }> { - const emailRaw = await promisify(fs.readFile)(emailFilePath, "utf8"); - const jsonStr = await relayerUtils.genEmailAuthInput(emailRaw, accountCode); - return JSON.parse(jsonStr); + const emailRaw = await promisify(fs.readFile)(emailFilePath, "utf8"); + const jsonStr = await relayerUtils.genEmailCircuitInput( + emailRaw, + accountCode, + options + ); + return JSON.parse(jsonStr); } diff --git a/packages/circuits/helpers/recipient.ts b/packages/circuits/helpers/recipient.ts index 2ec2f9d8..cb2c78fb 100644 --- a/packages/circuits/helpers/recipient.ts +++ b/packages/circuits/helpers/recipient.ts @@ -1,8 +1,9 @@ import fs from "fs"; import { promisify } from "util"; +import path from "path"; const relayerUtils = require("@zk-email/relayer-utils"); -export async function genRecipientInput(emailFilePath: string): Promise<{ +export async function genRecipientInputLegacy(emailFilePath: string): Promise<{ subject_email_addr_idx: number; rand: string; }> { @@ -28,3 +29,20 @@ export async function genRecipientInput(emailFilePath: string): Promise<{ rand: rand, }; } + +export async function genRecipientInput(command: string, signature: string): Promise<{ + command_email_addr_idx: number; + rand: string; +}> { + let commandEmailAddrIdx = 0; + try { + commandEmailAddrIdx = relayerUtils.extractEmailAddrIdxes(command)[0][0]; + } catch (e) { + console.log("No email address in command"); + } + const rand = relayerUtils.extractRandFromSignature(signature); + return { + command_email_addr_idx: commandEmailAddrIdx, + rand: rand, + }; +} \ No newline at end of file diff --git a/packages/circuits/package.json b/packages/circuits/package.json index 99f7d7fe..98607c10 100644 --- a/packages/circuits/package.json +++ b/packages/circuits/package.json @@ -3,28 +3,29 @@ "license": "MIT", "version": "1.0.0", "scripts": { - "build": "mkdir -p build && circom src/email_auth.circom --r1cs --wasm --sym -l ../../node_modules -o ./build", - "dev-setup": "NODE_OPTIONS=--max_old_space_size=8192 npx ts-node scripts/dev-setup.ts --output ./build", + "build": "mkdir -p build && circom src/email_auth.circom --r1cs --wasm --sym --c -l ../../node_modules -o ./build", + "build-legacy": "mkdir -p build && circom src/email_auth_legacy.circom --r1cs --wasm --sym --c -l ../../node_modules -o ./build", + "build-recipient": "mkdir -p build && circom src/email_auth_with_recipient.circom --r1cs --wasm --sym --c -l ../../node_modules -o ./build", + "dev-setup": "NODE_OPTIONS=--max_old_space_size=16384 npx ts-node scripts/dev-setup.ts --output ./build", "gen-input": "NODE_OPTIONS=--max_old_space_size=8192 npx ts-node scripts/gen_input.ts", - "verify-proofs": "NODE_OPTIONS=--max_old_space_size=8192 npx ts-node scripts/verify_proofs.ts", "test": "NODE_OPTIONS=--max_old_space_size=8192 jest" }, "dependencies": { - "@zk-email/circuits": "=6.1.5", - "@zk-email/relayer-utils": "=0.2.4", - "@zk-email/zk-regex-circom": "=2.1.1", - "commander": "^11.0.0", - "snarkjs": "^0.7.4" + "@zk-email/circuits": "=6.3.0", + "@zk-email/relayer-utils": "=0.3.7", + "@zk-email/zk-regex-circom": "=2.3.0", + "commander": "^12.1.0", + "snarkjs": "=0.7.5" }, "devDependencies": { "@babel/preset-env": "^7.22.20", "@babel/preset-typescript": "^7.23.0", "@types/jest": "^29.5.4", "chai": "^4.3.7", - "circom_tester": "^0.0.19", + "circom_tester": "^0.0.20", "circomlib": "^2.0.5", "circomlibjs": "^0.1.2", - "ffjavascript": "^0.2.59", + "ffjavascript": "^0.3.1", "jest": "^29.5.0", "mocha": "^10.2.0", "ts-jest": "^29.1.1", @@ -40,5 +41,12 @@ "jest" ] ] - } + }, + "files": [ + "/src", + "/helpers", + "/scripts", + "package.json", + "README.md" + ] } \ No newline at end of file diff --git a/packages/circuits/scripts/dev-setup.ts b/packages/circuits/scripts/dev-setup.ts index e8466c31..96bd1c4e 100644 --- a/packages/circuits/scripts/dev-setup.ts +++ b/packages/circuits/scripts/dev-setup.ts @@ -20,7 +20,8 @@ program "--output ", "Path to the directory storing output files" ) - .option("--silent", "No console logs"); + .option("--silent", "No console logs") + .option("--legacy", "Use a legacy circuit"); program.parse(); const args = program.opts(); @@ -40,8 +41,12 @@ if (ZKEY_BEACON == null) { ZKEY_BEACON = "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"; } -const phase1Url = - "https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_22.ptau"; +let phase1Url = + "https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_23.ptau"; +if (args.legacy) { + phase1Url = + "https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_22.ptau"; +} // const buildDir = path.join(__dirname, "../build"); // const phase1Path = path.join(buildDir, "powersOfTau28_hez_final_21.ptau"); // const r1cPath = path.join(buildDir, "wallet.r1cs"); @@ -135,19 +140,34 @@ async function generateKeys( async function exec() { const buildDir = args.output; - const phase1Path = path.join(buildDir, "powersOfTau28_hez_final_22.ptau"); - await downloadPhase1(phase1Path); - log("✓ Phase 1:", phase1Path); - const emailAuthR1csPath = path.join(buildDir, "email_auth.r1cs"); - if (!fs.existsSync(emailAuthR1csPath)) { - throw new Error(`${emailAuthR1csPath} does not exist.`); + if (args.legacy) { + const phase1Path = path.join(buildDir, "powersOfTau28_hez_final_22.ptau"); + + await downloadPhase1(phase1Path); + log("✓ Phase 1:", phase1Path); + + const emailAuthR1csPath = path.join(buildDir, "email_auth_legacy.r1cs"); + if (!fs.existsSync(emailAuthR1csPath)) { + throw new Error(`${emailAuthR1csPath} does not exist.`); + } + await generateKeys(phase1Path, emailAuthR1csPath, path.join(buildDir, "email_auth_legacy.zkey"), path.join(buildDir, "email_auth_legacy.vkey"), path.join(buildDir, "Groth16LegacyVerifier.sol")); + log("✓ Keys for email auth legacy circuit generated"); + } else { + const phase1Path = path.join(buildDir, "powersOfTau28_hez_final_23.ptau"); + + await downloadPhase1(phase1Path); + log("✓ Phase 1:", phase1Path); + + const emailAuthR1csPath = path.join(buildDir, "email_auth.r1cs"); + if (!fs.existsSync(emailAuthR1csPath)) { + throw new Error(`${emailAuthR1csPath} does not exist.`); + } + await generateKeys(phase1Path, emailAuthR1csPath, path.join(buildDir, "email_auth.zkey"), path.join(buildDir, "email_auth.vkey"), path.join(buildDir, "Groth16Verifier.sol")); + log("✓ Keys for email auth circuit generated"); } - await generateKeys(phase1Path, emailAuthR1csPath, path.join(buildDir, "email_auth.zkey"), path.join(buildDir, "email_auth.vkey"), path.join(buildDir, "Groth16Verifier.sol")); - log("✓ Keys for email auth circuit generated"); - } diff --git a/packages/circuits/scripts/gen_input.ts b/packages/circuits/scripts/gen_input.ts index 899ea05d..cc53c8c5 100644 --- a/packages/circuits/scripts/gen_input.ts +++ b/packages/circuits/scripts/gen_input.ts @@ -8,7 +8,7 @@ import { program } from "commander"; import fs from "fs"; import { promisify } from "util"; -import { genEmailAuthInput } from "../helpers/email_auth"; +import { genEmailCircuitInput } from "../helpers/email_auth"; import path from "path"; const snarkjs = require("snarkjs"); @@ -26,6 +26,7 @@ program "Path of a json file to write the generated input" ) .option("--silent", "No console logs") + .option("--legacy", "Use a legacy circuit") .option("--prove", "Also generate proof"); program.parse(); @@ -42,21 +43,49 @@ async function generate() { throw new Error("--input file path arg must end with .json"); } - log("Generating Inputs for:", args); + if (args.legacy) { + log("Generating Inputs for:", args); - const circuitInputs = await genEmailAuthInput(args.emailFile, args.accountCode); - log("\n\nGenerated Inputs:", circuitInputs, "\n\n"); + const circuitInputs = await genEmailCircuitInput(args.emailFile, args.accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true + }); + log("\n\nGenerated Inputs:", circuitInputs, "\n\n"); - await promisify(fs.writeFile)(args.inputFile, JSON.stringify(circuitInputs, null, 2)); + await promisify(fs.writeFile)(args.inputFile, JSON.stringify(circuitInputs, null, 2)); - log("Inputs written to", args.inputFile); + log("Inputs written to", args.inputFile); - if (args.prove) { - const dir = path.dirname(args.inputFile); - const { proof, publicSignals } = await snarkjs.groth16.fullProve(circuitInputs, path.join(dir, "email_auth.wasm"), path.join(dir, "email_auth.zkey"), console); - await promisify(fs.writeFile)(path.join(dir, "email_auth_proof.json"), JSON.stringify(proof, null, 2)); - await promisify(fs.writeFile)(path.join(dir, "email_auth_public.json"), JSON.stringify(publicSignals, null, 2)); - log("✓ Proof for email auth circuit generated"); + if (args.prove) { + const dir = path.dirname(args.inputFile); + const { proof, publicSignals } = await snarkjs.groth16.fullProve(circuitInputs, path.join(dir, "email_auth_legacy.wasm"), path.join(dir, "email_auth_legacy.zkey"), console); + await promisify(fs.writeFile)(path.join(dir, "email_auth_legacy_proof.json"), JSON.stringify(proof, null, 2)); + await promisify(fs.writeFile)(path.join(dir, "email_auth_legacy_public.json"), JSON.stringify(publicSignals, null, 2)); + log("✓ Proof for email auth legacy circuit generated"); + } + } else { + log("Generating Inputs for:", args); + + const { subject_idx, ...circuitInputs } = await genEmailCircuitInput(args.emailFile, args.accountCode, { + maxHeaderLength: 1024, + maxBodyLength: 1024, + ignoreBodyHashCheck: false, + shaPrecomputeSelector: '(
]*>)' + }); + console.log(circuitInputs.padded_body.length); + log("\n\nGenerated Inputs:", circuitInputs, "\n\n"); + + await promisify(fs.writeFile)(args.inputFile, JSON.stringify(circuitInputs, null, 2)); + + log("Inputs written to", args.inputFile); + + if (args.prove) { + const dir = path.dirname(args.inputFile); + const { proof, publicSignals } = await snarkjs.groth16.fullProve(circuitInputs, path.join(dir, "email_auth.wasm"), path.join(dir, "email_auth.zkey"), console); + await promisify(fs.writeFile)(path.join(dir, "email_auth_proof.json"), JSON.stringify(proof, null, 2)); + await promisify(fs.writeFile)(path.join(dir, "email_auth_public.json"), JSON.stringify(publicSignals, null, 2)); + log("✓ Proof for email auth circuit generated"); + } } process.exit(0); } diff --git a/packages/circuits/scripts/verify_proofs.ts b/packages/circuits/scripts/verify_proofs.ts deleted file mode 100644 index 8a5d327c..00000000 --- a/packages/circuits/scripts/verify_proofs.ts +++ /dev/null @@ -1,69 +0,0 @@ -/** - * - * This script is for verifying proofs - * - */ - - -import { program } from "commander"; -import fs from "fs"; -import { promisify } from "util"; -import path from "path"; -const snarkjs = require("snarkjs"); - -program - .requiredOption( - "--input ", - "Path to the directory storing input files" - ) - .option("--silent", "No console logs"); - -program.parse(); -const args = program.opts(); - -function log(...message: any) { - if (!args.silent) { - console.log(...message); - } -} - -async function verify(vkPath: string, proofPath: string, pubInputsPath: string) { - const vk = await promisify(fs.readFile)(vkPath); - const proof = await promisify(fs.readFile)(proofPath); - const pubInputs = await promisify(fs.readFile)(pubInputsPath); - console.log(await snarkjs.groth16.verify(JSON.parse(vk.toString()), JSON.parse(pubInputs.toString()), JSON.parse(proof.toString()), console)); - // const { proof, publicSignals } = await snarkjs.groth16.fullProve(input, wasmFile, zkeyFileName, console); - // await promisify(fs.writeFile)(proofPath, JSON.stringify(proof, null, 2)); - // await promisify(fs.writeFile)(pubInputsPath, JSON.stringify(publicSignals, null, 2)); -} - -async function exec() { - const buildDir = args.input; - // const phase1Path = path.join(buildDir, "powersOfTau28_hez_final_22.ptau"); - await verify(path.join(buildDir, "account_creation.vkey"), path.join(buildDir, "account_creation_proof.json"), path.join(buildDir, "account_creation_public.json")); - log("✓ Proof for account creation circuit verified"); - - await verify(path.join(buildDir, "account_init.vkey"), path.join(buildDir, "account_init_proof.json"), path.join(buildDir, "account_init_public.json")); - log("✓ Proof for account initialization circuit verified"); - - await verify(path.join(buildDir, "account_transport.vkey"), path.join(buildDir, "account_transport_proof.json"), path.join(buildDir, "account_transport_public.json")); - log("✓ Proof for account transport circuit verified"); - - await verify(path.join(buildDir, "claim.vkey"), path.join(buildDir, "claim_proof.json"), path.join(buildDir, "claim_public.json")); - log("✓ Proof for claim circuit verified"); - - await verify(path.join(buildDir, "email_sender.vkey"), path.join(buildDir, "email_sender_proof.json"), path.join(buildDir, "email_sender_public.json")); - log("✓ Proof for email sender circuit verified"); - - -} - - -exec() - .then(() => { - process.exit(0); - }) - .catch((err) => { - console.log("Error: ", err); - process.exit(1); - }); diff --git a/packages/circuits/src/email_auth.circom b/packages/circuits/src/email_auth.circom index 547c8978..fafd93ba 100644 --- a/packages/circuits/src/email_auth.circom +++ b/packages/circuits/src/email_auth.circom @@ -2,4 +2,4 @@ pragma circom 2.1.6; include "./email_auth_template.circom"; -component main = EmailAuth(121, 17, 1024, 605, 0); \ No newline at end of file +component main = EmailAuth(121, 17, 1024, 1024, 605, 0, 1); \ No newline at end of file diff --git a/packages/circuits/src/email_auth_legacy.circom b/packages/circuits/src/email_auth_legacy.circom new file mode 100644 index 00000000..11289c52 --- /dev/null +++ b/packages/circuits/src/email_auth_legacy.circom @@ -0,0 +1,5 @@ +pragma circom 2.1.6; + +include "./email_auth_legacy_template.circom"; + +component main = EmailAuthLegacy(121, 17, 1024, 605, 0); \ No newline at end of file diff --git a/packages/circuits/src/email_auth_legacy_template.circom b/packages/circuits/src/email_auth_legacy_template.circom new file mode 100644 index 00000000..be7fa0c4 --- /dev/null +++ b/packages/circuits/src/email_auth_legacy_template.circom @@ -0,0 +1,206 @@ +pragma circom 2.1.6; + +include "circomlib/circuits/bitify.circom"; +include "circomlib/circuits/comparators.circom"; +include "circomlib/circuits/poseidon.circom"; +include "@zk-email/circuits/email-verifier.circom"; +include "@zk-email/circuits/utils/regex.circom"; +include "@zk-email/circuits/utils/functions.circom"; +include "./utils/constants.circom"; +include "./utils/account_salt.circom"; +include "./utils/hash_sign.circom"; +include "./utils/email_nullifier.circom"; +include "./utils/bytes2ints.circom"; +include "./utils/digit2int.circom"; +include "./utils/hex2int.circom"; +include "./utils/email_addr_commit.circom"; +include "./regexes/invitation_code_with_prefix_regex.circom"; +include "./regexes/invitation_code_regex.circom"; +include "./regexes/command_regex.circom"; +include "@zk-email/zk-regex-circom/circuits/common/from_addr_regex.circom"; +include "@zk-email/zk-regex-circom/circuits/common/email_addr_regex.circom"; +include "@zk-email/zk-regex-circom/circuits/common/email_domain_regex.circom"; +include "@zk-email/zk-regex-circom/circuits/common/subject_all_regex.circom"; +include "@zk-email/zk-regex-circom/circuits/common/timestamp_regex.circom"; + + +// Verify email from user (sender) and extract subject, timestmap, recipient email (commitment), etc. +// This legacy template extracts a command not from the email body but from the email body. +// * n - the number of bits in each chunk of the RSA public key (modulust) +// * k - the number of chunks in the RSA public key (n * k > 2048) +// * max_header_bytes - max number of bytes in the email header +// * max_subject_bytes - max number of bytes in the email subject +// * recipient_enabled - whether the email address commitment of the recipient = email address in the subject is exposed +template EmailAuthLegacy(n, k, max_header_bytes, max_subject_bytes, recipient_enabled) { + signal input padded_header[max_header_bytes]; // email data (only header part) + signal input public_key[k]; // RSA public key (modulus), k parts of n bits each. + signal input signature[k]; // RSA signature, k parts of n bits each. + signal input padded_header_len; // length of in email data including the padding + signal input account_code; + signal input from_addr_idx; // Index of the from email address (= sender email address) in the email header + signal input subject_idx; // Index of the subject in the header + signal input domain_idx; // Index of the domain name in the from email address + signal input timestamp_idx; // Index of the timestamp in the header + signal input code_idx; // index of the invitation code in the header + + + var email_max_bytes = email_max_bytes_const(); + var subject_field_len = compute_ints_size(max_subject_bytes); + var domain_len = domain_len_const(); + var domain_field_len = compute_ints_size(domain_len); + var k2_chunked_size = k >> 1; + if(k % 2 == 1) { + k2_chunked_size += 1; + } + var timestamp_len = timestamp_len_const(); + var code_len = invitation_code_len_const(); + + + signal output domain_name[domain_field_len]; + signal output public_key_hash; + signal output email_nullifier; + signal output timestamp; + signal output masked_subject[subject_field_len]; + signal output account_salt; + signal output is_code_exist; + + // Verify Email Signature + component email_verifier = EmailVerifier(max_header_bytes, 0, n, k, 1, 0, 0, 0); + email_verifier.emailHeader <== padded_header; + email_verifier.pubkey <== public_key; + email_verifier.signature <== signature; + email_verifier.emailHeaderLength <== padded_header_len; + public_key_hash <== email_verifier.pubkeyHash; + + // FROM HEADER REGEX + signal from_regex_out, from_regex_reveal[max_header_bytes]; + (from_regex_out, from_regex_reveal) <== FromAddrRegex(max_header_bytes)(padded_header); + from_regex_out === 1; + signal is_valid_from_addr_idx <== LessThan(log2Ceil(max_header_bytes))([from_addr_idx, max_header_bytes]); + is_valid_from_addr_idx === 1; + signal from_email_addr[email_max_bytes]; + from_email_addr <== SelectRegexReveal(max_header_bytes, email_max_bytes)(from_regex_reveal, from_addr_idx); + + // DOMAIN NAME HEADER REGEX + signal domain_regex_out, domain_regex_reveal[email_max_bytes]; + (domain_regex_out, domain_regex_reveal) <== EmailDomainRegex(email_max_bytes)(from_email_addr); + domain_regex_out === 1; + signal is_valid_domain_idx <== LessThan(log2Ceil(email_max_bytes))([domain_idx, email_max_bytes]); + is_valid_domain_idx === 1; + signal domain_name_bytes[domain_len]; + domain_name_bytes <== SelectRegexReveal(email_max_bytes, domain_len)(domain_regex_reveal, domain_idx); + domain_name <== Bytes2Ints(domain_len)(domain_name_bytes); + + /// EMAIL NULLIFIER + signal sign_hash; + signal sign_ints[k2_chunked_size]; + (sign_hash, sign_ints) <== HashSign(n,k)(signature); + email_nullifier <== EmailNullifier()(sign_hash); + + + // SUBJECT HEADER REGEX + signal subject_regex_out, subject_regex_reveal[max_header_bytes]; + (subject_regex_out, subject_regex_reveal) <== SubjectAllRegex(max_header_bytes)(padded_header); + subject_regex_out === 1; + signal is_valid_subject_idx <== LessThan(log2Ceil(max_header_bytes))([subject_idx, max_header_bytes]); + is_valid_subject_idx === 1; + signal subject_all[max_subject_bytes]; + subject_all <== SelectRegexReveal(max_header_bytes, max_subject_bytes)(subject_regex_reveal, subject_idx); + + // Timestamp regex + convert to decimal format + signal timestamp_regex_out, timestamp_regex_reveal[max_header_bytes]; + (timestamp_regex_out, timestamp_regex_reveal) <== TimestampRegex(max_header_bytes)(padded_header); + signal is_valid_timestamp_idx <== LessThan(log2Ceil(max_header_bytes))([timestamp_idx, max_header_bytes]); + is_valid_timestamp_idx === 1; + signal timestamp_str[timestamp_len]; + timestamp_str <== SelectRegexReveal(max_header_bytes, timestamp_len)(timestamp_regex_reveal, timestamp_idx); + signal raw_timestamp <== Digit2Int(timestamp_len)(timestamp_str); + timestamp <== timestamp_regex_out * raw_timestamp; + + /// MASKED SUBJECT + /// INVITATION CODE WITH PREFIX REGEX + signal prefixed_code_regex_out, prefixed_code_regex_reveal[max_subject_bytes]; + (prefixed_code_regex_out, prefixed_code_regex_reveal) <== InvitationCodeWithPrefixRegex(max_subject_bytes)(subject_all); + is_code_exist <== prefixed_code_regex_out; + signal removed_code[max_subject_bytes]; + for(var i = 0; i < max_subject_bytes; i++) { + removed_code[i] <== is_code_exist * prefixed_code_regex_reveal[i]; + } + /// EMAIL ADDRESS REGEX + /// Note: the email address in the subject should not overlap with the invitation code + signal subject_email_addr_regex_out, subject_email_addr_regex_reveal[max_subject_bytes]; + (subject_email_addr_regex_out, subject_email_addr_regex_reveal) <== EmailAddrRegex(max_subject_bytes)(subject_all); + signal is_subject_email_addr_exist <== subject_email_addr_regex_out; + signal removed_subject_email_addr[max_subject_bytes]; + for(var i = 0; i < max_subject_bytes; i++) { + removed_subject_email_addr[i] <== is_subject_email_addr_exist * subject_email_addr_regex_reveal[i]; + } + signal masked_subject_bytes[max_subject_bytes]; + for(var i = 0; i < max_subject_bytes; i++) { + masked_subject_bytes[i] <== subject_all[i] - removed_code[i] - removed_subject_email_addr[i]; + } + masked_subject <== Bytes2Ints(max_subject_bytes)(masked_subject_bytes); + + // INVITATION CODE REGEX + signal code_regex_out, code_regex_reveal[max_header_bytes]; + (code_regex_out, code_regex_reveal) <== InvitationCodeRegex(max_header_bytes)(padded_header); + is_code_exist * (1 - code_regex_out) === 0; + signal replaced_code_regex_reveal[max_header_bytes]; + for(var i=0; i 2048) // * max_header_bytes - max number of bytes in the email header -// * max_subject_bytes - max number of bytes in the email subject +// * max_body_bytes - max number of bytes in the email body +// * max_command_bytes - max number of bytes in the command // * recipient_enabled - whether the email address commitment of the recipient = email address in the subject is exposed -template EmailAuth(n, k, max_header_bytes, max_subject_bytes, recipient_enabled) { +// * is_qp_encoded - whether the email body is qp encoded +template EmailAuth(n, k, max_header_bytes, max_body_bytes, max_command_bytes, recipient_enabled, is_qp_encoded) { signal input padded_header[max_header_bytes]; // email data (only header part) + signal input padded_header_len; // length of in email data including the padding signal input public_key[k]; // RSA public key (modulus), k parts of n bits each. signal input signature[k]; // RSA signature, k parts of n bits each. - signal input padded_header_len; // length of in email data including the padding - // signal input sender_relayer_rand; // Private randomness of the relayer + signal input body_hash_idx; // index of the bodyhash in the header + signal input precomputed_sha[32]; // precomputed sha256 of the email body + signal input padded_body[max_body_bytes]; // email data (only body part) + signal input padded_body_len; // length of in email data including the padding signal input account_code; signal input from_addr_idx; // Index of the from email address (= sender email address) in the email header - signal input subject_idx; // Index of the subject in the header signal input domain_idx; // Index of the domain name in the from email address signal input timestamp_idx; // Index of the timestamp in the header signal input code_idx; // index of the invitation code in the header - + signal input command_idx; // index of the command in the body + /// Note: padded_cleaned_body is only used for qp encoded email body, + /// for non-qp encoded email body, it should be equal to padded_body + signal input padded_cleaned_body[max_body_bytes]; // cleaned email body var email_max_bytes = email_max_bytes_const(); - var subject_field_len = compute_ints_size(max_subject_bytes); + var command_field_len = compute_ints_size(max_command_bytes); var domain_len = domain_len_const(); - var domain_filed_len = compute_ints_size(domain_len); + var domain_field_len = compute_ints_size(domain_len); var k2_chunked_size = k >> 1; if(k % 2 == 1) { k2_chunked_size += 1; @@ -54,22 +62,27 @@ template EmailAuth(n, k, max_header_bytes, max_subject_bytes, recipient_enabled) var timestamp_len = timestamp_len_const(); var code_len = invitation_code_len_const(); - - signal output domain_name[domain_filed_len]; + signal output domain_name[domain_field_len]; signal output public_key_hash; signal output email_nullifier; signal output timestamp; - signal output masked_subject[subject_field_len]; + signal output masked_command[command_field_len]; signal output account_salt; signal output is_code_exist; // Verify Email Signature - component email_verifier = EmailVerifier(max_header_bytes, 0, n, k, 1, 0, 0); + component email_verifier = EmailVerifier(max_header_bytes, max_body_bytes, n, k, 0, 0, 0, is_qp_encoded); email_verifier.emailHeader <== padded_header; + email_verifier.emailHeaderLength <== padded_header_len; email_verifier.pubkey <== public_key; email_verifier.signature <== signature; - email_verifier.emailHeaderLength <== padded_header_len; - signal header_hash[256] <== email_verifier.sha; + email_verifier.bodyHashIndex <== body_hash_idx; + email_verifier.precomputedSHA <== precomputed_sha; + email_verifier.emailBody <== padded_body; + email_verifier.emailBodyLength <== padded_body_len; + if (is_qp_encoded == 1) { + email_verifier.decodedEmailBodyIn <== padded_cleaned_body; + } public_key_hash <== email_verifier.pubkeyHash; // FROM HEADER REGEX @@ -91,71 +104,73 @@ template EmailAuth(n, k, max_header_bytes, max_subject_bytes, recipient_enabled) domain_name_bytes <== SelectRegexReveal(email_max_bytes, domain_len)(domain_regex_reveal, domain_idx); domain_name <== Bytes2Ints(domain_len)(domain_name_bytes); - /// EMAIL NULLIFIER signal sign_hash; signal sign_ints[k2_chunked_size]; (sign_hash, sign_ints) <== HashSign(n,k)(signature); email_nullifier <== EmailNullifier()(sign_hash); - - // SUBJECT HEADER REGEX - signal subject_regex_out, subject_regex_reveal[max_header_bytes]; - (subject_regex_out, subject_regex_reveal) <== SubjectAllRegex(max_header_bytes)(padded_header); - subject_regex_out === 1; - signal is_valid_subject_idx <== LessThan(log2Ceil(max_header_bytes))([subject_idx, max_header_bytes]); - is_valid_subject_idx === 1; - signal subject_all[max_subject_bytes]; - subject_all <== SelectRegexReveal(max_header_bytes, max_subject_bytes)(subject_regex_reveal, subject_idx); - // Timestamp regex + convert to decimal format signal timestamp_regex_out, timestamp_regex_reveal[max_header_bytes]; (timestamp_regex_out, timestamp_regex_reveal) <== TimestampRegex(max_header_bytes)(padded_header); + signal timestamp_str[timestamp_len]; signal is_valid_timestamp_idx <== LessThan(log2Ceil(max_header_bytes))([timestamp_idx, max_header_bytes]); is_valid_timestamp_idx === 1; - signal timestamp_str[timestamp_len]; timestamp_str <== SelectRegexReveal(max_header_bytes, timestamp_len)(timestamp_regex_reveal, timestamp_idx); signal raw_timestamp <== Digit2Int(timestamp_len)(timestamp_str); timestamp <== timestamp_regex_out * raw_timestamp; + + // Extract the command from the body + signal command_regex_out, command_regex_reveal[max_body_bytes]; + if (is_qp_encoded != 1) { + (command_regex_out, command_regex_reveal) <== CommandRegex(max_body_bytes)(padded_body); + } else { + (command_regex_out, command_regex_reveal) <== CommandRegex(max_body_bytes)(padded_cleaned_body); + } + command_regex_out === 1; + signal is_valid_command_idx <== LessThan(log2Ceil(max_command_bytes))([command_idx, max_command_bytes]); + is_valid_command_idx === 1; + signal command_all[max_command_bytes]; + command_all <== SelectRegexReveal(max_body_bytes, max_command_bytes)(command_regex_reveal, command_idx); - /// MASKED SUBJECT - /// INVITATION CODE WITH PREFIX REGEX - signal prefixed_code_regex_out, prefixed_code_regex_reveal[max_subject_bytes]; - (prefixed_code_regex_out, prefixed_code_regex_reveal) <== InvitationCodeWithPrefixRegex(max_subject_bytes)(subject_all); + signal prefixed_code_regex_out, prefixed_code_regex_reveal[max_command_bytes]; + (prefixed_code_regex_out, prefixed_code_regex_reveal) <== InvitationCodeWithPrefixRegex(max_command_bytes)(command_all); is_code_exist <== prefixed_code_regex_out; - signal removed_code[max_subject_bytes]; - for(var i = 0; i < max_subject_bytes; i++) { + signal removed_code[max_command_bytes]; + for(var i = 0; i < max_command_bytes; i++) { removed_code[i] <== is_code_exist * prefixed_code_regex_reveal[i]; } - /// EMAIL ADDRESS REGEX - /// Note: the email address in the subject should not overlap with the invitation code - signal subject_email_addr_regex_out, subject_email_addr_regex_reveal[max_subject_bytes]; - (subject_email_addr_regex_out, subject_email_addr_regex_reveal) <== EmailAddrRegex(max_subject_bytes)(subject_all); - signal is_subject_email_addr_exist <== subject_email_addr_regex_out; - signal removed_subject_email_addr[max_subject_bytes]; - for(var i = 0; i < max_subject_bytes; i++) { - removed_subject_email_addr[i] <== is_subject_email_addr_exist * subject_email_addr_regex_reveal[i]; + signal command_email_addr_regex_out, command_email_addr_regex_reveal[max_command_bytes]; + (command_email_addr_regex_out, command_email_addr_regex_reveal) <== EmailAddrRegex(max_command_bytes)(command_all); + signal is_command_email_addr_exist <== command_email_addr_regex_out; + signal removed_command_email_addr[max_command_bytes]; + for(var i = 0; i < max_command_bytes; i++) { + removed_command_email_addr[i] <== is_command_email_addr_exist * command_email_addr_regex_reveal[i]; } - signal masked_subject_bytes[max_subject_bytes]; - for(var i = 0; i < max_subject_bytes; i++) { - masked_subject_bytes[i] <== subject_all[i] - removed_code[i] - removed_subject_email_addr[i]; + signal masked_command_bytes[max_command_bytes]; + for(var i = 0; i < max_command_bytes; i++) { + masked_command_bytes[i] <== command_all[i] - removed_code[i] - removed_command_email_addr[i]; } - masked_subject <== Bytes2Ints(max_subject_bytes)(masked_subject_bytes); + masked_command <== Bytes2Ints(max_command_bytes)(masked_command_bytes); // INVITATION CODE REGEX - signal code_regex_out, code_regex_reveal[max_header_bytes]; - (code_regex_out, code_regex_reveal) <== InvitationCodeRegex(max_header_bytes)(padded_header); + signal code_regex_out, code_regex_reveal[max_body_bytes]; + if (is_qp_encoded != 1) { + (code_regex_out, code_regex_reveal) <== InvitationCodeRegex(max_body_bytes)(padded_body); + } else { + (code_regex_out, code_regex_reveal) <== InvitationCodeRegex(max_body_bytes)(padded_cleaned_body); + } is_code_exist * (1 - code_regex_out) === 0; - signal replaced_code_regex_reveal[max_header_bytes]; - for(var i=0; i]*>)" + }, + { + "is_public": true, + "regex_def": "[^<>/]+" + }, + { + "is_public": false, + "regex_def": "
" + } + ] +} \ No newline at end of file diff --git a/packages/circuits/src/regexes/command_regex.circom b/packages/circuits/src/regexes/command_regex.circom new file mode 100644 index 00000000..011ced9a --- /dev/null +++ b/packages/circuits/src/regexes/command_regex.circom @@ -0,0 +1,1366 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: (
]*>)[^<>/]+
+template CommandRegex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + _ <== LessThan(8)([msg[i], 255]); + in[i+1] <== msg[i]; + } + + component eq[82][num_bytes]; + component lt[38][num_bytes]; + component and[167][num_bytes]; + component multi_or[36][num_bytes]; + signal states[num_bytes+1][56]; + signal states_tmp[num_bytes+1][56]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 56; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(55); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 60; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== 0; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 100; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + and[1][i].b <== eq[1][i].out; + states[i+1][2] <== and[1][i].out; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 105; + and[2][i] = AND(); + and[2][i].a <== states[i][2]; + and[2][i].b <== eq[2][i].out; + states[i+1][3] <== and[2][i].out; + eq[3][i] = IsEqual(); + eq[3][i].in[0] <== in[i]; + eq[3][i].in[1] <== 118; + and[3][i] = AND(); + and[3][i].a <== states[i][3]; + and[3][i].b <== eq[3][i].out; + states[i+1][4] <== and[3][i].out; + eq[4][i] = IsEqual(); + eq[4][i].in[0] <== in[i]; + eq[4][i].in[1] <== 32; + and[4][i] = AND(); + and[4][i].a <== states[i][4]; + and[4][i].b <== eq[4][i].out; + states[i+1][5] <== and[4][i].out; + and[5][i] = AND(); + and[5][i].a <== states[i][5]; + and[5][i].b <== eq[2][i].out; + states[i+1][6] <== and[5][i].out; + and[6][i] = AND(); + and[6][i].a <== states[i][6]; + and[6][i].b <== eq[1][i].out; + states[i+1][7] <== and[6][i].out; + eq[5][i] = IsEqual(); + eq[5][i].in[0] <== in[i]; + eq[5][i].in[1] <== 61; + and[7][i] = AND(); + and[7][i].a <== states[i][7]; + and[7][i].b <== eq[5][i].out; + states[i+1][8] <== and[7][i].out; + eq[6][i] = IsEqual(); + eq[6][i].in[0] <== in[i]; + eq[6][i].in[1] <== 51; + and[8][i] = AND(); + and[8][i].a <== states[i][8]; + and[8][i].b <== eq[6][i].out; + states[i+1][9] <== and[8][i].out; + eq[7][i] = IsEqual(); + eq[7][i].in[0] <== in[i]; + eq[7][i].in[1] <== 68; + and[9][i] = AND(); + and[9][i].a <== states[i][9]; + and[9][i].b <== eq[7][i].out; + states[i+1][10] <== and[9][i].out; + eq[8][i] = IsEqual(); + eq[8][i].in[0] <== in[i]; + eq[8][i].in[1] <== 34; + and[10][i] = AND(); + and[10][i].a <== states[i][10]; + and[10][i].b <== eq[8][i].out; + lt[0][i] = LessEqThan(8); + lt[0][i].in[0] <== 1; + lt[0][i].in[1] <== in[i]; + lt[1][i] = LessEqThan(8); + lt[1][i].in[0] <== in[i]; + lt[1][i].in[1] <== 33; + and[11][i] = AND(); + and[11][i].a <== lt[0][i].out; + and[11][i].b <== lt[1][i].out; + lt[2][i] = LessEqThan(8); + lt[2][i].in[0] <== 35; + lt[2][i].in[1] <== in[i]; + lt[3][i] = LessEqThan(8); + lt[3][i].in[0] <== in[i]; + lt[3][i].in[1] <== 121; + and[12][i] = AND(); + and[12][i].a <== lt[2][i].out; + and[12][i].b <== lt[3][i].out; + eq[9][i] = IsEqual(); + eq[9][i].in[0] <== in[i]; + eq[9][i].in[1] <== 123; + eq[10][i] = IsEqual(); + eq[10][i].in[0] <== in[i]; + eq[10][i].in[1] <== 124; + eq[11][i] = IsEqual(); + eq[11][i].in[0] <== in[i]; + eq[11][i].in[1] <== 125; + eq[12][i] = IsEqual(); + eq[12][i].in[0] <== in[i]; + eq[12][i].in[1] <== 126; + eq[13][i] = IsEqual(); + eq[13][i].in[0] <== in[i]; + eq[13][i].in[1] <== 127; + and[13][i] = AND(); + and[13][i].a <== states[i][11]; + multi_or[0][i] = MultiOR(7); + multi_or[0][i].in[0] <== and[11][i].out; + multi_or[0][i].in[1] <== and[12][i].out; + multi_or[0][i].in[2] <== eq[9][i].out; + multi_or[0][i].in[3] <== eq[10][i].out; + multi_or[0][i].in[4] <== eq[11][i].out; + multi_or[0][i].in[5] <== eq[12][i].out; + multi_or[0][i].in[6] <== eq[13][i].out; + and[13][i].b <== multi_or[0][i].out; + lt[4][i] = LessEqThan(8); + lt[4][i].in[0] <== 128; + lt[4][i].in[1] <== in[i]; + lt[5][i] = LessEqThan(8); + lt[5][i].in[0] <== in[i]; + lt[5][i].in[1] <== 191; + and[14][i] = AND(); + and[14][i].a <== lt[4][i].out; + and[14][i].b <== lt[5][i].out; + and[15][i] = AND(); + and[15][i].a <== states[i][12]; + and[15][i].b <== and[14][i].out; + lt[6][i] = LessEqThan(8); + lt[6][i].in[0] <== 35; + lt[6][i].in[1] <== in[i]; + lt[7][i] = LessEqThan(8); + lt[7][i].in[0] <== in[i]; + lt[7][i].in[1] <== 106; + and[16][i] = AND(); + and[16][i].a <== lt[6][i].out; + and[16][i].b <== lt[7][i].out; + eq[14][i] = IsEqual(); + eq[14][i].in[0] <== in[i]; + eq[14][i].in[1] <== 108; + eq[15][i] = IsEqual(); + eq[15][i].in[0] <== in[i]; + eq[15][i].in[1] <== 109; + eq[16][i] = IsEqual(); + eq[16][i].in[0] <== in[i]; + eq[16][i].in[1] <== 110; + eq[17][i] = IsEqual(); + eq[17][i].in[0] <== in[i]; + eq[17][i].in[1] <== 111; + eq[18][i] = IsEqual(); + eq[18][i].in[0] <== in[i]; + eq[18][i].in[1] <== 112; + eq[19][i] = IsEqual(); + eq[19][i].in[0] <== in[i]; + eq[19][i].in[1] <== 113; + eq[20][i] = IsEqual(); + eq[20][i].in[0] <== in[i]; + eq[20][i].in[1] <== 114; + eq[21][i] = IsEqual(); + eq[21][i].in[0] <== in[i]; + eq[21][i].in[1] <== 115; + eq[22][i] = IsEqual(); + eq[22][i].in[0] <== in[i]; + eq[22][i].in[1] <== 116; + eq[23][i] = IsEqual(); + eq[23][i].in[0] <== in[i]; + eq[23][i].in[1] <== 117; + eq[24][i] = IsEqual(); + eq[24][i].in[0] <== in[i]; + eq[24][i].in[1] <== 119; + eq[25][i] = IsEqual(); + eq[25][i].in[0] <== in[i]; + eq[25][i].in[1] <== 120; + eq[26][i] = IsEqual(); + eq[26][i].in[0] <== in[i]; + eq[26][i].in[1] <== 121; + and[17][i] = AND(); + and[17][i].a <== states[i][19]; + multi_or[1][i] = MultiOR(21); + multi_or[1][i].in[0] <== and[11][i].out; + multi_or[1][i].in[1] <== and[16][i].out; + multi_or[1][i].in[2] <== eq[14][i].out; + multi_or[1][i].in[3] <== eq[15][i].out; + multi_or[1][i].in[4] <== eq[16][i].out; + multi_or[1][i].in[5] <== eq[17][i].out; + multi_or[1][i].in[6] <== eq[18][i].out; + multi_or[1][i].in[7] <== eq[19][i].out; + multi_or[1][i].in[8] <== eq[20][i].out; + multi_or[1][i].in[9] <== eq[21][i].out; + multi_or[1][i].in[10] <== eq[22][i].out; + multi_or[1][i].in[11] <== eq[23][i].out; + multi_or[1][i].in[12] <== eq[3][i].out; + multi_or[1][i].in[13] <== eq[24][i].out; + multi_or[1][i].in[14] <== eq[25][i].out; + multi_or[1][i].in[15] <== eq[26][i].out; + multi_or[1][i].in[16] <== eq[9][i].out; + multi_or[1][i].in[17] <== eq[10][i].out; + multi_or[1][i].in[18] <== eq[11][i].out; + multi_or[1][i].in[19] <== eq[12][i].out; + multi_or[1][i].in[20] <== eq[13][i].out; + and[17][i].b <== multi_or[1][i].out; + lt[8][i] = LessEqThan(8); + lt[8][i].in[0] <== 35; + lt[8][i].in[1] <== in[i]; + lt[9][i] = LessEqThan(8); + lt[9][i].in[0] <== in[i]; + lt[9][i].in[1] <== 100; + and[18][i] = AND(); + and[18][i].a <== lt[8][i].out; + and[18][i].b <== lt[9][i].out; + lt[10][i] = LessEqThan(8); + lt[10][i].in[0] <== 102; + lt[10][i].in[1] <== in[i]; + lt[11][i] = LessEqThan(8); + lt[11][i].in[0] <== in[i]; + lt[11][i].in[1] <== 121; + and[19][i] = AND(); + and[19][i].a <== lt[10][i].out; + and[19][i].b <== lt[11][i].out; + and[20][i] = AND(); + and[20][i].a <== states[i][20]; + multi_or[2][i] = MultiOR(8); + multi_or[2][i].in[0] <== and[11][i].out; + multi_or[2][i].in[1] <== and[18][i].out; + multi_or[2][i].in[2] <== and[19][i].out; + multi_or[2][i].in[3] <== eq[9][i].out; + multi_or[2][i].in[4] <== eq[10][i].out; + multi_or[2][i].in[5] <== eq[11][i].out; + multi_or[2][i].in[6] <== eq[12][i].out; + multi_or[2][i].in[7] <== eq[13][i].out; + and[20][i].b <== multi_or[2][i].out; + lt[12][i] = LessEqThan(8); + lt[12][i].in[0] <== 35; + lt[12][i].in[1] <== in[i]; + lt[13][i] = LessEqThan(8); + lt[13][i].in[0] <== in[i]; + lt[13][i].in[1] <== 108; + and[21][i] = AND(); + and[21][i].a <== lt[12][i].out; + and[21][i].b <== lt[13][i].out; + and[22][i] = AND(); + and[22][i].a <== states[i][21]; + multi_or[3][i] = MultiOR(19); + multi_or[3][i].in[0] <== and[11][i].out; + multi_or[3][i].in[1] <== and[21][i].out; + multi_or[3][i].in[2] <== eq[16][i].out; + multi_or[3][i].in[3] <== eq[17][i].out; + multi_or[3][i].in[4] <== eq[18][i].out; + multi_or[3][i].in[5] <== eq[19][i].out; + multi_or[3][i].in[6] <== eq[20][i].out; + multi_or[3][i].in[7] <== eq[21][i].out; + multi_or[3][i].in[8] <== eq[22][i].out; + multi_or[3][i].in[9] <== eq[23][i].out; + multi_or[3][i].in[10] <== eq[3][i].out; + multi_or[3][i].in[11] <== eq[24][i].out; + multi_or[3][i].in[12] <== eq[25][i].out; + multi_or[3][i].in[13] <== eq[26][i].out; + multi_or[3][i].in[14] <== eq[9][i].out; + multi_or[3][i].in[15] <== eq[10][i].out; + multi_or[3][i].in[16] <== eq[11][i].out; + multi_or[3][i].in[17] <== eq[12][i].out; + multi_or[3][i].in[18] <== eq[13][i].out; + and[22][i].b <== multi_or[3][i].out; + lt[14][i] = LessEqThan(8); + lt[14][i].in[0] <== 35; + lt[14][i].in[1] <== in[i]; + lt[15][i] = LessEqThan(8); + lt[15][i].in[0] <== in[i]; + lt[15][i].in[1] <== 96; + and[23][i] = AND(); + and[23][i].a <== lt[14][i].out; + and[23][i].b <== lt[15][i].out; + lt[16][i] = LessEqThan(8); + lt[16][i].in[0] <== 98; + lt[16][i].in[1] <== in[i]; + lt[17][i] = LessEqThan(8); + lt[17][i].in[0] <== in[i]; + lt[17][i].in[1] <== 121; + and[24][i] = AND(); + and[24][i].a <== lt[16][i].out; + and[24][i].b <== lt[17][i].out; + and[25][i] = AND(); + and[25][i].a <== states[i][22]; + multi_or[4][i] = MultiOR(8); + multi_or[4][i].in[0] <== and[11][i].out; + multi_or[4][i].in[1] <== and[23][i].out; + multi_or[4][i].in[2] <== and[24][i].out; + multi_or[4][i].in[3] <== eq[9][i].out; + multi_or[4][i].in[4] <== eq[10][i].out; + multi_or[4][i].in[5] <== eq[11][i].out; + multi_or[4][i].in[6] <== eq[12][i].out; + multi_or[4][i].in[7] <== eq[13][i].out; + and[25][i].b <== multi_or[4][i].out; + lt[18][i] = LessEqThan(8); + lt[18][i].in[0] <== 35; + lt[18][i].in[1] <== in[i]; + lt[19][i] = LessEqThan(8); + lt[19][i].in[0] <== in[i]; + lt[19][i].in[1] <== 104; + and[26][i] = AND(); + and[26][i].a <== lt[18][i].out; + and[26][i].b <== lt[19][i].out; + eq[27][i] = IsEqual(); + eq[27][i].in[0] <== in[i]; + eq[27][i].in[1] <== 106; + eq[28][i] = IsEqual(); + eq[28][i].in[0] <== in[i]; + eq[28][i].in[1] <== 107; + and[27][i] = AND(); + and[27][i].a <== states[i][23]; + multi_or[5][i] = MultiOR(23); + multi_or[5][i].in[0] <== and[11][i].out; + multi_or[5][i].in[1] <== and[26][i].out; + multi_or[5][i].in[2] <== eq[27][i].out; + multi_or[5][i].in[3] <== eq[28][i].out; + multi_or[5][i].in[4] <== eq[14][i].out; + multi_or[5][i].in[5] <== eq[15][i].out; + multi_or[5][i].in[6] <== eq[16][i].out; + multi_or[5][i].in[7] <== eq[17][i].out; + multi_or[5][i].in[8] <== eq[18][i].out; + multi_or[5][i].in[9] <== eq[19][i].out; + multi_or[5][i].in[10] <== eq[20][i].out; + multi_or[5][i].in[11] <== eq[21][i].out; + multi_or[5][i].in[12] <== eq[22][i].out; + multi_or[5][i].in[13] <== eq[23][i].out; + multi_or[5][i].in[14] <== eq[3][i].out; + multi_or[5][i].in[15] <== eq[24][i].out; + multi_or[5][i].in[16] <== eq[25][i].out; + multi_or[5][i].in[17] <== eq[26][i].out; + multi_or[5][i].in[18] <== eq[9][i].out; + multi_or[5][i].in[19] <== eq[10][i].out; + multi_or[5][i].in[20] <== eq[11][i].out; + multi_or[5][i].in[21] <== eq[12][i].out; + multi_or[5][i].in[22] <== eq[13][i].out; + and[27][i].b <== multi_or[5][i].out; + lt[20][i] = LessEqThan(8); + lt[20][i].in[0] <== 35; + lt[20][i].in[1] <== in[i]; + lt[21][i] = LessEqThan(8); + lt[21][i].in[0] <== in[i]; + lt[21][i].in[1] <== 107; + and[28][i] = AND(); + and[28][i].a <== lt[20][i].out; + and[28][i].b <== lt[21][i].out; + and[29][i] = AND(); + and[29][i].a <== states[i][24]; + multi_or[6][i] = MultiOR(20); + multi_or[6][i].in[0] <== and[11][i].out; + multi_or[6][i].in[1] <== and[28][i].out; + multi_or[6][i].in[2] <== eq[15][i].out; + multi_or[6][i].in[3] <== eq[16][i].out; + multi_or[6][i].in[4] <== eq[17][i].out; + multi_or[6][i].in[5] <== eq[18][i].out; + multi_or[6][i].in[6] <== eq[19][i].out; + multi_or[6][i].in[7] <== eq[20][i].out; + multi_or[6][i].in[8] <== eq[21][i].out; + multi_or[6][i].in[9] <== eq[22][i].out; + multi_or[6][i].in[10] <== eq[23][i].out; + multi_or[6][i].in[11] <== eq[3][i].out; + multi_or[6][i].in[12] <== eq[24][i].out; + multi_or[6][i].in[13] <== eq[25][i].out; + multi_or[6][i].in[14] <== eq[26][i].out; + multi_or[6][i].in[15] <== eq[9][i].out; + multi_or[6][i].in[16] <== eq[10][i].out; + multi_or[6][i].in[17] <== eq[11][i].out; + multi_or[6][i].in[18] <== eq[12][i].out; + multi_or[6][i].in[19] <== eq[13][i].out; + and[29][i].b <== multi_or[6][i].out; + multi_or[7][i] = MultiOR(9); + multi_or[7][i].in[0] <== and[10][i].out; + multi_or[7][i].in[1] <== and[13][i].out; + multi_or[7][i].in[2] <== and[15][i].out; + multi_or[7][i].in[3] <== and[17][i].out; + multi_or[7][i].in[4] <== and[20][i].out; + multi_or[7][i].in[5] <== and[22][i].out; + multi_or[7][i].in[6] <== and[25][i].out; + multi_or[7][i].in[7] <== and[27][i].out; + multi_or[7][i].in[8] <== and[29][i].out; + states[i+1][11] <== multi_or[7][i].out; + lt[22][i] = LessEqThan(8); + lt[22][i].in[0] <== 194; + lt[22][i].in[1] <== in[i]; + lt[23][i] = LessEqThan(8); + lt[23][i].in[0] <== in[i]; + lt[23][i].in[1] <== 223; + and[30][i] = AND(); + and[30][i].a <== lt[22][i].out; + and[30][i].b <== lt[23][i].out; + and[31][i] = AND(); + and[31][i].a <== states[i][11]; + and[31][i].b <== and[30][i].out; + lt[24][i] = LessEqThan(8); + lt[24][i].in[0] <== 160; + lt[24][i].in[1] <== in[i]; + lt[25][i] = LessEqThan(8); + lt[25][i].in[0] <== in[i]; + lt[25][i].in[1] <== 191; + and[32][i] = AND(); + and[32][i].a <== lt[24][i].out; + and[32][i].b <== lt[25][i].out; + and[33][i] = AND(); + and[33][i].a <== states[i][13]; + and[33][i].b <== and[32][i].out; + and[34][i] = AND(); + and[34][i].a <== states[i][14]; + and[34][i].b <== and[14][i].out; + lt[26][i] = LessEqThan(8); + lt[26][i].in[0] <== 128; + lt[26][i].in[1] <== in[i]; + lt[27][i] = LessEqThan(8); + lt[27][i].in[0] <== in[i]; + lt[27][i].in[1] <== 159; + and[35][i] = AND(); + and[35][i].a <== lt[26][i].out; + and[35][i].b <== lt[27][i].out; + and[36][i] = AND(); + and[36][i].a <== states[i][15]; + and[36][i].b <== and[35][i].out; + and[37][i] = AND(); + and[37][i].a <== states[i][19]; + and[37][i].b <== and[30][i].out; + and[38][i] = AND(); + and[38][i].a <== states[i][20]; + and[38][i].b <== and[30][i].out; + and[39][i] = AND(); + and[39][i].a <== states[i][21]; + and[39][i].b <== and[30][i].out; + and[40][i] = AND(); + and[40][i].a <== states[i][22]; + and[40][i].b <== and[30][i].out; + and[41][i] = AND(); + and[41][i].a <== states[i][23]; + and[41][i].b <== and[30][i].out; + and[42][i] = AND(); + and[42][i].a <== states[i][24]; + and[42][i].b <== and[30][i].out; + multi_or[8][i] = MultiOR(10); + multi_or[8][i].in[0] <== and[31][i].out; + multi_or[8][i].in[1] <== and[33][i].out; + multi_or[8][i].in[2] <== and[34][i].out; + multi_or[8][i].in[3] <== and[36][i].out; + multi_or[8][i].in[4] <== and[37][i].out; + multi_or[8][i].in[5] <== and[38][i].out; + multi_or[8][i].in[6] <== and[39][i].out; + multi_or[8][i].in[7] <== and[40][i].out; + multi_or[8][i].in[8] <== and[41][i].out; + multi_or[8][i].in[9] <== and[42][i].out; + states[i+1][12] <== multi_or[8][i].out; + eq[29][i] = IsEqual(); + eq[29][i].in[0] <== in[i]; + eq[29][i].in[1] <== 224; + and[43][i] = AND(); + and[43][i].a <== states[i][11]; + and[43][i].b <== eq[29][i].out; + and[44][i] = AND(); + and[44][i].a <== states[i][19]; + and[44][i].b <== eq[29][i].out; + and[45][i] = AND(); + and[45][i].a <== states[i][20]; + and[45][i].b <== eq[29][i].out; + and[46][i] = AND(); + and[46][i].a <== states[i][21]; + and[46][i].b <== eq[29][i].out; + and[47][i] = AND(); + and[47][i].a <== states[i][22]; + and[47][i].b <== eq[29][i].out; + and[48][i] = AND(); + and[48][i].a <== states[i][23]; + and[48][i].b <== eq[29][i].out; + and[49][i] = AND(); + and[49][i].a <== states[i][24]; + and[49][i].b <== eq[29][i].out; + multi_or[9][i] = MultiOR(7); + multi_or[9][i].in[0] <== and[43][i].out; + multi_or[9][i].in[1] <== and[44][i].out; + multi_or[9][i].in[2] <== and[45][i].out; + multi_or[9][i].in[3] <== and[46][i].out; + multi_or[9][i].in[4] <== and[47][i].out; + multi_or[9][i].in[5] <== and[48][i].out; + multi_or[9][i].in[6] <== and[49][i].out; + states[i+1][13] <== multi_or[9][i].out; + eq[30][i] = IsEqual(); + eq[30][i].in[0] <== in[i]; + eq[30][i].in[1] <== 225; + eq[31][i] = IsEqual(); + eq[31][i].in[0] <== in[i]; + eq[31][i].in[1] <== 226; + eq[32][i] = IsEqual(); + eq[32][i].in[0] <== in[i]; + eq[32][i].in[1] <== 227; + eq[33][i] = IsEqual(); + eq[33][i].in[0] <== in[i]; + eq[33][i].in[1] <== 228; + eq[34][i] = IsEqual(); + eq[34][i].in[0] <== in[i]; + eq[34][i].in[1] <== 229; + eq[35][i] = IsEqual(); + eq[35][i].in[0] <== in[i]; + eq[35][i].in[1] <== 230; + eq[36][i] = IsEqual(); + eq[36][i].in[0] <== in[i]; + eq[36][i].in[1] <== 231; + eq[37][i] = IsEqual(); + eq[37][i].in[0] <== in[i]; + eq[37][i].in[1] <== 232; + eq[38][i] = IsEqual(); + eq[38][i].in[0] <== in[i]; + eq[38][i].in[1] <== 233; + eq[39][i] = IsEqual(); + eq[39][i].in[0] <== in[i]; + eq[39][i].in[1] <== 234; + eq[40][i] = IsEqual(); + eq[40][i].in[0] <== in[i]; + eq[40][i].in[1] <== 235; + eq[41][i] = IsEqual(); + eq[41][i].in[0] <== in[i]; + eq[41][i].in[1] <== 236; + eq[42][i] = IsEqual(); + eq[42][i].in[0] <== in[i]; + eq[42][i].in[1] <== 238; + eq[43][i] = IsEqual(); + eq[43][i].in[0] <== in[i]; + eq[43][i].in[1] <== 239; + and[50][i] = AND(); + and[50][i].a <== states[i][11]; + multi_or[10][i] = MultiOR(14); + multi_or[10][i].in[0] <== eq[30][i].out; + multi_or[10][i].in[1] <== eq[31][i].out; + multi_or[10][i].in[2] <== eq[32][i].out; + multi_or[10][i].in[3] <== eq[33][i].out; + multi_or[10][i].in[4] <== eq[34][i].out; + multi_or[10][i].in[5] <== eq[35][i].out; + multi_or[10][i].in[6] <== eq[36][i].out; + multi_or[10][i].in[7] <== eq[37][i].out; + multi_or[10][i].in[8] <== eq[38][i].out; + multi_or[10][i].in[9] <== eq[39][i].out; + multi_or[10][i].in[10] <== eq[40][i].out; + multi_or[10][i].in[11] <== eq[41][i].out; + multi_or[10][i].in[12] <== eq[42][i].out; + multi_or[10][i].in[13] <== eq[43][i].out; + and[50][i].b <== multi_or[10][i].out; + lt[28][i] = LessEqThan(8); + lt[28][i].in[0] <== 144; + lt[28][i].in[1] <== in[i]; + lt[29][i] = LessEqThan(8); + lt[29][i].in[0] <== in[i]; + lt[29][i].in[1] <== 191; + and[51][i] = AND(); + and[51][i].a <== lt[28][i].out; + and[51][i].b <== lt[29][i].out; + and[52][i] = AND(); + and[52][i].a <== states[i][16]; + and[52][i].b <== and[51][i].out; + and[53][i] = AND(); + and[53][i].a <== states[i][17]; + and[53][i].b <== and[14][i].out; + eq[44][i] = IsEqual(); + eq[44][i].in[0] <== in[i]; + eq[44][i].in[1] <== 128; + eq[45][i] = IsEqual(); + eq[45][i].in[0] <== in[i]; + eq[45][i].in[1] <== 129; + eq[46][i] = IsEqual(); + eq[46][i].in[0] <== in[i]; + eq[46][i].in[1] <== 130; + eq[47][i] = IsEqual(); + eq[47][i].in[0] <== in[i]; + eq[47][i].in[1] <== 131; + eq[48][i] = IsEqual(); + eq[48][i].in[0] <== in[i]; + eq[48][i].in[1] <== 132; + eq[49][i] = IsEqual(); + eq[49][i].in[0] <== in[i]; + eq[49][i].in[1] <== 133; + eq[50][i] = IsEqual(); + eq[50][i].in[0] <== in[i]; + eq[50][i].in[1] <== 134; + eq[51][i] = IsEqual(); + eq[51][i].in[0] <== in[i]; + eq[51][i].in[1] <== 135; + eq[52][i] = IsEqual(); + eq[52][i].in[0] <== in[i]; + eq[52][i].in[1] <== 136; + eq[53][i] = IsEqual(); + eq[53][i].in[0] <== in[i]; + eq[53][i].in[1] <== 137; + eq[54][i] = IsEqual(); + eq[54][i].in[0] <== in[i]; + eq[54][i].in[1] <== 138; + eq[55][i] = IsEqual(); + eq[55][i].in[0] <== in[i]; + eq[55][i].in[1] <== 139; + eq[56][i] = IsEqual(); + eq[56][i].in[0] <== in[i]; + eq[56][i].in[1] <== 140; + eq[57][i] = IsEqual(); + eq[57][i].in[0] <== in[i]; + eq[57][i].in[1] <== 141; + eq[58][i] = IsEqual(); + eq[58][i].in[0] <== in[i]; + eq[58][i].in[1] <== 142; + eq[59][i] = IsEqual(); + eq[59][i].in[0] <== in[i]; + eq[59][i].in[1] <== 143; + and[54][i] = AND(); + and[54][i].a <== states[i][18]; + multi_or[11][i] = MultiOR(16); + multi_or[11][i].in[0] <== eq[44][i].out; + multi_or[11][i].in[1] <== eq[45][i].out; + multi_or[11][i].in[2] <== eq[46][i].out; + multi_or[11][i].in[3] <== eq[47][i].out; + multi_or[11][i].in[4] <== eq[48][i].out; + multi_or[11][i].in[5] <== eq[49][i].out; + multi_or[11][i].in[6] <== eq[50][i].out; + multi_or[11][i].in[7] <== eq[51][i].out; + multi_or[11][i].in[8] <== eq[52][i].out; + multi_or[11][i].in[9] <== eq[53][i].out; + multi_or[11][i].in[10] <== eq[54][i].out; + multi_or[11][i].in[11] <== eq[55][i].out; + multi_or[11][i].in[12] <== eq[56][i].out; + multi_or[11][i].in[13] <== eq[57][i].out; + multi_or[11][i].in[14] <== eq[58][i].out; + multi_or[11][i].in[15] <== eq[59][i].out; + and[54][i].b <== multi_or[11][i].out; + and[55][i] = AND(); + and[55][i].a <== states[i][19]; + and[55][i].b <== multi_or[10][i].out; + and[56][i] = AND(); + and[56][i].a <== states[i][20]; + and[56][i].b <== multi_or[10][i].out; + and[57][i] = AND(); + and[57][i].a <== states[i][21]; + and[57][i].b <== multi_or[10][i].out; + and[58][i] = AND(); + and[58][i].a <== states[i][22]; + and[58][i].b <== multi_or[10][i].out; + and[59][i] = AND(); + and[59][i].a <== states[i][23]; + and[59][i].b <== multi_or[10][i].out; + and[60][i] = AND(); + and[60][i].a <== states[i][24]; + and[60][i].b <== multi_or[10][i].out; + multi_or[12][i] = MultiOR(10); + multi_or[12][i].in[0] <== and[50][i].out; + multi_or[12][i].in[1] <== and[52][i].out; + multi_or[12][i].in[2] <== and[53][i].out; + multi_or[12][i].in[3] <== and[54][i].out; + multi_or[12][i].in[4] <== and[55][i].out; + multi_or[12][i].in[5] <== and[56][i].out; + multi_or[12][i].in[6] <== and[57][i].out; + multi_or[12][i].in[7] <== and[58][i].out; + multi_or[12][i].in[8] <== and[59][i].out; + multi_or[12][i].in[9] <== and[60][i].out; + states[i+1][14] <== multi_or[12][i].out; + eq[60][i] = IsEqual(); + eq[60][i].in[0] <== in[i]; + eq[60][i].in[1] <== 237; + and[61][i] = AND(); + and[61][i].a <== states[i][11]; + and[61][i].b <== eq[60][i].out; + and[62][i] = AND(); + and[62][i].a <== states[i][19]; + and[62][i].b <== eq[60][i].out; + and[63][i] = AND(); + and[63][i].a <== states[i][20]; + and[63][i].b <== eq[60][i].out; + and[64][i] = AND(); + and[64][i].a <== states[i][21]; + and[64][i].b <== eq[60][i].out; + and[65][i] = AND(); + and[65][i].a <== states[i][22]; + and[65][i].b <== eq[60][i].out; + and[66][i] = AND(); + and[66][i].a <== states[i][23]; + and[66][i].b <== eq[60][i].out; + and[67][i] = AND(); + and[67][i].a <== states[i][24]; + and[67][i].b <== eq[60][i].out; + multi_or[13][i] = MultiOR(7); + multi_or[13][i].in[0] <== and[61][i].out; + multi_or[13][i].in[1] <== and[62][i].out; + multi_or[13][i].in[2] <== and[63][i].out; + multi_or[13][i].in[3] <== and[64][i].out; + multi_or[13][i].in[4] <== and[65][i].out; + multi_or[13][i].in[5] <== and[66][i].out; + multi_or[13][i].in[6] <== and[67][i].out; + states[i+1][15] <== multi_or[13][i].out; + eq[61][i] = IsEqual(); + eq[61][i].in[0] <== in[i]; + eq[61][i].in[1] <== 240; + and[68][i] = AND(); + and[68][i].a <== states[i][11]; + and[68][i].b <== eq[61][i].out; + and[69][i] = AND(); + and[69][i].a <== states[i][19]; + and[69][i].b <== eq[61][i].out; + and[70][i] = AND(); + and[70][i].a <== states[i][20]; + and[70][i].b <== eq[61][i].out; + and[71][i] = AND(); + and[71][i].a <== states[i][21]; + and[71][i].b <== eq[61][i].out; + and[72][i] = AND(); + and[72][i].a <== states[i][22]; + and[72][i].b <== eq[61][i].out; + and[73][i] = AND(); + and[73][i].a <== states[i][23]; + and[73][i].b <== eq[61][i].out; + and[74][i] = AND(); + and[74][i].a <== states[i][24]; + and[74][i].b <== eq[61][i].out; + multi_or[14][i] = MultiOR(7); + multi_or[14][i].in[0] <== and[68][i].out; + multi_or[14][i].in[1] <== and[69][i].out; + multi_or[14][i].in[2] <== and[70][i].out; + multi_or[14][i].in[3] <== and[71][i].out; + multi_or[14][i].in[4] <== and[72][i].out; + multi_or[14][i].in[5] <== and[73][i].out; + multi_or[14][i].in[6] <== and[74][i].out; + states[i+1][16] <== multi_or[14][i].out; + eq[62][i] = IsEqual(); + eq[62][i].in[0] <== in[i]; + eq[62][i].in[1] <== 241; + eq[63][i] = IsEqual(); + eq[63][i].in[0] <== in[i]; + eq[63][i].in[1] <== 242; + eq[64][i] = IsEqual(); + eq[64][i].in[0] <== in[i]; + eq[64][i].in[1] <== 243; + and[75][i] = AND(); + and[75][i].a <== states[i][11]; + multi_or[15][i] = MultiOR(3); + multi_or[15][i].in[0] <== eq[62][i].out; + multi_or[15][i].in[1] <== eq[63][i].out; + multi_or[15][i].in[2] <== eq[64][i].out; + and[75][i].b <== multi_or[15][i].out; + and[76][i] = AND(); + and[76][i].a <== states[i][19]; + and[76][i].b <== multi_or[15][i].out; + and[77][i] = AND(); + and[77][i].a <== states[i][20]; + and[77][i].b <== multi_or[15][i].out; + and[78][i] = AND(); + and[78][i].a <== states[i][21]; + and[78][i].b <== multi_or[15][i].out; + and[79][i] = AND(); + and[79][i].a <== states[i][22]; + and[79][i].b <== multi_or[15][i].out; + and[80][i] = AND(); + and[80][i].a <== states[i][23]; + and[80][i].b <== multi_or[15][i].out; + and[81][i] = AND(); + and[81][i].a <== states[i][24]; + and[81][i].b <== multi_or[15][i].out; + multi_or[16][i] = MultiOR(7); + multi_or[16][i].in[0] <== and[75][i].out; + multi_or[16][i].in[1] <== and[76][i].out; + multi_or[16][i].in[2] <== and[77][i].out; + multi_or[16][i].in[3] <== and[78][i].out; + multi_or[16][i].in[4] <== and[79][i].out; + multi_or[16][i].in[5] <== and[80][i].out; + multi_or[16][i].in[6] <== and[81][i].out; + states[i+1][17] <== multi_or[16][i].out; + eq[65][i] = IsEqual(); + eq[65][i].in[0] <== in[i]; + eq[65][i].in[1] <== 244; + and[82][i] = AND(); + and[82][i].a <== states[i][11]; + and[82][i].b <== eq[65][i].out; + and[83][i] = AND(); + and[83][i].a <== states[i][19]; + and[83][i].b <== eq[65][i].out; + and[84][i] = AND(); + and[84][i].a <== states[i][20]; + and[84][i].b <== eq[65][i].out; + and[85][i] = AND(); + and[85][i].a <== states[i][21]; + and[85][i].b <== eq[65][i].out; + and[86][i] = AND(); + and[86][i].a <== states[i][22]; + and[86][i].b <== eq[65][i].out; + and[87][i] = AND(); + and[87][i].a <== states[i][23]; + and[87][i].b <== eq[65][i].out; + and[88][i] = AND(); + and[88][i].a <== states[i][24]; + and[88][i].b <== eq[65][i].out; + multi_or[17][i] = MultiOR(7); + multi_or[17][i].in[0] <== and[82][i].out; + multi_or[17][i].in[1] <== and[83][i].out; + multi_or[17][i].in[2] <== and[84][i].out; + multi_or[17][i].in[3] <== and[85][i].out; + multi_or[17][i].in[4] <== and[86][i].out; + multi_or[17][i].in[5] <== and[87][i].out; + multi_or[17][i].in[6] <== and[88][i].out; + states[i+1][18] <== multi_or[17][i].out; + eq[66][i] = IsEqual(); + eq[66][i].in[0] <== in[i]; + eq[66][i].in[1] <== 122; + and[89][i] = AND(); + and[89][i].a <== states[i][11]; + and[89][i].b <== eq[66][i].out; + and[90][i] = AND(); + and[90][i].a <== states[i][19]; + and[90][i].b <== eq[66][i].out; + and[91][i] = AND(); + and[91][i].a <== states[i][20]; + and[91][i].b <== eq[66][i].out; + and[92][i] = AND(); + and[92][i].a <== states[i][21]; + and[92][i].b <== eq[66][i].out; + and[93][i] = AND(); + and[93][i].a <== states[i][22]; + and[93][i].b <== eq[66][i].out; + and[94][i] = AND(); + and[94][i].a <== states[i][23]; + and[94][i].b <== eq[66][i].out; + and[95][i] = AND(); + and[95][i].a <== states[i][24]; + and[95][i].b <== eq[66][i].out; + multi_or[18][i] = MultiOR(7); + multi_or[18][i].in[0] <== and[89][i].out; + multi_or[18][i].in[1] <== and[90][i].out; + multi_or[18][i].in[2] <== and[91][i].out; + multi_or[18][i].in[3] <== and[92][i].out; + multi_or[18][i].in[4] <== and[93][i].out; + multi_or[18][i].in[5] <== and[94][i].out; + multi_or[18][i].in[6] <== and[95][i].out; + states[i+1][19] <== multi_or[18][i].out; + and[96][i] = AND(); + and[96][i].a <== states[i][19]; + and[96][i].b <== eq[28][i].out; + states[i+1][20] <== and[96][i].out; + eq[67][i] = IsEqual(); + eq[67][i].in[0] <== in[i]; + eq[67][i].in[1] <== 101; + and[97][i] = AND(); + and[97][i].a <== states[i][20]; + and[97][i].b <== eq[67][i].out; + states[i+1][21] <== and[97][i].out; + and[98][i] = AND(); + and[98][i].a <== states[i][21]; + and[98][i].b <== eq[15][i].out; + states[i+1][22] <== and[98][i].out; + eq[68][i] = IsEqual(); + eq[68][i].in[0] <== in[i]; + eq[68][i].in[1] <== 97; + and[99][i] = AND(); + and[99][i].a <== states[i][22]; + and[99][i].b <== eq[68][i].out; + states[i+1][23] <== and[99][i].out; + and[100][i] = AND(); + and[100][i].a <== states[i][23]; + and[100][i].b <== eq[2][i].out; + states[i+1][24] <== and[100][i].out; + and[101][i] = AND(); + and[101][i].a <== states[i][24]; + and[101][i].b <== eq[14][i].out; + lt[30][i] = LessEqThan(8); + lt[30][i].in[0] <== 35; + lt[30][i].in[1] <== in[i]; + lt[31][i] = LessEqThan(8); + lt[31][i].in[0] <== in[i]; + lt[31][i].in[1] <== 127; + and[102][i] = AND(); + and[102][i].a <== lt[30][i].out; + and[102][i].b <== lt[31][i].out; + and[103][i] = AND(); + and[103][i].a <== states[i][25]; + multi_or[19][i] = MultiOR(2); + multi_or[19][i].in[0] <== and[11][i].out; + multi_or[19][i].in[1] <== and[102][i].out; + and[103][i].b <== multi_or[19][i].out; + and[104][i] = AND(); + and[104][i].a <== states[i][27]; + and[104][i].b <== and[14][i].out; + multi_or[20][i] = MultiOR(3); + multi_or[20][i].in[0] <== and[101][i].out; + multi_or[20][i].in[1] <== and[103][i].out; + multi_or[20][i].in[2] <== and[104][i].out; + states[i+1][25] <== multi_or[20][i].out; + and[105][i] = AND(); + and[105][i].a <== states[i][25]; + and[105][i].b <== eq[8][i].out; + lt[32][i] = LessEqThan(8); + lt[32][i].in[0] <== 1; + lt[32][i].in[1] <== in[i]; + lt[33][i] = LessEqThan(8); + lt[33][i].in[0] <== in[i]; + lt[33][i].in[1] <== 61; + and[106][i] = AND(); + and[106][i].a <== lt[32][i].out; + and[106][i].b <== lt[33][i].out; + lt[34][i] = LessEqThan(8); + lt[34][i].in[0] <== 63; + lt[34][i].in[1] <== in[i]; + lt[35][i] = LessEqThan(8); + lt[35][i].in[0] <== in[i]; + lt[35][i].in[1] <== 127; + and[107][i] = AND(); + and[107][i].a <== lt[34][i].out; + and[107][i].b <== lt[35][i].out; + and[108][i] = AND(); + and[108][i].a <== states[i][26]; + multi_or[21][i] = MultiOR(2); + multi_or[21][i].in[0] <== and[106][i].out; + multi_or[21][i].in[1] <== and[107][i].out; + and[108][i].b <== multi_or[21][i].out; + and[109][i] = AND(); + and[109][i].a <== states[i][35]; + and[109][i].b <== and[14][i].out; + multi_or[22][i] = MultiOR(3); + multi_or[22][i].in[0] <== and[105][i].out; + multi_or[22][i].in[1] <== and[108][i].out; + multi_or[22][i].in[2] <== and[109][i].out; + states[i+1][26] <== multi_or[22][i].out; + and[110][i] = AND(); + and[110][i].a <== states[i][25]; + and[110][i].b <== and[30][i].out; + and[111][i] = AND(); + and[111][i].a <== states[i][28]; + and[111][i].b <== and[32][i].out; + and[112][i] = AND(); + and[112][i].a <== states[i][29]; + and[112][i].b <== and[14][i].out; + and[113][i] = AND(); + and[113][i].a <== states[i][30]; + and[113][i].b <== and[35][i].out; + multi_or[23][i] = MultiOR(4); + multi_or[23][i].in[0] <== and[110][i].out; + multi_or[23][i].in[1] <== and[111][i].out; + multi_or[23][i].in[2] <== and[112][i].out; + multi_or[23][i].in[3] <== and[113][i].out; + states[i+1][27] <== multi_or[23][i].out; + and[114][i] = AND(); + and[114][i].a <== states[i][25]; + and[114][i].b <== eq[29][i].out; + states[i+1][28] <== and[114][i].out; + and[115][i] = AND(); + and[115][i].a <== states[i][25]; + and[115][i].b <== multi_or[10][i].out; + and[116][i] = AND(); + and[116][i].a <== states[i][31]; + and[116][i].b <== and[51][i].out; + and[117][i] = AND(); + and[117][i].a <== states[i][32]; + and[117][i].b <== and[14][i].out; + and[118][i] = AND(); + and[118][i].a <== states[i][33]; + and[118][i].b <== multi_or[11][i].out; + multi_or[24][i] = MultiOR(4); + multi_or[24][i].in[0] <== and[115][i].out; + multi_or[24][i].in[1] <== and[116][i].out; + multi_or[24][i].in[2] <== and[117][i].out; + multi_or[24][i].in[3] <== and[118][i].out; + states[i+1][29] <== multi_or[24][i].out; + and[119][i] = AND(); + and[119][i].a <== states[i][25]; + and[119][i].b <== eq[60][i].out; + states[i+1][30] <== and[119][i].out; + and[120][i] = AND(); + and[120][i].a <== states[i][25]; + and[120][i].b <== eq[61][i].out; + states[i+1][31] <== and[120][i].out; + and[121][i] = AND(); + and[121][i].a <== states[i][25]; + and[121][i].b <== multi_or[15][i].out; + states[i+1][32] <== and[121][i].out; + and[122][i] = AND(); + and[122][i].a <== states[i][25]; + and[122][i].b <== eq[65][i].out; + states[i+1][33] <== and[122][i].out; + eq[69][i] = IsEqual(); + eq[69][i].in[0] <== in[i]; + eq[69][i].in[1] <== 62; + and[123][i] = AND(); + and[123][i].a <== states[i][26]; + and[123][i].b <== eq[69][i].out; + states[i+1][34] <== and[123][i].out; + and[124][i] = AND(); + and[124][i].a <== states[i][26]; + and[124][i].b <== and[30][i].out; + and[125][i] = AND(); + and[125][i].a <== states[i][36]; + and[125][i].b <== and[32][i].out; + and[126][i] = AND(); + and[126][i].a <== states[i][37]; + and[126][i].b <== and[14][i].out; + and[127][i] = AND(); + and[127][i].a <== states[i][38]; + and[127][i].b <== and[35][i].out; + multi_or[25][i] = MultiOR(4); + multi_or[25][i].in[0] <== and[124][i].out; + multi_or[25][i].in[1] <== and[125][i].out; + multi_or[25][i].in[2] <== and[126][i].out; + multi_or[25][i].in[3] <== and[127][i].out; + states[i+1][35] <== multi_or[25][i].out; + and[128][i] = AND(); + and[128][i].a <== states[i][26]; + and[128][i].b <== eq[29][i].out; + states[i+1][36] <== and[128][i].out; + and[129][i] = AND(); + and[129][i].a <== states[i][26]; + and[129][i].b <== multi_or[10][i].out; + and[130][i] = AND(); + and[130][i].a <== states[i][39]; + and[130][i].b <== and[51][i].out; + and[131][i] = AND(); + and[131][i].a <== states[i][40]; + and[131][i].b <== and[14][i].out; + and[132][i] = AND(); + and[132][i].a <== states[i][41]; + and[132][i].b <== multi_or[11][i].out; + multi_or[26][i] = MultiOR(4); + multi_or[26][i].in[0] <== and[129][i].out; + multi_or[26][i].in[1] <== and[130][i].out; + multi_or[26][i].in[2] <== and[131][i].out; + multi_or[26][i].in[3] <== and[132][i].out; + states[i+1][37] <== multi_or[26][i].out; + and[133][i] = AND(); + and[133][i].a <== states[i][26]; + and[133][i].b <== eq[60][i].out; + states[i+1][38] <== and[133][i].out; + and[134][i] = AND(); + and[134][i].a <== states[i][26]; + and[134][i].b <== eq[61][i].out; + states[i+1][39] <== and[134][i].out; + and[135][i] = AND(); + and[135][i].a <== states[i][26]; + and[135][i].b <== multi_or[15][i].out; + states[i+1][40] <== and[135][i].out; + and[136][i] = AND(); + and[136][i].a <== states[i][26]; + and[136][i].b <== eq[65][i].out; + states[i+1][41] <== and[136][i].out; + lt[36][i] = LessEqThan(8); + lt[36][i].in[0] <== 1; + lt[36][i].in[1] <== in[i]; + lt[37][i] = LessEqThan(8); + lt[37][i].in[0] <== in[i]; + lt[37][i].in[1] <== 46; + and[137][i] = AND(); + and[137][i].a <== lt[36][i].out; + and[137][i].b <== lt[37][i].out; + eq[70][i] = IsEqual(); + eq[70][i].in[0] <== in[i]; + eq[70][i].in[1] <== 48; + eq[71][i] = IsEqual(); + eq[71][i].in[0] <== in[i]; + eq[71][i].in[1] <== 49; + eq[72][i] = IsEqual(); + eq[72][i].in[0] <== in[i]; + eq[72][i].in[1] <== 50; + eq[73][i] = IsEqual(); + eq[73][i].in[0] <== in[i]; + eq[73][i].in[1] <== 52; + eq[74][i] = IsEqual(); + eq[74][i].in[0] <== in[i]; + eq[74][i].in[1] <== 53; + eq[75][i] = IsEqual(); + eq[75][i].in[0] <== in[i]; + eq[75][i].in[1] <== 54; + eq[76][i] = IsEqual(); + eq[76][i].in[0] <== in[i]; + eq[76][i].in[1] <== 55; + eq[77][i] = IsEqual(); + eq[77][i].in[0] <== in[i]; + eq[77][i].in[1] <== 56; + eq[78][i] = IsEqual(); + eq[78][i].in[0] <== in[i]; + eq[78][i].in[1] <== 57; + eq[79][i] = IsEqual(); + eq[79][i].in[0] <== in[i]; + eq[79][i].in[1] <== 58; + eq[80][i] = IsEqual(); + eq[80][i].in[0] <== in[i]; + eq[80][i].in[1] <== 59; + and[138][i] = AND(); + and[138][i].a <== states[i][34]; + multi_or[27][i] = MultiOR(15); + multi_or[27][i].in[0] <== and[137][i].out; + multi_or[27][i].in[1] <== and[107][i].out; + multi_or[27][i].in[2] <== eq[70][i].out; + multi_or[27][i].in[3] <== eq[71][i].out; + multi_or[27][i].in[4] <== eq[72][i].out; + multi_or[27][i].in[5] <== eq[6][i].out; + multi_or[27][i].in[6] <== eq[73][i].out; + multi_or[27][i].in[7] <== eq[74][i].out; + multi_or[27][i].in[8] <== eq[75][i].out; + multi_or[27][i].in[9] <== eq[76][i].out; + multi_or[27][i].in[10] <== eq[77][i].out; + multi_or[27][i].in[11] <== eq[78][i].out; + multi_or[27][i].in[12] <== eq[79][i].out; + multi_or[27][i].in[13] <== eq[80][i].out; + multi_or[27][i].in[14] <== eq[5][i].out; + and[138][i].b <== multi_or[27][i].out; + and[139][i] = AND(); + and[139][i].a <== states[i][42]; + and[139][i].b <== multi_or[27][i].out; + and[140][i] = AND(); + and[140][i].a <== states[i][43]; + and[140][i].b <== and[14][i].out; + multi_or[28][i] = MultiOR(3); + multi_or[28][i].in[0] <== and[138][i].out; + multi_or[28][i].in[1] <== and[139][i].out; + multi_or[28][i].in[2] <== and[140][i].out; + states[i+1][42] <== multi_or[28][i].out; + and[141][i] = AND(); + and[141][i].a <== states[i][34]; + and[141][i].b <== and[30][i].out; + and[142][i] = AND(); + and[142][i].a <== states[i][42]; + and[142][i].b <== and[30][i].out; + and[143][i] = AND(); + and[143][i].a <== states[i][44]; + and[143][i].b <== and[32][i].out; + and[144][i] = AND(); + and[144][i].a <== states[i][45]; + and[144][i].b <== and[14][i].out; + and[145][i] = AND(); + and[145][i].a <== states[i][46]; + and[145][i].b <== and[35][i].out; + multi_or[29][i] = MultiOR(5); + multi_or[29][i].in[0] <== and[141][i].out; + multi_or[29][i].in[1] <== and[142][i].out; + multi_or[29][i].in[2] <== and[143][i].out; + multi_or[29][i].in[3] <== and[144][i].out; + multi_or[29][i].in[4] <== and[145][i].out; + states[i+1][43] <== multi_or[29][i].out; + and[146][i] = AND(); + and[146][i].a <== states[i][34]; + and[146][i].b <== eq[29][i].out; + and[147][i] = AND(); + and[147][i].a <== states[i][42]; + and[147][i].b <== eq[29][i].out; + multi_or[30][i] = MultiOR(2); + multi_or[30][i].in[0] <== and[146][i].out; + multi_or[30][i].in[1] <== and[147][i].out; + states[i+1][44] <== multi_or[30][i].out; + and[148][i] = AND(); + and[148][i].a <== states[i][34]; + and[148][i].b <== multi_or[10][i].out; + and[149][i] = AND(); + and[149][i].a <== states[i][42]; + and[149][i].b <== multi_or[10][i].out; + and[150][i] = AND(); + and[150][i].a <== states[i][47]; + and[150][i].b <== and[51][i].out; + and[151][i] = AND(); + and[151][i].a <== states[i][48]; + and[151][i].b <== and[14][i].out; + and[152][i] = AND(); + and[152][i].a <== states[i][49]; + and[152][i].b <== multi_or[11][i].out; + multi_or[31][i] = MultiOR(5); + multi_or[31][i].in[0] <== and[148][i].out; + multi_or[31][i].in[1] <== and[149][i].out; + multi_or[31][i].in[2] <== and[150][i].out; + multi_or[31][i].in[3] <== and[151][i].out; + multi_or[31][i].in[4] <== and[152][i].out; + states[i+1][45] <== multi_or[31][i].out; + and[153][i] = AND(); + and[153][i].a <== states[i][34]; + and[153][i].b <== eq[60][i].out; + and[154][i] = AND(); + and[154][i].a <== states[i][42]; + and[154][i].b <== eq[60][i].out; + multi_or[32][i] = MultiOR(2); + multi_or[32][i].in[0] <== and[153][i].out; + multi_or[32][i].in[1] <== and[154][i].out; + states[i+1][46] <== multi_or[32][i].out; + and[155][i] = AND(); + and[155][i].a <== states[i][34]; + and[155][i].b <== eq[61][i].out; + and[156][i] = AND(); + and[156][i].a <== states[i][42]; + and[156][i].b <== eq[61][i].out; + multi_or[33][i] = MultiOR(2); + multi_or[33][i].in[0] <== and[155][i].out; + multi_or[33][i].in[1] <== and[156][i].out; + states[i+1][47] <== multi_or[33][i].out; + and[157][i] = AND(); + and[157][i].a <== states[i][34]; + and[157][i].b <== multi_or[15][i].out; + and[158][i] = AND(); + and[158][i].a <== states[i][42]; + and[158][i].b <== multi_or[15][i].out; + multi_or[34][i] = MultiOR(2); + multi_or[34][i].in[0] <== and[157][i].out; + multi_or[34][i].in[1] <== and[158][i].out; + states[i+1][48] <== multi_or[34][i].out; + and[159][i] = AND(); + and[159][i].a <== states[i][34]; + and[159][i].b <== eq[65][i].out; + and[160][i] = AND(); + and[160][i].a <== states[i][42]; + and[160][i].b <== eq[65][i].out; + multi_or[35][i] = MultiOR(2); + multi_or[35][i].in[0] <== and[159][i].out; + multi_or[35][i].in[1] <== and[160][i].out; + states[i+1][49] <== multi_or[35][i].out; + and[161][i] = AND(); + and[161][i].a <== states[i][42]; + and[161][i].b <== eq[0][i].out; + states[i+1][50] <== and[161][i].out; + eq[81][i] = IsEqual(); + eq[81][i].in[0] <== in[i]; + eq[81][i].in[1] <== 47; + and[162][i] = AND(); + and[162][i].a <== states[i][50]; + and[162][i].b <== eq[81][i].out; + states[i+1][51] <== and[162][i].out; + and[163][i] = AND(); + and[163][i].a <== states[i][51]; + and[163][i].b <== eq[1][i].out; + states[i+1][52] <== and[163][i].out; + and[164][i] = AND(); + and[164][i].a <== states[i][52]; + and[164][i].b <== eq[2][i].out; + states[i+1][53] <== and[164][i].out; + and[165][i] = AND(); + and[165][i].a <== states[i][53]; + and[165][i].b <== eq[3][i].out; + states[i+1][54] <== and[165][i].out; + and[166][i] = AND(); + and[166][i].a <== states[i][54]; + and[166][i].b <== eq[69][i].out; + states[i+1][55] <== and[166][i].out; + from_zero_enabled[i] <== MultiNOR(55)([states_tmp[i+1][1], states[i+1][2], states[i+1][3], states[i+1][4], states[i+1][5], states[i+1][6], states[i+1][7], states[i+1][8], states[i+1][9], states[i+1][10], states[i+1][11], states[i+1][12], states[i+1][13], states[i+1][14], states[i+1][15], states[i+1][16], states[i+1][17], states[i+1][18], states[i+1][19], states[i+1][20], states[i+1][21], states[i+1][22], states[i+1][23], states[i+1][24], states[i+1][25], states[i+1][26], states[i+1][27], states[i+1][28], states[i+1][29], states[i+1][30], states[i+1][31], states[i+1][32], states[i+1][33], states[i+1][34], states[i+1][35], states[i+1][36], states[i+1][37], states[i+1][38], states[i+1][39], states[i+1][40], states[i+1][41], states[i+1][42], states[i+1][43], states[i+1][44], states[i+1][45], states[i+1][46], states[i+1][47], states[i+1][48], states[i+1][49], states[i+1][50], states[i+1][51], states[i+1][52], states[i+1][53], states[i+1][54], states[i+1][55]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + state_changed[i].in[2] <== states[i+1][3]; + state_changed[i].in[3] <== states[i+1][4]; + state_changed[i].in[4] <== states[i+1][5]; + state_changed[i].in[5] <== states[i+1][6]; + state_changed[i].in[6] <== states[i+1][7]; + state_changed[i].in[7] <== states[i+1][8]; + state_changed[i].in[8] <== states[i+1][9]; + state_changed[i].in[9] <== states[i+1][10]; + state_changed[i].in[10] <== states[i+1][11]; + state_changed[i].in[11] <== states[i+1][12]; + state_changed[i].in[12] <== states[i+1][13]; + state_changed[i].in[13] <== states[i+1][14]; + state_changed[i].in[14] <== states[i+1][15]; + state_changed[i].in[15] <== states[i+1][16]; + state_changed[i].in[16] <== states[i+1][17]; + state_changed[i].in[17] <== states[i+1][18]; + state_changed[i].in[18] <== states[i+1][19]; + state_changed[i].in[19] <== states[i+1][20]; + state_changed[i].in[20] <== states[i+1][21]; + state_changed[i].in[21] <== states[i+1][22]; + state_changed[i].in[22] <== states[i+1][23]; + state_changed[i].in[23] <== states[i+1][24]; + state_changed[i].in[24] <== states[i+1][25]; + state_changed[i].in[25] <== states[i+1][26]; + state_changed[i].in[26] <== states[i+1][27]; + state_changed[i].in[27] <== states[i+1][28]; + state_changed[i].in[28] <== states[i+1][29]; + state_changed[i].in[29] <== states[i+1][30]; + state_changed[i].in[30] <== states[i+1][31]; + state_changed[i].in[31] <== states[i+1][32]; + state_changed[i].in[32] <== states[i+1][33]; + state_changed[i].in[33] <== states[i+1][34]; + state_changed[i].in[34] <== states[i+1][35]; + state_changed[i].in[35] <== states[i+1][36]; + state_changed[i].in[36] <== states[i+1][37]; + state_changed[i].in[37] <== states[i+1][38]; + state_changed[i].in[38] <== states[i+1][39]; + state_changed[i].in[39] <== states[i+1][40]; + state_changed[i].in[40] <== states[i+1][41]; + state_changed[i].in[41] <== states[i+1][42]; + state_changed[i].in[42] <== states[i+1][43]; + state_changed[i].in[43] <== states[i+1][44]; + state_changed[i].in[44] <== states[i+1][45]; + state_changed[i].in[45] <== states[i+1][46]; + state_changed[i].in[46] <== states[i+1][47]; + state_changed[i].in[47] <== states[i+1][48]; + state_changed[i].in[48] <== states[i+1][49]; + state_changed[i].in[49] <== states[i+1][50]; + state_changed[i].in[50] <== states[i+1][51]; + state_changed[i].in[51] <== states[i+1][52]; + state_changed[i].in[52] <== states[i+1][53]; + state_changed[i].in[53] <== states[i+1][54]; + state_changed[i].in[54] <== states[i+1][55]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][55]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][55] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][55], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [{(34, 42), (34, 43), (34, 44), (34, 45), (34, 46), (34, 47), (34, 48), (34, 49), (42, 42), (42, 43), (42, 44), (42, 45), (42, 46), (42, 47), (42, 48), (42, 49), (43, 42), (44, 43), (45, 43), (46, 43), (47, 45), (48, 45), (49, 45)}] + signal prev_states0[23][msg_bytes]; + signal is_substr0[msg_bytes]; + signal is_reveal0[msg_bytes]; + signal output reveal0[msg_bytes]; + for (var i = 0; i < msg_bytes; i++) { + // the 0-th substring transitions: [(34, 42), (34, 43), (34, 44), (34, 45), (34, 46), (34, 47), (34, 48), (34, 49), (42, 42), (42, 43), (42, 44), (42, 45), (42, 46), (42, 47), (42, 48), (42, 49), (43, 42), (44, 43), (45, 43), (46, 43), (47, 45), (48, 45), (49, 45)] + prev_states0[0][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][34]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][34]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][34]; + prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][34]; + prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][34]; + prev_states0[5][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][34]; + prev_states0[6][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][34]; + prev_states0[7][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][34]; + prev_states0[8][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][42]; + prev_states0[9][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][42]; + prev_states0[10][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][42]; + prev_states0[11][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][42]; + prev_states0[12][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][42]; + prev_states0[13][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][42]; + prev_states0[14][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][42]; + prev_states0[15][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][42]; + prev_states0[16][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][43]; + prev_states0[17][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][44]; + prev_states0[18][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][45]; + prev_states0[19][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][46]; + prev_states0[20][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][47]; + prev_states0[21][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][48]; + prev_states0[22][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][49]; + is_substr0[i] <== MultiOR(23)([prev_states0[0][i] * states[i+2][42], prev_states0[1][i] * states[i+2][43], prev_states0[2][i] * states[i+2][44], prev_states0[3][i] * states[i+2][45], prev_states0[4][i] * states[i+2][46], prev_states0[5][i] * states[i+2][47], prev_states0[6][i] * states[i+2][48], prev_states0[7][i] * states[i+2][49], prev_states0[8][i] * states[i+2][42], prev_states0[9][i] * states[i+2][43], prev_states0[10][i] * states[i+2][44], prev_states0[11][i] * states[i+2][45], prev_states0[12][i] * states[i+2][46], prev_states0[13][i] * states[i+2][47], prev_states0[14][i] * states[i+2][48], prev_states0[15][i] * states[i+2][49], prev_states0[16][i] * states[i+2][42], prev_states0[17][i] * states[i+2][43], prev_states0[18][i] * states[i+2][43], prev_states0[19][i] * states[i+2][43], prev_states0[20][i] * states[i+2][45], prev_states0[21][i] * states[i+2][45], prev_states0[22][i] * states[i+2][45]]); + is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); + reveal0[i] <== in[i+1] * is_reveal0[i]; + } +} \ No newline at end of file diff --git a/packages/circuits/src/regexes/forced_subject.json b/packages/circuits/src/regexes/forced_subject.json new file mode 100644 index 00000000..939953f6 --- /dev/null +++ b/packages/circuits/src/regexes/forced_subject.json @@ -0,0 +1,8 @@ +{ + "parts": [ + { + "is_public": false, + "regex_def": "(\r\n|^)subject:((re: )|(RE: )|(Re: )|(fwd: )|(FWD: )|(Fwd: ))*\\[Reply Needed\\][^\r\n]*\r\n" + } + ] +} \ No newline at end of file diff --git a/packages/circuits/src/regexes/forced_subject_regex.circom b/packages/circuits/src/regexes/forced_subject_regex.circom new file mode 100644 index 00000000..9e18a20f --- /dev/null +++ b/packages/circuits/src/regexes/forced_subject_regex.circom @@ -0,0 +1,656 @@ +pragma circom 2.1.5; + +include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; + +// regex: (\r\n|^)subject:((re: )|(RE: )|(Re: )|(fwd: )|(FWD: )|(Fwd: ))*\[Reply Needed\][^\r\n]*\r\n +template ForcedSubjectRegex(msg_bytes) { + signal input msg[msg_bytes]; + signal output out; + + var num_bytes = msg_bytes+1; + signal in[num_bytes]; + in[0]<==255; + for (var i = 0; i < msg_bytes; i++) { + _ <== LessThan(8)([msg[i], 255]); + in[i+1] <== msg[i]; + } + + component eq[75][num_bytes]; + component lt[12][num_bytes]; + component and[61][num_bytes]; + component multi_or[11][num_bytes]; + signal states[num_bytes+1][42]; + signal states_tmp[num_bytes+1][42]; + signal from_zero_enabled[num_bytes+1]; + from_zero_enabled[num_bytes] <== 0; + component state_changed[num_bytes]; + + for (var i = 1; i < 42; i++) { + states[0][i] <== 0; + } + + for (var i = 0; i < num_bytes; i++) { + state_changed[i] = MultiOR(41); + states[i][0] <== 1; + eq[0][i] = IsEqual(); + eq[0][i].in[0] <== in[i]; + eq[0][i].in[1] <== 13; + and[0][i] = AND(); + and[0][i].a <== states[i][0]; + and[0][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== 0; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 255; + and[1][i] = AND(); + and[1][i].a <== states[i][0]; + and[1][i].b <== eq[1][i].out; + eq[2][i] = IsEqual(); + eq[2][i].in[0] <== in[i]; + eq[2][i].in[1] <== 10; + and[2][i] = AND(); + and[2][i].a <== states[i][1]; + and[2][i].b <== eq[2][i].out; + states_tmp[i+1][2] <== and[2][i].out; + eq[3][i] = IsEqual(); + eq[3][i].in[0] <== in[i]; + eq[3][i].in[1] <== 115; + and[3][i] = AND(); + and[3][i].a <== states[i][2]; + and[3][i].b <== eq[3][i].out; + states[i+1][3] <== and[3][i].out; + eq[4][i] = IsEqual(); + eq[4][i].in[0] <== in[i]; + eq[4][i].in[1] <== 117; + and[4][i] = AND(); + and[4][i].a <== states[i][3]; + and[4][i].b <== eq[4][i].out; + states[i+1][4] <== and[4][i].out; + eq[5][i] = IsEqual(); + eq[5][i].in[0] <== in[i]; + eq[5][i].in[1] <== 98; + and[5][i] = AND(); + and[5][i].a <== states[i][4]; + and[5][i].b <== eq[5][i].out; + states[i+1][5] <== and[5][i].out; + eq[6][i] = IsEqual(); + eq[6][i].in[0] <== in[i]; + eq[6][i].in[1] <== 106; + and[6][i] = AND(); + and[6][i].a <== states[i][5]; + and[6][i].b <== eq[6][i].out; + states[i+1][6] <== and[6][i].out; + eq[7][i] = IsEqual(); + eq[7][i].in[0] <== in[i]; + eq[7][i].in[1] <== 101; + and[7][i] = AND(); + and[7][i].a <== states[i][6]; + and[7][i].b <== eq[7][i].out; + states[i+1][7] <== and[7][i].out; + eq[8][i] = IsEqual(); + eq[8][i].in[0] <== in[i]; + eq[8][i].in[1] <== 99; + and[8][i] = AND(); + and[8][i].a <== states[i][7]; + and[8][i].b <== eq[8][i].out; + states[i+1][8] <== and[8][i].out; + eq[9][i] = IsEqual(); + eq[9][i].in[0] <== in[i]; + eq[9][i].in[1] <== 116; + and[9][i] = AND(); + and[9][i].a <== states[i][8]; + and[9][i].b <== eq[9][i].out; + states[i+1][9] <== and[9][i].out; + eq[10][i] = IsEqual(); + eq[10][i].in[0] <== in[i]; + eq[10][i].in[1] <== 58; + and[10][i] = AND(); + and[10][i].a <== states[i][9]; + and[10][i].b <== eq[10][i].out; + eq[11][i] = IsEqual(); + eq[11][i].in[0] <== in[i]; + eq[11][i].in[1] <== 32; + and[11][i] = AND(); + and[11][i].a <== states[i][20]; + and[11][i].b <== eq[11][i].out; + multi_or[0][i] = MultiOR(2); + multi_or[0][i].in[0] <== and[10][i].out; + multi_or[0][i].in[1] <== and[11][i].out; + states[i+1][10] <== multi_or[0][i].out; + eq[12][i] = IsEqual(); + eq[12][i].in[0] <== in[i]; + eq[12][i].in[1] <== 70; + and[12][i] = AND(); + and[12][i].a <== states[i][10]; + and[12][i].b <== eq[12][i].out; + states[i+1][11] <== and[12][i].out; + eq[13][i] = IsEqual(); + eq[13][i].in[0] <== in[i]; + eq[13][i].in[1] <== 82; + and[13][i] = AND(); + and[13][i].a <== states[i][10]; + and[13][i].b <== eq[13][i].out; + states[i+1][12] <== and[13][i].out; + eq[14][i] = IsEqual(); + eq[14][i].in[0] <== in[i]; + eq[14][i].in[1] <== 91; + and[14][i] = AND(); + and[14][i].a <== states[i][10]; + and[14][i].b <== eq[14][i].out; + states[i+1][13] <== and[14][i].out; + eq[15][i] = IsEqual(); + eq[15][i].in[0] <== in[i]; + eq[15][i].in[1] <== 102; + and[15][i] = AND(); + and[15][i].a <== states[i][10]; + and[15][i].b <== eq[15][i].out; + states[i+1][14] <== and[15][i].out; + eq[16][i] = IsEqual(); + eq[16][i].in[0] <== in[i]; + eq[16][i].in[1] <== 114; + and[16][i] = AND(); + and[16][i].a <== states[i][10]; + and[16][i].b <== eq[16][i].out; + states[i+1][15] <== and[16][i].out; + eq[17][i] = IsEqual(); + eq[17][i].in[0] <== in[i]; + eq[17][i].in[1] <== 87; + and[17][i] = AND(); + and[17][i].a <== states[i][11]; + and[17][i].b <== eq[17][i].out; + states[i+1][16] <== and[17][i].out; + eq[18][i] = IsEqual(); + eq[18][i].in[0] <== in[i]; + eq[18][i].in[1] <== 119; + and[18][i] = AND(); + and[18][i].a <== states[i][11]; + and[18][i].b <== eq[18][i].out; + and[19][i] = AND(); + and[19][i].a <== states[i][14]; + and[19][i].b <== eq[18][i].out; + multi_or[1][i] = MultiOR(2); + multi_or[1][i].in[0] <== and[18][i].out; + multi_or[1][i].in[1] <== and[19][i].out; + states[i+1][17] <== multi_or[1][i].out; + eq[19][i] = IsEqual(); + eq[19][i].in[0] <== in[i]; + eq[19][i].in[1] <== 69; + and[20][i] = AND(); + and[20][i].a <== states[i][12]; + multi_or[2][i] = MultiOR(2); + multi_or[2][i].in[0] <== eq[19][i].out; + multi_or[2][i].in[1] <== eq[7][i].out; + and[20][i].b <== multi_or[2][i].out; + and[21][i] = AND(); + and[21][i].a <== states[i][15]; + and[21][i].b <== eq[7][i].out; + eq[20][i] = IsEqual(); + eq[20][i].in[0] <== in[i]; + eq[20][i].in[1] <== 68; + and[22][i] = AND(); + and[22][i].a <== states[i][16]; + and[22][i].b <== eq[20][i].out; + eq[21][i] = IsEqual(); + eq[21][i].in[0] <== in[i]; + eq[21][i].in[1] <== 100; + and[23][i] = AND(); + and[23][i].a <== states[i][17]; + and[23][i].b <== eq[21][i].out; + multi_or[3][i] = MultiOR(4); + multi_or[3][i].in[0] <== and[20][i].out; + multi_or[3][i].in[1] <== and[21][i].out; + multi_or[3][i].in[2] <== and[22][i].out; + multi_or[3][i].in[3] <== and[23][i].out; + states[i+1][18] <== multi_or[3][i].out; + and[24][i] = AND(); + and[24][i].a <== states[i][13]; + and[24][i].b <== eq[13][i].out; + states[i+1][19] <== and[24][i].out; + and[25][i] = AND(); + and[25][i].a <== states[i][18]; + and[25][i].b <== eq[10][i].out; + states[i+1][20] <== and[25][i].out; + and[26][i] = AND(); + and[26][i].a <== states[i][19]; + and[26][i].b <== eq[7][i].out; + states[i+1][21] <== and[26][i].out; + eq[22][i] = IsEqual(); + eq[22][i].in[0] <== in[i]; + eq[22][i].in[1] <== 112; + and[27][i] = AND(); + and[27][i].a <== states[i][21]; + and[27][i].b <== eq[22][i].out; + states[i+1][22] <== and[27][i].out; + eq[23][i] = IsEqual(); + eq[23][i].in[0] <== in[i]; + eq[23][i].in[1] <== 108; + and[28][i] = AND(); + and[28][i].a <== states[i][22]; + and[28][i].b <== eq[23][i].out; + states[i+1][23] <== and[28][i].out; + eq[24][i] = IsEqual(); + eq[24][i].in[0] <== in[i]; + eq[24][i].in[1] <== 121; + and[29][i] = AND(); + and[29][i].a <== states[i][23]; + and[29][i].b <== eq[24][i].out; + states[i+1][24] <== and[29][i].out; + and[30][i] = AND(); + and[30][i].a <== states[i][24]; + and[30][i].b <== eq[11][i].out; + states[i+1][25] <== and[30][i].out; + eq[25][i] = IsEqual(); + eq[25][i].in[0] <== in[i]; + eq[25][i].in[1] <== 78; + and[31][i] = AND(); + and[31][i].a <== states[i][25]; + and[31][i].b <== eq[25][i].out; + states[i+1][26] <== and[31][i].out; + and[32][i] = AND(); + and[32][i].a <== states[i][26]; + and[32][i].b <== eq[7][i].out; + states[i+1][27] <== and[32][i].out; + and[33][i] = AND(); + and[33][i].a <== states[i][27]; + and[33][i].b <== eq[7][i].out; + states[i+1][28] <== and[33][i].out; + and[34][i] = AND(); + and[34][i].a <== states[i][28]; + and[34][i].b <== eq[21][i].out; + states[i+1][29] <== and[34][i].out; + and[35][i] = AND(); + and[35][i].a <== states[i][29]; + and[35][i].b <== eq[7][i].out; + states[i+1][30] <== and[35][i].out; + and[36][i] = AND(); + and[36][i].a <== states[i][30]; + and[36][i].b <== eq[21][i].out; + states[i+1][31] <== and[36][i].out; + eq[26][i] = IsEqual(); + eq[26][i].in[0] <== in[i]; + eq[26][i].in[1] <== 93; + and[37][i] = AND(); + and[37][i].a <== states[i][31]; + and[37][i].b <== eq[26][i].out; + lt[0][i] = LessEqThan(8); + lt[0][i].in[0] <== 14; + lt[0][i].in[1] <== in[i]; + lt[1][i] = LessEqThan(8); + lt[1][i].in[0] <== in[i]; + lt[1][i].in[1] <== 127; + and[38][i] = AND(); + and[38][i].a <== lt[0][i].out; + and[38][i].b <== lt[1][i].out; + eq[27][i] = IsEqual(); + eq[27][i].in[0] <== in[i]; + eq[27][i].in[1] <== 1; + eq[28][i] = IsEqual(); + eq[28][i].in[0] <== in[i]; + eq[28][i].in[1] <== 2; + eq[29][i] = IsEqual(); + eq[29][i].in[0] <== in[i]; + eq[29][i].in[1] <== 3; + eq[30][i] = IsEqual(); + eq[30][i].in[0] <== in[i]; + eq[30][i].in[1] <== 4; + eq[31][i] = IsEqual(); + eq[31][i].in[0] <== in[i]; + eq[31][i].in[1] <== 5; + eq[32][i] = IsEqual(); + eq[32][i].in[0] <== in[i]; + eq[32][i].in[1] <== 6; + eq[33][i] = IsEqual(); + eq[33][i].in[0] <== in[i]; + eq[33][i].in[1] <== 7; + eq[34][i] = IsEqual(); + eq[34][i].in[0] <== in[i]; + eq[34][i].in[1] <== 8; + eq[35][i] = IsEqual(); + eq[35][i].in[0] <== in[i]; + eq[35][i].in[1] <== 9; + eq[36][i] = IsEqual(); + eq[36][i].in[0] <== in[i]; + eq[36][i].in[1] <== 11; + eq[37][i] = IsEqual(); + eq[37][i].in[0] <== in[i]; + eq[37][i].in[1] <== 12; + and[39][i] = AND(); + and[39][i].a <== states[i][32]; + multi_or[4][i] = MultiOR(12); + multi_or[4][i].in[0] <== and[38][i].out; + multi_or[4][i].in[1] <== eq[27][i].out; + multi_or[4][i].in[2] <== eq[28][i].out; + multi_or[4][i].in[3] <== eq[29][i].out; + multi_or[4][i].in[4] <== eq[30][i].out; + multi_or[4][i].in[5] <== eq[31][i].out; + multi_or[4][i].in[6] <== eq[32][i].out; + multi_or[4][i].in[7] <== eq[33][i].out; + multi_or[4][i].in[8] <== eq[34][i].out; + multi_or[4][i].in[9] <== eq[35][i].out; + multi_or[4][i].in[10] <== eq[36][i].out; + multi_or[4][i].in[11] <== eq[37][i].out; + and[39][i].b <== multi_or[4][i].out; + lt[2][i] = LessEqThan(8); + lt[2][i].in[0] <== 128; + lt[2][i].in[1] <== in[i]; + lt[3][i] = LessEqThan(8); + lt[3][i].in[0] <== in[i]; + lt[3][i].in[1] <== 191; + and[40][i] = AND(); + and[40][i].a <== lt[2][i].out; + and[40][i].b <== lt[3][i].out; + and[41][i] = AND(); + and[41][i].a <== states[i][34]; + and[41][i].b <== and[40][i].out; + multi_or[5][i] = MultiOR(3); + multi_or[5][i].in[0] <== and[37][i].out; + multi_or[5][i].in[1] <== and[39][i].out; + multi_or[5][i].in[2] <== and[41][i].out; + states[i+1][32] <== multi_or[5][i].out; + and[42][i] = AND(); + and[42][i].a <== states[i][32]; + and[42][i].b <== eq[0][i].out; + states[i+1][33] <== and[42][i].out; + lt[4][i] = LessEqThan(8); + lt[4][i].in[0] <== 194; + lt[4][i].in[1] <== in[i]; + lt[5][i] = LessEqThan(8); + lt[5][i].in[0] <== in[i]; + lt[5][i].in[1] <== 223; + and[43][i] = AND(); + and[43][i].a <== lt[4][i].out; + and[43][i].b <== lt[5][i].out; + and[44][i] = AND(); + and[44][i].a <== states[i][32]; + and[44][i].b <== and[43][i].out; + lt[6][i] = LessEqThan(8); + lt[6][i].in[0] <== 160; + lt[6][i].in[1] <== in[i]; + lt[7][i] = LessEqThan(8); + lt[7][i].in[0] <== in[i]; + lt[7][i].in[1] <== 191; + and[45][i] = AND(); + and[45][i].a <== lt[6][i].out; + and[45][i].b <== lt[7][i].out; + and[46][i] = AND(); + and[46][i].a <== states[i][35]; + and[46][i].b <== and[45][i].out; + and[47][i] = AND(); + and[47][i].a <== states[i][36]; + and[47][i].b <== and[40][i].out; + lt[8][i] = LessEqThan(8); + lt[8][i].in[0] <== 128; + lt[8][i].in[1] <== in[i]; + lt[9][i] = LessEqThan(8); + lt[9][i].in[0] <== in[i]; + lt[9][i].in[1] <== 159; + and[48][i] = AND(); + and[48][i].a <== lt[8][i].out; + and[48][i].b <== lt[9][i].out; + and[49][i] = AND(); + and[49][i].a <== states[i][37]; + and[49][i].b <== and[48][i].out; + multi_or[6][i] = MultiOR(4); + multi_or[6][i].in[0] <== and[44][i].out; + multi_or[6][i].in[1] <== and[46][i].out; + multi_or[6][i].in[2] <== and[47][i].out; + multi_or[6][i].in[3] <== and[49][i].out; + states[i+1][34] <== multi_or[6][i].out; + eq[38][i] = IsEqual(); + eq[38][i].in[0] <== in[i]; + eq[38][i].in[1] <== 224; + and[50][i] = AND(); + and[50][i].a <== states[i][32]; + and[50][i].b <== eq[38][i].out; + states[i+1][35] <== and[50][i].out; + eq[39][i] = IsEqual(); + eq[39][i].in[0] <== in[i]; + eq[39][i].in[1] <== 225; + eq[40][i] = IsEqual(); + eq[40][i].in[0] <== in[i]; + eq[40][i].in[1] <== 226; + eq[41][i] = IsEqual(); + eq[41][i].in[0] <== in[i]; + eq[41][i].in[1] <== 227; + eq[42][i] = IsEqual(); + eq[42][i].in[0] <== in[i]; + eq[42][i].in[1] <== 228; + eq[43][i] = IsEqual(); + eq[43][i].in[0] <== in[i]; + eq[43][i].in[1] <== 229; + eq[44][i] = IsEqual(); + eq[44][i].in[0] <== in[i]; + eq[44][i].in[1] <== 230; + eq[45][i] = IsEqual(); + eq[45][i].in[0] <== in[i]; + eq[45][i].in[1] <== 231; + eq[46][i] = IsEqual(); + eq[46][i].in[0] <== in[i]; + eq[46][i].in[1] <== 232; + eq[47][i] = IsEqual(); + eq[47][i].in[0] <== in[i]; + eq[47][i].in[1] <== 233; + eq[48][i] = IsEqual(); + eq[48][i].in[0] <== in[i]; + eq[48][i].in[1] <== 234; + eq[49][i] = IsEqual(); + eq[49][i].in[0] <== in[i]; + eq[49][i].in[1] <== 235; + eq[50][i] = IsEqual(); + eq[50][i].in[0] <== in[i]; + eq[50][i].in[1] <== 236; + eq[51][i] = IsEqual(); + eq[51][i].in[0] <== in[i]; + eq[51][i].in[1] <== 238; + eq[52][i] = IsEqual(); + eq[52][i].in[0] <== in[i]; + eq[52][i].in[1] <== 239; + and[51][i] = AND(); + and[51][i].a <== states[i][32]; + multi_or[7][i] = MultiOR(14); + multi_or[7][i].in[0] <== eq[39][i].out; + multi_or[7][i].in[1] <== eq[40][i].out; + multi_or[7][i].in[2] <== eq[41][i].out; + multi_or[7][i].in[3] <== eq[42][i].out; + multi_or[7][i].in[4] <== eq[43][i].out; + multi_or[7][i].in[5] <== eq[44][i].out; + multi_or[7][i].in[6] <== eq[45][i].out; + multi_or[7][i].in[7] <== eq[46][i].out; + multi_or[7][i].in[8] <== eq[47][i].out; + multi_or[7][i].in[9] <== eq[48][i].out; + multi_or[7][i].in[10] <== eq[49][i].out; + multi_or[7][i].in[11] <== eq[50][i].out; + multi_or[7][i].in[12] <== eq[51][i].out; + multi_or[7][i].in[13] <== eq[52][i].out; + and[51][i].b <== multi_or[7][i].out; + lt[10][i] = LessEqThan(8); + lt[10][i].in[0] <== 144; + lt[10][i].in[1] <== in[i]; + lt[11][i] = LessEqThan(8); + lt[11][i].in[0] <== in[i]; + lt[11][i].in[1] <== 191; + and[52][i] = AND(); + and[52][i].a <== lt[10][i].out; + and[52][i].b <== lt[11][i].out; + and[53][i] = AND(); + and[53][i].a <== states[i][38]; + and[53][i].b <== and[52][i].out; + and[54][i] = AND(); + and[54][i].a <== states[i][39]; + and[54][i].b <== and[40][i].out; + eq[53][i] = IsEqual(); + eq[53][i].in[0] <== in[i]; + eq[53][i].in[1] <== 128; + eq[54][i] = IsEqual(); + eq[54][i].in[0] <== in[i]; + eq[54][i].in[1] <== 129; + eq[55][i] = IsEqual(); + eq[55][i].in[0] <== in[i]; + eq[55][i].in[1] <== 130; + eq[56][i] = IsEqual(); + eq[56][i].in[0] <== in[i]; + eq[56][i].in[1] <== 131; + eq[57][i] = IsEqual(); + eq[57][i].in[0] <== in[i]; + eq[57][i].in[1] <== 132; + eq[58][i] = IsEqual(); + eq[58][i].in[0] <== in[i]; + eq[58][i].in[1] <== 133; + eq[59][i] = IsEqual(); + eq[59][i].in[0] <== in[i]; + eq[59][i].in[1] <== 134; + eq[60][i] = IsEqual(); + eq[60][i].in[0] <== in[i]; + eq[60][i].in[1] <== 135; + eq[61][i] = IsEqual(); + eq[61][i].in[0] <== in[i]; + eq[61][i].in[1] <== 136; + eq[62][i] = IsEqual(); + eq[62][i].in[0] <== in[i]; + eq[62][i].in[1] <== 137; + eq[63][i] = IsEqual(); + eq[63][i].in[0] <== in[i]; + eq[63][i].in[1] <== 138; + eq[64][i] = IsEqual(); + eq[64][i].in[0] <== in[i]; + eq[64][i].in[1] <== 139; + eq[65][i] = IsEqual(); + eq[65][i].in[0] <== in[i]; + eq[65][i].in[1] <== 140; + eq[66][i] = IsEqual(); + eq[66][i].in[0] <== in[i]; + eq[66][i].in[1] <== 141; + eq[67][i] = IsEqual(); + eq[67][i].in[0] <== in[i]; + eq[67][i].in[1] <== 142; + eq[68][i] = IsEqual(); + eq[68][i].in[0] <== in[i]; + eq[68][i].in[1] <== 143; + and[55][i] = AND(); + and[55][i].a <== states[i][40]; + multi_or[8][i] = MultiOR(16); + multi_or[8][i].in[0] <== eq[53][i].out; + multi_or[8][i].in[1] <== eq[54][i].out; + multi_or[8][i].in[2] <== eq[55][i].out; + multi_or[8][i].in[3] <== eq[56][i].out; + multi_or[8][i].in[4] <== eq[57][i].out; + multi_or[8][i].in[5] <== eq[58][i].out; + multi_or[8][i].in[6] <== eq[59][i].out; + multi_or[8][i].in[7] <== eq[60][i].out; + multi_or[8][i].in[8] <== eq[61][i].out; + multi_or[8][i].in[9] <== eq[62][i].out; + multi_or[8][i].in[10] <== eq[63][i].out; + multi_or[8][i].in[11] <== eq[64][i].out; + multi_or[8][i].in[12] <== eq[65][i].out; + multi_or[8][i].in[13] <== eq[66][i].out; + multi_or[8][i].in[14] <== eq[67][i].out; + multi_or[8][i].in[15] <== eq[68][i].out; + and[55][i].b <== multi_or[8][i].out; + multi_or[9][i] = MultiOR(4); + multi_or[9][i].in[0] <== and[51][i].out; + multi_or[9][i].in[1] <== and[53][i].out; + multi_or[9][i].in[2] <== and[54][i].out; + multi_or[9][i].in[3] <== and[55][i].out; + states[i+1][36] <== multi_or[9][i].out; + eq[69][i] = IsEqual(); + eq[69][i].in[0] <== in[i]; + eq[69][i].in[1] <== 237; + and[56][i] = AND(); + and[56][i].a <== states[i][32]; + and[56][i].b <== eq[69][i].out; + states[i+1][37] <== and[56][i].out; + eq[70][i] = IsEqual(); + eq[70][i].in[0] <== in[i]; + eq[70][i].in[1] <== 240; + and[57][i] = AND(); + and[57][i].a <== states[i][32]; + and[57][i].b <== eq[70][i].out; + states[i+1][38] <== and[57][i].out; + eq[71][i] = IsEqual(); + eq[71][i].in[0] <== in[i]; + eq[71][i].in[1] <== 241; + eq[72][i] = IsEqual(); + eq[72][i].in[0] <== in[i]; + eq[72][i].in[1] <== 242; + eq[73][i] = IsEqual(); + eq[73][i].in[0] <== in[i]; + eq[73][i].in[1] <== 243; + and[58][i] = AND(); + and[58][i].a <== states[i][32]; + multi_or[10][i] = MultiOR(3); + multi_or[10][i].in[0] <== eq[71][i].out; + multi_or[10][i].in[1] <== eq[72][i].out; + multi_or[10][i].in[2] <== eq[73][i].out; + and[58][i].b <== multi_or[10][i].out; + states[i+1][39] <== and[58][i].out; + eq[74][i] = IsEqual(); + eq[74][i].in[0] <== in[i]; + eq[74][i].in[1] <== 244; + and[59][i] = AND(); + and[59][i].a <== states[i][32]; + and[59][i].b <== eq[74][i].out; + states[i+1][40] <== and[59][i].out; + and[60][i] = AND(); + and[60][i].a <== states[i][33]; + and[60][i].b <== eq[2][i].out; + states[i+1][41] <== and[60][i].out; + from_zero_enabled[i] <== MultiNOR(41)([states_tmp[i+1][1], states_tmp[i+1][2], states[i+1][3], states[i+1][4], states[i+1][5], states[i+1][6], states[i+1][7], states[i+1][8], states[i+1][9], states[i+1][10], states[i+1][11], states[i+1][12], states[i+1][13], states[i+1][14], states[i+1][15], states[i+1][16], states[i+1][17], states[i+1][18], states[i+1][19], states[i+1][20], states[i+1][21], states[i+1][22], states[i+1][23], states[i+1][24], states[i+1][25], states[i+1][26], states[i+1][27], states[i+1][28], states[i+1][29], states[i+1][30], states[i+1][31], states[i+1][32], states[i+1][33], states[i+1][34], states[i+1][35], states[i+1][36], states[i+1][37], states[i+1][38], states[i+1][39], states[i+1][40], states[i+1][41]]); + states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); + states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[1][i].out]); + state_changed[i].in[0] <== states[i+1][1]; + state_changed[i].in[1] <== states[i+1][2]; + state_changed[i].in[2] <== states[i+1][3]; + state_changed[i].in[3] <== states[i+1][4]; + state_changed[i].in[4] <== states[i+1][5]; + state_changed[i].in[5] <== states[i+1][6]; + state_changed[i].in[6] <== states[i+1][7]; + state_changed[i].in[7] <== states[i+1][8]; + state_changed[i].in[8] <== states[i+1][9]; + state_changed[i].in[9] <== states[i+1][10]; + state_changed[i].in[10] <== states[i+1][11]; + state_changed[i].in[11] <== states[i+1][12]; + state_changed[i].in[12] <== states[i+1][13]; + state_changed[i].in[13] <== states[i+1][14]; + state_changed[i].in[14] <== states[i+1][15]; + state_changed[i].in[15] <== states[i+1][16]; + state_changed[i].in[16] <== states[i+1][17]; + state_changed[i].in[17] <== states[i+1][18]; + state_changed[i].in[18] <== states[i+1][19]; + state_changed[i].in[19] <== states[i+1][20]; + state_changed[i].in[20] <== states[i+1][21]; + state_changed[i].in[21] <== states[i+1][22]; + state_changed[i].in[22] <== states[i+1][23]; + state_changed[i].in[23] <== states[i+1][24]; + state_changed[i].in[24] <== states[i+1][25]; + state_changed[i].in[25] <== states[i+1][26]; + state_changed[i].in[26] <== states[i+1][27]; + state_changed[i].in[27] <== states[i+1][28]; + state_changed[i].in[28] <== states[i+1][29]; + state_changed[i].in[29] <== states[i+1][30]; + state_changed[i].in[30] <== states[i+1][31]; + state_changed[i].in[31] <== states[i+1][32]; + state_changed[i].in[32] <== states[i+1][33]; + state_changed[i].in[33] <== states[i+1][34]; + state_changed[i].in[34] <== states[i+1][35]; + state_changed[i].in[35] <== states[i+1][36]; + state_changed[i].in[36] <== states[i+1][37]; + state_changed[i].in[37] <== states[i+1][38]; + state_changed[i].in[38] <== states[i+1][39]; + state_changed[i].in[39] <== states[i+1][40]; + state_changed[i].in[40] <== states[i+1][41]; + } + + component is_accepted = MultiOR(num_bytes+1); + for (var i = 0; i <= num_bytes; i++) { + is_accepted.in[i] <== states[i][41]; + } + out <== is_accepted.out; + signal is_consecutive[msg_bytes+1][3]; + is_consecutive[msg_bytes][2] <== 0; + for (var i = 0; i < msg_bytes; i++) { + is_consecutive[msg_bytes-1-i][0] <== states[num_bytes-i][41] * (1 - is_consecutive[msg_bytes-i][2]) + is_consecutive[msg_bytes-i][2]; + is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; + is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][41], is_consecutive[msg_bytes-1-i][1]]); + } + // substrings calculated: [] +} \ No newline at end of file diff --git a/packages/circuits/src/regexes/invitation_code.json b/packages/circuits/src/regexes/invitation_code.json index c5c5aca4..19e8b809 100644 --- a/packages/circuits/src/regexes/invitation_code.json +++ b/packages/circuits/src/regexes/invitation_code.json @@ -2,7 +2,7 @@ "parts": [ { "is_public": false, - "regex_def": "( )?(c|C)ode( )?" + "regex_def": "( )(c|C)ode( )?" }, { "is_public": true, diff --git a/packages/circuits/src/regexes/invitation_code_regex.circom b/packages/circuits/src/regexes/invitation_code_regex.circom index 973366f9..6794cc45 100644 --- a/packages/circuits/src/regexes/invitation_code_regex.circom +++ b/packages/circuits/src/regexes/invitation_code_regex.circom @@ -2,7 +2,7 @@ pragma circom 2.1.5; include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; -// regex: ( )?(c|C)ode( )?(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)+ +// regex: ( )(c|C)ode( )?(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)+ template InvitationCodeRegex(msg_bytes) { signal input msg[msg_bytes]; signal output out; @@ -11,11 +11,12 @@ template InvitationCodeRegex(msg_bytes) { signal in[num_bytes]; in[0]<==255; for (var i = 0; i < msg_bytes; i++) { + _ <== LessThan(8)([msg[i], 255]); in[i+1] <== msg[i]; } component eq[19][num_bytes]; - component and[10][num_bytes]; + component and[9][num_bytes]; component multi_or[3][num_bytes]; signal states[num_bytes+1][8]; signal states_tmp[num_bytes+1][8]; @@ -32,52 +33,49 @@ template InvitationCodeRegex(msg_bytes) { states[i][0] <== 1; eq[0][i] = IsEqual(); eq[0][i].in[0] <== in[i]; - eq[0][i].in[1] <== 67; - eq[1][i] = IsEqual(); - eq[1][i].in[0] <== in[i]; - eq[1][i].in[1] <== 99; + eq[0][i].in[1] <== 32; and[0][i] = AND(); and[0][i].a <== states[i][0]; - multi_or[0][i] = MultiOR(2); - multi_or[0][i].in[0] <== eq[0][i].out; - multi_or[0][i].in[1] <== eq[1][i].out; - and[0][i].b <== multi_or[0][i].out; - and[1][i] = AND(); - and[1][i].a <== states[i][2]; - and[1][i].b <== multi_or[0][i].out; - states_tmp[i+1][1] <== and[1][i].out; + and[0][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== 0; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 67; eq[2][i] = IsEqual(); eq[2][i].in[0] <== in[i]; - eq[2][i].in[1] <== 32; - and[2][i] = AND(); - and[2][i].a <== states[i][0]; - and[2][i].b <== eq[2][i].out; - states_tmp[i+1][2] <== 0; + eq[2][i].in[1] <== 99; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + multi_or[0][i] = MultiOR(2); + multi_or[0][i].in[0] <== eq[1][i].out; + multi_or[0][i].in[1] <== eq[2][i].out; + and[1][i].b <== multi_or[0][i].out; + states[i+1][2] <== and[1][i].out; eq[3][i] = IsEqual(); eq[3][i].in[0] <== in[i]; eq[3][i].in[1] <== 111; - and[3][i] = AND(); - and[3][i].a <== states[i][1]; - and[3][i].b <== eq[3][i].out; - states[i+1][3] <== and[3][i].out; + and[2][i] = AND(); + and[2][i].a <== states[i][2]; + and[2][i].b <== eq[3][i].out; + states[i+1][3] <== and[2][i].out; eq[4][i] = IsEqual(); eq[4][i].in[0] <== in[i]; eq[4][i].in[1] <== 100; - and[4][i] = AND(); - and[4][i].a <== states[i][3]; - and[4][i].b <== eq[4][i].out; - states[i+1][4] <== and[4][i].out; + and[3][i] = AND(); + and[3][i].a <== states[i][3]; + and[3][i].b <== eq[4][i].out; + states[i+1][4] <== and[3][i].out; eq[5][i] = IsEqual(); eq[5][i].in[0] <== in[i]; eq[5][i].in[1] <== 101; + and[4][i] = AND(); + and[4][i].a <== states[i][4]; + and[4][i].b <== eq[5][i].out; + states[i+1][5] <== and[4][i].out; and[5][i] = AND(); - and[5][i].a <== states[i][4]; - and[5][i].b <== eq[5][i].out; - states[i+1][5] <== and[5][i].out; - and[6][i] = AND(); - and[6][i].a <== states[i][5]; - and[6][i].b <== eq[2][i].out; - states[i+1][6] <== and[6][i].out; + and[5][i].a <== states[i][5]; + and[5][i].b <== eq[0][i].out; + states[i+1][6] <== and[5][i].out; eq[6][i] = IsEqual(); eq[6][i].in[0] <== in[i]; eq[6][i].in[1] <== 48; @@ -117,8 +115,8 @@ template InvitationCodeRegex(msg_bytes) { eq[18][i] = IsEqual(); eq[18][i].in[0] <== in[i]; eq[18][i].in[1] <== 102; - and[7][i] = AND(); - and[7][i].a <== states[i][5]; + and[6][i] = AND(); + and[6][i].a <== states[i][5]; multi_or[1][i] = MultiOR(16); multi_or[1][i].in[0] <== eq[6][i].out; multi_or[1][i].in[1] <== eq[7][i].out; @@ -132,25 +130,24 @@ template InvitationCodeRegex(msg_bytes) { multi_or[1][i].in[9] <== eq[15][i].out; multi_or[1][i].in[10] <== eq[16][i].out; multi_or[1][i].in[11] <== eq[17][i].out; - multi_or[1][i].in[12] <== eq[1][i].out; + multi_or[1][i].in[12] <== eq[2][i].out; multi_or[1][i].in[13] <== eq[4][i].out; multi_or[1][i].in[14] <== eq[5][i].out; multi_or[1][i].in[15] <== eq[18][i].out; + and[6][i].b <== multi_or[1][i].out; + and[7][i] = AND(); + and[7][i].a <== states[i][6]; and[7][i].b <== multi_or[1][i].out; and[8][i] = AND(); - and[8][i].a <== states[i][6]; + and[8][i].a <== states[i][7]; and[8][i].b <== multi_or[1][i].out; - and[9][i] = AND(); - and[9][i].a <== states[i][7]; - and[9][i].b <== multi_or[1][i].out; multi_or[2][i] = MultiOR(3); - multi_or[2][i].in[0] <== and[7][i].out; - multi_or[2][i].in[1] <== and[8][i].out; - multi_or[2][i].in[2] <== and[9][i].out; + multi_or[2][i].in[0] <== and[6][i].out; + multi_or[2][i].in[1] <== and[7][i].out; + multi_or[2][i].in[2] <== and[8][i].out; states[i+1][7] <== multi_or[2][i].out; - from_zero_enabled[i] <== MultiNOR(7)([states_tmp[i+1][1], states_tmp[i+1][2], states[i+1][3], states[i+1][4], states[i+1][5], states[i+1][6], states[i+1][7]]); + from_zero_enabled[i] <== MultiNOR(7)([states_tmp[i+1][1], states[i+1][2], states[i+1][3], states[i+1][4], states[i+1][5], states[i+1][6], states[i+1][7]]); states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); - states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[2][i].out]); state_changed[i].in[0] <== states[i+1][1]; state_changed[i].in[1] <== states[i+1][2]; state_changed[i].in[2] <== states[i+1][3]; diff --git a/packages/circuits/src/regexes/invitation_code_with_prefix.json b/packages/circuits/src/regexes/invitation_code_with_prefix.json index e92abb45..5782b86f 100644 --- a/packages/circuits/src/regexes/invitation_code_with_prefix.json +++ b/packages/circuits/src/regexes/invitation_code_with_prefix.json @@ -2,7 +2,7 @@ "parts": [ { "is_public": true, - "regex_def": "( )?(c|C)ode( )?(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)+" + "regex_def": "( )(c|C)ode( )?(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)+" } ] } \ No newline at end of file diff --git a/packages/circuits/src/regexes/invitation_code_with_prefix_regex.circom b/packages/circuits/src/regexes/invitation_code_with_prefix_regex.circom index 979a9a5e..bf6ea2ee 100644 --- a/packages/circuits/src/regexes/invitation_code_with_prefix_regex.circom +++ b/packages/circuits/src/regexes/invitation_code_with_prefix_regex.circom @@ -2,7 +2,7 @@ pragma circom 2.1.5; include "@zk-email/zk-regex-circom/circuits/regex_helpers.circom"; -// regex: ( )?(c|C)ode( )?(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)+ +// regex: ( )(c|C)ode( )?(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)+ template InvitationCodeWithPrefixRegex(msg_bytes) { signal input msg[msg_bytes]; signal output out; @@ -11,11 +11,12 @@ template InvitationCodeWithPrefixRegex(msg_bytes) { signal in[num_bytes]; in[0]<==255; for (var i = 0; i < msg_bytes; i++) { + _ <== LessThan(8)([msg[i], 255]); in[i+1] <== msg[i]; } component eq[19][num_bytes]; - component and[10][num_bytes]; + component and[9][num_bytes]; component multi_or[3][num_bytes]; signal states[num_bytes+1][8]; signal states_tmp[num_bytes+1][8]; @@ -32,52 +33,49 @@ template InvitationCodeWithPrefixRegex(msg_bytes) { states[i][0] <== 1; eq[0][i] = IsEqual(); eq[0][i].in[0] <== in[i]; - eq[0][i].in[1] <== 67; - eq[1][i] = IsEqual(); - eq[1][i].in[0] <== in[i]; - eq[1][i].in[1] <== 99; + eq[0][i].in[1] <== 32; and[0][i] = AND(); and[0][i].a <== states[i][0]; - multi_or[0][i] = MultiOR(2); - multi_or[0][i].in[0] <== eq[0][i].out; - multi_or[0][i].in[1] <== eq[1][i].out; - and[0][i].b <== multi_or[0][i].out; - and[1][i] = AND(); - and[1][i].a <== states[i][2]; - and[1][i].b <== multi_or[0][i].out; - states_tmp[i+1][1] <== and[1][i].out; + and[0][i].b <== eq[0][i].out; + states_tmp[i+1][1] <== 0; + eq[1][i] = IsEqual(); + eq[1][i].in[0] <== in[i]; + eq[1][i].in[1] <== 67; eq[2][i] = IsEqual(); eq[2][i].in[0] <== in[i]; - eq[2][i].in[1] <== 32; - and[2][i] = AND(); - and[2][i].a <== states[i][0]; - and[2][i].b <== eq[2][i].out; - states_tmp[i+1][2] <== 0; + eq[2][i].in[1] <== 99; + and[1][i] = AND(); + and[1][i].a <== states[i][1]; + multi_or[0][i] = MultiOR(2); + multi_or[0][i].in[0] <== eq[1][i].out; + multi_or[0][i].in[1] <== eq[2][i].out; + and[1][i].b <== multi_or[0][i].out; + states[i+1][2] <== and[1][i].out; eq[3][i] = IsEqual(); eq[3][i].in[0] <== in[i]; eq[3][i].in[1] <== 111; - and[3][i] = AND(); - and[3][i].a <== states[i][1]; - and[3][i].b <== eq[3][i].out; - states[i+1][3] <== and[3][i].out; + and[2][i] = AND(); + and[2][i].a <== states[i][2]; + and[2][i].b <== eq[3][i].out; + states[i+1][3] <== and[2][i].out; eq[4][i] = IsEqual(); eq[4][i].in[0] <== in[i]; eq[4][i].in[1] <== 100; - and[4][i] = AND(); - and[4][i].a <== states[i][3]; - and[4][i].b <== eq[4][i].out; - states[i+1][4] <== and[4][i].out; + and[3][i] = AND(); + and[3][i].a <== states[i][3]; + and[3][i].b <== eq[4][i].out; + states[i+1][4] <== and[3][i].out; eq[5][i] = IsEqual(); eq[5][i].in[0] <== in[i]; eq[5][i].in[1] <== 101; + and[4][i] = AND(); + and[4][i].a <== states[i][4]; + and[4][i].b <== eq[5][i].out; + states[i+1][5] <== and[4][i].out; and[5][i] = AND(); - and[5][i].a <== states[i][4]; - and[5][i].b <== eq[5][i].out; - states[i+1][5] <== and[5][i].out; - and[6][i] = AND(); - and[6][i].a <== states[i][5]; - and[6][i].b <== eq[2][i].out; - states[i+1][6] <== and[6][i].out; + and[5][i].a <== states[i][5]; + and[5][i].b <== eq[0][i].out; + states[i+1][6] <== and[5][i].out; eq[6][i] = IsEqual(); eq[6][i].in[0] <== in[i]; eq[6][i].in[1] <== 48; @@ -117,8 +115,8 @@ template InvitationCodeWithPrefixRegex(msg_bytes) { eq[18][i] = IsEqual(); eq[18][i].in[0] <== in[i]; eq[18][i].in[1] <== 102; - and[7][i] = AND(); - and[7][i].a <== states[i][5]; + and[6][i] = AND(); + and[6][i].a <== states[i][5]; multi_or[1][i] = MultiOR(16); multi_or[1][i].in[0] <== eq[6][i].out; multi_or[1][i].in[1] <== eq[7][i].out; @@ -132,25 +130,24 @@ template InvitationCodeWithPrefixRegex(msg_bytes) { multi_or[1][i].in[9] <== eq[15][i].out; multi_or[1][i].in[10] <== eq[16][i].out; multi_or[1][i].in[11] <== eq[17][i].out; - multi_or[1][i].in[12] <== eq[1][i].out; + multi_or[1][i].in[12] <== eq[2][i].out; multi_or[1][i].in[13] <== eq[4][i].out; multi_or[1][i].in[14] <== eq[5][i].out; multi_or[1][i].in[15] <== eq[18][i].out; + and[6][i].b <== multi_or[1][i].out; + and[7][i] = AND(); + and[7][i].a <== states[i][6]; and[7][i].b <== multi_or[1][i].out; and[8][i] = AND(); - and[8][i].a <== states[i][6]; + and[8][i].a <== states[i][7]; and[8][i].b <== multi_or[1][i].out; - and[9][i] = AND(); - and[9][i].a <== states[i][7]; - and[9][i].b <== multi_or[1][i].out; multi_or[2][i] = MultiOR(3); - multi_or[2][i].in[0] <== and[7][i].out; - multi_or[2][i].in[1] <== and[8][i].out; - multi_or[2][i].in[2] <== and[9][i].out; + multi_or[2][i].in[0] <== and[6][i].out; + multi_or[2][i].in[1] <== and[7][i].out; + multi_or[2][i].in[2] <== and[8][i].out; states[i+1][7] <== multi_or[2][i].out; - from_zero_enabled[i] <== MultiNOR(7)([states_tmp[i+1][1], states_tmp[i+1][2], states[i+1][3], states[i+1][4], states[i+1][5], states[i+1][6], states[i+1][7]]); + from_zero_enabled[i] <== MultiNOR(7)([states_tmp[i+1][1], states[i+1][2], states[i+1][3], states[i+1][4], states[i+1][5], states[i+1][6], states[i+1][7]]); states[i+1][1] <== MultiOR(2)([states_tmp[i+1][1], from_zero_enabled[i] * and[0][i].out]); - states[i+1][2] <== MultiOR(2)([states_tmp[i+1][2], from_zero_enabled[i] * and[2][i].out]); state_changed[i].in[0] <== states[i+1][1]; state_changed[i].in[1] <== states[i+1][2]; state_changed[i].in[2] <== states[i+1][3]; @@ -172,24 +169,23 @@ template InvitationCodeWithPrefixRegex(msg_bytes) { is_consecutive[msg_bytes-1-i][1] <== state_changed[msg_bytes-i].out * is_consecutive[msg_bytes-1-i][0]; is_consecutive[msg_bytes-1-i][2] <== ORAnd()([(1 - from_zero_enabled[msg_bytes-i+1]), states[num_bytes-i][7], is_consecutive[msg_bytes-1-i][1]]); } - // substrings calculated: [{(0, 1), (0, 2), (1, 3), (2, 1), (3, 4), (4, 5), (5, 6), (5, 7), (6, 7), (7, 7)}] - signal prev_states0[10][msg_bytes]; + // substrings calculated: [{(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (5, 7), (6, 7), (7, 7)}] + signal prev_states0[9][msg_bytes]; signal is_substr0[msg_bytes]; signal is_reveal0[msg_bytes]; signal output reveal0[msg_bytes]; for (var i = 0; i < msg_bytes; i++) { - // the 0-th substring transitions: [(0, 1), (0, 2), (1, 3), (2, 1), (3, 4), (4, 5), (5, 6), (5, 7), (6, 7), (7, 7)] + // the 0-th substring transitions: [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (5, 7), (6, 7), (7, 7)] prev_states0[0][i] <== from_zero_enabled[i+1] * states[i+1][0]; - prev_states0[1][i] <== from_zero_enabled[i+1] * states[i+1][0]; - prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; - prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; - prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; - prev_states0[5][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][4]; + prev_states0[1][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][1]; + prev_states0[2][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][2]; + prev_states0[3][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][3]; + prev_states0[4][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][4]; + prev_states0[5][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; prev_states0[6][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; - prev_states0[7][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][5]; - prev_states0[8][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][6]; - prev_states0[9][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; - is_substr0[i] <== MultiOR(10)([prev_states0[0][i] * states[i+2][1], prev_states0[1][i] * states[i+2][2], prev_states0[2][i] * states[i+2][3], prev_states0[3][i] * states[i+2][1], prev_states0[4][i] * states[i+2][4], prev_states0[5][i] * states[i+2][5], prev_states0[6][i] * states[i+2][6], prev_states0[7][i] * states[i+2][7], prev_states0[8][i] * states[i+2][7], prev_states0[9][i] * states[i+2][7]]); + prev_states0[7][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][6]; + prev_states0[8][i] <== (1 - from_zero_enabled[i+1]) * states[i+1][7]; + is_substr0[i] <== MultiOR(9)([prev_states0[0][i] * states[i+2][1], prev_states0[1][i] * states[i+2][2], prev_states0[2][i] * states[i+2][3], prev_states0[3][i] * states[i+2][4], prev_states0[4][i] * states[i+2][5], prev_states0[5][i] * states[i+2][6], prev_states0[6][i] * states[i+2][7], prev_states0[7][i] * states[i+2][7], prev_states0[8][i] * states[i+2][7]]); is_reveal0[i] <== MultiAND(3)([out, is_substr0[i], is_consecutive[i][2]]); reveal0[i] <== in[i+1] * is_reveal0[i]; } diff --git a/packages/circuits/src/utils/bytes2ints.circom b/packages/circuits/src/utils/bytes2ints.circom index 9c628c55..8c9d5b4e 100644 --- a/packages/circuits/src/utils/bytes2ints.circom +++ b/packages/circuits/src/utils/bytes2ints.circom @@ -10,6 +10,7 @@ function compute_ints_size(bytes_size) { return computeIntChunkLength(bytes_size); } +// @dev The caller of this template must ensure that each byte fit in 8-bit. template Bytes2Ints(bytes_size) { var num_chunk = compute_ints_size(bytes_size); signal input bytes[bytes_size]; diff --git a/packages/circuits/src/utils/constants.circom b/packages/circuits/src/utils/constants.circom index baf032e6..983c1423 100644 --- a/packages/circuits/src/utils/constants.circom +++ b/packages/circuits/src/utils/constants.circom @@ -26,4 +26,3 @@ function pack_bytes_const() { function timestamp_len_const() { return 10; } - diff --git a/packages/circuits/tests/circuits/email_auth_with_recipient.circom b/packages/circuits/tests/circuits/email_auth_with_recipient.circom index fcab93e7..6bba2773 100644 --- a/packages/circuits/tests/circuits/email_auth_with_recipient.circom +++ b/packages/circuits/tests/circuits/email_auth_with_recipient.circom @@ -1,5 +1,5 @@ pragma circom 2.1.5; -include "../../src/email_auth_template.circom"; +include "../../src/email_auth_legacy_template.circom"; -component main = EmailAuth(121, 17, 1024, 605, 1); \ No newline at end of file +component main = EmailAuthLegacy(121, 17, 1024, 605, 1); \ No newline at end of file diff --git a/packages/circuits/tests/circuits/test_email_auth.circom b/packages/circuits/tests/circuits/test_email_auth.circom new file mode 100644 index 00000000..74510d0b --- /dev/null +++ b/packages/circuits/tests/circuits/test_email_auth.circom @@ -0,0 +1,5 @@ +pragma circom 2.1.6; + +include "../../src/email_auth_template.circom"; + +component main = EmailAuth(121, 17, 640, 768, 605, 0, 1); \ No newline at end of file diff --git a/packages/circuits/tests/circuits/test_email_auth_with_recipient.circom b/packages/circuits/tests/circuits/test_email_auth_with_recipient.circom new file mode 100644 index 00000000..1c0e029b --- /dev/null +++ b/packages/circuits/tests/circuits/test_email_auth_with_recipient.circom @@ -0,0 +1,5 @@ +pragma circom 2.1.6; + +include "../../src/email_auth_template.circom"; + +component main = EmailAuth(121, 17, 640, 768, 605, 1, 1); \ No newline at end of file diff --git a/packages/circuits/tests/circuits/test_forced_subject_regex.circom b/packages/circuits/tests/circuits/test_forced_subject_regex.circom new file mode 100644 index 00000000..f8a2f013 --- /dev/null +++ b/packages/circuits/tests/circuits/test_forced_subject_regex.circom @@ -0,0 +1,5 @@ +pragma circom 2.1.5; + +include "../../src/regexes/forced_subject_regex.circom"; + +component main = ForcedSubjectRegex(256); \ No newline at end of file diff --git a/packages/circuits/tests/emai_auth_legacy_recipient.test.ts b/packages/circuits/tests/emai_auth_legacy_recipient.test.ts new file mode 100644 index 00000000..85fd7815 --- /dev/null +++ b/packages/circuits/tests/emai_auth_legacy_recipient.test.ts @@ -0,0 +1,377 @@ +const circom_tester = require("circom_tester"); +const wasm_tester = circom_tester.wasm; +import * as path from "path"; +const relayerUtils = require("@zk-email/relayer-utils"); +import { genEmailCircuitInput } from "../helpers/email_auth"; +import { genRecipientInputLegacy } from "../helpers/recipient"; +import { readFileSync } from "fs"; + +jest.setTimeout(1440000); +describe("Email Auth Legacy with Recipient", () => { + let circuit; + beforeAll(async () => { + const option = { + include: path.join(__dirname, "../../../node_modules"), + }; + circuit = await wasm_tester( + path.join(__dirname, "./circuits/email_auth_with_recipient.circom"), + option + ); + }); + + it("Verify a sent email whose subject has an email address", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_legacy_test1.eml" + ); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + console.log(parsedEmail.canonicalizedHeader); + const accountCode = await relayerUtils.genAccountCode(); + const { + body_hash_idx, + precomputed_sha, + padded_body, + padded_body_len, + command_idx, + padded_cleaned_body, + ...emailAuthInput + } = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + const recipientInput = await genRecipientInputLegacy(emailFilePath); + const circuitInputs = { + ...emailAuthInput, + subject_email_addr_idx: recipientInput.subject_email_addr_idx, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + const timestamp = BigInt(1694989812); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + const maskedSubject = "Send 0.1 ETH to "; + const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); + const maskedSubjectFields = + relayerUtils.bytes2Fields(paddedMaskedSubject); + for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { + expect(BigInt(maskedSubjectFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + const fromAddr = "suegamisora@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedSubjectFields.length] + ); + expect(BigInt(0)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedSubjectFields.length + 1 + ] + ); + expect(BigInt(1)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedSubjectFields.length + 2 + ] + ); + const recipientEmailAddr = "alice@gmail.com"; + const emailAddrCommit = relayerUtils.emailAddrCommitWithSignature( + recipientEmailAddr, + parsedEmail.signature + ); + expect(BigInt(emailAddrCommit)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedSubjectFields.length + 3 + ] + ); + }); + + it("Verify a sent email whose from field has a dummy email address name", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_legacy_test3.eml" + ); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + console.log(parsedEmail.canonicalizedHeader); + const accountCode = await relayerUtils.genAccountCode(); + const { + body_hash_idx, + precomputed_sha, + padded_body, + padded_body_len, + command_idx, + padded_cleaned_body, + ...emailAuthInput + } = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + const recipientInput = await genRecipientInputLegacy(emailFilePath); + const circuitInputs = { + ...emailAuthInput, + subject_email_addr_idx: recipientInput.subject_email_addr_idx, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + const timestamp = BigInt(1696965932); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + const maskedSubject = "Send 1 ETH to "; + const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); + const maskedSubjectFields = + relayerUtils.bytes2Fields(paddedMaskedSubject); + for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { + expect(BigInt(maskedSubjectFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + const fromAddr = "suegamisora@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedSubjectFields.length] + ); + expect(BigInt(0)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedSubjectFields.length + 1 + ] + ); + expect(BigInt(1)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedSubjectFields.length + 2 + ] + ); + const recipientEmailAddr = "bob@example.com"; + const emailAddrCommit = relayerUtils.emailAddrCommitWithSignature( + recipientEmailAddr, + parsedEmail.signature + ); + expect(BigInt(emailAddrCommit)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedSubjectFields.length + 3 + ] + ); + }); + + it("Verify a sent email whose from field has a non-English name", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_legacy_test4.eml" + ); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + console.log(parsedEmail.canonicalizedHeader); + const accountCode = await relayerUtils.genAccountCode(); + const { + body_hash_idx, + precomputed_sha, + padded_body, + padded_body_len, + command_idx, + padded_cleaned_body, + ...emailAuthInput + } = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + const recipientInput = await genRecipientInputLegacy(emailFilePath); + const circuitInputs = { + ...emailAuthInput, + subject_email_addr_idx: recipientInput.subject_email_addr_idx, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + const timestamp = BigInt(1696967028); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + const maskedSubject = "Send 1 ETH to "; + const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); + const maskedSubjectFields = + relayerUtils.bytes2Fields(paddedMaskedSubject); + for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { + expect(BigInt(maskedSubjectFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + const fromAddr = "suegamisora@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedSubjectFields.length] + ); + expect(BigInt(0)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedSubjectFields.length + 1 + ] + ); + expect(BigInt(1)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedSubjectFields.length + 2 + ] + ); + const recipientEmailAddr = "bob@example.com"; + const emailAddrCommit = relayerUtils.emailAddrCommitWithSignature( + recipientEmailAddr, + parsedEmail.signature + ); + expect(BigInt(emailAddrCommit)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedSubjectFields.length + 3 + ] + ); + }); + + it("Verify a sent email whose subject has an invitation code", async () => { + const emailFilePath = path.join(__dirname, "./emails/email_auth_legacy_test5.eml"); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + console.log(parsedEmail.canonicalizedHeader); + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + const { + body_hash_idx, + precomputed_sha, + padded_body, + padded_body_len, + command_idx, + padded_cleaned_body, + ...emailAuthInput + } = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + const recipientInput = await genRecipientInputLegacy(emailFilePath); + const circuitInputs = { + ...emailAuthInput, + subject_email_addr_idx: recipientInput.subject_email_addr_idx, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + const timestamp = BigInt(1707866192); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + const maskedSubject = "Send 0.12 ETH to "; + const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); + const maskedSubjectFields = relayerUtils.bytes2Fields(paddedMaskedSubject); + for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { + expect(BigInt(maskedSubjectFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + const fromAddr = "suegamisora@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedSubjectFields.length] + ); + expect(BigInt(1)).toEqual( + witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 1] + ); + expect(BigInt(1)).toEqual( + witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 2] + ); + const recipientEmailAddr = "alice@gmail.com"; + const emailAddrCommit = relayerUtils.emailAddrCommitWithSignature( + recipientEmailAddr, + parsedEmail.signature + ); + expect(BigInt(emailAddrCommit)).toEqual( + witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 3] + ); + }); + + it("Verify a sent email with a too large subject_email_addr_idx", async () => { + const emailFilePath = path.join(__dirname, "./emails/email_auth_legacy_test1.eml"); + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + const { + body_hash_idx, + precomputed_sha, + padded_body, + padded_body_len, + command_idx, + padded_cleaned_body, + ...emailAuthInput + } = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + const recipientInput = await genRecipientInputLegacy(emailFilePath); + const circuitInputs = { + ...emailAuthInput, + subject_email_addr_idx: recipientInput.subject_email_addr_idx, + }; + circuitInputs.subject_email_addr_idx = 605; + async function failFn() { + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + } + await expect(failFn).rejects.toThrow(); + }); +}); diff --git a/packages/circuits/tests/emai_auth_recipient.test.ts b/packages/circuits/tests/emai_auth_recipient.test.ts new file mode 100644 index 00000000..a4b960fa --- /dev/null +++ b/packages/circuits/tests/emai_auth_recipient.test.ts @@ -0,0 +1,209 @@ +const circom_tester = require("circom_tester"); +const wasm_tester = circom_tester.wasm; +import * as path from "path"; +const relayerUtils = require("@zk-email/relayer-utils"); +import { genEmailCircuitInput } from "../helpers/email_auth"; +import { readFileSync } from "fs"; +import { genRecipientInput } from "../helpers/recipient"; + +const option = { + include: path.join(__dirname, "../../../node_modules"), + output: path.join(__dirname, "../build"), + recompile: true, +}; + +jest.setTimeout(1440000); +describe("Email Auth with Recipient", () => { + let circuit; + beforeAll(async () => { + circuit = await wasm_tester( + path.join( + __dirname, + "./circuits/test_email_auth_with_recipient.circom" + ), + option + ); + }); + + it("Verify a sent email whose body has an email address with the recipient's email address commitment", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_test1.eml" + ); + + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + console.log(parsedEmail); + const accountCode = await relayerUtils.genAccountCode(); + + const { + subject_idx, + ...emailAuthInput + } = + await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + shaPrecomputeSelector: '(<(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)? (=\r\n)?i(=\r\n)?d(=\r\n)?=3D(=\r\n)?"(=\r\n)?[^"]*(=\r\n)?z(=\r\n)?k(=\r\n)?e(=\r\n)?m(=\r\n)?a(=\r\n)?i(=\r\n)?l(=\r\n)?[^"]*(=\r\n)?"(=\r\n)?[^>]*(=\r\n)?>(=\r\n)?)(=\r\n)?([^<>/]+)(<(=\r\n)?/(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)?>(=\r\n)?)', + }); + const command = "Send 0.1 ETH to alice@gmail.com"; + const recipientInput = await genRecipientInput(command, parsedEmail.signature); + const circuitInputs = { + ...emailAuthInput, + command_email_addr_idx: recipientInput.command_email_addr_idx, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + + const timestamp = BigInt(1729865810); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + + const maskedCommand = "Send 0.1 ETH to "; + const paddedMaskedCommand = relayerUtils.padString(maskedCommand, 605); + const maskedCommandFields = + relayerUtils.bytes2Fields(paddedMaskedCommand); + for (let idx = 0; idx < maskedCommandFields.length; ++idx) { + expect(BigInt(maskedCommandFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + + const fromAddr = "emaiwallet.alice@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedCommandFields.length] + ); + + expect(BigInt(0)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedCommandFields.length + 1 + ] + ); + + const recipientEmailAddr = "alice@gmail.com"; + const emailAddrCommit = relayerUtils.emailAddrCommitWithSignature( + recipientEmailAddr, + parsedEmail.signature + ); + expect(BigInt(1)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedCommandFields.length + 2 + ] + ); + expect(BigInt(emailAddrCommit)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedCommandFields.length + 3 + ] + ); + }); + + it("Verify a sent email whose body has no email address with the recipient's email address commitment", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_test2.eml" + ); + + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + console.log(parsedEmail); + const accountCode = await relayerUtils.genAccountCode(); + + const { + subject_idx, + ...emailAuthInput + } = + await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + shaPrecomputeSelector: '(<(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)? (=\r\n)?i(=\r\n)?d(=\r\n)?=3D(=\r\n)?"(=\r\n)?[^"]*(=\r\n)?z(=\r\n)?k(=\r\n)?e(=\r\n)?m(=\r\n)?a(=\r\n)?i(=\r\n)?l(=\r\n)?[^"]*(=\r\n)?"(=\r\n)?[^>]*(=\r\n)?>(=\r\n)?)(=\r\n)?([^<>/]+)(<(=\r\n)?/(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)?>(=\r\n)?)', + }); + const command = "Swap 1 ETH to DAI"; + const recipientInput = await genRecipientInput(command, parsedEmail.signature); + const circuitInputs = { + ...emailAuthInput, + command_email_addr_idx: recipientInput.command_email_addr_idx, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + + const timestamp = BigInt(1729865832); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + + const maskedCommand = "Swap 1 ETH to DAI"; + const paddedMaskedCommand = relayerUtils.padString(maskedCommand, 605); + const maskedCommandFields = + relayerUtils.bytes2Fields(paddedMaskedCommand); + for (let idx = 0; idx < maskedCommandFields.length; ++idx) { + expect(BigInt(maskedCommandFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + + const fromAddr = "emaiwallet.alice@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedCommandFields.length] + ); + + expect(BigInt(0)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedCommandFields.length + 1 + ] + ); + + expect(BigInt(0)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedCommandFields.length + 2 + ] + ); + expect(BigInt(0)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedCommandFields.length + 3 + ] + ); + }); + +}); diff --git a/packages/circuits/tests/email_auth.test.ts b/packages/circuits/tests/email_auth.test.ts index d8526337..6028df88 100644 --- a/packages/circuits/tests/email_auth.test.ts +++ b/packages/circuits/tests/email_auth.test.ts @@ -2,397 +2,618 @@ const circom_tester = require("circom_tester"); const wasm_tester = circom_tester.wasm; import * as path from "path"; const relayerUtils = require("@zk-email/relayer-utils"); - -import { genEmailAuthInput } from "../helpers/email_auth"; +import { genEmailCircuitInput } from "../helpers/email_auth"; import { readFileSync } from "fs"; +import { genRecipientInput } from "../helpers/recipient"; + +const option = { + include: path.join(__dirname, "../../../node_modules"), + output: path.join(__dirname, "../build"), + recompile: true, +}; jest.setTimeout(1440000); describe("Email Auth", () => { - let circuit; - beforeAll(async () => { - const option = { - include: path.join(__dirname, "../../../node_modules"), - }; - circuit = await wasm_tester( - path.join(__dirname, "../src/email_auth.circom"), - option - ); - }); - - it("Verify a sent email whose subject has an email address", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test1.eml"); - const emailRaw = readFileSync(emailFilePath, "utf8"); - const parsedEmail = await relayerUtils.parseEmail(emailRaw); - console.log(parsedEmail.canonicalizedHeader); - const accountCode = await relayerUtils.genAccountCode(); - const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); - console.log(circuitInputs); - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - const domainName = "gmail.com"; - const paddedDomain = relayerUtils.padString(domainName, 255); - const domainFields = relayerUtils.bytes2Fields(paddedDomain); - for (let idx = 0; idx < domainFields.length; ++idx) { - expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); - } - const expectedPubKeyHash = relayerUtils.publicKeyHash( - parsedEmail.publicKey - ); - expect(BigInt(expectedPubKeyHash)).toEqual( - witness[1 + domainFields.length] - ); - const expectedEmailNullifier = relayerUtils.emailNullifier( - parsedEmail.signature - ); - expect(BigInt(expectedEmailNullifier)).toEqual( - witness[1 + domainFields.length + 1] - ); - const timestamp = 1694989812n; - expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); - const maskedSubject = "Send 0.1 ETH to "; - const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); - const maskedSubjectFields = relayerUtils.bytes2Fields(paddedMaskedSubject); - for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { - expect(BigInt(maskedSubjectFields[idx])).toEqual( - witness[1 + domainFields.length + 3 + idx] - ); - } - const fromAddr = "suegamisora@gmail.com"; - const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); - expect(BigInt(accountSalt)).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length] - ); - expect(0n).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 1] - ); - }); - - it("Verify a sent email whose subject does not have an email address", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test2.eml"); - const emailRaw = readFileSync(emailFilePath, "utf8"); - const parsedEmail = await relayerUtils.parseEmail(emailRaw); - console.log(parsedEmail.canonicalizedHeader); - const accountCode = await relayerUtils.genAccountCode(); - const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - const domainName = "gmail.com"; - const paddedDomain = relayerUtils.padString(domainName, 255); - const domainFields = relayerUtils.bytes2Fields(paddedDomain); - for (let idx = 0; idx < domainFields.length; ++idx) { - expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); - } - const expectedPubKeyHash = relayerUtils.publicKeyHash( - parsedEmail.publicKey - ); - expect(BigInt(expectedPubKeyHash)).toEqual( - witness[1 + domainFields.length] - ); - const expectedEmailNullifier = relayerUtils.emailNullifier( - parsedEmail.signature - ); - expect(BigInt(expectedEmailNullifier)).toEqual( - witness[1 + domainFields.length + 1] - ); - const timestamp = 1696964295n; - expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); - const maskedSubject = "Swap 1 ETH to DAI"; - const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); - const maskedSubjectFields = relayerUtils.bytes2Fields(paddedMaskedSubject); - for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { - expect(BigInt(maskedSubjectFields[idx])).toEqual( - witness[1 + domainFields.length + 3 + idx] - ); - } - const fromAddr = "suegamisora@gmail.com"; - const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); - expect(BigInt(accountSalt)).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length] - ); - expect(0n).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 1] - ); - }); - - it("Verify a sent email whose from field has a dummy email address name", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test3.eml"); - const emailRaw = readFileSync(emailFilePath, "utf8"); - const parsedEmail = await relayerUtils.parseEmail(emailRaw); - console.log(parsedEmail.canonicalizedHeader); - const accountCode = await relayerUtils.genAccountCode(); - const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - const domainName = "gmail.com"; - const paddedDomain = relayerUtils.padString(domainName, 255); - const domainFields = relayerUtils.bytes2Fields(paddedDomain); - for (let idx = 0; idx < domainFields.length; ++idx) { - expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); - } - const expectedPubKeyHash = relayerUtils.publicKeyHash( - parsedEmail.publicKey - ); - expect(BigInt(expectedPubKeyHash)).toEqual( - witness[1 + domainFields.length] - ); - const expectedEmailNullifier = relayerUtils.emailNullifier( - parsedEmail.signature - ); - expect(BigInt(expectedEmailNullifier)).toEqual( - witness[1 + domainFields.length + 1] - ); - const timestamp = 1696965932n; - expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); - const maskedSubject = "Send 1 ETH to "; - const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); - const maskedSubjectFields = relayerUtils.bytes2Fields(paddedMaskedSubject); - for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { - expect(BigInt(maskedSubjectFields[idx])).toEqual( - witness[1 + domainFields.length + 3 + idx] - ); - } - const fromAddr = "suegamisora@gmail.com"; - const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); - expect(BigInt(accountSalt)).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length] - ); - expect(0n).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 1] - ); - }); - - it("Verify a sent email whose from field has a non-English name", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test4.eml"); - const emailRaw = readFileSync(emailFilePath, "utf8"); - const parsedEmail = await relayerUtils.parseEmail(emailRaw); - console.log(parsedEmail.canonicalizedHeader); - const accountCode = await relayerUtils.genAccountCode(); - const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - const domainName = "gmail.com"; - const paddedDomain = relayerUtils.padString(domainName, 255); - const domainFields = relayerUtils.bytes2Fields(paddedDomain); - for (let idx = 0; idx < domainFields.length; ++idx) { - expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); - } - const expectedPubKeyHash = relayerUtils.publicKeyHash( - parsedEmail.publicKey - ); - expect(BigInt(expectedPubKeyHash)).toEqual( - witness[1 + domainFields.length] - ); - const expectedEmailNullifier = relayerUtils.emailNullifier( - parsedEmail.signature - ); - expect(BigInt(expectedEmailNullifier)).toEqual( - witness[1 + domainFields.length + 1] - ); - const timestamp = 1696967028n; - expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); - const maskedSubject = "Send 1 ETH to "; - const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); - const maskedSubjectFields = relayerUtils.bytes2Fields(paddedMaskedSubject); - for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { - expect(BigInt(maskedSubjectFields[idx])).toEqual( - witness[1 + domainFields.length + 3 + idx] - ); - } - const fromAddr = "suegamisora@gmail.com"; - const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); - expect(BigInt(accountSalt)).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length] - ); - expect(0n).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 1] - ); - }); - - it("Verify a sent email whose subject has an email address and an invitation code", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test5.eml"); - const emailRaw = readFileSync(emailFilePath, "utf8"); - const parsedEmail = await relayerUtils.parseEmail(emailRaw); - console.log(parsedEmail.canonicalizedHeader); - const accountCode = - "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; - const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - const domainName = "gmail.com"; - const paddedDomain = relayerUtils.padString(domainName, 255); - const domainFields = relayerUtils.bytes2Fields(paddedDomain); - for (let idx = 0; idx < domainFields.length; ++idx) { - expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); - } - const expectedPubKeyHash = relayerUtils.publicKeyHash( - parsedEmail.publicKey - ); - expect(BigInt(expectedPubKeyHash)).toEqual( - witness[1 + domainFields.length] - ); - const expectedEmailNullifier = relayerUtils.emailNullifier( - parsedEmail.signature - ); - expect(BigInt(expectedEmailNullifier)).toEqual( - witness[1 + domainFields.length + 1] - ); - const timestamp = 1707866192n; - expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); - const maskedSubject = "Send 0.12 ETH to "; - const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); - const maskedSubjectFields = relayerUtils.bytes2Fields(paddedMaskedSubject); - for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { - expect(BigInt(maskedSubjectFields[idx])).toEqual( - witness[1 + domainFields.length + 3 + idx] - ); - } - const fromAddr = "suegamisora@gmail.com"; - const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); - expect(BigInt(accountSalt)).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length] - ); - expect(1n).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 1] - ); - }); - - it("Verify a sent email whose subject has an invitation code", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test6.eml"); - const emailRaw = readFileSync(emailFilePath, "utf8"); - const parsedEmail = await relayerUtils.parseEmail(emailRaw); - const accountCode = - "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; - const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - const domainName = "gmail.com"; - const paddedDomain = relayerUtils.padString(domainName, 255); - const domainFields = relayerUtils.bytes2Fields(paddedDomain); - for (let idx = 0; idx < domainFields.length; ++idx) { - expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); - } - const expectedPubKeyHash = relayerUtils.publicKeyHash( - parsedEmail.publicKey - ); - expect(BigInt(expectedPubKeyHash)).toEqual( - witness[1 + domainFields.length] - ); - const expectedEmailNullifier = relayerUtils.emailNullifier( - parsedEmail.signature - ); - expect(BigInt(expectedEmailNullifier)).toEqual( - witness[1 + domainFields.length + 1] - ); - const timestamp = 1711992080n; - expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); - const maskedSubject = - "Re: Accept guardian request for 0x04884491560f38342C56E26BDD0fEAbb68E2d2FC"; - const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); - const maskedSubjectFields = relayerUtils.bytes2Fields(paddedMaskedSubject); - for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { - expect(BigInt(maskedSubjectFields[idx])).toEqual( - witness[1 + domainFields.length + 3 + idx] - ); - } - const fromAddr = "suegamisora@gmail.com"; - const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); - expect(BigInt(accountSalt)).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length] - ); - expect(1n).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 1] - ); - }); - - it("Verify a sent email whose subject tries to forge the From field", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test7.eml"); - const accountCode = - "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; - const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); - circuitInputs.from_addr_idx = circuitInputs.subject_idx; - async function failFn() { - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - } - await expect(failFn).rejects.toThrow(); - }); - - - it("Verify a sent email with a too large from_addr_idx", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test1.eml"); - const accountCode = - "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; - const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); - circuitInputs.from_addr_idx = 1024; - async function failFn() { - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - } - await expect(failFn).rejects.toThrow(); - }); - - it("Verify a sent email with a too large domain_idx", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test1.eml"); - const accountCode = - "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; - const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); - circuitInputs.domain_idx = 256; - async function failFn() { - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - } - await expect(failFn).rejects.toThrow(); - }); - - it("Verify a sent email with a too large subject_idx", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test1.eml"); - const accountCode = - "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; - const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); - circuitInputs.subject_idx = 1024; - async function failFn() { - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - } - await expect(failFn).rejects.toThrow(); - }); - - it("Verify a sent email with a too large timestamp_idx", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test1.eml"); - const accountCode = - "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; - const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); - circuitInputs.timestamp_idx = 1024; - async function failFn() { - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - } - await expect(failFn).rejects.toThrow(); - }); - - it("Verify a sent email with a too large code_idx", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test1.eml"); - const accountCode = - "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; - const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); - circuitInputs.code_idx = 1024; - async function failFn() { - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - } - await expect(failFn).rejects.toThrow(); - }); - - it("Verify a sent email with a too large code_idx 2", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test1.eml"); - const accountCode = - "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; - const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); - circuitInputs.code_idx = 1024 * 4; - async function failFn() { - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - } - await expect(failFn).rejects.toThrow(); - }); + let circuit; + beforeAll(async () => { + circuit = await wasm_tester( + path.join( + __dirname, + "./circuits/test_email_auth.circom" + ), + option + ); + }); + + it("Verify a sent email whose body has an email address", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_test1.eml" + ); + + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + console.log(parsedEmail); + const accountCode = await relayerUtils.genAccountCode(); + + const circuitInputs = + await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + shaPrecomputeSelector: '(<(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)? (=\r\n)?i(=\r\n)?d(=\r\n)?=3D(=\r\n)?"(=\r\n)?[^"]*(=\r\n)?z(=\r\n)?k(=\r\n)?e(=\r\n)?m(=\r\n)?a(=\r\n)?i(=\r\n)?l(=\r\n)?[^"]*(=\r\n)?"(=\r\n)?[^>]*(=\r\n)?>(=\r\n)?)(=\r\n)?([^<>/]+)(<(=\r\n)?/(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)?>(=\r\n)?)', + }); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + + const timestamp = BigInt(1729865810); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + + const maskedCommand = "Send 0.1 ETH to "; + const paddedMaskedCommand = relayerUtils.padString(maskedCommand, 605); + const maskedCommandFields = + relayerUtils.bytes2Fields(paddedMaskedCommand); + for (let idx = 0; idx < maskedCommandFields.length; ++idx) { + expect(BigInt(maskedCommandFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + + const fromAddr = "emaiwallet.alice@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedCommandFields.length] + ); + + expect(BigInt(0)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedCommandFields.length + 1 + ] + ); + }); + + it("Verify a sent email whose body does not have an email address", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_test2.eml" + ); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + + const accountCode = await relayerUtils.genAccountCode(); + const circuitInputs = + await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + shaPrecomputeSelector: '(<(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)? (=\r\n)?i(=\r\n)?d(=\r\n)?=3D(=\r\n)?"(=\r\n)?[^"]*(=\r\n)?z(=\r\n)?k(=\r\n)?e(=\r\n)?m(=\r\n)?a(=\r\n)?i(=\r\n)?l(=\r\n)?[^"]*(=\r\n)?"(=\r\n)?[^>]*(=\r\n)?>(=\r\n)?)(=\r\n)?([^<>/]+)(<(=\r\n)?/(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)?>(=\r\n)?)', + }); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + + const timestamp = BigInt(1729865832); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + + const maskedCommand = "Swap 1 ETH to DAI"; + const paddedMaskedCommand = relayerUtils.padString(maskedCommand, 605); + const maskedCommandFields = + relayerUtils.bytes2Fields(paddedMaskedCommand); + for (let idx = 0; idx < maskedCommandFields.length; ++idx) { + expect(BigInt(maskedCommandFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + + const fromAddr = "emaiwallet.alice@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedCommandFields.length] + ); + + expect(BigInt(0)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedCommandFields.length + 1 + ] + ); + }); + + it("Verify a sent email whose from field has a dummy email address name", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_test3.eml" + ); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + + const accountCode = await relayerUtils.genAccountCode(); + + const circuitInputs = + await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + shaPrecomputeSelector: '(<(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)? (=\r\n)?i(=\r\n)?d(=\r\n)?=3D(=\r\n)?"(=\r\n)?[^"]*(=\r\n)?z(=\r\n)?k(=\r\n)?e(=\r\n)?m(=\r\n)?a(=\r\n)?i(=\r\n)?l(=\r\n)?[^"]*(=\r\n)?"(=\r\n)?[^>]*(=\r\n)?>(=\r\n)?)(=\r\n)?([^<>/]+)(<(=\r\n)?/(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)?>(=\r\n)?)', + }); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + + const timestamp = BigInt(1729866032); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + + const maskedCommand = "Send 1 ETH to "; + const paddedMaskedCommand = relayerUtils.padString(maskedCommand, 605); + const maskedCommandFields = + relayerUtils.bytes2Fields(paddedMaskedCommand); + for (let idx = 0; idx < maskedCommandFields.length; ++idx) { + expect(BigInt(maskedCommandFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + + const fromAddr = "emaiwallet.alice@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedCommandFields.length] + ); + expect(BigInt(0)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedCommandFields.length + 1 + ] + ); + }); + + it("Verify a sent email whose body has an email address and an invitation code", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_test4.eml" + ); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + + const circuitInputs = + await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + shaPrecomputeSelector: '(<(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)? (=\r\n)?i(=\r\n)?d(=\r\n)?=3D(=\r\n)?"(=\r\n)?[^"]*(=\r\n)?z(=\r\n)?k(=\r\n)?e(=\r\n)?m(=\r\n)?a(=\r\n)?i(=\r\n)?l(=\r\n)?[^"]*(=\r\n)?"(=\r\n)?[^>]*(=\r\n)?>(=\r\n)?)(=\r\n)?([^<>/]+)(<(=\r\n)?/(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)?>(=\r\n)?)', + }); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + + const timestamp = BigInt(1729866112); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + + const maskedCommand = "Send 1 ETH to "; + const paddedMaskedCommand = relayerUtils.padString(maskedCommand, 605); + const maskedCommandFields = + relayerUtils.bytes2Fields(paddedMaskedCommand); + for (let idx = 0; idx < maskedCommandFields.length; ++idx) { + expect(BigInt(maskedCommandFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + + const fromAddr = "emaiwallet.alice@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedCommandFields.length] + ); + + expect(BigInt(1)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedCommandFields.length + 1 + ] + ); + }); + + it("Verify a sent email whose body has an invitation code and another hex string", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_test5.eml" + ); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + + const circuitInputs = + await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + shaPrecomputeSelector: '(<(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)? (=\r\n)?i(=\r\n)?d(=\r\n)?=3D(=\r\n)?"(=\r\n)?[^"]*(=\r\n)?z(=\r\n)?k(=\r\n)?e(=\r\n)?m(=\r\n)?a(=\r\n)?i(=\r\n)?l(=\r\n)?[^"]*(=\r\n)?"(=\r\n)?[^>]*(=\r\n)?>(=\r\n)?)(=\r\n)?([^<>/]+)(<(=\r\n)?/(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)?>(=\r\n)?)', + }); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + + const timestamp = BigInt(1729866146); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + + const maskedCommand = + "Accept guardian request for 0x04884491560f38342C56E26BDD0fEAbb68E2d2FC"; + const paddedMaskedCommand = relayerUtils.padString(maskedCommand, 605); + const maskedCommandFields = + relayerUtils.bytes2Fields(paddedMaskedCommand); + for (let idx = 0; idx < maskedCommandFields.length; ++idx) { + expect(BigInt(maskedCommandFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + const fromAddr = "emaiwallet.alice@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedCommandFields.length] + ); + + expect(BigInt(1)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedCommandFields.length + 1 + ] + ); + }); + + it("Verify a sent email whose subject has Re:", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_test6.eml" + ); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + + const circuitInputs = + await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + shaPrecomputeSelector: '(<(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)? (=\r\n)?i(=\r\n)?d(=\r\n)?=3D(=\r\n)?"(=\r\n)?[^"]*(=\r\n)?z(=\r\n)?k(=\r\n)?e(=\r\n)?m(=\r\n)?a(=\r\n)?i(=\r\n)?l(=\r\n)?[^"]*(=\r\n)?"(=\r\n)?[^>]*(=\r\n)?>(=\r\n)?)(=\r\n)?([^<>/]+)(<(=\r\n)?/(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)?>(=\r\n)?)', + }); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + + const timestamp = BigInt(1729866214); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + + const maskedCommand = + "Accept guardian request for 0x04884491560f38342C56E26BDD0fEAbb68E2d2FC"; + const paddedMaskedCommand = relayerUtils.padString(maskedCommand, 605); + const maskedCommandFields = + relayerUtils.bytes2Fields(paddedMaskedCommand); + for (let idx = 0; idx < maskedCommandFields.length; ++idx) { + expect(BigInt(maskedCommandFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + const fromAddr = "emaiwallet.alice@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedCommandFields.length] + ); + + expect(BigInt(1)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedCommandFields.length + 1 + ] + ); + }); + + it("Verify a sent email whose subject has FWD: FWD:", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_test7.eml" + ); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + + const circuitInputs = + await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + shaPrecomputeSelector: '(<(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)? (=\r\n)?i(=\r\n)?d(=\r\n)?=3D(=\r\n)?"(=\r\n)?[^"]*(=\r\n)?z(=\r\n)?k(=\r\n)?e(=\r\n)?m(=\r\n)?a(=\r\n)?i(=\r\n)?l(=\r\n)?[^"]*(=\r\n)?"(=\r\n)?[^>]*(=\r\n)?>(=\r\n)?)(=\r\n)?([^<>/]+)(<(=\r\n)?/(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)?>(=\r\n)?)', + }); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + + const timestamp = BigInt(1729866476); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + + const maskedCommand = + "Accept guardian request for 0x04884491560f38342C56E26BDD0fEAbb68E2d2FC"; + const paddedMaskedCommand = relayerUtils.padString(maskedCommand, 605); + const maskedCommandFields = + relayerUtils.bytes2Fields(paddedMaskedCommand); + for (let idx = 0; idx < maskedCommandFields.length; ++idx) { + expect(BigInt(maskedCommandFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + const fromAddr = "emaiwallet.alice@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedCommandFields.length] + ); + + expect(BigInt(1)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedCommandFields.length + 1 + ] + ); + }); + + it("Verify a sent email with a too large from_addr_idx", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_test1.eml" + ); + + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + + const circuitInputs = + await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + shaPrecomputeSelector: '(<(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)? (=\r\n)?i(=\r\n)?d(=\r\n)?=3D(=\r\n)?"(=\r\n)?[^"]*(=\r\n)?z(=\r\n)?k(=\r\n)?e(=\r\n)?m(=\r\n)?a(=\r\n)?i(=\r\n)?l(=\r\n)?[^"]*(=\r\n)?"(=\r\n)?[^>]*(=\r\n)?>(=\r\n)?)(=\r\n)?([^<>/]+)(<(=\r\n)?/(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)?>(=\r\n)?)', + }); + circuitInputs.from_addr_idx = 640; + async function failFn() { + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + } + await expect(failFn).rejects.toThrow(); + }); + + it("Verify a sent email with a too large domain_idx", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_test1.eml" + ); + + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + + const circuitInputs = + await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + shaPrecomputeSelector: '(<(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)? (=\r\n)?i(=\r\n)?d(=\r\n)?=3D(=\r\n)?"(=\r\n)?[^"]*(=\r\n)?z(=\r\n)?k(=\r\n)?e(=\r\n)?m(=\r\n)?a(=\r\n)?i(=\r\n)?l(=\r\n)?[^"]*(=\r\n)?"(=\r\n)?[^>]*(=\r\n)?>(=\r\n)?)(=\r\n)?([^<>/]+)(<(=\r\n)?/(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)?>(=\r\n)?)', + }); + circuitInputs.domain_idx = 256; + async function failFn() { + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + } + await expect(failFn).rejects.toThrow(); + }); + + it("Verify a sent email with a too large timestamp_idx", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_test1.eml" + ); + + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + + const circuitInputs = + await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + shaPrecomputeSelector: '(<(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)? (=\r\n)?i(=\r\n)?d(=\r\n)?=3D(=\r\n)?"(=\r\n)?[^"]*(=\r\n)?z(=\r\n)?k(=\r\n)?e(=\r\n)?m(=\r\n)?a(=\r\n)?i(=\r\n)?l(=\r\n)?[^"]*(=\r\n)?"(=\r\n)?[^>]*(=\r\n)?>(=\r\n)?)(=\r\n)?([^<>/]+)(<(=\r\n)?/(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)?>(=\r\n)?)', + }); + circuitInputs.timestamp_idx = 640; + async function failFn() { + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + } + await expect(failFn).rejects.toThrow(); + }); + + it("Verify a sent email with a too large code_idx", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_test1.eml" + ); + + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + + const circuitInputs = + await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + shaPrecomputeSelector: '(<(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)? (=\r\n)?i(=\r\n)?d(=\r\n)?=3D(=\r\n)?"(=\r\n)?[^"]*(=\r\n)?z(=\r\n)?k(=\r\n)?e(=\r\n)?m(=\r\n)?a(=\r\n)?i(=\r\n)?l(=\r\n)?[^"]*(=\r\n)?"(=\r\n)?[^>]*(=\r\n)?>(=\r\n)?)(=\r\n)?([^<>/]+)(<(=\r\n)?/(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)?>(=\r\n)?)', + }); + circuitInputs.code_idx = 768; + async function failFn() { + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + } + await expect(failFn).rejects.toThrow(); + }); + + it("Verify a sent email without the forced subject", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_invalid_test1.eml" + ); + + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + + const circuitInputs = + await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + shaPrecomputeSelector: '(<(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)? (=\r\n)?i(=\r\n)?d(=\r\n)?=3D(=\r\n)?"(=\r\n)?[^"]*(=\r\n)?z(=\r\n)?k(=\r\n)?e(=\r\n)?m(=\r\n)?a(=\r\n)?i(=\r\n)?l(=\r\n)?[^"]*(=\r\n)?"(=\r\n)?[^>]*(=\r\n)?>(=\r\n)?)(=\r\n)?([^<>/]+)(<(=\r\n)?/(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)?>(=\r\n)?)', + }); + circuitInputs.timestamp_idx = 640; + async function failFn() { + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + } + await expect(failFn).rejects.toThrow(); + }); }); diff --git a/packages/circuits/tests/email_auth_legacy.test.ts b/packages/circuits/tests/email_auth_legacy.test.ts new file mode 100644 index 00000000..7e37c6a0 --- /dev/null +++ b/packages/circuits/tests/email_auth_legacy.test.ts @@ -0,0 +1,536 @@ +const circom_tester = require("circom_tester"); +const wasm_tester = circom_tester.wasm; +import * as path from "path"; +const relayerUtils = require("@zk-email/relayer-utils"); + +import { genEmailCircuitInput } from "../helpers/email_auth"; +import { readFileSync } from "fs"; + +jest.setTimeout(1440000); +describe("Email Auth Legacy", () => { + let circuit; + beforeAll(async () => { + const option = { + include: path.join(__dirname, "../../../node_modules"), + recompile: true, + }; + circuit = await wasm_tester( + path.join(__dirname, "../src/email_auth_legacy.circom"), + option + ); + }); + + it("Verify a sent email whose subject has an email address", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_legacy_test1.eml" + ); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + console.log(parsedEmail.canonicalizedHeader); + const accountCode = await relayerUtils.genAccountCode(); + const { + body_hash_idx, + precomputed_sha, + padded_body, + padded_body_len, + command_idx, + padded_cleaned_body, + ...circuitInputsRelevant + } = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + console.log(circuitInputsRelevant); + const witness = await circuit.calculateWitness(circuitInputsRelevant); + await circuit.checkConstraints(witness); + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + const timestamp = BigInt(1694989812); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + const maskedSubject = "Send 0.1 ETH to "; + const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); + const maskedSubjectFields = + relayerUtils.bytes2Fields(paddedMaskedSubject); + for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { + expect(BigInt(maskedSubjectFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + const fromAddr = "suegamisora@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedSubjectFields.length] + ); + expect(BigInt(0)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedSubjectFields.length + 1 + ] + ); + }); + + it("Verify a sent email whose subject does not have an email address", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_legacy_test2.eml" + ); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + console.log(parsedEmail.canonicalizedHeader); + const accountCode = await relayerUtils.genAccountCode(); + const { + body_hash_idx, + precomputed_sha, + padded_body, + padded_body_len, + command_idx, + padded_cleaned_body, + ...circuitInputsRelevant + } = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + const witness = await circuit.calculateWitness(circuitInputsRelevant); + await circuit.checkConstraints(witness); + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + const timestamp = BigInt(1696964295); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + const maskedSubject = "Swap 1 ETH to DAI"; + const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); + const maskedSubjectFields = + relayerUtils.bytes2Fields(paddedMaskedSubject); + for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { + expect(BigInt(maskedSubjectFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + const fromAddr = "suegamisora@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedSubjectFields.length] + ); + expect(BigInt(0)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedSubjectFields.length + 1 + ] + ); + }); + + it("Verify a sent email whose from field has a dummy email address name", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_legacy_test3.eml" + ); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + console.log(parsedEmail.canonicalizedHeader); + const accountCode = await relayerUtils.genAccountCode(); + const { + body_hash_idx, + precomputed_sha, + padded_body, + padded_body_len, + command_idx, + padded_cleaned_body, + ...circuitInputsRelevant + } = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + const witness = await circuit.calculateWitness(circuitInputsRelevant); + await circuit.checkConstraints(witness); + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + const timestamp = BigInt(1696965932); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + const maskedSubject = "Send 1 ETH to "; + const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); + const maskedSubjectFields = + relayerUtils.bytes2Fields(paddedMaskedSubject); + for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { + expect(BigInt(maskedSubjectFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + const fromAddr = "suegamisora@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedSubjectFields.length] + ); + expect(BigInt(0)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedSubjectFields.length + 1 + ] + ); + }); + + it("Verify a sent email whose from field has a non-English name", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_legacy_test4.eml" + ); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + console.log(parsedEmail.canonicalizedHeader); + const accountCode = await relayerUtils.genAccountCode(); + const { + body_hash_idx, + precomputed_sha, + padded_body, + padded_body_len, + command_idx, + padded_cleaned_body, + ...circuitInputsRelevant + } = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + const witness = await circuit.calculateWitness(circuitInputsRelevant); + await circuit.checkConstraints(witness); + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + const timestamp = BigInt(1696967028); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + const maskedSubject = "Send 1 ETH to "; + const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); + const maskedSubjectFields = + relayerUtils.bytes2Fields(paddedMaskedSubject); + for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { + expect(BigInt(maskedSubjectFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + const fromAddr = "suegamisora@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedSubjectFields.length] + ); + expect(BigInt(0)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedSubjectFields.length + 1 + ] + ); + }); + + it("Verify a sent email whose subject has an email address and an invitation code", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_legacy_test5.eml" + ); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + console.log(parsedEmail.canonicalizedHeader); + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + const { + body_hash_idx, + precomputed_sha, + padded_body, + padded_body_len, + command_idx, + padded_cleaned_body, + ...circuitInputsRelevant + } = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + const witness = await circuit.calculateWitness(circuitInputsRelevant); + await circuit.checkConstraints(witness); + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + const timestamp = BigInt(1707866192); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + const maskedSubject = "Send 0.12 ETH to "; + const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); + const maskedSubjectFields = + relayerUtils.bytes2Fields(paddedMaskedSubject); + for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { + expect(BigInt(maskedSubjectFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + const fromAddr = "suegamisora@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedSubjectFields.length] + ); + expect(BigInt(1)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedSubjectFields.length + 1 + ] + ); + }); + + it("Verify a sent email whose subject has an invitation code and another hex string", async () => { + const emailFilePath = path.join( + __dirname, + "./emails/email_auth_legacy_test6.eml" + ); + const emailRaw = readFileSync(emailFilePath, "utf8"); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + const { + body_hash_idx, + precomputed_sha, + padded_body, + padded_body_len, + command_idx, + padded_cleaned_body, + ...circuitInputsRelevant + } = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + const witness = await circuit.calculateWitness(circuitInputsRelevant); + await circuit.checkConstraints(witness); + const domainName = "gmail.com"; + const paddedDomain = relayerUtils.padString(domainName, 255); + const domainFields = relayerUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + const expectedPubKeyHash = relayerUtils.publicKeyHash( + parsedEmail.publicKey + ); + expect(BigInt(expectedPubKeyHash)).toEqual( + witness[1 + domainFields.length] + ); + const expectedEmailNullifier = relayerUtils.emailNullifier( + parsedEmail.signature + ); + expect(BigInt(expectedEmailNullifier)).toEqual( + witness[1 + domainFields.length + 1] + ); + const timestamp = BigInt(1711992080); + expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); + const maskedSubject = + "Re: Accept guardian request for 0x04884491560f38342C56E26BDD0fEAbb68E2d2FC"; + const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); + const maskedSubjectFields = + relayerUtils.bytes2Fields(paddedMaskedSubject); + for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { + expect(BigInt(maskedSubjectFields[idx])).toEqual( + witness[1 + domainFields.length + 3 + idx] + ); + } + const fromAddr = "suegamisora@gmail.com"; + const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); + expect(BigInt(accountSalt)).toEqual( + witness[1 + domainFields.length + 3 + maskedSubjectFields.length] + ); + expect(BigInt(1)).toEqual( + witness[ + 1 + domainFields.length + 3 + maskedSubjectFields.length + 1 + ] + ); + }); + + it("Verify a sent email with a too large from_addr_idx", async () => { + const emailFilePath = path.join(__dirname, "./emails/email_auth_legacy_test1.eml"); + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + const circuitInputs = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + circuitInputs.from_addr_idx = 1024; + async function failFn() { + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + } + await expect(failFn).rejects.toThrow(); + }); + + it("Verify a sent email with a too large domain_idx", async () => { + const emailFilePath = path.join(__dirname, "./emails/email_auth_legacy_test1.eml"); + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + const circuitInputs = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + circuitInputs.domain_idx = 256; + async function failFn() { + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + } + await expect(failFn).rejects.toThrow(); + }); + + it("Verify a sent email with a too large subject_idx", async () => { + const emailFilePath = path.join(__dirname, "./emails/email_auth_legacy_test1.eml"); + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + const circuitInputs = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + circuitInputs.subject_idx = 1024; + async function failFn() { + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + } + await expect(failFn).rejects.toThrow(); + }); + + it("Verify a sent email with a too large timestamp_idx", async () => { + const emailFilePath = path.join(__dirname, "./emails/email_auth_legacy_test1.eml"); + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + const circuitInputs = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + circuitInputs.timestamp_idx = 1024; + async function failFn() { + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + } + await expect(failFn).rejects.toThrow(); + }); + + it("Verify a sent email with a too large code_idx", async () => { + const emailFilePath = path.join(__dirname, "./emails/email_auth_legacy_test1.eml"); + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + const circuitInputs = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + circuitInputs.code_idx = 1024; + async function failFn() { + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + } + await expect(failFn).rejects.toThrow(); + }); + + it("Verify a sent email with a too large code_idx 2", async () => { + const emailFilePath = path.join(__dirname, "./emails/email_auth_legacy_test1.eml"); + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + const circuitInputs = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + circuitInputs.code_idx = 1024 * 4; + async function failFn() { + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + } + await expect(failFn).rejects.toThrow(); + }); + + it("Verify a sent email whose subject tries to forge the From field", async () => { + const emailFilePath = path.join(__dirname, "./emails/email_auth_legacy_invalid_test1.eml"); + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + const circuitInputs = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + circuitInputs.from_addr_idx = circuitInputs.subject_idx; + async function failFn() { + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + } + await expect(failFn).rejects.toThrow(); + }); + + it("Verify a sent email with non-utf8 character", async () => { + const emailFilePath = path.join(__dirname, "./emails/email_auth_legacy_invalid_test2.eml"); + const accountCode = + "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + const circuitInputs = await genEmailCircuitInput(emailFilePath, accountCode, { + maxHeaderLength: 1024, + ignoreBodyHashCheck: true, + }); + async function failFn() { + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + } + await expect(failFn).rejects.toThrow(); + }); +}); diff --git a/packages/circuits/tests/emails/email_auth_invalid_test1.eml b/packages/circuits/tests/emails/email_auth_invalid_test1.eml new file mode 100644 index 00000000..3995ef6d --- /dev/null +++ b/packages/circuits/tests/emails/email_auth_invalid_test1.eml @@ -0,0 +1,98 @@ +Delivered-To: suegamisora@gmail.com +Received: by 2002:a05:7010:2284:b0:415:a8ba:b98c with SMTP id r4csp1040892mdg; + Fri, 25 Oct 2024 07:41:04 -0700 (PDT) +X-Received: by 2002:a17:902:e544:b0:20c:9d8d:1f65 with SMTP id d9443c01a7336-20fb994d810mr79073695ad.30.1729867263878; + Fri, 25 Oct 2024 07:41:03 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1729867263; cv=none; + d=google.com; s=arc-20240605; + b=b0Q+9VzThRKQBbRpT7G2X+gDYkjP4vahZQIixEMdVnxWwGAVh3MDAtAZScI7QoX3fZ + wZz3nlpP3F97+7AODdQushhfdgGFdFbcFj1wFHtT04UtJ1VFh5+q/FU1iPMV5ZgMU1dd + mJZi/tQY4KqZxFdtVDoRhfWd2Q/u8AClJOtb1DKS27AJiLOZABhAW6VH0g6mEq2ZVHq5 + A3RS/m6wIGZ7Zb6Xb2WeBB8zDGrtfd8+Iv66zGluLWsLiXgGfkm/Yyt7JYRYxZTgq66I + KwBGsNCq+9cCIlYftmEuh7jD5G6JqgE8zexVqPGO9iLmhARxIvjlDWaQgvuE2MLjVRcv + s2yg== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; + h=subject:to:from:mime-version:date:message-id:dkim-signature; + bh=PsLz804XfOcayfPHe0x6Z87/QdwLeZaJ8Aj7CjrmavU=; + fh=r9ZW45D/4i7BIl/4UeFGrkYKwbplztqhOVKfbV+WD3I=; + b=V6CR8wcQVdOM9ceeY6DcVnqRKwxprp72sHSgeth+GC3oB6JThZqA6xdiGzja4RRdXg + LnAzvyEfKMYNsd9D1uDbxwnmk0Q7tNYcr8bdZ0IbXGvYeytxF0NkM5g3GtgZQBubazpw + hxH2hcn5ctoySQhMaUNpbdKnbeiYFaRSYt/re2ouwyWkVN+HUI2oyl+eveYOiCJcA3sj + CZHxlqT1ZwJ/k//QkaR+7WfRzMdjX0yHBK7GoI3aVUGyjNMAkJQwV3p1u0t6PjDvLAFt + rKH/wx10/V1YJDfw2UNmG2HmRAf6wCahN1rvAV1ZHdTII6DUV+iGA2Lx8JyI4ZEKzgc5 + SU2A==; + dara=google.com +ARC-Authentication-Results: i=1; mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=HBr27x2l; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com +Return-Path: +Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) + by mx.google.com with SMTPS id d9443c01a7336-210bbfaa9aesor9989655ad.11.2024.10.25.07.41.03 + for + (Google Transport Security); + Fri, 25 Oct 2024 07:41:03 -0700 (PDT) +Received-SPF: pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; +Authentication-Results: mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=HBr27x2l; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1729867263; x=1730472063; dara=google.com; + h=subject:to:from:mime-version:date:message-id:from:to:cc:subject + :date:message-id:reply-to; + bh=PsLz804XfOcayfPHe0x6Z87/QdwLeZaJ8Aj7CjrmavU=; + b=HBr27x2lZpi95mQM2o50nym8vqklTpXkE9xwxYw85iJqLYn+gcA8dHPqSf9ylGppuP + nkhjLZ0zs0+AwJcylx+DWjN5O2SfCuG/fQjvVF3Ag7bVW/zNTDHR9yvwRi0g+93umVo2 + 4rZjVfLCK9xQFpXcQh6vmNfVMhIgTVLK8jJd6S9FlTUAJ+c7p8YcATUdi7JmWiS+xhhX + YQv353cN9lN5+KwRXQ+fy7HUr8V4dUmnfQbOZfFrfWq+IVWeBr/wd3dvhLX/D/NCS4eT + BYWVd/wxy87UowXzgxkaWEZvQuv3f8W2hy0N/rRIGwAXDYNGtkY2qy9jKShnsaTwtlQk + qXbw== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1729867263; x=1730472063; + h=subject:to:from:mime-version:date:message-id:x-gm-message-state + :from:to:cc:subject:date:message-id:reply-to; + bh=PsLz804XfOcayfPHe0x6Z87/QdwLeZaJ8Aj7CjrmavU=; + b=PuMKz5sQ1iDTUhv9mI+RPC4IqR3/14ODfkScu+Q/TSKVnLo3Y0TqCf+WZZTsq09Zns + bBjmjVL5Rb9yd8wf0i+2JtzkA4bINTjH8flT/UoLa3HveMMH/HaLodRq3HUb5yS/wte9 + TCRdl3062NQIB631iA+M0xVUOsmvvV8jXappu11nHkl0/ZgRb7XPd8qa9PwHb7s/dzE6 + yuDyDmZXpZU6+mxOOf2RDlaCLXPa/UmQAV16MkngRfsCYF0y2nEIfpbZFl9QIbDbYFus + EPKU++6FQSa5QeXvGwI1k6TsSuyeP/fpNUtEVawPRnYlFAkUCvkg7pt/DtATtQ9bN6b8 + ihTQ== +X-Gm-Message-State: AOJu0YxfXANbbAXSeGAgpT+V7QvlqTiQJ2kBKVfNtApuF1IuThgpyA5f + PWDU649n5u/BUfgM2n0VjDSAnzAKoMBsA4k5rdL/Wq8s8txIU+K2A1HV8jyv +X-Google-Smtp-Source: AGHT+IFfMY0A/Nt6e8j11mefQBEn0hU/WB6YvijjE202nDyjVaWFjkR2TagHs4oR8GRebcMq93uWZA== +X-Received: by 2002:a17:902:db08:b0:20c:5cdd:a9e with SMTP id d9443c01a7336-20fb9949e31mr63347775ad.28.1729867263044; + Fri, 25 Oct 2024 07:41:03 -0700 (PDT) +Return-Path: +Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ([93.118.43.168]) + by smtp.gmail.com with ESMTPSA id d9443c01a7336-210bbf6d6e7sm10039395ad.71.2024.10.25.07.41.00 + for + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Fri, 25 Oct 2024 07:41:01 -0700 (PDT) +Message-ID: <671badfd.170a0220.f37ed.3f59@mx.google.com> +Date: Fri, 25 Oct 2024 07:41:01 -0700 (PDT) +Content-Type: multipart/alternative; boundary="===============4967285061131455909==" +MIME-Version: 1.0 +From: "Alice" +To: suegamisora@gmail.com +Subject: Re: [Reply] Test Email Invalid + +--===============4967285061131455909== +Content-Type: text/html; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit + + + + +

Hello!

+

This is a test email with a basic HTML body.

+
Accept guardian request for 0x04884491560f38342C56E26BDD0fEAbb68E2d2FC Code 01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76
+

Thank you!

+ + + +--===============4967285061131455909==-- diff --git a/packages/circuits/tests/emails/email_auth_legacy_invalid_test1.eml b/packages/circuits/tests/emails/email_auth_legacy_invalid_test1.eml new file mode 100644 index 00000000..f24fd2ab --- /dev/null +++ b/packages/circuits/tests/emails/email_auth_legacy_invalid_test1.eml @@ -0,0 +1,87 @@ +Delivered-To: emailwallet.relayer@gmail.com +Received: by 2002:a05:7108:1451:b0:396:8fc9:464d with SMTP id m17csp87769gda; + Thu, 30 May 2024 08:28:23 -0700 (PDT) +X-Received: by 2002:a81:a00a:0:b0:627:e1f9:a139 with SMTP id 00721157ae682-62c6bc794b0mr26546177b3.41.1717082903271; + Thu, 30 May 2024 08:28:23 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1717082903; cv=none; + d=google.com; s=arc-20160816; + b=dcwAI85ZE2D9NASeT5NL1n9e8ZaXu7/GEsqGoeq11pmrZfjnJ0h6NrWC1XSthI6JYw + JRBlN+qW6Ujfw/aXxigYADISdeomqFiSDx8kBUQ80B2jR1g69wtUMnfYVgu2NjNsZiUW + gYk8qmReh3LSDEVV3s9UJ72s41yZ9Mx7nFzrHZTxbEvhowUXoh1thvSqmLR+vk7LJCX5 + qi8qrp1kdgw7nu8I7FpouTWFv+3qLSkt+NbfZxeLG2FUBuGY9GRPQX4SJVxCDYDNInEa + M2gQTOcM2LW6Y2Cb/2NRpj0MNoTSbYFQLz+zx0AWmRwo9heldsKSqHU6dAQsmgajr3oI + FgVw== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; + h=to:subject:message-id:date:from:mime-version:dkim-signature; + bh=pEJNaPbPBaXriQY87YlrxS7+Fs6WjCMJNhasTebOP90=; + fh=AKWw92sdXoMEDdHXKLL06vnizTpObKPGCfYXnoQDKO8=; + b=PquMn5DnN9Nr6t0wpyxBLZVp3oppCiH8LKq+Qi0Lgwewn15dzHH0UD9zOWozkjj7CP + 6oR9ft8Rv0GwrxFsNclAChpdZD4UUhhDIooITW3a9xfIlvVltCgENjdufd56dKTr+HkU + MiewdA2ntTNZEdtevwQgqURmNMG5+eietgUU+tl9ZdeE8UFoAr2rJmMq53+LvJgDdq4p + Ez80Hk50Kh1u2IxxQIwIqtMEhxCErlAXU8a+NNehyYMy/GhgNSqi5bOJWzQlKm/QKHlp + fFypOmhFDj7XfmVuY2Tsbw8Z/32FQvB4GUpKJ0+8ZjalcwiKpSxqL5EcOq/85/VwmbN0 + XFhQ==; + dara=google.com +ARC-Authentication-Results: i=1; mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=koGCsCmM; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com +Return-Path: +Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) + by mx.google.com with SMTPS id 00721157ae682-62a0a4a3aabsor81652417b3.18.2024.05.30.08.28.23 + for + (Google Transport Security); + Thu, 30 May 2024 08:28:23 -0700 (PDT) +Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; +Authentication-Results: mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=koGCsCmM; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1717082903; x=1717687703; dara=google.com; + h=to:subject:message-id:date:from:mime-version:from:to:cc:subject + :date:message-id:reply-to; + bh=pEJNaPbPBaXriQY87YlrxS7+Fs6WjCMJNhasTebOP90=; + b=koGCsCmMYnZBGgreIEhDd8QrBpdc+31J63pPLv+t+6xSO+7l3OAcgJMvc9fkIqguSR + t9v+a1zj5NtZEP4bfFNPNxLUaI8cB6HdHtcSS0x21JfdTrcoMw7rBN1X+UR7F8oYXi1U + lYiHF73WjEtiUUi6wdqdZ5TIMC0t1XDOhYyp4Sk6QupBHtmIU5Km4iKSEGHx9mrnjArg + 6CZgDyABv7AiF9pxedEVkSE2mgu+KLhJEdfO0PP6/IDh2WfqIXtNVMlje50UoXNpB3u4 + Gu8FTQ1pUsqOV1WIFeczBAwuErLgv48wmk1qOGhaQ5qW750ZdjdHPhh+HCqglUl6b552 + 3SDA== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1717082903; x=1717687703; + h=to:subject:message-id:date:from:mime-version:x-gm-message-state + :from:to:cc:subject:date:message-id:reply-to; + bh=pEJNaPbPBaXriQY87YlrxS7+Fs6WjCMJNhasTebOP90=; + b=bkZ3OMtPij0y8UDTJ6ywmP28P0mVt6ekOi4/w1rsfSpNF6XuaYJ+c3rvZVH/BvKKdD + eya1l6uajewpQfXkScHg4cYP61eXy2GTA1VAabnLfIiF+MDf//5l7aVEZw6SNsOCxfSs + Pptad4VrIqrIoVeHlJBBhBxGMjOmfuACTp3+nxvFs1m3MXWHZ9XF5jWQqKnPdGVI4Ukm + J9g3c84qSWx2X7Uf0afkxp95pLgmCGzLsNBCoCh6CKY7dngRCi5fJvAgLkCImZ3cUh0H + 2Zu9avrEwuwN7m7PvnfjB1B2DIHjyQSpIysw16r+gTFoOSU+WpJS/QtGdQ2TFPtl6Vp9 + ghRQ== +X-Gm-Message-State: AOJu0YxcUEs34CaehyGVUHkgKPfOIHW337G2F1GjAwlMEZTkvrdj2lMs + GVh0L9+vmgOAPOV+4HXw9KWUYTtpKsWyQzyWZN95yenGOl8F6a7jwV1X31qoX63EeACiFbBK/MH + jRbRdHQjFr4QtxZ/2YswNS6iGnVJ7v9yn +X-Google-Smtp-Source: AGHT+IH/Asa2+dzrdeRD0Y7sDKAbVp72XvgAlnZUxBxSDzr0V/2T8wGd+OWlB/9z8yKP/1UGUw/u95PtmBGcKnN5Zuw= +X-Received: by 2002:a0d:c6c1:0:b0:627:c0ab:22b9 with SMTP id + 00721157ae682-62c6bc00b87mr22083187b3.21.1717082902547; Thu, 30 May 2024 + 08:28:22 -0700 (PDT) +MIME-Version: 1.0 +From: Sora Suegami +Date: Fri, 31 May 2024 00:28:11 +0900 +Message-ID: +Subject: from:adversary@test.com +To: emailwallet.relayer@gmail.com +Content-Type: multipart/alternative; boundary="00000000000074d38f0619ad844a" + +--00000000000074d38f0619ad844a +Content-Type: text/plain; charset="UTF-8" + + + +--00000000000074d38f0619ad844a +Content-Type: text/html; charset="UTF-8" + +

+ +--00000000000074d38f0619ad844a-- diff --git a/packages/circuits/tests/emails/email_auth_legacy_invalid_test2.eml b/packages/circuits/tests/emails/email_auth_legacy_invalid_test2.eml new file mode 100644 index 00000000..3f316ea5 --- /dev/null +++ b/packages/circuits/tests/emails/email_auth_legacy_invalid_test2.eml @@ -0,0 +1,83 @@ +Delivered-To: suegamisora@gmail.com +Received: by 2002:a05:7010:4851:b0:403:8332:eb9c with SMTP id n17csp1004219mdi; + Thu, 10 Oct 2024 03:16:51 -0700 (PDT) +X-Received: by 2002:a17:902:f68e:b0:20c:895d:b41c with SMTP id d9443c01a7336-20c895db9d6mr26370195ad.41.1728555411499; + Thu, 10 Oct 2024 03:16:51 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1728555411; cv=none; + d=google.com; s=arc-20240605; + b=hLgWHORB2bUPXlG14L9i9qF3wy47/ajz04L/WYqj+kAE+x6t3wrgsUZPuc0aat2a68 + 5JEqWDq6g2oOKLfRyFDH+Gw7Atd5rCFyCQvix5wit3ZGKT4PMOrV4f9c2bzvTtUDMY1T + f4XRkhPXYvfumin715HcZmMM0ZKgv1lDw0DKnYphs3NQ962lsrrCxkHfXpBr5vfxOd5S + 9ERilliltCUVoX4TjuNmS7qR6DNa2jYEw9Gs8btimxAhhGAVhYY+tVF52RhSayTyOMRq + mNr8UOp6lzjQqdWLN8ecYOC3a7iENdveG4w2pLm2Fa9D/gUKqaV40U0yUhyHo6sW9a1l + FAqQ== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; + h=subject:to:from:date:message-id:dkim-signature; + bh=1iODMfYbGB0YsW+qkb/ylPSIB70wXGEkVgYLXH26p6U=; + fh=r9ZW45D/4i7BIl/4UeFGrkYKwbplztqhOVKfbV+WD3I=; + b=QcTr34vpV3TVGeCKL2CMxN/SmPJnoTBKdK9I6dqB8rVxUGQ6w1XqfZxSyDQKxC+DI4 + JwvPxLQEZcqEGPjr4RJPeUd3DamebbS2TyHi7gFms5DQib1rafdj76//1ObTiMtTPlpI + mtWYWajMVSs++FpLQXp1XMqNYRbvkccpqk0j4wj5iwYuyvobH97Yv2nRvid8cdX039Wq + 4MNJB9FsUGwqUDPIoyPGguEX5S5RKTYooIp38G8lsXoOxdtw0DJR5ZL/Gs0e8S7StFUf + /i3zXB7Pmx2FgCG6uAT1fcysG4pLNKe5E3Y3MrcTLXEzIn0w3Z3V1fACNkHFF8ay/s/I + 3u0g==; + dara=google.com +ARC-Authentication-Results: i=1; mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=hYAmcOut; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com +Return-Path: +Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) + by mx.google.com with SMTPS id d9443c01a7336-20c8c3780f3sor6195485ad.19.2024.10.10.03.16.51 + for + (Google Transport Security); + Thu, 10 Oct 2024 03:16:51 -0700 (PDT) +Received-SPF: pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; +Authentication-Results: mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=hYAmcOut; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1728555410; x=1729160210; dara=google.com; + h=subject:to:from:date:message-id:from:to:cc:subject:date:message-id + :reply-to; + bh=1iODMfYbGB0YsW+qkb/ylPSIB70wXGEkVgYLXH26p6U=; + b=hYAmcOutmZTFYcK/LSFg4MXKbRiPdUMjGpy0/Z5JgXyE/WrCYNxlkeuJC6HjYdZ2wM + 3EO36M95rNNI15wR7+XhoLSSp/x3db7N9Yk/TpMUKPTzds+UgO/vOjrdk9gvgo/hCMgx + geoqNZuzMhOfS9VlXQcvarOmzcnQumD/mqw7YOH7dEe/0nN8mud6nRPFDPqn9jHmgfwk + MlllMXRwlkzcQsKy74Ew/PNrnz2aRTcmjVwwXGybvKhHHgPUIBrLVylxQ7IkzP8wQfBW + ZfE9RBjcWhwXka2kLWIhqMVNE5G+ZGILRz0pBGyTXww3LXpKt7W2Qt8XpWaeuwu8VtCV + HjJA== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1728555410; x=1729160210; + h=subject:to:from:date:message-id:x-gm-message-state:from:to:cc + :subject:date:message-id:reply-to; + bh=1iODMfYbGB0YsW+qkb/ylPSIB70wXGEkVgYLXH26p6U=; + b=g3Fzh/Ujw9r2o0ockPKVQH7xXsPpqynm3KCPqMd5c3UtltnrPZCQ73gK2Gwjs+Ye7Y + PtlydjhjN6Cn0oInxeMvjBjmpGWdtBZ58ih+rXgcRp4CXajgdeqts2dFVcNTixk7Sojr + 4AJAd+EKQuDWFA8yA8HtRTG5angQ8uqUc3N0RRiLjdDrnznyfIFn5DP1h9PIdQUu0S7O + XFix+AuDGVSYnTgBHCsJ9DfHTEFQvLTwSIyFwLNXfOSoEYIQR0xg2ElSCAAa+c5vSzUl + bi5C1AG/1QD5BtVCQZXfeuq809uFsx4+pXwrynUgKgSo/BnV+MYMETwfJc7dFn/JGir6 + gBJg== +X-Gm-Message-State: AOJu0YzM0nASH0Qcd3Cp9W1A6jhYvFQZXh8E+Yl0wqw6ntS+PZ/kS9CT + R12Ps/acoprRoJ66pLPvIHXAyV6LyjBC9MD1FuK5O2T6Gj0VypE7XyS9RS4upSY= +X-Google-Smtp-Source: AGHT+IGR5twbXPQxXP91KzL6kIQv0YfEoH0Ry8NPblXLHL/gSi2nPIej4sSgmWI2mDlMqB96oMsgIw== +X-Received: by 2002:a17:902:d508:b0:20b:983c:f0a0 with SMTP id d9443c01a7336-20c6374311dmr89284895ad.31.1728555410624; + Thu, 10 Oct 2024 03:16:50 -0700 (PDT) +Return-Path: +Received: from mail-255.txt ([240d:1e:4e1:3300:b452:6d47:1e35:4cb]) + by smtp.gmail.com with ESMTPSA id d9443c01a7336-20c8c0e7769sm6924285ad.142.2024.10.10.03.16.49 + for + (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); + Thu, 10 Oct 2024 03:16:50 -0700 (PDT) +Message-ID: <6707a992.170a0220.14cddc.18e9@mx.google.com> +Date: Thu, 10 Oct 2024 03:16:50 -0700 (PDT) +from: emaiwallet.alice@gmail.com +To: suegamisora@gmail.com +Subject: This �s a test + + +ZK email? + diff --git a/packages/circuits/tests/emails/email_auth_legacy_test1.eml b/packages/circuits/tests/emails/email_auth_legacy_test1.eml new file mode 100644 index 00000000..f5c20406 --- /dev/null +++ b/packages/circuits/tests/emails/email_auth_legacy_test1.eml @@ -0,0 +1,85 @@ +Delivered-To: emailwallet.relayer@gmail.com +Received: by 2002:a05:7108:47b1:b0:342:22f4:d6db with SMTP id bz49csp1557082gdb; + Sun, 17 Sep 2023 15:30:13 -0700 (PDT) +X-Received: by 2002:a0d:e2d1:0:b0:595:59f:28d6 with SMTP id l200-20020a0de2d1000000b00595059f28d6mr8532154ywe.21.1694989813070; + Sun, 17 Sep 2023 15:30:13 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1694989813; cv=none; + d=google.com; s=arc-20160816; + b=WFAEAsVx9Z9pEmIAtOzTiZ/g+izqJNYn7WGrA7qPR+10JDAnfMjPEGVJFxqQ3/nc+l + fgIj520PStLh30yieeiJyZHTCiMUQWs1yBo/5u/MeEAcG1z3s6gpXjL8wPpYuMCPclFa + TvpC2dAcs1aVv8AvJHlgMkqc9MvRQWqoJVJevp9T4FOUfszaRKHnsNJHvhuJAl38xROp + P0oIx9vGnbNmVEHcTz4OBWwSoN56JwOK7NAc0o823B8lt1i+shw67HY8XM3nvIp6ftwx + dUyFQuxP9VEH4hwIu02C1L4yDJNgTshxn1IC83cHXIm8pcsZxfv2Vg0swrD0IK3tRsUx + tdTQ== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; + h=to:subject:message-id:date:from:mime-version:dkim-signature; + bh=BWETwQ9JDReS4GyR2v2TTR8Bpzj9ayumsWQJ3q7vehs=; + fh=AKWw92sdXoMEDdHXKLL06vnizTpObKPGCfYXnoQDKO8=; + b=e8eKiZWs5PsaB+Q2CCneEWl05AAzrCu4f2pzRbD0JUiF4dQeWWlorGXS70lPNRIuhU + ENk6ellkuIvA+uhsHgC/An+asGeAyC80h3xX94cvmXaeGCO3SnGzZ2VgATJOgYd+ScYY + G4xYrrUEQlsblFtCcG7povcW8Kwkmda7crkoNuj3sqdhQDgzGzI2l66GEUuYMlWXTrlY + /egEyxTvMy7nUjakk2n6VVCR5S4kLC1Fna3v6RLvWuC3sIXzAD93m0AgqBveopmyDZ+9 + eNKvAouT4znpujbD+FDydF6iC3r1GfZtjYJPBe6VfQOEwKCaoSHXSfinmh2Pm4gLtg3D + 4P0A== +ARC-Authentication-Results: i=1; mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=RHBgQbCx; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com +Return-Path: +Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) + by mx.google.com with SMTPS id m12-20020a0dca0c000000b0058460bc906bsor2973516ywd.11.2023.09.17.15.30.12 + for + (Google Transport Security); + Sun, 17 Sep 2023 15:30:13 -0700 (PDT) +Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; +Authentication-Results: mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=RHBgQbCx; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1694989812; x=1695594612; dara=google.com; + h=to:subject:message-id:date:from:mime-version:from:to:cc:subject + :date:message-id:reply-to; + bh=BWETwQ9JDReS4GyR2v2TTR8Bpzj9ayumsWQJ3q7vehs=; + b=RHBgQbCxhob0RHu/S1J4YdDG2aP1fRDJR6tQrN0wyfVHesARR9NhQIJ/lyUehRTLu/ + wfbHY5RGwSv/87X2iX/p94rGXKJ7R9QFWuuHi0owVNLw2cDNL7vNpT71IgujrHGBTQlB + gvGFd+Gp7/X7jY5DBte4MCi+syCGrf/v+qFsTQ/XUEKpsUu7beMEjTz879yZtdr7LVAE + 9bcsAe18sfX2li2ubRqdV/EPg6sWXIo19jtRTEZ2q1B1i6jxWmaUB+/Th+F8VUXHcJ2a + GluecEG4pSAeP/a64bbpkmOxdMx4bb5A4jyWr1q+TyeqfHXxOkHf8c7+gMHhzGp/tJiu + d12g== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1694989812; x=1695594612; + h=to:subject:message-id:date:from:mime-version:x-gm-message-state + :from:to:cc:subject:date:message-id:reply-to; + bh=BWETwQ9JDReS4GyR2v2TTR8Bpzj9ayumsWQJ3q7vehs=; + b=AFkTp60CFyHReF9haHoUVGsSO0+uQZWNhP/SdjYaR1hKqd7FDcv9QMWyo7Ruo2q668 + AtM04vsAxL3KPbCh8l7ghxonJlfpIdwnJFFwiIkAaymLN2nfa/iA3yTqLPsZc21+DKWI + 4L161IUCshKj2K2/ErZr/cslf7g9X4vA5z6vaQhUJgB1JL4dlx5eWwgldtAaL/5jSQAg + gThwEVUU6QqljCd1eVCyG5CcQGfJc6BuHNr3beq+4WMlvll97o5n3cpa+QFJJejXGoRn + n0QiaK8Xki3ajWSdhu+K2y+Y4Cd9KBp4utQhZ4Ed74b0o4JMmdU+UOqcxvQs3mRrqGTn + YsQA== +X-Gm-Message-State: AOJu0Yy/ikSKXhxWeOjidkPu0ZD7ioRrSKLdlg8Ngfo45pZ1AlVfsXzW + oHfddvOgIXyqeA8uYaGcdfJtfrWelHBChkfXWe8TvYbSGTp2mw== +X-Google-Smtp-Source: AGHT+IFwSk4ZOp7bjwU0GeSyGMnjOk59tjDeY5XcQ79bFaW3jx2uDJC6n1WvtgsSMCTZrtUKAJbs8eUMJCXS0G8mfPQ= +X-Received: by 2002:a81:9108:0:b0:583:f78c:994e with SMTP id + i8-20020a819108000000b00583f78c994emr7327928ywg.42.1694989812400; Sun, 17 Sep + 2023 15:30:12 -0700 (PDT) +MIME-Version: 1.0 +From: Sora Suegami +Date: Mon, 18 Sep 2023 07:29:59 +0900 +Message-ID: +Subject: Send 0.1 ETH to alice@gmail.com +To: emailwallet.relayer@gmail.com +Content-Type: multipart/alternative; boundary="000000000000aa87aa060595912c" + +--000000000000aa87aa060595912c +Content-Type: text/plain; charset="UTF-8" + + + +--000000000000aa87aa060595912c +Content-Type: text/html; charset="UTF-8" + +

+ +--000000000000aa87aa060595912c-- diff --git a/packages/circuits/tests/emails/email_auth_legacy_test2.eml b/packages/circuits/tests/emails/email_auth_legacy_test2.eml new file mode 100644 index 00000000..53af1ef5 --- /dev/null +++ b/packages/circuits/tests/emails/email_auth_legacy_test2.eml @@ -0,0 +1,85 @@ +Delivered-To: emailwallet.relayer@gmail.com +Received: by 2002:a05:7108:2c4:b0:342:22f4:d6db with SMTP id i4csp2966gds; + Tue, 10 Oct 2023 11:58:16 -0700 (PDT) +X-Received: by 2002:a81:4a55:0:b0:599:8bd:5bdf with SMTP id x82-20020a814a55000000b0059908bd5bdfmr21750490ywa.50.1696964296192; + Tue, 10 Oct 2023 11:58:16 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1696964296; cv=none; + d=google.com; s=arc-20160816; + b=a9xg8fw3SXXh572oqDh838o0dBzsmtImJhloG43idR4VIr3bD4bEg6yHiVQz/gCVHB + JWSqBwHpS0ejzoa4Z27guBfS062lETo+O297nNn/KXBFJ+E0RMj65rvQTgmLI703M7sp + uImKsxcVLIdfjERz8GBr0eRrg65WX1dvg39SzDcCtDYaHrV0yrs65B7H9DDdo8IknkF+ + S5j0tBvM15ZHa9U+tn/0pUT5MwAv3DREZP+dyKfZxh0/9z2jycOOi5NSyUXRbTtXppdj + PuaycQ+TMdAmOTdIMiLog1W8QOzrzv1uanDloMFu4ykOZ8q8MdDd1kk1fIDp4YbF4+KE + NwVQ== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; + h=to:subject:message-id:date:from:mime-version:dkim-signature; + bh=2mqY3PZCoz8InXGWf2u3R74gNz152fRD9sTUPAxlKYk=; + fh=AKWw92sdXoMEDdHXKLL06vnizTpObKPGCfYXnoQDKO8=; + b=wUxZO1jAnI6WgyweT+69bF7FzkKLyGZRvzQCNOaxKUnS+DQzLe51E19G5qYQNemciH + f5yU0dUPFZa3gJuf/CmImd6VlEojBNPfk0bY1VpCH61a8OfuXi8XbMeF82GoMHi2Id70 + QR4QcUsUUbBV2R3Prw3Jy1tI9F0KWG5iyztI6DvWJX546cMvgYZn2l9ah+mlsreB8gaL + kbhCQ3/vL8K2CDT0Cw3d8+dMzLxMgwpuNE1cF5Wff6vsrgbuYgsyB9qQEF5wRVgEQVxK + 0ewpCgRzR01nW6/no/aDZ3BhVd9UW5C9CX7+y8+RZ3vRkWwowaH5+juqESG/A9U/HP2p + hb6Q== +ARC-Authentication-Results: i=1; mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=ZtY1tM0G; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com +Return-Path: +Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) + by mx.google.com with SMTPS id r194-20020a0de8cb000000b005704eb70d02sor6290629ywe.11.2023.10.10.11.58.16 + for + (Google Transport Security); + Tue, 10 Oct 2023 11:58:16 -0700 (PDT) +Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; +Authentication-Results: mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=ZtY1tM0G; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1696964295; x=1697569095; dara=google.com; + h=to:subject:message-id:date:from:mime-version:from:to:cc:subject + :date:message-id:reply-to; + bh=2mqY3PZCoz8InXGWf2u3R74gNz152fRD9sTUPAxlKYk=; + b=ZtY1tM0Gaga0hoo7frGS439zDz3JKhYiDIag5WFs4cE0JBIQxOP5CPOpMhIP7mkkh8 + BT3+uoAIYAj6ewIFGtoE4iW+tEo8m+uusFn0+u+BiMUxrifgSUpm6L+7jmlRDGTELbiI + x0JrI+dqFN4qeDYbVrFpko2bh4EdBDFBZjHW/KM8dFR+FDyVcNWeNqdeD/0ht13SwULG + RsUboFNx3zVy4aCt0oi8kIc1c9XAYcM/lvM/pXkJVE4hPwErAwk5CZy25Uu6NN95eum4 + aaOI8h5MJ2aDR9a1jipuDcNJM/pLU0oyIPU9juP6otGCMotHqzJbJ0VQZm1pZAg++0Wy + X3cQ== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1696964295; x=1697569095; + h=to:subject:message-id:date:from:mime-version:x-gm-message-state + :from:to:cc:subject:date:message-id:reply-to; + bh=2mqY3PZCoz8InXGWf2u3R74gNz152fRD9sTUPAxlKYk=; + b=A9W23+Q7/4uDNevuWqpa7eRZlalXwzFjF2AZmRoa7XdFmJAN8puVKgJJgFAN9GxFG0 + TkGYTP5ZjSnAIkrjnnR1SpFgXnO02t6H+mJha8TK6d/QwSx3MO//ACD9H0Sy+fnygLly + +79YG4X8M51xVC7rzf3M8mfubRAMCIgx3H6bdv50KTugO0K7kAwaVfH7IelJziR6kDAf + /L43Mu2QQHNJSqE3uT5LJ5P8tVBP8U28adAPvVMB2UqNjAml8Jx8K/lIVL9yNS1HodjR + xx4CBDybd4ojU5Rsmyak489TFOq+7ibJRRqQoNDfZeulVjHnZC8nsJTJaMA1leEdBy8b + 7ReA== +X-Gm-Message-State: AOJu0Yx6Y8WGZ6/NuwJ93pEaku/8m84Fmu2At47SDfTmL91QgE7EwYp6 + PBXEK923tWejtcRNtvppo7NGaLlg/rRoIvkx0yMqdMC2 +X-Google-Smtp-Source: AGHT+IFTvu5B4yrT+n5M7sJsvjMOv8jW49fPuUZ9TW24SK9KQjLHUbZivpC/9kYnwwKhGAIlbfFezDxoOdgtxiVT4Sg= +X-Received: by 2002:a81:ac42:0:b0:5a7:acae:3bb0 with SMTP id + z2-20020a81ac42000000b005a7acae3bb0mr4278669ywj.5.1696964295610; Tue, 10 Oct + 2023 11:58:15 -0700 (PDT) +MIME-Version: 1.0 +From: Sora Suegami +Date: Wed, 11 Oct 2023 03:58:04 +0900 +Message-ID: +Subject: Swap 1 ETH to DAI +To: emailwallet.relayer@gmail.com +Content-Type: multipart/alternative; boundary="0000000000000958390607614a21" + +--0000000000000958390607614a21 +Content-Type: text/plain; charset="UTF-8" + + + +--0000000000000958390607614a21 +Content-Type: text/html; charset="UTF-8" + +

+ +--0000000000000958390607614a21-- diff --git a/packages/circuits/tests/emails/email_auth_legacy_test3.eml b/packages/circuits/tests/emails/email_auth_legacy_test3.eml new file mode 100644 index 00000000..b56bee8b --- /dev/null +++ b/packages/circuits/tests/emails/email_auth_legacy_test3.eml @@ -0,0 +1,85 @@ +Delivered-To: emailwallet.relayer@gmail.com +Received: by 2002:a05:7108:2c4:b0:342:22f4:d6db with SMTP id i4csp17038gds; + Tue, 10 Oct 2023 12:25:33 -0700 (PDT) +X-Received: by 2002:a81:47c4:0:b0:5a0:ae01:803c with SMTP id u187-20020a8147c4000000b005a0ae01803cmr19454050ywa.38.1696965932748; + Tue, 10 Oct 2023 12:25:32 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1696965932; cv=none; + d=google.com; s=arc-20160816; + b=Fsg3KEAwUjggHJzCpAIJuNz8Eq2GPO+sBNTbWQHDKlXgaLZxBWSohcJ7LrXfhUmuDA + Ji+99B0FbLIrjSPTojnSSVFahIf6015uZw7MB88+PhDeWPDHp1RZOAhwurrVDwijUigo + 07Tbc8Q5oFoMKst5d15ZMZQt/HcTunflxv/DdhmSKm1loIISuUc6VesLfqPe9MTaMztP + biSHonNs9AsiAi52llttRYAspoRP0rH/PLZ9KXZ0qqmTleAS1hUOwjbxkFYOtxYGyJpG + p1ouNBXpbzxWPivcoegCABNTCUDYYBZ0saR+MgACkDaULIXt2ett1jzPLsAdZvFJiSKF + Id+w== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; + h=to:subject:message-id:date:from:mime-version:dkim-signature; + bh=cyDN+YYekjfuyO0NSLmF5i598CHm65FOUxCJHB0q+Sw=; + fh=AKWw92sdXoMEDdHXKLL06vnizTpObKPGCfYXnoQDKO8=; + b=o5ksV0Fs6jZsEMgi0Z1SgiYU+tbWG3l2lw3KHVFUMWIToNFHYFmVQkr6rCUki1g2K0 + Bm8TubRMIuUkuyqMB6dWN5Acm/0lVhF0PMsZP8YqY3iNJWWdCWefl4dMFjkeijP4ki1j + BKzBYKr3UQCVeuVlFvaPeI/BpcD+QeCjqu80CGl3JFKyFUeS9Dou1lyLXm7Va20W+1+Y + ze8h3fv0h5DlTXA2oZVvsraXekIWKrxa+h45SYw/NSZ7bIwIM1W7B6hJ2IFDG25C65LX + ExpUkmBPfmps93jH5fWi+YxwRcx+dpCzn1MAodo0Ruyxui0KTYdCMvHBJVe1VUjIejzh + +cWQ== +ARC-Authentication-Results: i=1; mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=cZhRvd7Z; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com +Return-Path: +Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) + by mx.google.com with SMTPS id a20-20020a0dd814000000b005a220219985sor6072943ywe.16.2023.10.10.12.25.32 + for + (Google Transport Security); + Tue, 10 Oct 2023 12:25:32 -0700 (PDT) +Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; +Authentication-Results: mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=cZhRvd7Z; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1696965932; x=1697570732; dara=google.com; + h=to:subject:message-id:date:from:mime-version:from:to:cc:subject + :date:message-id:reply-to; + bh=cyDN+YYekjfuyO0NSLmF5i598CHm65FOUxCJHB0q+Sw=; + b=cZhRvd7Z9zTNAscMPIquUHj6CG/yLgKsvbGL2ikAMHAlGeJbhR4o0u2n4Rr9WN6h8O + G7SJcvUD6enlg/a9/1AU0y73bjVPjMjY2nDGk+8ltokhBfYSeZcVsKA7iMuK+tBoORth + ZFtTEdVlO7Ekly95ara84epofiYCCGTdvED/RshhzZqjhrp1Mbw/wFtHUAujXVkOmvt3 + MB0knG+mamYAjLqH6Bc/g50gbMMsk1yF5VUYWnbhCK6DUGOeNyZmeYYRLm2yFlSAbu8h + PJPz2QbNY+D5CrxWdetq1JizYnJYOOSiRV7nflunEMji9cLW5I6lUqIlKxhQkdWqd+6b + 3tTg== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1696965932; x=1697570732; + h=to:subject:message-id:date:from:mime-version:x-gm-message-state + :from:to:cc:subject:date:message-id:reply-to; + bh=cyDN+YYekjfuyO0NSLmF5i598CHm65FOUxCJHB0q+Sw=; + b=qeLyin8vj0JfK6n5sLb1/otbg/3P9Hf2kwVd8fnyEa/gnFl5db2e/2XvyhGjP2zMpU + sGjPCkXk7wCQozVEO35tBYsOzgah9uT480TUwVtTyuwW0xq4/4ZS1YizXlnRdmBR8SN8 + Ihjdyf5qhwKGv26xmUgGF7MqDbbfqFdwlPPRdYsPie+MWHdNMqu4dp1JW8Xtg3mpjcdN + 3usOCapPcAJCJG89wyaQWBaKbG9PuGCwULXw/BNMd6vYxQklrVOtNL5m9zEQG6DjBZeO + kD6lTBrYK7e6xMgTuqsF7vYIgAe51t1ijmy3r1hb6x7GPx+XId+PrVL1pMmWTFF4EcbW + W21w== +X-Gm-Message-State: AOJu0Yw2zJT1rbv9BoSJAwB4wOrj56soVWWji9646BXOk/k2D2gF+jCM + CRR/OyY9S2uGYRb5k9ED1f+XrRPwUp1R0gSBu2pZL/jP +X-Google-Smtp-Source: AGHT+IGSbOedb5aIuVhx7TayE6QXtIMR+yVf+UDmgKCrssN+p7v5iVhQJ21PrC58e5NK2EQvGB52q4bEypFxNZe+MG0= +X-Received: by 2002:a0d:de85:0:b0:59b:c0a8:2882 with SMTP id + h127-20020a0dde85000000b0059bc0a82882mr19390753ywe.46.1696965932010; Tue, 10 + Oct 2023 12:25:32 -0700 (PDT) +MIME-Version: 1.0 +From: "dummy@gmail.com" +Date: Wed, 11 Oct 2023 04:25:21 +0900 +Message-ID: +Subject: Send 1 ETH to bob@example.com +To: emailwallet.relayer@gmail.com +Content-Type: multipart/alternative; boundary="00000000000092d27c060761abc7" + +--00000000000092d27c060761abc7 +Content-Type: text/plain; charset="UTF-8" + + + +--00000000000092d27c060761abc7 +Content-Type: text/html; charset="UTF-8" + +

+ +--00000000000092d27c060761abc7-- diff --git a/packages/circuits/tests/emails/email_auth_legacy_test4.eml b/packages/circuits/tests/emails/email_auth_legacy_test4.eml new file mode 100644 index 00000000..22076d2c --- /dev/null +++ b/packages/circuits/tests/emails/email_auth_legacy_test4.eml @@ -0,0 +1,85 @@ +Delivered-To: emailwallet.relayer@gmail.com +Received: by 2002:a05:7108:2c4:b0:342:22f4:d6db with SMTP id i4csp25580gds; + Tue, 10 Oct 2023 12:43:48 -0700 (PDT) +X-Received: by 2002:a81:574f:0:b0:5a7:ab51:af5c with SMTP id l76-20020a81574f000000b005a7ab51af5cmr4673683ywb.13.1696967028753; + Tue, 10 Oct 2023 12:43:48 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1696967028; cv=none; + d=google.com; s=arc-20160816; + b=r2caNqB+Tqis40axvQ+9WATqElkSRMoLieRYBHHeoHlF3b5cTf4S5iBEzrihGSExv3 + hTEtPaFCXEplKGQn8+XVgqjAct61mkAYzHxflnaC1pgkd1CYbkt4zyNJEIW7qb+AIMSL + 1DdnLEuU9sb2oZNfbHyXMQaqXe6sEW6sZQDp6BZJHV0YsOAFhlRiacomh65Oq/DfY1P2 + Dvy9wahx+Qki20kIAfzR/TKuAx5z9IUwaOshdQuWH8i6HFjC8MRO0RwGVUb5ZMkRZFu7 + c4Sx/r9SfTiI4zsos0PvnaOvdNBXg2SPDMNYp0c/sFbngRVHuNK5WPE86v3vHnMi8Gmy + pmkQ== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; + h=to:subject:message-id:date:from:mime-version:dkim-signature; + bh=dH2d6q5VcS+7rfJUaWYK0fSFe6OjBSMp9T98v8goAXc=; + fh=AKWw92sdXoMEDdHXKLL06vnizTpObKPGCfYXnoQDKO8=; + b=C3ka6pwtIk5/XPtFgf/FbwOaJx7hdOxBOXAmkHKs/h6WtxIHmo65elkM6NsLK0fPKL + lzfD9jwUmfFTKto1p2dbsqQ3RSlNHsgvAQq60jv7NiwbSFRF8tV8V49waE5rwLGj+egO + CoYGPGYEwxtXsDC4jUFMevFH7xEArXp1Lb+pRTkuejQwGghyXQr0Quo6Dgv8ztrjE6+e + URqviuUsFNCFqHnPAgeyAQ+yrllq/as6SPZSky6UG42xkzktlobE3Yea08pLY0OL8UHK + 1WHVJbT5DFhIyZ+gCtkMQ3weEXl5rL1IWuuv1W1GeXZFv7rwzvPOE1OzyK33ZL4eWSXF + 2Clw== +ARC-Authentication-Results: i=1; mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b="GO/VW+4p"; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com +Return-Path: +Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) + by mx.google.com with SMTPS id i200-20020a8191d1000000b00586a708c858sor6327710ywg.12.2023.10.10.12.43.48 + for + (Google Transport Security); + Tue, 10 Oct 2023 12:43:48 -0700 (PDT) +Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; +Authentication-Results: mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b="GO/VW+4p"; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1696967028; x=1697571828; dara=google.com; + h=to:subject:message-id:date:from:mime-version:from:to:cc:subject + :date:message-id:reply-to; + bh=dH2d6q5VcS+7rfJUaWYK0fSFe6OjBSMp9T98v8goAXc=; + b=GO/VW+4pWlcPLz1OwBRtCcm/kaXWkMLFDByoke7dUKuKtScGtcpOfEOlc7LS26pRSn + G0KnZ6BH5SNcrx2uFXM/hPZi3OHdTBwGJ9Z3T5wmr94CY3+9JrrgjbXKv+3wCO9Xeqe2 + U7BE8fm2PeDR1oyxv1mufUqM7MDv/EZ6ZJXNw1w47SDu0jEtBfe44W/tsQGxgCziMzSQ + 2ziwXcCDoenkL0Wxq72g1Cab4o3gbBU19VCEtBWvkONhSTVN9lQuyIajNAmsD68OJwEe + TL9TWOzDeP5v37VQNVIQLN6fIUx8tjx2iH4+DMJPvRMzVZ+0MbuvcYLr8915xDjz7jjO + DK2A== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1696967028; x=1697571828; + h=to:subject:message-id:date:from:mime-version:x-gm-message-state + :from:to:cc:subject:date:message-id:reply-to; + bh=dH2d6q5VcS+7rfJUaWYK0fSFe6OjBSMp9T98v8goAXc=; + b=kLGz1m3GUfobNymbK3/DSTvJXAoppFTs4fRqRZd77TK9CkxPQe025/3PQAVhU2YW58 + r0Jk6MAhFcN/n15MPXdjVBT6eqC3sCmYhBR9n6RmX7vp2pEius50Lty64Q/eUj2cFH+t + CUNs6ctISm65/agHRNvt6no8XgzFr3Ma4KgfMhhzxcIK2bopoW90LfUmyKZFXSlaBVbm + KVQXbAC0NN/2DtYUykJTQJ2Ze0Cu9P1TxcyZZHpaSed7gz71fO4u/W8CXpslwOJfSfXl + VyiCQ1v8exrM+Q8WEmiGdqLTqZfTK6VcG2w7kmDG+ZhbXA2IRDsUw/j0h868878UaFNO + UPuQ== +X-Gm-Message-State: AOJu0YxbWTRDE1w3F70lfb2Bb828Alj1VEuoPi9QDhiWl/m63ILSpyXh + BV+ZKjoFknfARLzERgxd6gE8y/UYCBk+pUGDeB5KmATJ +X-Google-Smtp-Source: AGHT+IEeri9J0dpOppDay4cMM7UxoTbvoPvlULY8a5bikCTsqVXU2KmrxMjfyr+vW9S33WH/2w7ouMrZKF3lk6KAyCQ= +X-Received: by 2002:a81:ac42:0:b0:5a7:acae:3bb0 with SMTP id + z2-20020a81ac42000000b005a7acae3bb0mr4382907ywj.5.1696967028246; Tue, 10 Oct + 2023 12:43:48 -0700 (PDT) +MIME-Version: 1.0 +From: =?UTF-8?B?5pyr56We5aWP5a6Z?= +Date: Wed, 11 Oct 2023 04:43:37 +0900 +Message-ID: +Subject: Send 1 ETH to bob@example.com +To: emailwallet.relayer@gmail.com +Content-Type: multipart/alternative; boundary="000000000000ea0b6c060761ec19" + +--000000000000ea0b6c060761ec19 +Content-Type: text/plain; charset="UTF-8" + + + +--000000000000ea0b6c060761ec19 +Content-Type: text/html; charset="UTF-8" + +

+ +--000000000000ea0b6c060761ec19-- diff --git a/packages/circuits/tests/emails/email_auth_legacy_test5.eml b/packages/circuits/tests/emails/email_auth_legacy_test5.eml new file mode 100644 index 00000000..9fa5791b --- /dev/null +++ b/packages/circuits/tests/emails/email_auth_legacy_test5.eml @@ -0,0 +1,87 @@ +Delivered-To: emailwallet.relayer@gmail.com +Received: by 2002:a05:7109:6e90:b0:36d:793d:603 with SMTP id jg16csp154586gdc; + Tue, 13 Feb 2024 15:16:32 -0800 (PST) +X-Received: by 2002:a05:6902:513:b0:dca:c369:fac8 with SMTP id x19-20020a056902051300b00dcac369fac8mr531909ybs.1.1707866192552; + Tue, 13 Feb 2024 15:16:32 -0800 (PST) +ARC-Seal: i=1; a=rsa-sha256; t=1707866192; cv=none; + d=google.com; s=arc-20160816; + b=xgkYZBTJAlHk2Blzhp1MXYjDKpicXKjvQ8zaZA9BYkHjWuePzG3QSIR6MUgwszHp2N + Fz1cjRZ2+TsPsJLpCQ7Gdk3d5exxf85WfY1X0vPcCx+q+9xKHeJVKT8dh8bD8ZdNSaiK + N7OWwLsnAOamSN9kHG10/0h4EP3/ikuuH9/DNUqwNr+K+kUcp5tI5Ns6B/PULIGAxFQc + Yh43AzVSmcpbUpyZdSdxHg7uylAtFzwTb4FrCgTb7fyngC66EcQ8/vZGrmYboFXFA31W + WmbktdQRkmxZ8jGP560SDnkHr/aN209YYISC/w5pKDoHKp9uZMETx77WJvfzSTRWYeEm + KnRw== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; + h=to:subject:message-id:date:from:mime-version:dkim-signature; + bh=jrYxFJzQ6WxiZb/FBt9TVNuNlG27A2NoDr49B4lA+ZU=; + fh=AKWw92sdXoMEDdHXKLL06vnizTpObKPGCfYXnoQDKO8=; + b=NQUxVT/V866NNXN6CZBeb+X6XSm8e5RSXQ/oZ8dRnfl3WIEo9hZy87JU0ag0l+78g/ + MHzhcdQ3P0y0tPc55dR0FHIgCuUnFrrp9FOXnSqBTbYpXsH8dt5DxD9cpAJ2JcSp3G7f + rhtJdLq7yQmStIMiuaMxhs8jx8Z7+s/uWp7xTjZ+sBsG00dAhVa77Z0xkpUBIaXnbSbD + AsBIdFaiIEeNhtLZnY8fmyM8Zr46EAmPWfBFpBCPAKaregDLkhQPqxp+6VUzmP+4us4Q + pTwRWCR3O9t9QyjiV+Pa6//uSlyHKI8Hl3VmQiTUYsvSoweJdu5C00n5JieRMgAv/o5T + IfTQ==; + dara=google.com +ARC-Authentication-Results: i=1; mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b="h1U/KtaQ"; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com +Return-Path: +Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) + by mx.google.com with SMTPS id z127-20020a253385000000b00dc6b9629f4bsor3320137ybz.19.2024.02.13.15.16.32 + for + (Google Transport Security); + Tue, 13 Feb 2024 15:16:32 -0800 (PST) +Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; +Authentication-Results: mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b="h1U/KtaQ"; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1707866192; x=1708470992; dara=google.com; + h=to:subject:message-id:date:from:mime-version:from:to:cc:subject + :date:message-id:reply-to; + bh=jrYxFJzQ6WxiZb/FBt9TVNuNlG27A2NoDr49B4lA+ZU=; + b=h1U/KtaQD2q8O/pFPyBDxp8a/kwcvupwRCAU7fVBGbTC4RNG/YjuHEraMJhhgxm/qv + O8jlW06L6nBrgFlqw9tb7weX+xJjMWaI30iKrn+g+tO83joydWcaRqS0VpF0cYTfW60I + /WYnTl3q4ybt+yrNOV25BprKSLRzsfmUCZ6kii4zFvqwtvPRP5Vrbnrb6FPuVwNMtQHv + loOhNlgbGyd8RcTJjBa9rvJWC32nl9gDo6gpW9lxXZqb7jqV09XcBjHsTgG5u7pXWQYX + AVpviKSJS+dI4mKN8gDLVbzNr1tB0eY2EROjnmH36zNLNTu1TGys6QBgdVGsra7DIuqa + W4eQ== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1707866192; x=1708470992; + h=to:subject:message-id:date:from:mime-version:x-gm-message-state + :from:to:cc:subject:date:message-id:reply-to; + bh=jrYxFJzQ6WxiZb/FBt9TVNuNlG27A2NoDr49B4lA+ZU=; + b=S+VasXOuITIhUuebNUWaFGFT/UxrkRQhJOkLypuiyuJ6be09oHt/Xy9vfTNbLXAWAV + P9McoaaCw4sFbT4cqzNegbAFXy04EhshA4PrFjsNIHXK7QLQSGnveoFJ5lT+AufXG33f + PlfEpxv/VqIMls6s/z1otGqOtcyn8TAkTob2FnQrLyNhZZeTbyxtiK3dWFMlxD8r+A7k + IKpLozSif102Nfzmmj/Zi1WHlbscv5fTidxGAn1n7FYenFKJ6acqc7qs7jlJfK6ajjGD + VCB2ujSlvCcxoRp5GEJGywJd57LfLQrJlyBjuX+yd/3ejc9s/sWqzrpkNgtrKRYI7PEi + sSpA== +X-Gm-Message-State: AOJu0YzlHB0Ob5AJMbKmNN70Kwv+o4+d1r5aUQBYTDVmqPwoEX3mel/p + zgMMeG65Q+p5zj45ZyrUsI7UglfqtLXU/MdzzzpSiQQuQbEUzfMQzv+5og4He9CPNodovAfSKZ3 + B+PrRXw9ADbnDZmUfDks2kPs0wHoCI85b0HO7Lw== +X-Google-Smtp-Source: AGHT+IEn4n432lSRAbrl1I6OJWe5HZ13UMYAJJVv70tvwsMv3nSutjkaf0yxtN0rOA8WwskFFptX7hVjkTKvEGCZiIY= +X-Received: by 2002:a25:830f:0:b0:dc6:ff32:aae2 with SMTP id + s15-20020a25830f000000b00dc6ff32aae2mr443891ybk.63.1707866191956; Tue, 13 Feb + 2024 15:16:31 -0800 (PST) +MIME-Version: 1.0 +From: Sora Suegami +Date: Wed, 14 Feb 2024 08:16:20 +0900 +Message-ID: +Subject: Send 0.12 ETH to alice@gmail.com code 01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76 +To: emailwallet.relayer@gmail.com +Content-Type: multipart/alternative; boundary="000000000000b20eda06114b95b1" + +--000000000000b20eda06114b95b1 +Content-Type: text/plain; charset="UTF-8" + + + +--000000000000b20eda06114b95b1 +Content-Type: text/html; charset="UTF-8" + +

+ +--000000000000b20eda06114b95b1-- diff --git a/packages/circuits/tests/emails/email_auth_legacy_test6.eml b/packages/circuits/tests/emails/email_auth_legacy_test6.eml new file mode 100644 index 00000000..7b772af9 --- /dev/null +++ b/packages/circuits/tests/emails/email_auth_legacy_test6.eml @@ -0,0 +1,88 @@ +Delivered-To: emailwallet.relayer@gmail.com +Received: by 2002:a05:7108:c04:b0:37a:44d1:e2d0 with SMTP id pl4csp3207896gdb; + Mon, 1 Apr 2024 10:21:20 -0700 (PDT) +X-Received: by 2002:a25:3a04:0:b0:dcb:aa26:50fe with SMTP id h4-20020a253a04000000b00dcbaa2650femr7983649yba.15.1711992080732; + Mon, 01 Apr 2024 10:21:20 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1711992080; cv=none; + d=google.com; s=arc-20160816; + b=lriX+ZifwQ86IJZVArSx4+eGUcgeO31gOURsw64kSjQL48i2EpDDNHvLcl5vlEDF1k + RgQRUWnn080ZywAs+pwDcWFAHrP8XjHGz9z2N1H8I9LIQhTRcXRWgjZPORsf8gQ49oJM + 3pQWQEJARJ7TtDRLCWHNivXxrlOMGoubiv8YNCrT7FsE46OFZ4NDaqCCQebLF//XK/Kl + 616A6OtD7FDyd01nA807wra6pw3p7MBF0ACv655a7A8arlowqqtnuCD42I7/cysjMKt+ + RR3jIYICBT0PpxLCIXstkfqe2E0SPnLh936Cr0DwHj6+gHbxNIQbAu/I/lOjSd1TTtqA + 7aOg== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; + h=to:subject:message-id:date:from:mime-version:dkim-signature; + bh=aiM3ezBakDUzQO5qyB4uxVZuP7h9gh60LHvohxTHYSE=; + fh=AKWw92sdXoMEDdHXKLL06vnizTpObKPGCfYXnoQDKO8=; + b=wh60ywiB4oGfp4+N6degtlgMSqfqex/22YbG3XwEUcuY9bAapSOf4n1sVNHG+9PavK + N6nHd5ozTxc/H0/ItjfYqHQ6M6RGylCZrUMOBj5yAkpWJmK33eSZ5no7f9V7ASswF9Qg + J6atB98qe7IgSs/OBLG1hy0zX0NBCx6pUNwXaQvSTQwbajtIoHgpQrl8EIJ8Br8AtdX4 + 9r8ZwlpOx2yEx/xqb+lz+f6MNoyz3P7IzMu75vSvaCAhvf5sJ8ek6wb3xbAg52MgqeVf + M3EzWmun9+yj6yeW066/5B/0E7uFKIXcR1bByz8LZSdfAs0VuYfzKtjhjSksKhH3Lghh + p1Lw==; + dara=google.com +ARC-Authentication-Results: i=1; mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=KVPCp6Yj; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com +Return-Path: +Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) + by mx.google.com with SMTPS id r62-20020a252b41000000b00dcc1f1be907sor4483162ybr.16.2024.04.01.10.21.20 + for + (Google Transport Security); + Mon, 01 Apr 2024 10:21:20 -0700 (PDT) +Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; +Authentication-Results: mx.google.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=KVPCp6Yj; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20230601; t=1711992080; x=1712596880; dara=google.com; + h=to:subject:message-id:date:from:mime-version:from:to:cc:subject + :date:message-id:reply-to; + bh=aiM3ezBakDUzQO5qyB4uxVZuP7h9gh60LHvohxTHYSE=; + b=KVPCp6YjrUEelwchvP664IdNxEsqrTf7EWvO0Qg1QxVaWP5xZeow1dtYDo8gWjGfop + 9vtAHc9G7Lvtmnk7MtU2AKeqav7wdKY8gVNFL2qI+sV+EdqfVjHh5/VZaSDRUtjAxfN+ + w2X6iJ5nQbVaWhSaQ3Pe7KVBFz0Hzr5IUc9OZ6qAopinCQi8x5NnqsdMPFuwlvpz9bKi + Y7hGAe4Vm6FUjnqGOwCxR/N74MxBZnIso68OGBY96Z4k3PL7lwT4ni7JbS7PnLa1Q9rA + PnYP9qijNBwGj30SL7NhBhRGt5t+yCWY43ObhPT/dtFoRSDytZxkYx4ycE4zWS2wIJ1B + 0qVg== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1711992080; x=1712596880; + h=to:subject:message-id:date:from:mime-version:x-gm-message-state + :from:to:cc:subject:date:message-id:reply-to; + bh=aiM3ezBakDUzQO5qyB4uxVZuP7h9gh60LHvohxTHYSE=; + b=nt3FeKKHrH/hQ20gRvNFSRcw05JEHvjZyHpAxFfJGVPLMQLnT4OVZQffnqdDcadCSR + OaW4ZgR2yCdpLjJKwdiap5oFrPHPR+y/mA//mg+aCajGO8zt5CHDmc4ZZJWi+l5CpqDC + el8fOw0L2Hby0072I/mv4m/LD5pMH6aJzuKyCCyzD5KRJ9C3ngupIvZavrUAd2FiRGQF + U4g0/r/o8HLlV2fxNMPf3B6eDj2qZ7zYSQ0g0LYrLFfcbJNjm1V4rHyivXlbPKX5zmuL + 7UX8ePvS9WCXvYyEN/29L2HjdmssHscQcqYXXZ52LTpG3MMR1heWEi95x3+OafmSKWuB + e9fg== +X-Gm-Message-State: AOJu0YyL8Dr3XsXJIhymf6UhvXt4XTqXtXy/bmeVAXr+QUd6kzZMCmri + zhuxk4GSgbr0aBzla/7DAaBy6jc83DNEZTT3lJqqRbhOLfL14I4JpJ/2TOE8YlVjoly86yUCS0/ + T5a4+CiylmaHgG5dN1JbwmhgJ6JGAu6+c +X-Google-Smtp-Source: AGHT+IEVDNl9HlNqHqacvrnuQFWcEBTbheIMe06bJxH8fg2xlolVV9IVpaX7yCMmN/GC/2+kAuKJiZTUSXuC8mniFAs= +X-Received: by 2002:a25:ba47:0:b0:dda:aace:9665 with SMTP id + z7-20020a25ba47000000b00ddaaace9665mr7381032ybj.60.1711992080046; Mon, 01 Apr + 2024 10:21:20 -0700 (PDT) +MIME-Version: 1.0 +From: Sora Suegami +Date: Tue, 2 Apr 2024 02:21:08 +0900 +Message-ID: +Subject: Re: Accept guardian request for 0x04884491560f38342C56E26BDD0fEAbb68E2d2FC + code 01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76 +To: emailwallet.relayer@gmail.com +Content-Type: multipart/alternative; boundary="000000000000ca220006150c3707" + +--000000000000ca220006150c3707 +Content-Type: text/plain; charset="UTF-8" + + + +--000000000000ca220006150c3707 +Content-Type: text/html; charset="UTF-8" + +

+ +--000000000000ca220006150c3707-- diff --git a/packages/circuits/tests/emails/email_auth_test1.eml b/packages/circuits/tests/emails/email_auth_test1.eml index f5c20406..8122adad 100644 --- a/packages/circuits/tests/emails/email_auth_test1.eml +++ b/packages/circuits/tests/emails/email_auth_test1.eml @@ -1,85 +1,98 @@ -Delivered-To: emailwallet.relayer@gmail.com -Received: by 2002:a05:7108:47b1:b0:342:22f4:d6db with SMTP id bz49csp1557082gdb; - Sun, 17 Sep 2023 15:30:13 -0700 (PDT) -X-Received: by 2002:a0d:e2d1:0:b0:595:59f:28d6 with SMTP id l200-20020a0de2d1000000b00595059f28d6mr8532154ywe.21.1694989813070; - Sun, 17 Sep 2023 15:30:13 -0700 (PDT) -ARC-Seal: i=1; a=rsa-sha256; t=1694989813; cv=none; - d=google.com; s=arc-20160816; - b=WFAEAsVx9Z9pEmIAtOzTiZ/g+izqJNYn7WGrA7qPR+10JDAnfMjPEGVJFxqQ3/nc+l - fgIj520PStLh30yieeiJyZHTCiMUQWs1yBo/5u/MeEAcG1z3s6gpXjL8wPpYuMCPclFa - TvpC2dAcs1aVv8AvJHlgMkqc9MvRQWqoJVJevp9T4FOUfszaRKHnsNJHvhuJAl38xROp - P0oIx9vGnbNmVEHcTz4OBWwSoN56JwOK7NAc0o823B8lt1i+shw67HY8XM3nvIp6ftwx - dUyFQuxP9VEH4hwIu02C1L4yDJNgTshxn1IC83cHXIm8pcsZxfv2Vg0swrD0IK3tRsUx - tdTQ== -ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; - h=to:subject:message-id:date:from:mime-version:dkim-signature; - bh=BWETwQ9JDReS4GyR2v2TTR8Bpzj9ayumsWQJ3q7vehs=; - fh=AKWw92sdXoMEDdHXKLL06vnizTpObKPGCfYXnoQDKO8=; - b=e8eKiZWs5PsaB+Q2CCneEWl05AAzrCu4f2pzRbD0JUiF4dQeWWlorGXS70lPNRIuhU - ENk6ellkuIvA+uhsHgC/An+asGeAyC80h3xX94cvmXaeGCO3SnGzZ2VgATJOgYd+ScYY - G4xYrrUEQlsblFtCcG7povcW8Kwkmda7crkoNuj3sqdhQDgzGzI2l66GEUuYMlWXTrlY - /egEyxTvMy7nUjakk2n6VVCR5S4kLC1Fna3v6RLvWuC3sIXzAD93m0AgqBveopmyDZ+9 - eNKvAouT4znpujbD+FDydF6iC3r1GfZtjYJPBe6VfQOEwKCaoSHXSfinmh2Pm4gLtg3D - 4P0A== +Delivered-To: suegamisora@gmail.com +Received: by 2002:a05:7010:2284:b0:415:a8ba:b98c with SMTP id r4csp1023651mdg; + Fri, 25 Oct 2024 07:16:51 -0700 (PDT) +X-Received: by 2002:a17:903:244d:b0:20b:ab74:f567 with SMTP id d9443c01a7336-20fb99499ddmr75139865ad.27.1729865811161; + Fri, 25 Oct 2024 07:16:51 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1729865811; cv=none; + d=google.com; s=arc-20240605; + b=d8XJK9+pZJCprUUbpInC0h6dOlNOgCMMU7te50Lh/0ZMCPWVEfOJ6T2N8EyOZ6/wFe + 4nCuvGy6G33+OHk+ESdd/URG/j2bY68eIxGI/U+gqzmqYIZZkQYYOrKeUIlC7VAbIyvy + fQlagnM7l37UqdMPCj+a6YeZoT196WBX9xNIUY3BIrbbT4yDguziAgbx3xbWeIyFwgw8 + 7AO5N4sxz6VQ10l1B2EhtEivAox4sWBQJihjzRoTcP7z2G9Zha4GtIzQWbMqqUZBTs2U + Y5qwW+TqljQsCJyINC2WTgqrN4tTv5hugYjFey3PDjfL/K0lausBbu7Uo71cqyXOKhgt + wtjA== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; + h=subject:to:from:mime-version:date:message-id:dkim-signature; + bh=bT/LDY81RpBFmXm/KMUR+NkKSYXPaNrvqUT6/P1bYwc=; + fh=r9ZW45D/4i7BIl/4UeFGrkYKwbplztqhOVKfbV+WD3I=; + b=CMD4Fa/nGqeNrJLbNhdRDAeriZ3SBBm050L0vv1IbPjFnwZA5W0hhaDSx0JKc1aDTA + vaR3LATyHM0+IkGTIivTKnlYVVn6wazIXblzc23bykU2Nl30ce+QuLBy4VlsD3ZPzHy2 + kva+s5Esh3YGfIicRxxe3fa7QOWldGvI1zBqRAkMkGhOakUyjMVsFIM1BYv2PS7bNo3Z + fj0HJTNdcsdNtanTQK8QzQnxxE7DikgvgwyLQbcx7JzSgipVS3ROm1Y/4NcOreDQ9pkf + kI7EQ2KyGOFBWexG13Cb3l2ZrKc83pZJlY3MGLpHRiUt90J/EN3tFLj+aPNnLm+TOYYH + prIA==; + dara=google.com ARC-Authentication-Results: i=1; mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=RHBgQbCx; - spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; - dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com -Return-Path: + dkim=pass header.i=@gmail.com header.s=20230601 header.b=KIjQBw7z; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com +Return-Path: Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) - by mx.google.com with SMTPS id m12-20020a0dca0c000000b0058460bc906bsor2973516ywd.11.2023.09.17.15.30.12 - for + by mx.google.com with SMTPS id d9443c01a7336-210bbfaa9aesor9660625ad.11.2024.10.25.07.16.51 + for (Google Transport Security); - Sun, 17 Sep 2023 15:30:13 -0700 (PDT) -Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; + Fri, 25 Oct 2024 07:16:51 -0700 (PDT) +Received-SPF: pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; Authentication-Results: mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=RHBgQbCx; - spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; - dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com + dkim=pass header.i=@gmail.com header.s=20230601 header.b=KIjQBw7z; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20230601; t=1694989812; x=1695594612; dara=google.com; - h=to:subject:message-id:date:from:mime-version:from:to:cc:subject + d=gmail.com; s=20230601; t=1729865810; x=1730470610; dara=google.com; + h=subject:to:from:mime-version:date:message-id:from:to:cc:subject :date:message-id:reply-to; - bh=BWETwQ9JDReS4GyR2v2TTR8Bpzj9ayumsWQJ3q7vehs=; - b=RHBgQbCxhob0RHu/S1J4YdDG2aP1fRDJR6tQrN0wyfVHesARR9NhQIJ/lyUehRTLu/ - wfbHY5RGwSv/87X2iX/p94rGXKJ7R9QFWuuHi0owVNLw2cDNL7vNpT71IgujrHGBTQlB - gvGFd+Gp7/X7jY5DBte4MCi+syCGrf/v+qFsTQ/XUEKpsUu7beMEjTz879yZtdr7LVAE - 9bcsAe18sfX2li2ubRqdV/EPg6sWXIo19jtRTEZ2q1B1i6jxWmaUB+/Th+F8VUXHcJ2a - GluecEG4pSAeP/a64bbpkmOxdMx4bb5A4jyWr1q+TyeqfHXxOkHf8c7+gMHhzGp/tJiu - d12g== + bh=bT/LDY81RpBFmXm/KMUR+NkKSYXPaNrvqUT6/P1bYwc=; + b=KIjQBw7z7yB2LA/GAK2tZ0EFADBYU231VkXXkwjzQpcUwp0D7CKfO7f6olrFiP2/bI + 911tMT6S+t0NaKsG0C7iWiBmxp1bF34tF89K5VMRQaCG0mBxyJyxsrAVKc/grRdM1+qS + eWEQoRnbhjTJfN3MSd4Dp0gcwTgC3OnMTy5w4v0bD7XAeuxeBvTARnQYfMnesp+GWIpB + m6efm93+NDUHGoe2ouYsxbm2dONaC+F83OLNTp97v9sw3sjGVstJWgbBatKj3X72cc3e + 9an/zKXmn7MLdW0zqRMKx5uwIuyae3S7S8yAWk414H870TeJy/oqehA0LSWJ1Rw1Cqcw + Jjbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20230601; t=1694989812; x=1695594612; - h=to:subject:message-id:date:from:mime-version:x-gm-message-state + d=1e100.net; s=20230601; t=1729865810; x=1730470610; + h=subject:to:from:mime-version:date:message-id:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; - bh=BWETwQ9JDReS4GyR2v2TTR8Bpzj9ayumsWQJ3q7vehs=; - b=AFkTp60CFyHReF9haHoUVGsSO0+uQZWNhP/SdjYaR1hKqd7FDcv9QMWyo7Ruo2q668 - AtM04vsAxL3KPbCh8l7ghxonJlfpIdwnJFFwiIkAaymLN2nfa/iA3yTqLPsZc21+DKWI - 4L161IUCshKj2K2/ErZr/cslf7g9X4vA5z6vaQhUJgB1JL4dlx5eWwgldtAaL/5jSQAg - gThwEVUU6QqljCd1eVCyG5CcQGfJc6BuHNr3beq+4WMlvll97o5n3cpa+QFJJejXGoRn - n0QiaK8Xki3ajWSdhu+K2y+Y4Cd9KBp4utQhZ4Ed74b0o4JMmdU+UOqcxvQs3mRrqGTn - YsQA== -X-Gm-Message-State: AOJu0Yy/ikSKXhxWeOjidkPu0ZD7ioRrSKLdlg8Ngfo45pZ1AlVfsXzW - oHfddvOgIXyqeA8uYaGcdfJtfrWelHBChkfXWe8TvYbSGTp2mw== -X-Google-Smtp-Source: AGHT+IFwSk4ZOp7bjwU0GeSyGMnjOk59tjDeY5XcQ79bFaW3jx2uDJC6n1WvtgsSMCTZrtUKAJbs8eUMJCXS0G8mfPQ= -X-Received: by 2002:a81:9108:0:b0:583:f78c:994e with SMTP id - i8-20020a819108000000b00583f78c994emr7327928ywg.42.1694989812400; Sun, 17 Sep - 2023 15:30:12 -0700 (PDT) + bh=bT/LDY81RpBFmXm/KMUR+NkKSYXPaNrvqUT6/P1bYwc=; + b=Sx1BnrCkJff3QLkebYj+smj3lYHAsST4bWFVoQXIYYiiDR39vOWpIiuYlrgqCfI/gX + SX5ExYx+3Y6WmqfXiwERdQsQd2UQEYNBC3qcTpJ8fm0OElP6yCvxIef8+AHNF++vLGQh + DdA81IXhMva4WSdCIGN9y9mGJwp1UKxM60wEOK2AglnIYcd+K/KWyh2DkHdTljpOR4V7 + gfxCwX0yZ14d8JtXHjeYZugbz9QbiCsFoSJew17BpfpWyzv92I/7tecJtAYGiz3kKCB8 + w65Tz5aB2AF8YVZHclCsgGVLVc/Wd2n8z06fBsuSL1TYSxvG902x6qlgCzyAkRRy3Cw5 + adZw== +X-Gm-Message-State: AOJu0Yzege80eQmzaDuEGfJewEgdtOZnkhsoPQpZHuc63ZJsQCB955XL + vNPtZqu56A1KLglV5v8x0ULFftfCuvZuC4wdXQoWKIEELaANrLvmocAh/Vsq +X-Google-Smtp-Source: AGHT+IGVSna3D/ryeT3DaYAkWN9xJSkDN3vpNVXO5Iyp9EOu95r/HH/C75oGKJyP2qCD7YUIiljNNw== +X-Received: by 2002:a17:903:228b:b0:20c:f856:a8ff with SMTP id d9443c01a7336-20fb9a81f02mr80275975ad.58.1729865810266; + Fri, 25 Oct 2024 07:16:50 -0700 (PDT) +Return-Path: +Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ([93.118.43.168]) + by smtp.gmail.com with ESMTPSA id d9443c01a7336-210bbf4a21asm9792355ad.61.2024.10.25.07.16.47 + for + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Fri, 25 Oct 2024 07:16:49 -0700 (PDT) +Message-ID: <671ba851.170a0220.841e6.384e@mx.google.com> +Date: Fri, 25 Oct 2024 07:16:49 -0700 (PDT) +Content-Type: multipart/alternative; boundary="===============5778012197124243248==" MIME-Version: 1.0 -From: Sora Suegami -Date: Mon, 18 Sep 2023 07:29:59 +0900 -Message-ID: -Subject: Send 0.1 ETH to alice@gmail.com -To: emailwallet.relayer@gmail.com -Content-Type: multipart/alternative; boundary="000000000000aa87aa060595912c" +From: emaiwallet.alice@gmail.com +To: suegamisora@gmail.com +Subject: [Reply Needed] Test Email 1 ---000000000000aa87aa060595912c -Content-Type: text/plain; charset="UTF-8" - - - ---000000000000aa87aa060595912c -Content-Type: text/html; charset="UTF-8" +--===============5778012197124243248== +Content-Type: text/html; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit -

---000000000000aa87aa060595912c-- + + +

Hello!

+

This is a test email with a basic HTML body.

+
Send 0.1 ETH to alice@gmail.com
+

Thank you!

+ + + +--===============5778012197124243248==-- diff --git a/packages/circuits/tests/emails/email_auth_test2.eml b/packages/circuits/tests/emails/email_auth_test2.eml index 53af1ef5..0ac76ab3 100644 --- a/packages/circuits/tests/emails/email_auth_test2.eml +++ b/packages/circuits/tests/emails/email_auth_test2.eml @@ -1,85 +1,98 @@ -Delivered-To: emailwallet.relayer@gmail.com -Received: by 2002:a05:7108:2c4:b0:342:22f4:d6db with SMTP id i4csp2966gds; - Tue, 10 Oct 2023 11:58:16 -0700 (PDT) -X-Received: by 2002:a81:4a55:0:b0:599:8bd:5bdf with SMTP id x82-20020a814a55000000b0059908bd5bdfmr21750490ywa.50.1696964296192; - Tue, 10 Oct 2023 11:58:16 -0700 (PDT) -ARC-Seal: i=1; a=rsa-sha256; t=1696964296; cv=none; - d=google.com; s=arc-20160816; - b=a9xg8fw3SXXh572oqDh838o0dBzsmtImJhloG43idR4VIr3bD4bEg6yHiVQz/gCVHB - JWSqBwHpS0ejzoa4Z27guBfS062lETo+O297nNn/KXBFJ+E0RMj65rvQTgmLI703M7sp - uImKsxcVLIdfjERz8GBr0eRrg65WX1dvg39SzDcCtDYaHrV0yrs65B7H9DDdo8IknkF+ - S5j0tBvM15ZHa9U+tn/0pUT5MwAv3DREZP+dyKfZxh0/9z2jycOOi5NSyUXRbTtXppdj - PuaycQ+TMdAmOTdIMiLog1W8QOzrzv1uanDloMFu4ykOZ8q8MdDd1kk1fIDp4YbF4+KE - NwVQ== -ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; - h=to:subject:message-id:date:from:mime-version:dkim-signature; - bh=2mqY3PZCoz8InXGWf2u3R74gNz152fRD9sTUPAxlKYk=; - fh=AKWw92sdXoMEDdHXKLL06vnizTpObKPGCfYXnoQDKO8=; - b=wUxZO1jAnI6WgyweT+69bF7FzkKLyGZRvzQCNOaxKUnS+DQzLe51E19G5qYQNemciH - f5yU0dUPFZa3gJuf/CmImd6VlEojBNPfk0bY1VpCH61a8OfuXi8XbMeF82GoMHi2Id70 - QR4QcUsUUbBV2R3Prw3Jy1tI9F0KWG5iyztI6DvWJX546cMvgYZn2l9ah+mlsreB8gaL - kbhCQ3/vL8K2CDT0Cw3d8+dMzLxMgwpuNE1cF5Wff6vsrgbuYgsyB9qQEF5wRVgEQVxK - 0ewpCgRzR01nW6/no/aDZ3BhVd9UW5C9CX7+y8+RZ3vRkWwowaH5+juqESG/A9U/HP2p - hb6Q== +Delivered-To: suegamisora@gmail.com +Received: by 2002:a05:7010:2284:b0:415:a8ba:b98c with SMTP id r4csp1023919mdg; + Fri, 25 Oct 2024 07:17:13 -0700 (PDT) +X-Received: by 2002:a17:902:d507:b0:20b:5ea2:e06 with SMTP id d9443c01a7336-20fab31f644mr163925025ad.56.1729865832744; + Fri, 25 Oct 2024 07:17:12 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1729865832; cv=none; + d=google.com; s=arc-20240605; + b=JpgZ1306kVvis5Wm1ndA0twPVvZe0/etFD/bMeDM/3DMeUVzuFECO2oTD0bfHE+oOX + 1zM5jr97aF/4sg5PdXBCXBUdiWPXL/esZAnkZ5q+L0rBxxu8Z7VyjlF8uOPzjlQ9fzFx + Sc9sJhQ5LKPR+Q6fga6kgsTL76rHlt2areeap4ufaydsywTQEoYxpq/iXZYS2yS2OIer + ZbPqIETjNbgiV+7ArK9KsNcc8OqHMIp7M2bDqsFUZJdVoJo142t3MxUO7zcmiv4OOIMa + 05DY875TmRJ1ychstgILDc9FCeR/l+W2FUghE8XIKgBQU/rdG0vtqtiwo5GQBvw6H2Pg + BH+w== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; + h=subject:to:from:mime-version:date:message-id:dkim-signature; + bh=YRN4OabpSP0B0hwWP9Hg/op1b+rgEXfwLU9but56ffQ=; + fh=r9ZW45D/4i7BIl/4UeFGrkYKwbplztqhOVKfbV+WD3I=; + b=gLVT+Xz4WvQXUi9UfqkOpaGot5jdJq7jdzHbOwFBz/pQH6AgpCMkX7AxDCqAkhr1+J + f+DZ5GeFBFOjrPd8oyEzb6LlBwkPy8koTLBdaLubQnM3TBFbIX3zQwpRLPQh/e30pcet + iSZQXoQYts91HdB507zLuYqJHM/EJLXh1KC7YyzmGSmtDxrQEI+MTqM5KmizogEUeX0N + 95w660SCpDR36uKeTLwKXxx8CI2/C0fGc9R0bCS9dNlF/om7tL0bjJnlJaofpM5to+RA + /+ffZujWeKl1PEnXuMCZ0x4+p59VBAHjIIr4/1aGrD8pIWBn8cL0b2INHAql9cAturx4 + OLOw==; + dara=google.com ARC-Authentication-Results: i=1; mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=ZtY1tM0G; - spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; - dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com -Return-Path: + dkim=pass header.i=@gmail.com header.s=20230601 header.b=VBQS3DB6; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com +Return-Path: Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) - by mx.google.com with SMTPS id r194-20020a0de8cb000000b005704eb70d02sor6290629ywe.11.2023.10.10.11.58.16 - for + by mx.google.com with SMTPS id d9443c01a7336-210bbffdcc4sor9874345ad.12.2024.10.25.07.17.12 + for (Google Transport Security); - Tue, 10 Oct 2023 11:58:16 -0700 (PDT) -Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; + Fri, 25 Oct 2024 07:17:12 -0700 (PDT) +Received-SPF: pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; Authentication-Results: mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=ZtY1tM0G; - spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; - dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com + dkim=pass header.i=@gmail.com header.s=20230601 header.b=VBQS3DB6; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20230601; t=1696964295; x=1697569095; dara=google.com; - h=to:subject:message-id:date:from:mime-version:from:to:cc:subject + d=gmail.com; s=20230601; t=1729865832; x=1730470632; dara=google.com; + h=subject:to:from:mime-version:date:message-id:from:to:cc:subject :date:message-id:reply-to; - bh=2mqY3PZCoz8InXGWf2u3R74gNz152fRD9sTUPAxlKYk=; - b=ZtY1tM0Gaga0hoo7frGS439zDz3JKhYiDIag5WFs4cE0JBIQxOP5CPOpMhIP7mkkh8 - BT3+uoAIYAj6ewIFGtoE4iW+tEo8m+uusFn0+u+BiMUxrifgSUpm6L+7jmlRDGTELbiI - x0JrI+dqFN4qeDYbVrFpko2bh4EdBDFBZjHW/KM8dFR+FDyVcNWeNqdeD/0ht13SwULG - RsUboFNx3zVy4aCt0oi8kIc1c9XAYcM/lvM/pXkJVE4hPwErAwk5CZy25Uu6NN95eum4 - aaOI8h5MJ2aDR9a1jipuDcNJM/pLU0oyIPU9juP6otGCMotHqzJbJ0VQZm1pZAg++0Wy - X3cQ== + bh=YRN4OabpSP0B0hwWP9Hg/op1b+rgEXfwLU9but56ffQ=; + b=VBQS3DB6vBI5dEUVHVFmMYgtWDjO0T8V8vNbT7Wvz2+KvOnffUty1/aP9jWV9OKEnY + WylijcGiDqPNMIP8rmgCySz5pmWLWZhU3EV93zF/SwsaJ+OpE4jtynAy7XOW7DRbdQLi + h+sonYAD1LbZLoGFgE4dZeYet3uTBngBxbCXhZpxMMxccLp3+6Y8KMxRg7h8LaDrFlsy + 4ZqSH1oTUAjbtk/nxmF4cFSgvB+A+s2QjeIz36Sa6kIm9wZp63w4n6xW3pCmk1G+ZF6n + TlseOadki3mUI8SUtZ2JP9Tn7wHXBdT4FK7IPLk06ESjtaaL1wzvTV+spLuPfwqw6MEL + s4Hg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20230601; t=1696964295; x=1697569095; - h=to:subject:message-id:date:from:mime-version:x-gm-message-state + d=1e100.net; s=20230601; t=1729865832; x=1730470632; + h=subject:to:from:mime-version:date:message-id:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; - bh=2mqY3PZCoz8InXGWf2u3R74gNz152fRD9sTUPAxlKYk=; - b=A9W23+Q7/4uDNevuWqpa7eRZlalXwzFjF2AZmRoa7XdFmJAN8puVKgJJgFAN9GxFG0 - TkGYTP5ZjSnAIkrjnnR1SpFgXnO02t6H+mJha8TK6d/QwSx3MO//ACD9H0Sy+fnygLly - +79YG4X8M51xVC7rzf3M8mfubRAMCIgx3H6bdv50KTugO0K7kAwaVfH7IelJziR6kDAf - /L43Mu2QQHNJSqE3uT5LJ5P8tVBP8U28adAPvVMB2UqNjAml8Jx8K/lIVL9yNS1HodjR - xx4CBDybd4ojU5Rsmyak489TFOq+7ibJRRqQoNDfZeulVjHnZC8nsJTJaMA1leEdBy8b - 7ReA== -X-Gm-Message-State: AOJu0Yx6Y8WGZ6/NuwJ93pEaku/8m84Fmu2At47SDfTmL91QgE7EwYp6 - PBXEK923tWejtcRNtvppo7NGaLlg/rRoIvkx0yMqdMC2 -X-Google-Smtp-Source: AGHT+IFTvu5B4yrT+n5M7sJsvjMOv8jW49fPuUZ9TW24SK9KQjLHUbZivpC/9kYnwwKhGAIlbfFezDxoOdgtxiVT4Sg= -X-Received: by 2002:a81:ac42:0:b0:5a7:acae:3bb0 with SMTP id - z2-20020a81ac42000000b005a7acae3bb0mr4278669ywj.5.1696964295610; Tue, 10 Oct - 2023 11:58:15 -0700 (PDT) + bh=YRN4OabpSP0B0hwWP9Hg/op1b+rgEXfwLU9but56ffQ=; + b=FKK81BEWE2CsThDjUIeMZs8yggYxyc2wWZBjgzdvCuCqWxRsvT0JS0iTCWXcNlf4SU + EQXKIxpp6ZNMPVtpOP2wQxHy4V/8FmMkt1h+m+x8dzdpSFtdxQnXnCSRDnKfEaqkKYPV + yv+1n94nNgy8CZYY30Curgo3RAWqb26fZygwFq3W2srTjeXnah74o84bu+BpQcCng7gM + CxAjXA2f/0YNiZskauHgMLADzaRgVgTqsssArtH8bn90zo/vsCa+EL62UQGZTY0pez4V + rh7uRXafBjq+In8A7uciXW5jWqlYQJ29RFcCv4hPT13s9Tvc2o5N0ksjaEyeS5LictoA + t6BQ== +X-Gm-Message-State: AOJu0Yy0lZffis9HHI9IMIfHlwJbUOlRj4fq5gSYSlyIuUUeEPhbqvww + RjpWpnVBkmkJHdwWqiq/oQ+m432yVwnOeIs/YYBeNP+WSR08/MjORV57J0hwiHY= +X-Google-Smtp-Source: AGHT+IGUTObaL9kK8PQ1UoBOJfKZF7ytkUSrTKeS9oav/MsLaKSgLqUKzMCoEUmMFm7tD7+RLZ2nig== +X-Received: by 2002:a17:90a:5145:b0:2e2:ffb0:8a5c with SMTP id 98e67ed59e1d1-2e76b6d5410mr9993199a91.27.1729865831827; + Fri, 25 Oct 2024 07:17:11 -0700 (PDT) +Return-Path: +Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ([93.118.43.168]) + by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2e8e37720d5sm1465688a91.54.2024.10.25.07.17.09 + for + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Fri, 25 Oct 2024 07:17:11 -0700 (PDT) +Message-ID: <671ba867.170a0220.103a99.55f2@mx.google.com> +Date: Fri, 25 Oct 2024 07:17:11 -0700 (PDT) +Content-Type: multipart/alternative; boundary="===============2125664866228297927==" MIME-Version: 1.0 -From: Sora Suegami -Date: Wed, 11 Oct 2023 03:58:04 +0900 -Message-ID: -Subject: Swap 1 ETH to DAI -To: emailwallet.relayer@gmail.com -Content-Type: multipart/alternative; boundary="0000000000000958390607614a21" +From: emaiwallet.alice@gmail.com +To: suegamisora@gmail.com +Subject: [Reply Needed] Test Email 2 ---0000000000000958390607614a21 -Content-Type: text/plain; charset="UTF-8" - - - ---0000000000000958390607614a21 -Content-Type: text/html; charset="UTF-8" +--===============2125664866228297927== +Content-Type: text/html; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit -

---0000000000000958390607614a21-- + + +

Hello!

+

This is a test email with a basic HTML body.

+
Swap 1 ETH to DAI
+

Thank you!

+ + + +--===============2125664866228297927==-- diff --git a/packages/circuits/tests/emails/email_auth_test3.eml b/packages/circuits/tests/emails/email_auth_test3.eml index b56bee8b..d9840bce 100644 --- a/packages/circuits/tests/emails/email_auth_test3.eml +++ b/packages/circuits/tests/emails/email_auth_test3.eml @@ -1,85 +1,98 @@ -Delivered-To: emailwallet.relayer@gmail.com -Received: by 2002:a05:7108:2c4:b0:342:22f4:d6db with SMTP id i4csp17038gds; - Tue, 10 Oct 2023 12:25:33 -0700 (PDT) -X-Received: by 2002:a81:47c4:0:b0:5a0:ae01:803c with SMTP id u187-20020a8147c4000000b005a0ae01803cmr19454050ywa.38.1696965932748; - Tue, 10 Oct 2023 12:25:32 -0700 (PDT) -ARC-Seal: i=1; a=rsa-sha256; t=1696965932; cv=none; - d=google.com; s=arc-20160816; - b=Fsg3KEAwUjggHJzCpAIJuNz8Eq2GPO+sBNTbWQHDKlXgaLZxBWSohcJ7LrXfhUmuDA - Ji+99B0FbLIrjSPTojnSSVFahIf6015uZw7MB88+PhDeWPDHp1RZOAhwurrVDwijUigo - 07Tbc8Q5oFoMKst5d15ZMZQt/HcTunflxv/DdhmSKm1loIISuUc6VesLfqPe9MTaMztP - biSHonNs9AsiAi52llttRYAspoRP0rH/PLZ9KXZ0qqmTleAS1hUOwjbxkFYOtxYGyJpG - p1ouNBXpbzxWPivcoegCABNTCUDYYBZ0saR+MgACkDaULIXt2ett1jzPLsAdZvFJiSKF - Id+w== -ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; - h=to:subject:message-id:date:from:mime-version:dkim-signature; - bh=cyDN+YYekjfuyO0NSLmF5i598CHm65FOUxCJHB0q+Sw=; - fh=AKWw92sdXoMEDdHXKLL06vnizTpObKPGCfYXnoQDKO8=; - b=o5ksV0Fs6jZsEMgi0Z1SgiYU+tbWG3l2lw3KHVFUMWIToNFHYFmVQkr6rCUki1g2K0 - Bm8TubRMIuUkuyqMB6dWN5Acm/0lVhF0PMsZP8YqY3iNJWWdCWefl4dMFjkeijP4ki1j - BKzBYKr3UQCVeuVlFvaPeI/BpcD+QeCjqu80CGl3JFKyFUeS9Dou1lyLXm7Va20W+1+Y - ze8h3fv0h5DlTXA2oZVvsraXekIWKrxa+h45SYw/NSZ7bIwIM1W7B6hJ2IFDG25C65LX - ExpUkmBPfmps93jH5fWi+YxwRcx+dpCzn1MAodo0Ruyxui0KTYdCMvHBJVe1VUjIejzh - +cWQ== +Delivered-To: suegamisora@gmail.com +Received: by 2002:a05:7010:2284:b0:415:a8ba:b98c with SMTP id r4csp1026457mdg; + Fri, 25 Oct 2024 07:20:33 -0700 (PDT) +X-Received: by 2002:a17:902:f78b:b0:20e:5777:1b83 with SMTP id d9443c01a7336-20fa9e48d1amr123657765ad.24.1729866033016; + Fri, 25 Oct 2024 07:20:33 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1729866033; cv=none; + d=google.com; s=arc-20240605; + b=EmHTvYLz2pe5kSZfPfWgK0BQTq5o6ShJP3BhALa7H6vx7QBUm1fOahhnY4BEIlrvF2 + t+LMCigR7gc3OBY5E07O8dZURxU0ahA1RBVD1b4Mel2SsCF8DJZNwjOZ+A61pM8edcQl + 5piBcuP0rN2SQ6n6NfL+6QG3eis6W/shBF4XdeE3pVeM1QP8YMy+JZFh/CzrL3K3mOzX + hA3JMCSDFE4fS0Lm3hznrWMNABVg83dhblzeWRCokI0pIlDLi5AOelqg0TArQzpDaFip + CBZzFPl2FU5HyED4wpNJpJoWpOoV/AayMp0UvMZq9zQ+A4xDjB7jMhGMqX0ZuMk7Cw0I + amsg== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; + h=subject:to:from:mime-version:date:message-id:dkim-signature; + bh=wrHseP0aBOHr01LTA+P2fm6IQ8JhnLtsVT6E6jScTzo=; + fh=r9ZW45D/4i7BIl/4UeFGrkYKwbplztqhOVKfbV+WD3I=; + b=iQIksUyu6XvDYnbEA6Dy2HzkMJKtY+4RbjicfcjH4XzkwbcnMU0B1+U484/jN4uOs+ + 5Z/ZBe40P+XIM4nR/rvzWrBlesdB2GqfvEn+cvZ3BLGo/dL8V269J+g3JU9ApDFL1DAP + CRPtTROhc2BUvqjg2Qw9MmuSJCfsUJTI9GRrNHVKtf0P/aDN9MWyZguH0mjU1ZoWCsXu + 8sSbD+kDId5bDmcSk55vuTasISug1M1aEQ9SnUDyop++/bwn/hvyLleAnhPZpYUQEkoB + DRPuGvmhxMRyXTAGntEOu3g2RVKrlmnm4bf0S+BRsDZplTpxIv30mUGslGyEw6u8uHep + wacw==; + dara=google.com ARC-Authentication-Results: i=1; mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=cZhRvd7Z; - spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; - dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com -Return-Path: + dkim=pass header.i=@gmail.com header.s=20230601 header.b=WuouU0ZN; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com +Return-Path: Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) - by mx.google.com with SMTPS id a20-20020a0dd814000000b005a220219985sor6072943ywe.16.2023.10.10.12.25.32 - for + by mx.google.com with SMTPS id d9443c01a7336-210bbd909ccsor8596745ad.0.2024.10.25.07.20.32 + for (Google Transport Security); - Tue, 10 Oct 2023 12:25:32 -0700 (PDT) -Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; + Fri, 25 Oct 2024 07:20:33 -0700 (PDT) +Received-SPF: pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; Authentication-Results: mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=cZhRvd7Z; - spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; - dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com + dkim=pass header.i=@gmail.com header.s=20230601 header.b=WuouU0ZN; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20230601; t=1696965932; x=1697570732; dara=google.com; - h=to:subject:message-id:date:from:mime-version:from:to:cc:subject + d=gmail.com; s=20230601; t=1729866032; x=1730470832; dara=google.com; + h=subject:to:from:mime-version:date:message-id:from:to:cc:subject :date:message-id:reply-to; - bh=cyDN+YYekjfuyO0NSLmF5i598CHm65FOUxCJHB0q+Sw=; - b=cZhRvd7Z9zTNAscMPIquUHj6CG/yLgKsvbGL2ikAMHAlGeJbhR4o0u2n4Rr9WN6h8O - G7SJcvUD6enlg/a9/1AU0y73bjVPjMjY2nDGk+8ltokhBfYSeZcVsKA7iMuK+tBoORth - ZFtTEdVlO7Ekly95ara84epofiYCCGTdvED/RshhzZqjhrp1Mbw/wFtHUAujXVkOmvt3 - MB0knG+mamYAjLqH6Bc/g50gbMMsk1yF5VUYWnbhCK6DUGOeNyZmeYYRLm2yFlSAbu8h - PJPz2QbNY+D5CrxWdetq1JizYnJYOOSiRV7nflunEMji9cLW5I6lUqIlKxhQkdWqd+6b - 3tTg== + bh=wrHseP0aBOHr01LTA+P2fm6IQ8JhnLtsVT6E6jScTzo=; + b=WuouU0ZNu+8wGVEc7u96TpN8dtTX+wGOynTAi7WpGOGAU1yrZrzKn2qxHqHD8lX+3T + d1D9dHl0m/ecFDl2jrhv6jT6zkDX0blu7GgX6oBluR12pztMJ7WZ/2VwG9XacSZrwQmL + VQgaw7O7chi5Ch3ahECcfMDUM/rkDZq0pxfll68jZXmrJ9FeFx5pzCgM6WrVlNcnijWW + uipHDyNmJIhUw7oZGaF5qL+x+KwzqUPgbajEBD9br4MdxdpTgHEUEXva5WeSZqY9LatE + KtMurWT6sArRzMOUKrUBoT+/45o5eeH5UVFXWb8a8H8DSR1fIk6oSTW7hj76TFwduxSY + tSfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20230601; t=1696965932; x=1697570732; - h=to:subject:message-id:date:from:mime-version:x-gm-message-state + d=1e100.net; s=20230601; t=1729866032; x=1730470832; + h=subject:to:from:mime-version:date:message-id:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; - bh=cyDN+YYekjfuyO0NSLmF5i598CHm65FOUxCJHB0q+Sw=; - b=qeLyin8vj0JfK6n5sLb1/otbg/3P9Hf2kwVd8fnyEa/gnFl5db2e/2XvyhGjP2zMpU - sGjPCkXk7wCQozVEO35tBYsOzgah9uT480TUwVtTyuwW0xq4/4ZS1YizXlnRdmBR8SN8 - Ihjdyf5qhwKGv26xmUgGF7MqDbbfqFdwlPPRdYsPie+MWHdNMqu4dp1JW8Xtg3mpjcdN - 3usOCapPcAJCJG89wyaQWBaKbG9PuGCwULXw/BNMd6vYxQklrVOtNL5m9zEQG6DjBZeO - kD6lTBrYK7e6xMgTuqsF7vYIgAe51t1ijmy3r1hb6x7GPx+XId+PrVL1pMmWTFF4EcbW - W21w== -X-Gm-Message-State: AOJu0Yw2zJT1rbv9BoSJAwB4wOrj56soVWWji9646BXOk/k2D2gF+jCM - CRR/OyY9S2uGYRb5k9ED1f+XrRPwUp1R0gSBu2pZL/jP -X-Google-Smtp-Source: AGHT+IGSbOedb5aIuVhx7TayE6QXtIMR+yVf+UDmgKCrssN+p7v5iVhQJ21PrC58e5NK2EQvGB52q4bEypFxNZe+MG0= -X-Received: by 2002:a0d:de85:0:b0:59b:c0a8:2882 with SMTP id - h127-20020a0dde85000000b0059bc0a82882mr19390753ywe.46.1696965932010; Tue, 10 - Oct 2023 12:25:32 -0700 (PDT) + bh=wrHseP0aBOHr01LTA+P2fm6IQ8JhnLtsVT6E6jScTzo=; + b=BmP7NAvTz/h39raGzNhlLf2zOaJWhaHx0PRaubmjC+LCKjWBTWwCXOH5GACwA7IM75 + sCBsRpKOQ4ocuoxS328U5kpHXEVFVpAyDa5ui0KXS6vsib34zWBKHL4PccBb/3WSTGyh + K60SNebuIZbeOqANBnSphpAv6jPpedQ3A8EAcIy8A1FEF1mzblPrnR8Hx1CBiU5BKFy3 + PpmpeLfM7najX2XeYU/wv9FouJDTcxAK01YbSXEqXMRV+jChPHU4dpb5r5ZSbEEd6Q/Z + 1nhfjvu4PEWxvqo6GwO6g4srmRpaWrUa796tXosVO+dN2HEKHKXOJSWI6JdVW9MWoJK2 + Sshw== +X-Gm-Message-State: AOJu0YxFmo8lSWZEIHzknG5G1CBMWPY01HXRa4jVjNh0uSebf92UgSSA + GvWdu/JPqCBgQEVoqEkzat9ToG2KEd8gj1BdmHcXcp1vkYr8xp/4+99nqunE +X-Google-Smtp-Source: AGHT+IEhwhplSCtP/HgP0hdOjZeHJy9rS5FX1jo00eRclVhwqFWDaLTkpBCJ8duRJnGgVZgU3nF+gw== +X-Received: by 2002:a17:903:1c6:b0:20e:95c9:4ed5 with SMTP id d9443c01a7336-20fa9de0cc3mr143277135ad.7.1729866032207; + Fri, 25 Oct 2024 07:20:32 -0700 (PDT) +Return-Path: +Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ([93.118.43.168]) + by smtp.gmail.com with ESMTPSA id d9443c01a7336-210bc013699sm9771685ad.136.2024.10.25.07.20.30 + for + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Fri, 25 Oct 2024 07:20:31 -0700 (PDT) +Message-ID: <671ba92f.170a0220.176081.38b5@mx.google.com> +Date: Fri, 25 Oct 2024 07:20:31 -0700 (PDT) +Content-Type: multipart/alternative; boundary="===============0670125564578285345==" MIME-Version: 1.0 -From: "dummy@gmail.com" -Date: Wed, 11 Oct 2023 04:25:21 +0900 -Message-ID: -Subject: Send 1 ETH to bob@example.com -To: emailwallet.relayer@gmail.com -Content-Type: multipart/alternative; boundary="00000000000092d27c060761abc7" +From: "dummy@outlook.com" +To: suegamisora@gmail.com +Subject: [Reply Needed] Test Email 3 ---00000000000092d27c060761abc7 -Content-Type: text/plain; charset="UTF-8" - - - ---00000000000092d27c060761abc7 -Content-Type: text/html; charset="UTF-8" +--===============0670125564578285345== +Content-Type: text/html; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit -

---00000000000092d27c060761abc7-- + + +

Hello!

+

This is a test email with a basic HTML body.

+
Send 1 ETH to bob@example.com
+

Thank you!

+ + + +--===============0670125564578285345==-- diff --git a/packages/circuits/tests/emails/email_auth_test4.eml b/packages/circuits/tests/emails/email_auth_test4.eml index 22076d2c..5e51f719 100644 --- a/packages/circuits/tests/emails/email_auth_test4.eml +++ b/packages/circuits/tests/emails/email_auth_test4.eml @@ -1,85 +1,98 @@ -Delivered-To: emailwallet.relayer@gmail.com -Received: by 2002:a05:7108:2c4:b0:342:22f4:d6db with SMTP id i4csp25580gds; - Tue, 10 Oct 2023 12:43:48 -0700 (PDT) -X-Received: by 2002:a81:574f:0:b0:5a7:ab51:af5c with SMTP id l76-20020a81574f000000b005a7ab51af5cmr4673683ywb.13.1696967028753; - Tue, 10 Oct 2023 12:43:48 -0700 (PDT) -ARC-Seal: i=1; a=rsa-sha256; t=1696967028; cv=none; - d=google.com; s=arc-20160816; - b=r2caNqB+Tqis40axvQ+9WATqElkSRMoLieRYBHHeoHlF3b5cTf4S5iBEzrihGSExv3 - hTEtPaFCXEplKGQn8+XVgqjAct61mkAYzHxflnaC1pgkd1CYbkt4zyNJEIW7qb+AIMSL - 1DdnLEuU9sb2oZNfbHyXMQaqXe6sEW6sZQDp6BZJHV0YsOAFhlRiacomh65Oq/DfY1P2 - Dvy9wahx+Qki20kIAfzR/TKuAx5z9IUwaOshdQuWH8i6HFjC8MRO0RwGVUb5ZMkRZFu7 - c4Sx/r9SfTiI4zsos0PvnaOvdNBXg2SPDMNYp0c/sFbngRVHuNK5WPE86v3vHnMi8Gmy - pmkQ== -ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; - h=to:subject:message-id:date:from:mime-version:dkim-signature; - bh=dH2d6q5VcS+7rfJUaWYK0fSFe6OjBSMp9T98v8goAXc=; - fh=AKWw92sdXoMEDdHXKLL06vnizTpObKPGCfYXnoQDKO8=; - b=C3ka6pwtIk5/XPtFgf/FbwOaJx7hdOxBOXAmkHKs/h6WtxIHmo65elkM6NsLK0fPKL - lzfD9jwUmfFTKto1p2dbsqQ3RSlNHsgvAQq60jv7NiwbSFRF8tV8V49waE5rwLGj+egO - CoYGPGYEwxtXsDC4jUFMevFH7xEArXp1Lb+pRTkuejQwGghyXQr0Quo6Dgv8ztrjE6+e - URqviuUsFNCFqHnPAgeyAQ+yrllq/as6SPZSky6UG42xkzktlobE3Yea08pLY0OL8UHK - 1WHVJbT5DFhIyZ+gCtkMQ3weEXl5rL1IWuuv1W1GeXZFv7rwzvPOE1OzyK33ZL4eWSXF - 2Clw== +Delivered-To: suegamisora@gmail.com +Received: by 2002:a05:7010:2284:b0:415:a8ba:b98c with SMTP id r4csp1027504mdg; + Fri, 25 Oct 2024 07:21:53 -0700 (PDT) +X-Received: by 2002:a05:6a21:4d8a:b0:1d7:109f:cac4 with SMTP id adf61e73a8af0-1d98882f108mr10434238637.3.1729866113075; + Fri, 25 Oct 2024 07:21:53 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1729866113; cv=none; + d=google.com; s=arc-20240605; + b=J4270JJKKC8AN5dsp13tVApYO4Gqrz1LnxNmDaytR/v/UTiqe11AuBiDHx7hV8zw2R + B3eTltyLM1bcfo9FmefoQcZbegNmk4FxViNoe88v1POnvlKE8229wp5i4O1ZrwGZwSLL + tavGEprlBSJPKZcBk/+C1mkeQXMJL+ZeloOc0kvnTpimq1RwWWtaGceslWKw/ilqSRGx + HAQEaykFyO8KzsHsgw2V/i8JE/6S5v6cIiettVqrEuRIj+hrnfdOvM12EVbjhtkp0Fmg + PEFemCSIHRYJRhB2uFoxjLkqjB/rTVuZMXELqR38r5fHRhsHILAqWWaIYuSmtGSk/imZ + M5Fg== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; + h=subject:to:from:mime-version:date:message-id:dkim-signature; + bh=O8D9QG6lml0dQlPVnHJ2HX1q6V3Qlql+zuCo5zC0XG4=; + fh=r9ZW45D/4i7BIl/4UeFGrkYKwbplztqhOVKfbV+WD3I=; + b=bk+5eU9r/+D/5Vxpw6DWPrCOmxe0IKWcjjGwDDqmHRmsLEFt7818DegOOqjxix8rQl + 25O/XBja4OX7V4N37Tr1oLPpG82GFcXjcs46XfxOX0lxuHXpzRf93DR7IbnEcNHaNoxJ + +QVwM237RyFpV/KBl/H4uZ2inwc5OKgp3QxJ3aCsjPD+CD5grcokDC2RHtppi7N+vtYv + ASLBW5/uCrpBJuvIn/7xZZRyrKwkaZisBjbL5rJr5Fh64kFHJ57rkXKk1CikyDzFZ+Z/ + 9XALIrX+TK1uJeXptY1OpyNMdh2Fc7lv0OQFxo8pHz3WgYUpQzjTJeSnkFIY0mHsbQP5 + 215w==; + dara=google.com ARC-Authentication-Results: i=1; mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b="GO/VW+4p"; - spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; - dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com -Return-Path: + dkim=pass header.i=@gmail.com header.s=20230601 header.b=d8VQVFp4; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com +Return-Path: Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) - by mx.google.com with SMTPS id i200-20020a8191d1000000b00586a708c858sor6327710ywg.12.2023.10.10.12.43.48 - for + by mx.google.com with SMTPS id 41be03b00d2f7-7edc75c3287sor751909a12.5.2024.10.25.07.21.52 + for (Google Transport Security); - Tue, 10 Oct 2023 12:43:48 -0700 (PDT) -Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; + Fri, 25 Oct 2024 07:21:53 -0700 (PDT) +Received-SPF: pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; Authentication-Results: mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b="GO/VW+4p"; - spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; - dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com + dkim=pass header.i=@gmail.com header.s=20230601 header.b=d8VQVFp4; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20230601; t=1696967028; x=1697571828; dara=google.com; - h=to:subject:message-id:date:from:mime-version:from:to:cc:subject + d=gmail.com; s=20230601; t=1729866112; x=1730470912; dara=google.com; + h=subject:to:from:mime-version:date:message-id:from:to:cc:subject :date:message-id:reply-to; - bh=dH2d6q5VcS+7rfJUaWYK0fSFe6OjBSMp9T98v8goAXc=; - b=GO/VW+4pWlcPLz1OwBRtCcm/kaXWkMLFDByoke7dUKuKtScGtcpOfEOlc7LS26pRSn - G0KnZ6BH5SNcrx2uFXM/hPZi3OHdTBwGJ9Z3T5wmr94CY3+9JrrgjbXKv+3wCO9Xeqe2 - U7BE8fm2PeDR1oyxv1mufUqM7MDv/EZ6ZJXNw1w47SDu0jEtBfe44W/tsQGxgCziMzSQ - 2ziwXcCDoenkL0Wxq72g1Cab4o3gbBU19VCEtBWvkONhSTVN9lQuyIajNAmsD68OJwEe - TL9TWOzDeP5v37VQNVIQLN6fIUx8tjx2iH4+DMJPvRMzVZ+0MbuvcYLr8915xDjz7jjO - DK2A== + bh=O8D9QG6lml0dQlPVnHJ2HX1q6V3Qlql+zuCo5zC0XG4=; + b=d8VQVFp4FbfQcVh3uZQ8kdJhwH7r8Lnluo5bluM/LxCkI6I3cNiKwUVivh5UcIiwFo + gHARXkXwFhig6MzfT1uLHQFqgCwMEE4M9Y/Bt+gMX9R8CsZl5HoHY1KiUM539gnRLCOa + +m/ShGPaRuBP2spV7ORzkAJTAqQ+GKTunq+lM4LruzzrZl4f7txMtrhdKL157BNHKyMw + tHWZlMSFgbJiP3tsv+0VeWAiHOQxt9uR/I2UWpmDhJmyUm2JVtHNGVLvjayT/tN80FMi + zRBjcgY/L56+h+Ia8iUBUzJM29IW9npJqerQlMPO3vQ700g1qU1YRYlZJ6fmzWjk5NMq + muUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20230601; t=1696967028; x=1697571828; - h=to:subject:message-id:date:from:mime-version:x-gm-message-state + d=1e100.net; s=20230601; t=1729866112; x=1730470912; + h=subject:to:from:mime-version:date:message-id:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; - bh=dH2d6q5VcS+7rfJUaWYK0fSFe6OjBSMp9T98v8goAXc=; - b=kLGz1m3GUfobNymbK3/DSTvJXAoppFTs4fRqRZd77TK9CkxPQe025/3PQAVhU2YW58 - r0Jk6MAhFcN/n15MPXdjVBT6eqC3sCmYhBR9n6RmX7vp2pEius50Lty64Q/eUj2cFH+t - CUNs6ctISm65/agHRNvt6no8XgzFr3Ma4KgfMhhzxcIK2bopoW90LfUmyKZFXSlaBVbm - KVQXbAC0NN/2DtYUykJTQJ2Ze0Cu9P1TxcyZZHpaSed7gz71fO4u/W8CXpslwOJfSfXl - VyiCQ1v8exrM+Q8WEmiGdqLTqZfTK6VcG2w7kmDG+ZhbXA2IRDsUw/j0h868878UaFNO - UPuQ== -X-Gm-Message-State: AOJu0YxbWTRDE1w3F70lfb2Bb828Alj1VEuoPi9QDhiWl/m63ILSpyXh - BV+ZKjoFknfARLzERgxd6gE8y/UYCBk+pUGDeB5KmATJ -X-Google-Smtp-Source: AGHT+IEeri9J0dpOppDay4cMM7UxoTbvoPvlULY8a5bikCTsqVXU2KmrxMjfyr+vW9S33WH/2w7ouMrZKF3lk6KAyCQ= -X-Received: by 2002:a81:ac42:0:b0:5a7:acae:3bb0 with SMTP id - z2-20020a81ac42000000b005a7acae3bb0mr4382907ywj.5.1696967028246; Tue, 10 Oct - 2023 12:43:48 -0700 (PDT) + bh=O8D9QG6lml0dQlPVnHJ2HX1q6V3Qlql+zuCo5zC0XG4=; + b=jF/N/1JFMN3lYPY+U3yV69aYOBQh8JJbg+lMPnbhW2YBpEy7SZJzTlo1CMqFi7oCko + AqRN558Hxf6jOlb8SyV63aQ7pRqpiMkLuOT17FFZzINDGyHtRrbEMktnrdJ00nEiKDaG + pRMVlZbJdYyWr3XoZ1ukAY4wsx4mWliolKKojV0k2t8nEFx2thL7Bq32E3bDOkIGvVpr + SXXGYaph5JMiOZ/5kFG/WJ0SgehCqpOSVsfVARP2N85ftQ71etAW10F1hubq1McDxcp7 + nXyzDBX/vFPE2fsKNs0Lp8wP5VmNXaUuWYQcrpamxCDrFY1TorR+obSJP+Tx7yVGNHTu + AICQ== +X-Gm-Message-State: AOJu0YxU4AXOMzl9OECxkRs0yyZNifte4MaQ4nWo6CD5oKn2GIFcSLnX + KySDJF8rL8EclKLvIlUcEt25sZBpGgImMrBtE+gxWsvJZCm+qONHRA9R+Hw7 +X-Google-Smtp-Source: AGHT+IGWoETv1mjfZshi2JICdojFxzSHiXXPewdG+O0ghimcnPg4uRQC6i7GJ20miAeXVOMTYxG5VA== +X-Received: by 2002:a05:6a21:4d8a:b0:1d7:109f:cac4 with SMTP id adf61e73a8af0-1d98882f108mr10434156637.3.1729866112282; + Fri, 25 Oct 2024 07:21:52 -0700 (PDT) +Return-Path: +Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ([93.118.43.168]) + by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-72057931921sm1107829b3a.66.2024.10.25.07.21.50 + for + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Fri, 25 Oct 2024 07:21:51 -0700 (PDT) +Message-ID: <671ba97f.050a0220.10ba01.45af@mx.google.com> +Date: Fri, 25 Oct 2024 07:21:51 -0700 (PDT) +Content-Type: multipart/alternative; boundary="===============3475748289687066030==" MIME-Version: 1.0 -From: =?UTF-8?B?5pyr56We5aWP5a6Z?= -Date: Wed, 11 Oct 2023 04:43:37 +0900 -Message-ID: -Subject: Send 1 ETH to bob@example.com -To: emailwallet.relayer@gmail.com -Content-Type: multipart/alternative; boundary="000000000000ea0b6c060761ec19" +From: "Alice" +To: suegamisora@gmail.com +Subject: [Reply Needed] Test Email 4 ---000000000000ea0b6c060761ec19 -Content-Type: text/plain; charset="UTF-8" - - - ---000000000000ea0b6c060761ec19 -Content-Type: text/html; charset="UTF-8" +--===============3475748289687066030== +Content-Type: text/html; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit -

---000000000000ea0b6c060761ec19-- + + +

Hello!

+

This is a test email with a basic HTML body.

+
Send 1 ETH to bob@example.com code 01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76
+

Thank you!

+ + + +--===============3475748289687066030==-- diff --git a/packages/circuits/tests/emails/email_auth_test5.eml b/packages/circuits/tests/emails/email_auth_test5.eml index 9fa5791b..433b64ec 100644 --- a/packages/circuits/tests/emails/email_auth_test5.eml +++ b/packages/circuits/tests/emails/email_auth_test5.eml @@ -1,87 +1,98 @@ -Delivered-To: emailwallet.relayer@gmail.com -Received: by 2002:a05:7109:6e90:b0:36d:793d:603 with SMTP id jg16csp154586gdc; - Tue, 13 Feb 2024 15:16:32 -0800 (PST) -X-Received: by 2002:a05:6902:513:b0:dca:c369:fac8 with SMTP id x19-20020a056902051300b00dcac369fac8mr531909ybs.1.1707866192552; - Tue, 13 Feb 2024 15:16:32 -0800 (PST) -ARC-Seal: i=1; a=rsa-sha256; t=1707866192; cv=none; - d=google.com; s=arc-20160816; - b=xgkYZBTJAlHk2Blzhp1MXYjDKpicXKjvQ8zaZA9BYkHjWuePzG3QSIR6MUgwszHp2N - Fz1cjRZ2+TsPsJLpCQ7Gdk3d5exxf85WfY1X0vPcCx+q+9xKHeJVKT8dh8bD8ZdNSaiK - N7OWwLsnAOamSN9kHG10/0h4EP3/ikuuH9/DNUqwNr+K+kUcp5tI5Ns6B/PULIGAxFQc - Yh43AzVSmcpbUpyZdSdxHg7uylAtFzwTb4FrCgTb7fyngC66EcQ8/vZGrmYboFXFA31W - WmbktdQRkmxZ8jGP560SDnkHr/aN209YYISC/w5pKDoHKp9uZMETx77WJvfzSTRWYeEm - KnRw== -ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; - h=to:subject:message-id:date:from:mime-version:dkim-signature; - bh=jrYxFJzQ6WxiZb/FBt9TVNuNlG27A2NoDr49B4lA+ZU=; - fh=AKWw92sdXoMEDdHXKLL06vnizTpObKPGCfYXnoQDKO8=; - b=NQUxVT/V866NNXN6CZBeb+X6XSm8e5RSXQ/oZ8dRnfl3WIEo9hZy87JU0ag0l+78g/ - MHzhcdQ3P0y0tPc55dR0FHIgCuUnFrrp9FOXnSqBTbYpXsH8dt5DxD9cpAJ2JcSp3G7f - rhtJdLq7yQmStIMiuaMxhs8jx8Z7+s/uWp7xTjZ+sBsG00dAhVa77Z0xkpUBIaXnbSbD - AsBIdFaiIEeNhtLZnY8fmyM8Zr46EAmPWfBFpBCPAKaregDLkhQPqxp+6VUzmP+4us4Q - pTwRWCR3O9t9QyjiV+Pa6//uSlyHKI8Hl3VmQiTUYsvSoweJdu5C00n5JieRMgAv/o5T - IfTQ==; +Delivered-To: suegamisora@gmail.com +Received: by 2002:a05:7010:2284:b0:415:a8ba:b98c with SMTP id r4csp1027898mdg; + Fri, 25 Oct 2024 07:22:27 -0700 (PDT) +X-Received: by 2002:a05:6e02:1c0a:b0:3a2:7651:9846 with SMTP id e9e14a558f8ab-3a4de7a35e4mr76681065ab.13.1729866147071; + Fri, 25 Oct 2024 07:22:27 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1729866147; cv=none; + d=google.com; s=arc-20240605; + b=X+KHpla/YYvO5+FQVKEeEwgrxYSL8LFzV7y/PGRZCyuTnZvjgTBzajAN3hZmrUcKdl + 8nGlxyXfWD1OhXZ/NEmiRVVMU4SrfjJ0Rhi66cqJ7hZE7fNaqQYFT+ZY3obuwdBSix1W + 9B0bzknV36nU14IQmd9nPSrpOzv5yBuSbpbnA5NAfyURUMhn5lky4b7kZreMTx6jV1iL + zr1F5F5Otshz9mBrD2fVzbpW8r3RmWFY9b0tk4JfM8m9geM1dtloXEBn24Qo0czaynbi + wPkQ1lhpBA0GhrRO/A4Ym0JxaFkSTi+XxRHFriClE29Al2MpRsn5ygOZ5mswI1QurVaN + EXSQ== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; + h=subject:to:from:mime-version:date:message-id:dkim-signature; + bh=6HItyPXrtmMM6i7cBA3Fnz+dvPzXNQf0ncXRv4X+xTs=; + fh=r9ZW45D/4i7BIl/4UeFGrkYKwbplztqhOVKfbV+WD3I=; + b=EjLz+LeWtLYDOEj/PhsIc2pbzCN/qq2EnrtagCyagUNXcoSoskq9ZxSa4QuMNO5BUy + 0ZC9wDmoqjwYqxhvzr2gLMQ/c02CqcUGZ6zzPYX/RQcAb/h1ltCMIAuaprvOY1LWt1w/ + 8YJlXZhpfWd9VAcDdU7WSq5EBYYLhcA71EP/I+6kJyHHureg7cxhb/jEWhkU9330pRLR + 6F1VN9jLEEsIZHW4laUz6SRjzXRBPz5Vmm1i60tQvaw2p5ubZKXnryvFVGwKaWK22JJx + 9ix9VyZbzJwaY+5O4sM/zQQbG1l4r4HOlfgqiIh8o31NjmynGAsrSwwBIDvEy0E3xRsJ + i7rQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b="h1U/KtaQ"; - spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; - dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com -Return-Path: + dkim=pass header.i=@gmail.com header.s=20230601 header.b=Wpa+lApl; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com +Return-Path: Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) - by mx.google.com with SMTPS id z127-20020a253385000000b00dc6b9629f4bsor3320137ybz.19.2024.02.13.15.16.32 - for + by mx.google.com with SMTPS id 41be03b00d2f7-7edc8bf823esor611123a12.7.2024.10.25.07.22.26 + for (Google Transport Security); - Tue, 13 Feb 2024 15:16:32 -0800 (PST) -Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; + Fri, 25 Oct 2024 07:22:27 -0700 (PDT) +Received-SPF: pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; Authentication-Results: mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b="h1U/KtaQ"; - spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; - dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com + dkim=pass header.i=@gmail.com header.s=20230601 header.b=Wpa+lApl; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20230601; t=1707866192; x=1708470992; dara=google.com; - h=to:subject:message-id:date:from:mime-version:from:to:cc:subject + d=gmail.com; s=20230601; t=1729866146; x=1730470946; dara=google.com; + h=subject:to:from:mime-version:date:message-id:from:to:cc:subject :date:message-id:reply-to; - bh=jrYxFJzQ6WxiZb/FBt9TVNuNlG27A2NoDr49B4lA+ZU=; - b=h1U/KtaQD2q8O/pFPyBDxp8a/kwcvupwRCAU7fVBGbTC4RNG/YjuHEraMJhhgxm/qv - O8jlW06L6nBrgFlqw9tb7weX+xJjMWaI30iKrn+g+tO83joydWcaRqS0VpF0cYTfW60I - /WYnTl3q4ybt+yrNOV25BprKSLRzsfmUCZ6kii4zFvqwtvPRP5Vrbnrb6FPuVwNMtQHv - loOhNlgbGyd8RcTJjBa9rvJWC32nl9gDo6gpW9lxXZqb7jqV09XcBjHsTgG5u7pXWQYX - AVpviKSJS+dI4mKN8gDLVbzNr1tB0eY2EROjnmH36zNLNTu1TGys6QBgdVGsra7DIuqa - W4eQ== + bh=6HItyPXrtmMM6i7cBA3Fnz+dvPzXNQf0ncXRv4X+xTs=; + b=Wpa+lAplCI3vmlsiHpZ0sCGkB2yDjzqZPQrWsBP5cXK+YUlAqBsDerRI9wd3RcPY2H + EnOj6ZG/05VeThctryNBXm+40PI3/Z14nDctCAuIONkn8/8pCIOllj7FNX/rKW+F5j8s + aILJS4pHx9O2GFTsZVL4AniAR1Fyl7Z+emcU/F3PijAU3mgA9AiLu8SoDndPqPgGBqqQ + BF4GNDhJFv/fGqMtPLvicaumITXHz8QqHqCy142wqxP6zuc9jb5nFbZPA9M2pcHesM/1 + 3rGpFjk00Tq/B7r/KE8d2LppKXU22X/gaYTmZ+1EWBLvKdV0m+D664K/CtdtD6vo1asg + qbOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20230601; t=1707866192; x=1708470992; - h=to:subject:message-id:date:from:mime-version:x-gm-message-state + d=1e100.net; s=20230601; t=1729866146; x=1730470946; + h=subject:to:from:mime-version:date:message-id:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; - bh=jrYxFJzQ6WxiZb/FBt9TVNuNlG27A2NoDr49B4lA+ZU=; - b=S+VasXOuITIhUuebNUWaFGFT/UxrkRQhJOkLypuiyuJ6be09oHt/Xy9vfTNbLXAWAV - P9McoaaCw4sFbT4cqzNegbAFXy04EhshA4PrFjsNIHXK7QLQSGnveoFJ5lT+AufXG33f - PlfEpxv/VqIMls6s/z1otGqOtcyn8TAkTob2FnQrLyNhZZeTbyxtiK3dWFMlxD8r+A7k - IKpLozSif102Nfzmmj/Zi1WHlbscv5fTidxGAn1n7FYenFKJ6acqc7qs7jlJfK6ajjGD - VCB2ujSlvCcxoRp5GEJGywJd57LfLQrJlyBjuX+yd/3ejc9s/sWqzrpkNgtrKRYI7PEi - sSpA== -X-Gm-Message-State: AOJu0YzlHB0Ob5AJMbKmNN70Kwv+o4+d1r5aUQBYTDVmqPwoEX3mel/p - zgMMeG65Q+p5zj45ZyrUsI7UglfqtLXU/MdzzzpSiQQuQbEUzfMQzv+5og4He9CPNodovAfSKZ3 - B+PrRXw9ADbnDZmUfDks2kPs0wHoCI85b0HO7Lw== -X-Google-Smtp-Source: AGHT+IEn4n432lSRAbrl1I6OJWe5HZ13UMYAJJVv70tvwsMv3nSutjkaf0yxtN0rOA8WwskFFptX7hVjkTKvEGCZiIY= -X-Received: by 2002:a25:830f:0:b0:dc6:ff32:aae2 with SMTP id - s15-20020a25830f000000b00dc6ff32aae2mr443891ybk.63.1707866191956; Tue, 13 Feb - 2024 15:16:31 -0800 (PST) + bh=6HItyPXrtmMM6i7cBA3Fnz+dvPzXNQf0ncXRv4X+xTs=; + b=hiASFhPhxHXnaFrpXQw+tFPMBBX2qL1vY0YedaiztTnkdZ4nHLolZ9BD343lPrK6vr + Ed6JUX3hSKGk8bY8EYDxga22C/f0FeddwgWVS18wolsjHiPj6o4ilC3/y2ANVblT8rSX + hxXnOUi/Nj9chizOg+IUWIJRVksom8rGdLzPaMARvUHpRYQGwH43n++rXJrua15MUgtx + 1ibfT6VA72eFnKkrnEM8C2lI9Hx8E/Iil1+5TbyeJAUKQuX/uugpfSCV0mzMjlxQWYEV + FNPAY6zhMpFIVlnOu8SuIN8YS5G8Hs+AwlkdkdZeuXKZ5HANF4HXeJH7kuE0ltIzwD70 + rkpA== +X-Gm-Message-State: AOJu0YxBDr1bn7JXBdoZ/gGWykjgCVmmXoyFSlkFYb4ZV3a49lmSoQb/ + +HJxAukMq5F4RFzTQyaG4lzq+JKM0xLmOHcvKilxud5GK91oIAuaBnQ6HvGu +X-Google-Smtp-Source: AGHT+IGa25bEz/UR0PTxQUZSxs8Kd7BRfJdpsVjyhvmM8qNbwgZQk0EBmMVUjMco1V9JTtoO5RNyQA== +X-Received: by 2002:a05:6a21:e90:b0:1d5:14ff:a153 with SMTP id adf61e73a8af0-1d989a777demr6740320637.12.1729866146301; + Fri, 25 Oct 2024 07:22:26 -0700 (PDT) +Return-Path: +Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ([93.118.43.168]) + by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7205780e3f5sm1117929b3a.0.2024.10.25.07.22.24 + for + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Fri, 25 Oct 2024 07:22:25 -0700 (PDT) +Message-ID: <671ba9a1.050a0220.775c9.43a8@mx.google.com> +Date: Fri, 25 Oct 2024 07:22:25 -0700 (PDT) +Content-Type: multipart/alternative; boundary="===============7169662076175162728==" MIME-Version: 1.0 -From: Sora Suegami -Date: Wed, 14 Feb 2024 08:16:20 +0900 -Message-ID: -Subject: Send 0.12 ETH to alice@gmail.com code 01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76 -To: emailwallet.relayer@gmail.com -Content-Type: multipart/alternative; boundary="000000000000b20eda06114b95b1" +From: "Alice" +To: suegamisora@gmail.com +Subject: [Reply Needed] Test Email 5 ---000000000000b20eda06114b95b1 -Content-Type: text/plain; charset="UTF-8" - - - ---000000000000b20eda06114b95b1 -Content-Type: text/html; charset="UTF-8" +--===============7169662076175162728== +Content-Type: text/html; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit -

---000000000000b20eda06114b95b1-- + + +

Hello!

+

This is a test email with a basic HTML body.

+
Accept guardian request for 0x04884491560f38342C56E26BDD0fEAbb68E2d2FC Code 01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76
+

Thank you!

+ + + +--===============7169662076175162728==-- diff --git a/packages/circuits/tests/emails/email_auth_test6.eml b/packages/circuits/tests/emails/email_auth_test6.eml index 7b772af9..86bacc90 100644 --- a/packages/circuits/tests/emails/email_auth_test6.eml +++ b/packages/circuits/tests/emails/email_auth_test6.eml @@ -1,88 +1,98 @@ -Delivered-To: emailwallet.relayer@gmail.com -Received: by 2002:a05:7108:c04:b0:37a:44d1:e2d0 with SMTP id pl4csp3207896gdb; - Mon, 1 Apr 2024 10:21:20 -0700 (PDT) -X-Received: by 2002:a25:3a04:0:b0:dcb:aa26:50fe with SMTP id h4-20020a253a04000000b00dcbaa2650femr7983649yba.15.1711992080732; - Mon, 01 Apr 2024 10:21:20 -0700 (PDT) -ARC-Seal: i=1; a=rsa-sha256; t=1711992080; cv=none; - d=google.com; s=arc-20160816; - b=lriX+ZifwQ86IJZVArSx4+eGUcgeO31gOURsw64kSjQL48i2EpDDNHvLcl5vlEDF1k - RgQRUWnn080ZywAs+pwDcWFAHrP8XjHGz9z2N1H8I9LIQhTRcXRWgjZPORsf8gQ49oJM - 3pQWQEJARJ7TtDRLCWHNivXxrlOMGoubiv8YNCrT7FsE46OFZ4NDaqCCQebLF//XK/Kl - 616A6OtD7FDyd01nA807wra6pw3p7MBF0ACv655a7A8arlowqqtnuCD42I7/cysjMKt+ - RR3jIYICBT0PpxLCIXstkfqe2E0SPnLh936Cr0DwHj6+gHbxNIQbAu/I/lOjSd1TTtqA - 7aOg== -ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; - h=to:subject:message-id:date:from:mime-version:dkim-signature; - bh=aiM3ezBakDUzQO5qyB4uxVZuP7h9gh60LHvohxTHYSE=; - fh=AKWw92sdXoMEDdHXKLL06vnizTpObKPGCfYXnoQDKO8=; - b=wh60ywiB4oGfp4+N6degtlgMSqfqex/22YbG3XwEUcuY9bAapSOf4n1sVNHG+9PavK - N6nHd5ozTxc/H0/ItjfYqHQ6M6RGylCZrUMOBj5yAkpWJmK33eSZ5no7f9V7ASswF9Qg - J6atB98qe7IgSs/OBLG1hy0zX0NBCx6pUNwXaQvSTQwbajtIoHgpQrl8EIJ8Br8AtdX4 - 9r8ZwlpOx2yEx/xqb+lz+f6MNoyz3P7IzMu75vSvaCAhvf5sJ8ek6wb3xbAg52MgqeVf - M3EzWmun9+yj6yeW066/5B/0E7uFKIXcR1bByz8LZSdfAs0VuYfzKtjhjSksKhH3Lghh - p1Lw==; +Delivered-To: suegamisora@gmail.com +Received: by 2002:a05:7010:2284:b0:415:a8ba:b98c with SMTP id r4csp1028717mdg; + Fri, 25 Oct 2024 07:23:34 -0700 (PDT) +X-Received: by 2002:a17:902:e5c6:b0:20c:5bf8:bd6e with SMTP id d9443c01a7336-20fb9aca160mr62348705ad.48.1729866214624; + Fri, 25 Oct 2024 07:23:34 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1729866214; cv=none; + d=google.com; s=arc-20240605; + b=UiY4Io8oOE7tVEFdLzehTudTY2WEV7a655LYJe/3zqGX1FQ1oLf82DgL4S9CP014Nx + RDY5Js7G3fRRkRpg+DAn94YJAvwMz4lQk+Ld8GGyOPUugzsgnIdzgCYtlo3hnw/wQgPm + F0nXIjvSyvOORNdfdKjnjPjW+HXK20sGnRCcIy99fsP8m4mTKOuK0+/aRzt57Hi6d4TJ + 6IOb5s1DJcyz20EehPaKsaY28OonW8ltL8Iyjd/IV63f81FFVUsWePNWjrqIdGQZjGGF + NQGsp9RRmSNkVnWYyDTwtkfEHtecvguOu2gTFNCo8l9URIroVMH/AQ/33kdFbomkk56l + wO5w== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; + h=subject:to:from:mime-version:date:message-id:dkim-signature; + bh=ln4eYrH1D79U8QvoIL3DxbustLn71hXsB2AuFftFFfI=; + fh=r9ZW45D/4i7BIl/4UeFGrkYKwbplztqhOVKfbV+WD3I=; + b=RgmHDmpqd2IVTsbocs+ipvbo9dmMt6e8+n6cn8AklhLk2VhPKakkaUkVQ+MByNQifj + Yh+24XF3LCSdAJZUtuljWPC0HNKGwApAxtwrTWQNMawhafXPODTjf5OKxqtBabivJ4li + oeCHaC0hiYpC7G19ddqRhAd62QUfDXSUD8wuw440sFVDv2AaAN6YWSA9DgeoJ20KE5hf + 17/CyiOBgTjM69WMNJBX7XxHRKChJ1z7ZoLHOJ1ib+mJpgPpKKmROhIX7ck6vXy9KzYH + QnZu/WjV69eDepmDFD1/I1j13Rm+5I1ZSnL0LD6Yin4ugZTI7bXVRRzy25WHho+m51Nj + sFfg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=KVPCp6Yj; - spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; - dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com -Return-Path: + dkim=pass header.i=@gmail.com header.s=20230601 header.b="KrvSftF/"; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com +Return-Path: Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) - by mx.google.com with SMTPS id r62-20020a252b41000000b00dcc1f1be907sor4483162ybr.16.2024.04.01.10.21.20 - for + by mx.google.com with SMTPS id d9443c01a7336-210bc21b215sor9335105ad.20.2024.10.25.07.23.34 + for (Google Transport Security); - Mon, 01 Apr 2024 10:21:20 -0700 (PDT) -Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; + Fri, 25 Oct 2024 07:23:34 -0700 (PDT) +Received-SPF: pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; Authentication-Results: mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=KVPCp6Yj; - spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; - dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com + dkim=pass header.i=@gmail.com header.s=20230601 header.b="KrvSftF/"; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20230601; t=1711992080; x=1712596880; dara=google.com; - h=to:subject:message-id:date:from:mime-version:from:to:cc:subject + d=gmail.com; s=20230601; t=1729866214; x=1730471014; dara=google.com; + h=subject:to:from:mime-version:date:message-id:from:to:cc:subject :date:message-id:reply-to; - bh=aiM3ezBakDUzQO5qyB4uxVZuP7h9gh60LHvohxTHYSE=; - b=KVPCp6YjrUEelwchvP664IdNxEsqrTf7EWvO0Qg1QxVaWP5xZeow1dtYDo8gWjGfop - 9vtAHc9G7Lvtmnk7MtU2AKeqav7wdKY8gVNFL2qI+sV+EdqfVjHh5/VZaSDRUtjAxfN+ - w2X6iJ5nQbVaWhSaQ3Pe7KVBFz0Hzr5IUc9OZ6qAopinCQi8x5NnqsdMPFuwlvpz9bKi - Y7hGAe4Vm6FUjnqGOwCxR/N74MxBZnIso68OGBY96Z4k3PL7lwT4ni7JbS7PnLa1Q9rA - PnYP9qijNBwGj30SL7NhBhRGt5t+yCWY43ObhPT/dtFoRSDytZxkYx4ycE4zWS2wIJ1B - 0qVg== + bh=ln4eYrH1D79U8QvoIL3DxbustLn71hXsB2AuFftFFfI=; + b=KrvSftF/Dhz3uF5pai+VwDkm+s04/mHB4/y8af0gUcXt3r+hZ1AcNfQA9VhSklQQT7 + fqdXed617Z5dMLKouLp4cWNYxrVBZkZD9udPyGaqEO7Fa1zidf9UzNkAikmWPTUbfPjh + lypVOIFwkmfX1dILxoo5nmIy26CIIV3ym6a6wKpXbJ/Gou80K3a22kDKM7lBOUFWX7Zv + pFDr5zFRIK/nbA2EaM9TW8tBjNpF4W1T8AVir6Da72782Bf4aa9bB9jAq7xahKq3BFjr + 7Bjea+2bGNh6gHrAU7I2Rh8bY3fV+Vmn37dzsAxKrdESWnVGup2Gndba4+3hIFl3PoeL + w3Mg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20230601; t=1711992080; x=1712596880; - h=to:subject:message-id:date:from:mime-version:x-gm-message-state + d=1e100.net; s=20230601; t=1729866214; x=1730471014; + h=subject:to:from:mime-version:date:message-id:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; - bh=aiM3ezBakDUzQO5qyB4uxVZuP7h9gh60LHvohxTHYSE=; - b=nt3FeKKHrH/hQ20gRvNFSRcw05JEHvjZyHpAxFfJGVPLMQLnT4OVZQffnqdDcadCSR - OaW4ZgR2yCdpLjJKwdiap5oFrPHPR+y/mA//mg+aCajGO8zt5CHDmc4ZZJWi+l5CpqDC - el8fOw0L2Hby0072I/mv4m/LD5pMH6aJzuKyCCyzD5KRJ9C3ngupIvZavrUAd2FiRGQF - U4g0/r/o8HLlV2fxNMPf3B6eDj2qZ7zYSQ0g0LYrLFfcbJNjm1V4rHyivXlbPKX5zmuL - 7UX8ePvS9WCXvYyEN/29L2HjdmssHscQcqYXXZ52LTpG3MMR1heWEi95x3+OafmSKWuB - e9fg== -X-Gm-Message-State: AOJu0YyL8Dr3XsXJIhymf6UhvXt4XTqXtXy/bmeVAXr+QUd6kzZMCmri - zhuxk4GSgbr0aBzla/7DAaBy6jc83DNEZTT3lJqqRbhOLfL14I4JpJ/2TOE8YlVjoly86yUCS0/ - T5a4+CiylmaHgG5dN1JbwmhgJ6JGAu6+c -X-Google-Smtp-Source: AGHT+IEVDNl9HlNqHqacvrnuQFWcEBTbheIMe06bJxH8fg2xlolVV9IVpaX7yCMmN/GC/2+kAuKJiZTUSXuC8mniFAs= -X-Received: by 2002:a25:ba47:0:b0:dda:aace:9665 with SMTP id - z7-20020a25ba47000000b00ddaaace9665mr7381032ybj.60.1711992080046; Mon, 01 Apr - 2024 10:21:20 -0700 (PDT) + bh=ln4eYrH1D79U8QvoIL3DxbustLn71hXsB2AuFftFFfI=; + b=GbYMbCsI400YqSo9jFm64o3pAXE79gvCO4Xk/4lSaryBB6hoLX+UitkyIyfI3lEJeC + bgi1C2Q+g6P6XK2HsAXpqDk264VnSyVQnzYcXHaVxzRYy4hUSdmtEVtFoya2bA1nrQFS + fOpPbm9Lqhh4Fg0+Dgh6ceh9ffe1iPkUgofPs2B46nTczIePZUR8E1slpt5R6tmWvQsM + tCY+aVcv80VmqYjoJgB5scyIWB+i7nLuu2VTDiMG9vk3d98Je7Wp00/vVWTesTl6wdeF + iBefyUY/CE+lesOXEFhVETYsmAgrMcfbAi9fHZOJCCcsYeLVzZSRp5f1VP9D52Rs7sAO + 7alw== +X-Gm-Message-State: AOJu0YzuLjl1RGUCa2R1WsTfXaybN/EiJ8Mp2JRelbD+xCQUqNgCsb18 + fjjuEO6cjigEs7Uvj2+yPOoqMRdBaa9k38sUutW4sMdMwuvcwFsHpBdEgoDY +X-Google-Smtp-Source: AGHT+IE5RKClLLsWii0Zz4+IpZAI9TLY8eOHXMXBiXmGYJjiLW0dMyOGP6+PclgFy5UVSWP/oiBOcQ== +X-Received: by 2002:a17:902:e883:b0:20c:d578:d72d with SMTP id d9443c01a7336-20fb98f1eb7mr80402645ad.7.1729866213877; + Fri, 25 Oct 2024 07:23:33 -0700 (PDT) +Return-Path: +Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ([93.118.43.168]) + by smtp.gmail.com with ESMTPSA id d9443c01a7336-210bc02ecdesm9892885ad.206.2024.10.25.07.23.31 + for + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Fri, 25 Oct 2024 07:23:33 -0700 (PDT) +Message-ID: <671ba9e5.170a0220.2e7f0.3d9a@mx.google.com> +Date: Fri, 25 Oct 2024 07:23:33 -0700 (PDT) +Content-Type: multipart/alternative; boundary="===============1589864651930508876==" MIME-Version: 1.0 -From: Sora Suegami -Date: Tue, 2 Apr 2024 02:21:08 +0900 -Message-ID: -Subject: Re: Accept guardian request for 0x04884491560f38342C56E26BDD0fEAbb68E2d2FC - code 01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76 -To: emailwallet.relayer@gmail.com -Content-Type: multipart/alternative; boundary="000000000000ca220006150c3707" +From: "Alice" +To: suegamisora@gmail.com +Subject: Re: [Reply Needed] Test Email 6 ---000000000000ca220006150c3707 -Content-Type: text/plain; charset="UTF-8" - - - ---000000000000ca220006150c3707 -Content-Type: text/html; charset="UTF-8" +--===============1589864651930508876== +Content-Type: text/html; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit -

---000000000000ca220006150c3707-- + + +

Hello!

+

This is a test email with a basic HTML body.

+
Accept guardian request for 0x04884491560f38342C56E26BDD0fEAbb68E2d2FC Code 01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76
+

Thank you!

+ + + +--===============1589864651930508876==-- diff --git a/packages/circuits/tests/emails/email_auth_test7.eml b/packages/circuits/tests/emails/email_auth_test7.eml index f24fd2ab..ea04faff 100644 --- a/packages/circuits/tests/emails/email_auth_test7.eml +++ b/packages/circuits/tests/emails/email_auth_test7.eml @@ -1,87 +1,98 @@ -Delivered-To: emailwallet.relayer@gmail.com -Received: by 2002:a05:7108:1451:b0:396:8fc9:464d with SMTP id m17csp87769gda; - Thu, 30 May 2024 08:28:23 -0700 (PDT) -X-Received: by 2002:a81:a00a:0:b0:627:e1f9:a139 with SMTP id 00721157ae682-62c6bc794b0mr26546177b3.41.1717082903271; - Thu, 30 May 2024 08:28:23 -0700 (PDT) -ARC-Seal: i=1; a=rsa-sha256; t=1717082903; cv=none; - d=google.com; s=arc-20160816; - b=dcwAI85ZE2D9NASeT5NL1n9e8ZaXu7/GEsqGoeq11pmrZfjnJ0h6NrWC1XSthI6JYw - JRBlN+qW6Ujfw/aXxigYADISdeomqFiSDx8kBUQ80B2jR1g69wtUMnfYVgu2NjNsZiUW - gYk8qmReh3LSDEVV3s9UJ72s41yZ9Mx7nFzrHZTxbEvhowUXoh1thvSqmLR+vk7LJCX5 - qi8qrp1kdgw7nu8I7FpouTWFv+3qLSkt+NbfZxeLG2FUBuGY9GRPQX4SJVxCDYDNInEa - M2gQTOcM2LW6Y2Cb/2NRpj0MNoTSbYFQLz+zx0AWmRwo9heldsKSqHU6dAQsmgajr3oI - FgVw== -ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; - h=to:subject:message-id:date:from:mime-version:dkim-signature; - bh=pEJNaPbPBaXriQY87YlrxS7+Fs6WjCMJNhasTebOP90=; - fh=AKWw92sdXoMEDdHXKLL06vnizTpObKPGCfYXnoQDKO8=; - b=PquMn5DnN9Nr6t0wpyxBLZVp3oppCiH8LKq+Qi0Lgwewn15dzHH0UD9zOWozkjj7CP - 6oR9ft8Rv0GwrxFsNclAChpdZD4UUhhDIooITW3a9xfIlvVltCgENjdufd56dKTr+HkU - MiewdA2ntTNZEdtevwQgqURmNMG5+eietgUU+tl9ZdeE8UFoAr2rJmMq53+LvJgDdq4p - Ez80Hk50Kh1u2IxxQIwIqtMEhxCErlAXU8a+NNehyYMy/GhgNSqi5bOJWzQlKm/QKHlp - fFypOmhFDj7XfmVuY2Tsbw8Z/32FQvB4GUpKJ0+8ZjalcwiKpSxqL5EcOq/85/VwmbN0 - XFhQ==; +Delivered-To: suegamisora@gmail.com +Received: by 2002:a05:7010:2284:b0:415:a8ba:b98c with SMTP id r4csp1031766mdg; + Fri, 25 Oct 2024 07:27:57 -0700 (PDT) +X-Received: by 2002:a05:6a00:22d3:b0:71e:4930:162c with SMTP id d2e1a72fcca58-72030a517f5mr13453926b3a.6.1729866477028; + Fri, 25 Oct 2024 07:27:57 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1729866477; cv=none; + d=google.com; s=arc-20240605; + b=XmTjknQ4dHK4Jpz+h4JVxCS5kiJbCyBTNRh3AM45bJYeYqYOBEnNvNoAqFkstrS4DY + u2lMT9FuS9OWyASXl/ZuDegFjlXbYVUDQ+zyYCxZDbg6WjKhnGevutQEWfPzEBHQUbkq + GguM3+QpHEvv0MSK3H8P/FjucQmwnPPjg3xErUDiACgB2qdaa/qNrsSbGqPKIgk9Xltq + ohrQ4fz+W18mW6tNgE6ijFfqt31xtUBqyXpWembFHnNLnFHCVe+3nSdpDWw6be8ar5G4 + /i6QmK2OJKJGUt8q1Mcw7xMOQ8Jr22LyYw/uSZMLY1HysiZ8DYHfpzeTZO6UkRJolLTZ + ioMg== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; + h=subject:to:from:mime-version:date:message-id:dkim-signature; + bh=LC/5Oq6OtPdl+4eOPJE2ZXrJpnslw2SMedCRl0ndjHM=; + fh=r9ZW45D/4i7BIl/4UeFGrkYKwbplztqhOVKfbV+WD3I=; + b=a5T8tfxqMK/b9hEKgZvYWPDYWg+ATNDbi88i1Uh6ID2yjtRzx88IIa3OKGI7JfX5XP + 0wbK7tMlrox8d8Sh/PKzoQMn7KcwFzZ4kvrxG8vXzTz7m/evw9/2XwnajcfrkGpMVAX8 + CZe4piv6x0LcGjlDFQtmaMDqrYGtEv2h39LsH6qb6hvg5Ud+7vMr7RlpGBaZ/j67jfVD + FFXjsZoQ98ASZA4dwEJedaF4VDoaZVLN7lLiOmgmxByXbLlPfRuoqjC57Gna9SQaGbZw + OvPbCBlpxM9mRk7mzuopuRtqyjNCS9wlhZiz2GiKbCqIXn3wEu4si5VP/Q3ayzJBWnuT + J5aQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=koGCsCmM; - spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; - dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com -Return-Path: + dkim=pass header.i=@gmail.com header.s=20230601 header.b=anDrqw2E; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com +Return-Path: Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) - by mx.google.com with SMTPS id 00721157ae682-62a0a4a3aabsor81652417b3.18.2024.05.30.08.28.23 - for + by mx.google.com with SMTPS id d2e1a72fcca58-72057939682sor863659b3a.5.2024.10.25.07.27.56 + for (Google Transport Security); - Thu, 30 May 2024 08:28:23 -0700 (PDT) -Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; + Fri, 25 Oct 2024 07:27:57 -0700 (PDT) +Received-SPF: pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; Authentication-Results: mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=koGCsCmM; - spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; - dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com + dkim=pass header.i=@gmail.com header.s=20230601 header.b=anDrqw2E; + spf=pass (google.com: domain of emaiwallet.alice@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emaiwallet.alice@gmail.com; + dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; + dara=pass header.i=@gmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20230601; t=1717082903; x=1717687703; dara=google.com; - h=to:subject:message-id:date:from:mime-version:from:to:cc:subject + d=gmail.com; s=20230601; t=1729866476; x=1730471276; dara=google.com; + h=subject:to:from:mime-version:date:message-id:from:to:cc:subject :date:message-id:reply-to; - bh=pEJNaPbPBaXriQY87YlrxS7+Fs6WjCMJNhasTebOP90=; - b=koGCsCmMYnZBGgreIEhDd8QrBpdc+31J63pPLv+t+6xSO+7l3OAcgJMvc9fkIqguSR - t9v+a1zj5NtZEP4bfFNPNxLUaI8cB6HdHtcSS0x21JfdTrcoMw7rBN1X+UR7F8oYXi1U - lYiHF73WjEtiUUi6wdqdZ5TIMC0t1XDOhYyp4Sk6QupBHtmIU5Km4iKSEGHx9mrnjArg - 6CZgDyABv7AiF9pxedEVkSE2mgu+KLhJEdfO0PP6/IDh2WfqIXtNVMlje50UoXNpB3u4 - Gu8FTQ1pUsqOV1WIFeczBAwuErLgv48wmk1qOGhaQ5qW750ZdjdHPhh+HCqglUl6b552 - 3SDA== + bh=LC/5Oq6OtPdl+4eOPJE2ZXrJpnslw2SMedCRl0ndjHM=; + b=anDrqw2EPChWGBU7AuarTKA2sKxGxo7/ixgBP+RLZgzfdoL3gguGtySNOGnOyGM6cF + 9hWbNKpSRpaTXzshtcri+Ikf+2hjIPRoNYDVB/4AcPUrCjqCGhiu90fnrxaVU20jT2Vr + sJj5mqBblj3B763sKaHmx52z6G17l2fv1n9cXVA3LwbGUglzrEdgDS4dQ38zqqxnSgYj + KystOX95LvO9q+RgKNPrJ+eMnMYD6dvm3umTebxWlG5mRojaRZQGdNdmeniD4+/bwJ3c + pfFOQ8FjGoypJPK0tqS76saWgR21xc/blc7K6xBQLyQ2qrI7pDmtUlDnW8mgeC64a/CW + eP0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20230601; t=1717082903; x=1717687703; - h=to:subject:message-id:date:from:mime-version:x-gm-message-state + d=1e100.net; s=20230601; t=1729866476; x=1730471276; + h=subject:to:from:mime-version:date:message-id:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; - bh=pEJNaPbPBaXriQY87YlrxS7+Fs6WjCMJNhasTebOP90=; - b=bkZ3OMtPij0y8UDTJ6ywmP28P0mVt6ekOi4/w1rsfSpNF6XuaYJ+c3rvZVH/BvKKdD - eya1l6uajewpQfXkScHg4cYP61eXy2GTA1VAabnLfIiF+MDf//5l7aVEZw6SNsOCxfSs - Pptad4VrIqrIoVeHlJBBhBxGMjOmfuACTp3+nxvFs1m3MXWHZ9XF5jWQqKnPdGVI4Ukm - J9g3c84qSWx2X7Uf0afkxp95pLgmCGzLsNBCoCh6CKY7dngRCi5fJvAgLkCImZ3cUh0H - 2Zu9avrEwuwN7m7PvnfjB1B2DIHjyQSpIysw16r+gTFoOSU+WpJS/QtGdQ2TFPtl6Vp9 - ghRQ== -X-Gm-Message-State: AOJu0YxcUEs34CaehyGVUHkgKPfOIHW337G2F1GjAwlMEZTkvrdj2lMs - GVh0L9+vmgOAPOV+4HXw9KWUYTtpKsWyQzyWZN95yenGOl8F6a7jwV1X31qoX63EeACiFbBK/MH - jRbRdHQjFr4QtxZ/2YswNS6iGnVJ7v9yn -X-Google-Smtp-Source: AGHT+IH/Asa2+dzrdeRD0Y7sDKAbVp72XvgAlnZUxBxSDzr0V/2T8wGd+OWlB/9z8yKP/1UGUw/u95PtmBGcKnN5Zuw= -X-Received: by 2002:a0d:c6c1:0:b0:627:c0ab:22b9 with SMTP id - 00721157ae682-62c6bc00b87mr22083187b3.21.1717082902547; Thu, 30 May 2024 - 08:28:22 -0700 (PDT) + bh=LC/5Oq6OtPdl+4eOPJE2ZXrJpnslw2SMedCRl0ndjHM=; + b=S+yBX9UilDOty1GGjXv08moJZPwI32wfakEbgVgD2qt9gHjnM1pdD3VJFmqLWBbE6G + EPQsuVmdii/AazgiWK07N+MAZbrOlCOuUMbtdDfSBZwB/mmoCu02mfD7NJCgMKi/4FMT + B1tyJSHe+911xkzZhp3Q9wjL3NphToMb05te/+JfViR2NCFsak5q0lwkqJgmI1chNGt+ + XEFxrU0+svICuyJ0bcWI+uJypRc0jYXotW++yoJr9sd+9TOUbI4GFg4hnCEZOY8Vv7Kj + UNAR9rNhQAD/lUqWiTpM+vU/iuMMvEKUPPTZ3wUfOF1VTd2KzEjCQqc0sCw+5+wXQhuv + FnEw== +X-Gm-Message-State: AOJu0YyBoiRAIml7mTwqM6BxAlcMvxEnTLvTiUF2C4nwxiY0fUWGbag0 + LKiVP9kkW4VI7l04BWHqg0Z04CHQJgg/tyi45s6Am8F1puedqhpKmAC+X2Kh +X-Google-Smtp-Source: AGHT+IFHsmfCzGx0FAHdtSI9/BuidaiAzep1CqKERtZh1qOeguO6USAYGK2SHtvLXXHeGE7pwPrYGA== +X-Received: by 2002:a05:6a20:d805:b0:1d9:2018:9e24 with SMTP id adf61e73a8af0-1d978aead30mr12276795637.10.1729866476232; + Fri, 25 Oct 2024 07:27:56 -0700 (PDT) +Return-Path: +Received: from SoraMacBook-4.local ([93.118.43.168]) + by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-7edc8660a6asm1144014a12.9.2024.10.25.07.27.52 + for + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Fri, 25 Oct 2024 07:27:54 -0700 (PDT) +Message-ID: <671baaea.630a0220.389df1.4b77@mx.google.com> +Date: Fri, 25 Oct 2024 07:27:54 -0700 (PDT) +Content-Type: multipart/alternative; boundary="===============0054196134273425787==" MIME-Version: 1.0 -From: Sora Suegami -Date: Fri, 31 May 2024 00:28:11 +0900 -Message-ID: -Subject: from:adversary@test.com -To: emailwallet.relayer@gmail.com -Content-Type: multipart/alternative; boundary="00000000000074d38f0619ad844a" +From: "Alice" +To: suegamisora@gmail.com +Subject: FWD: FWD: [Reply Needed] Test Email 7 ---00000000000074d38f0619ad844a -Content-Type: text/plain; charset="UTF-8" - - - ---00000000000074d38f0619ad844a -Content-Type: text/html; charset="UTF-8" +--===============0054196134273425787== +Content-Type: text/html; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit -

---00000000000074d38f0619ad844a-- + + +

Hello!

+

This is a test email with a basic HTML body.

+
Accept guardian request for 0x04884491560f38342C56E26BDD0fEAbb68E2d2FC Code 01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76
+

Thank you!

+ + + +--===============0054196134273425787==-- diff --git a/packages/circuits/tests/forced_subject_regex.test.ts b/packages/circuits/tests/forced_subject_regex.test.ts new file mode 100644 index 00000000..6bf16121 --- /dev/null +++ b/packages/circuits/tests/forced_subject_regex.test.ts @@ -0,0 +1,216 @@ +const circom_tester = require("circom_tester"); +const wasm_tester = circom_tester.wasm; +import * as path from "path"; +const relayerUtils = require("@zk-email/relayer-utils"); + +// const grumpkin = require("circom-grumpkin"); +jest.setTimeout(120000); +describe("Forced Subject Regex", () => { + let circuit; + beforeAll(async () => { + const option = { + include: path.join(__dirname, "../../../node_modules"), + output: path.join(__dirname, "../build"), + recompile: true, + }; + circuit = await wasm_tester( + path.join( + __dirname, + "./circuits/test_forced_subject_regex.circom" + ), + option + ); + }); + + it("forced subject valid case", async () => { + const codeStr = "subject:[Reply Needed]\r\n"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + it("forced subject valid case with re", async () => { + const codeStr = "subject:re: [Reply Needed]\r\n"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + it("forced subject valid case with RE", async () => { + const codeStr = "subject:RE: [Reply Needed]\r\n"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + it("forced subject valid case with Re", async () => { + const codeStr = "subject:Re: [Reply Needed]\r\n"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + it("forced subject valid case with fwd", async () => { + const codeStr = "subject:fwd: [Reply Needed]\r\n"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + it("forced subject valid case with FWD", async () => { + const codeStr = "subject:FWD: [Reply Needed]\r\n"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + + it("forced subject valid case with Fwd", async () => { + const codeStr = "subject:Fwd: [Reply Needed]\r\n"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + + it("forced subject valid case with following string", async () => { + const codeStr = "subject:[Reply Needed] Command X\r\n"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + it("forced subject valid case with re with following string", async () => { + const codeStr = "subject:re: [Reply Needed] Command X\r\n"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + it("forced subject valid case with RE with following string", async () => { + const codeStr = "subject:RE: [Reply Needed] Command X\r\n"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + it("forced subject valid case with Re with following string", async () => { + const codeStr = "subject:Re: [Reply Needed] Command X\r\n"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + it("forced subject valid case with fwd with following string", async () => { + const codeStr = "subject:fwd: [Reply Needed] Command X\r\n"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + it("forced subject valid case with FWD with following string", async () => { + const codeStr = "subject:FWD: [Reply Needed] Command X\r\n"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + + it("forced subject valid case with Fwd with following string", async () => { + const codeStr = "subject:Fwd: [Reply Needed] Command X\r\n"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + + it("forced subject valid case with other fields", async () => { + const codeStr = "from: a@gmail.com\r\nsubject:Re: [Reply Needed] Command X\r\nto:b@gmail.com"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + + it("forced subject valid case with multiple prefixes", async () => { + const codeStr = "from: a@gmail.com\r\nsubject:Re: Re: Re: Re: Re: [Reply Needed] Command X\r\nto:b@gmail.com"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(1)).toEqual(witness[1]); + }); + + it("forced subject invalid case", async () => { + const codeStr = "from: a@gmail.com\r\nsubject:Re: [Reply Unneeded] Command X\r\nto:b@gmail.com"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(0)).toEqual(witness[1]); + }); +}); diff --git a/packages/circuits/tests/invitation_code_regex.test.ts b/packages/circuits/tests/invitation_code_regex.test.ts index 9621c444..19f126fb 100644 --- a/packages/circuits/tests/invitation_code_regex.test.ts +++ b/packages/circuits/tests/invitation_code_regex.test.ts @@ -3,172 +3,192 @@ const wasm_tester = circom_tester.wasm; import * as path from "path"; const relayerUtils = require("@zk-email/relayer-utils"); const option = { - include: path.join(__dirname, "../../../node_modules"), + include: path.join(__dirname, "../../../node_modules"), }; // const grumpkin = require("circom-grumpkin"); jest.setTimeout(120000); describe("Invitation Code Regex", () => { - it("invitation code", async () => { - const codeStr = "Code 123abc"; - const paddedStr = relayerUtils.padString(codeStr, 256); - const circuitInputs = { - msg: paddedStr, - }; - const circuit = await wasm_tester( - path.join(__dirname, "./circuits/test_invitation_code_regex.circom"), - option - ); - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - // console.log(witness); - expect(1n).toEqual(witness[1]); - const prefixIdxes = relayerUtils.extractInvitationCodeIdxes(codeStr)[0]; - for (let idx = 0; idx < 256; ++idx) { - if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { - expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); - } else { - expect(0n).toEqual(witness[2 + idx]); - } - } - }); + it("invitation code", async () => { + const codeStr = " Code 123abc"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const circuit = await wasm_tester( + path.join( + __dirname, + "./circuits/test_invitation_code_regex.circom" + ), + option + ); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + // console.log(witness); + expect(BigInt(1)).toEqual(witness[1]); + const prefixIdxes = relayerUtils.extractInvitationCodeIdxes(codeStr)[0]; + for (let idx = 0; idx < 256; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(BigInt(0)).toEqual(witness[2 + idx]); + } + } + }); - it("invitation code in the subject", async () => { - const codeStr = "Swap 0.1 ETH to DAI code 123abc"; - const paddedStr = relayerUtils.padString(codeStr, 256); - const circuitInputs = { - msg: paddedStr, - }; - const circuit = await wasm_tester( - path.join(__dirname, "./circuits/test_invitation_code_regex.circom"), - option - ); - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - // console.log(witness); - expect(1n).toEqual(witness[1]); - const prefixIdxes = relayerUtils.extractInvitationCodeIdxes(codeStr)[0]; - // const revealedStartIdx = emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))[0][0]; - // console.log(emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))); - for (let idx = 0; idx < 256; ++idx) { - if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { - expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); - } else { - expect(0n).toEqual(witness[2 + idx]); - } - } - }); + it("invitation code in the subject", async () => { + const codeStr = "Swap 0.1 ETH to DAI code 123abc"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const circuit = await wasm_tester( + path.join( + __dirname, + "./circuits/test_invitation_code_regex.circom" + ), + option + ); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + // console.log(witness); + expect(BigInt(1)).toEqual(witness[1]); + const prefixIdxes = relayerUtils.extractInvitationCodeIdxes(codeStr)[0]; + // const revealedStartIdx = emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))[0][0]; + // console.log(emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))); + for (let idx = 0; idx < 256; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(BigInt(0)).toEqual(witness[2 + idx]); + } + } + }); - it("email address and invitation code in the subject", async () => { - const codeStr = "Send 0.1 ETH to alice@gmail.com code 123abc"; - const paddedStr = relayerUtils.padString(codeStr, 256); - const circuitInputs = { - msg: paddedStr, - }; - const circuit = await wasm_tester( - path.join(__dirname, "./circuits/test_invitation_code_regex.circom"), - option - ); - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - // console.log(witness); - expect(1n).toEqual(witness[1]); - const prefixIdxes = relayerUtils.extractInvitationCodeIdxes(codeStr)[0]; - // const revealedStartIdx = emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))[0][0]; - // console.log(emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))); - for (let idx = 0; idx < 256; ++idx) { - if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { - expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); - } else { - expect(0n).toEqual(witness[2 + idx]); - } - } - }); + it("email address and invitation code in the subject", async () => { + const codeStr = "Send 0.1 ETH to alice@gmail.com code 123abc"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const circuit = await wasm_tester( + path.join( + __dirname, + "./circuits/test_invitation_code_regex.circom" + ), + option + ); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + // console.log(witness); + expect(BigInt(1)).toEqual(witness[1]); + const prefixIdxes = relayerUtils.extractInvitationCodeIdxes(codeStr)[0]; + // const revealedStartIdx = emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))[0][0]; + // console.log(emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))); + for (let idx = 0; idx < 256; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(BigInt(0)).toEqual(witness[2 + idx]); + } + } + }); - it("invitation code in the email address", async () => { - const codeStr = "sepolia+code123456@sendeth.org"; - const paddedStr = relayerUtils.padString(codeStr, 256); - const circuitInputs = { - msg: paddedStr, - }; - const circuit = await wasm_tester( - path.join(__dirname, "./circuits/test_invitation_code_regex.circom"), - option - ); - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - // console.log(witness); - expect(1n).toEqual(witness[1]); - const prefixIdxes = relayerUtils.extractInvitationCodeIdxes(codeStr)[0]; - // const revealedStartIdx = emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))[0][0]; - // console.log(emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))); - for (let idx = 0; idx < 256; ++idx) { - if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { - expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); - } else { - expect(0n).toEqual(witness[2 + idx]); - } - } - }); + it("prefix + invitation code in the subject", async () => { + const codeStr = "Swap 0.1 ETH to DAI code 123abc"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const circuit = await wasm_tester( + path.join( + __dirname, + "./circuits/test_invitation_code_with_prefix_regex.circom" + ), + option + ); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + // console.log(witness); + expect(BigInt(1)).toEqual(witness[1]); + const prefixIdxes = + relayerUtils.extractInvitationCodeWithPrefixIdxes(codeStr)[0]; + // const revealedStartIdx = emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))[0][0]; + // console.log(emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))); + for (let idx = 0; idx < 256; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(BigInt(0)).toEqual(witness[2 + idx]); + } + } + }); - it("prefix + invitation code in the subject", async () => { - const codeStr = "Swap 0.1 ETH to DAI code 123abc"; - const paddedStr = relayerUtils.padString(codeStr, 256); - const circuitInputs = { - msg: paddedStr, - }; - const circuit = await wasm_tester( - path.join( - __dirname, - "./circuits/test_invitation_code_with_prefix_regex.circom" - ), - option - ); - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - // console.log(witness); - expect(1n).toEqual(witness[1]); - const prefixIdxes = - relayerUtils.extractInvitationCodeWithPrefixIdxes(codeStr)[0]; - // const revealedStartIdx = emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))[0][0]; - // console.log(emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))); - for (let idx = 0; idx < 256; ++idx) { - if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { - expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); - } else { - expect(0n).toEqual(witness[2 + idx]); - } - } - }); + it("prefix + invitation code in the subject 2", async () => { + const codeStr = + "Re: Accept guardian request for 0x04884491560f38342C56E26BDD0fEAbb68E2d2FC Code 01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const circuit = await wasm_tester( + path.join( + __dirname, + "./circuits/test_invitation_code_with_prefix_regex.circom" + ), + option + ); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + // console.log(witness); + expect(BigInt(1)).toEqual(witness[1]); + const prefixIdxes = + relayerUtils.extractInvitationCodeWithPrefixIdxes(codeStr)[0]; + // const revealedStartIdx = emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))[0][0]; + // console.log(emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))); + for (let idx = 0; idx < 256; ++idx) { + if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { + expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); + } else { + expect(BigInt(0)).toEqual(witness[2 + idx]); + } + } + }); - it("prefix + invitation code in the subject 2", async () => { - const codeStr = - "Re: Accept guardian request for 0x04884491560f38342C56E26BDD0fEAbb68E2d2FC Code 01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; - const paddedStr = relayerUtils.padString(codeStr, 256); - const circuitInputs = { - msg: paddedStr, - }; - const circuit = await wasm_tester( - path.join( - __dirname, - "./circuits/test_invitation_code_with_prefix_regex.circom" - ), - option - ); - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - // console.log(witness); - expect(1n).toEqual(witness[1]); - const prefixIdxes = - relayerUtils.extractInvitationCodeWithPrefixIdxes(codeStr)[0]; - // const revealedStartIdx = emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))[0][0]; - // console.log(emailWalletUtils.extractSubstrIdxes(codeStr, readFileSync(path.join(__dirname, "../src/regexes/invitation_code.json"), "utf8"))); - for (let idx = 0; idx < 256; ++idx) { - if (idx >= prefixIdxes[0] && idx < prefixIdxes[1]) { - expect(BigInt(paddedStr[idx])).toEqual(witness[2 + idx]); - } else { - expect(0n).toEqual(witness[2 + idx]); - } - } - }); + + it("invitation code in the email address should fail 1", async () => { + const codeStr = "sepolia+code123456@sendeth.org"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const circuit = await wasm_tester( + path.join( + __dirname, + "./circuits/test_invitation_code_regex.circom" + ), + option + ); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(0)).toEqual(witness[1]); + }); + + it("invitation code in the email address should fail 2", async () => { + const codeStr = "sepoliacode123456@sendeth.org"; + const paddedStr = relayerUtils.padString(codeStr, 256); + const circuitInputs = { + msg: paddedStr, + }; + const circuit = await wasm_tester( + path.join( + __dirname, + "./circuits/test_invitation_code_with_prefix_regex.circom" + ), + option + ); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + expect(BigInt(0)).toEqual(witness[1]); + }); }); diff --git a/packages/circuits/tests/recipient_enabled.test.ts b/packages/circuits/tests/recipient_enabled.test.ts deleted file mode 100644 index d38fe35a..00000000 --- a/packages/circuits/tests/recipient_enabled.test.ts +++ /dev/null @@ -1,292 +0,0 @@ -const circom_tester = require("circom_tester"); -const wasm_tester = circom_tester.wasm; -import * as path from "path"; -const relayerUtils = require("@zk-email/relayer-utils"); -import { genEmailAuthInput } from "../helpers/email_auth"; -import { genRecipientInput } from "../helpers/recipient"; -import { readFileSync } from "fs"; - -jest.setTimeout(1440000); -describe("Email Auth", () => { - let circuit; - beforeAll(async () => { - const option = { - include: path.join(__dirname, "../../../node_modules"), - }; - circuit = await wasm_tester( - path.join(__dirname, "./circuits/email_auth_with_recipient.circom"), - option - ); - }); - - it("Verify a sent email whose subject has an email address", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test1.eml"); - const emailRaw = readFileSync(emailFilePath, "utf8"); - const parsedEmail = await relayerUtils.parseEmail(emailRaw); - console.log(parsedEmail.canonicalizedHeader); - const accountCode = await relayerUtils.genAccountCode(); - const emailAuthInput = await genEmailAuthInput(emailFilePath, accountCode); - const recipientInput = await genRecipientInput(emailFilePath); - const circuitInputs = { - ...emailAuthInput, - subject_email_addr_idx: recipientInput.subject_email_addr_idx, - }; - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - const domainName = "gmail.com"; - const paddedDomain = relayerUtils.padString(domainName, 255); - const domainFields = relayerUtils.bytes2Fields(paddedDomain); - for (let idx = 0; idx < domainFields.length; ++idx) { - expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); - } - const expectedPubKeyHash = relayerUtils.publicKeyHash( - parsedEmail.publicKey - ); - expect(BigInt(expectedPubKeyHash)).toEqual( - witness[1 + domainFields.length] - ); - const expectedEmailNullifier = relayerUtils.emailNullifier( - parsedEmail.signature - ); - expect(BigInt(expectedEmailNullifier)).toEqual( - witness[1 + domainFields.length + 1] - ); - const timestamp = 1694989812n; - expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); - const maskedSubject = "Send 0.1 ETH to "; - const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); - const maskedSubjectFields = relayerUtils.bytes2Fields(paddedMaskedSubject); - for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { - expect(BigInt(maskedSubjectFields[idx])).toEqual( - witness[1 + domainFields.length + 3 + idx] - ); - } - const fromAddr = "suegamisora@gmail.com"; - const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); - expect(BigInt(accountSalt)).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length] - ); - expect(0n).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 1] - ); - expect(1n).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 2] - ); - const recipientEmailAddr = "alice@gmail.com"; - const emailAddrCommit = relayerUtils.emailAddrCommitWithSignature( - recipientEmailAddr, - parsedEmail.signature - ); - expect(BigInt(emailAddrCommit)).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 3] - ); - }); - - it("Verify a sent email whose from field has a dummy email address name", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test3.eml"); - const emailRaw = readFileSync(emailFilePath, "utf8"); - const parsedEmail = await relayerUtils.parseEmail(emailRaw); - console.log(parsedEmail.canonicalizedHeader); - const accountCode = await relayerUtils.genAccountCode(); - const emailAuthInput = await genEmailAuthInput(emailFilePath, accountCode); - const recipientInput = await genRecipientInput(emailFilePath); - const circuitInputs = { - ...emailAuthInput, - subject_email_addr_idx: recipientInput.subject_email_addr_idx, - }; - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - const domainName = "gmail.com"; - const paddedDomain = relayerUtils.padString(domainName, 255); - const domainFields = relayerUtils.bytes2Fields(paddedDomain); - for (let idx = 0; idx < domainFields.length; ++idx) { - expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); - } - const expectedPubKeyHash = relayerUtils.publicKeyHash( - parsedEmail.publicKey - ); - expect(BigInt(expectedPubKeyHash)).toEqual( - witness[1 + domainFields.length] - ); - const expectedEmailNullifier = relayerUtils.emailNullifier( - parsedEmail.signature - ); - expect(BigInt(expectedEmailNullifier)).toEqual( - witness[1 + domainFields.length + 1] - ); - const timestamp = 1696965932n; - expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); - const maskedSubject = "Send 1 ETH to "; - const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); - const maskedSubjectFields = relayerUtils.bytes2Fields(paddedMaskedSubject); - for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { - expect(BigInt(maskedSubjectFields[idx])).toEqual( - witness[1 + domainFields.length + 3 + idx] - ); - } - const fromAddr = "suegamisora@gmail.com"; - const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); - expect(BigInt(accountSalt)).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length] - ); - expect(0n).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 1] - ); - expect(1n).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 2] - ); - const recipientEmailAddr = "bob@example.com"; - const emailAddrCommit = relayerUtils.emailAddrCommitWithSignature( - recipientEmailAddr, - parsedEmail.signature - ); - expect(BigInt(emailAddrCommit)).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 3] - ); - }); - - it("Verify a sent email whose from field has a non-English name", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test4.eml"); - const emailRaw = readFileSync(emailFilePath, "utf8"); - const parsedEmail = await relayerUtils.parseEmail(emailRaw); - console.log(parsedEmail.canonicalizedHeader); - const accountCode = await relayerUtils.genAccountCode(); - const emailAuthInput = await genEmailAuthInput(emailFilePath, accountCode); - const recipientInput = await genRecipientInput(emailFilePath); - const circuitInputs = { - ...emailAuthInput, - subject_email_addr_idx: recipientInput.subject_email_addr_idx, - }; - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - const domainName = "gmail.com"; - const paddedDomain = relayerUtils.padString(domainName, 255); - const domainFields = relayerUtils.bytes2Fields(paddedDomain); - for (let idx = 0; idx < domainFields.length; ++idx) { - expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); - } - const expectedPubKeyHash = relayerUtils.publicKeyHash( - parsedEmail.publicKey - ); - expect(BigInt(expectedPubKeyHash)).toEqual( - witness[1 + domainFields.length] - ); - const expectedEmailNullifier = relayerUtils.emailNullifier( - parsedEmail.signature - ); - expect(BigInt(expectedEmailNullifier)).toEqual( - witness[1 + domainFields.length + 1] - ); - const timestamp = 1696967028n; - expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); - const maskedSubject = "Send 1 ETH to "; - const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); - const maskedSubjectFields = relayerUtils.bytes2Fields(paddedMaskedSubject); - for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { - expect(BigInt(maskedSubjectFields[idx])).toEqual( - witness[1 + domainFields.length + 3 + idx] - ); - } - const fromAddr = "suegamisora@gmail.com"; - const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); - expect(BigInt(accountSalt)).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length] - ); - expect(0n).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 1] - ); - expect(1n).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 2] - ); - const recipientEmailAddr = "bob@example.com"; - const emailAddrCommit = relayerUtils.emailAddrCommitWithSignature( - recipientEmailAddr, - parsedEmail.signature - ); - expect(BigInt(emailAddrCommit)).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 3] - ); - }); - - it("Verify a sent email whose subject has an invitation code", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test5.eml"); - const emailRaw = readFileSync(emailFilePath, "utf8"); - const parsedEmail = await relayerUtils.parseEmail(emailRaw); - console.log(parsedEmail.canonicalizedHeader); - const accountCode = - "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; - const emailAuthInput = await genEmailAuthInput(emailFilePath, accountCode); - const recipientInput = await genRecipientInput(emailFilePath); - const circuitInputs = { - ...emailAuthInput, - subject_email_addr_idx: recipientInput.subject_email_addr_idx, - }; - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - const domainName = "gmail.com"; - const paddedDomain = relayerUtils.padString(domainName, 255); - const domainFields = relayerUtils.bytes2Fields(paddedDomain); - for (let idx = 0; idx < domainFields.length; ++idx) { - expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); - } - const expectedPubKeyHash = relayerUtils.publicKeyHash( - parsedEmail.publicKey - ); - expect(BigInt(expectedPubKeyHash)).toEqual( - witness[1 + domainFields.length] - ); - const expectedEmailNullifier = relayerUtils.emailNullifier( - parsedEmail.signature - ); - expect(BigInt(expectedEmailNullifier)).toEqual( - witness[1 + domainFields.length + 1] - ); - const timestamp = 1707866192n; - expect(timestamp).toEqual(witness[1 + domainFields.length + 2]); - const maskedSubject = "Send 0.12 ETH to "; - const paddedMaskedSubject = relayerUtils.padString(maskedSubject, 605); - const maskedSubjectFields = relayerUtils.bytes2Fields(paddedMaskedSubject); - for (let idx = 0; idx < maskedSubjectFields.length; ++idx) { - expect(BigInt(maskedSubjectFields[idx])).toEqual( - witness[1 + domainFields.length + 3 + idx] - ); - } - const fromAddr = "suegamisora@gmail.com"; - const accountSalt = relayerUtils.accountSalt(fromAddr, accountCode); - expect(BigInt(accountSalt)).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length] - ); - expect(1n).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 1] - ); - expect(1n).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 2] - ); - const recipientEmailAddr = "alice@gmail.com"; - const emailAddrCommit = relayerUtils.emailAddrCommitWithSignature( - recipientEmailAddr, - parsedEmail.signature - ); - expect(BigInt(emailAddrCommit)).toEqual( - witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 3] - ); - }); - - it("Verify a sent email with a too large subject_email_addr_idx", async () => { - const emailFilePath = path.join(__dirname, "./emails/email_auth_test1.eml"); - const accountCode = - "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; - const emailAuthInput = await genEmailAuthInput(emailFilePath, accountCode); - const recipientInput = await genRecipientInput(emailFilePath); - const circuitInputs = { - ...emailAuthInput, - subject_email_addr_idx: recipientInput.subject_email_addr_idx, - }; - circuitInputs.subject_email_addr_idx = 605; - async function failFn() { - const witness = await circuit.calculateWitness(circuitInputs); - await circuit.checkConstraints(witness); - } - await expect(failFn).rejects.toThrow(); - }); -}); diff --git a/packages/circuits/tests/script/send_email.py b/packages/circuits/tests/script/send_email.py new file mode 100644 index 00000000..c1cb392f --- /dev/null +++ b/packages/circuits/tests/script/send_email.py @@ -0,0 +1,53 @@ +import smtplib +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText + + +def send_html_email( + sender_email, sender_password, recipient_email, subject, html_content +): + # Create a multipart message + msg = MIMEMultipart("alternative") + msg["From"] = sender_email + msg["To"] = recipient_email + msg["Subject"] = subject + + # Attach the HTML body to the email + msg.attach(MIMEText(html_content, "html")) + + try: + # Connect to the Gmail SMTP server + server = smtplib.SMTP("smtp.gmail.com", 587) + server.starttls() # Upgrade the connection to a secure encrypted SSL/TLS connection + server.login(sender_email, sender_password) + + # Send the email + server.sendmail(sender_email, recipient_email, msg.as_string()) + + print("Email sent successfully!") + except Exception as e: + print(f"Failed to send email: {e}") + finally: + server.quit() + + +if __name__ == "__main__": + # Replace with your details + sender_email = "" + sender_password = "" + recipient_email = "" + subject = "ZK Email:" + + # Basic HTML content + html_content = """ + + +
ZK Email Command
+ + + """ + + # Send the email + send_html_email( + sender_email, sender_password, recipient_email, subject, html_content + ) diff --git a/packages/contracts/.env.example b/packages/contracts/.env.example new file mode 100644 index 00000000..79e5e4e1 --- /dev/null +++ b/packages/contracts/.env.example @@ -0,0 +1,23 @@ +LOCALHOST_RPC_URL=http://127.0.0.1:8545 +SEPOLIA_RPC_URL=https://sepolia.base.org +# For zksync +# SEPOLIA_RPC_URL=https://sepolia.era.zksync.dev + +MAINNET_RPC_URL=https://mainnet.base.org + +# NEED 0x prefix +PRIVATE_KEY= +INITIAL_OWNER= + +CHAIN_ID=84532 +RPC_URL="https://sepolia.base.org" +DKIM_SIGNER=0x6293a80bf4bd3fff995a0cab74cbf281d922da02 # Signer for the dkim oracle on IC (Don't change this) +ETHERSCAN_API_KEY= +# CHAIN_NAME="base_sepolia" + +PROXY_BYTECODE_HASH=0x0000000000000000000000000000000000000000000000000000000000000000 + +# Open Zeppelin Defender +DEFENDER_KEY="YOUR_KEY" +DEFENDER_SECRET="YOUR_SECRET" +FOUNDRY_OUT="artifacts" \ No newline at end of file diff --git a/packages/contracts/.env.sample b/packages/contracts/.env.sample deleted file mode 100644 index 8e28ffb5..00000000 --- a/packages/contracts/.env.sample +++ /dev/null @@ -1,15 +0,0 @@ -LOCALHOST_RPC_URL=http://127.0.0.1:8545 -SEPOLIA_RPC_URL=https://sepolia.base.org -# For zksync -# SEPOLIA_RPC_URL=https://sepolia.era.zksync.dev - -MAINNET_RPC_URL=https://mainnet.base.org - -# NEED 0x prefix -PRIVATE_KEY= - -CHAIN_ID=84532 -RPC_URL="https://sepolia.base.org" -SIGNER=0x69bec2dd161d6bbcc91ec32aa44d9333ebc864c0 # Signer for the dkim oracle on IC (Don't change this) -ETHERSCAN_API_KEY= -# CHAIN_NAME="base_sepolia" diff --git a/packages/contracts/.zksolc-libraries-cache/missing_library_dependencies.json b/packages/contracts/.zksolc-libraries-cache/missing_library_dependencies.json new file mode 100644 index 00000000..0e7f1f1b --- /dev/null +++ b/packages/contracts/.zksolc-libraries-cache/missing_library_dependencies.json @@ -0,0 +1,14 @@ +[ + { + "contract_name": "CommandUtils", + "contract_path": "src/libraries/CommandUtils.sol", + "missing_libraries": [ + "src/libraries/DecimalUtils.sol:DecimalUtils" + ] + }, + { + "contract_name": "DecimalUtils", + "contract_path": "src/libraries/DecimalUtils.sol", + "missing_libraries": [] + } +] \ No newline at end of file diff --git a/packages/contracts/README.md b/packages/contracts/README.md index 406c6006..12fb3b8b 100644 --- a/packages/contracts/README.md +++ b/packages/contracts/README.md @@ -25,12 +25,12 @@ $ yarn test Run integration tests Before running integration tests, you need to make a `packages/contracts/test/build_integration` directory, download the zip file from the following link, and place its unzipped directory under that directory. -https://drive.google.com/file/d/1Ybtxe1TCVUtHzCPUs9cuZAGbM-MVwigE/view?usp=drive_link +https://drive.google.com/file/d/1XDPFIL5YK8JzLGoTjmHLXO9zMDjSQcJH/view?usp=sharing -Then, move `email_auth.zkey` and `email_auth.wasm` in the unzipped directory `params` to `build_integration`. +Then, move `email_auth_with_body_parsing_with_qp_encoding.zkey` and `email_auth_with_body_parsing_with_qp_encoding.wasm` in the unzipped directory `params` to `build_integration`. -Run each integration tests **one by one** as each test will consume lot of memory. +Run each integration tests **one by one** as each test will consume a lot of memory. ```bash Eg: contracts % forge test --skip '*ZKSync*' --match-contract "IntegrationTest" -vvv --chain 8453 --ffi ``` @@ -48,20 +48,28 @@ After deploying common contracts, you can deploy a proxy contract of `SimpleWall ## Specification There are four main contracts that developers should understand: `IDKIMRegistry`, `Verifier`, `EmailAuth` and `EmailAccountRecovery`. -While the first three contracts are agnostic to usecases of our SDK, the last one is an abstract contract only for our email-based account recovery. +While the first three contracts are agnostic to use cases of our SDK, the last one is an abstract contract only for our email-based account recovery. ### `IDKIMRegistry` Contract It is an interface of the DKIM registry contract that traces public keys registered for each email domain in DNS. It is defined in [the zk-email library](https://github.com/zkemail/zk-email-verify/blob/main/packages/contracts/interfaces/IDKIMRegistry.sol). -It requires a function `isDKIMPublicKeyHashValid(string domainName, bytes32 publicKeyHash) view returns (bool)`: it returns true iff the given hash of the public key `publicKeyHash` is registered for the given email-domain name `domainName`. +It requires a function `isDKIMPublicKeyHashValid(string domainName, bytes32 publicKeyHash) view returns (bool)`: it returns true if the given hash of the public key `publicKeyHash` is registered for the given email-domain name `domainName`. One of its implementations is [`ECDSAOwnedDKIMRegistry`](https://github.com/zkemail/ether-email-auth/blob/main/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol). It stores the Ethereum address `signer` who can update the registry. -We also provide another implementation called [`ForwardDKIMRegistry`](https://github.com/zkemail/ether-email-auth/blob/main/packages/contracts/src/utils/ForwardDKIMRegistry.sol). It stores an address of any internal DKIM registry and forwards its outputs. We can use it to upgrade a proxy of the ECDSAOwnedDKIMRegistry registry to a new DKIM registry with a different storage slots design by 1) upgrading its implementation into ForwardDKIMRegistry and 2) calling resetStorageForUpgradeFromECDSAOwnedDKIMRegistry function with an address of the internal DKIM registry. +We also provide another implementation called [`UserOverrideableDKIMRegistry`](https://github.com/zkemail/ether-email-auth/blob/main/packages/contracts/node_modules/@zk-email/contracts/UserOverrideableDKIMRegistry.sol). + +Key features of `UserOverrideableDKIMRegistry` include: +1. User-specific public key setting +2. Time-delayed activation of main authorizer's approvals +3. Dual revocation mechanism (user or main authorizer) +4. Reactivation of revoked keys (by users only) + +This implementation provides a balance between centralized management and user autonomy in the DKIM registry system. ### `Verifier` Contract -It has a responsibility to verify a ZK proof for the [`email_auth.circom` circuit](https://github.com/zkemail/ether-email-auth/blob/main/packages/circuits/src/email_auth.circom). +It has the responsibility to verify a ZK proof for the [`email_auth_with_body_parsing_with_qp_encoding.circom` circuit](https://github.com/zkemail/ether-email-auth/blob/main/packages/circuits/src/email_auth_with_body_parsing_with_qp_encoding.circom). It is implemented in [`utils/Verifier.sol`](https://github.com/zkemail/ether-email-auth/blob/main/packages/contracts/src/utils/Verifier.sol). It defines a structure `EmailProof` consisting of the ZK proof and data of the instances necessary for proof verification as follows: @@ -70,34 +78,34 @@ struct EmailProof { string domainName; // Domain name of the sender's email bytes32 publicKeyHash; // Hash of the DKIM public key used in email/proof uint timestamp; // Timestamp of the email - string maskedSubject; // Masked subject of the email + string maskedCommand; // Masked command of the email bytes32 emailNullifier; // Nullifier of the email to prevent its reuse. bytes32 accountSalt; // Create2 salt of the account - bool isCodeExist; // Check if the account code is exist + bool isCodeExist; // Check if the account code exists bytes proof; // ZK Proof of Email } ``` -Using that, it provides a function `function verifyEmailProof(EmailProof memory proof) public view returns (bool)`: it takes as input the `EmailProof proof` and returns true iff the proof is valid. Notably, it internally calls [`Groth16Verifier.sol`](https://github.com/zkemail/ether-email-auth/blob/main/packages/contracts/src/utils/Groth16Verifier.sol) generated by snarkjs from the verifying key of the [`email_auth.circom` circuit](https://github.com/zkemail/ether-email-auth/blob/main/packages/circuits/src/email_auth.circom). +Using that, it provides a function `function verifyEmailProof(EmailProof memory proof) public view returns (bool)`: it takes as input the `EmailProof proof` and returns true if the proof is valid. Notably, it internally calls [`Groth16Verifier.sol`](https://github.com/zkemail/ether-email-auth/blob/main/packages/contracts/src/utils/Groth16Verifier.sol) generated by snarkjs from the verifying key of the [`email_auth_with_body_parsing_with_qp_encoding.circom` circuit](https://github.com/zkemail/ether-email-auth/blob/main/packages/circuits/src/email_auth_with_body_parsing_with_qp_encoding.circom). ### `EmailAuth` Contract It is a contract deployed for each email user to verify an email-auth message from that user. The structure of the email-auth message is defined as follows: ``` struct EmailAuthMsg { - uint templateId; // The ID of the subject template that the email subject should satisfy. - bytes[] subjectParams; // The parameters in the email subject, which should be taken according to the specified subject template. - uint skipedSubjectPrefix; // The number of skiiped bytes in the email subject. + uint templateId; // The ID of the command template that the email command should satisfy. + bytes[] commandParams; // The parameters in the email command, which should be taken according to the specified command template. + uint skippedCommandPrefix; // The number of skipped bytes in the email command. EmailProof proof; // The email proof containing the zk proof and other necessary information for the email verification by the verifier contract. -} -``` +} +``` It has the following storage variables. - `address owner`: an address of the contract owner. - `bytes32 accountSalt`: an `accountSalt` used for the CREATE2 salt of this contract. - `DKIMRegistry dkim`: an instance of the DKIM registry contract. - `Verifier verifier`: an instance of the Verifier contract. -- `address controller`: an address of a controller contract, defining the subject templates supported by this contract. -- `mapping(uint=>string[]) subjectTemplates`: a mapping of the supported subject templates associated with its ID. +- `address controller`: an address of a controller contract, defining the command templates supported by this contract. +- `mapping(uint=>string[]) commandTemplates`: a mapping of the supported command templates associated with its ID. - `mapping(bytes32⇒bytes32) authedHash`: a mapping of the hash of the authorized message associated with its `emailNullifier`. - `uint lastTimestamp`: the latest `timestamp` in the verified `EmailAuthMsg`. - `mapping(bytes32=>bool) usedNullifiers`: a mapping storing the used `emailNullifier` bytes. @@ -137,33 +145,33 @@ It provides the following functions. 1. Assert `msg.sender==owner` . 2. Assert `_dkimRegistryAddr!=0`. 3. Update `dkim` to `DKIMRegistry(_dkimRegistryAddr)`. -- `getSubjectTemplate(uint _templateId) public view returns (string[] memory)` - 1. Assert that the template for `_templateId` exists, i.e., `subjectTemplates[_templateId].length >0` holds. - 2. Return `subjectTemplates[_templateId]`. -- `insertSubjectTemplate(uint _templateId, string[] _subjectTemplate)` - 1. Assert `_subjectTemplate.length>0` . +- `getCommandTemplate(uint _templateId) public view returns (string[] memory)` + 1. Assert that the template for `_templateId` exists, i.e., `commandTemplates[_templateId].length >0` holds. + 2. Return `commandTemplates[_templateId]`. +- `insertCommandTemplate(uint _templateId, string[] _commandTemplate)` + 1. Assert `_commandTemplate.length>0` . 2. Assert `msg.sender==controller`. - 3. Assert `subjectTemplates[_templateId].length == 0`, i.e., no template has not been registered with `_templateId`. - 4. Set `subjectTemplates[_templateId]=_subjectTemplate`. -- `updateSubjectTemplate(uint _templateId, string[] _subjectTemplate)` - 1. Assert `_subjectTemplate.length>0` . + 3. Assert `commandTemplates[_templateId].length == 0`, i.e., no template has not been registered with `_templateId`. + 4. Set `commandTemplates[_templateId]=_commandTemplate`. +- `updateCommandTemplate(uint _templateId, string[] _commandTemplate)` + 1. Assert `_commandTemplate.length>0` . 2. Assert `msg.sender==controller`. - 3. Assert `subjectTemplates[_templateId].length != 0` , i.e., any template has been already registered with `_templateId`. - 4. Set `subjectTemplates[_templateId]=_subjectTemplate`. -- `deleteSubjectTemplate(uint _templateId)` + 3. Assert `commandTemplates[_templateId].length != 0` , i.e., any template has been already registered with `_templateId`. + 4. Set `commandTemplates[_templateId]=_commandTemplate`. +- `deleteCommandTemplate(uint _templateId)` 1. Assert `msg.sender==controller`. - 2. Assert `subjectTemplates[_templateId].length > 0`, i.e., any template has been already registered with `_templateId`. - 3. `delete subjectTemplates[_templateId]`. + 2. Assert `commandTemplates[_templateId].length > 0`, i.e., any template has been already registered with `_templateId`. + 3. `delete commandTemplates[_templateId]`. - `authEmail(EmailAuthMsg emailAuthMsg) returns (bytes32)` 1. Assert `msg.sender==controller`. - 2. Let `string[] memory template = subjectTemplates[emailAuthMsg.templateId]`. + 2. Let `string[] memory template = commandTemplates[emailAuthMsg.templateId]`. 3. Assert `template.length > 0`. 4. Assert `dkim.isDKIMPublicKeyHashValid(emailAuthMsg.proof.domain, emailAuthMsg.proof.publicKeyHash)==true`. 5. Assert `usedNullifiers[emailAuthMsg.proof.emailNullifier]==false` and set `usedNullifiers[emailAuthMsg.proof.emailNullifier]` to `true`. 6. Assert `accountSalt==emailAuthMsg.proof.accountSalt`. 7. If `timestampCheckEnabled` is true, assert that `emailAuthMsg.proof.timestamp` is zero OR `lastTimestamp < emailAuthMsg.proof.timestamp`, and update `lastTimestamp` to `emailAuthMsg.proof.timestamp`. - 8. Construct an expected subject `expectedSubject` from `template` and the values of `emailAuthMsg.subjectParams`. - 9. Assert that `expectedSubject` is equal to `emailAuthMsg.proof.maskedSubject[skipedSubjectPrefix:]` , i.e., the string of `emailAuthMsg.proof.maskedSubject` from the `skipedSubjectPrefix`-th byte. + 8. Construct an expected command `expectedCommand` from `template` and the values of `emailAuthMsg.commandParams`. + 9. Assert that `expectedCommand` is equal to `emailAuthMsg.proof.maskedCommand[skippedCommandPrefix:]` , i.e., the string of `emailAuthMsg.proof.maskedCommand` from the `skippedCommandPrefix`-th byte. 10. Assert `verifier.verifyEmailProof(emailAuthMsg.proof)==true`. - `isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4 magicValue)` 1. Parse `_signature` as `(bytes32 emailNullifier)`. @@ -173,20 +181,20 @@ It provides the following functions. 2. Set `timestampCheckEnabled` to `enabled`. ### `EmailAccountRecovery` Contract -It is an abstract contract for each smart account brand to implement the email-based account recovery. **Each smart account provider only needs to implement the following functions in a new contract called controller.** In the following, the `templateIdx` is different from `templateId` in the email-auth contract in the sense that the `templateIdx` is an incremental index defined for each of the subject templates in `acceptanceSubjectTemplates()` and `recoverySubjectTemplates()`. +It is an abstract contract for each smart account brand to implement the email-based account recovery. **Each smart account provider only needs to implement the following functions in a new contract called controller.** In the following, the `templateIdx` is different from `templateId` in the email-auth contract in the sense that the `templateIdx` is an incremental index defined for each of the command templates in `acceptanceCommandTemplates()` and `recoveryCommandTemplates()`. - `isActivated(address recoveredAccount) public view virtual returns (bool)`: it returns if the account to be recovered has already activated the controller (the contract implementing `EmailAccountRecovery`). -- `acceptanceSubjectTemplates() public view virtual returns (string[][])`: it returns multiple subject templates for an email to accept becoming a guardian (acceptance email). -- `recoverySubjectTemplates() public view virtual returns (string[][])`: it returns multiple subject templates for an email to confirm the account recovery (recovery email). -- `extractRecoveredAccountFromAcceptanceSubject(bytes[] memory subjectParams, uint templateIdx) public view virtual returns (address)`: it takes as input the parameters `subjectParams` and the index of the chosen subject template `templateIdx` in those for acceptance emails. -- `extractRecoveredAccountFromRecoverySubject(bytes[] memory subjectParams, uint templateIdx) public view virtual returns (address)`: it takes as input the parameters `subjectParams` and the index of the chosen subject template `templateIdx` in those for recovery emails. -- `acceptGuardian(address guardian, uint templateIdx, bytes[] subjectParams, bytes32 emailNullifier) internal virtual`: it takes as input the Ethereum address `guardian` corresponding to the guardian's email address, the index `templateIdx` of the subject template in the output of `acceptanceSubjectTemplates()`, the parameter values of the variable parts `subjectParams` in the template `acceptanceSubjectTemplates()[templateIdx]`, and an email nullifier `emailNullifier`. It is called after verifying the email-auth message to accept the role of the guardian; thus you can assume the arguments are already verified. -- `processRecovery(address guardian, uint templateIdx, bytes[] subjectParams, bytes32 emailNullifier) internal virtual`: it takes as input the Ethereum address `guardian` corresponding to the guardian's email address, the index `templateIdx` of the subject template in the output of `recoverySubjectTemplates()`, the parameter values of the variable parts `subjectParams` in the template `recoverySubjectTemplates()[templateIdx]`, and an email nullifier `emailNullifier`. It is called after verifying the email-auth message to confirm the recovery; thus you can assume the arguments are already verified. +- `acceptanceCommandTemplates() public view virtual returns (string[][])`: it returns multiple command templates for an email to accept becoming a guardian (acceptance email). +- `recoveryCommandTemplates() public view virtual returns (string[][])`: it returns multiple command templates for an email to confirm the account recovery (recovery email). +- `extractRecoveredAccountFromAcceptanceCommand(bytes[] memory commandParams, uint templateIdx) public view virtual returns (address)`: it takes as input the parameters `commandParams` and the index of the chosen command template `templateIdx` in those for acceptance emails. +- `extractRecoveredAccountFromRecoveryCommand(bytes[] memory commandParams, uint templateIdx) public view virtual returns (address)`: it takes as input the parameters `commandParams` and the index of the chosen command template `templateIdx` in those for recovery emails. +- `acceptGuardian(address guardian, uint templateIdx, bytes[] commandParams, bytes32 emailNullifier) internal virtual`: it takes as input the Ethereum address `guardian` corresponding to the guardian's email address, the index `templateIdx` of the command template in the output of `acceptanceCommandTemplates()`, the parameter values of the variable parts `commandParams` in the template `acceptanceCommandTemplates()[templateIdx]`, and an email nullifier `emailNullifier`. It is called after verifying the email-auth message to accept the role of the guardian; thus you can assume the arguments are already verified. +- `processRecovery(address guardian, uint templateIdx, bytes[] commandParams, bytes32 emailNullifier) internal virtual`: it takes as input the Ethereum address `guardian` corresponding to the guardian's email address, the index `templateIdx` of the command template in the output of `recoveryCommandTemplates()`, the parameter values of the variable parts `commandParams` in the template `recoveryCommandTemplates()[templateIdx]`, and an email nullifier `emailNullifier`. It is called after verifying the email-auth message to confirm the recovery; thus you can assume the arguments are already verified. - `completeRecovery(address account, bytes memory completeCalldata) external virtual`: it can be called by anyone, in particular a Relayer, when completing the account recovery. It should first check if the condition for the recovery of `account` holds and then update its owner's address in the wallet contract. It also provides the following entry functions with their default implementations, called by the Relayer. - `handleAcceptance(EmailAuthMsg emailAuthMsg, uint templateIdx) external` - 1. Extract an account address to be recovered `recoveredAccount` by calling `extractRecoveredAccountFromAcceptanceSubject`. + 1. Extract an account address to be recovered `recoveredAccount` by calling `extractRecoveredAccountFromAcceptanceCommand`. 2. Let `address guardian = CREATE2(emailAuthMsg.proof.accountSalt, ERC1967Proxy.creationCode, emailAuthImplementation(), (emailAuthMsg.proof.accountSalt))`. 3. Let `uint templateId = keccak256(EMAIL_ACCOUNT_RECOVERY_VERSION_ID, "ACCEPTANCE", templateIdx)`. 4. Assert that `templateId` is equal to `emailAuthMsg.templateId`. @@ -194,30 +202,23 @@ It also provides the following entry functions with their default implementation 6. If the `EmailAuth` contract of `guardian` has not been deployed, deploy the proxy contract of `emailAuthImplementation()`. Its salt is `emailAuthMsg.proof.accountSalt` and its initialization parameter is `recoveredAccount`, `emailAuthMsg.proof.accountSalt`, and `address(this)`, which is a controller of the deployed contract. 7. If the `EmailAuth` contract of `guardian` has not been deployed, call `EmailAuth(guardian).initDKIMRegistry(dkim())`. 8. If the `EmailAuth` contract of `guardian` has not been deployed, call `EmailAuth(guardian).initVerifier(verifier())`. - 9. If the `EmailAuth` contract of `guardian` has not been deployed, for each `template` in `acceptanceSubjectTemplates()` along with its index `idx`, call `EmailAuth(guardian).insertSubjectTemplate(keccak256(EMAIL_ACCOUNT_RECOVERY_VERSION_ID, "ACCEPTANCE", idx), template)`. - 10. If the `EmailAuth` contract of `guardian` has not been deployed, for each `template` in `recoverySubjectTemplates()` along with its index `idx`, call `EmailAuth(guardian).insertSubjectTemplate(keccak256(EMAIL_ACCOUNT_RECOVERY_VERSION_ID, "RECOVERY", idx), template)`. + 9. If the `EmailAuth` contract of `guardian` has not been deployed, for each `template` in `acceptanceCommandTemplates()` along with its index `idx`, call `EmailAuth(guardian).insertCommandTemplate(keccak256(EMAIL_ACCOUNT_RECOVERY_VERSION_ID, "ACCEPTANCE", idx), template)`. + 10. If the `EmailAuth` contract of `guardian` has not been deployed, for each `template` in `recoveryCommandTemplates()` along with its index `idx`, call `EmailAuth(guardian).insertCommandTemplate(keccak256(EMAIL_ACCOUNT_RECOVERY_VERSION_ID, "RECOVERY", idx), template)`. 11. If the `EmailAuth` contract of `guardian` has been already deployed, assert that its `controller` is equal to `address(this)`. - 11. Assert that `EmailAuth(guardian).authEmail(1emailAuthMsg)` returns no error. - 12. Call `acceptGuardian(guardian, templateIdx, emailAuthMsg.subjectParams, emailAuthMsg.proof.emailNullifier)`. + 11. Assert that `EmailAuth(guardian).authEmail(emailAuthMsg)` returns no error. + 12. Call `acceptGuardian(guardian, templateIdx, emailAuthMsg.commandParams, emailAuthMsg.proof.emailNullifier)`. - `handleRecovery(EmailAuthMsg emailAuthMsg, uint templateIdx) external` - 1. Extract an account address to be recovered `recoveredAccount` by calling `extractRecoveredAccountFromRecoverySubject`. + 1. Extract an account address to be recovered `recoveredAccount` by calling `extractRecoveredAccountFromRecoveryCommand`. 1. Let `address guardian = CREATE2(emailAuthMsg.proof.accountSalt, ERC1967Proxy.creationCode, emailAuthImplementation(), (emailAuthMsg.proof.accountSalt))`. 2. Assert that the contract of `guardian` has been already deployed. 3. Let `uint templateId=keccak256(EMAIL_ACCOUNT_RECOVERY_VERSION_ID, "RECOVERY", templateIdx)`. 4. Assert that `templateId` is equal to `emailAuthMsg.templateId`. 5. Assert that `EmailAuth(guardian).authEmail(emailAuthMsg)` returns no error. - 6. Call `processRecovery(guardian, templateIdx, emailAuthMsg.subjectParams, emailAuthMsg.proof.emailNullifier)`. - -# For zkSync - -You should use foundry-zksync, the installation process is following URL. -https://github.com/matter-labs/foundry-zksync - -Current version foundry-zksync is forge 0.0.2 (6e1c282 2024-07-01T00:26:02.947919000Z) + 6. Call `processRecovery(guardian, templateIdx, emailAuthMsg.commandParams, emailAuthMsg.proof.emailNullifier)`. -Now foundry-zksync supports solc 0.8.26, but it won't be automatically downloaded by foundry-zksync. -First you should compile our contracts with foundry, and then install foundry-zksync. +# For ZKsync +## Set up and build ``` # Install foundry foundryup @@ -225,26 +226,13 @@ foundryup cd packages/contracts yarn build -# Check if you have already had 0.8.26 -ls -l /Users/{USER_NAME}/Library/Application\ Support/svm/0.8.26 +# Install foundry-zksync, please follow this URL +https://foundry-book.zksync.io/getting-started/installation -# Install foundry-zksync -cd YOUR_FOUNDRY_ZKSYNC_DIR -chmod +x ./install-foundry-zksync -./install-foundry-zksync - -# Install zksolc-bin 1.5.0 manually -# Download https://github.com/matter-labs/zksolc-bin/releases/tag/v1.5.0 -chmod a+x {BINARY_NAME} -mv {BINARY_NAME} ~/.zksync/. +# Install era-test-node +https://github.com/matter-labs/era-test-node ``` -In addition, there are the problem with foundy-zksync. Currently they can't resolve contracts in monorepo's node_modules. - -https://github.com/matter-labs/foundry-zksync/issues/411 - -To fix this, you should copy `node_modules` in the project root dir to `packages/contracts/node_modules`. And then you should replace `libs = ["../../node_modules", "lib"]` to `libs = ["node_modules", "lib"]` in `foundry.toml`. At the end, you should replace `../../node_modules` to `node_modules` in `remappings.txt`. - Next, you should uncomment the following lines in `foundry.toml`. ``` @@ -257,6 +245,12 @@ Partial comment-out files can be found the following. Please uncomment them. - src/utils/ZKSyncCreate2Factory.sol - test/helpers/DeploymentHelper.sol +Run the era-test-node forking zksync sepolia + +``` +era_test_node fork https://sepolia.era.zksync.dev +``` + At the first forge build, you need to detect the missing libraries. ``` @@ -268,113 +262,115 @@ You can deploy them by the following command for example. ``` $ forge build --zksync --zk-detect-missing-libraries -Missing libraries detected: src/libraries/SubjectUtils.sol:SubjectUtils, src/libraries/DecimalUtils.sol:DecimalUtils +Missing libraries detected: src/libraries/CommandUtils.sol:CommandUtils, src/libraries/DecimalUtils.sol:DecimalUtils, src/libraries/StringUtils.sol:StringUtils ``` -Run the following command in order to deploy each missing library: +Run the following command in order to deploy each missing libraries: ``` -forge create src/libraries/DecimalUtils.sol:DecimalUtils --private-key {YOUR_PRIVATE_KEY} --rpc-url https://sepolia.era.zksync.dev --chain 300 --zksync -forge create src/libraries/SubjectUtils.sol:SubjectUtils --private-key {YOUR_PRIVATE_KEY} --rpc-url https://sepolia.era.zksync.dev --chain 300 --zksync --libraries src/libraries/DecimalUtils.sol:DecimalUtils:{DECIMAL_UTILS_DEPLOYED_ADDRESS} +export PRIVATE_KEY={YOUR_PRIVATE_KEY} +export RPC_URL=http://127.0.0.1:8011 +export CHAIN_ID=260 + +forge create src/libraries/DecimalUtils.sol:DecimalUtils --private-key $PRIVATE_KEY --rpc-url $RPC_URL --chain $CHAIN_ID --zksync +forge create src/libraries/CommandUtils.sol:CommandUtils --private-key $PRIVATE_KEY --rpc-url $RPC_URL --chain $CHAIN_ID --zksync --libraries src/libraries/DecimalUtils.sol:DecimalUtils:{DECIMAL_UTILS_ADDRESS_YOU_DEPLOYED} +forge create src/libraries/StringUtils.sol:StringUtils --private-key $PRIVATE_KEY --rpc-url $RPC_URL --chain $CHAIN_ID --zksync ``` -After that, you can see the following line in foundry.toml. -Also, this line is needed only for foundry-zksync, if you use foundry, please remove this line. Otherwise, the test will fail. +After that, you can see the following lines in the foundry.toml. Please replace `{PROJECT_DIR}` and `{DEPLOYED_ADDRESS}`. +Also, this lines are needed only for foundry-zksync, if you use normal foundry commands, please comment out. + ``` libraries = [ "{PROJECT_DIR}/packages/contracts/src/libraries/DecimalUtils.sol:DecimalUtils:{DEPLOYED_ADDRESS}", - "{PROJECT_DIR}/packages/contracts/src/libraries/SubjectUtils.sol:SubjectUtils:{DEPLOYED_ADDRESS}"] + "{PROJECT_DIR}/packages/contracts/src/libraries/CommandUtils.sol:CommandUtils:{DEPLOYED_ADDRESS}" + "{PROJECT_DIR}/packages/contracts/src/libraries/StringUtils.sol:StringUtils:{DEPLOYED_ADDRESS}" +] ``` -Incidentally, the above line already exists in `foundy.toml` with it commented out, if you uncomment it by replacing `{PROJECT_DIR}` with the appropriate path, it will also work. - About Create2, `L2ContractHelper.computeCreate2Address` should be used. -And `type(ERC1967Proxy).creationCode` doesn't work correctly in zkSync. -We need to hardcode the `type(ERC1967Proxy).creationCode` to bytecodeHash. -Perhaps that is different value in each compiler version. - -You should replace the following line to the correct hash. -packages/contracts/src/EmailAccountRecovery.sol:L111 - -See, test/ComputeCreate2Address.t.sol - -# For zkSync testing - -Run `yarn zktest`. - -Current foundry-zksync overrides the foundry behavior. If you installed foundry-zksync, some EVM code will be different and some test cases will be failed. If you want to test on other EVM, please install foundry. - -Even if the contract size is fine for EVM, it may exceed the bytecode size limit for zksync, and the test may not be executed. -Therefore, EmailAccountRecovery.t.sol has been splited. +`type(ERC1967Proxy).creationCode` doesn't work correctly in ZKsync. +We need to use the bytecode hash intead of `type(ERC1967Proxy).creationCode`. +Perhaps that is a different value in each compiler version and library addresses. -Currently some test cases are not work correctly because there is a issue about missing libraries. +Run the following commands, you'll get the bytecode hash. -https://github.com/matter-labs/foundry-zksync/issues/382 +``` +forge test --match-test "testComputeCreate2Address" --no-match-contract ".*Script.*" --system-mode=true --zksync --gas-limit 1000000000 --chain 300 -vvv --fork-url http://127.0.0.1:8011 +``` -Failing test cases are here. +And then, you should replace `{YOUR_BYTECODE_HASH}` in the .env -DKIMRegistryUpgrade.t.sol +``` +PROXY_BYTECODE_HASH={YOUR_BYTECODE_HASH} +``` -- testAuthEmail() +## Unit tests -EmailAuth.t.sol +Run the following commands -- testAuthEmail() -- testExpectRevertAuthEmailEmailNullifierAlreadyUsed() -- testExpectRevertAuthEmailInvalidEmailProof() -- testExpectRevertAuthEmailInvalidSubject() -- testExpectRevertAuthEmailInvalidTimestamp() +``` +source .env +yarn zktest +``` -EmailAuthWithUserOverrideableDkim.t.sol +Even if the contract size is fine for EVM, it may exceed the bytecode size limit for zksync, and the test may not be executed. If you encountered the contract size error, please consider the contract design. -- testAuthEmail() +## Integration tests -# For integration testing +``` +source .env +forge test --match-contract "IntegrationZKSyncTest" --system-mode=true --zksync --gas-limit 1000000000 --chain 300 -vvv --ffi +``` -To pass the instegration testing, you should use era-test-node. -See the following URL and install it. -https://github.com/matter-labs/era-test-node +## Deployment (For zksync sepolia) -Run the era-test-node +As you saw before, you need to deploy missing libraries. +You can deploy them by the following commands for example. ``` -era_test_node fork https://sepolia.era.zksync.dev +export PRIVATE_KEY={YOUR_PRIVATE_KEY} +export RPC_URL=https://sepolia.era.zksync.dev +export CHAIN_ID=300 + +forge create src/libraries/DecimalUtils.sol:DecimalUtils --private-key $PRIVATE_KEY --rpc-url $RPC_URL --chain $CHAIN_ID --zksync +forge create src/libraries/CommandUtils.sol:CommandUtils --private-key $PRIVATE_KEY --rpc-url $RPC_URL --chain $CHAIN_ID --zksync --libraries src/libraries/DecimalUtils.sol:DecimalUtils:{DECIMAL_UTILS_ADDRESS_YOU_DEPLOYED} +forge create src/libraries/StringUtils.sol:StringUtils --private-key $PRIVATE_KEY --rpc-url $RPC_URL --chain $CHAIN_ID --zksync ``` -You remove .zksolc-libraries-cache directory, and run the following command. +And then you need to replace `{PROJECT_DIR}` and `{DEPLOYED_ADDRESS}` in the foundy.toml. ``` -forge build --zksync --zk-detect-missing-libraries +libraries = [ + "{PROJECT_DIR}/packages/contracts/src/libraries/DecimalUtils.sol:DecimalUtils:{DEPLOYED_ADDRESS}", + "{PROJECT_DIR}/packages/contracts/src/libraries/CommandUtils.sol:CommandUtils:{DEPLOYED_ADDRESS}"] + "{PROJECT_DIR}/packages/contracts/src/libraries/StringUtils.sol:StringUtils:{DEPLOYED_ADDRESS}" ``` -As you saw before, you need to deploy missing libraries. -You can deploy them by the following command for example. +Run this command again, you'll get the bytecode hash. ``` -Missing libraries detected: src/libraries/SubjectUtils.sol:SubjectUtils, src/libraries/DecimalUtils.sol:DecimalUtils - -Run the following command in order to deploy each missing library: - -forge create src/libraries/DecimalUtils.sol:DecimalUtils --private-key {YOUR_PRIVATE_KEY} --rpc-url http://127.0.0.1:8011 --chain 260 --zksync -forge create src/libraries/SubjectUtils.sol:SubjectUtils --private-key {YOUR_PRIVATE_KEY} --rpc-url http://127.0.0.1:8011 --chain 260 --zksync --libraries src/libraries/DecimalUtils.sol:DecimalUtils:{DECIMAL_UTILS_DEPLOYED_ADDRESS} +forge test --match-test "testComputeCreate2Address" --no-match-contract ".*Script.*" --system-mode=true --zksync --gas-limit 1000000000 --chain 300 -vvv --fork-url http://127.0.0.1:8011 ``` -Set the libraries in foundry.toml using the above deployed address. - -And then, run the integration testing. +And then, you should replace `{YOUR_BYTECODE_HASH}` in the .env ``` -forge test --match-contract "IntegrationZkSyncTest" --system-mode=true --zksync --gas-limit 1000000000 --chain 300 -vvv --ffi +PROXY_BYTECODE_HASH={YOUR_BYTECODE_HASH} ``` -# For zkSync deployment (For test net) - -You need to edit .env at first. -Second just run the following commands with `--zksync` +Run the deploy script ``` source .env + +export RPC_URL=https://sepolia.era.zksync.dev +export CHAIN_ID=300 + forge script script/DeployRecoveryControllerZKSync.s.sol:Deploy --zksync --rpc-url $RPC_URL --broadcast --slow --via-ir --system-mode true -vvvv ``` +# Emergency Response + +For information on how upgrade contracts for handling emergency situations, please refer to our [Upgrading Contracts](../../docs/upgrade.md). \ No newline at end of file diff --git a/packages/contracts/foundry.toml b/packages/contracts/foundry.toml index 7ff2e1a0..7ea45184 100644 --- a/packages/contracts/foundry.toml +++ b/packages/contracts/foundry.toml @@ -4,13 +4,13 @@ out = "artifacts" libs = ["../../node_modules", "lib"] optimizer = true # The following line `via-ir = true` is needed to compile this project using zksync features -# See README.md for more details -> TODO # via-ir = true optimizer-runs = 20_000 fs_permissions = [ { access = "read", path = "./artifacts/WETH9.sol/WETH9.json" }, { access = "read", path = "./test/build_integration" }, { access = "read", path = "./zkout/ERC1967Proxy.sol/ERC1967Proxy.json" }, + { access = "read", path = "./artifacts" }, ] solc = "0.8.26" @@ -18,13 +18,16 @@ solc = "0.8.26" # See more config options https://github.com/foundry-rs/foundry/tree/master/config # OpenZeppelin +ffi = true +ast = true build_info = true extra_output = ["storageLayout"] -# For missing libraries, please comment out this if you use foundry-zksync +# For missing libraries, please comment out following line and replace some placeholders if you use foundry-zksync #libraries = [ -# "{PROJECT_DIR}/packages/contracts/src/libraries/DecimalUtils.sol:DecimalUtils:0x91cc0f0a227b8dd56794f9391e8af48b40420a0b", -# "{PROJECT_DIR}/packages/contracts/src/libraries/SubjectUtils.sol:SubjectUtils:0x981e3df952358a57753c7b85de7949da4abcf54a" +# "{PROJECT_DIR}/packages/contracts/src/libraries/DecimalUtils.sol:DecimalUtils:{DEPLOYED_ADDRESS}", +# "{PROJECT_DIR}/packages/contracts/src/libraries/CommandUtils.sol:CommandUtils:{DEPLOYED_ADDRESS}", +# "{PROJECT_DIR}/packages/contracts/src/libraries/StringUtils.sol:StringUtils:{DEPLOYED_ADDRESS}" #] [rpc_endpoints] @@ -33,14 +36,12 @@ sepolia = "${SEPOLIA_RPC_URL}" mainnet = "${MAINNET_RPC_URL}" [etherscan] -sepolia = { key = "${ETHERSCAN_API_KEY}" } -mainnet = { key = "${ETHERSCAN_API_KEY}" } +# sepolia = { key = "${ETHERSCAN_API_KEY}" } +# mainnet = { key = "${ETHERSCAN_API_KEY}" } -[profile.default.zksync] +[profile.default.zksync] src = 'src' libs = ["node_modules", "lib"] fallback_oz = true is_system = true mode = "3" - -zksolc = "1.5.0" \ No newline at end of file diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 44bae057..817a38e0 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -4,25 +4,30 @@ "license": "MIT", "scripts": { "build": "forge build --skip '*ZKSync*'", - "zkbuild": "forge build --zksync", - "test": "forge test --no-match-test \"testIntegration\" --skip '*ZKSync*'", - "zktest": "forge test --no-match-test \"testIntegration\" --system-mode=true --zksync --gas-limit 1000000000 --chain 300", - "build": "forge build --skip '*ZKSync*'", - "zkbuild": "forge build --zksync", - "test": "forge test --no-match-test \"testIntegration\" --skip '*ZKSync*'", - "zktest": "forge test --no-match-test \"testIntegration\" --system-mode=true --zksync --gas-limit 1000000000 --chain 300", + "test": "forge test --force --no-match-test \"testIntegration\" --no-match-contract \".*Script.*\" --skip '*ZKSync*'", + "test:script": "forge test --force --no-match-test \"testIntegration\" --skip '*ZKSync*' --match-path test/script/**/*.sol --threads 1", + "zkbuild": "forge build --skip test --zksync", + "zktest": "forge test --no-match-test \"testIntegration\" --no-match-contract \".*Script.*\" --system-mode=true --zksync --gas-limit 2000000000 --chain 300 --fork-url http://127.0.0.1:8011", "lint": "solhint 'src/**/*.sol'" }, "dependencies": { + "@matterlabs/zksync-contracts": "^0.6.1", "@openzeppelin/contracts": "^5.0.0", "@openzeppelin/contracts-upgradeable": "^5.0.0", - "@zk-email/contracts": "^6.1.5", - "@matterlabs/zksync-contracts": "^0.6.1", - "solady": "^0.0.123" + "@zk-email/contracts": "^6.3.1", + "solady": "^0.0.123", + "solidity-stringutils": "github:LayerZero-Labs/solidity-stringutils" }, "devDependencies": { "ds-test": "https://github.com/dapphub/ds-test", "forge-std": "https://github.com/foundry-rs/forge-std", "solhint": "^3.6.1" - } -} + }, + "files": [ + "/src", + "foundry.toml", + "package.json", + "README.md", + "remappings.txt" + ] +} \ No newline at end of file diff --git a/packages/contracts/remappings.txt b/packages/contracts/remappings.txt index 1ae10899..c22d4aa9 100644 --- a/packages/contracts/remappings.txt +++ b/packages/contracts/remappings.txt @@ -6,4 +6,6 @@ forge-std/=../../node_modules/forge-std/src ds-test/=../../node_modules/ds-test/src solady/=../../node_modules/solady/src/ -accountabstraction/=../../node_modules/accountabstraction/ \ No newline at end of file +accountabstraction/=../../node_modules/accountabstraction/ +solidity-stringutils/=../../node_modules/solidity-stringutils/ +openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/ \ No newline at end of file diff --git a/packages/contracts/script/BaseDeployScript.sol b/packages/contracts/script/BaseDeployScript.sol new file mode 100644 index 00000000..08708d81 --- /dev/null +++ b/packages/contracts/script/BaseDeployScript.sol @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import {Script} from "forge-std/Script.sol"; +import {console} from "forge-std/console.sol"; +import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import {UserOverrideableDKIMRegistry} from "@zk-email/contracts/UserOverrideableDKIMRegistry.sol"; + +import {SimpleWallet} from "../test/helpers/SimpleWallet.sol"; +import {RecoveryController} from "../test/helpers/RecoveryController.sol"; +import {RecoveryControllerZKSync} from "../test/helpers/RecoveryControllerZKSync.sol"; +import {ZKSyncCreate2Factory} from "../src/utils/ZKSyncCreate2Factory.sol"; +import {Verifier} from "../src/utils/Verifier.sol"; +import {Groth16Verifier} from "../src/utils/Groth16Verifier.sol"; +import {ECDSAOwnedDKIMRegistry} from "../src/utils/ECDSAOwnedDKIMRegistry.sol"; +import {EmailAuth} from "../src/EmailAuth.sol"; + +contract BaseDeployScript is Script { + address initialOwner; + uint256 deployerPrivateKey; + + /// @notice Sets up deployment configuration based on whether using Defender or private key + function run() public virtual { + deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + if (deployerPrivateKey == 0) { + console.log("PRIVATE_KEY env var not set"); + return; + } + + initialOwner = vm.envOr("INITIAL_OWNER", address(0)); + if (initialOwner == address(0)) { + initialOwner = vm.addr(deployerPrivateKey); + } + } + + /// @notice Deploys a UserOverrideableDKIMRegistry contract with a specified owner, dkim signer and time delay + function deployUserOverrideableDKIMRegistry( + address owner, + address dkimSigner, + uint256 timeDelay + ) public returns (address) { + address dkimProxyAddress; + UserOverrideableDKIMRegistry dkimImpl = new UserOverrideableDKIMRegistry(); + dkimProxyAddress = address( + new ERC1967Proxy( + address(dkimImpl), + abi.encodeCall( + UserOverrideableDKIMRegistry.initialize, + (owner, dkimSigner, timeDelay) + ) + ) + ); + console.log( + "UseroverrideableDKIMRegistry proxy deployed at: %s", + dkimProxyAddress + ); + return dkimProxyAddress; + } + + /// @notice Deploys an ECDSAOwnedDKIMRegistry contract with a specified owner and dkim signer + function deployECDSAOwnedDKIMRegistry( + address owner, + address dkimSigner + ) public returns (address) { + address ecdsaDkimProxyAddress; + ECDSAOwnedDKIMRegistry ecdsaDkimImpl = new ECDSAOwnedDKIMRegistry(); + ecdsaDkimProxyAddress = address( + new ERC1967Proxy( + address(ecdsaDkimImpl), + abi.encodeCall(ecdsaDkimImpl.initialize, (owner, dkimSigner)) + ) + ); + console.log( + "ECDSAOwnedDKIMRegistry proxy deployed at: %s", + ecdsaDkimProxyAddress + ); + return ecdsaDkimProxyAddress; + } + + /// @notice Deploys a Verifier contract with a specified owner and Groth16 verifier + function deployVerifier(address owner) public returns (address) { + address verifierProxyAddress; + Verifier verifierImpl = new Verifier(); + Groth16Verifier groth16Verifier = new Groth16Verifier(); + verifierProxyAddress = address( + new ERC1967Proxy( + address(verifierImpl), + abi.encodeCall( + verifierImpl.initialize, + (owner, address(groth16Verifier)) + ) + ) + ); + console.log("Verifier deployed at: %s", verifierProxyAddress); + return verifierProxyAddress; + } + + /// @notice Deploys an EmailAuth implementation contract + function deployEmailAuthImplementation() public returns (address) { + address emailAuthImplAddress; + emailAuthImplAddress = address(new EmailAuth()); + console.log( + "EmailAuth implementation deployed at: %s", + emailAuthImplAddress + ); + return emailAuthImplAddress; + } + + /// @notice Deploys a RecoveryController contract with specified owner, verifier, DKIM registry and EmailAuth implementation + function deployRecoveryController( + address owner, + address verifier, + address dkim, + address emailAuthImpl + ) public returns (address) { + address recoveryControllerProxyAddress; + RecoveryController recoveryControllerImpl = new RecoveryController(); + recoveryControllerProxyAddress = address( + new ERC1967Proxy( + address(recoveryControllerImpl), + abi.encodeCall( + RecoveryController.initialize, + (owner, verifier, dkim, emailAuthImpl) + ) + ) + ); + console.log( + "RecoveryController deployed at: %s", + recoveryControllerProxyAddress + ); + return recoveryControllerProxyAddress; + } + + /// @notice Deploys a ZK Sync specific RecoveryController with additional factory and proxy bytecode parameters + function deployRecoveryControllerZKSync( + address owner, + address verifier, + address dkim, + address emailAuthImpl, + address factoryImpl, + bytes32 proxyBytecodeHash + ) public returns (address) { + address recoveryControllerProxyAddress; + RecoveryControllerZKSync recoveryControllerZKSyncImpl = new RecoveryControllerZKSync(); + recoveryControllerProxyAddress = address( + new ERC1967Proxy( + address(recoveryControllerZKSyncImpl), + abi.encodeCall( + recoveryControllerZKSyncImpl.initialize, + ( + owner, + verifier, + dkim, + emailAuthImpl, + factoryImpl, + proxyBytecodeHash + ) + ) + ) + ); + console.log( + "RecoveryControllerZKSync deployed at: %s", + recoveryControllerProxyAddress + ); + return recoveryControllerProxyAddress; + } + + /// @notice Deploys a ZK Sync Create2 factory contract + function deployZKSyncCreate2Factory() public returns (address) { + address factoryImplAddress; + factoryImplAddress = address(new ZKSyncCreate2Factory()); + console.log("ZKSyncCreate2Factory deployed at: %s", factoryImplAddress); + return factoryImplAddress; + } + + /// @notice Deploys a SimpleWallet contract with a specified owner and recovery controller + function deploySimpleWallet( + address owner, + address recoveryController + ) public returns (address) { + address simpleWalletProxyAddress; + SimpleWallet simpleWalletImpl = new SimpleWallet(); + simpleWalletProxyAddress = address( + new ERC1967Proxy( + address(simpleWalletImpl), + abi.encodeCall( + simpleWalletImpl.initialize, + (owner, address(recoveryController)) + ) + ) + ); + console.log("SimpleWallet deployed at: %s", simpleWalletProxyAddress); + return simpleWalletProxyAddress; + } +} diff --git a/packages/contracts/script/ChangeOwners.s.sol b/packages/contracts/script/ChangeOwners.s.sol index 8f7bd0ef..c33dda13 100644 --- a/packages/contracts/script/ChangeOwners.s.sol +++ b/packages/contracts/script/ChangeOwners.s.sol @@ -4,13 +4,10 @@ pragma solidity ^0.8.13; import "forge-std/Script.sol"; import "../src/utils/Verifier.sol"; -import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; -import "../src/utils/ForwardDKIMRegistry.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; contract ChangeOwners is Script { function run() external { - uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); if (deployerPrivateKey == 0) { console.log("PRIVATE_KEY env var not set"); diff --git a/packages/contracts/script/ChangeSourceInForwardDKIMRegistry.s.sol b/packages/contracts/script/ChangeSourceInForwardDKIMRegistry.s.sol deleted file mode 100644 index 4788ab79..00000000 --- a/packages/contracts/script/ChangeSourceInForwardDKIMRegistry.s.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import "forge-std/Script.sol"; - -import "../src/utils/ForwardDKIMRegistry.sol"; - -contract ChangeSource is Script { - function run() external { - uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); - if (deployerPrivateKey == 0) { - console.log("PRIVATE_KEY env var not set"); - return; - } - address dkimAddr = vm.envAddress("DKIM"); - if (dkimAddr == address(0)) { - console.log("DKIM env var not set"); - return; - } - address newSource = vm.envAddress("NEW_SOURCE"); - if (newSource == address(0)) { - console.log("NEW_SOURCE env var not set"); - return; - } - vm.startBroadcast(deployerPrivateKey); - ForwardDKIMRegistry dkim = ForwardDKIMRegistry(dkimAddr); - dkim.changeSourceDKIMRegistry(newSource); - vm.stopBroadcast(); - } -} diff --git a/packages/contracts/script/DeployCommons.s.sol b/packages/contracts/script/DeployCommons.s.sol deleted file mode 100644 index 9a392170..00000000 --- a/packages/contracts/script/DeployCommons.s.sol +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import "forge-std/Script.sol"; - -import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import "../test/helpers/SimpleWallet.sol"; -import "../src/utils/Verifier.sol"; -import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; -// import "../src/utils/ForwardDKIMRegistry.sol"; -import "../src/EmailAuth.sol"; -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; - -contract Deploy is Script { - using ECDSA for *; - - ECDSAOwnedDKIMRegistry dkimImpl; - ECDSAOwnedDKIMRegistry dkim; - // ForwardDKIMRegistry dkimImpl; - // ForwardDKIMRegistry dkim; - Verifier verifierImpl; - Verifier verifier; - EmailAuth emailAuthImpl; - SimpleWallet simpleWalletImpl; - - function run() external { - uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); - if (deployerPrivateKey == 0) { - console.log("PRIVATE_KEY env var not set"); - return; - } - address signer = vm.envAddress("SIGNER"); - if (signer == address(0)) { - console.log("SIGNER env var not set"); - return; - } - - vm.startBroadcast(deployerPrivateKey); - address initialOwner = vm.addr(deployerPrivateKey); - console.log("Initial owner: %s", vm.toString(initialOwner)); - // Deploy ECDSA DKIM registry - { - dkimImpl = new ECDSAOwnedDKIMRegistry(); - console.log( - "ECDSAOwnedDKIMRegistry implementation deployed at: %s", - address(dkimImpl) - ); - ERC1967Proxy dkimProxy = new ERC1967Proxy( - address(dkimImpl), - abi.encodeCall(dkimImpl.initialize, (initialOwner, signer)) - ); - dkim = ECDSAOwnedDKIMRegistry(address(dkimProxy)); - console.log( - "ECDSAOwnedDKIMRegistry deployed at: %s", - address(dkim) - ); - vm.setEnv("ECDSA_DKIM", vm.toString(address(dkim))); - } - - // Deploy Forward DKIM registry - // { - // dkimImpl = new ForwardDKIMRegistry(); - // console.log( - // "ForwardDKIMRegistry implementation deployed at: %s", - // address(dkimImpl) - // ); - // ERC1967Proxy dkimProxy = new ERC1967Proxy( - // address(dkimImpl), - // abi.encodeCall(dkimImpl.initialize, (initialOwner, signer)) - // ); - // dkim = ForwardDKIMRegistry(address(dkimProxy)); - // console.log("ForwardDKIMRegistry deployed at: %s", address(dkim)); - // vm.setEnv("DKIM", vm.toString(address(dkim))); - // } - - // Deploy Verifier - { - verifierImpl = new Verifier(); - console.log( - "Verifier implementation deployed at: %s", - address(verifierImpl) - ); - ERC1967Proxy verifierProxy = new ERC1967Proxy( - address(verifierImpl), - abi.encodeCall(verifierImpl.initialize, (initialOwner)) - ); - verifier = Verifier(address(verifierProxy)); - console.log("Verifier deployed at: %s", address(verifier)); - vm.setEnv("VERIFIER", vm.toString(address(verifier))); - } - - // Deploy EmailAuth Implementation - { - emailAuthImpl = new EmailAuth(); - console.log( - "EmailAuth implementation deployed at: %s", - address(emailAuthImpl) - ); - vm.setEnv("EMAIL_AUTH_IMPL", vm.toString(address(emailAuthImpl))); - } - - // Deploy SimpleWallet Implementation - { - simpleWalletImpl = new SimpleWallet(); - console.log( - "SimpleWallet implementation deployed at: %s", - address(simpleWalletImpl) - ); - vm.setEnv( - "SIMPLE_WALLET_IMPL", - vm.toString(address(simpleWalletImpl)) - ); - } - vm.stopBroadcast(); - } -} diff --git a/packages/contracts/script/DeployEmailAuthWithCreate2ZKSync.s.sol b/packages/contracts/script/DeployEmailAuthWithCreate2ZKSync.s.sol index 59972915..2f8fc51f 100644 --- a/packages/contracts/script/DeployEmailAuthWithCreate2ZKSync.s.sol +++ b/packages/contracts/script/DeployEmailAuthWithCreate2ZKSync.s.sol @@ -1,46 +1,34 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; -import "forge-std/Script.sol"; - import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import "../src/EmailAuth.sol"; import {ZKSyncCreate2Factory} from "../src/utils/ZKSyncCreate2Factory.sol"; +import "./BaseDeployScript.sol"; -contract Deploy is Script { +contract Deploy is BaseDeployScript { using ECDSA for *; - function run() external { - uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); - if (deployerPrivateKey == 0) { - console.log("PRIVATE_KEY env var not set"); - return; - } - + function run() public override { + super.run(); vm.startBroadcast(deployerPrivateKey); - EmailAuth emailAuth = new EmailAuth(); + EmailAuth emailAuth = EmailAuth(deployEmailAuthImplementation()); address recoveredAccount = address(0x1); bytes32 accountSalt = 0x0; - - ERC1967Proxy proxy = new ERC1967Proxy( - address(emailAuth), - abi.encodeCall(emailAuth.initialize, (recoveredAccount, accountSalt, address(this))) + address controller = address(this); + bytes memory emailAuthInit = abi.encode( + address(emailAuth), abi.encodeCall(EmailAuth.initialize, (recoveredAccount, accountSalt, controller)) ); - console.log("normal deployed proxyAddress %s", address(proxy)); - ZKSyncCreate2Factory factory = new ZKSyncCreate2Factory(); + ZKSyncCreate2Factory factory = ZKSyncCreate2Factory(deployZKSyncCreate2Factory()); string memory artifact = vm.readFile("zkout/ERC1967Proxy.sol/ERC1967Proxy.json"); bytes32 bytecodeHash = vm.parseJsonBytes32(artifact, ".hash"); console.log("bytecodeHash"); console.logBytes32(bytes32(bytecodeHash)); - bytes memory emailAuthInit = abi.encode( - address(emailAuth), abi.encodeCall(EmailAuth.initialize, (recoveredAccount, accountSalt, address(this))) - ); - address computedAddress = factory.computeAddress(accountSalt, bytecodeHash, emailAuthInit); console.log("computedAddress", computedAddress); diff --git a/packages/contracts/script/DeployForwardDKIMRegistry.s.sol b/packages/contracts/script/DeployForwardDKIMRegistry.s.sol deleted file mode 100644 index f2108c05..00000000 --- a/packages/contracts/script/DeployForwardDKIMRegistry.s.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import "forge-std/Script.sol"; - -import "../src/utils/ForwardDKIMRegistry.sol"; -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; - -contract Deploy is Script { - ForwardDKIMRegistry dkimImpl; - ForwardDKIMRegistry dkim; - function run() external { - uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); - if (deployerPrivateKey == 0) { - console.log("PRIVATE_KEY env var not set"); - return; - } - address sourceDKIMRegistry = vm.envAddress("SOURCE_DKIM"); - if (sourceDKIMRegistry == address(0)) { - console.log("SOURCE_DKIM env var not set"); - return; - } - - vm.startBroadcast(deployerPrivateKey); - address initialOwner = vm.addr(deployerPrivateKey); - console.log("Initial owner: %s", vm.toString(initialOwner)); - - // Deploy Forward DKIM registry - { - dkimImpl = new ForwardDKIMRegistry(); - console.log( - "ForwardDKIMRegistry implementation deployed at: %s", - address(dkimImpl) - ); - ERC1967Proxy dkimProxy = new ERC1967Proxy( - address(dkimImpl), - abi.encodeCall( - dkimImpl.initialize, - (initialOwner, sourceDKIMRegistry) - ) - ); - dkim = ForwardDKIMRegistry(address(dkimProxy)); - console.log("ForwardDKIMRegistry deployed at: %s", address(dkim)); - vm.setEnv("DKIM", vm.toString(address(dkim))); - } - - vm.stopBroadcast(); - } -} diff --git a/packages/contracts/script/DeployRecoveryController.s.sol b/packages/contracts/script/DeployRecoveryController.s.sol index 5df2c89a..40a47b31 100644 --- a/packages/contracts/script/DeployRecoveryController.s.sol +++ b/packages/contracts/script/DeployRecoveryController.s.sol @@ -1,150 +1,75 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; -import "forge-std/Script.sol"; - -import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import "../test/helpers/SimpleWallet.sol"; -import "../test/helpers/RecoveryController.sol"; -import "../src/utils/Verifier.sol"; -import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; -// import "../src/utils/ForwardDKIMRegistry.sol"; -import "../src/EmailAuth.sol"; +import {console} from "forge-std/console.sol"; +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import {SimpleWallet} from "../test/helpers/SimpleWallet.sol"; +import {RecoveryController} from "../test/helpers/RecoveryController.sol"; +import {Verifier} from "../src/utils/Verifier.sol"; +import {Groth16Verifier} from "../src/utils/Groth16Verifier.sol"; +import {ECDSAOwnedDKIMRegistry} from "../src/utils/ECDSAOwnedDKIMRegistry.sol"; +import {EmailAuth} from "../src/EmailAuth.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import {UserOverrideableDKIMRegistry} from "@zk-email/contracts/UserOverrideableDKIMRegistry.sol"; +import {BaseDeployScript} from "./BaseDeployScript.sol"; -contract Deploy is Script { +contract Deploy is BaseDeployScript { using ECDSA for *; - ECDSAOwnedDKIMRegistry dkim; - Verifier verifier; - EmailAuth emailAuthImpl; - SimpleWallet simpleWallet; - RecoveryController recoveryController; - - function run() external { - uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); - if (deployerPrivateKey == 0) { - console.log("PRIVATE_KEY env var not set"); - return; - } - address signer = vm.envAddress("SIGNER"); - if (signer == address(0)) { - console.log("SIGNER env var not set"); - return; - } + address dkim; + address verifier; + address emailAuthImpl; + address simpleWallet; + address recoveryController; + function run() public override { + super.run(); vm.startBroadcast(deployerPrivateKey); - address initialOwner = msg.sender; - // Deploy ECDSAOwned DKIM registry - dkim = ECDSAOwnedDKIMRegistry(vm.envOr("ECDSA_DKIM", address(0))); + // Deploy User-overrideable DKIM registry + dkim = vm.envOr("DKIM", address(0)); if (address(dkim) == address(0)) { - ECDSAOwnedDKIMRegistry ecdsaDkimImpl = new ECDSAOwnedDKIMRegistry(); - console.log( - "ECDSAOwnedDKIMRegistry implementation deployed at: %s", - address(ecdsaDkimImpl) - ); - ERC1967Proxy ecdsaDkimProxy = new ERC1967Proxy( - address(ecdsaDkimImpl), - abi.encodeCall(ecdsaDkimImpl.initialize, (initialOwner, signer)) - ); - dkim = ECDSAOwnedDKIMRegistry(address(ecdsaDkimProxy)); - console.log( - "ECDSAOwnedDKIMRegistry deployed at: %s", - address(dkim) + address dkimSigner = vm.envAddress("DKIM_SIGNER"); + if (dkimSigner == address(0)) { + console.log("DKIM_SIGNER env var not set"); + return; + } + uint256 timeDelay = vm.envOr("DKIM_DELAY", uint256(0)); + console.log("DKIM_DELAY: %s", timeDelay); + + dkim = deployUserOverrideableDKIMRegistry( + initialOwner, + dkimSigner, + timeDelay ); - vm.setEnv("ECDSA_DKIM", vm.toString(address(dkim))); - // dkimImpl = new ForwardDKIMRegistry(); - // console.log( - // "ForwardDKIMRegistry implementation deployed at: %s", - // address(dkimImpl) - // ); - // ERC1967Proxy dkimProxy = new ERC1967Proxy( - // address(dkimImpl), - // abi.encodeCall(dkimImpl.initialize, (initialOwner, signer)) - // ); - // dkim = ForwardDKIMRegistry(address(dkimProxy)); - // console.log("ForwardDKIMRegistry deployed at: %s", address(dkim)); - // vm.setEnv("DKIM", vm.toString(address(dkim))); } + // Deploy Verifier - verifier = Verifier(vm.envOr("VERIFIER", address(0))); + verifier = vm.envOr("VERIFIER", address(0)); if (address(verifier) == address(0)) { - Verifier verifierImpl = new Verifier(); - console.log( - "Verifier implementation deployed at: %s", - address(verifierImpl) - ); - ERC1967Proxy verifierProxy = new ERC1967Proxy( - address(verifierImpl), - abi.encodeCall(verifierImpl.initialize, (initialOwner)) - ); - verifier = Verifier(address(verifierProxy)); - console.log("Verifier deployed at: %s", address(verifier)); - vm.setEnv("VERIFIER", vm.toString(address(verifier))); + verifier = deployVerifier(initialOwner); } // Deploy EmailAuth Implementation - emailAuthImpl = EmailAuth(vm.envOr("EMAIL_AUTH_IMPL", address(0))); - if (address(emailAuthImpl) == address(0)) { - emailAuthImpl = new EmailAuth(); - console.log( - "EmailAuth implementation deployed at: %s", - address(emailAuthImpl) - ); - vm.setEnv("EMAIL_AUTH_IMPL", vm.toString(address(emailAuthImpl))); + emailAuthImpl = vm.envOr("EMAIL_AUTH_IMPL", address(0)); + if (emailAuthImpl == address(0)) { + emailAuthImpl = deployEmailAuthImplementation(); } // Create RecoveryController as EmailAccountRecovery implementation - { - RecoveryController recoveryControllerImpl = new RecoveryController(); - ERC1967Proxy recoveryControllerProxy = new ERC1967Proxy( - address(recoveryControllerImpl), - abi.encodeCall( - recoveryControllerImpl.initialize, - ( - signer, - address(verifier), - address(dkim), - address(emailAuthImpl) - ) - ) - ); - recoveryController = RecoveryController( - payable(address(recoveryControllerProxy)) - ); - console.log( - "RecoveryController deployed at: %s", - address(recoveryController) - ); - vm.setEnv( - "RECOVERY_CONTROLLER", - vm.toString(address(recoveryController)) - ); - } + recoveryController = deployRecoveryController( + initialOwner, + address(verifier), + address(dkim), + address(emailAuthImpl) + ); // Deploy SimpleWallet Implementation - { - SimpleWallet simpleWalletImpl = new SimpleWallet(); - console.log( - "SimpleWallet implementation deployed at: %s", - address(simpleWalletImpl) - ); - vm.setEnv( - "SIMPLE_WALLET_IMPL", - vm.toString(address(simpleWalletImpl)) - ); - ERC1967Proxy simpleWalletProxy = new ERC1967Proxy( - address(simpleWalletImpl), - abi.encodeCall( - simpleWalletImpl.initialize, - (signer, address(recoveryController)) - ) - ); - simpleWallet = SimpleWallet(payable(address(simpleWalletProxy))); - console.log("SimpleWallet deployed at: %s", address(simpleWallet)); - vm.setEnv("SIMPLE_WALLET", vm.toString(address(simpleWallet))); - } + simpleWallet = deploySimpleWallet( + initialOwner, + address(recoveryController) + ); + vm.stopBroadcast(); } } diff --git a/packages/contracts/script/DeployRecoveryControllerZKSync.s.sol b/packages/contracts/script/DeployRecoveryControllerZKSync.s.sol index 6767cc5f..1d09be27 100644 --- a/packages/contracts/script/DeployRecoveryControllerZKSync.s.sol +++ b/packages/contracts/script/DeployRecoveryControllerZKSync.s.sol @@ -1,164 +1,77 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; -import "forge-std/Script.sol"; - -import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import "../test/helpers/SimpleWallet.sol"; -import "../test/helpers/RecoveryControllerZKSync.sol"; -import "../src/utils/Verifier.sol"; -import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; -// import "../src/utils/ForwardDKIMRegistry.sol"; -import "../src/EmailAuth.sol"; +import {console} from "forge-std/console.sol"; +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import {SimpleWallet} from "../test/helpers/SimpleWallet.sol"; +import {RecoveryControllerZKSync} from "../test/helpers/RecoveryControllerZKSync.sol"; +import {Verifier} from "../src/utils/Verifier.sol"; +import {Groth16Verifier} from "../src/utils/Groth16Verifier.sol"; +import {EmailAuth} from "../src/EmailAuth.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import {ZKSyncCreate2Factory} from "../src/utils/ZKSyncCreate2Factory.sol"; +import {UserOverrideableDKIMRegistry} from "@zk-email/contracts/UserOverrideableDKIMRegistry.sol"; +import {BaseDeployScript} from "./BaseDeployScript.sol"; -contract Deploy is Script { +contract Deploy is BaseDeployScript { using ECDSA for *; - ECDSAOwnedDKIMRegistry dkim; - Verifier verifier; - EmailAuth emailAuthImpl; - SimpleWallet simpleWallet; - RecoveryControllerZKSync recoveryControllerZKSync; - ZKSyncCreate2Factory factoryImpl; + address dkim; + address verifier; + address emailAuthImpl; + address simpleWallet; + address recoveryControllerZKSync; + address factory; - function run() external { - uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); - if (deployerPrivateKey == 0) { - console.log("PRIVATE_KEY env var not set"); - return; - } - address signer = vm.envAddress("SIGNER"); - if (signer == address(0)) { - console.log("SIGNER env var not set"); - return; + function run() public override { + super.run(); + + bytes32 proxyBytecodeHash = vm.envBytes32("PROXY_BYTECODE_HASH"); + if (proxyBytecodeHash == bytes32(0)) { + revert("PROXY_BYTECODE_HASH env var not set or invalid"); } vm.startBroadcast(deployerPrivateKey); - address initialOwner = msg.sender; - // Deploy ECDSAOwned DKIM registry - dkim = ECDSAOwnedDKIMRegistry(vm.envOr("ECDSA_DKIM", address(0))); + // Deploy Useroverrideable DKIM registry + dkim = vm.envOr("DKIM", address(0)); if (address(dkim) == address(0)) { - ECDSAOwnedDKIMRegistry ecdsaDkimImpl = new ECDSAOwnedDKIMRegistry(); - console.log( - "ECDSAOwnedDKIMRegistry implementation deployed at: %s", - address(ecdsaDkimImpl) - ); - ERC1967Proxy ecdsaDkimProxy = new ERC1967Proxy( - address(ecdsaDkimImpl), - abi.encodeCall(ecdsaDkimImpl.initialize, (initialOwner, signer)) - ); - dkim = ECDSAOwnedDKIMRegistry(address(ecdsaDkimProxy)); - console.log( - "ECDSAOwnedDKIMRegistry deployed at: %s", - address(dkim) - ); - vm.setEnv("ECDSA_DKIM", vm.toString(address(dkim))); - // dkimImpl = new ForwardDKIMRegistry(); - // console.log( - // "ForwardDKIMRegistry implementation deployed at: %s", - // address(dkimImpl) - // ); - // ERC1967Proxy dkimProxy = new ERC1967Proxy( - // address(dkimImpl), - // abi.encodeCall(dkimImpl.initialize, (initialOwner, signer)) - // ); - // dkim = ForwardDKIMRegistry(address(dkimProxy)); - // console.log("ForwardDKIMRegistry deployed at: %s", address(dkim)); - // vm.setEnv("DKIM", vm.toString(address(dkim))); + address dkimSigner = vm.envAddress("DKIM_SIGNER"); + if (dkimSigner == address(0)) { + console.log("DKIM_SIGNER env var not set"); + return; + } + uint256 timeDelay = vm.envOr("DKIM_DELAY", uint256(0)); + console.log("DKIM_DELAY: %s", timeDelay); + + dkim = deployUserOverrideableDKIMRegistry(initialOwner, dkimSigner, timeDelay); } + // Deploy Verifier - verifier = Verifier(vm.envOr("VERIFIER", address(0))); + verifier = vm.envOr("VERIFIER", address(0)); if (address(verifier) == address(0)) { - Verifier verifierImpl = new Verifier(); - console.log( - "Verifier implementation deployed at: %s", - address(verifierImpl) - ); - ERC1967Proxy verifierProxy = new ERC1967Proxy( - address(verifierImpl), - abi.encodeCall(verifierImpl.initialize, (initialOwner)) - ); - verifier = Verifier(address(verifierProxy)); - console.log("Verifier deployed at: %s", address(verifier)); - vm.setEnv("VERIFIER", vm.toString(address(verifier))); + verifier = deployVerifier(initialOwner); } // Deploy EmailAuth Implementation - emailAuthImpl = EmailAuth(vm.envOr("EMAIL_AUTH_IMPL", address(0))); + emailAuthImpl = vm.envOr("EMAIL_AUTH_IMPL", address(0)); if (address(emailAuthImpl) == address(0)) { - emailAuthImpl = new EmailAuth(); - console.log( - "EmailAuth implementation deployed at: %s", - address(emailAuthImpl) - ); - vm.setEnv("EMAIL_AUTH_IMPL", vm.toString(address(emailAuthImpl))); + emailAuthImpl = deployEmailAuthImplementation(); } // Deploy Factory - factoryImpl = ZKSyncCreate2Factory(vm.envOr("FACTORY", address(0))); - if (address(factoryImpl) == address(0)) { - factoryImpl = new ZKSyncCreate2Factory(); - console.log( - "Factory implementation deployed at: %s", - address(factoryImpl) - ); - vm.setEnv("FACTORY", vm.toString(address(factoryImpl))); + factory = vm.envOr("ZKSYNC_CREATE2_FACTORY", address(0)); + if (address(factory) == address(0)) { + factory = deployZKSyncCreate2Factory(); } // Create RecoveryControllerZKSync as EmailAccountRecovery implementation - { - RecoveryControllerZKSync recoveryControllerZKSyncImpl = new RecoveryControllerZKSync(); - ERC1967Proxy recoveryControllerZKSyncProxy = new ERC1967Proxy( - address(recoveryControllerZKSyncImpl), - abi.encodeCall( - recoveryControllerZKSyncImpl.initialize, - ( - signer, - address(verifier), - address(dkim), - address(emailAuthImpl), - address(factoryImpl) - ) - ) - ); - recoveryControllerZKSync = RecoveryControllerZKSync( - payable(address(recoveryControllerZKSyncProxy)) - ); - console.log( - "RecoveryControllerZKSync deployed at: %s", - address(recoveryControllerZKSync) - ); - vm.setEnv( - "RECOVERY_CONTROLLER_ZKSYNC", - vm.toString(address(recoveryControllerZKSync)) - ); - } + recoveryControllerZKSync = deployRecoveryControllerZKSync( + initialOwner, address(verifier), address(dkim), address(emailAuthImpl), address(factory), proxyBytecodeHash + ); // Deploy SimpleWallet Implementation - { - SimpleWallet simpleWalletImpl = new SimpleWallet(); - console.log( - "SimpleWallet implementation deployed at: %s", - address(simpleWalletImpl) - ); - vm.setEnv( - "SIMPLE_WALLET_IMPL", - vm.toString(address(simpleWalletImpl)) - ); - ERC1967Proxy simpleWalletProxy = new ERC1967Proxy( - address(simpleWalletImpl), - abi.encodeCall( - simpleWalletImpl.initialize, - (signer, address(recoveryControllerZKSync)) - ) - ); - simpleWallet = SimpleWallet(payable(address(simpleWalletProxy))); - console.log("SimpleWallet deployed at: %s", address(simpleWallet)); - vm.setEnv("SIMPLE_WALLET", vm.toString(address(simpleWallet))); - } + simpleWallet = deploySimpleWallet(initialOwner, address(recoveryControllerZKSync)); vm.stopBroadcast(); } } diff --git a/packages/contracts/script/DeploySimpleWallet.s.sol b/packages/contracts/script/DeploySimpleWallet.s.sol index e2f4321e..ab0a9c8c 100644 --- a/packages/contracts/script/DeploySimpleWallet.s.sol +++ b/packages/contracts/script/DeploySimpleWallet.s.sol @@ -1,55 +1,16 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; -import "forge-std/Script.sol"; +// import "forge-std/Script.sol"; -import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import "../test/helpers/SimpleWallet.sol"; -import "../src/utils/Verifier.sol"; -import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; -import "../src/EmailAuth.sol"; +import {BaseDeployScript} from "./BaseDeployScript.sol"; -contract Deploy is Script { - using ECDSA for *; - - function run() external { - uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); - if (deployerPrivateKey == 0) { - console.log("PRIVATE_KEY env var not set"); - return; - } - address dkim = vm.envAddress("DKIM"); - if (dkim == address(0)) { - console.log("DKIM env var not set"); - return; - } - address verifier = vm.envAddress("VERIFIER"); - if (verifier == address(0)) { - console.log("VERIFIER env var not set"); - return; - } - address emailAuthImpl = vm.envAddress("EMAIL_AUTH_IMPL"); - if (emailAuthImpl == address(0)) { - console.log("EMAIL_AUTH_IMPL env var not set"); - return; - } - address simpleWalletImpl = vm.envAddress("SIMPLE_WALLET_IMPL"); - if (simpleWalletImpl == address(0)) { - console.log("SIMPLE_WALLET_IMPL env var not set"); - return; - } - - vm.startBroadcast(deployerPrivateKey); - bytes memory data = abi.encodeWithSelector( - SimpleWallet(payable(simpleWalletImpl)).initialize.selector, - vm.addr(deployerPrivateKey), - verifier, - dkim, - emailAuthImpl - ); - ERC1967Proxy proxy = new ERC1967Proxy(address(simpleWalletImpl), data); - console.log("SimpleWallet deployed at: %s", address(proxy)); - vm.stopBroadcast(); +contract Deploy is BaseDeployScript { + function run() public override { + super.run(); + address controller = vm.envAddress("RECOVERY_CONTROLLER"); + deploySimpleWallet(initialOwner, address(controller)); } } diff --git a/packages/contracts/script/ReactivateDKIMPublicKeyHashSimpleWallet.s.sol b/packages/contracts/script/ReactivateDKIMPublicKeyHashSimpleWallet.s.sol new file mode 100644 index 00000000..8693c26f --- /dev/null +++ b/packages/contracts/script/ReactivateDKIMPublicKeyHashSimpleWallet.s.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "forge-std/Script.sol"; + +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import "../test/helpers/SimpleWallet.sol"; +import "../test/helpers/RecoveryController.sol"; +import "../src/utils/Verifier.sol"; +import "../src/utils/Groth16Verifier.sol"; +import "../src/EmailAuth.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import {UserOverrideableDKIMRegistry} from "@zk-email/contracts/UserOverrideableDKIMRegistry.sol"; +import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; + +contract ReactivatePublicKeyHash is Script { + using ECDSA for *; + + UserOverrideableDKIMRegistry dkim; + RecoveryController recoveryController; + + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + if (deployerPrivateKey == 0) { + console.log("PRIVATE_KEY env var not set"); + return; + } + address dkimAddr = vm.envAddress("DKIM"); + if (dkimAddr == address(0)) { + console.log("DKIM env var not set"); + return; + } + address walletAddr = vm.envAddress("SIMPLE_WALLET"); + if (walletAddr == address(0)) { + console.log("SIMPLE_WALLET env var not set"); + return; + } + dkim = UserOverrideableDKIMRegistry(dkimAddr); + string memory domainName = vm.envString("DOMAIN"); + if (bytes(domainName).length == 0) { + console.log("DOMAIN env var not set"); + return; + } + bytes32 publicKeyHash = vm.envBytes32("PUBLIC_KEY_HASH"); + if (publicKeyHash == bytes32(0)) { + console.log("PUBLIC_KEY_HASH env var not set"); + return; + } + string memory signedMsg = dkim.computeSignedMsg( + dkim.REACTIVATE_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(deployerPrivateKey, digest); + bytes memory signature = abi.encodePacked(r, s, v); + vm.startBroadcast(deployerPrivateKey); + dkim.reactivateDKIMPublicKeyHash( + domainName, + publicKeyHash, + walletAddr, + signature + ); + vm.stopBroadcast(); + } +} diff --git a/packages/contracts/script/RenounceOwners.s.sol b/packages/contracts/script/RenounceOwners.s.sol index d432b795..1fc2b405 100644 --- a/packages/contracts/script/RenounceOwners.s.sol +++ b/packages/contracts/script/RenounceOwners.s.sol @@ -5,7 +5,6 @@ import "forge-std/Script.sol"; import "../src/utils/Verifier.sol"; import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; -import "../src/utils/ForwardDKIMRegistry.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; contract RenounceOwners is Script { diff --git a/packages/contracts/script/RequestGuardianSimpleWallet.sol b/packages/contracts/script/RequestGuardianSimpleWallet.sol new file mode 100644 index 00000000..18a1ab88 --- /dev/null +++ b/packages/contracts/script/RequestGuardianSimpleWallet.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "forge-std/Script.sol"; + +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import "../test/helpers/SimpleWallet.sol"; +import "../src/utils/Verifier.sol"; +import "../src/utils/Groth16Verifier.sol"; +import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; +import "../src/EmailAuth.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; + +contract RequestGuardian is Script { + using ECDSA for *; + + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + if (deployerPrivateKey == 0) { + console.log("PRIVATE_KEY env var not set"); + return; + } + + address simpleWalletAddr = vm.envAddress("SIMPLE_WALLET"); + if (simpleWalletAddr == address(0)) { + console.log("SIMPLE_WALLET env var not set"); + return; + } + + address controllerAddr = vm.envAddress("RECOVERY_CONTROLLER"); + if (controllerAddr == address(0)) { + console.log("RECOVERY_CONTROLLER env var not set"); + return; + } + + bytes32 accountSalt = vm.envBytes32("ACCOUNT_SALT"); + if (accountSalt == 0) { + console.log("ACCOUNT_SALT env var not set"); + return; + } + + vm.startBroadcast(deployerPrivateKey); + address initialOwner = vm.addr(deployerPrivateKey); + console.log("Initial owner: %s", vm.toString(initialOwner)); + + RecoveryController controller = RecoveryController(controllerAddr); + address guardian = controller.computeEmailAuthAddress( + simpleWalletAddr, + accountSalt + ); + console.log("Guardian: %s", vm.toString(guardian)); + SimpleWallet wallet = SimpleWallet(payable(simpleWalletAddr)); + wallet.requestGuardian(guardian); + vm.stopBroadcast(); + } +} diff --git a/packages/contracts/script/RevokeDKIMPublicKeyHashSimpleWallet.s.sol b/packages/contracts/script/RevokeDKIMPublicKeyHashSimpleWallet.s.sol new file mode 100644 index 00000000..38a28067 --- /dev/null +++ b/packages/contracts/script/RevokeDKIMPublicKeyHashSimpleWallet.s.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "forge-std/Script.sol"; + +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import "../test/helpers/SimpleWallet.sol"; +import "../test/helpers/RecoveryController.sol"; +import "../src/utils/Verifier.sol"; +import "../src/utils/Groth16Verifier.sol"; +import "../src/EmailAuth.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import {UserOverrideableDKIMRegistry} from "@zk-email/contracts/UserOverrideableDKIMRegistry.sol"; +import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; + +contract RevokePublicKeyHash is Script { + using ECDSA for *; + + UserOverrideableDKIMRegistry dkim; + RecoveryController recoveryController; + + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + if (deployerPrivateKey == 0) { + console.log("PRIVATE_KEY env var not set"); + return; + } + address dkimAddr = vm.envAddress("DKIM"); + if (dkimAddr == address(0)) { + console.log("DKIM env var not set"); + return; + } + address walletAddr = vm.envAddress("SIMPLE_WALLET"); + if (walletAddr == address(0)) { + console.log("SIMPLE_WALLET env var not set"); + return; + } + dkim = UserOverrideableDKIMRegistry(dkimAddr); + string memory domainName = vm.envString("DOMAIN"); + if (bytes(domainName).length == 0) { + console.log("DOMAIN env var not set"); + return; + } + bytes32 publicKeyHash = vm.envBytes32("PUBLIC_KEY_HASH"); + if (publicKeyHash == bytes32(0)) { + console.log("PUBLIC_KEY_HASH env var not set"); + return; + } + string memory signedMsg = dkim.computeSignedMsg( + dkim.REVOKE_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(deployerPrivateKey, digest); + bytes memory signature = abi.encodePacked(r, s, v); + vm.startBroadcast(deployerPrivateKey); + dkim.revokeDKIMPublicKeyHash( + domainName, + publicKeyHash, + walletAddr, + signature + ); + vm.stopBroadcast(); + } +} diff --git a/packages/contracts/script/SetDKIMPublicKeyHashSimpleWallet.s.sol b/packages/contracts/script/SetDKIMPublicKeyHashSimpleWallet.s.sol new file mode 100644 index 00000000..dee8bc0b --- /dev/null +++ b/packages/contracts/script/SetDKIMPublicKeyHashSimpleWallet.s.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "forge-std/Script.sol"; + +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import "../test/helpers/SimpleWallet.sol"; +import "../test/helpers/RecoveryController.sol"; +import "../src/utils/Verifier.sol"; +import "../src/utils/Groth16Verifier.sol"; +import "../src/EmailAuth.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import {UserOverrideableDKIMRegistry} from "@zk-email/contracts/UserOverrideableDKIMRegistry.sol"; +import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; + +contract SetPublicKeyHash is Script { + using ECDSA for *; + + UserOverrideableDKIMRegistry dkim; + RecoveryController recoveryController; + + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + if (deployerPrivateKey == 0) { + console.log("PRIVATE_KEY env var not set"); + return; + } + address dkimAddr = vm.envAddress("DKIM"); + if (dkimAddr == address(0)) { + console.log("DKIM env var not set"); + return; + } + address walletAddr = vm.envAddress("SIMPLE_WALLET"); + if (walletAddr == address(0)) { + console.log("SIMPLE_WALLET env var not set"); + return; + } + dkim = UserOverrideableDKIMRegistry(dkimAddr); + string memory domainName = vm.envString("DOMAIN"); + if (bytes(domainName).length == 0) { + console.log("DOMAIN env var not set"); + return; + } + bytes32 publicKeyHash = vm.envBytes32("PUBLIC_KEY_HASH"); + if (publicKeyHash == bytes32(0)) { + console.log("PUBLIC_KEY_HASH env var not set"); + return; + } + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(deployerPrivateKey, digest); + bytes memory signature = abi.encodePacked(r, s, v); + vm.startBroadcast(deployerPrivateKey); + dkim.setDKIMPublicKeyHash( + domainName, + publicKeyHash, + walletAddr, + signature + ); + vm.stopBroadcast(); + } +} diff --git a/packages/contracts/script/Upgrades.s.sol b/packages/contracts/script/Upgrades.s.sol index d06cf964..eb0746ce 100644 --- a/packages/contracts/script/Upgrades.s.sol +++ b/packages/contracts/script/Upgrades.s.sol @@ -1,48 +1,58 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; -import "forge-std/Script.sol"; - +import {console} from "forge-std/console.sol"; import "../src/utils/Verifier.sol"; import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; -import "../src/utils/ForwardDKIMRegistry.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {Create2} from "@openzeppelin/contracts/utils/Create2.sol"; +import {UserOverrideableDKIMRegistry} from "@zk-email/contracts/UserOverrideableDKIMRegistry.sol"; +import {BaseDeployScript} from "./BaseDeployScript.sol"; -contract Upgrades is Script { - function run() external { - uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); - if (deployerPrivateKey == 0) { - console.log("PRIVATE_KEY env var not set"); - return; - } - address verifier = vm.envOr("VERIFIER", address(0)); - address ecdsaDkim = vm.envOr("ECDSA_DKIM", address(0)); - address dkim = vm.envOr("DKIM", address(0)); +contract Upgrades is BaseDeployScript { + function run() public override { + super.run(); + + address verifierProxy = vm.envOr("VERIFIER", address(0)); + address ecdsaDkimProxy = vm.envOr("ECDSA_DKIM", address(0)); + address dkimProxy = vm.envOr("DKIM", address(0)); vm.startBroadcast(deployerPrivateKey); - if (verifier != address(0)) { - Verifier newVerifierImpl = new Verifier(); - UUPSUpgradeable(verifier).upgradeToAndCall( - address(newVerifierImpl), - bytes("") - ); + if (verifierProxy != address(0)) { + upgradeVerifier(verifierProxy); } - if (ecdsaDkim != address(0)) { - ECDSAOwnedDKIMRegistry newECDSAOwnedDKIMRegistryImpl = new ECDSAOwnedDKIMRegistry(); - UUPSUpgradeable(ecdsaDkim).upgradeToAndCall( - address(newECDSAOwnedDKIMRegistryImpl), - bytes("") - ); + if (ecdsaDkimProxy != address(0)) { + upgradeECDSAOwnedDKIMRegistry(ecdsaDkimProxy); } - if (dkim != address(0)) { - ForwardDKIMRegistry newForwardDKIMRegistryImpl = new ForwardDKIMRegistry(); - UUPSUpgradeable(dkim).upgradeToAndCall( - address(newForwardDKIMRegistryImpl), - bytes("") - ); + if (dkimProxy != address(0)) { + upgradeUserOverrideableDKIMRegistry(dkimProxy); } vm.stopBroadcast(); } + + function upgradeVerifier(address verifierProxy) public { + Verifier newVerifierImpl = new Verifier(); + UUPSUpgradeable(verifierProxy).upgradeToAndCall( + address(newVerifierImpl), + bytes("") + ); + } + + function upgradeECDSAOwnedDKIMRegistry(address ecdsaDkimProxy) public { + ECDSAOwnedDKIMRegistry newECDSAOwnedDKIMRegistryImpl = new ECDSAOwnedDKIMRegistry(); + UUPSUpgradeable(ecdsaDkimProxy).upgradeToAndCall( + address(newECDSAOwnedDKIMRegistryImpl), + bytes("") + ); + } + + function upgradeUserOverrideableDKIMRegistry(address dkimProxy) public { + UserOverrideableDKIMRegistry newDkimImpl = new UserOverrideableDKIMRegistry(); + UUPSUpgradeable(dkimProxy).upgradeToAndCall( + address(newDkimImpl), + bytes("") + ); + } } diff --git a/packages/contracts/src/EmailAccountRecovery.sol b/packages/contracts/src/EmailAccountRecovery.sol index c1a87acd..d1754387 100644 --- a/packages/contracts/src/EmailAccountRecovery.sol +++ b/packages/contracts/src/EmailAccountRecovery.sol @@ -44,53 +44,53 @@ abstract contract EmailAccountRecovery { address recoveredAccount ) public view virtual returns (bool); - /// @notice Returns a two-dimensional array of strings representing the subject templates for an acceptance by a new guardian's. - /// @dev This function is virtual and should be implemented by inheriting contracts to define specific acceptance subject templates. - /// @return string[][] A two-dimensional array of strings, where each inner array represents a set of fixed strings and matchers for a subject template. - function acceptanceSubjectTemplates() + /// @notice Returns a two-dimensional array of strings representing the command templates for an acceptance by a new guardian's. + /// @dev This function is virtual and should be implemented by inheriting contracts to define specific acceptance command templates. + /// @return string[][] A two-dimensional array of strings, where each inner array represents a set of fixed strings and matchers for a command template. + function acceptanceCommandTemplates() public view virtual returns (string[][] memory); - /// @notice Returns a two-dimensional array of strings representing the subject templates for email recovery. - /// @dev This function is virtual and should be implemented by inheriting contracts to define specific recovery subject templates. - /// @return string[][] A two-dimensional array of strings, where each inner array represents a set of fixed strings and matchers for a subject template. - function recoverySubjectTemplates() + /// @notice Returns a two-dimensional array of strings representing the command templates for email recovery. + /// @dev This function is virtual and should be implemented by inheriting contracts to define specific recovery command templates. + /// @return string[][] A two-dimensional array of strings, where each inner array represents a set of fixed strings and matchers for a command template. + function recoveryCommandTemplates() public view virtual returns (string[][] memory); - /// @notice Extracts the account address to be recovered from the subject parameters of an acceptance email. - /// @dev This function is virtual and should be implemented by inheriting contracts to extract the account address from the subject parameters. - /// @param subjectParams The subject parameters of the acceptance email. - /// @param templateIdx The index of the acceptance subject template. - function extractRecoveredAccountFromAcceptanceSubject( - bytes[] memory subjectParams, + /// @notice Extracts the account address to be recovered from the command parameters of an acceptance email. + /// @dev This function is virtual and should be implemented by inheriting contracts to extract the account address from the command parameters. + /// @param commandParams The command parameters of the acceptance email. + /// @param templateIdx The index of the acceptance command template. + function extractRecoveredAccountFromAcceptanceCommand( + bytes[] memory commandParams, uint templateIdx ) public view virtual returns (address); - /// @notice Extracts the account address to be recovered from the subject parameters of a recovery email. - /// @dev This function is virtual and should be implemented by inheriting contracts to extract the account address from the subject parameters. - /// @param subjectParams The subject parameters of the recovery email. - /// @param templateIdx The index of the recovery subject template. - function extractRecoveredAccountFromRecoverySubject( - bytes[] memory subjectParams, + /// @notice Extracts the account address to be recovered from the command parameters of a recovery email. + /// @dev This function is virtual and should be implemented by inheriting contracts to extract the account address from the command parameters. + /// @param commandParams The command parameters of the recovery email. + /// @param templateIdx The index of the recovery command template. + function extractRecoveredAccountFromRecoveryCommand( + bytes[] memory commandParams, uint templateIdx ) public view virtual returns (address); function acceptGuardian( address guardian, uint templateIdx, - bytes[] memory subjectParams, + bytes[] memory commandParams, bytes32 emailNullifier ) internal virtual; function processRecovery( address guardian, uint templateIdx, - bytes[] memory subjectParams, + bytes[] memory commandParams, bytes32 emailNullifier ) internal virtual; @@ -124,11 +124,7 @@ abstract contract EmailAccountRecovery { emailAuthImplementation(), abi.encodeCall( EmailAuth.initialize, - ( - recoveredAccount, - accountSalt, - address(this) - ) + (recoveredAccount, accountSalt, address(this)) ) ) ) @@ -142,7 +138,7 @@ abstract contract EmailAccountRecovery { /// @param accountSalt A bytes32 salt value used to ensure the uniqueness of the deployed proxy address. /// @return address The address of the newly deployed proxy contract. function deployEmailAuthProxy( - address recoveredAccount, + address recoveredAccount, bytes32 accountSalt ) internal virtual returns (address) { ERC1967Proxy proxy = new ERC1967Proxy{salt: accountSalt}( @@ -155,10 +151,10 @@ abstract contract EmailAccountRecovery { return address(proxy); } - /// @notice Calculates a unique subject template ID for an acceptance subject template using its index. + /// @notice Calculates a unique command template ID for an acceptance command template using its index. /// @dev Encodes the email account recovery version ID, "ACCEPTANCE", and the template index, /// then uses keccak256 to hash these values into a uint ID. - /// @param templateIdx The index of the acceptance subject template. + /// @param templateIdx The index of the acceptance command template. /// @return uint The computed uint ID. function computeAcceptanceTemplateId( uint templateIdx @@ -175,10 +171,10 @@ abstract contract EmailAccountRecovery { ); } - /// @notice Calculates a unique ID for a recovery subject template using its index. + /// @notice Calculates a unique ID for a recovery command template using its index. /// @dev Encodes the email account recovery version ID, "RECOVERY", and the template index, /// then uses keccak256 to hash these values into a uint256 ID. - /// @param templateIdx The index of the recovery subject template. + /// @param templateIdx The index of the recovery command template. /// @return uint The computed uint ID. function computeRecoveryTemplateId( uint templateIdx @@ -197,13 +193,13 @@ abstract contract EmailAccountRecovery { /// @notice Handles an acceptance by a new guardian. /// @dev This function validates the email auth message, deploys a new EmailAuth contract as a proxy if validations pass and initializes the contract. /// @param emailAuthMsg The email auth message for the email send from the guardian. - /// @param templateIdx The index of the subject template for acceptance, which should match with the subject in the given email auth message. + /// @param templateIdx The index of the command template for acceptance, which should match with the command in the given email auth message. function handleAcceptance( EmailAuthMsg memory emailAuthMsg, uint templateIdx ) external { - address recoveredAccount = extractRecoveredAccountFromAcceptanceSubject( - emailAuthMsg.subjectParams, + address recoveredAccount = extractRecoveredAccountFromAcceptanceCommand( + emailAuthMsg.commandParams, templateIdx ); require(recoveredAccount != address(0), "invalid account in email"); @@ -217,24 +213,27 @@ abstract contract EmailAccountRecovery { EmailAuth guardianEmailAuth; if (guardian.code.length == 0) { - address proxyAddress = deployEmailAuthProxy(recoveredAccount, emailAuthMsg.proof.accountSalt); + address proxyAddress = deployEmailAuthProxy( + recoveredAccount, + emailAuthMsg.proof.accountSalt + ); guardianEmailAuth = EmailAuth(proxyAddress); guardianEmailAuth.initDKIMRegistry(dkim()); guardianEmailAuth.initVerifier(verifier()); for ( uint idx = 0; - idx < acceptanceSubjectTemplates().length; + idx < acceptanceCommandTemplates().length; idx++ ) { - guardianEmailAuth.insertSubjectTemplate( + guardianEmailAuth.insertCommandTemplate( computeAcceptanceTemplateId(idx), - acceptanceSubjectTemplates()[idx] + acceptanceCommandTemplates()[idx] ); } - for (uint idx = 0; idx < recoverySubjectTemplates().length; idx++) { - guardianEmailAuth.insertSubjectTemplate( + for (uint idx = 0; idx < recoveryCommandTemplates().length; idx++) { + guardianEmailAuth.insertCommandTemplate( computeRecoveryTemplateId(idx), - recoverySubjectTemplates()[idx] + recoveryCommandTemplates()[idx] ); } } else { @@ -251,22 +250,22 @@ abstract contract EmailAccountRecovery { acceptGuardian( guardian, templateIdx, - emailAuthMsg.subjectParams, + emailAuthMsg.commandParams, emailAuthMsg.proof.emailNullifier ); } /// @notice Processes the recovery based on an email from the guardian. - /// @dev Verify the provided email auth message for a deployed guardian's EmailAuth contract and a specific subject template for recovery. + /// @dev Verify the provided email auth message for a deployed guardian's EmailAuth contract and a specific command template for recovery. /// Requires that the guardian is already deployed, and the template ID corresponds to the `templateId` in the given email auth message. Once validated. /// @param emailAuthMsg The email auth message for recovery. - /// @param templateIdx The index of the subject template for recovery, which should match with the subject in the given email auth message. + /// @param templateIdx The index of the command template for recovery, which should match with the command in the given email auth message. function handleRecovery( EmailAuthMsg memory emailAuthMsg, uint templateIdx ) external { - address recoveredAccount = extractRecoveredAccountFromRecoverySubject( - emailAuthMsg.subjectParams, + address recoveredAccount = extractRecoveredAccountFromRecoveryCommand( + emailAuthMsg.commandParams, templateIdx ); require(recoveredAccount != address(0), "invalid account in email"); @@ -296,7 +295,7 @@ abstract contract EmailAccountRecovery { processRecovery( guardian, templateIdx, - emailAuthMsg.subjectParams, + emailAuthMsg.commandParams, emailAuthMsg.proof.emailNullifier ); } diff --git a/packages/contracts/src/EmailAccountRecoveryZKSync.sol b/packages/contracts/src/EmailAccountRecoveryZKSync.sol index fbd14a68..a247524f 100644 --- a/packages/contracts/src/EmailAccountRecoveryZKSync.sol +++ b/packages/contracts/src/EmailAccountRecoveryZKSync.sol @@ -9,13 +9,12 @@ import {ZKSyncCreate2Factory} from "./utils/ZKSyncCreate2Factory.sol"; /// @notice Provides mechanisms for email-based account recovery, leveraging guardians and template-based email verification. /// @dev This contract is abstract and requires implementation of several methods for configuring a new guardian and recovering an account contract. abstract contract EmailAccountRecoveryZKSync is EmailAccountRecovery { - // This is the address of the zkSync factory contract address public factoryAddr; - // The bytecodeHash is hardcoded here because type(ERC1967Proxy).creationCode doesn't work on eraVM currently + // The bytecodeHash is assumed to be provided as an initialization parameter because type(ERC1967Proxy).creationCode doesn't work on eraVM currently // If you failed some test cases, check the bytecodeHash by yourself // see, test/ComputeCreate2Address.t.sol - bytes32 public constant proxyBytecodeHash = 0x0100008338d33e12c716a5b695c6f7f4e526cf162a9378c0713eea5386c09951; + bytes32 public proxyBytecodeHash; /// @notice Returns the address of the zkSyncfactory contract. /// @dev This function is virtual and can be overridden by inheriting contracts. @@ -34,19 +33,20 @@ abstract contract EmailAccountRecoveryZKSync is EmailAccountRecovery { function computeEmailAuthAddress( address recoveredAccount, bytes32 accountSalt - ) public view override returns (address) { + ) public view virtual override returns (address) { // If on zksync, we use another logic to calculate create2 address. - return ZKSyncCreate2Factory(factory()).computeAddress( - accountSalt, - proxyBytecodeHash, - abi.encode( - emailAuthImplementation(), - abi.encodeCall( - EmailAuth.initialize, - (recoveredAccount, accountSalt, address(this)) + return + ZKSyncCreate2Factory(factory()).computeAddress( + accountSalt, + proxyBytecodeHash, + abi.encode( + emailAuthImplementation(), + abi.encodeCall( + EmailAuth.initialize, + (recoveredAccount, accountSalt, address(this)) + ) ) - ) - ); + ); } /// @notice Deploys a proxy contract for email authentication using the CREATE2 opcode. @@ -57,25 +57,24 @@ abstract contract EmailAccountRecoveryZKSync is EmailAccountRecovery { /// @param accountSalt A bytes32 salt value defined as a hash of the guardian's email address and an account code. This is assumed to be unique to a pair of the guardian's email address and the wallet address to be recovered. /// @return address The address of the deployed proxy contract. function deployEmailAuthProxy( - address recoveredAccount, + address recoveredAccount, bytes32 accountSalt - ) internal override returns (address) { - (bool success, bytes memory returnData) = ZKSyncCreate2Factory(factory()).deploy( - accountSalt, - proxyBytecodeHash, - abi.encode( - emailAuthImplementation(), - abi.encodeCall( - EmailAuth.initialize, - ( - recoveredAccount, - accountSalt, - address(this) + ) internal virtual override returns (address) { + (bool success, bytes memory returnData) = ZKSyncCreate2Factory( + factory() + ).deploy( + accountSalt, + proxyBytecodeHash, + abi.encode( + emailAuthImplementation(), + abi.encodeCall( + EmailAuth.initialize, + (recoveredAccount, accountSalt, address(this)) ) ) - ) - ); + ); + require(success, "zksync deploy failed"); address payable proxyAddress = abi.decode(returnData, (address)); return proxyAddress; } -} \ No newline at end of file +} diff --git a/packages/contracts/src/EmailAuth.sol b/packages/contracts/src/EmailAuth.sol index 19297fd7..5379e40a 100644 --- a/packages/contracts/src/EmailAuth.sol +++ b/packages/contracts/src/EmailAuth.sol @@ -3,26 +3,26 @@ pragma solidity ^0.8.12; import {EmailProof} from "./utils/Verifier.sol"; import {IDKIMRegistry} from "@zk-email/contracts/DKIMRegistry.sol"; -import {Verifier} from "./utils/Verifier.sol"; -import {SubjectUtils} from "./libraries/SubjectUtils.sol"; +import {IVerifier, EmailProof} from "./interfaces/IVerifier.sol"; +import {CommandUtils} from "./libraries/CommandUtils.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; /// @notice Struct to hold the email authentication/authorization message. struct EmailAuthMsg { - /// @notice The ID of the subject template that the email subject should satisfy. + /// @notice The ID of the command template that the command in the email body should satisfy. uint templateId; - /// @notice The parameters in the email subject, which should be taken according to the specified subject template. - bytes[] subjectParams; - /// @notice The number of skiiped bytes in the email subject. - uint skipedSubjectPrefix; + /// @notice The parameters in the command of the email body, which should be taken according to the specified command template. + bytes[] commandParams; + /// @notice The number of skipped bytes in the command. + uint skippedCommandPrefix; /// @notice The email proof containing the zk proof and other necessary information for the email verification by the verifier contract. EmailProof proof; } /// @title Email Authentication/Authorization Contract -/// @notice This contract provides functionalities for the authentication of the email sender and the authentication of the message in the email subject using DKIM and custom verification logic. +/// @notice This contract provides functionalities for the authentication of the email sender and the authentication of the message in the command part of the email body using DKIM and custom verification logic. /// @dev Inherits from OwnableUpgradeable and UUPSUpgradeable for upgradeability and ownership management. contract EmailAuth is OwnableUpgradeable, UUPSUpgradeable { /// The CREATE2 salt of this contract defined as a hash of an email address and an account code. @@ -30,11 +30,11 @@ contract EmailAuth is OwnableUpgradeable, UUPSUpgradeable { /// An instance of the DKIM registry contract. IDKIMRegistry internal dkim; /// An instance of the Verifier contract. - Verifier internal verifier; - /// An address of a controller contract, defining the subject templates supported by this contract. + IVerifier internal verifier; + /// An address of a controller contract, defining the command templates supported by this contract. address public controller; - /// A mapping of the supported subject templates associated with its ID. - mapping(uint => string[]) public subjectTemplates; + /// A mapping of the supported command templates associated with its ID. + mapping(uint => string[]) public commandTemplates; /// A mapping of the hash of the authorized message associated with its `emailNullifier`. uint public lastTimestamp; /// The latest `timestamp` in the verified `EmailAuthMsg`. @@ -44,9 +44,9 @@ contract EmailAuth is OwnableUpgradeable, UUPSUpgradeable { event DKIMRegistryUpdated(address indexed dkimRegistry); event VerifierUpdated(address indexed verifier); - event SubjectTemplateInserted(uint indexed templateId); - event SubjectTemplateUpdated(uint indexed templateId); - event SubjectTemplateDeleted(uint indexed templateId); + event CommandTemplateInserted(uint indexed templateId); + event CommandTemplateUpdated(uint indexed templateId); + event CommandTemplateDeleted(uint indexed templateId); event EmailAuthed( bytes32 indexed emailNullifier, bytes32 indexed accountSalt, @@ -112,7 +112,7 @@ contract EmailAuth is OwnableUpgradeable, UUPSUpgradeable { address(verifier) == address(0), "verifier already initialized" ); - verifier = Verifier(_verifierAddr); + verifier = IVerifier(_verifierAddr); emit VerifierUpdated(_verifierAddr); } @@ -131,74 +131,74 @@ contract EmailAuth is OwnableUpgradeable, UUPSUpgradeable { /// @param _verifierAddr The new address of the verifier contract. function updateVerifier(address _verifierAddr) public onlyOwner { require(_verifierAddr != address(0), "invalid verifier address"); - verifier = Verifier(_verifierAddr); + verifier = IVerifier(_verifierAddr); emit VerifierUpdated(_verifierAddr); } - /// @notice Retrieves a subject template by its ID. - /// @param _templateId The ID of the subject template to be retrieved. - /// @return string[] The subject template as an array of strings. - function getSubjectTemplate( + /// @notice Retrieves a command template by its ID. + /// @param _templateId The ID of the command template to be retrieved. + /// @return string[] The command template as an array of strings. + function getCommandTemplate( uint _templateId ) public view returns (string[] memory) { require( - subjectTemplates[_templateId].length > 0, + commandTemplates[_templateId].length > 0, "template id not exists" ); - return subjectTemplates[_templateId]; + return commandTemplates[_templateId]; } - /// @notice Inserts a new subject template. - /// @dev This function can only be called by the owner of the contract. - /// @param _templateId The ID for the new subject template. - /// @param _subjectTemplate The subject template as an array of strings. - function insertSubjectTemplate( + /// @notice Inserts a new command template. + /// @dev This function can only be called by the controller of the contract. + /// @param _templateId The ID for the new command template. + /// @param _commandTemplate The command template as an array of strings. + function insertCommandTemplate( uint _templateId, - string[] memory _subjectTemplate + string[] memory _commandTemplate ) public onlyController { - require(_subjectTemplate.length > 0, "subject template is empty"); + require(_commandTemplate.length > 0, "command template is empty"); require( - subjectTemplates[_templateId].length == 0, + commandTemplates[_templateId].length == 0, "template id already exists" ); - subjectTemplates[_templateId] = _subjectTemplate; - emit SubjectTemplateInserted(_templateId); + commandTemplates[_templateId] = _commandTemplate; + emit CommandTemplateInserted(_templateId); } - /// @notice Updates an existing subject template by its ID. + /// @notice Updates an existing command template by its ID. /// @dev This function can only be called by the controller contract. /// @param _templateId The ID of the template to update. - /// @param _subjectTemplate The new subject template as an array of strings. - function updateSubjectTemplate( + /// @param _commandTemplate The new command template as an array of strings. + function updateCommandTemplate( uint _templateId, - string[] memory _subjectTemplate + string[] memory _commandTemplate ) public onlyController { - require(_subjectTemplate.length > 0, "subject template is empty"); + require(_commandTemplate.length > 0, "command template is empty"); require( - subjectTemplates[_templateId].length > 0, + commandTemplates[_templateId].length > 0, "template id not exists" ); - subjectTemplates[_templateId] = _subjectTemplate; - emit SubjectTemplateUpdated(_templateId); + commandTemplates[_templateId] = _commandTemplate; + emit CommandTemplateUpdated(_templateId); } - /// @notice Deletes an existing subject template by its ID. - /// @dev This function can only be called by the owner of the contract. - /// @param _templateId The ID of the subject template to be deleted. - function deleteSubjectTemplate(uint _templateId) public onlyController { + /// @notice Deletes an existing command template by its ID. + /// @dev This function can only be called by the controller of the contract. + /// @param _templateId The ID of the command template to be deleted. + function deleteCommandTemplate(uint _templateId) public onlyController { require( - subjectTemplates[_templateId].length > 0, + commandTemplates[_templateId].length > 0, "template id not exists" ); - delete subjectTemplates[_templateId]; - emit SubjectTemplateDeleted(_templateId); + delete commandTemplates[_templateId]; + emit CommandTemplateDeleted(_templateId); } - /// @notice Authenticate the email sender and authorize the message in the email subject based on the provided email auth message. + /// @notice Authenticate the email sender and authorize the message in the email command based on the provided email auth message. /// @dev This function can only be called by the controller contract. /// @param emailAuthMsg The email auth message containing all necessary information for authentication and authorization. function authEmail(EmailAuthMsg memory emailAuthMsg) public onlyController { - string[] memory template = subjectTemplates[emailAuthMsg.templateId]; + string[] memory template = commandTemplates[emailAuthMsg.templateId]; require(template.length > 0, "template id not exists"); require( dkim.isDKIMPublicKeyHashValid( @@ -222,32 +222,32 @@ contract EmailAuth is OwnableUpgradeable, UUPSUpgradeable { "invalid timestamp" ); require( - bytes(emailAuthMsg.proof.maskedSubject).length <= - verifier.SUBJECT_BYTES(), - "invalid masked subject length" + bytes(emailAuthMsg.proof.maskedCommand).length <= + verifier.commandBytes(), + "invalid masked command length" ); require( - emailAuthMsg.skipedSubjectPrefix < verifier.SUBJECT_BYTES(), - "invalid size of the skipped subject prefix" + emailAuthMsg.skippedCommandPrefix < verifier.commandBytes(), + "invalid size of the skipped command prefix" ); - // Construct an expectedSubject from template and the values of emailAuthMsg.subjectParams. - string memory trimmedMaskedSubject = removePrefix( - emailAuthMsg.proof.maskedSubject, - emailAuthMsg.skipedSubjectPrefix + // Construct an expectedCommand from template and the values of emailAuthMsg.commandParams. + string memory trimmedMaskedCommand = removePrefix( + emailAuthMsg.proof.maskedCommand, + emailAuthMsg.skippedCommandPrefix ); - string memory expectedSubject = ""; + string memory expectedCommand = ""; for (uint stringCase = 0; stringCase < 3; stringCase++) { - expectedSubject = SubjectUtils.computeExpectedSubject( - emailAuthMsg.subjectParams, + expectedCommand = CommandUtils.computeExpectedCommand( + emailAuthMsg.commandParams, template, stringCase ); - if (Strings.equal(expectedSubject, trimmedMaskedSubject)) { + if (Strings.equal(expectedCommand, trimmedMaskedCommand)) { break; } if (stringCase == 2) { - revert("invalid subject"); + revert("invalid command"); } } @@ -269,7 +269,7 @@ contract EmailAuth is OwnableUpgradeable, UUPSUpgradeable { } /// @notice Enables or disables the timestamp check. - /// @dev This function can only be called by the contract owner. + /// @dev This function can only be called by the controller. /// @param _enabled Boolean flag to enable or disable the timestamp check. function setTimestampCheckEnabled(bool _enabled) public onlyController { timestampCheckEnabled = _enabled; @@ -284,15 +284,18 @@ contract EmailAuth is OwnableUpgradeable, UUPSUpgradeable { function removePrefix( string memory str, - uint numChars + uint numBytes ) private pure returns (string memory) { - require(numChars <= bytes(str).length, "Invalid number of characters"); + require( + numBytes <= bytes(str).length, + "Invalid size of the removed bytes" + ); bytes memory strBytes = bytes(str); - bytes memory result = new bytes(strBytes.length - numChars); + bytes memory result = new bytes(strBytes.length - numBytes); - for (uint i = numChars; i < strBytes.length; i++) { - result[i - numChars] = strBytes[i]; + for (uint i = numBytes; i < strBytes.length; i++) { + result[i - numBytes] = strBytes[i]; } return string(result); diff --git a/packages/contracts/src/interfaces/IGroth16Verifier.sol b/packages/contracts/src/interfaces/IGroth16Verifier.sol new file mode 100644 index 00000000..47bc46fd --- /dev/null +++ b/packages/contracts/src/interfaces/IGroth16Verifier.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +interface IGroth16Verifier { + function verifyProof( + uint[2] calldata _pA, + uint[2][2] calldata _pB, + uint[2] calldata _pC, + uint[34] calldata _pubSignals + ) external view returns (bool); +} diff --git a/packages/contracts/src/interfaces/IVerifier.sol b/packages/contracts/src/interfaces/IVerifier.sol new file mode 100644 index 00000000..d12cb5e2 --- /dev/null +++ b/packages/contracts/src/interfaces/IVerifier.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +struct EmailProof { + string domainName; // Domain name of the sender's email + bytes32 publicKeyHash; // Hash of the DKIM public key used in email/proof + uint timestamp; // Timestamp of the email + string maskedCommand; // Masked command of the email + bytes32 emailNullifier; // Nullifier of the email to prevent its reuse. + bytes32 accountSalt; // Create2 salt of the account + bool isCodeExist; // Check if the account code is exist + bytes proof; // ZK Proof of Email +} + +interface IVerifier { + function commandBytes() external view returns (uint256); + + function verifyEmailProof( + EmailProof memory proof + ) external view returns (bool); +} diff --git a/packages/contracts/src/libraries/SubjectUtils.sol b/packages/contracts/src/libraries/CommandUtils.sol similarity index 82% rename from packages/contracts/src/libraries/SubjectUtils.sol rename to packages/contracts/src/libraries/CommandUtils.sol index 84823931..a94c1297 100644 --- a/packages/contracts/src/libraries/SubjectUtils.sol +++ b/packages/contracts/src/libraries/CommandUtils.sol @@ -5,8 +5,9 @@ import "@openzeppelin/contracts/utils/Strings.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import "./DecimalUtils.sol"; +import "./StringUtils.sol"; -library SubjectUtils { +library CommandUtils { bytes16 private constant LOWER_HEX_DIGITS = "0123456789abcdef"; bytes16 private constant UPPER_HEX_DIGITS = "0123456789ABCDEF"; string public constant STRING_MATCHER = "{string}"; @@ -102,16 +103,16 @@ library SubjectUtils { return string(hexString); } - /// @notice Calculate the expected subject. - /// @param subjectParams Params to be used in the subject - /// @param template Template to be used for the subject - /// @param stringCase Case of the string - 0:checksumed, 1: lowercase, 2: uppercase - function computeExpectedSubject( - bytes[] memory subjectParams, + /// @notice Calculate the expected command. + /// @param commandParams Params to be used in the command + /// @param template Template to be used for the command + /// @param stringCase Case of the ethereum address string to be used for the command - 0: checksum, 1: lowercase, 2: uppercase + function computeExpectedCommand( + bytes[] memory commandParams, string[] memory template, uint stringCase - ) public pure returns (string memory expectedSubject) { - // Construct an expectedSubject from template and the values of emailAuthMsg.subjectParams. + ) public pure returns (string memory expectedCommand) { + // Construct an expectedCommand from template and the values of commandParams. uint8 nextParamIndex = 0; string memory stringParam; bool isParamExist; @@ -119,31 +120,31 @@ library SubjectUtils { isParamExist = true; if (Strings.equal(template[i], STRING_MATCHER)) { string memory param = abi.decode( - subjectParams[nextParamIndex], + commandParams[nextParamIndex], (string) ); stringParam = param; } else if (Strings.equal(template[i], UINT_MATCHER)) { uint256 param = abi.decode( - subjectParams[nextParamIndex], + commandParams[nextParamIndex], (uint256) ); stringParam = Strings.toString(param); } else if (Strings.equal(template[i], INT_MATCHER)) { int256 param = abi.decode( - subjectParams[nextParamIndex], + commandParams[nextParamIndex], (int256) ); stringParam = Strings.toStringSigned(param); } else if (Strings.equal(template[i], DECIMALS_MATCHER)) { uint256 param = abi.decode( - subjectParams[nextParamIndex], + commandParams[nextParamIndex], (uint256) ); stringParam = DecimalUtils.uintToDecimalString(param); } else if (Strings.equal(template[i], ETH_ADDR_MATCHER)) { address param = abi.decode( - subjectParams[nextParamIndex], + commandParams[nextParamIndex], (address) ); stringParam = addressToHexString(param, stringCase); @@ -153,17 +154,17 @@ library SubjectUtils { } if (i > 0) { - expectedSubject = string( - abi.encodePacked(expectedSubject, " ") + expectedCommand = string( + abi.encodePacked(expectedCommand, " ") ); } - expectedSubject = string( - abi.encodePacked(expectedSubject, stringParam) + expectedCommand = string( + abi.encodePacked(expectedCommand, stringParam) ); if (isParamExist) { nextParamIndex++; } } - return expectedSubject; + return expectedCommand; } } diff --git a/packages/contracts/src/libraries/StringUtils.sol b/packages/contracts/src/libraries/StringUtils.sol new file mode 100644 index 00000000..d44d4549 --- /dev/null +++ b/packages/contracts/src/libraries/StringUtils.sol @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import {strings} from "solidity-stringutils/src/strings.sol"; + +/** + * @title StringUtils + * @notice This library provides utility functions for converting hexadecimal strings to bytes. + * @author Clave & ZK Email + */ +library StringUtils { + using strings for *; + + /** + * @dev Converts a hexadecimal string to bytes. + * @param hexStr The hexadecimal string to convert. Must start with "0x" prefix. + * @return bytes A bytes array representing the converted hexadecimal string. + */ + function hexToBytes( + string calldata hexStr + ) public pure returns (bytes memory) { + require( + hexStr.toSlice().startsWith("0x".toSlice()), + "invalid hex prefix" + ); + string memory hexStrNoPrefix = hexStr[2:]; + bytes memory hexBytes = bytes(hexStrNoPrefix); + require( + hexBytes.length != 0 && hexBytes.length % 2 == 0, + "invalid hex string length" + ); + + bytes memory result = new bytes(hexBytes.length / 2); + for (uint256 i = 0; i < hexBytes.length / 2; i++) { + result[i] = bytes1( + (hexChar2Int(hexBytes[2 * i]) << 4) + + hexChar2Int(hexBytes[2 * i + 1]) + ); + } + return result; + } + + /** + * @dev Converts a hexadecimal string to a bytes32 value. + * @param hexStr The hexadecimal string to convert. + * @return bytes32 A bytes32 value representing the converted hexadecimal string. + */ + function hexToBytes32( + string calldata hexStr + ) public pure returns (bytes32) { + bytes memory result = hexToBytes(hexStr); + require(result.length == 32, "bytes length is not 32"); + return bytes32(result); + } + + /** + * @dev Converts a single hexadecimal character to its integer equivalent. + * @param char The hexadecimal character to convert (0-9, A-F, or a-f). + * @return uint8 The integer value of the hexadecimal character (0-15). + */ + function hexChar2Int(bytes1 char) private pure returns (uint8) { + uint8 charInt = uint8(char); + if (charInt >= 48 && charInt <= 57) { + return charInt - 48; // '0' - '9' + } else if (charInt >= 65 && charInt <= 70) { + return charInt - 55; // 'A' - 'F' + } else if (charInt >= 97 && charInt <= 102) { + return charInt - 87; // 'a' - 'f' + } else { + revert("invalid hex char"); + } + } +} diff --git a/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol b/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol index 602454f8..b53e59b5 100644 --- a/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol +++ b/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol @@ -25,6 +25,8 @@ contract ECDSAOwnedDKIMRegistry is string public constant SET_PREFIX = "SET:"; string public constant REVOKE_PREFIX = "REVOKE:"; + event SignerChanged(address indexed oldSigner, address indexed newOwner); + constructor() {} /// @notice Initializes the contract with a predefined signer and deploys a new DKIMRegistry. @@ -76,7 +78,6 @@ contract ECDSAOwnedDKIMRegistry is string memory signedMsg = computeSignedMsg( SET_PREFIX, - selector, domainName, publicKeyHash ); @@ -115,7 +116,6 @@ contract ECDSAOwnedDKIMRegistry is string memory signedMsg = computeSignedMsg( REVOKE_PREFIX, - selector, domainName, publicKeyHash ); @@ -130,23 +130,19 @@ contract ECDSAOwnedDKIMRegistry is /// @notice Computes a signed message string for setting or revoking a DKIM public key hash. /// @param prefix The operation prefix (SET: or REVOKE:). - /// @param selector The selector associated with the DKIM public key. /// @param domainName The domain name related to the operation. /// @param publicKeyHash The DKIM public key hash involved in the operation. /// @return string The computed signed message. /// @dev This function is used internally to generate the message that needs to be signed for setting or revoking a public key hash. function computeSignedMsg( string memory prefix, - string memory selector, string memory domainName, bytes32 publicKeyHash ) public pure returns (string memory) { return string.concat( prefix, - "selector=", - selector, - ";domain=", + "domain=", domainName, ";public_key_hash=", uint256(publicKeyHash).toHexString(), @@ -159,7 +155,9 @@ contract ECDSAOwnedDKIMRegistry is function changeSigner(address _newSigner) public onlyOwner { require(_newSigner != address(0), "Invalid signer"); require(_newSigner != signer, "Same signer"); + address oldSigner = signer; signer = _newSigner; + emit SignerChanged(oldSigner, _newSigner); } /// @notice Upgrade the implementation of the proxy. diff --git a/packages/contracts/src/utils/ForwardDKIMRegistry.sol b/packages/contracts/src/utils/ForwardDKIMRegistry.sol deleted file mode 100644 index fa8fc753..00000000 --- a/packages/contracts/src/utils/ForwardDKIMRegistry.sol +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.12; - -import "@zk-email/contracts/DKIMRegistry.sol"; -import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; -import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; - -/// @title Forward DKIM Registry -/// @notice This contract forwards outputs from a source DKIMRegistry contract. -contract ForwardDKIMRegistry is - IDKIMRegistry, - OwnableUpgradeable, - UUPSUpgradeable -{ - IDKIMRegistry public sourceDKIMRegistry; - - constructor() {} - - /// @notice Initializes the contract with a predefined signer and deploys a new DKIMRegistry. - /// @param _initialOwner The address of the initial owner of the contract. - /// @param _sourceDKIMRegistry The address of the source DKIMRegistry contract to forward outputs from. - function initialize( - address _initialOwner, - address _sourceDKIMRegistry - ) public initializer { - __Ownable_init(_initialOwner); - sourceDKIMRegistry = IDKIMRegistry(_sourceDKIMRegistry); - } - - /// @notice Checks if a DKIM public key hash is valid and not revoked for a given domain name. - /// @param domainName The domain name to check the DKIM public key hash for. - /// @param publicKeyHash The DKIM public key hash to validate. - /// @return bool Returns true if the public key hash is valid and not revoked, false otherwise. - function isDKIMPublicKeyHashValid( - string memory domainName, - bytes32 publicKeyHash - ) public view returns (bool) { - return - sourceDKIMRegistry.isDKIMPublicKeyHashValid( - domainName, - publicKeyHash - ); - } - - /// @notice Sets a new souce DKIMRegistry contract to forward outputs from. - /// @param _newSourceDKIMRegistry The address of the new source DKIMRegistry contract. - function changeSourceDKIMRegistry( - address _newSourceDKIMRegistry - ) public onlyOwner { - require(_newSourceDKIMRegistry != address(0), "Invalid address"); - require( - _newSourceDKIMRegistry != address(sourceDKIMRegistry), - "Same source DKIMRegistry" - ); - require( - _newSourceDKIMRegistry != address(this), - "Cannot set self as source DKIMRegistry" - ); - sourceDKIMRegistry = IDKIMRegistry(_newSourceDKIMRegistry); - } - - /// @notice Upgrade the implementation of the proxy from the ECDSAOwnedDKIMRegistry. - /// @param _sourceDKIMRegistry The address of the source DKIMRegistry contract to forward outputs from. - /// @dev This function resets the storage at sourceDKIMRegistry.slot+1, which is `signer` in the ECDSAOwnedDKIMRegistry contract. - function resetStorageForUpgradeFromECDSAOwnedDKIMRegistry( - address _sourceDKIMRegistry - ) public onlyOwner { - assembly { - sstore(sourceDKIMRegistry.slot, _sourceDKIMRegistry) - sstore(add(sourceDKIMRegistry.slot, 1), 0) - } - } - - /// @notice Upgrade the implementation of the proxy. - /// @param newImplementation Address of the new implementation. - function _authorizeUpgrade( - address newImplementation - ) internal override onlyOwner {} -} diff --git a/packages/contracts/src/utils/Groth16Verifier.sol b/packages/contracts/src/utils/Groth16Verifier.sol index 68dce985..3ce14223 100644 --- a/packages/contracts/src/utils/Groth16Verifier.sol +++ b/packages/contracts/src/utils/Groth16Verifier.sol @@ -22,140 +22,229 @@ pragma solidity >=0.7.0 <0.9.0; contract Groth16Verifier { // 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 gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634; - uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; - uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; - uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930; - uint256 constant deltax1 = 15319578088144148433870292454392579210531397678084258888038350512286180645447; - uint256 constant deltax2 = 1086199161593118582719091177042876064789126336461297231728792628701689859806; - uint256 constant deltay1 = 4446519589909698948619442693220675737896467901545229603388595770900353019149; - uint256 constant deltay2 = 8139820593384559533426709059696820531467462438480254791000622464992960199684; - - - uint256 constant IC0x = 13986287304781811629818135937460078168318260622373795543277096066372223143543; - uint256 constant IC0y = 15894331243762149015069486145475096510770522826153695662065578862511865498937; - - uint256 constant IC1x = 6657352747838160193290269178909503517423918732593479650799343149184802404227; - uint256 constant IC1y = 17531545371284544846757265261390554928852673143570772606416106283932089249579; - - uint256 constant IC2x = 16051798939592501067339450771812211828093389728707303947187369590196641845613; - uint256 constant IC2y = 10642771260914469864609917257305668847488863380437098896048772227333105938215; - - uint256 constant IC3x = 11516771157572865390427149046363199727462471754207638386939698647160647244244; - uint256 constant IC3y = 17750959699385211687017966515706019664346563638845176389048062816482362876919; - - uint256 constant IC4x = 16585945905928734303656632207622552215825428661762022954125060983592130784974; - uint256 constant IC4y = 3229598948329671362480222913836846699152815669479715539731783730018250763823; - - uint256 constant IC5x = 2735854243292750270201823836486550894787960439689214123103674588113028210303; - uint256 constant IC5y = 10229313779238541038726274141671860314069645438049912809508167509745776241686; - - uint256 constant IC6x = 14190416281134666159920819160995974222908686549823480648732091214431137294963; - uint256 constant IC6y = 9029501137578433593499338927272434967030906660585173877815017333537018567602; - - uint256 constant IC7x = 12170260117675309582350267080302912575028682087359352382893089877455951772473; - uint256 constant IC7y = 20464605792252479349840655650760617496046593314952148684746613675335058350942; - - uint256 constant IC8x = 4668263935738216597600035713072363446560555431149535779407481594748353348299; - uint256 constant IC8y = 6761669100053229151181201776369124528384949481913373501345799877551671442490; - - uint256 constant IC9x = 17613426733350227864491099426537059832375604576663256857363196285633689216670; - uint256 constant IC9y = 5805908718695762877817749042508472227770796644334990955096436485320700026010; - - uint256 constant IC10x = 1007270225032823010989311002543641079754257589690234134844035082768426542620; - uint256 constant IC10y = 21475642872129196888302396594264201358769263783216674834698667474324214197953; - - uint256 constant IC11x = 15081923087373370787973554347749696256252721214961183946262805192094431665288; - uint256 constant IC11y = 16680069154888020053830495566095733479743182649643804408659380808462437769348; - - uint256 constant IC12x = 7353920573820203673864179902327357836943865465363806932276427158533966054007; - uint256 constant IC12y = 4906960257966631805968560571985842137400392165080887614941226783003180438368; - - uint256 constant IC13x = 4533862304475638755375693106780349782380565190034231050848543922795764879802; - uint256 constant IC13y = 598446044155555715891219562107384479652732465225600288479065093170075495657; - - uint256 constant IC14x = 7122480915086391928930945426177923412929688778313549168236076125436940484112; - uint256 constant IC14y = 9038961138446510912414783948801197218570794393245280448178371602457294281632; - - uint256 constant IC15x = 6714101981980268884481533101476229027015190942378292707659542820827021193397; - uint256 constant IC15y = 11272887771609959733703167827323622301549783063678829277178890525700670890129; - - uint256 constant IC16x = 20437112715761765707147148391773769986470432308919910067302657232573395960162; - uint256 constant IC16y = 15321179474484971518132512130588191553678751040283340303685576790320739150657; - - uint256 constant IC17x = 19219092435091423465633523463253249487338506702794487406401643619518191650129; - uint256 constant IC17y = 17282626638553680622130806938296519057489422178618812871701640691501519771672; - - uint256 constant IC18x = 16606183112206685785600995921349860405026995817135601022134279364752803469536; - uint256 constant IC18y = 16043499772242927375270363061004003839285471350971879635887182974533742603287; - - uint256 constant IC19x = 1210707359308302969770163002263119043614552129675869248158635495219906105852; - uint256 constant IC19y = 12680511356057658336130187063160473463083334743891046286452211277763548137276; - - uint256 constant IC20x = 11086125674217491500739269827053901222271696690174050254374133368712953243088; - uint256 constant IC20y = 6053103800204978405773186514845086084032005357588363656542377416178871564775; - - uint256 constant IC21x = 14748494146527412772741859783064786419256684299339014876234608950795174044510; - uint256 constant IC21y = 8712883247211066789641782294202642212131980591356063435892043611448376329402; - - uint256 constant IC22x = 11839379700336717343079420809622942111687375327897345508451774961872673770316; - uint256 constant IC22y = 8895701596719783222411291561512126156358240424160295697039536555088618180915; - - uint256 constant IC23x = 18344723580640218566078573334781871542714315793755378650476142891258578517167; - uint256 constant IC23y = 6037447496975377303076282689670453476478799098316334507779292520966118416141; - - uint256 constant IC24x = 1219018687863146079804927794790349811713233524506071692145203043151155579912; - uint256 constant IC24y = 12259329329644691804803466046583012104373647543094116751541858451574329049339; - - uint256 constant IC25x = 18616266469772173270024938497854580018451184027620595567381348061717260755876; - uint256 constant IC25y = 13657793433977158706390923089623450140219483127718023788044217038622204508743; - - uint256 constant IC26x = 12727423626475319557504848343871689884624000795573098126755145386839939527511; - uint256 constant IC26y = 2938262592563768549228983305699572862280081061292424052023446347112367143549; - - uint256 constant IC27x = 21487591408762398705234938070547673395123973173141617628201773263097079121694; - uint256 constant IC27y = 12720246748523909661755448585533297402316709697570936404470276522191359637563; - - uint256 constant IC28x = 16467178226026300059831605377943086050334723191464668213518101445484504783848; - uint256 constant IC28y = 9139131916495414634537516523354727831542697092324217153640571950935058484467; - - uint256 constant IC29x = 11813394657812788297263465566473337219295871229603907247462957762987163286727; - uint256 constant IC29y = 2333466569019313289053951330259295038552214976343543633683510156531235807982; - - uint256 constant IC30x = 5758319522107086585563855735449863655068464994393372981823525634565012585161; - uint256 constant IC30y = 281303738559625778766939028867621386494750433481191839742375920626126152406; - - uint256 constant IC31x = 10766255441893413771043297335573055973288564739850120191905483233382630740246; - uint256 constant IC31y = 8012588191039935342856190453376510257080197619321852273994553617995812833773; - - uint256 constant IC32x = 13740647652203492799542105246627141268848155986372129145815588390071245063824; - uint256 constant IC32y = 12989805147963975539185412669782613149167981050611353053030652178298637898321; - - uint256 constant IC33x = 11678473503165871308190682100052535955722167524502187482920769926720343167599; - uint256 constant IC33y = 13548393914151182724283386224251830133662331816742832947222699249802146353834; - - uint256 constant IC34x = 20746424191835410865488887203537015077703505567964632145891041247460534632431; - uint256 constant IC34y = 14888985375914925013094608784755252069956164909406628467775584250729953169513; - - + 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 = + 5497488235179473826828684387336498481269856448745725476449758558899122533965; + uint256 constant deltax2 = + 4003153155889817328460023080016930336723532885689205290620422457794938611877; + uint256 constant deltay1 = + 18315354651962278644845506881891113119054778749068091769665326968932369037073; + uint256 constant deltay2 = + 21098611876989822455957506930132954763752169279648301152081784213815758941363; + + uint256 constant IC0x = + 9170617522866991135920485929060945961251903707439116464009103514785703018722; + uint256 constant IC0y = + 21464668013911866124563191908999294995464566429237314295942207031454516302123; + + uint256 constant IC1x = + 8036698806103763640351502391006481935487865878289833393815794668836536153167; + uint256 constant IC1y = + 13596639679061071633812079299877222850807480030873626881735523275070865893057; + + uint256 constant IC2x = + 499506615085385319550600819547038712066288500371838317885514224486277713046; + uint256 constant IC2y = + 18122501973397572280523052679560581860450255803082322647610830104242737040547; + + uint256 constant IC3x = + 16027020211893007538458223254125476146596225011320323167351093627291965558474; + uint256 constant IC3y = + 20898438163660952821715072153405033904082580408391343581266941097136380340202; + + uint256 constant IC4x = + 17797428184725397522989067964088125681422143297689241282215813176727518015314; + uint256 constant IC4y = + 4873693227630449792291352496013411166085222578702675914989902281431159727425; + + uint256 constant IC5x = + 12023745408722526643528949957434555547940449565910300230914721190107978063692; + uint256 constant IC5y = + 7113510604640248866229327602140012470092520724668151899773219017541006499297; + + uint256 constant IC6x = + 15092867219733677231883227116417357592793695380712213807744179224782743690589; + uint256 constant IC6y = + 14073738731917256064323792082179332493257848781058843897946309361960073327978; + + uint256 constant IC7x = + 3684741090613658947708742012848533383585720001368047937575886240445033851906; + uint256 constant IC7y = + 12207747334874542453080362673676466829579409088542537082423635827245088128272; + + uint256 constant IC8x = + 19002324477985922167064744385878968732899209399143060380793149556026251592602; + uint256 constant IC8y = + 4059961567391272264685529975466168592722724488333375025668990370066233646166; + + uint256 constant IC9x = + 18119862666587048057671133841224298259438630983276244986744261806380749837773; + uint256 constant IC9y = + 11962479760502925616694601274223949055656714994982269820791207291024000632609; + + uint256 constant IC10x = + 4837987697990457908433233670645319075873778433938647361721602242125452738030; + uint256 constant IC10y = + 15236268659498569797075030548022359846010902866726138387738164423503072310707; + + uint256 constant IC11x = + 2247396818182013430087036496942142214752772542649703327806617027071497917942; + uint256 constant IC11y = + 7230776950211947694928844765804460712717757707661339065648508460015655104228; + + uint256 constant IC12x = + 12713866304006001178181591584880622511186107746653655885620366199651976233161; + uint256 constant IC12y = + 8503403690339164684791321070468528510206988145312360891509303133763745413970; + + uint256 constant IC13x = + 18786348310700161544409631041798363545102509830963516511899026172253149396332; + uint256 constant IC13y = + 21500707182197186213030353100630787487264113882577328681154515012353735900843; + + uint256 constant IC14x = + 19744710172151809333993281803386438409947096275265004935622878676630675470833; + uint256 constant IC14y = + 2576981868538969889173351250763305912513432113413525575578065236377800875822; + + uint256 constant IC15x = + 3206564470727573087917372342973225125555287399342021084149838990642821371127; + uint256 constant IC15y = + 5161383469468878225198418179083564775190127925714644111334764258425279357217; + + uint256 constant IC16x = + 19800719324327815136401634331189026968197343603735164559359238874592683083541; + uint256 constant IC16y = + 15353409434530944340514132291821683791468326075312829060336930345885204539706; + + uint256 constant IC17x = + 3640440581565461755502514856833693195947470325337339914156654321867531155465; + uint256 constant IC17y = + 18079282812947186632120156585970526079738045461684618442425751105696328516097; + + uint256 constant IC18x = + 10893763966492325670332807228126944020670778202517987145728964637567836758346; + uint256 constant IC18y = + 10411790247488882499382877703586711529597727515468034179207752283364566985888; + + uint256 constant IC19x = + 4764427752328278744254518251166003976466653421436809959915751631447496050938; + uint256 constant IC19y = + 19077753055984861715512342844683789209011005809457938960067599507730134463681; + + uint256 constant IC20x = + 19239217140206655417849511896762436383483680427288929636227826897033073930831; + uint256 constant IC20y = + 325669322205419711078742210764058451859960204265448263589903725256769719908; + + uint256 constant IC21x = + 9046949632757385439211234657284735159060916785506782533392679376767484273311; + uint256 constant IC21y = + 20044713591428591732634085797466932645663425416025585843668452500891354065874; + + uint256 constant IC22x = + 16596559512784641563136311168565033649965163504772478406283477546552735512444; + uint256 constant IC22y = + 18774916477080192640977299596116488820879582886257295797472287704487118274582; + + uint256 constant IC23x = + 11065920011030170977088976300578864595621412015518607945690661420939547443287; + uint256 constant IC23y = + 9783662703088180423518052023535664031839193609219041737685439910536024663110; + + uint256 constant IC24x = + 9425175894243140889465318007705005738526030710167099033209810247905244108455; + uint256 constant IC24y = + 20108686730560795297992101621420823068690965693475885571800874269588037486848; + + uint256 constant IC25x = + 6609840993179990263963690359015759426724737820953411246704701817106482402765; + uint256 constant IC25y = + 8229882515191225544586553421357621578418249956862953960306318915181230001321; + + uint256 constant IC26x = + 6217618480062881120509048997150849300692609908856364032921701274211185432605; + uint256 constant IC26y = + 17797067728027591123982021819619850181346889026541414686916538486686336569724; + + uint256 constant IC27x = + 1167682482959817892490769846144428259164241510916012050018984311559474630505; + uint256 constant IC27y = + 4288329427112040042914279815845143159445276063584132207380270762778849241945; + + uint256 constant IC28x = + 5415115331131793084519828832117894467078578382634776057559235045636691870013; + uint256 constant IC28y = + 294500291396098324360741728286526924810064976792973340408461656451862732414; + + uint256 constant IC29x = + 14856578790154174007849553677467062531597996074804148901675028113916393017677; + uint256 constant IC29y = + 6361029624624071755451013494330930602310752529446989393421427506813362412640; + + uint256 constant IC30x = + 17962991793243414860245089352956560187894972850467815106957643891422523715958; + uint256 constant IC30y = + 18841505088866678579127925206390276772822034114801476039320216285471834301092; + + uint256 constant IC31x = + 13846860298119975507726775645108672548648502244874250861778555730227332305060; + uint256 constant IC31y = + 657667593986857792918295730942299182651889534697927169554073515375088513619; + + uint256 constant IC32x = + 20870099023226942480166036035118260888733585326446307013318721811253039624277; + uint256 constant IC32y = + 16200956906397254163030543075393672323548410478543768674895989718450369275888; + + uint256 constant IC33x = + 16368783358795172690167609997311543188986742122336668117233901650756123609986; + uint256 constant IC33y = + 16566438916809530207078763106488760552869428102855514589370790379158565723484; + + uint256 constant IC34x = + 2230845793580325981748815021422651861534270868481069377891033264104263784264; + uint256 constant IC34y = + 11702184962308460081167560437631611976965156120031396153640734755006168447805; + // 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[34] calldata _pubSignals) public view returns (bool) { + function verifyProof( + uint[2] calldata _pA, + uint[2][2] calldata _pB, + uint[2] calldata _pC, + uint[34] calldata _pubSignals + ) public view returns (bool) { assembly { function checkField(v) { if iszero(lt(v, r)) { @@ -163,7 +252,7 @@ contract Groth16Verifier { 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 @@ -198,79 +287,206 @@ contract Groth16Verifier { 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))) - - g1_mulAccC(_pVk, IC22x, IC22y, calldataload(add(pubSignals, 672))) - - g1_mulAccC(_pVk, IC23x, IC23y, calldataload(add(pubSignals, 704))) - - g1_mulAccC(_pVk, IC24x, IC24y, calldataload(add(pubSignals, 736))) - - g1_mulAccC(_pVk, IC25x, IC25y, calldataload(add(pubSignals, 768))) - - g1_mulAccC(_pVk, IC26x, IC26y, calldataload(add(pubSignals, 800))) - - g1_mulAccC(_pVk, IC27x, IC27y, calldataload(add(pubSignals, 832))) - - g1_mulAccC(_pVk, IC28x, IC28y, calldataload(add(pubSignals, 864))) - - g1_mulAccC(_pVk, IC29x, IC29y, calldataload(add(pubSignals, 896))) - - g1_mulAccC(_pVk, IC30x, IC30y, calldataload(add(pubSignals, 928))) - - g1_mulAccC(_pVk, IC31x, IC31y, calldataload(add(pubSignals, 960))) - - g1_mulAccC(_pVk, IC32x, IC32y, calldataload(add(pubSignals, 992))) - - g1_mulAccC(_pVk, IC33x, IC33y, calldataload(add(pubSignals, 1024))) - - g1_mulAccC(_pVk, IC34x, IC34y, calldataload(add(pubSignals, 1056))) - + + 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)) + ) + + g1_mulAccC( + _pVk, + IC22x, + IC22y, + calldataload(add(pubSignals, 672)) + ) + + g1_mulAccC( + _pVk, + IC23x, + IC23y, + calldataload(add(pubSignals, 704)) + ) + + g1_mulAccC( + _pVk, + IC24x, + IC24y, + calldataload(add(pubSignals, 736)) + ) + + g1_mulAccC( + _pVk, + IC25x, + IC25y, + calldataload(add(pubSignals, 768)) + ) + + g1_mulAccC( + _pVk, + IC26x, + IC26y, + calldataload(add(pubSignals, 800)) + ) + + g1_mulAccC( + _pVk, + IC27x, + IC27y, + calldataload(add(pubSignals, 832)) + ) + + g1_mulAccC( + _pVk, + IC28x, + IC28y, + calldataload(add(pubSignals, 864)) + ) + + g1_mulAccC( + _pVk, + IC29x, + IC29y, + calldataload(add(pubSignals, 896)) + ) + + g1_mulAccC( + _pVk, + IC30x, + IC30y, + calldataload(add(pubSignals, 928)) + ) + + g1_mulAccC( + _pVk, + IC31x, + IC31y, + calldataload(add(pubSignals, 960)) + ) + + g1_mulAccC( + _pVk, + IC32x, + IC32y, + calldataload(add(pubSignals, 992)) + ) + + g1_mulAccC( + _pVk, + IC33x, + IC33y, + calldataload(add(pubSignals, 1024)) + ) + + g1_mulAccC( + _pVk, + IC34x, + IC34y, + calldataload(add(pubSignals, 1056)) + ) // -A mstore(_pPairing, calldataload(pA)) - mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q)) + mstore( + add(_pPairing, 32), + mod(sub(q, calldataload(add(pA, 32))), q) + ) // B mstore(add(_pPairing, 64), calldataload(pB)) @@ -292,7 +508,6 @@ contract Groth16Verifier { 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) @@ -309,8 +524,14 @@ contract Groth16Verifier { mstore(add(_pPairing, 704), deltay1) mstore(add(_pPairing, 736), deltay2) - - let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20) + let success := staticcall( + sub(gas(), 2000), + 8, + _pPairing, + 768, + _pPairing, + 0x20 + ) isOk := and(success, mload(_pPairing)) } @@ -319,83 +540,80 @@ contract Groth16Verifier { 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))) - + checkField(calldataload(add(_pubSignals, 672))) - + checkField(calldataload(add(_pubSignals, 704))) - + checkField(calldataload(add(_pubSignals, 736))) - + checkField(calldataload(add(_pubSignals, 768))) - + checkField(calldataload(add(_pubSignals, 800))) - + checkField(calldataload(add(_pubSignals, 832))) - + checkField(calldataload(add(_pubSignals, 864))) - + checkField(calldataload(add(_pubSignals, 896))) - + checkField(calldataload(add(_pubSignals, 928))) - + checkField(calldataload(add(_pubSignals, 960))) - + checkField(calldataload(add(_pubSignals, 992))) - + checkField(calldataload(add(_pubSignals, 1024))) - + checkField(calldataload(add(_pubSignals, 1056))) - - checkField(calldataload(add(_pubSignals, 1088))) - // Validate all evaluations let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem) mstore(0, isValid) - return(0, 0x20) - } - } - } + return(0, 0x20) + } + } +} diff --git a/packages/contracts/src/utils/Verifier.sol b/packages/contracts/src/utils/Verifier.sol index 2ccff85d..ccbcdea5 100644 --- a/packages/contracts/src/utils/Verifier.sol +++ b/packages/contracts/src/utils/Verifier.sol @@ -1,36 +1,37 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.9; -import "./Groth16Verifier.sol"; +import "../interfaces/IGroth16Verifier.sol"; import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {IVerifier, EmailProof} from "../interfaces/IVerifier.sol"; -struct EmailProof { - string domainName; // Domain name of the sender's email - bytes32 publicKeyHash; // Hash of the DKIM public key used in email/proof - uint timestamp; // Timestamp of the email - string maskedSubject; // Masked subject of the email - bytes32 emailNullifier; // Nullifier of the email to prevent its reuse. - bytes32 accountSalt; // Create2 salt of the account - bool isCodeExist; // Check if the account code is exist - bytes proof; // ZK Proof of Email -} - -contract Verifier is OwnableUpgradeable, UUPSUpgradeable { - Groth16Verifier groth16Verifier; +contract Verifier is OwnableUpgradeable, UUPSUpgradeable, IVerifier { + IGroth16Verifier groth16Verifier; uint256 public constant DOMAIN_FIELDS = 9; uint256 public constant DOMAIN_BYTES = 255; - uint256 public constant SUBJECT_FIELDS = 20; - uint256 public constant SUBJECT_BYTES = 605; + uint256 public constant COMMAND_FIELDS = 20; + uint256 public constant COMMAND_BYTES = 605; + + // Base field size + uint256 constant q = + 21888242871839275222246405745257275088696311157297823662689037894645226208583; constructor() {} /// @notice Initialize the contract with the initial owner and deploy Groth16Verifier /// @param _initialOwner The address of the initial owner - function initialize(address _initialOwner) public initializer { + function initialize( + address _initialOwner, + address _groth16Verifier + ) public initializer { __Ownable_init(_initialOwner); - groth16Verifier = new Groth16Verifier(); + groth16Verifier = IGroth16Verifier(_groth16Verifier); + } + + function commandBytes() external pure returns (uint256) { + return COMMAND_BYTES; } function verifyEmailProof( @@ -41,8 +42,13 @@ contract Verifier is OwnableUpgradeable, UUPSUpgradeable { uint256[2][2] memory pB, uint256[2] memory pC ) = abi.decode(proof.proof, (uint256[2], uint256[2][2], uint256[2])); - - uint256[DOMAIN_FIELDS + SUBJECT_FIELDS + 5] memory pubSignals; + require(pA[0] < q && pA[1] < q, "invalid format of pA"); + require( + pB[0][0] < q && pB[0][1] < q && pB[1][0] < q && pB[1][1] < q, + "invalid format of pB" + ); + require(pC[0] < q && pC[1] < q, "invalid format of pC"); + uint256[DOMAIN_FIELDS + COMMAND_FIELDS + 5] memory pubSignals; uint256[] memory stringFields; stringFields = _packBytes2Fields(bytes(proof.domainName), DOMAIN_BYTES); for (uint256 i = 0; i < DOMAIN_FIELDS; i++) { @@ -52,16 +58,16 @@ contract Verifier is OwnableUpgradeable, UUPSUpgradeable { pubSignals[DOMAIN_FIELDS + 1] = uint256(proof.emailNullifier); pubSignals[DOMAIN_FIELDS + 2] = uint256(proof.timestamp); stringFields = _packBytes2Fields( - bytes(proof.maskedSubject), - SUBJECT_BYTES + bytes(proof.maskedCommand), + COMMAND_BYTES ); - for (uint256 i = 0; i < SUBJECT_FIELDS; i++) { + for (uint256 i = 0; i < COMMAND_FIELDS; i++) { pubSignals[DOMAIN_FIELDS + 3 + i] = stringFields[i]; } - pubSignals[DOMAIN_FIELDS + 3 + SUBJECT_FIELDS] = uint256( + pubSignals[DOMAIN_FIELDS + 3 + COMMAND_FIELDS] = uint256( proof.accountSalt ); - pubSignals[DOMAIN_FIELDS + 3 + SUBJECT_FIELDS + 1] = proof.isCodeExist + pubSignals[DOMAIN_FIELDS + 3 + COMMAND_FIELDS + 1] = proof.isCodeExist ? 1 : 0; @@ -71,7 +77,7 @@ contract Verifier is OwnableUpgradeable, UUPSUpgradeable { function _packBytes2Fields( bytes memory _bytes, uint256 _paddedSize - ) public pure returns (uint256[] memory) { + ) private pure returns (uint256[] memory) { uint256 remain = _paddedSize % 31; uint256 numFields = (_paddedSize - remain) / 31; if (remain > 0) { diff --git a/packages/contracts/src/utils/ZKSyncCreate2Factory.sol b/packages/contracts/src/utils/ZKSyncCreate2Factory.sol index ee3ba883..09e22097 100644 --- a/packages/contracts/src/utils/ZKSyncCreate2Factory.sol +++ b/packages/contracts/src/utils/ZKSyncCreate2Factory.sol @@ -10,12 +10,12 @@ import {ZKSyncCreate2FactoryBase} from "./ZKSyncCreate2FactoryBase.sol"; contract ZKSyncCreate2Factory is ZKSyncCreate2FactoryBase { // // FOR_ZKSYNC:START - // function computeAddress(bytes32 salt, bytes32 bytecodeHash, bytes memory input) external view returns (address) { + // function computeAddress(bytes32 salt, bytes32 bytecodeHash, bytes memory input) external override view returns (address) { // return L2ContractHelper.computeCreate2Address(address(this), salt, bytes32(bytecodeHash), keccak256(input)); // } - // function deploy(bytes32 salt, bytes32 bytecodeHash, bytes memory input) // external + // override // returns (bool success, bytes memory returnData) // { // (success, returnData) = SystemContractsCaller.systemCallWithReturndata( diff --git a/packages/contracts/test/DKIMRegistryUpgrade.t.sol b/packages/contracts/test/DKIMRegistryUpgrade.t.sol index 82342991..59d8d986 100644 --- a/packages/contracts/test/DKIMRegistryUpgrade.t.sol +++ b/packages/contracts/test/DKIMRegistryUpgrade.t.sol @@ -8,15 +8,14 @@ import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "../src/EmailAuth.sol"; import "../src/utils/Verifier.sol"; import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; -import "../src/utils/ForwardDKIMRegistry.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import "./helpers/StructHelper.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {UserOverrideableDKIMRegistry} from "@zk-email/contracts/UserOverrideableDKIMRegistry.sol"; contract DKIMRegistryUpgradeTest is StructHelper { function setUp() public override { super.setUp(); - vm.startPrank(deployer); emailAuth.initialize(deployer, accountSalt, deployer); vm.expectEmit(true, false, false, false); @@ -25,42 +24,44 @@ contract DKIMRegistryUpgradeTest is StructHelper { vm.expectEmit(true, false, false, false); emit EmailAuth.DKIMRegistryUpdated(address(dkim)); emailAuth.updateDKIMRegistry(address(dkim)); - - ForwardDKIMRegistry forwardDkimImpl = new ForwardDKIMRegistry(); - dkim.upgradeToAndCall( - address(forwardDkimImpl), + UserOverrideableDKIMRegistry overrideableDkimImpl = new UserOverrideableDKIMRegistry(); + ERC1967Proxy overrideableDkimProxy = new ERC1967Proxy( + address(overrideableDkimImpl), abi.encodeCall( - forwardDkimImpl - .resetStorageForUpgradeFromECDSAOwnedDKIMRegistry, - (address(overrideableDkim)) + overrideableDkimImpl.initialize, + (deployer, deployer, setTimestampDelay) ) ); + UserOverrideableDKIMRegistry overrideableDkim = UserOverrideableDKIMRegistry( + address(overrideableDkimProxy) + ); + overrideableDkim.setDKIMPublicKeyHash( + domainName, + publicKeyHash, + deployer, + new bytes(0) + ); vm.stopPrank(); } - function testDkimRegistryAddr() public view { address dkimAddr = emailAuth.dkimRegistryAddr(); assertEq(dkimAddr, address(dkim)); } - - function _testInsertSubjectTemplate() private { - emailAuth.insertSubjectTemplate(templateId, subjectTemplate); - string[] memory result = emailAuth.getSubjectTemplate(templateId); - assertEq(result, subjectTemplate); + function _testInsertCommandTemplate() private { + emailAuth.insertCommandTemplate(templateId, commandTemplate); + string[] memory result = emailAuth.getCommandTemplate(templateId); + assertEq(result, commandTemplate); } - function testAuthEmail() public { vm.startPrank(deployer); - _testInsertSubjectTemplate(); + _testInsertCommandTemplate(); EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); vm.stopPrank(); - assertEq( emailAuth.usedNullifiers(emailAuthMsg.proof.emailNullifier), false ); assertEq(emailAuth.lastTimestamp(), 0); - vm.startPrank(deployer); vm.expectEmit(true, true, true, true); emit EmailAuth.EmailAuthed( @@ -71,7 +72,6 @@ contract DKIMRegistryUpgradeTest is StructHelper { ); emailAuth.authEmail(emailAuthMsg); vm.stopPrank(); - assertEq( emailAuth.usedNullifiers(emailAuthMsg.proof.emailNullifier), true diff --git a/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_acceptanceSubjectTemplates.t.sol b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_acceptanceSubjectTemplates.t.sol index 71ebc88b..7e596e79 100644 --- a/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_acceptanceSubjectTemplates.t.sol +++ b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_acceptanceSubjectTemplates.t.sol @@ -9,18 +9,18 @@ import {StructHelper} from "../helpers/StructHelper.sol"; import {SimpleWallet} from "../helpers/SimpleWallet.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -contract EmailAccountRecoveryTest_acceptanceSubjectTemplates is StructHelper { +contract EmailAccountRecoveryTest_acceptanceCommandTemplates is StructHelper { constructor() {} function setUp() public override { super.setUp(); } - function testAcceptanceSubjectTemplates() public { + function testAcceptanceCommandTemplates() public { skipIfZkSync(); - + setUp(); - string[][] memory res = recoveryController.acceptanceSubjectTemplates(); + string[][] memory res = recoveryController.acceptanceCommandTemplates(); assertEq(res[0][0], "Accept"); assertEq(res[0][1], "guardian"); assertEq(res[0][2], "request"); diff --git a/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_completeRecovery.t.sol b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_completeRecovery.t.sol index b76c15b7..00ba5401 100644 --- a/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_completeRecovery.t.sol +++ b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_completeRecovery.t.sol @@ -50,9 +50,9 @@ contract EmailAccountRecoveryTest_completeRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; vm.mockCall( address(recoveryController.emailAuthImplementationAddr()), @@ -94,10 +94,10 @@ contract EmailAccountRecoveryTest_completeRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; vm.mockCall( address(recoveryController.emailAuthImplementationAddr()), diff --git a/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_general.t.sol b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_general.t.sol new file mode 100644 index 00000000..7f574df4 --- /dev/null +++ b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_general.t.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "../helpers/StructHelper.sol"; + +contract EmailAccountRecoveryTest_general is Test, StructHelper { + function test_erifier() public { + assertEq(recoveryController.verifier(), address(verifier)); + } + + function test_DKIM() public { + assertEq(recoveryController.dkim(), address(dkim)); + } + + function test_EmailAuthImplementation() public { + assertEq(recoveryController.emailAuthImplementation(), address(emailAuth)); + } +} \ No newline at end of file diff --git a/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_handleAcceptance.t.sol b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_handleAcceptance.t.sol index 2bda3928..3e689134 100644 --- a/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_handleAcceptance.t.sol +++ b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_handleAcceptance.t.sol @@ -8,6 +8,7 @@ import {RecoveryController} from "../helpers/RecoveryController.sol"; import {StructHelper} from "../helpers/StructHelper.sol"; import {SimpleWallet} from "../helpers/SimpleWallet.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol"; contract EmailAccountRecoveryTest_handleAcceptance is StructHelper { constructor() {} @@ -35,9 +36,228 @@ contract EmailAccountRecoveryTest_handleAcceptance is StructHelper { ); } + function testExpectRevertHandleAcceptanceInvalidRecoveredAccount() public { + skipIfZkSync(); + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + emailAuthMsg.templateId = recoveryController + .computeAcceptanceTemplateId(0); + emailAuthMsg.commandParams[0] = abi.encode(address(0x0)); // Invalid account + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("invalid command params")); + recoveryController.handleAcceptance(emailAuthMsg, 0); + vm.stopPrank(); + } + + function testExpectRevertHandleAcceptanceInvalidTemplateId() public { + skipIfZkSync(); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryController.computeAcceptanceTemplateId( + templateIdx + ); + emailAuthMsg.templateId = 999; // invalid template id + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("invalid template id")); + recoveryController.handleAcceptance(emailAuthMsg, 0); + vm.stopPrank(); + } + + function testExpectRevertHandleAcceptanceInvalidEmailAuthMsgStructure() + public + { + skipIfZkSync(); + + requestGuardian(); + + require( + recoveryController.guardians(guardian) == + RecoveryController.GuardianStatus.REQUESTED + ); + + uint templateIdx = 0; + + // Create an invalid EmailAuthMsg with empty commandParams + EmailAuthMsg memory emailAuthMsg; + emailAuthMsg.templateId = recoveryController + .computeAcceptanceTemplateId(templateIdx); + emailAuthMsg.commandParams = new bytes[](0); // Invalid structure + + vm.mockCall( + address(recoveryController.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("invalid command params")); + recoveryController.handleAcceptance(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + + function testExpectRevertHandleAcceptanceInvalidVerifier() public { + skipIfZkSync(); + + requestGuardian(); + + require( + recoveryController.guardians(guardian) == + RecoveryController.GuardianStatus.REQUESTED + ); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryController.computeAcceptanceTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; + + // Set Verifier address to address(0) + vm.store( + address(recoveryController), + bytes32(uint256(0)), // Assuming Verifier is the 1st storage slot in RecoveryController + bytes32(uint256(0)) + ); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("invalid verifier address")); + recoveryController.handleAcceptance(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + + function testExpectRevertHandleAcceptanceInvalidDKIMRegistry() public { + skipIfZkSync(); + + requestGuardian(); + + require( + recoveryController.guardians(guardian) == + RecoveryController.GuardianStatus.REQUESTED + ); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryController.computeAcceptanceTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; + + // Set DKIMRegistry address to address(0) + vm.store( + address(recoveryController), + bytes32(uint256(1)), // Assuming DKIMRegistry is the 2nd storage slot in RecoveryController + bytes32(uint256(0)) + ); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("invalid dkim registry address")); + recoveryController.handleAcceptance(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + + function testExpectRevertHandleAcceptanceInvalidEmailAuthImplementationAddr() + public + { + skipIfZkSync(); + + requestGuardian(); + + require( + recoveryController.guardians(guardian) == + RecoveryController.GuardianStatus.REQUESTED + ); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryController.computeAcceptanceTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; + + // Set EmailAuthImplementationAddr address to address(0) + vm.store( + address(recoveryController), + bytes32(uint256(2)), // Assuming EmailAuthImplementationAddr is the 3rd storage slot in RecoveryController + bytes32(uint256(0)) + ); + + vm.startPrank(someRelayer); + vm.expectRevert( + abi.encodeWithSelector( + ERC1967Utils.ERC1967InvalidImplementation.selector, + address(0) + ) + ); + recoveryController.handleAcceptance(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + + function testExpectRevertHandleAcceptanceInvalidController() public { + skipIfZkSync(); + + // First, request and accept a guardian + requestGuardian(); + uint templateIdx = 0; + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + uint templateId = recoveryController.computeAcceptanceTemplateId( + templateIdx + ); + emailAuthMsg.templateId = templateId; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; + + vm.mockCall( + address(recoveryController.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.prank(someRelayer); + recoveryController.handleAcceptance(emailAuthMsg, templateIdx); + + require( + recoveryController.guardians(guardian) == + RecoveryController.GuardianStatus.ACCEPTED, + "Guardian should be accepted" + ); + + // Now, set an invalid controller for the guardian's EmailAuth contract + address invalidController = address(0x1234); + vm.mockCall( + guardian, + abi.encodeWithSelector(bytes4(keccak256("controller()"))), + abi.encode(invalidController) + ); + + // Try to handle acceptance again, which should fail due to invalid controller + vm.expectRevert("invalid controller"); + vm.prank(someRelayer); + recoveryController.handleAcceptance(emailAuthMsg, templateIdx); + } + function testHandleAcceptance() public { skipIfZkSync(); - + requestGuardian(); console.log("guardian", guardian); @@ -54,9 +274,9 @@ contract EmailAccountRecoveryTest_handleAcceptance is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; vm.mockCall( address(recoveryController.emailAuthImplementationAddr()), @@ -97,9 +317,9 @@ contract EmailAccountRecoveryTest_handleAcceptance is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; emailAuthMsg.proof.accountSalt = 0x0; vm.mockCall( @@ -131,9 +351,9 @@ contract EmailAccountRecoveryTest_handleAcceptance is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; vm.mockCall( address(recoveryController.emailAuthImplementationAddr()), @@ -147,7 +367,7 @@ contract EmailAccountRecoveryTest_handleAcceptance is StructHelper { vm.stopPrank(); } - function testExpectRevertHandleAcceptanceInvalidSubjectParams() public { + function testExpectRevertHandleAcceptanceInvalidCommandParams() public { skipIfZkSync(); requestGuardian(); @@ -164,10 +384,10 @@ contract EmailAccountRecoveryTest_handleAcceptance is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForAcceptance = new bytes[](2); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); - subjectParamsForAcceptance[1] = abi.encode(address(simpleWallet)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](2); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + commandParamsForAcceptance[1] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; vm.mockCall( address(recoveryController.emailAuthImplementationAddr()), @@ -176,7 +396,7 @@ contract EmailAccountRecoveryTest_handleAcceptance is StructHelper { ); vm.startPrank(someRelayer); - vm.expectRevert(bytes("invalid subject params")); + vm.expectRevert(bytes("invalid command params")); recoveryController.handleAcceptance(emailAuthMsg, templateIdx); vm.stopPrank(); } @@ -200,9 +420,9 @@ contract EmailAccountRecoveryTest_handleAcceptance is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(0x0)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(0x0)); + emailAuthMsg.commandParams = commandParamsForAcceptance; vm.mockCall( address(recoveryController.emailAuthImplementationAddr()), diff --git a/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_handleRecovery.t.sol b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_handleRecovery.t.sol index f497a36e..7bb5f67b 100644 --- a/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_handleRecovery.t.sol +++ b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_handleRecovery.t.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.12; import "forge-std/Test.sol"; import "forge-std/console.sol"; import {EmailAuth, EmailAuthMsg} from "../../src/EmailAuth.sol"; -import {RecoveryController} from "../helpers/RecoveryController.sol"; +import {RecoveryController, EmailAccountRecovery} from "../helpers/RecoveryController.sol"; import {StructHelper} from "../helpers/StructHelper.sol"; import {SimpleWallet} from "../helpers/SimpleWallet.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; @@ -52,9 +52,9 @@ contract EmailAccountRecoveryTest_handleRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; vm.mockCall( address(recoveryController.emailAuthImplementationAddr()), @@ -73,6 +73,129 @@ contract EmailAccountRecoveryTest_handleRecovery is StructHelper { ); } + function testExpectRevertHandleRecoveryInvalidRecoveredAccount() public { + skipIfZkSync(); + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + emailAuthMsg.templateId = recoveryController.computeRecoveryTemplateId( + 0 + ); + emailAuthMsg.commandParams[0] = abi.encode(address(0x0)); // Invalid account + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("invalid account in email")); + recoveryController.handleRecovery(emailAuthMsg, 0); + vm.stopPrank(); + } + + function testExpectRevertHandleRecoveryInvalidAccountInEmail() public { + skipIfZkSync(); + + handleAcceptance(); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + emailAuthMsg.templateId = recoveryController.computeRecoveryTemplateId( + templateIdx + ); + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(address(0x0)); // Invalid account + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; + + vm.mockCall( + address(recoveryController.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("invalid account in email")); + recoveryController.handleRecovery(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + + function testExpectRevertHandleRecoveryGuardianCodeLengthZero() public { + skipIfZkSync(); + + handleAcceptance(); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + emailAuthMsg.templateId = recoveryController.computeRecoveryTemplateId( + templateIdx + ); + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; + + // Mock guardian with no code + vm.etch(guardian, ""); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("guardian is not deployed")); + recoveryController.handleRecovery(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + + function testExpectRevertHandleRecoveryTemplateIdMismatch() public { + skipIfZkSync(); + + handleAcceptance(); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + emailAuthMsg.templateId = 999; // Invalid template ID + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; + + vm.mockCall( + address(recoveryController.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + abi.encode(0x0) + ); + + vm.startPrank(someRelayer); + vm.expectRevert(bytes("invalid template id")); + recoveryController.handleRecovery(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + + function testExpectRevertHandleRecoveryAuthEmailFailure() public { + skipIfZkSync(); + + handleAcceptance(); + + uint templateIdx = 0; + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + emailAuthMsg.templateId = recoveryController.computeRecoveryTemplateId( + templateIdx + ); + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; + + // Mock authEmail to fail + vm.mockCallRevert( + address(recoveryController.emailAuthImplementationAddr()), + abi.encodeWithSelector(EmailAuth.authEmail.selector, emailAuthMsg), + "REVERT_MESSAGE" + ); + + vm.startPrank(someRelayer); + vm.expectRevert(); // Expect any revert due to authEmail failure + recoveryController.handleRecovery(emailAuthMsg, templateIdx); + vm.stopPrank(); + } + function testHandleRecovery() public { skipIfZkSync(); @@ -98,10 +221,10 @@ contract EmailAccountRecoveryTest_handleRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; vm.mockCall( address(recoveryController.emailAuthImplementationAddr()), @@ -155,10 +278,10 @@ contract EmailAccountRecoveryTest_handleRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; emailAuthMsg.proof.accountSalt = 0x0; vm.mockCall( @@ -194,10 +317,10 @@ contract EmailAccountRecoveryTest_handleRecovery is StructHelper { uint templateIdx = 0; EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; vm.mockCall( address(recoveryController.emailAuthImplementationAddr()), @@ -241,10 +364,10 @@ contract EmailAccountRecoveryTest_handleRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; emailAuthMsg.proof.accountSalt = 0x0; // vm.mockCall( @@ -296,10 +419,10 @@ contract EmailAccountRecoveryTest_handleRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; vm.mockCall( address(recoveryController.emailAuthImplementationAddr()), @@ -313,7 +436,7 @@ contract EmailAccountRecoveryTest_handleRecovery is StructHelper { vm.stopPrank(); } - function testExpectRevertHandleRecoveryInvalidSubjectParams() public { + function testExpectRevertHandleRecoveryInvalidCommandParams() public { skipIfZkSync(); handleAcceptance(); @@ -337,11 +460,11 @@ contract EmailAccountRecoveryTest_handleRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](3); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - subjectParamsForRecovery[1] = abi.encode(address(0x0)); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](3); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + commandParamsForRecovery[1] = abi.encode(address(0x0)); + emailAuthMsg.commandParams = commandParamsForRecovery; vm.mockCall( address(recoveryController.emailAuthImplementationAddr()), @@ -350,7 +473,7 @@ contract EmailAccountRecoveryTest_handleRecovery is StructHelper { ); vm.startPrank(someRelayer); - vm.expectRevert(bytes("invalid subject params")); + vm.expectRevert(bytes("invalid command params")); recoveryController.handleRecovery(emailAuthMsg, templateIdx); vm.stopPrank(); } @@ -373,10 +496,10 @@ contract EmailAccountRecoveryTest_handleRecovery is StructHelper { // EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); // uint templateId = recoveryController.computeRecoveryTemplateId(templateIdx); // emailAuthMsg.templateId = templateId; - // bytes[] memory subjectParamsForRecovery = new bytes[](2); - // subjectParamsForRecovery[0] = abi.encode(address(0x0)); - // subjectParamsForRecovery[1] = abi.encode(newSigner); - // emailAuthMsg.subjectParams = subjectParamsForRecovery; + // bytes[] memory commandParamsForRecovery = new bytes[](2); + // commandParamsForRecovery[0] = abi.encode(address(0x0)); + // commandParamsForRecovery[1] = abi.encode(newSigner); + // emailAuthMsg.commandParams = commandParamsForRecovery; // vm.mockCall( // address(recoveryController.emailAuthImplementationAddr()), @@ -414,10 +537,10 @@ contract EmailAccountRecoveryTest_handleRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(address(0x0)); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(address(0x0)); + emailAuthMsg.commandParams = commandParamsForRecovery; vm.mockCall( address(recoveryController.emailAuthImplementationAddr()), diff --git a/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_recoverySubjectTemplates.t.sol b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_recoverySubjectTemplates.t.sol index 50e720ac..db7a925c 100644 --- a/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_recoverySubjectTemplates.t.sol +++ b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_recoverySubjectTemplates.t.sol @@ -9,18 +9,18 @@ import {StructHelper} from "../helpers/StructHelper.sol"; import {SimpleWallet} from "../helpers/SimpleWallet.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -contract EmailAccountRecoveryTest_recoverySubjectTemplates is StructHelper { +contract EmailAccountRecoveryTest_recoveryCommandTemplates is StructHelper { constructor() {} function setUp() public override { super.setUp(); } - function testRecoverySubjectTemplates() public { + function testRecoveryCommandTemplates() public { skipIfZkSync(); - - setUp(); - string[][] memory res = recoveryController.recoverySubjectTemplates(); + + setUp(); + string[][] memory res = recoveryController.recoveryCommandTemplates(); assertEq(res[0][0], "Set"); assertEq(res[0][1], "the"); assertEq(res[0][2], "new"); diff --git a/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_rejectRecovery.t.sol b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_rejectRecovery.t.sol index 2c554711..d11b52c3 100644 --- a/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_rejectRecovery.t.sol +++ b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_rejectRecovery.t.sol @@ -9,7 +9,9 @@ import {StructHelper} from "../helpers/StructHelper.sol"; import {SimpleWallet} from "../helpers/SimpleWallet.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -contract EmailAccountRecoveryForRejectRecoveryTest_rejectRecovery is StructHelper { +contract EmailAccountRecoveryForRejectRecoveryTest_rejectRecovery is + StructHelper +{ constructor() {} function setUp() public override { @@ -49,12 +51,12 @@ contract EmailAccountRecoveryForRejectRecoveryTest_rejectRecovery is StructHelpe uint templateIdx = 0; EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; address recoveredAccount = recoveryController - .extractRecoveredAccountFromAcceptanceSubject( - emailAuthMsg.subjectParams, + .extractRecoveredAccountFromAcceptanceCommand( + emailAuthMsg.commandParams, templateIdx ); address computedGuardian = recoveryController.computeEmailAuthAddress( @@ -107,10 +109,10 @@ contract EmailAccountRecoveryForRejectRecoveryTest_rejectRecovery is StructHelpe templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; vm.mockCall( address(recoveryController.emailAuthImplementationAddr()), diff --git a/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_requestGuardian.t.sol b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_requestGuardian.t.sol index e03bdaf3..a0a99734 100644 --- a/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_requestGuardian.t.sol +++ b/packages/contracts/test/EmailAccountRecovery/EmailAccountRecovery_requestGuardian.t.sol @@ -10,48 +10,32 @@ import {SimpleWallet} from "../helpers/SimpleWallet.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; contract EmailAccountRecoveryTest_requestGuardian is StructHelper { + using stdStorage for StdStorage; + constructor() {} function setUp() public override { super.setUp(); } - function testRequestGuardian() public { + function testExpectRevertRequestGuardianRecoveryInProgress() public { skipIfZkSync(); setUp(); - require( - recoveryController.guardians(guardian) == - RecoveryController.GuardianStatus.NONE - ); - vm.startPrank(deployer); recoveryController.requestGuardian(guardian); - vm.stopPrank(); - - require( - recoveryController.guardians(guardian) == - RecoveryController.GuardianStatus.REQUESTED - ); - } - // function testRequestGuardianNotOwner() public { - // setUp(); + // Simulate recovery in progress + stdstore + .target(address(recoveryController)) + .sig("isRecovering(address)") + .with_key(address(deployer)) + .checked_write(true); - // require( - // recoveryController.guardians(guardian) == - // recoveryController.GuardianStatus.NONE - // ); - - // vm.startPrank(receiver); - // recoveryController.requestGuardian(guardian); - // vm.stopPrank(); - - // require( - // recoveryController.guardians(guardian) == - // recoveryController.GuardianStatus.NONE - // ); - // } + vm.expectRevert(bytes("recovery in progress")); + recoveryController.requestGuardian(address(0x123)); // Try to request a new guardian + vm.stopPrank(); + } function testExpectRevertRequestGuardianInvalidGuardian() public { skipIfZkSync(); @@ -85,4 +69,43 @@ contract EmailAccountRecoveryTest_requestGuardian is StructHelper { recoveryController.requestGuardian(guardian); vm.stopPrank(); } + + function testRequestGuardian() public { + skipIfZkSync(); + + setUp(); + require( + recoveryController.guardians(guardian) == + RecoveryController.GuardianStatus.NONE + ); + + vm.startPrank(deployer); + recoveryController.requestGuardian(guardian); + vm.stopPrank(); + + require( + recoveryController.guardians(guardian) == + RecoveryController.GuardianStatus.REQUESTED + ); + } + + function testMultipleGuardianRequests() public { + skipIfZkSync(); + + address anotherGuardian = vm.addr(9); + setUp(); + vm.startPrank(deployer); + recoveryController.requestGuardian(guardian); + recoveryController.requestGuardian(anotherGuardian); // Assuming anotherGuardian is defined + vm.stopPrank(); + + require( + recoveryController.guardians(guardian) == + RecoveryController.GuardianStatus.REQUESTED + ); + require( + recoveryController.guardians(anotherGuardian) == + RecoveryController.GuardianStatus.REQUESTED + ); + } } diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_completeRecovery.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_completeRecovery.t.sol index 6713f75e..181c3f51 100644 --- a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_completeRecovery.t.sol +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_completeRecovery.t.sol @@ -50,9 +50,9 @@ contract EmailAccountRecoveryZKSyncTest_completeRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; vm.mockCall( address(recoveryControllerZKSync.emailAuthImplementationAddr()), @@ -74,9 +74,14 @@ contract EmailAccountRecoveryZKSyncTest_completeRecovery is StructHelper { function handleRecovery() public { handleAcceptance(); - assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), false); assertEq( - recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + recoveryControllerZKSync.isRecovering(address(simpleWallet)), + false + ); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount( + address(simpleWallet) + ), 0 ); assertEq(simpleWallet.owner(), deployer); @@ -94,10 +99,10 @@ contract EmailAccountRecoveryZKSyncTest_completeRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; vm.mockCall( address(recoveryControllerZKSync.emailAuthImplementationAddr()), @@ -109,7 +114,10 @@ contract EmailAccountRecoveryZKSyncTest_completeRecovery is StructHelper { recoveryControllerZKSync.handleRecovery(emailAuthMsg, templateIdx); vm.stopPrank(); - assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), true); + assertEq( + recoveryControllerZKSync.isRecovering(address(simpleWallet)), + true + ); assertEq(simpleWallet.owner(), deployer); assertEq( recoveryControllerZKSync.newSignerCandidateOfAccount( @@ -118,7 +126,9 @@ contract EmailAccountRecoveryZKSyncTest_completeRecovery is StructHelper { newSigner ); assertEq( - recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + recoveryControllerZKSync.currentTimelockOfAccount( + address(simpleWallet) + ), block.timestamp + recoveryControllerZKSync.timelockPeriodOfAccount( address(simpleWallet) @@ -131,9 +141,14 @@ contract EmailAccountRecoveryZKSyncTest_completeRecovery is StructHelper { handleRecovery(); - assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), true); assertEq( - recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + recoveryControllerZKSync.isRecovering(address(simpleWallet)), + true + ); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount( + address(simpleWallet) + ), block.timestamp + recoveryControllerZKSync.timelockPeriodOfAccount( address(simpleWallet) @@ -148,16 +163,21 @@ contract EmailAccountRecoveryZKSyncTest_completeRecovery is StructHelper { ); vm.startPrank(someRelayer); - vm.warp(4 days); + vm.warp(block.timestamp + 4 days); recoveryControllerZKSync.completeRecovery( address(simpleWallet), new bytes(0) ); vm.stopPrank(); - assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), false); assertEq( - recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + recoveryControllerZKSync.isRecovering(address(simpleWallet)), + false + ); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount( + address(simpleWallet) + ), 0 ); assertEq(simpleWallet.owner(), newSigner); @@ -174,9 +194,14 @@ contract EmailAccountRecoveryZKSyncTest_completeRecovery is StructHelper { handleAcceptance(); - assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), false); assertEq( - recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + recoveryControllerZKSync.isRecovering(address(simpleWallet)), + false + ); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount( + address(simpleWallet) + ), 0 ); assertEq(simpleWallet.owner(), deployer); @@ -188,7 +213,7 @@ contract EmailAccountRecoveryZKSyncTest_completeRecovery is StructHelper { ); vm.startPrank(someRelayer); - vm.warp(4 days); + vm.warp(block.timestamp + 4 days); vm.expectRevert(bytes("recovery not in progress")); bytes memory recoveryCalldata; recoveryControllerZKSync.completeRecovery( @@ -204,9 +229,14 @@ contract EmailAccountRecoveryZKSyncTest_completeRecovery is StructHelper { handleRecovery(); - assertEq(recoveryControllerZKSync.isRecovering(address(simpleWallet)), true); assertEq( - recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)), + recoveryControllerZKSync.isRecovering(address(simpleWallet)), + true + ); + assertEq( + recoveryControllerZKSync.currentTimelockOfAccount( + address(simpleWallet) + ), block.timestamp + recoveryControllerZKSync.timelockPeriodOfAccount( address(simpleWallet) diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_handleAcceptance.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_handleAcceptance.t.sol index 9db78895..fa88af64 100644 --- a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_handleAcceptance.t.sol +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_handleAcceptance.t.sol @@ -54,9 +54,9 @@ contract EmailAccountRecoveryZKSyncTest_handleAcceptance is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; vm.mockCall( address(recoveryControllerZKSync.emailAuthImplementationAddr()), @@ -97,9 +97,9 @@ contract EmailAccountRecoveryZKSyncTest_handleAcceptance is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; emailAuthMsg.proof.accountSalt = 0x0; vm.mockCall( @@ -131,9 +131,9 @@ contract EmailAccountRecoveryZKSyncTest_handleAcceptance is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; vm.mockCall( address(recoveryControllerZKSync.emailAuthImplementationAddr()), @@ -147,7 +147,7 @@ contract EmailAccountRecoveryZKSyncTest_handleAcceptance is StructHelper { vm.stopPrank(); } - function testExpectRevertHandleAcceptanceInvalidSubjectParams() public { + function testExpectRevertHandleAcceptanceInvalidcommandParams() public { skipIfNotZkSync(); requestGuardian(); @@ -164,10 +164,10 @@ contract EmailAccountRecoveryZKSyncTest_handleAcceptance is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForAcceptance = new bytes[](2); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); - subjectParamsForAcceptance[1] = abi.encode(address(simpleWallet)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](2); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + commandParamsForAcceptance[1] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; vm.mockCall( address(recoveryControllerZKSync.emailAuthImplementationAddr()), @@ -176,7 +176,7 @@ contract EmailAccountRecoveryZKSyncTest_handleAcceptance is StructHelper { ); vm.startPrank(someRelayer); - vm.expectRevert(bytes("invalid subject params")); + vm.expectRevert(bytes("invalid command params")); recoveryControllerZKSync.handleAcceptance(emailAuthMsg, templateIdx); vm.stopPrank(); } @@ -200,9 +200,9 @@ contract EmailAccountRecoveryZKSyncTest_handleAcceptance is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(0x0)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(0x0)); + emailAuthMsg.commandParams = commandParamsForAcceptance; vm.mockCall( address(recoveryControllerZKSync.emailAuthImplementationAddr()), diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_handleRecovery.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_handleRecovery.t.sol index 3a55ec9c..288b234f 100644 --- a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_handleRecovery.t.sol +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_handleRecovery.t.sol @@ -52,9 +52,9 @@ contract EmailAccountRecoveryZKSyncTest_handleRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; vm.mockCall( address(recoveryControllerZKSync.emailAuthImplementationAddr()), @@ -98,10 +98,10 @@ contract EmailAccountRecoveryZKSyncTest_handleRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; vm.mockCall( address(recoveryControllerZKSync.emailAuthImplementationAddr()), @@ -155,10 +155,10 @@ contract EmailAccountRecoveryZKSyncTest_handleRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; emailAuthMsg.proof.accountSalt = 0x0; vm.mockCall( @@ -194,10 +194,10 @@ contract EmailAccountRecoveryZKSyncTest_handleRecovery is StructHelper { uint templateIdx = 0; EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; vm.mockCall( address(recoveryControllerZKSync.emailAuthImplementationAddr()), @@ -241,10 +241,10 @@ contract EmailAccountRecoveryZKSyncTest_handleRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; emailAuthMsg.proof.accountSalt = 0x0; // vm.mockCall( @@ -296,10 +296,10 @@ contract EmailAccountRecoveryZKSyncTest_handleRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; vm.mockCall( address(recoveryControllerZKSync.emailAuthImplementationAddr()), @@ -313,7 +313,7 @@ contract EmailAccountRecoveryZKSyncTest_handleRecovery is StructHelper { vm.stopPrank(); } - function testExpectRevertHandleRecoveryInvalidSubjectParams() public { + function testExpectRevertHandleRecoveryInvalidcommandParams() public { skipIfNotZkSync(); handleAcceptance(); @@ -337,11 +337,11 @@ contract EmailAccountRecoveryZKSyncTest_handleRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](3); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - subjectParamsForRecovery[1] = abi.encode(address(0x0)); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](3); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + commandParamsForRecovery[1] = abi.encode(address(0x0)); + emailAuthMsg.commandParams = commandParamsForRecovery; vm.mockCall( address(recoveryControllerZKSync.emailAuthImplementationAddr()), @@ -350,7 +350,7 @@ contract EmailAccountRecoveryZKSyncTest_handleRecovery is StructHelper { ); vm.startPrank(someRelayer); - vm.expectRevert(bytes("invalid subject params")); + vm.expectRevert(bytes("invalid command params")); recoveryControllerZKSync.handleRecovery(emailAuthMsg, templateIdx); vm.stopPrank(); } @@ -373,10 +373,10 @@ contract EmailAccountRecoveryZKSyncTest_handleRecovery is StructHelper { // EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); // uint templateId = recoveryControllerZKSync.computeRecoveryTemplateId(templateIdx); // emailAuthMsg.templateId = templateId; - // bytes[] memory subjectParamsForRecovery = new bytes[](2); - // subjectParamsForRecovery[0] = abi.encode(address(0x0)); - // subjectParamsForRecovery[1] = abi.encode(newSigner); - // emailAuthMsg.subjectParams = subjectParamsForRecovery; + // bytes[] memory commandParamsForRecovery = new bytes[](2); + // commandParamsForRecovery[0] = abi.encode(address(0x0)); + // commandParamsForRecovery[1] = abi.encode(newSigner); + // emailAuthMsg.commandParams = commandParamsForRecovery; // vm.mockCall( // address(recoveryControllerZKSync.emailAuthImplementationAddr()), @@ -414,10 +414,10 @@ contract EmailAccountRecoveryZKSyncTest_handleRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(address(0x0)); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(address(0x0)); + emailAuthMsg.commandParams = commandParamsForRecovery; vm.mockCall( address(recoveryControllerZKSync.emailAuthImplementationAddr()), diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_rejectRecovery.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_rejectRecovery.t.sol index 8293060b..e17c900e 100644 --- a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_rejectRecovery.t.sol +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_rejectRecovery.t.sol @@ -49,12 +49,12 @@ contract EmailAccountRecoveryZKSyncTest_rejectRecovery is StructHelper { uint templateIdx = 0; EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); - emailAuthMsg.subjectParams = subjectParamsForAcceptance; + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + emailAuthMsg.commandParams = commandParamsForAcceptance; address recoveredAccount = recoveryControllerZKSync - .extractRecoveredAccountFromAcceptanceSubject( - emailAuthMsg.subjectParams, + .extractRecoveredAccountFromAcceptanceCommand( + emailAuthMsg.commandParams, templateIdx ); address computedGuardian = recoveryControllerZKSync.computeEmailAuthAddress( @@ -107,10 +107,10 @@ contract EmailAccountRecoveryZKSyncTest_rejectRecovery is StructHelper { templateIdx ); emailAuthMsg.templateId = templateId; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(simpleWallet); - subjectParamsForRecovery[1] = abi.encode(newSigner); - emailAuthMsg.subjectParams = subjectParamsForRecovery; + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(simpleWallet); + commandParamsForRecovery[1] = abi.encode(newSigner); + emailAuthMsg.commandParams = commandParamsForRecovery; vm.mockCall( address(recoveryControllerZKSync.emailAuthImplementationAddr()), diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_requestGuardian.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_requestGuardian.t.sol index 03418653..1dbe837b 100644 --- a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_requestGuardian.t.sol +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_requestGuardian.t.sol @@ -35,24 +35,6 @@ contract EmailAccountRecoveryZKSyncTest_requestGuardian is StructHelper { ); } - // function testRequestGuardianNotOwner() public { - // setUp(); - - // require( - // recoveryControllerZKSync.guardians(guardian) == - // recoveryControllerZKSync.GuardianStatus.NONE - // ); - - // vm.startPrank(receiver); - // recoveryControllerZKSync.requestGuardian(guardian); - // vm.stopPrank(); - - // require( - // recoveryControllerZKSync.guardians(guardian) == - // recoveryControllerZKSync.GuardianStatus.NONE - // ); - // } - function testExpectRevertRequestGuardianInvalidGuardian() public { skipIfNotZkSync(); diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_transfer.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_transfer.t.sol index b784847d..5b9440b1 100644 --- a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_transfer.t.sol +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_transfer.t.sol @@ -21,9 +21,11 @@ contract EmailAccountRecoveryZKSyncTest_transfer is StructHelper { setUp(); + vm.deal(address(simpleWallet), 1 ether); assertEq(address(simpleWallet).balance, 1 ether); - assertEq(receiver.balance, 0 ether); + vm.deal(receiver, 0 ether); + assertEq(receiver.balance, 0 ether); vm.startPrank(deployer); simpleWallet.transfer(receiver, 1 ether); vm.stopPrank(); @@ -37,7 +39,10 @@ contract EmailAccountRecoveryZKSyncTest_transfer is StructHelper { setUp(); + vm.deal(address(simpleWallet), 1 ether); assertEq(address(simpleWallet).balance, 1 ether); + + vm.deal(receiver, 0 ether); assertEq(receiver.balance, 0 ether); vm.startPrank(receiver); @@ -55,12 +60,13 @@ contract EmailAccountRecoveryZKSyncTest_transfer is StructHelper { skipIfNotZkSync(); setUp(); - + vm.deal(address(simpleWallet), 1 ether); assertEq(address(simpleWallet).balance, 1 ether); + + vm.deal(receiver, 0 ether); assertEq(receiver.balance, 0 ether); vm.startPrank(deployer); - assertEq(receiver.balance, 0 ether); vm.expectRevert(bytes("insufficient balance")); simpleWallet.transfer(receiver, 2 ether); vm.stopPrank(); diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_withdraw.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_withdraw.t.sol index 07d347d6..18decdc2 100644 --- a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_withdraw.t.sol +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZKSync_withdraw.t.sol @@ -21,8 +21,10 @@ contract EmailAccountRecoveryZKSyncTest_withdraw is StructHelper { setUp(); + vm.deal(address(simpleWallet), 1 ether); assertEq(address(simpleWallet).balance, 1 ether); - assertEq(deployer.balance, 0 ether); + + vm.deal(deployer, 0 ether); vm.startPrank(deployer); simpleWallet.withdraw(1 ether); @@ -38,7 +40,6 @@ contract EmailAccountRecoveryZKSyncTest_withdraw is StructHelper { setUp(); assertEq(address(simpleWallet).balance, 1 ether); - assertEq(deployer.balance, 0 ether); vm.startPrank(receiver); vm.expectRevert( @@ -57,7 +58,6 @@ contract EmailAccountRecoveryZKSyncTest_withdraw is StructHelper { setUp(); assertEq(address(simpleWallet).balance, 1 ether); - assertEq(deployer.balance, 0 ether); vm.startPrank(deployer); vm.expectRevert(bytes("insufficient balance")); diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_acceptanceSubjectTemplates.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_acceptanceCommandTemplates.t.sol similarity index 78% rename from packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_acceptanceSubjectTemplates.t.sol rename to packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_acceptanceCommandTemplates.t.sol index 9290a69c..81d9a67c 100644 --- a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_acceptanceSubjectTemplates.t.sol +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_acceptanceCommandTemplates.t.sol @@ -9,18 +9,20 @@ import {StructHelper} from "../helpers/StructHelper.sol"; import {SimpleWallet} from "../helpers/SimpleWallet.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -contract EmailAccountRecoveryZKSyncTest_acceptanceSubjectTemplates is StructHelper { +contract EmailAccountRecoveryZKSyncTest_acceptanceCommandTemplates is + StructHelper +{ constructor() {} function setUp() public override { super.setUp(); } - function testAcceptanceSubjectTemplates() public { + function testAcceptanceCommandTemplates() public { skipIfNotZkSync(); setUp(); - string[][] memory res = recoveryController.acceptanceSubjectTemplates(); + string[][] memory res = recoveryController.acceptanceCommandTemplates(); assertEq(res[0][0], "Accept"); assertEq(res[0][1], "guardian"); assertEq(res[0][2], "request"); diff --git a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_recoverySubjectTemplates.t.sol b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_recoveryCommandTemplates.t.sol similarity index 79% rename from packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_recoverySubjectTemplates.t.sol rename to packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_recoveryCommandTemplates.t.sol index 051c655b..62271e43 100644 --- a/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_recoverySubjectTemplates.t.sol +++ b/packages/contracts/test/EmailAccountRecoveryZkSync/EmailAccountRecoveryZkSync_recoveryCommandTemplates.t.sol @@ -9,18 +9,20 @@ import {StructHelper} from "../helpers/StructHelper.sol"; import {SimpleWallet} from "../helpers/SimpleWallet.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -contract EmailAccountRecoveryZKSyncTest_recoverySubjectTemplates is StructHelper { +contract EmailAccountRecoveryZKSyncTest_recoveryCommandTemplates is + StructHelper +{ constructor() {} function setUp() public override { super.setUp(); } - function testRecoverySubjectTemplates() public { + function testRecoveryCommandTemplates() public { skipIfNotZkSync(); - - setUp(); - string[][] memory res = recoveryController.recoverySubjectTemplates(); + + setUp(); + string[][] memory res = recoveryController.recoveryCommandTemplates(); assertEq(res[0][0], "Set"); assertEq(res[0][1], "the"); assertEq(res[0][2], "new"); diff --git a/packages/contracts/test/EmailAuth.t.sol b/packages/contracts/test/EmailAuth.t.sol index 7ba173aa..0b9a6990 100644 --- a/packages/contracts/test/EmailAuth.t.sol +++ b/packages/contracts/test/EmailAuth.t.sol @@ -8,7 +8,6 @@ import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "../src/EmailAuth.sol"; import "../src/utils/Verifier.sol"; import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; -import "../src/utils/ForwardDKIMRegistry.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import "./helpers/StructHelper.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; @@ -59,31 +58,6 @@ contract EmailAuthTest is StructHelper { assertEq(emailAuth.dkimRegistryAddr(), address(newDKIM)); } - function testUpdateDKIMRegistryToForward() public { - assertEq(emailAuth.dkimRegistryAddr(), address(dkim)); - - vm.startPrank(deployer); - ECDSAOwnedDKIMRegistry dummyDKIM = new ECDSAOwnedDKIMRegistry(); - ForwardDKIMRegistry newDKIM; - { - ForwardDKIMRegistry dkimImpl = new ForwardDKIMRegistry(); - ERC1967Proxy dkimProxy = new ERC1967Proxy( - address(dkimImpl), - abi.encodeCall( - dkimImpl.initialize, - (msg.sender, address(dummyDKIM)) - ) - ); - newDKIM = ForwardDKIMRegistry(address(dkimProxy)); - } - vm.expectEmit(true, false, false, false); - emit EmailAuth.DKIMRegistryUpdated(address(newDKIM)); - emailAuth.updateDKIMRegistry(address(newDKIM)); - vm.stopPrank(); - - assertEq(emailAuth.dkimRegistryAddr(), address(newDKIM)); - } - function testExpectRevertUpdateDKIMRegistryInvalidDkimRegistryAddress() public { @@ -117,140 +91,140 @@ contract EmailAuthTest is StructHelper { vm.stopPrank(); } - function testGetSubjectTemplate() public { + function testGetCommandTemplate() public { vm.startPrank(deployer); - emailAuth.insertSubjectTemplate(templateId, subjectTemplate); + emailAuth.insertCommandTemplate(templateId, commandTemplate); vm.stopPrank(); - string[] memory result = emailAuth.getSubjectTemplate(templateId); - assertEq(result, subjectTemplate); + string[] memory result = emailAuth.getCommandTemplate(templateId); + assertEq(result, commandTemplate); } - function testExpectRevertGetSubjectTemplateTemplateIdNotExists() public { + function testExpectRevertGetCommandTemplateTemplateIdNotExists() public { vm.expectRevert(bytes("template id not exists")); - emailAuth.getSubjectTemplate(templateId); + emailAuth.getCommandTemplate(templateId); } - function testInsertSubjectTemplate() public { + function testInsertCommandTemplate() public { vm.startPrank(deployer); vm.expectEmit(true, false, false, false); - emit EmailAuth.SubjectTemplateInserted(templateId); - _testInsertSubjectTemplate(); + emit EmailAuth.CommandTemplateInserted(templateId); + _testInsertCommandTemplate(); vm.stopPrank(); } - function _testInsertSubjectTemplate() private { - emailAuth.insertSubjectTemplate(templateId, subjectTemplate); - string[] memory result = emailAuth.getSubjectTemplate(templateId); - assertEq(result, subjectTemplate); + function _testInsertCommandTemplate() private { + emailAuth.insertCommandTemplate(templateId, commandTemplate); + string[] memory result = emailAuth.getCommandTemplate(templateId); + assertEq(result, commandTemplate); } - function testExpectRevertInsertSubjectTemplateSubjectTemplateIsEmpty() + function testExpectRevertInsertCommandTemplateCommandTemplateIsEmpty() public { vm.startPrank(deployer); - string[] memory emptySubjectTemplate = new string[](0); - vm.expectRevert(bytes("subject template is empty")); - emailAuth.insertSubjectTemplate(templateId, emptySubjectTemplate); + string[] memory emptyCommandTemplate = new string[](0); + vm.expectRevert(bytes("command template is empty")); + emailAuth.insertCommandTemplate(templateId, emptyCommandTemplate); vm.stopPrank(); } - function testExpectRevertInsertSubjectTemplateTemplateIdAlreadyExists() + function testExpectRevertInsertCommandTemplateTemplateIdAlreadyExists() public { vm.startPrank(deployer); - emailAuth.insertSubjectTemplate(templateId, subjectTemplate); - string[] memory result = emailAuth.getSubjectTemplate(templateId); - assertEq(result, subjectTemplate); + emailAuth.insertCommandTemplate(templateId, commandTemplate); + string[] memory result = emailAuth.getCommandTemplate(templateId); + assertEq(result, commandTemplate); vm.expectRevert(bytes("template id already exists")); - emailAuth.insertSubjectTemplate(templateId, subjectTemplate); + emailAuth.insertCommandTemplate(templateId, commandTemplate); vm.stopPrank(); } - function testUpdateSubjectTemplate() public { + function testUpdateCommandTemplate() public { vm.expectRevert(bytes("template id not exists")); - string[] memory result = emailAuth.getSubjectTemplate(templateId); + string[] memory result = emailAuth.getCommandTemplate(templateId); vm.startPrank(deployer); - _testInsertSubjectTemplate(); + _testInsertCommandTemplate(); vm.stopPrank(); - result = emailAuth.getSubjectTemplate(templateId); - assertEq(result, subjectTemplate); + result = emailAuth.getCommandTemplate(templateId); + assertEq(result, commandTemplate); vm.startPrank(deployer); vm.expectEmit(true, false, false, false); - emit EmailAuth.SubjectTemplateUpdated(templateId); - emailAuth.updateSubjectTemplate(templateId, newSubjectTemplate); + emit EmailAuth.CommandTemplateUpdated(templateId); + emailAuth.updateCommandTemplate(templateId, newCommandTemplate); vm.stopPrank(); - result = emailAuth.getSubjectTemplate(templateId); - assertEq(result, newSubjectTemplate); + result = emailAuth.getCommandTemplate(templateId); + assertEq(result, newCommandTemplate); } - function testExpectRevertUpdateSubjectTemplateCallerIsNotTheModule() + function testExpectRevertUpdateCommandTemplateCallerIsNotTheModule() public { vm.expectRevert("only controller"); - emailAuth.updateSubjectTemplate(templateId, subjectTemplate); + emailAuth.updateCommandTemplate(templateId, commandTemplate); } - function testExpectRevertUpdateSubjectTemplateSubjectTemplateIsEmpty() + function testExpectRevertUpdateCommandTemplateCommandTemplateIsEmpty() public { vm.startPrank(deployer); - string[] memory emptySubjectTemplate = new string[](0); - vm.expectRevert(bytes("subject template is empty")); - emailAuth.updateSubjectTemplate(templateId, emptySubjectTemplate); + string[] memory emptyCommandTemplate = new string[](0); + vm.expectRevert(bytes("command template is empty")); + emailAuth.updateCommandTemplate(templateId, emptyCommandTemplate); vm.stopPrank(); } - function testExpectRevertUpdateSubjectTemplateTemplateIdNotExists() public { + function testExpectRevertUpdateCommandTemplateTemplateIdNotExists() public { vm.startPrank(deployer); vm.expectRevert(bytes("template id not exists")); - emailAuth.updateSubjectTemplate(templateId, subjectTemplate); + emailAuth.updateCommandTemplate(templateId, commandTemplate); vm.stopPrank(); } - function testDeleteSubjectTemplate() public { + function testDeleteCommandTemplate() public { vm.startPrank(deployer); - _testInsertSubjectTemplate(); + _testInsertCommandTemplate(); vm.stopPrank(); - string[] memory result = emailAuth.getSubjectTemplate(templateId); - assertEq(result, subjectTemplate); + string[] memory result = emailAuth.getCommandTemplate(templateId); + assertEq(result, commandTemplate); vm.startPrank(deployer); vm.expectEmit(true, false, false, false); - emit EmailAuth.SubjectTemplateDeleted(templateId); - emailAuth.deleteSubjectTemplate(templateId); + emit EmailAuth.CommandTemplateDeleted(templateId); + emailAuth.deleteCommandTemplate(templateId); vm.stopPrank(); vm.expectRevert(bytes("template id not exists")); - emailAuth.getSubjectTemplate(templateId); + emailAuth.getCommandTemplate(templateId); } - function testExpectRevertDeleteSubjectTemplateCallerIsNotTheModule() + function testExpectRevertDeleteCommandTemplateCallerIsNotTheModule() public { vm.expectRevert("only controller"); - emailAuth.deleteSubjectTemplate(templateId); + emailAuth.deleteCommandTemplate(templateId); } - function testExpectRevertDeleteSubjectTemplateTemplateIdNotExists() public { + function testExpectRevertDeleteCommandTemplateTemplateIdNotExists() public { vm.startPrank(deployer); vm.expectRevert(bytes("template id not exists")); - emailAuth.deleteSubjectTemplate(templateId); + emailAuth.deleteCommandTemplate(templateId); vm.stopPrank(); } function testAuthEmail() public { vm.startPrank(deployer); - _testInsertSubjectTemplate(); + _testInsertCommandTemplate(); EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); vm.stopPrank(); @@ -310,7 +284,7 @@ contract EmailAuthTest is StructHelper { function testExpectRevertAuthEmailInvalidDkimPublicKeyHash() public { vm.startPrank(deployer); - _testInsertSubjectTemplate(); + _testInsertCommandTemplate(); EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); vm.stopPrank(); @@ -329,7 +303,7 @@ contract EmailAuthTest is StructHelper { function testExpectRevertAuthEmailEmailNullifierAlreadyUsed() public { vm.startPrank(deployer); - _testInsertSubjectTemplate(); + _testInsertCommandTemplate(); EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); vm.stopPrank(); @@ -348,7 +322,7 @@ contract EmailAuthTest is StructHelper { function testExpectRevertAuthEmailInvalidAccountSalt() public { vm.startPrank(deployer); - _testInsertSubjectTemplate(); + _testInsertCommandTemplate(); EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); vm.stopPrank(); @@ -367,7 +341,7 @@ contract EmailAuthTest is StructHelper { function testExpectRevertAuthEmailInvalidTimestamp() public { vm.startPrank(deployer); - _testInsertSubjectTemplate(); + _testInsertCommandTemplate(); EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); emailAuth.authEmail(emailAuthMsg); vm.stopPrank(); @@ -387,9 +361,9 @@ contract EmailAuthTest is StructHelper { vm.stopPrank(); } - function testExpectRevertAuthEmailInvalidSubject() public { + function testExpectRevertAuthEmailInvalidCommand() public { vm.startPrank(deployer); - _testInsertSubjectTemplate(); + _testInsertCommandTemplate(); EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); vm.stopPrank(); @@ -400,15 +374,15 @@ contract EmailAuthTest is StructHelper { assertEq(emailAuth.lastTimestamp(), 0); vm.startPrank(deployer); - emailAuthMsg.subjectParams[0] = abi.encode(2 ether); - vm.expectRevert(bytes("invalid subject")); + emailAuthMsg.commandParams[0] = abi.encode(2 ether); + vm.expectRevert(bytes("invalid command")); emailAuth.authEmail(emailAuthMsg); vm.stopPrank(); } function testExpectRevertAuthEmailInvalidEmailProof() public { vm.startPrank(deployer); - _testInsertSubjectTemplate(); + _testInsertCommandTemplate(); EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); vm.stopPrank(); @@ -432,9 +406,9 @@ contract EmailAuthTest is StructHelper { vm.stopPrank(); } - function testExpectRevertAuthEmailInvalidMaskedSubjectLength() public { + function testExpectRevertAuthEmailInvalidMaskedCommandLength() public { vm.startPrank(deployer); - _testInsertSubjectTemplate(); + _testInsertCommandTemplate(); EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); vm.stopPrank(); @@ -444,18 +418,63 @@ contract EmailAuthTest is StructHelper { ); assertEq(emailAuth.lastTimestamp(), 0); - // Set masked subject length to 606, which should be 605 or less defined in the verifier. - emailAuthMsg.proof.maskedSubject = string(new bytes(606)); + // Set masked command length to 606, which should be 605 or less defined in the verifier. + emailAuthMsg.proof.maskedCommand = string(new bytes(606)); vm.startPrank(deployer); - vm.expectRevert(bytes("invalid masked subject length")); + vm.expectRevert(bytes("invalid masked command length")); emailAuth.authEmail(emailAuthMsg); vm.stopPrank(); } - function testExpectRevertAuthEmailInvalidSizeOfTheSkippedSubjectPrefix() public { + function testAuthEmailWithMultiBytePrefix() public { vm.startPrank(deployer); - _testInsertSubjectTemplate(); + _testInsertCommandTemplate(); + vm.stopPrank(); + + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + emailAuthMsg.proof.maskedCommand = string.concat( + unicode"Japanese Prefix ねこ ", + emailAuthMsg.proof.maskedCommand + ); + // The japanese word "ねこ" has six bytes. + // "ねこ" means cats. + emailAuthMsg.skippedCommandPrefix = 17 + 6; + + assertEq( + emailAuth.usedNullifiers(emailAuthMsg.proof.emailNullifier), + false + ); + assertEq(emailAuth.lastTimestamp(), 0); + + vm.startPrank(deployer); + vm.expectEmit(true, true, true, true); + emit EmailAuth.EmailAuthed( + emailAuthMsg.proof.emailNullifier, + emailAuthMsg.proof.accountSalt, + emailAuthMsg.proof.isCodeExist, + emailAuthMsg.templateId + ); + vm.mockCall( + address(verifier), + abi.encodeCall(Verifier.verifyEmailProof, (emailAuthMsg.proof)), + abi.encode(true) + ); + emailAuth.authEmail(emailAuthMsg); + vm.stopPrank(); + + assertEq( + emailAuth.usedNullifiers(emailAuthMsg.proof.emailNullifier), + true + ); + assertEq(emailAuth.lastTimestamp(), emailAuthMsg.proof.timestamp); + } + + function testExpectRevertAuthEmailInvalidSizeOfTheSkippedCommandPrefix() + public + { + vm.startPrank(deployer); + _testInsertCommandTemplate(); EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); vm.stopPrank(); @@ -465,11 +484,11 @@ contract EmailAuthTest is StructHelper { ); assertEq(emailAuth.lastTimestamp(), 0); - // Set skipped subject prefix length to 605, it should be less than 605. - emailAuthMsg.skipedSubjectPrefix = 605; + // Set skipped command prefix length to 605, it should be less than 605. + emailAuthMsg.skippedCommandPrefix = 605; vm.startPrank(deployer); - vm.expectRevert(bytes("invalid size of the skipped subject prefix")); + vm.expectRevert(bytes("invalid size of the skipped command prefix")); emailAuth.authEmail(emailAuthMsg); vm.stopPrank(); } @@ -490,4 +509,36 @@ contract EmailAuthTest is StructHelper { vm.expectRevert("only controller"); emailAuth.setTimestampCheckEnabled(false); } + + function testUpgradeEmailAuth() public { + vm.startPrank(deployer); + + // Deploy new implementation + EmailAuth newImplementation = new EmailAuth(); + + // Execute upgrade using proxy + // Upgrade implementation through proxy contract + ERC1967Proxy proxy = new ERC1967Proxy( + address(emailAuth), + abi.encodeCall( + emailAuth.initialize, + (deployer, accountSalt, deployer) + ) + ); + EmailAuth emailAuthProxy = EmailAuth(payable(proxy)); + bytes32 beforeAccountSalt = emailAuthProxy.accountSalt(); + + // Upgrade to new implementation through proxy + emailAuthProxy.upgradeToAndCall( + address(newImplementation), + new bytes(0) + ); + + bytes32 afterAccountSalt = emailAuthProxy.accountSalt(); + + // Verify the upgrade + assertEq(beforeAccountSalt, afterAccountSalt); + + vm.stopPrank(); + } } diff --git a/packages/contracts/test/EmailAuthWithUserOverrideableDkim.t.sol b/packages/contracts/test/EmailAuthWithUserOverrideableDkim.t.sol index 3f55ef7d..d50ac85a 100644 --- a/packages/contracts/test/EmailAuthWithUserOverrideableDkim.t.sol +++ b/packages/contracts/test/EmailAuthWithUserOverrideableDkim.t.sol @@ -8,56 +8,105 @@ import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "../src/EmailAuth.sol"; import "../src/utils/Verifier.sol"; import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; -import "../src/utils/ForwardDKIMRegistry.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import "./helpers/StructHelper.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; contract EmailAuthWithUserOverrideableDkimTest is StructHelper { - ForwardDKIMRegistry forwardDkim; + UserOverrideableDKIMRegistry overrideableDkim; + address emailAuthOwner = vm.addr(77); function setUp() public override { super.setUp(); - vm.startPrank(deployer); - ForwardDKIMRegistry forwardDkimImpl = new ForwardDKIMRegistry(); - ERC1967Proxy forwardDKIMRegistryProxy = new ERC1967Proxy( - address(forwardDkimImpl), + ERC1967Proxy overrideableDkimProxy = new ERC1967Proxy( + address(overrideableDkimImpl), abi.encodeCall( - forwardDkimImpl.initialize, - (deployer, address(overrideableDkim)) + overrideableDkimImpl.initialize, + (deployer, deployer, setTimestampDelay) ) ); - forwardDkim = ForwardDKIMRegistry(address(forwardDKIMRegistryProxy)); + overrideableDkim = UserOverrideableDKIMRegistry( + address(overrideableDkimProxy) + ); - emailAuth.initialize(deployer, accountSalt, deployer); + { + ERC1967Proxy emailAuthProxy = new ERC1967Proxy( + address(emailAuth), + abi.encodeCall( + emailAuth.initialize, + (emailAuthOwner, accountSalt, deployer) + ) + ); + emailAuth = EmailAuth(address(emailAuthProxy)); + } + // emailAuth.initialize(emailAuthOwner, accountSalt, deployer); vm.expectEmit(true, false, false, false); emit EmailAuth.VerifierUpdated(address(verifier)); - emailAuth.updateVerifier(address(verifier)); + emailAuth.initVerifier(address(verifier)); vm.expectEmit(true, false, false, false); - emit EmailAuth.DKIMRegistryUpdated(address(forwardDkim)); - emailAuth.updateDKIMRegistry(address(forwardDkim)); + emit EmailAuth.DKIMRegistryUpdated(address(overrideableDkim)); + emailAuth.initDKIMRegistry(address(overrideableDkim)); vm.stopPrank(); } - function testDkimRegistryAddr() public view { - address dkimAddr = emailAuth.dkimRegistryAddr(); - assertEq(dkimAddr, address(forwardDkim)); + function _testInsertCommandTemplate() private { + emailAuth.insertCommandTemplate(templateId, commandTemplate); + string[] memory result = emailAuth.getCommandTemplate(templateId); + assertEq(result, commandTemplate); + } + + function testAuthEmailBeforeEnabled() public { + vm.startPrank(deployer); + _testInsertCommandTemplate(); + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + vm.stopPrank(); + assertEq( - address(forwardDkim.sourceDKIMRegistry()), - address(overrideableDkim) + emailAuth.usedNullifiers(emailAuthMsg.proof.emailNullifier), + false ); - } + assertEq(emailAuth.lastTimestamp(), 0); + + vm.startPrank(deployer); + overrideableDkim.setDKIMPublicKeyHash( + domainName, + publicKeyHash, + deployer, + new bytes(0) + ); + vm.stopPrank(); - function _testInsertSubjectTemplate() private { - emailAuth.insertSubjectTemplate(templateId, subjectTemplate); - string[] memory result = emailAuth.getSubjectTemplate(templateId); - assertEq(result, subjectTemplate); + vm.startPrank(emailAuthOwner); + overrideableDkim.setDKIMPublicKeyHash( + domainName, + publicKeyHash, + emailAuthOwner, + new bytes(0) + ); + vm.stopPrank(); + + vm.startPrank(deployer); + vm.expectEmit(true, true, true, true); + emit EmailAuth.EmailAuthed( + emailAuthMsg.proof.emailNullifier, + emailAuthMsg.proof.accountSalt, + emailAuthMsg.proof.isCodeExist, + emailAuthMsg.templateId + ); + emailAuth.authEmail(emailAuthMsg); + vm.stopPrank(); + + assertEq( + emailAuth.usedNullifiers(emailAuthMsg.proof.emailNullifier), + true + ); + assertEq(emailAuth.lastTimestamp(), emailAuthMsg.proof.timestamp); } - function testAuthEmail() public { + function testAuthEmailAfterEnabled() public { vm.startPrank(deployer); - _testInsertSubjectTemplate(); + _testInsertCommandTemplate(); EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); vm.stopPrank(); @@ -67,6 +116,17 @@ contract EmailAuthWithUserOverrideableDkimTest is StructHelper { ); assertEq(emailAuth.lastTimestamp(), 0); + vm.startPrank(deployer); + overrideableDkim.setDKIMPublicKeyHash( + domainName, + publicKeyHash, + deployer, + new bytes(0) + ); + vm.stopPrank(); + + vm.warp(block.timestamp + setTimestampDelay + 1); + vm.startPrank(deployer); vm.expectEmit(true, true, true, true); emit EmailAuth.EmailAuthed( @@ -84,4 +144,33 @@ contract EmailAuthWithUserOverrideableDkimTest is StructHelper { ); assertEq(emailAuth.lastTimestamp(), emailAuthMsg.proof.timestamp); } + + function testFailAuthEmailBeforeEnabledWithoutUserApprove() public { + vm.startPrank(deployer); + _testInsertCommandTemplate(); + EmailAuthMsg memory emailAuthMsg = buildEmailAuthMsg(); + vm.stopPrank(); + + assertEq( + emailAuth.usedNullifiers(emailAuthMsg.proof.emailNullifier), + false + ); + assertEq(emailAuth.lastTimestamp(), 0); + + vm.startPrank(deployer); + overrideableDkim.setDKIMPublicKeyHash( + domainName, + publicKeyHash, + deployer, + new bytes(0) + ); + emailAuth.authEmail(emailAuthMsg); + vm.stopPrank(); + + assertEq( + emailAuth.usedNullifiers(emailAuthMsg.proof.emailNullifier), + true + ); + assertEq(emailAuth.lastTimestamp(), emailAuthMsg.proof.timestamp); + } } diff --git a/packages/contracts/test/Integration.t.sol b/packages/contracts/test/Integration.t.sol index b17fc0cf..174804fe 100644 --- a/packages/contracts/test/Integration.t.sol +++ b/packages/contracts/test/Integration.t.sol @@ -9,11 +9,13 @@ import "@zk-email/contracts/DKIMRegistry.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "../src/EmailAuth.sol"; import "../src/utils/Verifier.sol"; -import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; +import "../src/utils/Groth16Verifier.sol"; import "./helpers/SimpleWallet.sol"; import "./helpers/RecoveryController.sol"; import "forge-std/console.sol"; import "../src/utils/ZKSyncCreate2Factory.sol"; +import {UserOverrideableDKIMRegistry} from "@zk-email/contracts/UserOverrideableDKIMRegistry.sol"; +import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; contract IntegrationTest is Test { using Strings for *; @@ -21,7 +23,7 @@ contract IntegrationTest is Test { EmailAuth emailAuth; Verifier verifier; - ECDSAOwnedDKIMRegistry dkim; + UserOverrideableDKIMRegistry dkim; RecoveryController recoveryController; SimpleWallet simpleWallet; @@ -36,49 +38,60 @@ contract IntegrationTest is Test { string domainName = "gmail.com"; bytes32 publicKeyHash = 0x0ea9c777dc7110e5a9e89b13f0cfc540e3845ba120b2b6dc24024d61488d4788; - uint256 startTimestamp = 1723443691; // September 11, 2024, 17:34:51 UTC + // uint256 startTimestamp = 1729512214; + uint256 recoveryTimelock = 5 days; + uint256 setTimeDelay = 3 days; function setUp() public { vm.createSelectFork("https://mainnet.base.org"); - vm.warp(startTimestamp); + // vm.warp(startTimestamp); vm.startPrank(deployer); address signer = deployer; // Create DKIM registry + UserOverrideableDKIMRegistry overrideableDkimImpl = new UserOverrideableDKIMRegistry(); { - ECDSAOwnedDKIMRegistry ecdsaDkimImpl = new ECDSAOwnedDKIMRegistry(); - ERC1967Proxy ecdsaDkimProxy = new ERC1967Proxy( - address(ecdsaDkimImpl), - abi.encodeCall(ecdsaDkimImpl.initialize, (msg.sender, signer)) + ERC1967Proxy overrideableDkimProxy = new ERC1967Proxy( + address(overrideableDkimImpl), + abi.encodeCall( + overrideableDkimImpl.initialize, + (msg.sender, signer, setTimeDelay) + ) ); - dkim = ECDSAOwnedDKIMRegistry(address(ecdsaDkimProxy)); + dkim = UserOverrideableDKIMRegistry(address(overrideableDkimProxy)); + } + { + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + dkim.setDKIMPublicKeyHash( + domainName, + publicKeyHash, + signer, + signature + ); + vm.warp(block.timestamp + setTimeDelay + 1); } - string memory signedMsg = dkim.computeSignedMsg( - dkim.SET_PREFIX(), - selector, - domainName, - publicKeyHash - ); - bytes32 digest = MessageHashUtils.toEthSignedMessageHash( - bytes(signedMsg) - ); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); - bytes memory signature = abi.encodePacked(r, s, v); - dkim.setDKIMPublicKeyHash( - selector, - domainName, - publicKeyHash, - signature - ); // Create Verifier { Verifier verifierImpl = new Verifier(); + Groth16Verifier groth16Verifier = new Groth16Verifier(); ERC1967Proxy verifierProxy = new ERC1967Proxy( address(verifierImpl), - abi.encodeCall(verifierImpl.initialize, (msg.sender)) + abi.encodeCall( + verifierImpl.initialize, + (msg.sender, address(groth16Verifier)) + ) ); verifier = Verifier(address(verifierProxy)); } @@ -125,7 +138,9 @@ contract IntegrationTest is Test { // "emailAuthImplementation", // simpleWallet.emailAuthImplementation() // ); - + vm.stopPrank(); + vm.startPrank(address(simpleWallet)); + recoveryController.configureTimelockPeriod(recoveryTimelock); vm.stopPrank(); } @@ -141,7 +156,7 @@ contract IntegrationTest is Test { console.log("SimpleWallet is at ", address(simpleWallet)); assertEq( address(simpleWallet), - 0xeb8E21A363Dce22ff6057dEEF7c074062037F571 + 0xa3A6f0FDd72Ae9936C44cE36151CB4DB3E9949d1 ); address simpleWalletOwner = simpleWallet.owner(); @@ -176,7 +191,7 @@ contract IntegrationTest is Test { emailProof.publicKeyHash = bytes32(vm.parseUint(pubSignals[9])); emailProof.timestamp = vm.parseUint(pubSignals[11]); emailProof - .maskedSubject = "Accept guardian request for 0xeb8E21A363Dce22ff6057dEEF7c074062037F571"; + .maskedCommand = "Accept guardian request for 0xa3A6f0FDd72Ae9936C44cE36151CB4DB3E9949d1"; emailProof.emailNullifier = bytes32(vm.parseUint(pubSignals[10])); emailProof.accountSalt = bytes32(vm.parseUint(pubSignals[32])); accountSalt = emailProof.accountSalt; @@ -210,14 +225,14 @@ contract IntegrationTest is Test { ); // Call handleAcceptance -> GuardianStatus.ACCEPTED - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); EmailAuthMsg memory emailAuthMsg = EmailAuthMsg({ templateId: recoveryController.computeAcceptanceTemplateId( templateIdx ), - subjectParams: subjectParamsForAcceptance, - skipedSubjectPrefix: 0, + commandParams: commandParamsForAcceptance, + skippedCommandPrefix: 0, proof: emailProof }); recoveryController.handleAcceptance(emailAuthMsg, templateIdx); @@ -254,11 +269,8 @@ contract IntegrationTest is Test { emailProof.domainName = "gmail.com"; emailProof.publicKeyHash = bytes32(vm.parseUint(pubSignals[9])); emailProof.timestamp = vm.parseUint(pubSignals[11]); - - // 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 is account 9 emailProof - .maskedSubject = "Set the new signer of 0xeb8E21A363Dce22ff6057dEEF7c074062037F571 to 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720"; - + .maskedCommand = "Set the new signer of 0xa3A6f0FDd72Ae9936C44cE36151CB4DB3E9949d1 to 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720"; emailProof.emailNullifier = bytes32(vm.parseUint(pubSignals[10])); emailProof.accountSalt = bytes32(vm.parseUint(pubSignals[32])); require( @@ -283,17 +295,17 @@ contract IntegrationTest is Test { console.log("is code exist: ", vm.parseUint(pubSignals[33])); // Call handleRecovery -> isRecovering = true; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(address(simpleWallet)); - subjectParamsForRecovery[1] = abi.encode( + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(address(simpleWallet)); + commandParamsForRecovery[1] = abi.encode( address(0xa0Ee7A142d267C1f36714E4a8F75612F20a79720) ); emailAuthMsg = EmailAuthMsg({ templateId: recoveryController.computeRecoveryTemplateId( templateIdx ), - subjectParams: subjectParamsForRecovery, - skipedSubjectPrefix: 0, + commandParams: commandParamsForRecovery, + skippedCommandPrefix: 0, proof: emailProof }); recoveryController.handleRecovery(emailAuthMsg, templateIdx); @@ -318,8 +330,7 @@ contract IntegrationTest is Test { ); // Call completeRecovery - // Warp at 3 days + 10 seconds later - vm.warp(startTimestamp + (3 * 24 * 60 * 60) + 10); + vm.warp(block.timestamp + recoveryTimelock + 1); recoveryController.completeRecovery( address(simpleWallet), new bytes(0) diff --git a/packages/contracts/test/IntegrationZKSync.t.sol b/packages/contracts/test/IntegrationZKSync.t.sol index f30cc72b..778463c1 100644 --- a/packages/contracts/test/IntegrationZKSync.t.sol +++ b/packages/contracts/test/IntegrationZKSync.t.sol @@ -9,11 +9,13 @@ import "@zk-email/contracts/DKIMRegistry.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "../src/EmailAuth.sol"; import "../src/utils/Verifier.sol"; -import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; +import "../src/utils/Groth16Verifier.sol"; import "./helpers/SimpleWallet.sol"; import "./helpers/RecoveryControllerZKSync.sol"; import "forge-std/console.sol"; import "../src/utils/ZKSyncCreate2Factory.sol"; +import {UserOverrideableDKIMRegistry} from "@zk-email/contracts/UserOverrideableDKIMRegistry.sol"; +import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; contract IntegrationZKSyncTest is Test { using Strings for *; @@ -21,7 +23,7 @@ contract IntegrationZKSyncTest is Test { EmailAuth emailAuth; Verifier verifier; - ECDSAOwnedDKIMRegistry dkim; + UserOverrideableDKIMRegistry dkim; RecoveryControllerZKSync recoveryControllerZKSync; SimpleWallet simpleWallet; @@ -36,49 +38,61 @@ contract IntegrationZKSyncTest is Test { string domainName = "gmail.com"; bytes32 publicKeyHash = 0x0ea9c777dc7110e5a9e89b13f0cfc540e3845ba120b2b6dc24024d61488d4788; - uint256 startTimestamp = 1723443691; // September 11, 2024, 17:34:51 UTC + // uint256 startTimestamp = 1723443691; // September 11, 2024, 17:34:51 UTC + uint256 recoveryTimelock = 5 days; + uint256 setTimeDelay = 3 days; + + bytes32 public proxyBytecodeHash = + vm.envOr("PROXY_BYTECODE_HASH", bytes32(0)); function setUp() public { vm.createSelectFork("http://127.0.0.1:8011"); - - vm.warp(startTimestamp); vm.startPrank(deployer); address signer = deployer; // Create DKIM registry + UserOverrideableDKIMRegistry overrideableDkimImpl = new UserOverrideableDKIMRegistry(); { - ECDSAOwnedDKIMRegistry ecdsaDkimImpl = new ECDSAOwnedDKIMRegistry(); - ERC1967Proxy ecdsaDkimProxy = new ERC1967Proxy( - address(ecdsaDkimImpl), - abi.encodeCall(ecdsaDkimImpl.initialize, (msg.sender, signer)) + ERC1967Proxy overrideableDkimProxy = new ERC1967Proxy( + address(overrideableDkimImpl), + abi.encodeCall( + overrideableDkimImpl.initialize, + (msg.sender, signer, setTimeDelay) + ) ); - dkim = ECDSAOwnedDKIMRegistry(address(ecdsaDkimProxy)); + dkim = UserOverrideableDKIMRegistry(address(overrideableDkimProxy)); + } + { + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + dkim.setDKIMPublicKeyHash( + domainName, + publicKeyHash, + signer, + signature + ); + vm.warp(block.timestamp + setTimeDelay + 1); } - string memory signedMsg = dkim.computeSignedMsg( - dkim.SET_PREFIX(), - selector, - domainName, - publicKeyHash - ); - bytes32 digest = MessageHashUtils.toEthSignedMessageHash( - bytes(signedMsg) - ); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); - bytes memory signature = abi.encodePacked(r, s, v); - dkim.setDKIMPublicKeyHash( - selector, - domainName, - publicKeyHash, - signature - ); // Create Verifier { Verifier verifierImpl = new Verifier(); + Groth16Verifier groth16Verifier = new Groth16Verifier(); ERC1967Proxy verifierProxy = new ERC1967Proxy( address(verifierImpl), - abi.encodeCall(verifierImpl.initialize, (msg.sender)) + abi.encodeCall( + verifierImpl.initialize, + (msg.sender, address(groth16Verifier)) + ) ); verifier = Verifier(address(verifierProxy)); } @@ -104,7 +118,8 @@ contract IntegrationZKSyncTest is Test { address(verifier), address(dkim), address(emailAuthImpl), - address(factoryImpl) + address(factoryImpl), + proxyBytecodeHash ) ) ); @@ -122,11 +137,9 @@ contract IntegrationZKSyncTest is Test { ) ); simpleWallet = SimpleWallet(payable(address(simpleWalletProxy))); - // console.log( - // "emailAuthImplementation", - // simpleWallet.emailAuthImplementation() - // ); - + vm.stopPrank(); + vm.startPrank(address(simpleWallet)); + recoveryControllerZKSync.configureTimelockPeriod(recoveryTimelock); vm.stopPrank(); } @@ -142,7 +155,7 @@ contract IntegrationZKSyncTest is Test { console.log("SimpleWallet is at ", address(simpleWallet)); assertEq( address(simpleWallet), - 0x7c5E4b26643682AF77A196781A851c9Fe769472d + 0xc9a403a0f75924677Dc0b011Da7eD8dD902063A6 ); address simpleWalletOwner = simpleWallet.owner(); @@ -177,7 +190,7 @@ contract IntegrationZKSyncTest is Test { emailProof.publicKeyHash = bytes32(vm.parseUint(pubSignals[9])); emailProof.timestamp = vm.parseUint(pubSignals[11]); emailProof - .maskedSubject = "Accept guardian request for 0x7c5E4b26643682AF77A196781A851c9Fe769472d"; + .maskedCommand = "Accept guardian request for 0xc9a403a0f75924677Dc0b011Da7eD8dD902063A6"; emailProof.emailNullifier = bytes32(vm.parseUint(pubSignals[10])); emailProof.accountSalt = bytes32(vm.parseUint(pubSignals[32])); accountSalt = emailProof.accountSalt; @@ -211,14 +224,14 @@ contract IntegrationZKSyncTest is Test { ); // Call handleAcceptance -> GuardianStatus.ACCEPTED - bytes[] memory subjectParamsForAcceptance = new bytes[](1); - subjectParamsForAcceptance[0] = abi.encode(address(simpleWallet)); + bytes[] memory commandParamsForAcceptance = new bytes[](1); + commandParamsForAcceptance[0] = abi.encode(address(simpleWallet)); EmailAuthMsg memory emailAuthMsg = EmailAuthMsg({ templateId: recoveryControllerZKSync.computeAcceptanceTemplateId( templateIdx ), - subjectParams: subjectParamsForAcceptance, - skipedSubjectPrefix: 0, + commandParams: commandParamsForAcceptance, + skippedCommandPrefix: 0, proof: emailProof }); recoveryControllerZKSync.handleAcceptance(emailAuthMsg, templateIdx); @@ -258,7 +271,7 @@ contract IntegrationZKSyncTest is Test { // 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 is account 9 emailProof - .maskedSubject = "Set the new signer of 0x7c5E4b26643682AF77A196781A851c9Fe769472d to 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720"; + .maskedCommand = "Set the new signer of 0xC9A403A0F75924677DC0B011DA7ED8DD902063A6 to 0xA0EE7A142D267C1F36714E4A8F75612F20A79720"; emailProof.emailNullifier = bytes32(vm.parseUint(pubSignals[10])); emailProof.accountSalt = bytes32(vm.parseUint(pubSignals[32])); @@ -284,17 +297,17 @@ contract IntegrationZKSyncTest is Test { console.log("is code exist: ", vm.parseUint(pubSignals[33])); // Call handleRecovery -> isRecovering = true; - bytes[] memory subjectParamsForRecovery = new bytes[](2); - subjectParamsForRecovery[0] = abi.encode(address(simpleWallet)); - subjectParamsForRecovery[1] = abi.encode( + bytes[] memory commandParamsForRecovery = new bytes[](2); + commandParamsForRecovery[0] = abi.encode(address(simpleWallet)); + commandParamsForRecovery[1] = abi.encode( address(0xa0Ee7A142d267C1f36714E4a8F75612F20a79720) ); emailAuthMsg = EmailAuthMsg({ templateId: recoveryControllerZKSync.computeRecoveryTemplateId( templateIdx ), - subjectParams: subjectParamsForRecovery, - skipedSubjectPrefix: 0, + commandParams: commandParamsForRecovery, + skippedCommandPrefix: 0, proof: emailProof }); recoveryControllerZKSync.handleRecovery(emailAuthMsg, templateIdx); @@ -309,8 +322,9 @@ contract IntegrationZKSyncTest is Test { "newSignerCandidate should be set" ); require( - recoveryControllerZKSync.currentTimelockOfAccount(address(simpleWallet)) > - 0, + recoveryControllerZKSync.currentTimelockOfAccount( + address(simpleWallet) + ) > 0, "timelock should be set" ); require( @@ -319,8 +333,7 @@ contract IntegrationZKSyncTest is Test { ); // Call completeRecovery - // Warp at 3 days + 10 seconds later - vm.warp(startTimestamp + (3 * 24 * 60 * 60) + 10); + vm.warp(block.timestamp + recoveryTimelock + 1); recoveryControllerZKSync.completeRecovery( address(simpleWallet), new bytes(0) diff --git a/packages/contracts/test/emails/300/accept.eml b/packages/contracts/test/emails/300/accept.eml index 7e10ce7a..f1f54312 100644 --- a/packages/contracts/test/emails/300/accept.eml +++ b/packages/contracts/test/emails/300/accept.eml @@ -1,90 +1,127 @@ -Delivered-To: rrelayerbob@gmail.com -Received: by 2002:a05:6400:2670:b0:264:9270:cc66 with SMTP id jy48csp750570ecb; - Wed, 28 Aug 2024 00:53:22 -0700 (PDT) -X-Received: by 2002:a05:6214:5b0a:b0:6bf:8cb9:420 with SMTP id 6a1803df08f44-6c3362e69d4mr13631006d6.28.1724831602260; - Wed, 28 Aug 2024 00:53:22 -0700 (PDT) -ARC-Seal: i=1; a=rsa-sha256; t=1724831602; cv=none; - d=google.com; s=arc-20160816; - b=XHYkOsPNkoh6Z/JlWBpmbftiVMlvTrQleXhtrViXaWIdnKIvwTAPXdaICvrHd/Gx6P - 3oVxnHb8Cuhi3cJ+ctMJ40RfT+f2+DRWXG2Csihny9ayIWeJ4mhPEy1Y6ZXkCEr3Gud8 - mVeHCXLthekdgQly8uhWxC6vn3wXtCEvx49iJM0gyfcyAI4Nt1eYDS0hr2gH6XNY4F+Q - mEiHfFbZj6s95egRsp2ZipfGz7yojKoKDTUWupDDPF4YpM9TxHrKyqVhk7mgT5PHaAWm - xkgUr8fWf+2/a+ini06UovznocNQCwGEHbRyPcIQ8SssjV21Xh0P3vwUSdKQKZYJJvTD - wUIg== -ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; - h=to:subject:message-id:date:from:mime-version:dkim-signature; - bh=wfoUswYdacWo98C2NPNyTM5htDNHLSMk6+9pc8+wtuY=; - fh=OYPr0JdXtRRlM3Htj/E6+khbD9huvtdqkRTmPoW0wko=; - b=H8LtD87fAH1qc7wN2hssgsTYQ10genWfiNzNwL+379b1AP/AMubRu3Ekep9uRlkgle - K7AUiX3xkCtX0jmtFAm4EgRqByv9EgAaedHzXbrc/jOBWUq7g0zJM+uk6QffM7ETNNvt - aI263gbooi401SQK+epiPYQ+yF4nXX6cNidm/HyGR0LzxEKWio3NPblQUxihlUKbwN/T - 4MWYgM18G4/ebFrdkbe9707tKHDK6P/BuK9P4mWH6DJwHmGVK40Pyu7xKCtr0/L74/Zu - U04dV6Rho5On1vS0fiEjdhSJdQ5Co1UkyMhn2s8Oalxk9pm95yN6EIcMM+81l2l6dI4+ - GkbA==; +Delivered-To: emaiwallet.alice@gmail.com +Received: by 2002:a05:6f02:50a:b0:77:b002:4a0a with SMTP id 10csp354010rch; + Sat, 26 Oct 2024 03:05:59 -0700 (PDT) +X-Received: by 2002:a05:690c:f0a:b0:6e5:e163:e001 with SMTP id 00721157ae682-6e9d89948d7mr20744637b3.8.1729937158848; + Sat, 26 Oct 2024 03:05:58 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1729937158; cv=none; + d=google.com; s=arc-20240605; + b=V+s/ezo2b7ImjTgbTg7Zn4NZGP7dpxEzMP6NHfpJgeM5eoKiqyhxZJcQKPPd7Ct+nG + +wgNvOq231Qge1xBUUEZ9K81biYH7JS0qezqyPtaSLjYdiEfjc4SwAXaA0p7VBzttVzK + X2Mgpaog+tSb1M+srZh2HlZy7pg45HW7QIrgAQaIOb7ZHFSLNKxHo5fzdJ1Bfg1RZtm9 + ty1fzQ93vOv/KItVyGuwnTRyBTRnRAjhFqUcSbBeiGBtFq4qErmbr7g4AN+D+mbeo7im + fQpQiLDKoxmd6LW+gzuJ0i8jwnZwzklt1Uf5KcHSZF5EYyL3oPGHYm5jk4zCcb7c5xOs + Oyug== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; + h=to:subject:message-id:date:from:in-reply-to:references:mime-version + :dkim-signature; + bh=LcnAcLtVZuqCU5Jjo9juA2FtHn9o1ru3lHN2dDAZHyQ=; + fh=piqzy4ujdlR+MUXqs15gF7XdlDw2mZShl76veKMclKc=; + b=KGQeCwcswgap53GgtByhGE7GWPSclz7ldctfnGEHdTXb4JfKVakTIWP1q14PyMR0Rj + NKjzZMmdj4hubyg+HpROG3zM3vaNLoEx0W7HQLzdf64PLCIX6a4rTX5vFGWbrwI8AghZ + JOcVRbrmIAN7GsA6G3jw5AZhEieXKKY7MTS1An21JVCilM9FwQx1m/xvrn3Yn49lAyV0 + mkdTKtM84OobusgbvYdwNdgJhWJAA7Ojj9rvlamhZ/b/FSlcdZWg5E53ro5XbQbP7tk/ + YwkeFaamdq3mmBMlLRdBf9ryLLEXe4RjiE1dcTYW5fIG2gxJ6gGABCk00op8my4+N5y4 + TKeQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=kOFwnIGQ; - spf=pass (google.com: domain of emailwalletrelayer987@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emailwalletrelayer987@gmail.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=BkoenyZF; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=pass header.i=@gmail.com -Return-Path: +Return-Path: Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) - by mx.google.com with SMTPS id 6a1803df08f44-6c162e8aa5dsor71159546d6.9.2024.08.28.00.53.22 - for + by mx.google.com with SMTPS id 00721157ae682-6e9c6c82315sor21482737b3.16.2024.10.26.03.05.58 + for (Google Transport Security); - Wed, 28 Aug 2024 00:53:22 -0700 (PDT) -Received-SPF: pass (google.com: domain of emailwalletrelayer987@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; + Sat, 26 Oct 2024 03:05:58 -0700 (PDT) +Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; Authentication-Results: mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=kOFwnIGQ; - spf=pass (google.com: domain of emailwalletrelayer987@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emailwalletrelayer987@gmail.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=BkoenyZF; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=pass header.i=@gmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20230601; t=1724831601; x=1725436401; dara=google.com; - h=to:subject:message-id:date:from:mime-version:from:to:cc:subject - :date:message-id:reply-to; - bh=wfoUswYdacWo98C2NPNyTM5htDNHLSMk6+9pc8+wtuY=; - b=kOFwnIGQ8CiIR0+qd/kNcIr9AyL0k/UMnrM2nWMnTJPHgOVyYzJt1v9dGuP1MqNvrA - kHAigFUd6kPv6vYZna755EG9ciFpvWXvdb0IgigVfKH35jBxKA2kTdGfbgkfHlZA3KSj - fwsytkQrkSVFpp/5ZuOIZ7WWqRbLYjJ75ICYYjmzpCQwjAA6MDpMvSpYHOlxmXxBzE+c - 9VPDfEIhD8HsVMgTB3NSYRPkSX7M8Sl3aFOUWhNW6KU7W5yqgNXq28P2PiyiFGzsh2B3 - dTx6SR/HadkLihJGpkC5C8qNgeCoUf1crLTNjbGESClqzNHIyjJ5Q6wt3MuKlgu80olN - xJmg== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20230601; t=1724831601; x=1725436401; - h=to:subject:message-id:date:from:mime-version:x-gm-message-state + d=gmail.com; s=20230601; t=1729937158; x=1730541958; dara=google.com; + h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; - bh=wfoUswYdacWo98C2NPNyTM5htDNHLSMk6+9pc8+wtuY=; - b=P8nKrBqskVA91k6q3XbmEdSc5BVCGGg2Utz+Ire/PS7MN3jnT1sQ5HxVqnWq/HiiDS - tVz4/wRFtUDmkkCNEzQ4DzLr2674IcS+vQ23hRaovrYEKos9yu2TKyV9xtNI/+zP3NNU - BmtuwCazEpMzK1BmOZ4NDX+Jd3DAha1uodiTxyfmKNxpoVg1QTluPlKtWALVc56Rk2tT - sGZXH6rpDalEF32vsi4hcGj7sA9n7pZIexLtjd1BZSILtJ0c0ImA2yyZIJwotFV/7Yn4 - DvC0VgQj5dtdrSI707fhUYXPZ+z1tEaVtINPNKz7X9Cy7TmTZ8dOdj05DaTA4eCixgFM - mgPQ== -X-Gm-Message-State: AOJu0YwrGQCEe9+PJ6Zepa+H3q3Cq2LyydJZATE3K+17Co3Iom94DUhW - vD7YwjhQbaLqC1niaQEOlycvMfVNNnTluvbVzbuYqqE/Kk5SBwcM7zJBcW5OBmSMV81PM0fPTWK - mLt1/FTNquOh5CWZ8GAsjw2p44F0k -X-Google-Smtp-Source: AGHT+IF9+HGRRMj6SjPxYPjB7WJiyoxKQSEitAal6QSa9IbQzWwfeh3hSAdLj9EMUwnFSJLGcixB1gy28cyAeKaW51A= -X-Received: by 2002:a05:6214:4306:b0:6bf:7474:348f with SMTP id - 6a1803df08f44-6c3362d2fa8mr9836466d6.21.1724831601609; Wed, 28 Aug 2024 - 00:53:21 -0700 (PDT) + bh=LcnAcLtVZuqCU5Jjo9juA2FtHn9o1ru3lHN2dDAZHyQ=; + b=BkoenyZFtCC1AWPIkGh46Ati7NWpgurTPlq3ESfFP0ZDcs83AL0cHJFsMVqGjh9qTw + /o1XN7MyXPxp+uXoQLNTn4Jm8UeAHyb6nqi9sBoN8G6ig27PFK19k3dz/GOADY+Q8N25 + 8Hlibj2wEZpcs3GfVthIKj3hs6xtjsoGUH8N/5cUmIrxbNwqXHaLA16Qw+X+v3cgWbjr + aBkQXippGF6hEFzv+N5gvqi2tqIjlZjPJUXY7YsFUd54Q9Jrk6MUs41VcJ9QUgrPUgmo + 5JsFtGADlekRlrVYQPnnIEZoL4iMkHGeNKtMZtyK+OzGSAQTBZaDZGyDE95p90TTEhv6 + SihQ== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1729937158; x=1730541958; + h=to:subject:message-id:date:from:in-reply-to:references:mime-version + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=LcnAcLtVZuqCU5Jjo9juA2FtHn9o1ru3lHN2dDAZHyQ=; + b=eAPJHebo0zQ7SF5YGsnvBHYGw7QnvdRO227vsMxOBl2DfRdrp/c0mL4Xjkhh2EKRnc + sXQYHHcwRnN5+jvnTww4v/2sJ+4LhwcoAv3BYS5LrzBHszoLDoXVEvGKg1Qz+lBljh+z + BA1DQdtJPCfN4zo2vpCn3/mClU2vpe9OwbwxZSgx5sqEBcfixcTbhNts379E4K/VFxry + bzOERLdeppOrtF9JKcaMSdIR2/tk7dC+Fw6658E2iCMT1cBFmF1uYg8MVebl7LYva+id + lRpAxtA/WR0zsPB1w2i/c4SfS+9Vf5Li4ZRtVsKMbT8X49nCXTq+V1mOhD2J8JBVAO2h + JahA== +X-Gm-Message-State: AOJu0YzhUHrbcil+369Y3Hb5BJK4BjmYqUBhWB2RDkrgNhbITLbYZ8pW + IRRJ/wukR87f8II7jfOdmWMokhXKjcBMz3VBYhGr8ITG5Jd0vd6b/WEPtXrKVOFzR0Ba+7ma3Ds + qd/8HHNJZUHttpACM5UoEu3LXZphNCp++ +X-Google-Smtp-Source: AGHT+IEThO03WP97va0PLQUTgwmsc9kADVY29b6jjytxjnFqkpKSPJbM5ZB+mmxGo/TLXFc7PsXUETLPq/jPgm1rdK8= +X-Received: by 2002:a05:690c:2841:b0:6e2:12e5:35a2 with SMTP id + 00721157ae682-6e9d8994b2bmr18478697b3.4.1729937158162; Sat, 26 Oct 2024 + 03:05:58 -0700 (PDT) MIME-Version: 1.0 -From: "emailwallet.relayer.2" -Date: Wed, 28 Aug 2024 16:53:10 +0900 -Message-ID: -Subject: Accept guardian request for 0x7c5E4b26643682AF77A196781A851c9Fe769472d - Code 1162ebff40918afe5305e68396f0283eb675901d0387f97d21928d423aaa0b54 -To: rrelayerbob@gmail.com -Content-Type: multipart/alternative; boundary="000000000000e9559a0620b9a62f" +References: <671cbe5d.630a0220.e20db.9df1@mx.google.com> +In-Reply-To: <671cbe5d.630a0220.e20db.9df1@mx.google.com> +From: Sora Suegami +Date: Sat, 26 Oct 2024 19:05:47 +0900 +Message-ID: +Subject: Re: [Reply Needed] Accept Email +To: Alice +Content-Type: multipart/alternative; boundary="000000000000cbd16e06255e610a" ---000000000000e9559a0620b9a62f +--000000000000cbd16e06255e610a Content-Type: text/plain; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + +On Sat, Oct 26, 2024 at 7:03=E2=80=AFPM Alice = +wrote: + +> Hello! +> +> This is a test email with a basic HTML body. +> Accept guardian request for 0xc9a403a0f75924677Dc0b011Da7eD8dD902063A6 +> Code 1162ebff40918afe5305e68396f0283eb675901d0387f97d21928d423aaa0b54 +> +> *Thank you!* +> +--=20 +--- +Sent with Gmail for Sidekick Browser ---000000000000e9559a0620b9a62f +--000000000000cbd16e06255e610a Content-Type: text/html; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable -

+


On Sat, Oct 26, 2024 at 7:03=E2=80=AFPM Alice <emaiwallet.alice@gmail.com>= +; wrote:
+ =20 +
+

Hello!

+

This is a test email with a basic HTML body.

+
Accept guar= +dian request for 0xc9a403a0f75924677Dc0b011Da7eD8dD902063A6 Code 1162ebff40= +918afe5305e68396f0283eb675901d0387f97d21928d423aaa0b54
+

Thank you!

+
+ =20 +


--
---
Sent with Gmail for Sidekick Browser
---000000000000e9559a0620b9a62f-- +--000000000000cbd16e06255e610a-- diff --git a/packages/contracts/test/emails/300/recovery.eml b/packages/contracts/test/emails/300/recovery.eml index 5b795415..95f86d6d 100644 --- a/packages/contracts/test/emails/300/recovery.eml +++ b/packages/contracts/test/emails/300/recovery.eml @@ -1,90 +1,127 @@ -Delivered-To: rrelayerbob@gmail.com -Received: by 2002:a05:6400:2670:b0:264:9270:cc66 with SMTP id jy48csp750751ecb; - Wed, 28 Aug 2024 00:54:02 -0700 (PDT) -X-Received: by 2002:a05:6102:26c9:b0:492:a9f8:4a71 with SMTP id ada2fe7eead31-49a4ed30da9mr1309811137.8.1724831642136; - Wed, 28 Aug 2024 00:54:02 -0700 (PDT) -ARC-Seal: i=1; a=rsa-sha256; t=1724831642; cv=none; - d=google.com; s=arc-20160816; - b=cpTbX87GQyaBGaVXbNadJs8tRJ3H6JwDzUCyAR6zbLifi7OvRIHe/CqXAdOjD88MEN - S5Vri34IQ0pQX+/0KPKejM0sKlvuQXSca6+H87JzalG4kkXOChT58Wjm5zrWcY9Xslh5 - s275+Zh5T6gx7IBZZZtXLcOgtRgZgsHhpF2DkzgSiRh1FtJC35ewsspFC1VtqWZqUAZh - +41nK1p++/vFWBqpB3YZXSdWFDGsyJ7QtHFfi3vG/x8b/h6c4vHrvT0zx5lDwZB+YmV+ - xXROwXhRH2ND5375vtZz8OyfaQHhY43HVSP4dOfrHgeUbtVzcQiYW+SR3Q6FPHCUqStc - EycQ== -ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; - h=to:subject:message-id:date:from:mime-version:dkim-signature; - bh=IehaSA/JR4L/KX7NlPKK5B7zTFO/0C8UNbHTPhhIN84=; - fh=OYPr0JdXtRRlM3Htj/E6+khbD9huvtdqkRTmPoW0wko=; - b=OUQ5TcZbiTNRl396nTBZH0uojnYZfc5tChwa5yntVLuQouy9qXfZXnKWHKNwRb/MiT - P2sVT7nG4DDbzSMdsOi7fG06vsBJfq4Oetaco5s1zyL7T7dCC0L4PnwJ2sRQbpSoh/Zb - YAknwfYkp1F0bjeYw2HBdfqlT93kzDLe7sI6zk2uADL1gp9oUMzKpotSMIrbzBIX6nGv - 26ASehd6ceNdxqCKCFCagi8WOuQQBNjN8E+G2m+7Zx1YjGif1LTgmzh6RxtpYT/M02gW - 4eidLLTEv6bQzFwKo9rwJq3iD1A9H9HESrEJGGWjAd5dTDxOLRQXge3igywzFjOnwPq0 - 9huw==; +Delivered-To: emaiwallet.alice@gmail.com +Received: by 2002:a05:6f02:50a:b0:77:b002:4a0a with SMTP id 10csp354626rch; + Sat, 26 Oct 2024 03:07:26 -0700 (PDT) +X-Received: by 2002:a05:690c:2506:b0:66a:ba89:d671 with SMTP id 00721157ae682-6e9d8ab9902mr24442997b3.35.1729937241694; + Sat, 26 Oct 2024 03:07:21 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1729937241; cv=none; + d=google.com; s=arc-20240605; + b=GwbT273POG3bJMybtOyGOxRKvNg3hDG73yX6fiqwW7ZTulvjV1VmVsJT8Su/C81nt8 + g5Y+Pd6ciEI3XB33uBj0U9dZORj7Q3+XYJkOtS9i0tRB+BbMqZvguOkKf1YKDbuURizc + k2i0/We80m3uhamnCxZYSqQ8EuFiiRUiUmVwZOHuDO4ca5BFp8lBqnmzSJg4wpxuo92z + RG+Tu+5AItNWzhI4jbGWBAlM6ncX/pEsDQ4R8sE7u3BRyyOdxeideWEkZyp74MvukHkd + sfIuHKo9wt1wkBwXyy3zLXynjC7kxBqLIobwAWvuVJUMQA0sXUkgKA78wXMzsAJM+cLk + 1j+Q== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; + h=to:subject:message-id:date:from:in-reply-to:references:mime-version + :dkim-signature; + bh=AqaLmXmHu6qu1K4WXdGaGJwLt+9pUk+m7VL8Dj0OUko=; + fh=piqzy4ujdlR+MUXqs15gF7XdlDw2mZShl76veKMclKc=; + b=NZYDgVZv7zWrKfYNKXfGjEFnLn6GYr7xP+AzjeT4t9MW9KLp3ND6r1reDjPsShofEi + Mswx8/uEvm6riBR3k0r2rl2QfQhqaSBF/oljT1MUL+mBNYb2evZJqEs+YLAWvkKr6OMF + YfytDhRqBRnw8ifLAhP4yyF7pOf93QpDaeRHuRuyahEn5iuuFp9/oqPzwCpOZwpYhCWm + WgGbiAQvyLvoDLNNnSKdAK+/BsP7boRcKAgkreIaedXe/sVScFCpq4o9/9nJXow9SKHJ + ipYiS3Ws/xFubbN3shcUha/lt1L5C983RDFE4gkJ/+4h0L/zy2oot0HLcGmOv4hCnqJM + IaHA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=XTkwK+MJ; - spf=pass (google.com: domain of emailwalletrelayer987@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emailwalletrelayer987@gmail.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=YMnW3Xsh; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=pass header.i=@gmail.com -Return-Path: +Return-Path: Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) - by mx.google.com with SMTPS id ada2fe7eead31-498e47e8b90sor1864165137.5.2024.08.28.00.54.02 - for + by mx.google.com with SMTPS id 00721157ae682-6e9c6ba4534sor20900587b3.2.2024.10.26.03.07.21 + for (Google Transport Security); - Wed, 28 Aug 2024 00:54:02 -0700 (PDT) -Received-SPF: pass (google.com: domain of emailwalletrelayer987@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; + Sat, 26 Oct 2024 03:07:21 -0700 (PDT) +Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; Authentication-Results: mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=XTkwK+MJ; - spf=pass (google.com: domain of emailwalletrelayer987@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emailwalletrelayer987@gmail.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=YMnW3Xsh; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=pass header.i=@gmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20230601; t=1724831641; x=1725436441; dara=google.com; - h=to:subject:message-id:date:from:mime-version:from:to:cc:subject - :date:message-id:reply-to; - bh=IehaSA/JR4L/KX7NlPKK5B7zTFO/0C8UNbHTPhhIN84=; - b=XTkwK+MJbzJP7Sy/I5oNWMkuJ7jrQZc5ovy3+4meyBwreJFQ1+F5UZOtUKd1svPC+u - v3TNvLvzlUTeXHW7TujG7U2WOxNOqqyYF18mgBIRlw5FXtgjz9j+bbALp0fo61e7gKhS - PHiRPocLWJpLgsMFy5nHod39aqcLWv0uMkCzwveMnDzlZYQFVxEKotyumIHUKLPIj2DI - BhOM5LhSml1qRzpB3eKpXGzEaLnyesPrOQNPwKB4ZfiSaP3xPYNfeAZhwohVEBTigi0h - ZnrH0DwfaJ6P1UdTTfG1YPfY1qm8BpEi4qFrYUUeZL1fK341NNq0y08egz0R6Q/CPJKL - l0KA== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20230601; t=1724831641; x=1725436441; - h=to:subject:message-id:date:from:mime-version:x-gm-message-state + d=gmail.com; s=20230601; t=1729937241; x=1730542041; dara=google.com; + h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; - bh=IehaSA/JR4L/KX7NlPKK5B7zTFO/0C8UNbHTPhhIN84=; - b=tlCjTjy8XCtY9U/SDWIKjLwWqYynJdQR9tV9VMWBcf37cDm9UpUVw5Ey9aScTxPLq+ - gadkjTGfA6ljpL8UsTbM1A2/b296DjfVZ2bYiCzZ58z/Httf8lSd9nInC1Tmd0iRIm3O - 8L/X9hWHkcbPGm8EhXNRiUKNBAFxshxpr24+jE2gWoPa7FVUmD1uY/nlYKMRGvvARqkq - RGQ9qpCa8LnWEPyRsE8AaV/g16kksprSEOoZocT3bwL+r/4O+s45ZNEHn9X0jEFPmb4U - 18/92ludL29pZ/PYgmz39iKbTEucY/7lZz3oKq2iNmWZPVKSjEf5kfYKMzIycQauxeN8 - lBDw== -X-Gm-Message-State: AOJu0YwP8OnzV4z4jcMcybAydVxa6xFnitsmWGjgRtqw9ENgSBo5ki6u - RGO9v2uhgEZvUHgR0fuGEYNoi7DCCDKFWePFH0ZVWNRGylHSvGShhFUZfztJ/KnOeUFE3KO+JyG - 8/1vz6i+Tu9quIYwBMxTsxItL1LJD -X-Google-Smtp-Source: AGHT+IFGI8kUAMWkx4LUP4o9Lv0V2QzLQJZlC8zeOQeO/P2VdPkPSYJrFwDo+q0Ez3VMetqJIH7d4YaBQI3E5y+sAWA= -X-Received: by 2002:a05:6102:c0b:b0:498:e21c:cc66 with SMTP id - ada2fe7eead31-49a4ecd79bemr1392977137.6.1724831641483; Wed, 28 Aug 2024 - 00:54:01 -0700 (PDT) + bh=AqaLmXmHu6qu1K4WXdGaGJwLt+9pUk+m7VL8Dj0OUko=; + b=YMnW3XshPWwKeGWphgkGbD8JIicy5669KnQbsGdDn5tvOT9DCLnJ4E41vTWTfiV71t + jZbNxF5l9Fw0WPeeaqcH0qCGlGKwrjGAPhIxONKjrL3j7bj2c5Wpv79khu3wpOLw658X + u9S8iIeNmAgiZJg0EpXUEi/tjKohQC1Ag8GmEriyc4wv4PML1SR4An2dpVqjLakZLsXP + 7yt/oW3cKhhnwabMCoPa3KmWq6VKyQ4Scqhq2adZhMMY84eKi6jNAwRfofjfcI7HbloA + B3iZJ55aAVwCs8oUWpwnypLLNLZLDZz4UbIUoB4d1EvURBxlVhUL1lEJE3PxOWpr1GW1 + DNvQ== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1729937241; x=1730542041; + h=to:subject:message-id:date:from:in-reply-to:references:mime-version + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=AqaLmXmHu6qu1K4WXdGaGJwLt+9pUk+m7VL8Dj0OUko=; + b=dQOKocIpFawpPLKCIU9HSiNq0cnMrUbwZH78ngMbLDkodVHb6iEdnC6BhBaZUyu6HH + H7Wpd7LVj9EpihF9MVhXrXWweW6j3Bp6M+yjXeLBH+DyUFfo8HRLUhxiNF94FHdUH5Oe + mzk9kPMCTzhYpHcf6BrCvHTWrWfU4peDRMrZdtQ+5rG3vmQ1J/JRJZnwd4ThXHZinWwh + 4mMKbLkQgFwE9RUrVGwkf0blegByFGDsQk14m96WSQo8Pb+psiq7sI/Q4dZ/e5kGOCvc + M+6qYR13Hv76Wf5BHDFjWA7QawvqU/v/lCWghwOf7+M4ZMC1iZWHo+HR5glEETBJedsq + YJwA== +X-Gm-Message-State: AOJu0YympUjJfX6WafJYGf7XPsa/P8kvPzM2JD9WJk6SNDJgvdGN/nSW + Xy9eV0GGNjOlafo1D+1B7FmuXn7kdW5RWoPtnRW/MENjRol/2/lfiJxVxiLtnXRh5n2H026S/2d + uZTNqezLOxC3qJi3+JVbCwNoa8V3aKzmT +X-Google-Smtp-Source: AGHT+IE9UXqIayoYdOuQsZUVsrqKSz2rsxJSnIkESJNWRoxXLQyOz0goCgAQyN1U6Vhzx+3It0NpIfY1k4DVpiIdtAY= +X-Received: by 2002:a05:690c:668b:b0:6e3:2864:c6b3 with SMTP id + 00721157ae682-6e9d8afc8admr20369567b3.37.1729937240981; Sat, 26 Oct 2024 + 03:07:20 -0700 (PDT) MIME-Version: 1.0 -From: "emailwallet.relayer.2" -Date: Wed, 28 Aug 2024 16:53:50 +0900 -Message-ID: -Subject: Set the new signer of 0x7c5E4b26643682AF77A196781A851c9Fe769472d to - 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 Code 1162ebff40918afe5305e68396f0283eb675901d0387f97d21928d423aaa0b54 -To: rrelayerbob@gmail.com -Content-Type: multipart/alternative; boundary="00000000000049c5260620b9a9a6" +References: <671cbf40.170a0220.1c1735.8ab8@mx.google.com> +In-Reply-To: <671cbf40.170a0220.1c1735.8ab8@mx.google.com> +From: Sora Suegami +Date: Sat, 26 Oct 2024 19:07:09 +0900 +Message-ID: +Subject: Re: [Reply Needed] Recovery Email +To: Alice +Content-Type: multipart/alternative; boundary="000000000000bb89cf06255e664d" ---00000000000049c5260620b9a9a6 +--000000000000bb89cf06255e664d Content-Type: text/plain; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + +On Sat, Oct 26, 2024 at 7:06=E2=80=AFPM Alice = +wrote: + +> Hello! +> +> This is a test email with a basic HTML body. +> Set the new signer of 0xC9A403A0F75924677DC0B011DA7ED8DD902063A6 to +> 0xA0EE7A142D267C1F36714E4A8F75612F20A79720 +> +> *Thank you!* +> +--=20 +--- +Sent with Gmail for Sidekick Browser ---00000000000049c5260620b9a9a6 +--000000000000bb89cf06255e664d Content-Type: text/html; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable -

+


On Sat, Oct 26, 2024 at 7:06=E2=80=AFPM Alice <emaiwallet.alice@gmail.com>= +; wrote:
+ =20 +
+

Hello!

+

This is a test email with a basic HTML body.

+
Set the new s= +igner of 0xC9A403A0F75924677DC0B011DA7ED8DD902063A6 to 0xA0EE7A142D267C1F36= +714E4A8F75612F20A79720
+

Thank you!

+
+ =20 +


--
---
Sent with Gmail for Sidekick Browser
---00000000000049c5260620b9a9a6-- +--000000000000bb89cf06255e664d-- diff --git a/packages/contracts/test/emails/8453/accept.eml b/packages/contracts/test/emails/8453/accept.eml index 1cc21c9b..8082498d 100644 --- a/packages/contracts/test/emails/8453/accept.eml +++ b/packages/contracts/test/emails/8453/accept.eml @@ -1,90 +1,127 @@ -Delivered-To: rrelayerbob@gmail.com -Received: by 2002:a05:6400:28a:b0:271:da57:79 with SMTP id hs10csp865237ecb; - Sun, 8 Sep 2024 17:38:53 -0700 (PDT) -X-Received: by 2002:a05:6358:9143:b0:1b8:226a:2622 with SMTP id e5c5f4694b2df-1b84beaea04mr864194555d.21.1725842333641; - Sun, 08 Sep 2024 17:38:53 -0700 (PDT) -ARC-Seal: i=1; a=rsa-sha256; t=1725842333; cv=none; - d=google.com; s=arc-20160816; - b=Eo8FQDuq26qqB1YlOaTQ5KkpTWjMuduMUW/YTGvZXhX88eYKZsBZHO1Qgucz7eT4GP - lxiIeLbUjVkJU/kbWNOLusUabrsuMYm3UnOTVeiTZBX8LtHpy8/kWi72IiL0/wpszOB6 - M+CKFud0FgParMBL/FeowgITRN2lfSXXcrEFE7OJ46OUeZTkZH6o5klmAxRaP/WWnK7Q - Lv72Pleqdm7epcpoduR2K5V2t4WD/6hEhqFxkJQf3LfxOAIRYXX2brBpCKGNN7AmnMGJ - 1j4yTPYwX3FjSYBB0dFgRQpO7JqUQuoIWQWuE2IsFf8MowINFSOfzG2HGLCptV7GBdu8 - nR5g== -ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; - h=to:subject:message-id:date:from:mime-version:dkim-signature; - bh=u3BMBmOH3oo7W5+AST9Mudcc8sUjkyZ9Ee118Aw1hRA=; - fh=OYPr0JdXtRRlM3Htj/E6+khbD9huvtdqkRTmPoW0wko=; - b=S7CO2YA0iDfPdwyRITTdtNCwpPJQ8OA27yWCiXjsYME+l2C6U73hWlxoUbTO8XqTOL - sQEE4O8zwppLIWznAgRsdXQ5tvcJjn8J+hRO/sDeiGAfeMVyKOXBFWfGwUpbUHHBZ1wS - 6rS2zhzDcrjm6qmnqUY+AeptvSkeb46ECH+QIutZ3BU8iXIe6xYhf7XL/5AkoSrrrTf6 - 4gmti0p2vUJcV+Npyb7QHzcW+AjCFpLPtvkDXRJMHeFxKlMFiaiiugn7vOk1yjxCSaVn - ahfeCUgcBSwkAp03icM2nTpYCVr6Ou0/ZOS74+yal0VsHbQkKAk6Xr6qP4AwCowX0Sc/ - //0w==; +Delivered-To: emaiwallet.alice@gmail.com +Received: by 2002:a05:6f02:6f6:b0:77:b002:4a0a with SMTP id f54csp330097rce; + Fri, 1 Nov 2024 03:02:42 -0700 (PDT) +X-Received: by 2002:a05:690c:9c0f:b0:6de:a3:a7ca with SMTP id 00721157ae682-6e9d8acb4a9mr277187697b3.32.1730455361946; + Fri, 01 Nov 2024 03:02:41 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1730455361; cv=none; + d=google.com; s=arc-20240605; + b=UT9PJ1kGlcXGGEjGgXHBTkf3N9y5J8rWimEVNdGzZiZmpVCfI68ja3sRSK0iq/RThp + GCf+AIXLL5dQ3hUPd0CNRozTqryNmoLndgpiuOHlb3HhllSaDO/KLYjSFr0G8CbRekGh + bEhlknRr6uZ/sOqOjHRAcBU7QZRpUNW341HUqBvLxx4tmL2HwfzJZmoI05ZWT70Bp4Js + IsjTQXwMtWF4KEsMyyAuVGlu/V9y+eq+TifqOxIgdQCIEs2TpBf+eHgnVbayXbsh3waU + o6QDbcvYd1CNcepgxWXppjn67GhMOAApSLhfM7q7uy3bo4L8Lld8DPGfDQ5ICvgzrVMh + rLbA== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; + h=to:subject:message-id:date:from:in-reply-to:references:mime-version + :dkim-signature; + bh=KyF9d1a+n4fYTSkZQNoUYaw6sykzzH9Y53ENgK0zkoA=; + fh=piqzy4ujdlR+MUXqs15gF7XdlDw2mZShl76veKMclKc=; + b=k9wqht/tAObn9SnYH6WEwoMkKhD9yjZJj5HoQHrPnr6sZq3pJKQPfDOoyg3oiMz+Jg + oV/UDi3smJW4zgyev86/o+RCoFpOICeJ4CbXOMRqGXzOuSddTQD2Bj/3LWmxoKr8QdFh + 5S82Jf1DIAGmOS6NEnxBc5tOKSyXL9MbiXyCZ7b40XIs+yRwPV2ZXBzPj8ydJoW5ScYe + alOQl+oKGJ3GBK+vHIoklFOl8CKKcs05PG0HH4btGMziCtMb/VA5RqYLuZ2Dg9T2q0PZ + G+m78daUJySJFqL5AIpQNWHadNsXubSv8GYchlaUIvP0xfKTTyGKdvnjkQ2GCJ50kIV4 + L9hw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=RwyfZUyf; - spf=pass (google.com: domain of emailwalletrelayer987@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emailwalletrelayer987@gmail.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=CQfLn7Bw; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=pass header.i=@gmail.com -Return-Path: +Return-Path: Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) - by mx.google.com with SMTPS id af79cd13be357-7a9a7a73740sor176146885a.19.2024.09.08.17.38.53 - for + by mx.google.com with SMTPS id 00721157ae682-6ea55b3ca7csor26603827b3.7.2024.11.01.03.02.41 + for (Google Transport Security); - Sun, 08 Sep 2024 17:38:53 -0700 (PDT) -Received-SPF: pass (google.com: domain of emailwalletrelayer987@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; + Fri, 01 Nov 2024 03:02:41 -0700 (PDT) +Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; Authentication-Results: mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=RwyfZUyf; - spf=pass (google.com: domain of emailwalletrelayer987@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emailwalletrelayer987@gmail.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=CQfLn7Bw; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=pass header.i=@gmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20230601; t=1725842333; x=1726447133; dara=google.com; - h=to:subject:message-id:date:from:mime-version:from:to:cc:subject - :date:message-id:reply-to; - bh=u3BMBmOH3oo7W5+AST9Mudcc8sUjkyZ9Ee118Aw1hRA=; - b=RwyfZUyfwOg5nNyFlHnCyClaJ27wgLGNekZls/hqRQSxYrc25H+aqdjBkpubBKuvpj - E0COKCv052KffeYVWD5/xcmIxNXpX7ZVv923i65P8ObFCVtt02qpyTarw2GYO9QXPtIa - roA2+VV0W7gEoQl1iSeQckJrRtt/9+nZwdZY/0/uAROHnOeKlvWjA4bikh74EZtjJg2E - jetr3A8eh2+yJ2EeXknJCZSX+QUpwJEjxnOju+tSiUH3ojAxjD9gnx86ZWVGSsaeUjP1 - +PlSjabZVDmkrOSq1HMj5fGpWCKDGQsvKa9MKLrwwzQBrEp0DE4TDhoR6TWN7znLdKgv - AXxw== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20230601; t=1725842333; x=1726447133; - h=to:subject:message-id:date:from:mime-version:x-gm-message-state + d=gmail.com; s=20230601; t=1730455361; x=1731060161; dara=google.com; + h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; - bh=u3BMBmOH3oo7W5+AST9Mudcc8sUjkyZ9Ee118Aw1hRA=; - b=OEx1J3HwB0T1PRnrPhqrVXxq2fd4HehGlOGD8qyfS8tuRl6sdyKsrF+wgTVNyWcwCM - uY9ZRVCFTb5/2/Z9n6O8dRV9JWsnK7hb7NYSmD/s2zaPFtfTIYBafm5TW+3uaPjQ25Gf - /5sGy64lE5uOegFmf12PkWKIQwgs1ytMLQ/PN24tjIS142p6Fj2Ns1f1CvV6ySttUO7i - btVq9zrBUNrsB88II+0srbEnYVrMIspUp4bMXgLiRuRjU53tiIXoZe9QqZrY3ZT1SXvq - cURQ3X5zoMg2FIJT7qLyRG9xa8bbq+uaszbjE6n/AmxowT6VzPJebE12Z7wvvGKs0+qs - RfZw== -X-Gm-Message-State: AOJu0Yyf0PsSEn60KLTqdIQcs8o4LO7Pa3spSzQjW1mUOwM8e/WTWsW0 - Zqu6dlktj82yEUBmOe30+KU4qyJ/WS4/FFRyayQDHrEK7IZEZIsaGDdPQpcmIOx+d+ZhxJLePKe - xsurjVlEiLeE9Va+J0s6JwZm7dG3X -X-Google-Smtp-Source: AGHT+IElTLWDEBfxtyVnOba2cERBK6YgvSGie3f/wnb+tcjM9hAUxYGKZci+WQB/O7imoT0PysrYKS2H8UaDLXML0Ew= -X-Received: by 2002:a05:620a:1910:b0:79f:12fb:ed1 with SMTP id - af79cd13be357-7a9a38a8187mr646569985a.16.1725842332968; Sun, 08 Sep 2024 - 17:38:52 -0700 (PDT) + bh=KyF9d1a+n4fYTSkZQNoUYaw6sykzzH9Y53ENgK0zkoA=; + b=CQfLn7BwyPRSED9uryHffAUv/H5b1LMI7Yirj7BYBEg6csGx8WqGecX8QUpKRcc+EU + ikEohKU88TXkt5CjQlgjCssP3NScZApqRdq929Q2ztH+ZCorbsZDoV2qsrl5XVlRHaTu + qqQKnzv8VaUGFaRFE/v6l4hlsQj9yOFCEPdj3atWpBR60sl9QzZlbITXMsRUJAj3kO+a + 9kv6KhItPyO6u3JL+ma/NYSgcftaSEN0cRBW9xQjzygGAEzERjkAF72GReMDdf0t1ir2 + wkbCRvzlTd/KhrjjKAnO3FbKoC4knvpQJzf8Qekq2VLpgnIF1T1KTbPLIqhtbrX6l4AV + sIsw== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1730455361; x=1731060161; + h=to:subject:message-id:date:from:in-reply-to:references:mime-version + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=KyF9d1a+n4fYTSkZQNoUYaw6sykzzH9Y53ENgK0zkoA=; + b=O5YLktCAErj8Kc1pveGTSZ/+22ADKlhS84tBCBlPYG9JV6QIOlJlPrMezX8jpO4Opd + x80n8uS1LtJLBQfWAap1zLxIZk9Q3v9N4CYK011TfnJ+ZXtlM0uiorX2pSvVBbiXtYnP + hPYEB1b22RMg3auErPPf/ndWgXIIV3DmdkElXXWrczt9YjKAVi5IAfAuR4TdUJ7FQrbE + tuC6wC806UzYaIidDByZF3JJUeZJkkI0bpiennbpMSmtJWnT6U84DFae7rBKCGcJOb2r + RNb1VY3HYuPQnR18zvVK2x12M7EyYZy+dFVgeR+2CeTTEPdnNG+V8rsHF1fCJgJAgjFz + BTHA== +X-Gm-Message-State: AOJu0Yycx94I/O2Lm7bU41w1OyXLtrVTntxgrqYKFAr6Q0BdW/2mS5WT + 1rAnV+X4oijRr+5xVc0hiJfeOgfYzU+s/WCjUj+t+kuD9FYK7N100AdaXhy5/OLTe2mFcbzDvVs + qW2qMQ127i23xQViSFMd+0VpkUB6qFlyt +X-Google-Smtp-Source: AGHT+IF2B+yIY7gaQxHWawqKLaW9hPUSYUTmXS2OkBkr/IxO58SRqSK9ryWyrMNcXzBftKSKWUiCu3tJ3I8blbNSwlg= +X-Received: by 2002:a05:690c:318e:b0:6e6:45b:5d0 with SMTP id + 00721157ae682-6e9d8b55218mr147141597b3.45.1730455361170; Fri, 01 Nov 2024 + 03:02:41 -0700 (PDT) MIME-Version: 1.0 -From: "emailwallet.relayer.2" -Date: Mon, 9 Sep 2024 09:38:42 +0900 -Message-ID: -Subject: Accept guardian request for 0xeb8E21A363Dce22ff6057dEEF7c074062037F571 - Code 1162ebff40918afe5305e68396f0283eb675901d0387f97d21928d423aaa0b54 -To: rrelayerbob@gmail.com -Content-Type: multipart/alternative; boundary="00000000000031f01c0621a4fbb6" +References: <6724a727.170a0220.1bb60.8eff@mx.google.com> +In-Reply-To: <6724a727.170a0220.1bb60.8eff@mx.google.com> +From: Sora Suegami +Date: Fri, 1 Nov 2024 19:02:28 +0900 +Message-ID: +Subject: Re: [Reply Needed] Accept Email +To: Alice +Content-Type: multipart/alternative; boundary="0000000000001a344d0625d70920" ---00000000000031f01c0621a4fbb6 +--0000000000001a344d0625d70920 Content-Type: text/plain; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + +On Fri, Nov 1, 2024 at 7:02=E2=80=AFPM Alice w= +rote: + +> Hello! +> +> This is a test email with a basic HTML body. +> Accept guardian request for 0xa3A6f0FDd72Ae9936C44cE36151CB4DB3E9949d1 +> Code 1162ebff40918afe5305e68396f0283eb675901d0387f97d21928d423aaa0b54 +> +> *Thank you!* +> +--=20 +--- +Sent with Gmail for Sidekick Browser ---00000000000031f01c0621a4fbb6 +--0000000000001a344d0625d70920 Content-Type: text/html; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable -

+


On Fri, Nov 1, 2024 at 7:02=E2=80=AFPM Alice <emaiwallet.alice@gmail.com>= + wrote:
+ =20 +
+

Hello!

+

This is a test email with a basic HTML body.

+
Accept guard= +ian request for 0xa3A6f0FDd72Ae9936C44cE36151CB4DB3E9949d1 Code 1162ebff409= +18afe5305e68396f0283eb675901d0387f97d21928d423aaa0b54
+

Thank you!

+
+ =20 +


--
---
Sent with Gmail for Sidekick Browser
---00000000000031f01c0621a4fbb6-- +--0000000000001a344d0625d70920-- diff --git a/packages/contracts/test/emails/8453/recovery.eml b/packages/contracts/test/emails/8453/recovery.eml index 0be721ce..abfd73f9 100644 --- a/packages/contracts/test/emails/8453/recovery.eml +++ b/packages/contracts/test/emails/8453/recovery.eml @@ -1,89 +1,127 @@ -Delivered-To: rrelayerbob@gmail.com -Received: by 2002:a05:6400:28a:b0:271:da57:79 with SMTP id hs10csp865517ecb; - Sun, 8 Sep 2024 17:39:56 -0700 (PDT) -X-Received: by 2002:a05:6102:e0f:b0:49c:1bc:1eff with SMTP id ada2fe7eead31-49c01bc22femr2263104137.28.1725842396118; - Sun, 08 Sep 2024 17:39:56 -0700 (PDT) -ARC-Seal: i=1; a=rsa-sha256; t=1725842396; cv=none; - d=google.com; s=arc-20160816; - b=D41hDnFU3G2f/9wRCrVHNx7sasI4u/B06uRAaZgq+tOf6E/zpCTbGcMG2Qk83mFEIM - L00rZK/B4/akwHdjQW8Iel1GwfkdJNHEM+XGiEW6641RId75OwQC2kMG/m+fHakpBsLU - Xpcq4RjCaKJ1WqwkhYjrHxpH/ScVA1vp5sLVbHaymmFVYtC3ztYrVhyYnuKrUjgnAqdR - +PelC5UCIbuORBiLbdTc+cCzQIJV4OlI+u641PQJwrs67H2UrgZnyl6cXMcPNJrzXZiw - oKoD/mTHXGmPY+k6vO23OFy6fU63scpYc6i29ZIuseE2X6+CBodBAtPiYFmeK+hUxTDP - R1SQ== -ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; - h=to:subject:message-id:date:from:mime-version:dkim-signature; - bh=mvDapCNNa9oKBO12XFAqF92pzaTTjGLTiE2clMtdRzM=; - fh=OYPr0JdXtRRlM3Htj/E6+khbD9huvtdqkRTmPoW0wko=; - b=a9iG6t8RdHTSDJrDnbsG10Kdnq2Es9QDHumVktkIoOi0UF2vf5YprDs0nj7OFSPoCc - nAZAZvIwB8fL4f+cqM+ZIWzFjplOY1tfspreWsfZkxDUrhKNUhhiuyVI3JkdY/BMeCJ2 - mim96jnyH3ckvBPgeJdiCkZWknstuQrce1CQyfp64rUB0WQ4MgdgyPYBLSrbc2ZfQo3r - jahYqae1lJTY37m29wLIMh/vix2SJutq47+/St2rIk59SpgTz3xIJSPKI76ovOBR3sbU - /PjYxt8wFw2eP0g/etqbGS1sxVdu4UMWDqXpCrEQ63bTlfgTpwrYMh9ugZNfG4kHxD96 - 3uAA==; +Delivered-To: emaiwallet.alice@gmail.com +Received: by 2002:a05:6f02:6f6:b0:77:b002:4a0a with SMTP id f54csp331236rce; + Fri, 1 Nov 2024 03:04:29 -0700 (PDT) +X-Received: by 2002:a05:690c:708d:b0:6ea:2ac4:9df6 with SMTP id 00721157ae682-6ea64ab2f86mr32916447b3.3.1730455469506; + Fri, 01 Nov 2024 03:04:29 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1730455469; cv=none; + d=google.com; s=arc-20240605; + b=kXXzlAXeS6ht9X8mgWup1C2zoTqFH6beoAJik2VmQRjfaVsBW8WFXsDlAX0UEwITGs + 3F5neaBnwHjWrQv+RphDJ/CthdXRLqUl/HAI+TpmBDOkgNlZjz5OwHpWKMkoHUbgX+9k + hFQIrJknl4JB7dAds6P4No3E/cwlHDKxgey2GZWwWToEC+EKsC5ejgjZaw0XRYnL8j5p + 4669mxwnH5C/ye/eJ9B6KS+qr7MBw1VuZIr5TOXbvZG/3xcsTGFiZ9KN4VMx+q557BRd + N/WuNGOsHQHEHUEBne1+HPtGUJ/vTX6v/WcWaOsMX4qMpgIeIWl5Siqo2HO/aJ/xF0Mp + zlKw== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; + h=to:subject:message-id:date:from:in-reply-to:references:mime-version + :dkim-signature; + bh=qfP3fcgGLM6DKMMm9CJ3H+Hz60AolkxUOYYkf2x1EQo=; + fh=piqzy4ujdlR+MUXqs15gF7XdlDw2mZShl76veKMclKc=; + b=JJ1Exgudtr8gwlXqq1dOMfZRcMLlEbEeAf08c2kXTMMyzAw6RBNh+Gafm4jt8fspEB + 0LhjkC1QvP0vAQCOqESbq7Xa2K5vkEdMQcXLRpUYyh+gEn3BYPCmbiCT9Ox1a7emxlFO + sbF5zQ8Q2fVGXTm1BQtSsHb+gLIVDxuQLYtmGYLzc4zrJ8KVwwV880mv2SAIunFi3zzz + h1KXV6shHPf2frj7AsZyoRaln7Uz3pH3Evbn1EDY4H6V3xpbaBQOiQER/2/DhVHGKgGm + figBUs9bsGv/g/o6nLtTVLi8KRk/6ijpx4gqIc3/VDzPLuNiZXTFteB11NdP+Z5QQr0N + HsMg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=RfgErx0i; - spf=pass (google.com: domain of emailwalletrelayer987@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emailwalletrelayer987@gmail.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=HdCCbFgP; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=pass header.i=@gmail.com -Return-Path: +Return-Path: Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) - by mx.google.com with SMTPS id af79cd13be357-7a9a7a296c5sor198986385a.15.2024.09.08.17.39.55 - for + by mx.google.com with SMTPS id 00721157ae682-6ea55fa703dsor28180747b3.13.2024.11.01.03.04.29 + for (Google Transport Security); - Sun, 08 Sep 2024 17:39:56 -0700 (PDT) -Received-SPF: pass (google.com: domain of emailwalletrelayer987@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; + Fri, 01 Nov 2024 03:04:29 -0700 (PDT) +Received-SPF: pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; Authentication-Results: mx.google.com; - dkim=pass header.i=@gmail.com header.s=20230601 header.b=RfgErx0i; - spf=pass (google.com: domain of emailwalletrelayer987@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=emailwalletrelayer987@gmail.com; + dkim=pass header.i=@gmail.com header.s=20230601 header.b=HdCCbFgP; + spf=pass (google.com: domain of suegamisora@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=suegamisora@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=pass header.i=@gmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20230601; t=1725842395; x=1726447195; dara=google.com; - h=to:subject:message-id:date:from:mime-version:from:to:cc:subject - :date:message-id:reply-to; - bh=mvDapCNNa9oKBO12XFAqF92pzaTTjGLTiE2clMtdRzM=; - b=RfgErx0ifG4YFDsIv9nxEu9TStTl0mBznYQZMMwT6Dpn3diDq+uhHBN2bRDMAT0dYv - 5w88/E+d8oLyhT6/TBlkps9ahwTKkfOZUCi4UUmBx2n/p+5uYTAVLP9Fv29PtgQFHnDe - qySfOEb7NKj8LR22QXYRUxRLN/jhmskaIpg9fs+HmC7jU4+fpoFmpoIgWb8rGI/uzip8 - pZYYEvVICaXHH3E4aRMps28DY2VYHBycwlC+a4+O0Ui7Ctpay0eALDUq20YrqimKBa+K - 72gp//f9/UMHuG581IRQDiqE3pPz+Cx8KYc0z7DYbEF1YknhJG7gwdOwPJzGjv2LVeps - o3xg== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20230601; t=1725842395; x=1726447195; - h=to:subject:message-id:date:from:mime-version:x-gm-message-state + d=gmail.com; s=20230601; t=1730455469; x=1731060269; dara=google.com; + h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; - bh=mvDapCNNa9oKBO12XFAqF92pzaTTjGLTiE2clMtdRzM=; - b=GWRnggEPlVvXAqrwoXCKq4ZOgguVgZiZb4jQpoFHV+/oc9UYFBSsN9b5B+OUaj2F0N - G6nv2u7c346WsoIfb3kCvyqwQbZBP1Kzcb/n3DUW7CjlE2VSz6BOOrPQxLl5nshDU1Du - QGGoGjE4+dzEZBdYjJVFSq2L1DJilntkNAFS1ff9DaGqOCEEftx0Y/MfFumclnwZ5VYR - C2+o9qH45iwtw88mBsfJ7Yl7OoI9w10NuuraYQcoeu72zwmb30E2uHfUe5osGldslgXJ - RcGV8JsFGwAJJUbmr/4HZFQDt3EMeydn7KkieTgi41fExIj5ZC3VhEt1rw4PTdqcTbSG - mEdQ== -X-Gm-Message-State: AOJu0YzZrLLg8bVVKkxvRm1k5x4qHXit4w1BuMonhJq6LxOP+DHivono - +8JABSGbjSpXofT9yUe7vRgJ5G3KTm5sIL9UP2ZOxlI4c3j37jmENGKx2sb/T9IdgYq1A3890fY - 2SoTWndVkyH23ZCxWm/36uVvQOyum -X-Google-Smtp-Source: AGHT+IGhU+pRzJcpq3/XnnchlgpJSMnc3PvuTm0gfTpuyITwadr4gnoO1o/F4dGPxxKl9Epjas8+m4UXLqVKM8yWsCo= -X-Received: by 2002:a05:620a:2901:b0:7a2:1bc:fc1e with SMTP id - af79cd13be357-7a99739b7bbmr1356449485a.61.1725842395467; Sun, 08 Sep 2024 - 17:39:55 -0700 (PDT) + bh=qfP3fcgGLM6DKMMm9CJ3H+Hz60AolkxUOYYkf2x1EQo=; + b=HdCCbFgP+MMDhws3gnsyQSJOiFOYiXT/LqI/sziklrZgwppoCUxuCQaXYoaStJOklZ + HNLypVL9XqYizfqEF4EwQSGE+EcnCVMYInx+dL6n2sv93pLiQYGggwoL3O+tEiZOdrT9 + xfRqcGSTWSHjykf+8Ja6E4evTb6htclHcmJLEWPG38bCX19iAUQA1/ncIIclCHJoXZi3 + smKpSm4pQjAohGyq6uuGws4JUlNziPHdpU+POx/726KtxZ2qGsBxn5fm1JT4TY41ddHv + w88ptrwnEvUP4hR+3kbLsn6NBwlxzBDT1ocBhZ/WsvNBQlt+pZtwiG61LDF4peK6Xvk0 + jNjA== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20230601; t=1730455469; x=1731060269; + h=to:subject:message-id:date:from:in-reply-to:references:mime-version + :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; + bh=qfP3fcgGLM6DKMMm9CJ3H+Hz60AolkxUOYYkf2x1EQo=; + b=u9PJ5BMFezervz47BOTSfhnxe0gKbmbbbjjjN8IM60fquCnkKOOFmk1tP4fes+iDev + 3q59+i51jg2HGu5S3yt+xA+bNSjKI231/jcxHYa+03HV2v14PZUZIvy3pptBPUvE69NB + Q7raPLNH2NoW3azZbXDvcT3pXtLJzPF9rn/h0NfjTehbai4NXZShA7sBf8OYWOMSNiyb + nKqQmeJsYlxBTWQaAoTEG5OLQzhyP9DWqUCAGpxORXSDo4p+siiMKXWl2hUhVHT68+e/ + LPgD4d0emoAeJY4driZGx1SbfYiLMpyQP7CMWQCrsCNnUDlATO36Cs90kOwVAnjP0M8W + hqfw== +X-Gm-Message-State: AOJu0YzLSJ1kJRnegVjBkilYs3ZAsCLhVihVYNDOIm9c9nruTAzSsfNU + tOKgiTONti0dufWvLMEebJJxktAEoeVppFp4w5Zz/xrNmBSsWSAEcJIoEbuWcCJoEywFN6RnB0D + pqWD/78nb6xC55VTEbQvzdkfpGFNU+3mU +X-Google-Smtp-Source: AGHT+IH+lF2f38lLJ+LMdVr86b9JpC1RoVG2y1BzooyNEtphr3e3lQt3UzM9u3dslLl6S8OD2I6vAN6P8rauQYV1zpY= +X-Received: by 2002:a05:690c:7482:b0:6ea:3e6d:2b01 with SMTP id + 00721157ae682-6ea64b2b6femr32405347b3.19.1730455468746; Fri, 01 Nov 2024 + 03:04:28 -0700 (PDT) MIME-Version: 1.0 -From: "emailwallet.relayer.2" -Date: Mon, 9 Sep 2024 09:39:44 +0900 -Message-ID: -Subject: Set the new signer of 0xeb8E21A363Dce22ff6057dEEF7c074062037F571 to 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 -To: rrelayerbob@gmail.com -Content-Type: multipart/alternative; boundary="000000000000eb98600621a4fedf" +References: <6724a77c.a70a0220.fcd92.a9ea@mx.google.com> +In-Reply-To: <6724a77c.a70a0220.fcd92.a9ea@mx.google.com> +From: Sora Suegami +Date: Fri, 1 Nov 2024 19:04:11 +0900 +Message-ID: +Subject: Re: [Reply Needed] Recovery Email +To: Alice +Content-Type: multipart/alternative; boundary="00000000000083afb90625d70fee" ---000000000000eb98600621a4fedf +--00000000000083afb90625d70fee Content-Type: text/plain; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + +On Fri, Nov 1, 2024 at 7:03=E2=80=AFPM Alice w= +rote: + +> Hello! +> +> This is a test email with a basic HTML body. +> Set the new signer of 0xa3A6f0FDd72Ae9936C44cE36151CB4DB3E9949d1 to +> 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 +> +> *Thank you!* +> +--=20 +--- +Sent with Gmail for Sidekick Browser ---000000000000eb98600621a4fedf +--00000000000083afb90625d70fee Content-Type: text/html; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable -

+


On Fri, Nov 1, 2024 at 7:03=E2=80=AFPM Alice <emaiwallet.alice@gmail.com>= + wrote:
+ =20 +
+

Hello!

+

This is a test email with a basic HTML body.

+
Set the new = +signer of 0xa3A6f0FDd72Ae9936C44cE36151CB4DB3E9949d1 to 0xa0Ee7A142d267C1f3= +6714E4a8F75612F20a79720
+

Thank you!

+
+ =20 +


--
---
Sent with Gmail for Sidekick Browser
---000000000000eb98600621a4fedf-- +--00000000000083afb90625d70fee-- diff --git a/packages/contracts/test/helpers/DeploymentHelper.sol b/packages/contracts/test/helpers/DeploymentHelper.sol index dc345500..4d421a7b 100644 --- a/packages/contracts/test/helpers/DeploymentHelper.sol +++ b/packages/contracts/test/helpers/DeploymentHelper.sol @@ -7,6 +7,7 @@ import "forge-std/console.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import {EmailAuth, EmailAuthMsg} from "../../src/EmailAuth.sol"; import {Verifier, EmailProof} from "../../src/utils/Verifier.sol"; +import {Groth16Verifier} from "../../src/utils/Groth16Verifier.sol"; import {ECDSAOwnedDKIMRegistry} from "../../src/utils/ECDSAOwnedDKIMRegistry.sol"; import {UserOverrideableDKIMRegistry} from "@zk-email/contracts/UserOverrideableDKIMRegistry.sol"; import {SimpleWallet} from "./SimpleWallet.sol"; @@ -16,7 +17,6 @@ import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.s // // FOR_ZKSYNC:START // import {ZKSyncCreate2Factory} from "../../src/utils/ZKSyncCreate2Factory.sol"; -// import "../../src/utils/ForwardDKIMRegistry.sol"; // import {RecoveryControllerZKSync, EmailAccountRecoveryZKSync} from "./RecoveryControllerZKSync.sol"; // // FOR_ZKSYNC:END @@ -26,7 +26,7 @@ contract DeploymentHelper is Test { EmailAuth emailAuth; Verifier verifier; ECDSAOwnedDKIMRegistry dkim; - UserOverrideableDKIMRegistry overrideableDkim; + UserOverrideableDKIMRegistry overrideableDkimImpl; RecoveryController recoveryController; SimpleWallet simpleWalletImpl; SimpleWallet simpleWallet; @@ -43,8 +43,8 @@ contract DeploymentHelper is Test { bytes32 accountSalt; uint templateId; - string[] subjectTemplate; - string[] newSubjectTemplate; + string[] commandTemplate; + string[] newCommandTemplate; bytes mockProof = abi.encodePacked(bytes1(0x01)); string selector = "12345"; @@ -53,6 +53,10 @@ contract DeploymentHelper is Test { 0x0ea9c777dc7110e5a9e89b13f0cfc540e3845ba120b2b6dc24024d61488d4788; bytes32 emailNullifier = 0x00a83fce3d4b1c9ef0f600644c1ecc6c8115b57b1596e0e3295e2c5105fbfd8a; + uint256 setTimestampDelay = 3 days; + + bytes32 public proxyBytecodeHash = + vm.envOr("PROXY_BYTECODE_HASH", bytes32(0)); function setUp() public virtual { vm.startPrank(deployer); @@ -69,7 +73,6 @@ contract DeploymentHelper is Test { } string memory signedMsg = dkim.computeSignedMsg( dkim.SET_PREFIX(), - selector, domainName, publicKeyHash ); @@ -85,14 +88,27 @@ contract DeploymentHelper is Test { signature ); - // Create userOverrideable dkim registry - overrideableDkim = new UserOverrideableDKIMRegistry(deployer, deployer); - overrideableDkim.setDKIMPublicKeyHash( - domainName, - publicKeyHash, - deployer, - new bytes(0) - ); + // Create userOverrideable dkim registry implementation + overrideableDkimImpl = new UserOverrideableDKIMRegistry(); + // { + // UserOverrideableDKIMRegistry overrideableDkimImpl = new UserOverrideableDKIMRegistry(); + // ERC1967Proxy overrideableDkimProxy = new ERC1967Proxy( + // address(overrideableDkimImpl), + // abi.encodeCall( + // overrideableDkimImpl.initialize, + // (deployer, signer, setTimestampDelay) + // ) + // ); + // overrideableDkim = UserOverrideableDKIMRegistry( + // address(overrideableDkimProxy) + // ); + // } + // overrideableDkim.setDKIMPublicKeyHash( + // domainName, + // publicKeyHash, + // deployer, + // new bytes(0) + // ); // Create Verifier { @@ -101,9 +117,13 @@ contract DeploymentHelper is Test { "Verifier implementation deployed at: %s", address(verifierImpl) ); + Groth16Verifier groth16Verifier = new Groth16Verifier(); ERC1967Proxy verifierProxy = new ERC1967Proxy( address(verifierImpl), - abi.encodeCall(verifierImpl.initialize, (msg.sender)) + abi.encodeCall( + verifierImpl.initialize, + (msg.sender, address(groth16Verifier)) + ) ); verifier = Verifier(address(verifierProxy)); } @@ -115,8 +135,8 @@ contract DeploymentHelper is Test { uint templateIdx = 0; templateId = uint256(keccak256(abi.encodePacked("TEST", templateIdx))); - subjectTemplate = ["Send", "{decimals}", "ETH", "to", "{ethAddr}"]; - newSubjectTemplate = ["Send", "{decimals}", "USDC", "to", "{ethAddr}"]; + commandTemplate = ["Send", "{decimals}", "ETH", "to", "{ethAddr}"]; + newCommandTemplate = ["Send", "{decimals}", "USDC", "to", "{ethAddr}"]; // Create RecoveryController as EmailAccountRecovery implementation RecoveryController recoveryControllerImpl = new RecoveryController(); @@ -136,7 +156,6 @@ contract DeploymentHelper is Test { payable(address(recoveryControllerProxy)) ); - // Create SimpleWallet simpleWalletImpl = new SimpleWallet(); address recoveryControllerAddress = address(recoveryController); @@ -156,7 +175,8 @@ contract DeploymentHelper is Test { // address(verifier), // address(dkim), // address(emailAuthImpl), - // address(factoryImpl) + // address(factoryImpl), + // proxyBytecodeHash // ) // ) // ); @@ -209,4 +229,19 @@ contract DeploymentHelper is Test { vm.skip(false); } } + + function resetEnviromentVariables() public { + vm.setEnv("PRIVATE_KEY", vm.toString(uint256(0))); + vm.setEnv("INITIAL_OWNER", vm.toString(uint256(0))); + vm.setEnv("DKIM_SIGNER", vm.toString(address(0))); + vm.setEnv("DKIM", vm.toString(address(0))); + vm.setEnv("DKIM_DELAY", vm.toString(uint256(0))); + vm.setEnv("ECDSA_DKIM", vm.toString(address(0))); + vm.setEnv("VERIFIER", vm.toString(address(0))); + vm.setEnv("EMAIL_AUTH_IMPL", vm.toString(address(0))); + vm.setEnv("RECOVERY_CONTROLLER", vm.toString(address(0))); + vm.setEnv("RECOVERY_CONTROLLER_ZKSYNC", vm.toString(address(0))); + vm.setEnv("ZKSYNC_CREATE2_FACTORY", vm.toString(address(0))); + vm.setEnv("SIMPLE_WALLET", vm.toString(address(0))); + } } diff --git a/packages/contracts/test/helpers/RecoveryController.sol b/packages/contracts/test/helpers/RecoveryController.sol index 725bca68..a73e5b7e 100644 --- a/packages/contracts/test/helpers/RecoveryController.sol +++ b/packages/contracts/test/helpers/RecoveryController.sol @@ -22,12 +22,6 @@ contract RecoveryController is OwnableUpgradeable, EmailAccountRecovery { mapping(address => uint) public timelockPeriodOfAccount; mapping(address => uint) public currentTimelockOfAccount; - // modifier onlyNotRecoveringOwner() { - // require(msg.sender == owner(), "only owner"); - // require(!isRecovering, "recovery in progress"); - // _; - // } - constructor() {} function initialize( @@ -48,7 +42,7 @@ contract RecoveryController is OwnableUpgradeable, EmailAccountRecovery { return isActivatedOfAccount[recoveredAccount]; } - function acceptanceSubjectTemplates() + function acceptanceCommandTemplates() public pure override @@ -64,7 +58,7 @@ contract RecoveryController is OwnableUpgradeable, EmailAccountRecovery { return templates; } - function recoverySubjectTemplates() + function recoveryCommandTemplates() public pure override @@ -83,22 +77,22 @@ contract RecoveryController is OwnableUpgradeable, EmailAccountRecovery { return templates; } - function extractRecoveredAccountFromAcceptanceSubject( - bytes[] memory subjectParams, + function extractRecoveredAccountFromAcceptanceCommand( + bytes[] memory commandParams, uint templateIdx ) public pure override returns (address) { require(templateIdx == 0, "invalid template index"); - require(subjectParams.length == 1, "invalid subject params"); - return abi.decode(subjectParams[0], (address)); + require(commandParams.length == 1, "invalid command params"); + return abi.decode(commandParams[0], (address)); } - function extractRecoveredAccountFromRecoverySubject( - bytes[] memory subjectParams, + function extractRecoveredAccountFromRecoveryCommand( + bytes[] memory commandParams, uint templateIdx ) public pure override returns (address) { require(templateIdx == 0, "invalid template index"); - require(subjectParams.length == 2, "invalid subject params"); - return abi.decode(subjectParams[0], (address)); + require(commandParams.length == 2, "invalid command params"); + return abi.decode(commandParams[0], (address)); } function requestGuardian(address guardian) public { @@ -122,10 +116,10 @@ contract RecoveryController is OwnableUpgradeable, EmailAccountRecovery { function acceptGuardian( address guardian, uint templateIdx, - bytes[] memory subjectParams, + bytes[] memory commandParams, bytes32 ) internal override { - address account = abi.decode(subjectParams[0], (address)); + address account = abi.decode(commandParams[0], (address)); require(!isRecovering[account], "recovery in progress"); require(guardian != address(0), "invalid guardian"); @@ -134,17 +128,17 @@ contract RecoveryController is OwnableUpgradeable, EmailAccountRecovery { "guardian status must be REQUESTED" ); require(templateIdx == 0, "invalid template index"); - require(subjectParams.length == 1, "invalid subject params"); + require(commandParams.length == 1, "invalid command params"); guardians[guardian] = GuardianStatus.ACCEPTED; } function processRecovery( address guardian, uint templateIdx, - bytes[] memory subjectParams, + bytes[] memory commandParams, bytes32 ) internal override { - address account = abi.decode(subjectParams[0], (address)); + address account = abi.decode(commandParams[0], (address)); require(!isRecovering[account], "recovery in progress"); require(guardian != address(0), "invalid guardian"); require( @@ -152,8 +146,8 @@ contract RecoveryController is OwnableUpgradeable, EmailAccountRecovery { "guardian status must be ACCEPTED" ); require(templateIdx == 0, "invalid template index"); - require(subjectParams.length == 2, "invalid subject params"); - address newSignerInEmail = abi.decode(subjectParams[1], (address)); + require(commandParams.length == 2, "invalid command params"); + address newSignerInEmail = abi.decode(commandParams[1], (address)); require(newSignerInEmail != address(0), "invalid new signer"); isRecovering[account] = true; newSignerCandidateOfAccount[account] = newSignerInEmail; diff --git a/packages/contracts/test/helpers/RecoveryControllerZKSync.sol b/packages/contracts/test/helpers/RecoveryControllerZKSync.sol index f9a7a67c..9f7714d9 100644 --- a/packages/contracts/test/helpers/RecoveryControllerZKSync.sol +++ b/packages/contracts/test/helpers/RecoveryControllerZKSync.sol @@ -6,7 +6,10 @@ import {EmailAccountRecoveryZKSync} from "../../src/EmailAccountRecoveryZKSync.s import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import {SimpleWallet} from "./SimpleWallet.sol"; -contract RecoveryControllerZKSync is OwnableUpgradeable, EmailAccountRecoveryZKSync { +contract RecoveryControllerZKSync is + OwnableUpgradeable, + EmailAccountRecoveryZKSync +{ enum GuardianStatus { NONE, REQUESTED, @@ -34,13 +37,15 @@ contract RecoveryControllerZKSync is OwnableUpgradeable, EmailAccountRecoveryZKS address _verifier, address _dkim, address _emailAuthImplementation, - address _factory + address _factory, + bytes32 _proxyBytecodeHash ) public initializer { __Ownable_init(_initialOwner); verifierAddr = _verifier; dkimAddr = _dkim; emailAuthImplementationAddr = _emailAuthImplementation; factoryAddr = _factory; + proxyBytecodeHash = _proxyBytecodeHash; } function isActivated( @@ -49,7 +54,7 @@ contract RecoveryControllerZKSync is OwnableUpgradeable, EmailAccountRecoveryZKS return isActivatedOfAccount[recoveredAccount]; } - function acceptanceSubjectTemplates() + function acceptanceCommandTemplates() public pure override @@ -65,7 +70,7 @@ contract RecoveryControllerZKSync is OwnableUpgradeable, EmailAccountRecoveryZKS return templates; } - function recoverySubjectTemplates() + function recoveryCommandTemplates() public pure override @@ -84,22 +89,22 @@ contract RecoveryControllerZKSync is OwnableUpgradeable, EmailAccountRecoveryZKS return templates; } - function extractRecoveredAccountFromAcceptanceSubject( - bytes[] memory subjectParams, + function extractRecoveredAccountFromAcceptanceCommand( + bytes[] memory commandParams, uint templateIdx ) public pure override returns (address) { require(templateIdx == 0, "invalid template index"); - require(subjectParams.length == 1, "invalid subject params"); - return abi.decode(subjectParams[0], (address)); + require(commandParams.length == 1, "invalid command params"); + return abi.decode(commandParams[0], (address)); } - function extractRecoveredAccountFromRecoverySubject( - bytes[] memory subjectParams, + function extractRecoveredAccountFromRecoveryCommand( + bytes[] memory commandParams, uint templateIdx ) public pure override returns (address) { require(templateIdx == 0, "invalid template index"); - require(subjectParams.length == 2, "invalid subject params"); - return abi.decode(subjectParams[0], (address)); + require(commandParams.length == 2, "invalid command params"); + return abi.decode(commandParams[0], (address)); } function requestGuardian(address guardian) public { @@ -123,10 +128,10 @@ contract RecoveryControllerZKSync is OwnableUpgradeable, EmailAccountRecoveryZKS function acceptGuardian( address guardian, uint templateIdx, - bytes[] memory subjectParams, + bytes[] memory commandParams, bytes32 ) internal override { - address account = abi.decode(subjectParams[0], (address)); + address account = abi.decode(commandParams[0], (address)); require(!isRecovering[account], "recovery in progress"); require(guardian != address(0), "invalid guardian"); @@ -135,17 +140,17 @@ contract RecoveryControllerZKSync is OwnableUpgradeable, EmailAccountRecoveryZKS "guardian status must be REQUESTED" ); require(templateIdx == 0, "invalid template index"); - require(subjectParams.length == 1, "invalid subject params"); + require(commandParams.length == 1, "invalid command params"); guardians[guardian] = GuardianStatus.ACCEPTED; } function processRecovery( address guardian, uint templateIdx, - bytes[] memory subjectParams, + bytes[] memory commandParams, bytes32 ) internal override { - address account = abi.decode(subjectParams[0], (address)); + address account = abi.decode(commandParams[0], (address)); require(!isRecovering[account], "recovery in progress"); require(guardian != address(0), "invalid guardian"); require( @@ -153,8 +158,8 @@ contract RecoveryControllerZKSync is OwnableUpgradeable, EmailAccountRecoveryZKS "guardian status must be ACCEPTED" ); require(templateIdx == 0, "invalid template index"); - require(subjectParams.length == 2, "invalid subject params"); - address newSignerInEmail = abi.decode(subjectParams[1], (address)); + require(commandParams.length == 2, "invalid command params"); + address newSignerInEmail = abi.decode(commandParams[1], (address)); require(newSignerInEmail != address(0), "invalid new signer"); isRecovering[account] = true; newSignerCandidateOfAccount[account] = newSignerInEmail; diff --git a/packages/contracts/test/helpers/SimpleWallet.sol b/packages/contracts/test/helpers/SimpleWallet.sol index 27678ebb..2e0be982 100644 --- a/packages/contracts/test/helpers/SimpleWallet.sol +++ b/packages/contracts/test/helpers/SimpleWallet.sol @@ -4,8 +4,12 @@ pragma solidity ^0.8.12; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import {RecoveryController} from "./RecoveryController.sol"; +import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol"; +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; + +contract SimpleWallet is OwnableUpgradeable, IERC1271 { + using ECDSA for *; -contract SimpleWallet is OwnableUpgradeable { enum GuardianStatus { NONE, REQUESTED, @@ -49,4 +53,24 @@ contract SimpleWallet is OwnableUpgradeable { ); _transferOwnership(newOwner); } + + function requestGuardian(address guardian) public { + require(msg.sender == owner(), "only owner"); + RecoveryController(recoveryController).requestGuardian(guardian); + } + + /** + * @notice Verifies that the signer is the owner of the signing contract. + */ + function isValidSignature( + bytes32 _hash, + bytes calldata _signature + ) external view override returns (bytes4) { + // Validate signatures + if (_hash.recover(_signature) == owner()) { + return 0x1626ba7e; + } else { + return 0xffffffff; + } + } } diff --git a/packages/contracts/test/helpers/StructHelper.sol b/packages/contracts/test/helpers/StructHelper.sol index cae1eb2f..e8c75761 100644 --- a/packages/contracts/test/helpers/StructHelper.sol +++ b/packages/contracts/test/helpers/StructHelper.sol @@ -8,9 +8,9 @@ contract StructHelper is DeploymentHelper { public returns (EmailAuthMsg memory emailAuthMsg) { - bytes[] memory subjectParams = new bytes[](2); - subjectParams[0] = abi.encode(1 ether); - subjectParams[1] = abi.encode( + bytes[] memory commandParams = new bytes[](2); + commandParams[0] = abi.encode(1 ether); + commandParams[1] = abi.encode( "0x0000000000000000000000000000000000000020" ); @@ -18,7 +18,7 @@ contract StructHelper is DeploymentHelper { domainName: "gmail.com", publicKeyHash: publicKeyHash, timestamp: 1694989812, - maskedSubject: "Send 1 ETH to 0x0000000000000000000000000000000000000020", + maskedCommand: "Send 1 ETH to 0x0000000000000000000000000000000000000020", emailNullifier: emailNullifier, accountSalt: accountSalt, isCodeExist: true, @@ -27,8 +27,8 @@ contract StructHelper is DeploymentHelper { emailAuthMsg = EmailAuthMsg({ templateId: templateId, - subjectParams: subjectParams, - skipedSubjectPrefix: 0, + commandParams: commandParams, + skippedCommandPrefix: 0, proof: emailProof }); diff --git a/packages/contracts/test/libraries/StringUtils/StringUtils_hexToBytes.t.sol b/packages/contracts/test/libraries/StringUtils/StringUtils_hexToBytes.t.sol new file mode 100644 index 00000000..828f4f6d --- /dev/null +++ b/packages/contracts/test/libraries/StringUtils/StringUtils_hexToBytes.t.sol @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import {StringUtils} from "src/libraries/StringUtils.sol"; +import {StructHelper} from "../../helpers/StructHelper.sol"; + +contract StringUtils_HexToBytes_Test is StructHelper { + function setUp() public override { + super.setUp(); + } + + function test_HexToBytes_RevertWhen_InvalidHexPrefix() public { + string memory bytesStringNoHexPrefix = "509d286573e85f37b51f178c1"; + + vm.expectRevert("invalid hex prefix"); + StringUtils.hexToBytes(bytesStringNoHexPrefix); + } + + function test_HexToBytes_RevertWhen_InvalidHexPrefix_EmptyString() public { + string memory emptyString = ""; + + vm.expectRevert("invalid hex prefix"); + StringUtils.hexToBytes(emptyString); + } + + function test_HexToBytes_RevertWhen_InvalidHexPrefix_Zero() public { + string memory shortBytesString = "0"; + + vm.expectRevert("invalid hex prefix"); + StringUtils.hexToBytes(shortBytesString); + } + + function test_HexToBytes_RevertWhen_IncorrectPrefix_CapitalLetter() public { + string + memory invalidPrefixBytesString = "0X509d376452ba746b093a149f9d733c145539771d"; + + vm.expectRevert("invalid hex prefix"); + StringUtils.hexToBytes(invalidPrefixBytesString); + } + + function test_HexToBytes_RevertWhen_InvalidHexPrefix_LeadingWhitespace() + public + { + string + memory bytesString = " 0x509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145746b093a149f9d733c1539771d"; + + vm.expectRevert("invalid hex prefix"); + StringUtils.hexToBytes(bytesString); + } + + function test_HexToBytes_RevertWhen_InvalidHexStringLength_TrailingWhitespace() + public + { + string + memory bytesString = "0x509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c1455d286573e85f37b51f178c1cf8376452ba746b093Ca149f9d733c145539771d "; + + vm.expectRevert("invalid hex string length"); + StringUtils.hexToBytes(bytesString); + } + + function test_HexToBytes_RevertWhen_InvalidHexStringLength_ZeroShortBytes() + public + { + string memory shortBytesString = "0x"; + vm.expectRevert("invalid hex string length"); + StringUtils.hexToBytes(shortBytesString); + } + + function test_HexToBytes_RevertWhen_InvalidHexStringLength_TooHigh() + public + { + string + memory invalidBytesString = "0x509D286573e85F37b51F178c1cf8376452ba746b093A149f9d733c145539771dd"; // extra character + + vm.expectRevert("invalid hex string length"); + StringUtils.hexToBytes(invalidBytesString); + } + + function test_HexToBytes_RevertWhen_InvalidHexStringLength_TooLow() public { + // hardcoded bytes memory value with final character removed + string + memory shortBytesString = "0xdbc39d6cd28b2a38b8af5d4892c194bea383af28e55e7430d26474150280f15"; + + vm.expectRevert("invalid hex string length"); + StringUtils.hexToBytes(shortBytesString); + } + + function test_HexToBytes_RevertWhen_InvalidHexChar_SingleNonHexChar() + public + { + string + memory invalidContentBytesString = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdeG"; // G + + vm.expectRevert("invalid hex char"); + StringUtils.hexToBytes(invalidContentBytesString); + } + + function test_HexToBytes_RevertWhen_InvalidHexChar() public { + string + memory invalidBytesString = "0x509d2865zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"; + + vm.expectRevert("invalid hex char"); + StringUtils.hexToBytes(invalidBytesString); + } + + function test_HexToBytes_SucceedsWhen_LongerInput() public { + bytes memory expectedBytes = abi.encodePacked( + hex"509d286573e85f37b51f178c1cf8376452509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d509d286573e85f37b51f178c1cf837509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d509d286573e85f37b51f178c1cf837509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d509d286573e85f37b51f178c1cf837ba746b093a149f9d733c145539771d509d286573e85509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d509d286573e85f37b51f178c1cf837f37b509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d509d286573e85f37b51f178c1cf83751f178c1cf837509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d509d286573e85f37b51f178c1cf83764" + ); + string + memory longBytesString = "0x509d286573e85f37b51f178c1cf8376452509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d509d286573e85f37b51f178c1cf837509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d509d286573e85f37b51f178c1cf837509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d509d286573e85f37b51f178c1cf837ba746b093a149f9d733c145539771d509d286573e85509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d509d286573e85f37b51f178c1cf837f37b509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d509d286573e85f37b51f178c1cf83751f178c1cf837509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d509d286573e85f37b51f178c1cf83764"; + + bytes memory bytesResult = StringUtils.hexToBytes(longBytesString); + + assertEq(bytesResult, expectedBytes); + } + + function test_HexToBytes_SucceesWhen_SingleCapitalLetter() public { + // hardcoded bytes memory value with final character capitalized + bytes memory expectedBytes = abi.encodePacked( + hex"509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771D" + ); + string + memory bytesString = "0x509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771D"; + + bytes memory result = StringUtils.hexToBytes(bytesString); + + assertEq(result, expectedBytes); + } + + function test_HexToBytes_SucceedsWhen_MixedCaseHex() public { + bytes memory expectedMixedCaseBytes = abi.encodePacked( + hex"509D286573e85F37b51F178c1cf8376452ba746b093A149f9d733c145539771d" + ); + string + memory mixedCaseString = "0x509D286573e85F37b51F178c1cf8376452ba746b093A149f9d733c145539771d"; + + bytes memory result = StringUtils.hexToBytes(mixedCaseString); + + assertEq(result, expectedMixedCaseBytes); + } + + function test_HexToBytes_ConvertsZeroBytes() public pure { + bytes memory zeroBytes = abi.encodePacked( + hex"0000000000000000000000000000000000000000000000000000000000000000" + ); + string + memory invalidBytesString = "0x0000000000000000000000000000000000000000000000000000000000000000"; + + bytes memory result = StringUtils.hexToBytes(invalidBytesString); + + assertEq(result, zeroBytes); + } + + function test_hexToBytes_ComputesExpectedBytes() public pure { + bytes memory expectedBytes1 = abi.encodePacked(hex"509d"); + bytes memory expectedBytes2 = abi.encodePacked( + hex"a2baeb0f5a80b8f086147ffc05236f2d243357d9240c080a821b2aa987cb150c" + ); + bytes memory expectedBytes3 = abi.encodePacked( + hex"ac276f708bfba694fe2f7bfdc52e6b158a612c72f88a72bddacdfb33f190e9b9ac276f708bfba694fe2f7bfdc52e6b158a612c72f88a72bddacdfb33f190e9b9" + ); + string memory bytesString1 = "0x509d"; + string + memory bytesString2 = "0xa2baeb0f5a80b8f086147ffc05236f2d243357d9240c080a821b2aa987cb150c"; + string + memory bytesString3 = "0xac276f708bfba694fe2f7bfdc52e6b158a612c72f88a72bddacdfb33f190e9b9ac276f708bfba694fe2f7bfdc52e6b158a612c72f88a72bddacdfb33f190e9b9"; + + bytes memory bytesResult1 = StringUtils.hexToBytes(bytesString1); + bytes memory bytesResult2 = StringUtils.hexToBytes(bytesString2); + bytes memory bytesResult3 = StringUtils.hexToBytes(bytesString3); + + assertEq(bytesResult1, expectedBytes1); + assertEq(bytesResult2, expectedBytes2); + assertEq(bytesResult3, expectedBytes3); + } + + function test_hexToBytes_ComputesExpectedAddressBytes() public pure { + address addressToBytes1 = 0x0000000000000000000000000000000000000001; + address addressToBytes2 = 0xF9c73EedAd50dC6de889450c6469F4BA78a826dd; + address addressToBytes3 = 0x328809Bc894f92807417D2dAD6b7C998c1aFdac6; + bytes memory expectedBytes1 = abi.encodePacked(addressToBytes1); + bytes memory expectedBytes2 = abi.encodePacked(addressToBytes2); + bytes memory expectedBytes3 = abi.encodePacked(addressToBytes3); + string + memory bytesString1 = "0x0000000000000000000000000000000000000001"; + string + memory bytesString2 = "0xf9c73eedad50dc6de889450c6469f4ba78a826dd"; + string + memory bytesString3 = "0x328809bc894f92807417d2dad6b7c998c1afdac6"; + + bytes memory bytesResult1 = StringUtils.hexToBytes(bytesString1); + bytes memory bytesResult2 = StringUtils.hexToBytes(bytesString2); + bytes memory bytesResult3 = StringUtils.hexToBytes(bytesString3); + + assertEq(bytesResult1, expectedBytes1); + assertEq(bytesResult2, expectedBytes2); + assertEq(bytesResult3, expectedBytes3); + } + + function test_hexToBytes_ComputesExpectedCalldataBytes() public view { + address owner = 0xCe9A87013DB006Dde79E7382bf48D45bF891e90D; + address newOwner = 0x63aaF092604406C03E5B36ca1bEc1CDDF4a5Fa9d; + address account = 0xF4F7b3D8e43a41833774CD6d962D10282f806017; + address validator = 0x756e0562323ADcDA4430d6cb456d9151f605290B; + + bytes memory calldata1 = abi.encodeWithSignature( + "swapOwner(address,address,address)", + address(1), + owner, + newOwner + ); + bytes memory recoveryData1 = abi.encode(account, calldata1); + bytes memory recoveryDataBytes1 = recoveryData1; + + bytes memory calldata2 = abi.encodeWithSignature( + "changeOwner(address)", + newOwner + ); + bytes memory recoveryData2 = abi.encode(validator, calldata2); + bytes memory recoveryDataBytes2 = recoveryData2; + + string + memory bytesString1 = "0x000000000000000000000000f4f7b3d8e43a41833774cd6d962d10282f80601700000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064e318b52b0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000ce9a87013db006dde79e7382bf48d45bf891e90d00000000000000000000000063aaf092604406c03e5b36ca1bec1cddf4a5fa9d00000000000000000000000000000000000000000000000000000000"; + string + memory bytesString2 = "0x000000000000000000000000756e0562323adcda4430d6cb456d9151f605290b00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000024a6f9dae100000000000000000000000063aaf092604406c03e5b36ca1bec1cddf4a5fa9d00000000000000000000000000000000000000000000000000000000"; + + bytes memory bytesResult1 = StringUtils.hexToBytes(bytesString1); + bytes memory bytesResult2 = StringUtils.hexToBytes(bytesString2); + + assertEq(bytesResult1, recoveryDataBytes1); + assertEq(bytesResult2, recoveryDataBytes2); + } + + function test_HexToBytes_MaximumValue() public pure { + bytes memory maxBytes32 = bytes( + hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + ); + string + memory maxBytesString = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + + bytes memory result = StringUtils.hexToBytes(maxBytesString); + + assertEq(result, maxBytes32); + } +} diff --git a/packages/contracts/test/libraries/StringUtils/StringUtils_hexToBytes32.t.sol b/packages/contracts/test/libraries/StringUtils/StringUtils_hexToBytes32.t.sol new file mode 100644 index 00000000..7f51acec --- /dev/null +++ b/packages/contracts/test/libraries/StringUtils/StringUtils_hexToBytes32.t.sol @@ -0,0 +1,252 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import {StringUtils} from "src/libraries/StringUtils.sol"; +import {StructHelper} from "../../helpers/StructHelper.sol"; + +contract StringUtils_HexToBytes32_Test is StructHelper { + function setUp() public override { + super.setUp(); + } + + function test_HexToBytes32_RevertWhen_InvalidHexPrefix() public { + string + memory invalidPrefixHashString = "509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d"; + + vm.expectRevert("invalid hex prefix"); + StringUtils.hexToBytes32(invalidPrefixHashString); + } + + function test_HexToBytes32_RevertWhen_InvalidHexPrefix_EmptyString() + public + { + string memory emptyString = ""; + + vm.expectRevert("invalid hex prefix"); + StringUtils.hexToBytes32(emptyString); + } + + function test_HexToBytes32_RevertWhen_InvalidHexPrefix_Zero() public { + string memory shortHashString = "0"; + + vm.expectRevert("invalid hex prefix"); + StringUtils.hexToBytes32(shortHashString); + } + + function test_HexToBytes32_RevertWhen_IncorrectPrefix_CapitalLetter() + public + { + string + memory invalidPrefixHashString = "0X509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d"; + + vm.expectRevert("invalid hex prefix"); + StringUtils.hexToBytes32(invalidPrefixHashString); + } + + function test_HexToBytes32_RevertWhen_InvalidHexPrefix_LeadingWhitespace() + public + { + string + memory hashString = " 0x509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d"; + + vm.expectRevert("invalid hex prefix"); + StringUtils.hexToBytes32(hashString); + } + + function test_HexToBytes32_RevertWhen_InvalidHexStringLength_TrailingWhitespace() + public + { + string + memory hashString = "0x509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d "; + + vm.expectRevert("invalid hex string length"); + StringUtils.hexToBytes32(hashString); + } + + function test_HexToBytes32_RevertWhen_InvalidHexStringLength_ZeroBytes() + public + { + string memory shortHashString = "0x"; + + vm.expectRevert("invalid hex string length"); + StringUtils.hexToBytes32(shortHashString); + } + + function test_HexToBytes32_RevertWhen_InvalidHexStringLength_ZeroShortBytes() + public + { + string memory shortHashString = "0x00"; + + vm.expectRevert("bytes length is not 32"); + StringUtils.hexToBytes32(shortHashString); + } + + function test_HexToBytes32_RevertWhen_InvalidHexStringLength_TooHigh() + public + { + string memory stringToHash = "I'm a test string"; + bytes32 expectedHash = keccak256(abi.encodePacked(stringToHash)); + string + memory invalidHashString = "0x00dbc39d6cd28b2a38b8af5d4892c194bea383af28e55e7430d26474150280f15e"; + + vm.expectRevert("bytes length is not 32"); + StringUtils.hexToBytes32(invalidHashString); + } + + function test_HexToBytes32_RevertWhen_InvalidHexStringLength_VeryLongInput() + public + { + string + memory longHashString = "0x509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d509d286573e85f37b51f178c1cf83764"; + + vm.expectRevert("bytes length is not 32"); + StringUtils.hexToBytes32(longHashString); + } + + function test_HexToBytes32_RevertWhen_InvalidHexStringLength_TooLow() + public + { + // hardcoded bytes32 value with final character removed + string + memory shortHashString = "0xdbc39d6cd28b2a38b8af5d4892c194bea383af28e55e7430d26474150280f15"; + + vm.expectRevert("invalid hex string length"); + StringUtils.hexToBytes32(shortHashString); + } + + function test_HexToBytes32_RevertWhen_InvalidHexChar_SingleNonHexChar() + public + { + string + memory invalidContentHashString = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdeG"; // G + + vm.expectRevert("invalid hex char"); + StringUtils.hexToBytes32(invalidContentHashString); + } + + function test_HexToBytes32_RevertWhen_InvalidHexChar() public { + string + memory invalidHashString = "0x509d2865zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"; + + vm.expectRevert("invalid hex char"); + StringUtils.hexToBytes32(invalidHashString); + } + + function test_HexToBytes32_SucceedsWhen_MixedCaseHex() public { + bytes32 expectedMixedCaseHash = 0x509D286573e85F37b51F178c1cf8376452ba746b093A149f9d733c145539771d; + string + memory mixedCaseHashString = "0x509D286573e85F37b51F178c1cf8376452ba746b093A149f9d733c145539771d"; + + bytes32 result = StringUtils.hexToBytes32(mixedCaseHashString); + + assertEq(result, expectedMixedCaseHash); + } + + function test_HexToBytes32_SucceedsWhen_SingleCapitalLetter() public { + // hardcoded bytes32 value with final character capitalized + bytes32 expectedHash = 0x509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771D; + string + memory hashString = "0x509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771D"; + + bytes32 result = StringUtils.hexToBytes32(hashString); + + assertEq(result, expectedHash); + } + + function test_HexToBytes32_ConvertsZeroHash() public pure { + bytes32 zeroHash = bytes32(0); + string + memory invalidHashString = "0x0000000000000000000000000000000000000000000000000000000000000000"; + bytes32 result = StringUtils.hexToBytes32(invalidHashString); + assertEq(result, zeroHash); + } + + function test_hexToBytes32_ComputesExpectedHash() public pure { + bytes32 expectedHash1 = 0x509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d; + bytes32 expectedHash2 = 0xa2baeb0f5a80b8f086147ffc05236f2d243357d9240c080a821b2aa987cb150c; + bytes32 expectedHash3 = 0xac276f708bfba694fe2f7bfdc52e6b158a612c72f88a72bddacdfb33f190e9b9; + string + memory hashString1 = "0x509d286573e85f37b51f178c1cf8376452ba746b093a149f9d733c145539771d"; + string + memory hashString2 = "0xa2baeb0f5a80b8f086147ffc05236f2d243357d9240c080a821b2aa987cb150c"; + string + memory hashString3 = "0xac276f708bfba694fe2f7bfdc52e6b158a612c72f88a72bddacdfb33f190e9b9"; + + bytes32 hashResult1 = StringUtils.hexToBytes32(hashString1); + bytes32 hashResult2 = StringUtils.hexToBytes32(hashString2); + bytes32 hashResult3 = StringUtils.hexToBytes32(hashString3); + + assertEq(hashResult1, expectedHash1); + assertEq(hashResult2, expectedHash2); + assertEq(hashResult3, expectedHash3); + } + + function test_hexToBytes32_ComputesExpectedAddressHash() public pure { + address addressToHash1 = 0x0000000000000000000000000000000000000001; + address addressToHash2 = 0xF9c73EedAd50dC6de889450c6469F4BA78a826dd; + address addressToHash3 = 0x328809Bc894f92807417D2dAD6b7C998c1aFdac6; + bytes32 expectedHash1 = keccak256(abi.encodePacked(addressToHash1)); + bytes32 expectedHash2 = keccak256(abi.encodePacked(addressToHash2)); + bytes32 expectedHash3 = keccak256(abi.encodePacked(addressToHash3)); + string + memory hashString1 = "0x1468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d"; + string + memory hashString2 = "0x74f5064398929fa4a58c46b60031ae3e0788e7e2e9294b06e0a82978f22ad502"; + string + memory hashString3 = "0x72d7a3f1e9fa3953b9dfa6828dd4d4068abbe2041e121a61f102e1f7f9603d2a"; + + bytes32 hashResult1 = StringUtils.hexToBytes32(hashString1); + bytes32 hashResult2 = StringUtils.hexToBytes32(hashString2); + bytes32 hashResult3 = StringUtils.hexToBytes32(hashString3); + + assertEq(hashResult1, expectedHash1); + assertEq(hashResult2, expectedHash2); + assertEq(hashResult3, expectedHash3); + } + + function test_hexToBytes32_ComputesExpectedCalldataHash() public view { + address owner = 0xCe9A87013DB006Dde79E7382bf48D45bF891e90D; + address newOwner = 0x63aaF092604406C03E5B36ca1bEc1CDDF4a5Fa9d; + address account = 0xF4F7b3D8e43a41833774CD6d962D10282f806017; + address validator = 0x756e0562323ADcDA4430d6cb456d9151f605290B; + + bytes memory calldata1 = abi.encodeWithSignature( + "swapOwner(address,address,address)", + address(1), + owner, + newOwner + ); + bytes memory recoveryData1 = abi.encode(account, calldata1); + bytes32 recoveryDataHash1 = keccak256(recoveryData1); + + bytes memory calldata2 = abi.encodeWithSignature( + "changeOwner(address)", + newOwner + ); + bytes memory recoveryData2 = abi.encode(validator, calldata2); + bytes32 recoveryDataHash2 = keccak256(recoveryData2); + + string + memory hashString1 = "0x268857b2318fd7eaa7e5be744cc041d64415d2df4588e3d234e7335ede6593a5"; + string + memory hashString2 = "0x6ac9d4f1b3c69064f3f728b53ed1d38c79462138b4b03d5c2838a001233b7920"; + + bytes32 hashResult1 = StringUtils.hexToBytes32(hashString1); + bytes32 hashResult2 = StringUtils.hexToBytes32(hashString2); + + assertEq(hashResult1, recoveryDataHash1); + assertEq(hashResult2, recoveryDataHash2); + } + + function test_HexToBytes32_MaximumValue() public pure { + bytes32 maxBytes32 = bytes32( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + string + memory maxHashString = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + + bytes32 result = StringUtils.hexToBytes32(maxHashString); + + assertEq(result, maxBytes32); + } +} diff --git a/packages/contracts/test/libraries/StringUtils/fuzz/StringUtils_fuzz_hexToBytes.t.sol b/packages/contracts/test/libraries/StringUtils/fuzz/StringUtils_fuzz_hexToBytes.t.sol new file mode 100644 index 00000000..eb113327 --- /dev/null +++ b/packages/contracts/test/libraries/StringUtils/fuzz/StringUtils_fuzz_hexToBytes.t.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import {StringUtils} from "src/libraries/StringUtils.sol"; +import {StructHelper} from "../../../helpers/StructHelper.sol"; + +contract StringUtils_HexToBytes_Fuzz_Test is StructHelper { + function setUp() public override { + super.setUp(); + } + + /// @notice Helper function to convert bytes to hex string for testing + function bytesToHexString( + bytes memory data + ) internal pure returns (string memory) { + bytes memory alphabet = "0123456789abcdef"; + bytes memory str = new bytes(2 + data.length * 2); + str[0] = "0"; + str[1] = "x"; + for (uint256 i = 0; i < data.length; i++) { + str[2 + i * 2] = alphabet[uint256(uint8(data[i] >> 4))]; + str[3 + i * 2] = alphabet[uint256(uint8(data[i] & 0x0f))]; + } + return string(str); + } + + function testFuzz_hexToBytes_ComputesExpectedBytes( + bytes memory expectedBytes + ) public { + vm.assume(expectedBytes.length > 0); + string memory bytesString = bytesToHexString(expectedBytes); + + if (bytes(bytesString).length % 2 != 0) { + vm.expectRevert("invalid hex string length"); + } + bytes memory bytesResult = StringUtils.hexToBytes(bytesString); + + assertEq(bytesResult, expectedBytes); + } + + function testFuzz_hexToBytes_ComputesExpectedAddressBytes( + address addressToBytes + ) public pure { + bytes memory expectedBytes = abi.encodePacked(addressToBytes); + string memory bytesString = bytesToHexString(expectedBytes); + + bytes memory bytesResult = StringUtils.hexToBytes(bytesString); + + assertEq(bytesResult, expectedBytes); + } + + function testFuzz_hexToBytes_ComputesExpectedCalldataBytes( + bytes4 selector, + address addressValue1, + address addressValue2, + bytes memory bytesValue, + uint256 uintValue + ) public { + bytes memory expectedCalldata = abi.encodeWithSelector( + selector, + addressValue1, + addressValue2, + bytesValue, + uintValue + ); + string memory bytesString = bytesToHexString(expectedCalldata); + + bytes memory bytesResult = StringUtils.hexToBytes(bytesString); + + assertEq(bytesResult, expectedCalldata); + } +} diff --git a/packages/contracts/test/libraries/StringUtils/fuzz/StringUtils_fuzz_hexToBytes32.t.sol b/packages/contracts/test/libraries/StringUtils/fuzz/StringUtils_fuzz_hexToBytes32.t.sol new file mode 100644 index 00000000..38c4fdeb --- /dev/null +++ b/packages/contracts/test/libraries/StringUtils/fuzz/StringUtils_fuzz_hexToBytes32.t.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.25; + +import { StringUtils } from "src/libraries/StringUtils.sol"; +import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; +import { StructHelper } from "../../../helpers/StructHelper.sol"; + +// Currently, tests in this contract are disabled on zkSync +// due to LLVM issues with Strings and StringUtils libraries +contract StringUtils_HexToBytes32_Fuzz_Test is StructHelper { + using Strings for uint256; + + function setUp() public override { + super.setUp(); + } + + function testFuzz_hexToBytes32_ComputesExpectedHash(bytes32 expectedHash) public { + skipIfZkSync(); + + string memory hashString = uint256(expectedHash).toHexString(32); + bytes32 hashResult = StringUtils.hexToBytes32(hashString); + + assertEq(hashResult, expectedHash); + } + + function testFuzz_hexToBytes32_ComputesExpectedAddressHash(address addressToHash) public { + skipIfZkSync(); + + bytes32 expectedHash = keccak256(abi.encodePacked(addressToHash)); + string memory hashString = uint256(expectedHash).toHexString(32); + bytes32 hashResult = StringUtils.hexToBytes32(hashString); + + assertEq(hashResult, expectedHash); + } + + function testFuzz_hexToBytes32_ComputesExpectedCalldataHash(bytes memory calldataToHash) + public + { + skipIfZkSync(); + + bytes32 expectedHash = keccak256(calldataToHash); + string memory hashString = uint256(expectedHash).toHexString(32); + + bytes32 hashResult = StringUtils.hexToBytes32(hashString); + + assertEq(hashResult, expectedHash); + } +} diff --git a/packages/contracts/test/script/ChangeOwners.t.sol b/packages/contracts/test/script/ChangeOwnersScript.t.sol similarity index 53% rename from packages/contracts/test/script/ChangeOwners.t.sol rename to packages/contracts/test/script/ChangeOwnersScript.t.sol index dcbe183f..13743a1f 100644 --- a/packages/contracts/test/script/ChangeOwners.t.sol +++ b/packages/contracts/test/script/ChangeOwnersScript.t.sol @@ -4,19 +4,24 @@ pragma solidity ^0.8.12; import "forge-std/Test.sol"; import "forge-std/console.sol"; -import {Deploy} from "../../script/DeployCommons.s.sol"; -import {Deploy as Deploy2} from "../../script/DeployForwardDKIMRegistry.s.sol"; +import {Deploy} from "../../script/DeployRecoveryController.s.sol"; import {ChangeOwners} from "../../script/ChangeOwners.s.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import {StructHelper} from "../helpers/StructHelper.sol"; -contract ChangeOwnersTest is StructHelper { +contract ChangeOwnersScriptTest is StructHelper { function setUp() public override { + resetEnviromentVariables(); + super.setUp(); vm.setEnv( "PRIVATE_KEY", - "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" + "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d" + ); + vm.setEnv("DKIM_SIGNER", "0x69bec2dd161d6bbcc91ec32aa44d9333ebc864c0"); + vm.setEnv( + "INITIAL_OWNER", + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" ); - vm.setEnv("SIGNER", "0x69bec2dd161d6bbcc91ec32aa44d9333ebc864c0"); vm.setEnv("NEW_OWNER", "0xa1bec2dd161d6bbcc91ec32aa44d9333e2a864c0"); } @@ -25,9 +30,21 @@ contract ChangeOwnersTest is StructHelper { Deploy deploy = new Deploy(); deploy.run(); - vm.setEnv("SOURCE_DKIM", vm.toString(vm.envAddress("ECDSA_DKIM"))); - Deploy2 deploy2 = new Deploy2(); - deploy2.run(); + vm.setEnv("DKIM", "0x71C95911E9a5D330f4D621842EC243EE1343292e"); + vm.setEnv("VERIFIER", "0xbCF26943C0197d2eE0E5D05c716Be60cc2761508"); + vm.setEnv( + "EMAIL_AUTH_IMPL", + "0x59F2f1fCfE2474fD5F0b9BA1E73ca90b143Eb8d0" + ); + vm.setEnv( + "RECOVERY_CONTROLLER", + "0x1275D096B9DBf2347bD2a131Fb6BDaB0B4882487" + ); + deploy.deployECDSAOwnedDKIMRegistry( + vm.envAddress("INITIAL_OWNER"), + vm.envAddress("DKIM_SIGNER") + ); + vm.setEnv("ECDSA_DKIM", "0x037eDa3aDB1198021A9b2e88C22B464fD38db3f3"); ChangeOwners changeOwners = new ChangeOwners(); changeOwners.run(); address verifier = vm.envAddress("VERIFIER"); diff --git a/packages/contracts/test/script/ChangeSignerInECDSAOwnedDKIMRegistry.t.sol b/packages/contracts/test/script/ChangeSignerInECDSAOwnedDKIMRegistry.t.sol deleted file mode 100644 index 26bc8797..00000000 --- a/packages/contracts/test/script/ChangeSignerInECDSAOwnedDKIMRegistry.t.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.12; - -import "forge-std/Test.sol"; -import "forge-std/console.sol"; - -import {Deploy} from "../../script/DeployCommons.s.sol"; -import {ChangeSigner} from "../../script/ChangeSignerInECDSAOwnedDKIMRegistry.s.sol"; -import {ECDSAOwnedDKIMRegistry} from "../../src/utils/ECDSAOwnedDKIMRegistry.sol"; -import {StructHelper} from "../helpers/StructHelper.sol"; - -contract ChangeSignerInECDSAOwnedDKIMRegistryTest is StructHelper { - function setUp() public override { - vm.setEnv( - "PRIVATE_KEY", - "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" - ); - vm.setEnv("SIGNER", "0x69bec2dd161d6bbcc91ec32aa44d9333ebc864c0"); - vm.setEnv("NEW_SIGNER", "0xa1bec2dd161d6bbcc91ec32aa44d9333e2a864c0"); - } - - function test_run() public { - skipIfZkSync(); - - Deploy deploy = new Deploy(); - deploy.run(); - ChangeSigner changeSigner = new ChangeSigner(); - changeSigner.run(); - address ecdsaDkimAddr = vm.envAddress("ECDSA_DKIM"); - ECDSAOwnedDKIMRegistry ecdsaDkim = ECDSAOwnedDKIMRegistry( - ecdsaDkimAddr - ); - assertEq(ecdsaDkim.signer(), vm.envAddress("NEW_SIGNER")); - } -} diff --git a/packages/contracts/test/script/ChangeSignerInECDSAOwnedDKIMRegistryScript.t.sol b/packages/contracts/test/script/ChangeSignerInECDSAOwnedDKIMRegistryScript.t.sol new file mode 100644 index 00000000..89cb3b2a --- /dev/null +++ b/packages/contracts/test/script/ChangeSignerInECDSAOwnedDKIMRegistryScript.t.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; + +import {Deploy} from "../../script/DeployRecoveryController.s.sol"; +import {ChangeSigner} from "../../script/ChangeSignerInECDSAOwnedDKIMRegistry.s.sol"; +import {ECDSAOwnedDKIMRegistry} from "../../src/utils/ECDSAOwnedDKIMRegistry.sol"; +import {StructHelper} from "../helpers/StructHelper.sol"; + +contract ChangeSignerInECDSAOwnedDKIMRegistryScriptTest is StructHelper { + function setUp() public override { + resetEnviromentVariables(); + super.setUp(); + vm.setEnv( + "PRIVATE_KEY", + "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d" + ); + vm.setEnv("DKIM_SIGNER", "0x69bec2dd161d6bbcc91ec32aa44d9333ebc864c0"); + vm.setEnv( + "INITIAL_OWNER", + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" + ); + vm.setEnv("NEW_SIGNER", "0xa1bec2dd161d6bbcc91ec32aa44d9333e2a864c0"); + } + + function test_run() public { + skipIfZkSync(); + + Deploy deploy = new Deploy(); + deploy.run(); + vm.setEnv("DKIM", "0x71C95911E9a5D330f4D621842EC243EE1343292e"); + vm.setEnv("VERIFIER", "0xbCF26943C0197d2eE0E5D05c716Be60cc2761508"); + vm.setEnv( + "EMAIL_AUTH_IMPL", + "0x59F2f1fCfE2474fD5F0b9BA1E73ca90b143Eb8d0" + ); + vm.setEnv( + "RECOVERY_CONTROLLER", + "0x1275D096B9DBf2347bD2a131Fb6BDaB0B4882487" + ); + deploy.deployECDSAOwnedDKIMRegistry( + vm.addr(vm.envUint("PRIVATE_KEY")), + vm.envAddress("DKIM_SIGNER") + ); + vm.setEnv("ECDSA_DKIM", "0x037eDa3aDB1198021A9b2e88C22B464fD38db3f3"); + ChangeSigner changeSigner = new ChangeSigner(); + changeSigner.run(); + address ecdsaDkimAddr = vm.envAddress("ECDSA_DKIM"); + ECDSAOwnedDKIMRegistry ecdsaDkim = ECDSAOwnedDKIMRegistry( + ecdsaDkimAddr + ); + assertEq(ecdsaDkim.signer(), vm.envAddress("NEW_SIGNER")); + } +} diff --git a/packages/contracts/test/script/ChangeSourceInForwardDKIMRegistry.t.sol b/packages/contracts/test/script/ChangeSourceInForwardDKIMRegistry.t.sol deleted file mode 100644 index 0c90097a..00000000 --- a/packages/contracts/test/script/ChangeSourceInForwardDKIMRegistry.t.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.12; - -import "forge-std/Test.sol"; -import "forge-std/console.sol"; - -import {Deploy} from "../../script/DeployCommons.s.sol"; -import {Deploy as Deploy2} from "../../script/DeployForwardDKIMRegistry.s.sol"; -import {ChangeSource} from "../../script/ChangeSourceInForwardDKIMRegistry.s.sol"; -import {ForwardDKIMRegistry} from "../../src/utils/ForwardDKIMRegistry.sol"; -import {StructHelper} from "../helpers/StructHelper.sol"; - -contract ChangeSourceInForwardDKIMRegistryTest is StructHelper { - function setUp() public override { - vm.setEnv( - "PRIVATE_KEY", - "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" - ); - vm.setEnv("SIGNER", "0x69bec2dd161d6bbcc91ec32aa44d9333ebc864c0"); - vm.setEnv("NEW_SOURCE", "0xa1bec2dd161d6bbcc91ec32aa44d9333e2a864c0"); - } - - function test_run() public { - skipIfZkSync(); - - Deploy deploy = new Deploy(); - deploy.run(); - vm.setEnv("SOURCE_DKIM", vm.toString(vm.envAddress("ECDSA_DKIM"))); - Deploy2 deploy2 = new Deploy2(); - deploy2.run(); - ChangeSource changeSource = new ChangeSource(); - changeSource.run(); - address dkimAddr = vm.envAddress("DKIM"); - ForwardDKIMRegistry dkim = ForwardDKIMRegistry(dkimAddr); - assertEq( - address(dkim.sourceDKIMRegistry()), - vm.envAddress("NEW_SOURCE") - ); - } -} diff --git a/packages/contracts/test/script/DeployCommons.t.sol b/packages/contracts/test/script/DeployCommons.t.sol deleted file mode 100644 index a9ff89b2..00000000 --- a/packages/contracts/test/script/DeployCommons.t.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.12; - -import "forge-std/Test.sol"; -import "forge-std/console.sol"; - -import { Deploy } from "../../script/DeployCommons.s.sol"; -import { StructHelper } from "../helpers/StructHelper.sol"; - -contract DeployCommonsTest is StructHelper { - function setUp() public override { - vm.setEnv( - "PRIVATE_KEY", - "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" - ); - vm.setEnv( - "SIGNER", - "0x69bec2dd161d6bbcc91ec32aa44d9333ebc864c0" - ); - } - - function test_run() public { - skipIfZkSync(); - - Deploy deploy = new Deploy(); - deploy.run(); - } -} diff --git a/packages/contracts/test/script/DeployRecoveryController.t.sol b/packages/contracts/test/script/DeployRecoveryController.t.sol deleted file mode 100644 index 6a66b7f1..00000000 --- a/packages/contracts/test/script/DeployRecoveryController.t.sol +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.12; - -import "forge-std/Test.sol"; -import "forge-std/console.sol"; - -import {Deploy} from "../../script/DeployRecoveryController.s.sol"; -import {StructHelper} from "../helpers/StructHelper.sol"; - -contract DeployRecoveryControllerTest is StructHelper { - function setUp() public override { - vm.setEnv( - "PRIVATE_KEY", - "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" - ); - vm.setEnv("SIGNER", "0x69bec2dd161d6bbcc91ec32aa44d9333ebc864c0"); - } - - function test_run() public { - skipIfZkSync(); - - Deploy deploy = new Deploy(); - deploy.run(); - require( - vm.envAddress("ECDSA_DKIM") != address(0), - "ECDSA_DKIM is not set" - ); - require(vm.envAddress("VERIFIER") != address(0), "VERIFIER is not set"); - require( - vm.envAddress("EMAIL_AUTH_IMPL") != address(0), - "EMAIL_AUTH_IMPL is not set" - ); - require( - vm.envAddress("RECOVERY_CONTROLLER") != address(0), - "RECOVERY_CONTROLLER is not set" - ); - require( - vm.envAddress("SIMPLE_WALLET") != address(0), - "SIMPLE_WALLET is not set" - ); - } - - // TODO: Comment out this test case because removing environment variables will affect other tests - // If you want to run this test case, please run `forge test --match-test testFail_run_no_signer`. It works. - // function testFail_run_no_signer() public { - // // Remove DKIM and SIGNER from the environment variables - // vm.setEnv("DKIM", vm.toString(address(0))); - // vm.setEnv("SIGNER", vm.toString(address(0))); - - // Deploy deploy = new Deploy(); - // deploy.run(); - // require(vm.envAddress("DKIM") != address(0), "DKIM is not set"); - // } -} diff --git a/packages/contracts/test/script/DeployRecoveryControllerScript.t.sol b/packages/contracts/test/script/DeployRecoveryControllerScript.t.sol new file mode 100644 index 00000000..e220d94b --- /dev/null +++ b/packages/contracts/test/script/DeployRecoveryControllerScript.t.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; + +import {Deploy} from "../../script/DeployRecoveryController.s.sol"; +import {StructHelper} from "../helpers/StructHelper.sol"; + +contract DeployRecoveryControllerScriptTest is StructHelper { + function setUp() public override { + resetEnviromentVariables(); + super.setUp(); + vm.setEnv( + "PRIVATE_KEY", + "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d" + ); + vm.setEnv("DKIM_SIGNER", "0x69bec2dd161d6bbcc91ec32aa44d9333ebc864c0"); + vm.setEnv( + "INITIAL_OWNER", + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" + ); + } + + function test_run() public { + skipIfZkSync(); + + Deploy deploy = new Deploy(); + deploy.run(); + vm.setEnv("DKIM", "0x71C95911E9a5D330f4D621842EC243EE1343292e"); + vm.setEnv("VERIFIER", "0xbCF26943C0197d2eE0E5D05c716Be60cc2761508"); + vm.setEnv( + "EMAIL_AUTH_IMPL", + "0x59F2f1fCfE2474fD5F0b9BA1E73ca90b143Eb8d0" + ); + vm.setEnv( + "RECOVERY_CONTROLLER", + "0x1275D096B9DBf2347bD2a131Fb6BDaB0B4882487" + ); + vm.setEnv( + "SIMPLE_WALLET", + "0x0b48aF34f4c854F5ae1A3D587da471FeA45bAD52" + ); + deploy.deployECDSAOwnedDKIMRegistry( + vm.addr(vm.envUint("PRIVATE_KEY")), + vm.envAddress("DKIM_SIGNER") + ); + vm.setEnv("ECDSA_DKIM", "0x037eDa3aDB1198021A9b2e88C22B464fD38db3f3"); + require( + vm.envAddress("ECDSA_DKIM") != address(0), + "ECDSA_DKIM is not set" + ); + require(vm.envAddress("VERIFIER") != address(0), "VERIFIER is not set"); + require( + vm.envAddress("EMAIL_AUTH_IMPL") != address(0), + "EMAIL_AUTH_IMPL is not set" + ); + require( + vm.envAddress("RECOVERY_CONTROLLER") != address(0), + "RECOVERY_CONTROLLER is not set" + ); + require( + vm.envAddress("SIMPLE_WALLET") != address(0), + "SIMPLE_WALLET is not set" + ); + } +} diff --git a/packages/contracts/test/script/DeploySimpleWallet.t.sol b/packages/contracts/test/script/DeploySimpleWalletScript.t.sol similarity index 58% rename from packages/contracts/test/script/DeploySimpleWallet.t.sol rename to packages/contracts/test/script/DeploySimpleWalletScript.t.sol index a0bbf164..1e4c8cbb 100644 --- a/packages/contracts/test/script/DeploySimpleWallet.t.sol +++ b/packages/contracts/test/script/DeploySimpleWalletScript.t.sol @@ -4,37 +4,24 @@ pragma solidity ^0.8.12; import "forge-std/Test.sol"; import "forge-std/console.sol"; -import { Deploy } from "../../script/DeployCommons.s.sol"; -import { StructHelper } from "../helpers/StructHelper.sol"; +import {Deploy} from "../../script/DeployRecoveryController.s.sol"; +import {StructHelper} from "../helpers/StructHelper.sol"; -contract DeploySimpleWalletTest is StructHelper { +contract DeploySimpleWalletScriptTest is StructHelper { function setUp() public override { + resetEnviromentVariables(); super.setUp(); vm.setEnv( - "PRIVATE_KEY", - "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" - ); - vm.setEnv( - "SIGNER", - "0x69bec2dd161d6bbcc91ec32aa44d9333ebc864c0" - ); - - vm.setEnv( - "DKIM", - vm.toString(address(dkim)) - ); - vm.setEnv( - "VERIFIER", - vm.toString(address(verifier)) - ); - vm.setEnv( - "EMAIL_AUTH_IMPL", - vm.toString(address(emailAuth)) - ); - vm.setEnv( - "SIMPLE_WALLET_IMPL", - vm.toString(address(simpleWalletImpl)) + "PRIVATE_KEY", + "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d" ); + vm.setEnv("DKIM_SIGNER", "0x69bec2dd161d6bbcc91ec32aa44d9333ebc864c0"); + vm.setEnv("INITIAL_OWNER", "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"); + + vm.setEnv("DKIM", vm.toString(address(dkim))); + vm.setEnv("VERIFIER", vm.toString(address(verifier))); + vm.setEnv("EMAIL_AUTH_IMPL", vm.toString(address(emailAuth))); + vm.setEnv("SIMPLE_WALLET_IMPL", vm.toString(address(simpleWalletImpl))); } function test_run() public { diff --git a/packages/contracts/test/script/RenounceOwners.t.sol b/packages/contracts/test/script/RenounceOwners.t.sol deleted file mode 100644 index cafb6610..00000000 --- a/packages/contracts/test/script/RenounceOwners.t.sol +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.12; - -import "forge-std/Test.sol"; -import "forge-std/console.sol"; - -import {Deploy} from "../../script/DeployCommons.s.sol"; -import {Deploy as Deploy2} from "../../script/DeployForwardDKIMRegistry.s.sol"; -import {RenounceOwners} from "../../script/RenounceOwners.s.sol"; -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import {StructHelper} from "../helpers/StructHelper.sol"; - -contract RenounceOwnersTest is StructHelper { - function setUp() public override { - vm.setEnv( - "PRIVATE_KEY", - "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" - ); - vm.setEnv("SIGNER", "0x69bec2dd161d6bbcc91ec32aa44d9333ebc864c0"); - } - - function test_run() public { - skipIfZkSync(); - - Deploy deploy = new Deploy(); - deploy.run(); - vm.setEnv("SOURCE_DKIM", vm.toString(vm.envAddress("ECDSA_DKIM"))); - Deploy2 deploy2 = new Deploy2(); - deploy2.run(); - RenounceOwners renounceOwners = new RenounceOwners(); - renounceOwners.run(); - address verifier = vm.envAddress("VERIFIER"); - address ecdsaDkimAddr = vm.envAddress("ECDSA_DKIM"); - address dkim = vm.envAddress("DKIM"); - assertEq(OwnableUpgradeable(verifier).owner(), address(0)); - assertEq(OwnableUpgradeable(ecdsaDkimAddr).owner(), address(0)); - assertEq(OwnableUpgradeable(dkim).owner(), address(0)); - } -} diff --git a/packages/contracts/test/script/RenounceOwnersScript.t.sol b/packages/contracts/test/script/RenounceOwnersScript.t.sol new file mode 100644 index 00000000..1bf9dcd0 --- /dev/null +++ b/packages/contracts/test/script/RenounceOwnersScript.t.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; + +import {Deploy} from "../../script/DeployRecoveryController.s.sol"; +import {RenounceOwners} from "../../script/RenounceOwners.s.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {StructHelper} from "../helpers/StructHelper.sol"; + +contract RenounceOwnersScriptTest is StructHelper { + function setUp() public override { + resetEnviromentVariables(); + super.setUp(); + vm.setEnv( + "PRIVATE_KEY", + "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d" + ); + vm.setEnv("DKIM_SIGNER", "0x69bec2dd161d6bbcc91ec32aa44d9333ebc864c0"); + vm.setEnv( + "INITIAL_OWNER", + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" + ); + } + + function test_run() public { + skipIfZkSync(); + Deploy deploy = new Deploy(); + deploy.run(); + vm.setEnv("DKIM", "0x71C95911E9a5D330f4D621842EC243EE1343292e"); + vm.setEnv("VERIFIER", "0xbCF26943C0197d2eE0E5D05c716Be60cc2761508"); + vm.setEnv( + "EMAIL_AUTH_IMPL", + "0x59F2f1fCfE2474fD5F0b9BA1E73ca90b143Eb8d0" + ); + vm.setEnv( + "RECOVERY_CONTROLLER", + "0x1275D096B9DBf2347bD2a131Fb6BDaB0B4882487" + ); + vm.setEnv( + "SIMPLE_WALLET", + "0x0b48aF34f4c854F5ae1A3D587da471FeA45bAD52" + ); + deploy.deployECDSAOwnedDKIMRegistry( + vm.addr(vm.envUint("PRIVATE_KEY")), + vm.envAddress("DKIM_SIGNER") + ); + vm.setEnv("ECDSA_DKIM", "0x037eDa3aDB1198021A9b2e88C22B464fD38db3f3"); + RenounceOwners renounceOwners = new RenounceOwners(); + renounceOwners.run(); + address verifier = vm.envAddress("VERIFIER"); + address ecdsaDkimAddr = vm.envAddress("ECDSA_DKIM"); + address dkim = vm.envAddress("DKIM"); + assertEq(OwnableUpgradeable(verifier).owner(), address(0)); + assertEq(OwnableUpgradeable(ecdsaDkimAddr).owner(), address(0)); + assertEq(OwnableUpgradeable(dkim).owner(), address(0)); + } +} diff --git a/packages/contracts/test/script/Upgrades.t.sol b/packages/contracts/test/script/Upgrades.t.sol deleted file mode 100644 index 862eba32..00000000 --- a/packages/contracts/test/script/Upgrades.t.sol +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.12; - -import "forge-std/Test.sol"; -import "forge-std/console.sol"; - -import {Deploy} from "../../script/DeployCommons.s.sol"; -import {Deploy as Deploy2} from "../../script/DeployForwardDKIMRegistry.s.sol"; -import {Upgrades} from "../../script/Upgrades.s.sol"; -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -import {StructHelper} from "../helpers/StructHelper.sol"; - -contract UpgradesTest is StructHelper { - uint256 internal constant IMPLEMENTATION_SLOT = - 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - function setUp() public override { - vm.setEnv( - "PRIVATE_KEY", - "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" - ); - vm.setEnv("SIGNER", "0x69bec2dd161d6bbcc91ec32aa44d9333ebc864c0"); - } - - function test_run() public { - skipIfZkSync(); - - Deploy deploy = new Deploy(); - deploy.run(); - vm.setEnv("SOURCE_DKIM", vm.toString(vm.envAddress("ECDSA_DKIM"))); - Deploy2 deploy2 = new Deploy2(); - deploy2.run(); - // address verifier = vm.envAddress("VERIFIER"); - // address ecdsaDkimAddr = vm.envAddress("ECDSA_DKIM"); - // address dkim = vm.envAddress("DKIM"); - // address verifierImpl = _readAddressFromSlot( - // verifier, - // IMPLEMENTATION_SLOT - // ); - // address ecdsaDkimImpl = _readAddressFromSlot( - // ecdsaDkimAddr, - // IMPLEMENTATION_SLOT - // ); - // address dkimImpl = _readAddressFromSlot(dkim, IMPLEMENTATION_SLOT); - Upgrades upgrades = new Upgrades(); - upgrades.run(); - // assertNotEq( - // verifierImpl, - // _readAddressFromSlot(verifier, IMPLEMENTATION_SLOT) - // ); - // assertNotEq( - // ecdsaDkimImpl, - // _readAddressFromSlot(ecdsaDkimAddr, IMPLEMENTATION_SLOT) - // ); - // assertNotEq(dkimImpl, _readAddressFromSlot(dkim, IMPLEMENTATION_SLOT)); - } - - // function _readAddressFromSlot( - // address contractAddress, - // uint256 slot - // ) private view returns (address) { - // address value; - // assembly { - // // Create a pointer to the slot - // let ptr := mload(0x40) - // mstore(ptr, slot) - // // Read the value from the slot - // value := sload(add(ptr, contractAddress)) - // } - // return value; - // } -} diff --git a/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/changeSigner.t.sol b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/changeSigner.t.sol new file mode 100644 index 00000000..38be5160 --- /dev/null +++ b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/changeSigner.t.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "../../../src/utils/ECDSAOwnedDKIMRegistry.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; + +contract ECDSAOwnedDKIMRegistryTest_changeSigner is Test { + ECDSAOwnedDKIMRegistry dkim; + + function setUp() public { + address signer = vm.addr(1); + ECDSAOwnedDKIMRegistry dkimImpl = new ECDSAOwnedDKIMRegistry(); + ERC1967Proxy dkimProxy = new ERC1967Proxy( + address(dkimImpl), + abi.encodeCall(dkimImpl.initialize, (msg.sender, signer)) + ); + dkim = ECDSAOwnedDKIMRegistry(address(dkimProxy)); + } + + function test_ChangeSigner() public { + address owner = dkim.owner(); + address newSigner = vm.addr(2); + + vm.startPrank(owner); + dkim.changeSigner(newSigner); + vm.stopPrank(); + + assertEq(dkim.signer(), newSigner, "Signer was not changed correctly"); + } + + function test_Revert_IfNewSignerIsZeroAddress() public { + address owner = dkim.owner(); + vm.startPrank(owner); + + vm.expectRevert("Invalid signer"); + dkim.changeSigner(address(0)); + } + + function test_Revert_IfNewSignerIsSame() public { + address owner = dkim.owner(); + address currentSigner = dkim.signer(); + + vm.startPrank(owner); + vm.expectRevert("Same signer"); + dkim.changeSigner(currentSigner); + } +} diff --git a/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/computeSignedMsg.t.sol b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/computeSignedMsg.t.sol new file mode 100644 index 00000000..d231ca59 --- /dev/null +++ b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/computeSignedMsg.t.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "../../../src/utils/ECDSAOwnedDKIMRegistry.sol"; + +contract ECDSAOwnedDKIMRegistryTest_computeSignedMsg is Test { + using Strings for *; + + ECDSAOwnedDKIMRegistry dkim; + + function setUp() public { + address signer = vm.addr(1); + ECDSAOwnedDKIMRegistry dkimImpl = new ECDSAOwnedDKIMRegistry(); + dkimImpl.initialize(msg.sender, signer); + dkim = dkimImpl; + } + + function test_computeSignedMsg() public { + string memory prefix = "SET:"; + string memory selector = "12345"; + string memory domainName = "example.com"; + bytes32 publicKeyHash = bytes32(uint256(1)); + + string memory expectedMsg = string.concat( + prefix, + "domain=", + domainName, + ";public_key_hash=", + uint256(publicKeyHash).toHexString(), + ";" + ); + + string memory computedMsg = dkim.computeSignedMsg( + prefix, + domainName, + publicKeyHash + ); + + assertEq( + computedMsg, + expectedMsg, + "Computed message does not match expected message" + ); + } +} diff --git a/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/isDKIMPublicKeyHashValid.t.sol b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/isDKIMPublicKeyHashValid.t.sol new file mode 100644 index 00000000..58a315c3 --- /dev/null +++ b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/isDKIMPublicKeyHashValid.t.sol @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "../../../src/utils/ECDSAOwnedDKIMRegistry.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; + +contract ECDSAOwnedDKIMRegistryTest_isDKIMPublicKeyHashValid is Test { + ECDSAOwnedDKIMRegistry dkim; + + string public selector = "12345"; + string public domainName = "example.com"; + bytes32 public publicKeyHash = bytes32(uint256(1)); + + function setUp() public { + address signer = vm.addr(1); + ECDSAOwnedDKIMRegistry dkimImpl = new ECDSAOwnedDKIMRegistry(); + ERC1967Proxy dkimProxy = new ERC1967Proxy( + address(dkimImpl), + abi.encodeCall(dkimImpl.initialize, (msg.sender, signer)) + ); + dkim = ECDSAOwnedDKIMRegistry(address(dkimProxy)); + } + + function test_IsDKIMPublicKeyHashValid_True() public { + // Set a valid public key hash + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + dkim.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + + // Check if the public key hash is valid + bool isValid = dkim.isDKIMPublicKeyHashValid(domainName, publicKeyHash); + require(isValid, "Public key hash should be valid"); + } + + function test_IsDKIMPublicKeyHashValid_False() public { + // Check if a non-set public key hash is invalid + bytes32 nonExistentPublicKeyHash = bytes32(uint256(2)); + bool isValid = dkim.isDKIMPublicKeyHashValid( + domainName, + nonExistentPublicKeyHash + ); + require(!isValid, "Public key hash should not be valid"); + } + + function test_IsDKIMPublicKeyHashValid_AfterRevoke() public { + // Set and then revoke a public key hash + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + dkim.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + + // Revoke the public key hash + string memory revokeMsg = dkim.computeSignedMsg( + dkim.REVOKE_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 revokeDigest = MessageHashUtils.toEthSignedMessageHash( + bytes(revokeMsg) + ); + (uint8 v1, bytes32 r1, bytes32 s1) = vm.sign(1, revokeDigest); + bytes memory revokeSig = abi.encodePacked(r1, s1, v1); + dkim.revokeDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + revokeSig + ); + + // Check if the public key hash is invalid after revocation + bool isValid = dkim.isDKIMPublicKeyHashValid(domainName, publicKeyHash); + require( + !isValid, + "Public key hash should not be valid after revocation" + ); + } +} diff --git a/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/revokeDKIMPublicKeyHash.t.sol b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/revokeDKIMPublicKeyHash.t.sol new file mode 100644 index 00000000..c47acf72 --- /dev/null +++ b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/revokeDKIMPublicKeyHash.t.sol @@ -0,0 +1,335 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import "../../../src/utils/ECDSAOwnedDKIMRegistry.sol"; +import "@openzeppelin/contracts/utils/Strings.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; + +contract ECDSAOwnedDKIMRegistryTest_revokeDKIMPublicKeyHash is Test { + ECDSAOwnedDKIMRegistry dkim; + using console for *; + using ECDSA for *; + using Strings for *; + + string public selector = "12345"; + string public domainName = "example.com"; + // uint public signValidityDuration = 1 days; + bytes32 public publicKeyHash = bytes32(uint256(1)); + + function setUp() public { + address signer = vm.addr(1); + { + ECDSAOwnedDKIMRegistry dkimImpl = new ECDSAOwnedDKIMRegistry(); + ERC1967Proxy dkimProxy = new ERC1967Proxy( + address(dkimImpl), + abi.encodeCall(dkimImpl.initialize, (msg.sender, signer)) + ); + dkim = ECDSAOwnedDKIMRegistry(address(dkimProxy)); + } + } + + function test_Revert_IfPublicKeyHashNotSet() public { + // Attempt to revoke a public key hash that hasn't been set + string memory revokeMsg = dkim.computeSignedMsg( + dkim.REVOKE_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(revokeMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + + vm.expectRevert("publicKeyHash is not set"); + dkim.revokeDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + } + + function test_Revert_IfSignerIsIncorrect() public { + // Set a valid public key hash first + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + dkim.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + + // Attempt to revoke with a signature from a different signer + (uint8 v1, bytes32 r1, bytes32 s1) = vm.sign(2, digest); // Different signer + bytes memory invalidSignature = abi.encodePacked(r1, s1, v1); + + vm.expectRevert("Invalid signature"); + dkim.revokeDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + invalidSignature + ); + } + + // Test invalid domain name + function test_Revert_IfDomainNameIsInvalid() public { + // Set a valid public key hash first + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + dkim.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + + // Attempt to revoke with an invalid domain name + string memory invalidDomainName = ""; + string memory revokeMsg = dkim.computeSignedMsg( + dkim.REVOKE_PREFIX(), + invalidDomainName, + publicKeyHash + ); + bytes32 revokeDigest = MessageHashUtils.toEthSignedMessageHash( + bytes(revokeMsg) + ); + (uint8 v1, bytes32 r1, bytes32 s1) = vm.sign(1, revokeDigest); + bytes memory revokeSig = abi.encodePacked(r1, s1, v1); + + vm.expectRevert("Invalid domain name"); + dkim.revokeDKIMPublicKeyHash( + selector, + invalidDomainName, + publicKeyHash, + revokeSig + ); + } + // Test invalid public key hash + function test_Revert_IfPublicKeyHashIsInvalid() public { + // Set a valid public key hash first + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + dkim.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + + // Attempt to revoke with an invalid public key hash + bytes32 invalidPublicKeyHash = bytes32(0); + string memory revokeMsg = dkim.computeSignedMsg( + dkim.REVOKE_PREFIX(), + domainName, + invalidPublicKeyHash + ); + bytes32 revokeDigest = MessageHashUtils.toEthSignedMessageHash( + bytes(revokeMsg) + ); + (uint8 v1, bytes32 r1, bytes32 s1) = vm.sign(1, revokeDigest); + bytes memory revokeSig = abi.encodePacked(r1, s1, v1); + + vm.expectRevert("Invalid public key hash"); + dkim.revokeDKIMPublicKeyHash( + selector, + domainName, + invalidPublicKeyHash, + revokeSig + ); + } + // Test if publicKeyHash is already revoked + function test_Revert_IfPublicKeyHashIsAlreadyRevoked() public { + // Set a valid public key hash first + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + dkim.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + + // Revoke the public key hash + string memory revokeMsg = dkim.computeSignedMsg( + dkim.REVOKE_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 revokeDigest = MessageHashUtils.toEthSignedMessageHash( + bytes(revokeMsg) + ); + (uint8 v1, bytes32 r1, bytes32 s1) = vm.sign(1, revokeDigest); + bytes memory revokeSig = abi.encodePacked(r1, s1, v1); + dkim.revokeDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + revokeSig + ); + + // Mock the call to dkimRegistry.isDKIMPublicKeyHashValid to return true + vm.mockCall( + address(dkim.dkimRegistry()), + abi.encodeWithSelector( + IDKIMRegistry.isDKIMPublicKeyHashValid.selector + ), + abi.encode(true) + ); + // Attempt to revoke the already revoked public key hash + vm.expectRevert("publicKeyHash is already revoked"); + dkim.revokeDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + revokeSig + ); + } + + function test_Revert_IfSignatureIsInvalid() public { + // Set a valid public key hash first + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + dkim.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + + // Attempt to revoke with an invalid signature + bytes memory invalidSignature = abi.encodePacked(r, s, v + 1); // Alter the signature + vm.expectRevert("Invalid signature"); + dkim.revokeDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + invalidSignature + ); + } + function test_Revert_IfDomainNameIsDifferent() public { + // Set a valid public key hash first + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + dkim.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + + // Attempt to revoke with a different domain name + string memory differentDomainName = "different.com"; + string memory revokeMsg = dkim.computeSignedMsg( + dkim.REVOKE_PREFIX(), + differentDomainName, + publicKeyHash + ); + bytes32 revokeDigest = MessageHashUtils.toEthSignedMessageHash( + bytes(revokeMsg) + ); + (uint8 v1, bytes32 r1, bytes32 s1) = vm.sign(1, revokeDigest); + bytes memory revokeSig = abi.encodePacked(r1, s1, v1); + + vm.expectRevert("publicKeyHash is not set"); + dkim.revokeDKIMPublicKeyHash( + selector, + differentDomainName, + publicKeyHash, + revokeSig + ); + } + + function test_RevokeDKIMPublicKeyHash() public { + // vm.chainId(1); + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + dkim.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + + // Revoke + string memory revokeMsg = dkim.computeSignedMsg( + dkim.REVOKE_PREFIX(), + domainName, + publicKeyHash + ); + (uint8 v1, bytes32 r1, bytes32 s1) = vm.sign( + 1, + MessageHashUtils.toEthSignedMessageHash(bytes(revokeMsg)) + ); + bytes memory revokeSig = abi.encodePacked(r1, s1, v1); + dkim.revokeDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + revokeSig + ); + + require(!dkim.isDKIMPublicKeyHashValid(domainName, publicKeyHash)); + } +} diff --git a/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry.t.sol b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/setDKIMPublicKeyHash.t.sol similarity index 63% rename from packages/contracts/test/utils/ECDSAOwnedDKIMRegistry.t.sol rename to packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/setDKIMPublicKeyHash.t.sol index 9c5aa1e6..9dd205ed 100644 --- a/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry.t.sol +++ b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry/setDKIMPublicKeyHash.t.sol @@ -4,11 +4,11 @@ pragma solidity ^0.8.12; import "forge-std/Test.sol"; import "forge-std/console.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import "../../src/utils/ECDSAOwnedDKIMRegistry.sol"; +import "../../../src/utils/ECDSAOwnedDKIMRegistry.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -contract ECDSAOwnedDKIMRegistryTest is Test { +contract ECDSAOwnedDKIMRegistryTest_setDKIMPublicKeyHash is Test { ECDSAOwnedDKIMRegistry dkim; using console for *; using ECDSA for *; @@ -31,11 +31,155 @@ contract ECDSAOwnedDKIMRegistryTest is Test { } } - function test_SetDKIMPublicKeyHash() public { + function test_Revert_IfInvalidSelector() public { + string memory invalidSelector = ""; // Example of an invalid selector (empty string) + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + domainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + + vm.expectRevert("Invalid selector"); + dkim.setDKIMPublicKeyHash( + invalidSelector, + domainName, + publicKeyHash, + signature + ); + } + + function test_Revert_IfInvalidDomainName() public { + string memory invalidDomainName = ""; // Example of an invalid domain name (empty string) + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + invalidDomainName, + publicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + + vm.expectRevert("Invalid domain name"); + dkim.setDKIMPublicKeyHash( + selector, + invalidDomainName, + publicKeyHash, + signature + ); + } + + function test_MinLengthSelectorAndDomainName() public { + string memory minSelector = "a"; + string memory minDomainName = "b"; + bytes32 minPublicKeyHash = bytes32(uint256(1)); + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + minDomainName, + minPublicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + + dkim.setDKIMPublicKeyHash( + minSelector, + minDomainName, + minPublicKeyHash, + signature + ); + require( + dkim.isDKIMPublicKeyHashValid(minDomainName, minPublicKeyHash), + "Invalid public key hash" + ); + } + + function test_MaxLengthSelectorAndDomainName() public { + string memory maxSelector = new string(256); + string memory maxDomainName = new string(256); + bytes32 aPublicKeyHash = bytes32(uint256(1)); + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + maxDomainName, + aPublicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + + dkim.setDKIMPublicKeyHash( + maxSelector, + maxDomainName, + aPublicKeyHash, + signature + ); + require( + dkim.isDKIMPublicKeyHashValid(maxDomainName, aPublicKeyHash), + "Invalid public key hash" + ); + } + + function test_Revert_IfInvalidPublicKeyHash() public { + bytes32 zeroPublicKeyHash = bytes32(0); + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + domainName, + zeroPublicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + + vm.expectRevert("Invalid public key hash"); + dkim.setDKIMPublicKeyHash( + selector, + domainName, + zeroPublicKeyHash, + signature + ); + } + + function test_MaxValuePublicKeyHash() public { + bytes32 maxPublicKeyHash = bytes32(type(uint256).max); string memory signedMsg = dkim.computeSignedMsg( dkim.SET_PREFIX(), + domainName, + maxPublicKeyHash + ); + bytes32 digest = MessageHashUtils.toEthSignedMessageHash( + bytes(signedMsg) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + + dkim.setDKIMPublicKeyHash( selector, domainName, + maxPublicKeyHash, + signature + ); + require( + dkim.isDKIMPublicKeyHashValid(domainName, maxPublicKeyHash), + "Invalid public key hash" + ); + } + + function test_SetDKIMPublicKeyHash() public { + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + domainName, publicKeyHash ); bytes32 digest = MessageHashUtils.toEthSignedMessageHash( @@ -59,7 +203,6 @@ contract ECDSAOwnedDKIMRegistryTest is Test { // vm.chainId(1); string memory signedMsg = dkim.computeSignedMsg( dkim.SET_PREFIX(), - selector, domainName, publicKeyHash ); @@ -84,7 +227,6 @@ contract ECDSAOwnedDKIMRegistryTest is Test { publicKeyHash = bytes32(uint256(2)); signedMsg = dkim.computeSignedMsg( dkim.SET_PREFIX(), - selector, domainName, publicKeyHash ); @@ -107,7 +249,6 @@ contract ECDSAOwnedDKIMRegistryTest is Test { // vm.chainId(1); string memory signedMsg = dkim.computeSignedMsg( dkim.SET_PREFIX(), - selector, domainName, publicKeyHash ); @@ -126,7 +267,6 @@ contract ECDSAOwnedDKIMRegistryTest is Test { // Revoke string memory revokeMsg = dkim.computeSignedMsg( dkim.REVOKE_PREFIX(), - selector, domainName, publicKeyHash ); @@ -149,7 +289,6 @@ contract ECDSAOwnedDKIMRegistryTest is Test { // vm.chainId(1); string memory signedMsg = dkim.computeSignedMsg( dkim.SET_PREFIX(), - selector, domainName, publicKeyHash ); @@ -180,11 +319,10 @@ contract ECDSAOwnedDKIMRegistryTest is Test { ); } - function test_RevertIfRevorked() public { + function test_Revert_IfRevorked() public { // vm.chainId(1); string memory signedMsg = dkim.computeSignedMsg( dkim.SET_PREFIX(), - selector, domainName, publicKeyHash ); @@ -207,7 +345,6 @@ contract ECDSAOwnedDKIMRegistryTest is Test { // Revoke string memory revokeMsg = dkim.computeSignedMsg( dkim.REVOKE_PREFIX(), - selector, domainName, publicKeyHash ); @@ -226,7 +363,6 @@ contract ECDSAOwnedDKIMRegistryTest is Test { signedMsg = dkim.computeSignedMsg( dkim.SET_PREFIX(), - selector, domainName, publicKeyHash ); @@ -241,11 +377,10 @@ contract ECDSAOwnedDKIMRegistryTest is Test { ); } - function test_RevertIfSignatureInvalid() public { + function test_Revert_IfSignatureInvalid() public { // vm.chainId(1); string memory signedMsg = dkim.computeSignedMsg( dkim.SET_PREFIX(), - selector, domainName, publicKeyHash ); @@ -271,7 +406,7 @@ contract ECDSAOwnedDKIMRegistryTest is Test { address(dkimImpl), abi.encodeCall( dkimImpl.initialize, - (msg.sender, 0x69Bec2Dd161d6Bbcc91ec32AA44D9333EBc864c0) + (msg.sender, 0x6293A80BF4Bd3fff995a0CAb74CBf281d922dA02) ) ); dkim = ECDSAOwnedDKIMRegistry(address(dkimProxy)); @@ -284,7 +419,7 @@ contract ECDSAOwnedDKIMRegistryTest is Test { domainName, publicKeyHash, vm.parseBytes( - "0xe5fb9c45bd6468877e8ec7e04063b03e8ac89206354060e757b15d6269f7754e6c515b5825fbb6be4e939f92d1ad62dc7f548607fe4349033ed51f8da8a18c4c1c" + "0xb491dad31ddd0fd9994e76e0325f29a0f44732c56220b6df0e2672750b87fb2d46e41069e3e93d88ee55e45bb6c712e2b077749c8392908a1a862432e68b104b1b" ) ); require( diff --git a/packages/contracts/test/utils/Verifier.t.sol b/packages/contracts/test/utils/Verifier.t.sol new file mode 100644 index 00000000..b38d30c2 --- /dev/null +++ b/packages/contracts/test/utils/Verifier.t.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "../../src/utils/Verifier.sol"; +import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; + +contract VerifierTest is Test { + Verifier public verifier; + address public deployer; + + function setUp() public { + deployer = address(this); + verifier = new Verifier(); + } + + function testUpgradeVerifier() public { + // Deploy new implementation + Verifier newImplementation = new Verifier(); + + // Execute upgrade using proxy + ERC1967Proxy proxy = new ERC1967Proxy( + address(verifier), + abi.encodeCall( + verifier.initialize, + (deployer, address(0)) // Assuming a dummy address for groth16Verifier + ) + ); + Verifier verifierProxy = Verifier(address(proxy)); + + // Store initial values for comparison + uint256 initialDomainFields = verifierProxy.DOMAIN_FIELDS(); + uint256 initialDomainBytes = verifierProxy.DOMAIN_BYTES(); + + // Upgrade to new implementation through proxy + verifierProxy.upgradeToAndCall( + address(newImplementation), + new bytes(0) + ); + + // Verify the upgrade + assertEq(verifierProxy.DOMAIN_FIELDS(), initialDomainFields); + assertEq(verifierProxy.DOMAIN_BYTES(), initialDomainBytes); + } +} diff --git a/packages/prover/Dockerfile b/packages/prover/Dockerfile index 256a6db4..524debb1 100644 --- a/packages/prover/Dockerfile +++ b/packages/prover/Dockerfile @@ -1,50 +1,85 @@ -FROM python:3.10 +FROM nvidia/cuda:12.4.0-devel-ubuntu22.04 RUN apt-get update && apt-get upgrade -y # Update the package list and install necessary dependencies RUN apt-get update && \ - apt install -y cmake build-essential pkg-config libssl-dev libgmp-dev libsodium-dev nasm git awscli gcc nodejs npm + DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \ + cmake \ + build-essential \ + pkg-config \ + libssl-dev \ + libgmp-dev \ + libffi-dev \ + libsodium-dev \ + nasm \ + git \ + awscli \ + gcc \ + nodejs \ + npm \ + curl \ + m4 \ + python3 \ + python3-pip \ + python3-dev \ + wget \ + software-properties-common \ + unzip \ + && rm -rf /var/lib/apt/lists/* + +# Set Python 3 as the default python version +RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 1 \ + && update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1 # Node install RUN npm install -g n -RUN n 18 +RUN n 22 RUN npm install -g yarn snarkjs -RUN git clone https://github.com/zkemail/ether-email-auth.git + +RUN git clone -b feat/audit-fix-2024-09-gpus https://github.com/zkemail/ether-email-auth.git WORKDIR /ether-email-auth/packages/prover RUN pip install -r requirements.txt RUN cp ./circom_proofgen.sh /root +# RUN cp ./email_auth_with_body_parsing_with_qp_encoding /root WORKDIR /root RUN ls /root -# RUN mkdir params -# RUN cp /email-wallet/packages/prover/params/account_creation.wasm /root/params -# RUN cp /email-wallet/packages/prover/params/account_init.wasm /root/params -# RUN cp /email-wallet/packages/prover/params/account_transport.wasm /root/params -# RUN cp /email-wallet/packages/prover/params/claim.wasm /root/params -# RUN cp /email-wallet/packages/prover/params/email_sender.wasm /root/params RUN mkdir params WORKDIR /root/params -RUN gdown "https://drive.google.com/uc?id=1Ybtxe1TCVUtHzCPUs9cuZAGbM-MVwigE" -RUN unzip params.zip -RUN mv params/* /root/params +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth.zkey --output ./email_auth.zkey +RUN mkdir ./email_auth_cpp +WORKDIR /root/params/email_auth_cpp +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/email_auth --output ./email_auth +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/Makefile --output ./Makefile +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/calcwit.cpp --output ./calcwit.cpp +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/calcwit.hpp --output ./calcwit.hpp +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/calcwit.o --output ./calcwit.o +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/circom.hpp --output ./circom.hpp +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/email_auth.cpp --output ./email_auth.cpp +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/email_auth.dat --output ./email_auth.dat +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/fr.asm --output ./fr.asm +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/fr.cpp --output ./fr.cpp +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/fr.hpp --output ./fr.hpp +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/fr.o --output ./fr.o +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/fr_asm.o --output ./fr_asm.o +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/main.cpp --output ./main.cpp +RUN curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/main.o --output ./main.o +RUN chmod +x ./email_auth WORKDIR /root RUN ls params -# RUN mv build params -# RUN curl https://email-wallet-trusted-setup-ceremony-pse-p0tion-production.s3.eu-central-1.amazonaws.com/circuits/emailwallet-account-creation/contributions/emailwallet-account-creation_00019.zkey --output ./params/account_creation.zkey -# RUN curl https://email-wallet-trusted-setup-ceremony-pse-p0tion-production.s3.eu-central-1.amazonaws.com/circuits/emailwallet-account-init/contributions/emailwallet-account-init_00007.zkey --output ./params/account_init.zkey -# RUN curl https://email-wallet-trusted-setup-ceremony-pse-p0tion-production.s3.eu-central-1.amazonaws.com/circuits/emailwallet-account-transport/contributions/emailwallet-account-transport_00005.zkey --output ./params/account_transport.zkey -# RUN curl https://email-wallet-trusted-setup-ceremony-pse-p0tion-production.s3.eu-central-1.amazonaws.com/circuits/emailwallet-claim/contributions/emailwallet-claim_00006.zkey --output ./params/claim.zkey -# RUN curl https://email-wallet-trusted-setup-ceremony-pse-p0tion-production.s3.eu-central-1.amazonaws.com/circuits/emailwallet-email-sender/contributions/emailwallet-email-sender_00006.zkey --output ./params/email_sender.zkey +RUN ls params/email_auth_cpp RUN chmod +x circom_proofgen.sh RUN mkdir build -RUN git clone https://github.com/iden3/rapidsnark-old.git rapidsnark +RUN git clone https://github.com/Orbiter-Finance/rapidsnark.git rapidsnark WORKDIR /root/rapidsnark RUN yarn RUN git submodule init RUN git submodule update -RUN npx task createFieldSources -RUN npx task buildPistache -RUN npx task buildProver -RUN chmod +x build/prover +RUN ./build_gmp.sh host +RUN mkdir build_prover +WORKDIR /root/rapidsnark/build_prover +RUN cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package -DNVML_LIBRARY=/usr/local/cuda-12.4/targets/x86_64-linux/lib/stubs/libnvidia-ml.so +RUN make -j$(nproc) && make install +RUN chmod +x ../package/bin/prover_cuda WORKDIR /root \ No newline at end of file diff --git a/packages/prover/circom_proofgen.sh b/packages/prover/circom_proofgen.sh index 738f2e2c..7d89993d 100755 --- a/packages/prover/circom_proofgen.sh +++ b/packages/prover/circom_proofgen.sh @@ -21,21 +21,9 @@ public_path="${buildDir}/rapidsnark_public_${circuitName}_${nonce}.json" cd "${SCRIPT_DIR}" echo "entered zk email path: ${SCRIPT_DIR}" -echo "NODE_OPTIONS='--max-old-space-size=644000' snarkjs wc "${paramsDir}/${circuitName}.wasm" "${input_path}" "${witness_path}"" -NODE_OPTIONS='--max-old-space-size=644000' snarkjs wc "${paramsDir}/${circuitName}.wasm" "${input_path}" "${witness_path}" | tee /dev/stderr +${paramsDir}/${circuitName}_cpp/${circuitName} "${input_path}" "${witness_path}" status_jswitgen=$? -echo "✓ Finished witness generation with js! ${status_jswitgen}" - -# TODO: Get C-based witness gen to work -# echo "/${build_dir}/${CIRCUIT_NAME}_cpp/${CIRCUIT_NAME} ${input_wallet_path} ${witness_path}" -# "/${build_dir}/${CIRCUIT_NAME}_cpp/${CIRCUIT_NAME}" "${input_wallet_path}" "${witness_path}" -# status_c_wit=$? - -# echo "Finished C witness gen! Status: ${status_c_wit}" -# if [ $status_c_wit -ne 0 ]; then -# echo "C based witness gen failed with status (might be on machine specs diff than compilation): ${status_c_wit}" -# exit 1 -# fi +echo "✓ Finished witness generation with cpp! ${status_jswitgen}" if [ $isLocal = 1 ]; then # DEFAULT SNARKJS PROVER (SLOW) @@ -43,14 +31,14 @@ if [ $isLocal = 1 ]; then status_prover=$? echo "✓ Finished slow proofgen! Status: ${status_prover}" else - # RAPIDSNARK PROVER (10x FASTER) - echo "ldd ${SCRIPT_DIR}/rapidsnark/build/prover" - ldd "${SCRIPT_DIR}/rapidsnark/build/prover" + # RAPIDSNARK PROVER GPU + echo "ldd ${SCRIPT_DIR}/rapidsnark/package/bin/prover_cuda" + ldd "${SCRIPT_DIR}/rapidsnark/package/bin/prover_cuda" status_lld=$? echo "✓ lld prover dependencies present! ${status_lld}" - echo "${SCRIPT_DIR}/rapidsnark/build/prover ${paramsDir}/${circuitName}.zkey ${witness_path} ${proof_path} ${public_path}" - "${SCRIPT_DIR}/rapidsnark/build/prover" "${paramsDir}/${circuitName}.zkey" "${witness_path}" "${proof_path}" "${public_path}" | tee /dev/stderr + echo "${SCRIPT_DIR}/rapidsnark/package/bin/prover_cuda ${paramsDir}/${circuitName}.zkey ${witness_path} ${proof_path} ${public_path}" + "${SCRIPT_DIR}/rapidsnark/package/bin/prover_cuda" "${paramsDir}/${circuitName}.zkey" "${witness_path}" "${proof_path}" "${public_path}" status_prover=$? echo "✓ Finished rapid proofgen! Status: ${status_prover}" fi diff --git a/packages/prover/core.py b/packages/prover/core.py index d182cc81..41c28531 100644 --- a/packages/prover/core.py +++ b/packages/prover/core.py @@ -1,6 +1,7 @@ import subprocess import os import json + import logging logger = logging.getLogger(__name__) @@ -31,6 +32,10 @@ def store_input(circuit_name: str, nonce: str, json_data: dict): logger.info(f"Store user input to {json_file_path}") with open(json_file_path, "w") as json_file: json_file.write(json_data) + # Read the file back + with open(json_file_path, "r") as json_file: + print(json_file.read()) + print("Stored input") def load_proof(circuit_name: str, nonce: str) -> dict: diff --git a/packages/prover/local_setup.sh b/packages/prover/local_setup.sh index b8266f1e..8f81a350 100755 --- a/packages/prover/local_setup.sh +++ b/packages/prover/local_setup.sh @@ -6,11 +6,32 @@ mkdir -p build npm install -g snarkjs@latest pip install -r requirements.txt mkdir build && cd build -gdown "https://drive.google.com/uc?id=1Ybtxe1TCVUtHzCPUs9cuZAGbM-MVwigE" -unzip params.zip +# gdown "https://drive.google.com/uc?id=1XDPFIL5YK8JzLGoTjmHLXO9zMDjSQcJH" +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth.zkey --output ./email_auth.zkey +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth --output ./email_auth +mkdir ./email_auth_cpp +cd ./email_auth_cpp +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth --output ./email_auth +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/Makefile --output ./Makefile +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/calcwit.cpp --output ./calcwit.cpp +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/calcwit.hpp --output ./calcwit.hpp +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/calcwit.o --output ./calcwit.o +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/circom.hpp --output ./circom.hpp +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/email_auth.cpp --output ./email_auth.cpp +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/email_auth.dat --output ./email_auth.dat +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/fr.asm --output ./fr.asm +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/fr.cpp --output ./fr.cpp +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/fr.hpp --output ./fr.hpp +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/fr.o --output ./fr.o +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/fr_asm.o --output ./fr_asm.o +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/main.cpp --output ./main.cpp +curl https://storage.googleapis.com/circom-ether-email-auth/v2.0.1-preview/email_auth_cpp/main.o --output ./main.o +chmod +x ./email_auth +cd ../../ +# unzip params.zip # curl https://email-wallet-trusted-setup-ceremony-pse-p0tion-production.s3.eu-central-1.amazonaws.com/circuits/emailwallet-account-creation/contributions/emailwallet-account-creation_00019.zkey --output /root/params/account_creation.zkey # curl https://email-wallet-trusted-setup-ceremony-pse-p0tion-production.s3.eu-central-1.amazonaws.com/circuits/emailwallet-account-init/contributions/emailwallet-account-init_00007.zkey --output /root/params/account_init.zkey # curl https://email-wallet-trusted-setup-ceremony-pse-p0tion-production.s3.eu-central-1.amazonaws.com/circuits/emailwallet-account-transport/contributions/emailwallet-account-transport_00005.zkey --output /root/params/account_transport.zkey # curl https://email-wallet-trusted-setup-ceremony-pse-p0tion-production.s3.eu-central-1.amazonaws.com/circuits/emailwallet-claim/contributions/emailwallet-claim_00006.zkey --output /root/params/claim.zkey # curl https://email-wallet-trusted-setup-ceremony-pse-p0tion-production.s3.eu-central-1.amazonaws.com/circuits/emailwallet-email-sender/contributions/emailwallet-email-sender_00006.zkey --output /root/params/email_sender.zkey -chmod +x circom_proofgen.sh +chmod +x circom_proofgen.sh \ No newline at end of file diff --git a/packages/prover/modal_server.py b/packages/prover/modal_server.py index 54b93b3d..d751a9cf 100644 --- a/packages/prover/modal_server.py +++ b/packages/prover/modal_server.py @@ -1,11 +1,12 @@ import modal + import logging from google.cloud.logging import Client from google.cloud.logging.handlers import CloudLoggingHandler from google.cloud.logging_v2.handlers import setup_logging from google.oauth2 import service_account -app = modal.App("email-auth-prover-v1.1.0") +app = modal.App("email-auth-prover-v1.5.2") image = modal.Image.from_dockerfile("Dockerfile") @@ -15,8 +16,10 @@ mounts=[ modal.Mount.from_local_python_packages("core"), ], - cpu=14, + cpu=1, + gpu="t4", secrets=[modal.Secret.from_name("gc-ether-email-auth-prover")], + keep_warm=True, ) @modal.wsgi_app() def flask_app(): diff --git a/packages/relayer/.env.example b/packages/relayer/.env.example index fe8fd1be..60deb675 100644 --- a/packages/relayer/.env.example +++ b/packages/relayer/.env.example @@ -1,21 +1,24 @@ -EMAIL_ACCOUNT_RECOVERY_VERSION_ID= # Version ID of the email account recovery. -PRIVATE_KEY= # Private key for Relayer's account. +EMAIL_ACCOUNT_RECOVERY_VERSION_ID=1 # Version ID of the email account recovery. +PRIVATE_KEY="" # Private key for Relayer's account. CHAIN_RPC_PROVIDER=http://127.0.0.1:8545 CHAIN_RPC_EXPLORER= CHAIN_ID=11155111 # Chain ID of the testnet. SMTP_SERVER= -PROVER_ADDRESS="https://zkemail--email-auth-prover-v1-0-4-flask-app.modal.run" +PROVER_ADDRESS="https://zkemail--email-auth-prover-v1-5-0-flask-app.modal.run" DATABASE_URL= "postgres://test@localhost/emailauth_test" RELAYER_EMAIL_ADDR= WEB_SERVER_ADDRESS="127.0.0.1:4500" -CIRCUITS_DIR_PATH= #Path to email-wallet/packages/circuits EMAIL_TEMPLATES_PATH= #Path to email templates, e.g. ./packages/relayer/eml_templates/ +REGEX_JSON_DIR_PATH= -CANISTER_ID="q7eci-dyaaa-aaaak-qdbia-cai" +DKIM_CANISTER_ID="fxmww-qiaaa-aaaaj-azu7a-cai" +WALLET_CANISTER_ID= PEM_PATH="./.ic.pem" -IC_REPLICA_URL="https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=q7eci-dyaaa-aaaak-qdbia-cai" +IC_REPLICA_URL="https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=fxmww-qiaaa-aaaaj-azu7a-cai" -JSON_LOGGER=false \ No newline at end of file +JSON_LOGGER=false + +ERROR_EMAIL_ADDR="error@example.com" \ No newline at end of file diff --git a/packages/relayer/CODING_GUIDELINES.md b/packages/relayer/CODING_GUIDELINES.md new file mode 100644 index 00000000..93043ca2 --- /dev/null +++ b/packages/relayer/CODING_GUIDELINES.md @@ -0,0 +1,98 @@ +# Coding Guidelines for Relayer + +This document outlines the coding guidelines for contributing to the Relayer. Following these guidelines will help maintain a consistent and high-quality codebase. + +## 1. Code Formatting + +- **Tool**: Use `rustfmt` to automatically format your code. Ensure that all code is formatted before committing. Run `cargo fmt` to format your code according to the project's style guidelines. +- **Indentation**: Use 4 spaces per indentation level. Do not use tabs. +- **Line Length**: Aim to keep lines under 100 characters, but it's not a strict rule. Use your judgment to ensure readability. +- **Imports**: Group imports into four sections: `extern crate`, `use`, `use crate`, and `use super`. + - Example: + ```rust + extern crate serde; + + use std::collections::HashMap; + use std::io::{self, Read}; + + use crate::utils::config; + + use super::super::common::logger; + ``` +- **Braces**: Use the Allman style for braces, where the opening brace is on the same line as the function signature. + - Example: + ```rust + fn main() { + // function body + } + ``` +- **Comments**: Use `//` for single-line comments and `/* ... */` for multi-line comments. +- **Whitespace**: Use a single space after commas and colons, and no space before commas and colons. + - Example: + ```rust + let numbers = vec![1, 2, 3]; + let user = User { name: "Alice", age: 30 }; + ``` +- **Function Length**: Aim to keep functions short and focused. If a function is too long, consider breaking it up into smaller functions. +- **Code Duplication**: Avoid duplicating code. If you find yourself copying and pasting code, consider refactoring it into a shared function or module. +- **No warnings**: Ensure that your code compiles without warnings. Fix any warnings before committing. + +## 2. Code Linting + +- **Tool**: Use `cargo clippy` to lint your code and catch common mistakes and improve your Rust code. Run `cargo clippy` before committing your code to ensure it adheres to Rust's best practices and the project's specific requirements. +- **Handling Lints**: Address all warnings and errors reported by `clippy`. If you must ignore a lint, use `#[allow(clippy::lint_name)]` and provide a comment explaining why. + +## 3. Naming Conventions + +- **Variables and Functions**: Use `snake_case`. + - Example: `let user_name = "Alice";` +- **Structs and Enums**: Use `PascalCase`. + - Example: `struct UserAccount { ... }` +- **Constants**: Use `UPPER_SNAKE_CASE`. + - Example: `const MAX_USERS: u32 = 100;` +- **Module Names**: Use `snake_case`. + - Example: `mod user_account;` + +## 4. Documentation + +- **Public Items**: All public functions, structs, and modules must have documentation comments using `///`. + - Example: + ```rust + /// Creates a new user account. + /// + /// # Arguments + /// + /// * `name` - The name of the user. + /// + /// # Returns + /// + /// A `UserAccount` struct. + pub fn create_user_account(name: &str) -> UserAccount { + // function body + } + ``` +- **Private Items**: Document private items where the intent or functionality is not immediately clear. +- **Module Documentation**: Each module should have a comment at the top explaining its purpose. + - Example: + ```rust + //! This module contains utility functions for user management. + + // module contents + ``` + +## 5. Error Handling + +- **Use of `Result` and `Option`**: + - Use `Result` for operations that can fail and `Option` for values that may or may not be present. + - Example: + ```rust + fn find_user(id: u32) -> Option { + // function body + } + + fn open_file(path: &str) -> Result { + // function body + } + ``` +- **Custom Error Types**: When appropriate, define custom error types using `enum` and implement the `anyhow::Error` trait. +- **Error Propagation**: Propagate errors using `?` where possible to simplify error handling. \ No newline at end of file diff --git a/packages/relayer/CONTRIBUTING.md b/packages/relayer/CONTRIBUTING.md new file mode 100644 index 00000000..b249c89d --- /dev/null +++ b/packages/relayer/CONTRIBUTING.md @@ -0,0 +1,116 @@ +# Contributing to Relayer + +Thank you for considering contributing to our project! We welcome contributions of all kinds, including code, documentation, bug reports, feature requests, and more. This document outlines the process for contributing to this project. + +## Table of Contents +- [Contributing to Relayer](#contributing-to-relayer) + - [Table of Contents](#table-of-contents) + - [1. Code of Conduct](#1-code-of-conduct) + - [2. Getting Started](#2-getting-started) + - [3. Coding Guidelines](#3-coding-guidelines) + - [4. Testing](#4-testing) + - [5. Commit Messages](#5-commit-messages) + - [6. Pull Request Process](#6-pull-request-process) + - [7. Contact](#7-contact) + +## 1. Code of Conduct +We are committed to providing a welcoming and inspiring community for all and expect our Code of Conduct to be honored. Anyone who violates this code of conduct may be banned from the community. + +Our community strives to: + +- **Be friendly and patient.** +- **Be welcoming**: We strive to be a community that welcomes and supports people of all backgrounds and identities. +- **Be considerate**: Your work will be used by other people, and you in turn will depend on the work of others. +- **Be respectful**: Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. +- **Be careful in the words that you choose**: We are a community of professionals, and we conduct ourselves professionally. +- **Be kind to others**: Do not insult or put down other participants. Harassment and other exclusionary behavior aren't acceptable. + +This includes, but is not limited to: + +- Violent threats or language directed against another person. +- Discriminatory jokes and language. +- Posting sexually explicit or violent material. +- Posting (or threatening to post) other people's personally identifying information ("doxing"). +- Personal insults, especially those using racist or sexist terms. +- Unwelcome sexual attention. +- Advocating for, or encouraging, any of the above behavior. +- Repeated harassment of others. In general, if someone asks you to stop, then stop. + +Moderation + +These are the policies for upholding our community’s standards of conduct. If you feel that a thread needs moderation, please contact the community team at [paradox@pse.dev](mailto:paradox@pse.dev). + +1. **Remarks that violate the Relayer Utils standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed.** (Cursing is allowed, but never targeting another user, and never in a hateful manner.) +2. **Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed.** +3. **Moderators will first respond to such remarks with a warning.** +4. **If the warning is unheeded, the user will be “kicked,” i.e., temporarily banned from the community.** +5. **If the user comes back and continues to make trouble, they will be banned permanently from the community.** +6. **Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology.** +7. **If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, in a private discussion.** + +**Please try to emulate these behaviors, especially when debating the merits of different options.** + +Thank you for helping make this a welcoming, friendly community for all. + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4, available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct.html](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html) + + +## 2. Getting Started +To start contributing, follow these steps: + +1. Fork the repository. +2. Clone your fork to your local machine: + ```bash + git clone https://github.com/zkemail/relayer-utils.git + ``` +3. Create a new branch for your feature or bugfix: + ```bash + git checkout -b feat/your-feature-name + ``` +4. Install the necessary dependencies: + ```bash + cargo build + ``` +5. Make your changes. + +## 3. Coding Guidelines + +Please follow the coding guidelines in [CODING_GUIDELINES.md](CODING_GUIDELINES.md) when contributing to this project. + +## 4. Testing + +Please write tests for your contributions. We aim for high test coverage. + + • Unit Tests: Place unit tests in the same file as the code they are testing. + • Integration Tests: Place integration tests in the tests/ directory. + +Run all tests before submitting your code with cargo test. + +Run all tests before submitting your code with cargo test. + +## 5. Commit Messages + +Use conventional commit messages for your commits. This helps us automatically generate the changelog and follow semantic versioning. + + • Format: `: ` + • Example: `feat: add new feature` + +For more information, see [Conventional Commits](https://www.conventionalcommits.org/). + +## 6. Pull Request Process + + 1. Ensure your branch is up-to-date with the main branch: + • git fetch origin + • git checkout main + • git merge origin/main + 2. Push your branch to your fork: + • git push origin feature/your-feature-name + 3. Open a pull request from your branch to the main branch of the original repository. + 4. Ensure that your pull request passes all checks (e.g., CI tests). + 5. A reviewer will review your pull request. Be prepared to make adjustments based on feedback. + +## 7. Contact + +If you have any questions or need further assistance, feel free to open an issue or contact us at [paradox@pse.dev](mailto:paradox@pse.dev). + +Thank you for your contributions! \ No newline at end of file diff --git a/packages/relayer/Cargo.toml b/packages/relayer/Cargo.toml index 2ce3120e..eb6d86f5 100644 --- a/packages/relayer/Cargo.toml +++ b/packages/relayer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "relayer" -version = "1.1.0" +version = "1.0.0" edition = "2021" [dependencies] @@ -24,7 +24,7 @@ serde_json = "1.0.68" tiny_http = "0.12.0" lettre = { version = "0.10.4", features = ["tokio1", "tokio1-native-tls"] } ethers = { version = "2.0.10", features = ["abigen"] } -relayer-utils = { git = "https://github.com/zkemail/relayer-utils", rev = "2c3e9b8" } +relayer-utils = { version = "0.4.2", git = "https://github.com/zkemail/relayer-utils.git" } futures = "0.3.28" sqlx = { version = "=0.7.3", features = ["postgres", "runtime-tokio"] } regex = "1.10.2" @@ -34,14 +34,11 @@ reqwest = "0.11.22" num-bigint = { version = "0.4", features = ["rand"] } num-traits = "0.2.16" hex = "0.4.3" -chrono = "0.4.31" +chrono = "0.4.38" ff = { version = "0.13.0", default-features = false, features = ["std"] } async-trait = "0.1.36" handlebars = "4.4.0" graphql_client = { version = "0.13.0", features = ["reqwest"] } -ic-utils = { version = "0.30.0" } -ic-agent = { version = "0.30.0", features = ["pem", "reqwest"] } -candid = "0.9.11" lazy_static = "1.4" slog = { version = "2.7.0", features = [ "max_level_trace", @@ -51,10 +48,14 @@ slog-async = "2.8.0" slog-term = "2.9.0" slog-json = "2.6.1" file-rotate = "0.7.5" -function_name = "0.3.0" base64 = "0.21.7" uuid = "1.8.0" http = "1.1.0" +ic-agent = { version = "0.37.1", features = ["pem", "reqwest"] } +ic-utils = "0.37.0" +candid = "0.10.10" +thiserror = "1.0.63" +rustc-hex = "2.1.0" [build-dependencies] ethers = "2.0.10" diff --git a/packages/relayer/README.md b/packages/relayer/README.md index e0ef2c5f..b89967b1 100644 --- a/packages/relayer/README.md +++ b/packages/relayer/README.md @@ -18,7 +18,7 @@ You can run the relayer either on your local environments or cloud instances (we PRIVATE_KEY="" CHAIN_ID=84532 RPC_URL="https://sepolia.base.org" - SIGNER=0x69bec2dd161d6bbcc91ec32aa44d9333ebc864c0 # Signer for the dkim oracle on IC (Don't change this) + SIGNER=0x6293a80bf4bd3fff995a0cab74cbf281d922da02 # Signer for the dkim oracle on IC (Don't change this) ETHERSCAN_API_KEY= # CHAIN_NAME="base_sepolia" ``` @@ -51,13 +51,12 @@ You can run the relayer either on your local environments or cloud instances (we DATABASE_URL= "postgres://new_user:my_secure_password@localhost/my_new_database" WEB_SERVER_ADDRESS="127.0.0.1:4500" - CIRCUITS_DIR_PATH= # Absolute path to packages/circuits EMAIL_TEMPLATES_PATH= # Absolute path to packages/relayer/eml_templates CANISTER_ID="q7eci-dyaaa-aaaak-qdbia-cai" PEM_PATH="./.ic.pem" IC_REPLICA_URL="https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=q7eci-dyaaa-aaaak-qdbia-cai" - + ERROR_EMAIL_ADDR="" # System user email address receiving error notification for user JSON_LOGGER=false ``` 3. Generate the `.ic.pem` file and password. diff --git a/packages/relayer/build.rs b/packages/relayer/build.rs index 28907c0e..f01e2d0e 100644 --- a/packages/relayer/build.rs +++ b/packages/relayer/build.rs @@ -10,14 +10,23 @@ fn main() { .unwrap() .write_to_file("./src/abis/email_auth.rs") .unwrap(); + // Abigen::new( + // "ECDSAOwnedDKIMRegistry", + // "../contracts/artifacts/ECDSAOwnedDKIMRegistry.sol/ECDSAOwnedDKIMRegistry.json", + // ) + // .unwrap() + // .generate() + // .unwrap() + // .write_to_file("./src/abis/ecdsa_owned_dkim_registry.rs") + // .unwrap(); Abigen::new( - "ECDSAOwnedDKIMRegistry", - "../contracts/artifacts/ECDSAOwnedDKIMRegistry.sol/ECDSAOwnedDKIMRegistry.json", + "UserOverridableDKIMRegistry", + "../contracts/artifacts/UserOverrideableDKIMRegistry.sol/UserOverrideableDKIMRegistry.json", ) .unwrap() .generate() .unwrap() - .write_to_file("./src/abis/ecdsa_owned_dkim_registry.rs") + .write_to_file("./src/abis/user_overridable_dkim_registry.rs") .unwrap(); Abigen::new( "EmailAccountRecovery", diff --git a/packages/relayer/eml_templates/acceptance_request.html b/packages/relayer/eml_templates/acceptance_request.html index 6c20379e..853efc6f 100644 --- a/packages/relayer/eml_templates/acceptance_request.html +++ b/packages/relayer/eml_templates/acceptance_request.html @@ -1,420 +1,257 @@ + - Email Auth + - Set Your Guardian Email - - + + + + + -   +
{{command}}
diff --git a/packages/relayer/eml_templates/acceptance_success.html b/packages/relayer/eml_templates/acceptance_success.html index 4e45a5b4..45908fee 100644 --- a/packages/relayer/eml_templates/acceptance_success.html +++ b/packages/relayer/eml_templates/acceptance_success.html @@ -1,414 +1,250 @@ + - Email Auth + - Guardian Email Set! - - + + + + + -   diff --git a/packages/relayer/eml_templates/acknowledgement.html b/packages/relayer/eml_templates/acknowledgement.html index 713ce805..6c720aa7 100644 --- a/packages/relayer/eml_templates/acknowledgement.html +++ b/packages/relayer/eml_templates/acknowledgement.html @@ -1,412 +1,249 @@ + - Email Wallet + - Email Wallet Acknowledgement - - + + + + + -   diff --git a/packages/relayer/eml_templates/credential_not_present.html b/packages/relayer/eml_templates/credential_not_present.html index d823a014..dde84e8d 100644 --- a/packages/relayer/eml_templates/credential_not_present.html +++ b/packages/relayer/eml_templates/credential_not_present.html @@ -1,417 +1,254 @@ + - Email Auth + - Credential Not Present - - + + + + + -   diff --git a/packages/relayer/eml_templates/error.html b/packages/relayer/eml_templates/error.html index aef12c26..52893dda 100644 --- a/packages/relayer/eml_templates/error.html +++ b/packages/relayer/eml_templates/error.html @@ -1,414 +1,250 @@ + - Email Auth + - Error - - + + + + + -   diff --git a/packages/relayer/eml_templates/error_for_admin.html b/packages/relayer/eml_templates/error_for_admin.html new file mode 100644 index 00000000..8b140036 --- /dev/null +++ b/packages/relayer/eml_templates/error_for_admin.html @@ -0,0 +1,264 @@ + + + + + + + + + + + + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + +
+ An error occurred while processing this request.
+ Error: {{error}} +
+ Request ID: {{requestId}} +
+ Command: {{command}} +
+ Account address: {{account_address}} +
+ Controller address: {{controller_address}} +
+ Email: {{email}} +
+ + + + + + +
+

+ Powered by + ZK Email +

+ + + + + + + +
+ + + + + + + +
+
+
+ + diff --git a/packages/relayer/eml_templates/guardian_already_exists.html b/packages/relayer/eml_templates/guardian_already_exists.html index 8d52d462..00a0192b 100644 --- a/packages/relayer/eml_templates/guardian_already_exists.html +++ b/packages/relayer/eml_templates/guardian_already_exists.html @@ -1,414 +1,251 @@ + - Email Auth + - Guardian Already Set - - + + + + + -   diff --git a/packages/relayer/eml_templates/guardian_not_set.html b/packages/relayer/eml_templates/guardian_not_set.html index 853bb3d6..4ad15982 100644 --- a/packages/relayer/eml_templates/guardian_not_set.html +++ b/packages/relayer/eml_templates/guardian_not_set.html @@ -1,412 +1,249 @@ + - Email Auth + - Guardian Not Set - - + + + + + -   diff --git a/packages/relayer/eml_templates/recovery_request.html b/packages/relayer/eml_templates/recovery_request.html index efb9d9ae..d09987f4 100644 --- a/packages/relayer/eml_templates/recovery_request.html +++ b/packages/relayer/eml_templates/recovery_request.html @@ -1,418 +1,256 @@ + - Email Auth + - Recovery Request - - + + + + + -   +
{{command}}
diff --git a/packages/relayer/eml_templates/recovery_success.html b/packages/relayer/eml_templates/recovery_success.html index d067c2f6..a9416ca4 100644 --- a/packages/relayer/eml_templates/recovery_success.html +++ b/packages/relayer/eml_templates/recovery_success.html @@ -1,414 +1,250 @@ + - Email Auth + - Recovery Successful - - + + + + + -   diff --git a/packages/relayer/src/abis/ecdsa_owned_dkim_registry.rs b/packages/relayer/src/abis/ecdsa_owned_dkim_registry.rs deleted file mode 100644 index 98f2b254..00000000 --- a/packages/relayer/src/abis/ecdsa_owned_dkim_registry.rs +++ /dev/null @@ -1,2333 +0,0 @@ -pub use ecdsa_owned_dkim_registry::*; -/// This module was auto-generated with ethers-rs Abigen. -/// More information at: -#[allow( - clippy::enum_variant_names, - clippy::too_many_arguments, - clippy::upper_case_acronyms, - clippy::type_complexity, - dead_code, - non_camel_case_types, -)] -pub mod ecdsa_owned_dkim_registry { - #[allow(deprecated)] - fn __abi() -> ::ethers::core::abi::Abi { - ::ethers::core::abi::ethabi::Contract { - constructor: ::core::option::Option::Some(::ethers::core::abi::ethabi::Constructor { - inputs: ::std::vec![], - }), - functions: ::core::convert::From::from([ - ( - ::std::borrow::ToOwned::to_owned("REVOKE_PREFIX"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("REVOKE_PREFIX"), - inputs: ::std::vec![], - outputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::String, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("string"), - ), - }, - ], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("SET_PREFIX"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("SET_PREFIX"), - inputs: ::std::vec![], - outputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::String, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("string"), - ), - }, - ], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("UPGRADE_INTERFACE_VERSION"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned( - "UPGRADE_INTERFACE_VERSION", - ), - inputs: ::std::vec![], - outputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::String, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("string"), - ), - }, - ], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("changeSigner"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("changeSigner"), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("_newSigner"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - }, - ], - outputs: ::std::vec![], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("computeSignedMsg"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("computeSignedMsg"), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("prefix"), - kind: ::ethers::core::abi::ethabi::ParamType::String, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("string"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("selector"), - kind: ::ethers::core::abi::ethabi::ParamType::String, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("string"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("domainName"), - kind: ::ethers::core::abi::ethabi::ParamType::String, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("string"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("publicKeyHash"), - kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( - 32usize, - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes32"), - ), - }, - ], - outputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::String, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("string"), - ), - }, - ], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::Pure, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("dkimRegistry"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("dkimRegistry"), - inputs: ::std::vec![], - outputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("contract DKIMRegistry"), - ), - }, - ], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("initialize"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("initialize"), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("_initialOwner"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("_signer"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - }, - ], - outputs: ::std::vec![], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("isDKIMPublicKeyHashValid"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned( - "isDKIMPublicKeyHashValid", - ), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("domainName"), - kind: ::ethers::core::abi::ethabi::ParamType::String, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("string"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("publicKeyHash"), - kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( - 32usize, - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes32"), - ), - }, - ], - outputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Bool, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bool"), - ), - }, - ], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("owner"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("owner"), - inputs: ::std::vec![], - outputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - }, - ], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("proxiableUUID"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("proxiableUUID"), - inputs: ::std::vec![], - outputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( - 32usize, - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes32"), - ), - }, - ], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("renounceOwnership"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("renounceOwnership"), - inputs: ::std::vec![], - outputs: ::std::vec![], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("revokeDKIMPublicKeyHash"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned( - "revokeDKIMPublicKeyHash", - ), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("selector"), - kind: ::ethers::core::abi::ethabi::ParamType::String, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("string"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("domainName"), - kind: ::ethers::core::abi::ethabi::ParamType::String, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("string"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("publicKeyHash"), - kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( - 32usize, - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes32"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("signature"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes"), - ), - }, - ], - outputs: ::std::vec![], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("setDKIMPublicKeyHash"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned( - "setDKIMPublicKeyHash", - ), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("selector"), - kind: ::ethers::core::abi::ethabi::ParamType::String, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("string"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("domainName"), - kind: ::ethers::core::abi::ethabi::ParamType::String, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("string"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("publicKeyHash"), - kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( - 32usize, - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes32"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("signature"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes"), - ), - }, - ], - outputs: ::std::vec![], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("signer"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("signer"), - inputs: ::std::vec![], - outputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - }, - ], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("transferOwnership"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("transferOwnership"), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("newOwner"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - }, - ], - outputs: ::std::vec![], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("upgradeToAndCall"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("upgradeToAndCall"), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("newImplementation"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("data"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes"), - ), - }, - ], - outputs: ::std::vec![], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::Payable, - }, - ], - ), - ]), - events: ::core::convert::From::from([ - ( - ::std::borrow::ToOwned::to_owned("Initialized"), - ::std::vec![ - ::ethers::core::abi::ethabi::Event { - name: ::std::borrow::ToOwned::to_owned("Initialized"), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("version"), - kind: ::ethers::core::abi::ethabi::ParamType::Uint(64usize), - indexed: false, - }, - ], - anonymous: false, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("OwnershipTransferred"), - ::std::vec![ - ::ethers::core::abi::ethabi::Event { - name: ::std::borrow::ToOwned::to_owned( - "OwnershipTransferred", - ), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("previousOwner"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - indexed: true, - }, - ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("newOwner"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - indexed: true, - }, - ], - anonymous: false, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("Upgraded"), - ::std::vec![ - ::ethers::core::abi::ethabi::Event { - name: ::std::borrow::ToOwned::to_owned("Upgraded"), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("implementation"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - indexed: true, - }, - ], - anonymous: false, - }, - ], - ), - ]), - errors: ::core::convert::From::from([ - ( - ::std::borrow::ToOwned::to_owned("AddressEmptyCode"), - ::std::vec![ - ::ethers::core::abi::ethabi::AbiError { - name: ::std::borrow::ToOwned::to_owned("AddressEmptyCode"), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("target"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - }, - ], - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("ECDSAInvalidSignature"), - ::std::vec![ - ::ethers::core::abi::ethabi::AbiError { - name: ::std::borrow::ToOwned::to_owned( - "ECDSAInvalidSignature", - ), - inputs: ::std::vec![], - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("ECDSAInvalidSignatureLength"), - ::std::vec![ - ::ethers::core::abi::ethabi::AbiError { - name: ::std::borrow::ToOwned::to_owned( - "ECDSAInvalidSignatureLength", - ), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("length"), - kind: ::ethers::core::abi::ethabi::ParamType::Uint( - 256usize, - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("uint256"), - ), - }, - ], - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("ECDSAInvalidSignatureS"), - ::std::vec![ - ::ethers::core::abi::ethabi::AbiError { - name: ::std::borrow::ToOwned::to_owned( - "ECDSAInvalidSignatureS", - ), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("s"), - kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( - 32usize, - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes32"), - ), - }, - ], - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("ERC1967InvalidImplementation"), - ::std::vec![ - ::ethers::core::abi::ethabi::AbiError { - name: ::std::borrow::ToOwned::to_owned( - "ERC1967InvalidImplementation", - ), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("implementation"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - }, - ], - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("ERC1967NonPayable"), - ::std::vec![ - ::ethers::core::abi::ethabi::AbiError { - name: ::std::borrow::ToOwned::to_owned("ERC1967NonPayable"), - inputs: ::std::vec![], - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("FailedInnerCall"), - ::std::vec![ - ::ethers::core::abi::ethabi::AbiError { - name: ::std::borrow::ToOwned::to_owned("FailedInnerCall"), - inputs: ::std::vec![], - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("InvalidInitialization"), - ::std::vec![ - ::ethers::core::abi::ethabi::AbiError { - name: ::std::borrow::ToOwned::to_owned( - "InvalidInitialization", - ), - inputs: ::std::vec![], - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("NotInitializing"), - ::std::vec![ - ::ethers::core::abi::ethabi::AbiError { - name: ::std::borrow::ToOwned::to_owned("NotInitializing"), - inputs: ::std::vec![], - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("OwnableInvalidOwner"), - ::std::vec![ - ::ethers::core::abi::ethabi::AbiError { - name: ::std::borrow::ToOwned::to_owned( - "OwnableInvalidOwner", - ), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("owner"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - }, - ], - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("OwnableUnauthorizedAccount"), - ::std::vec![ - ::ethers::core::abi::ethabi::AbiError { - name: ::std::borrow::ToOwned::to_owned( - "OwnableUnauthorizedAccount", - ), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("account"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - }, - ], - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("StringsInsufficientHexLength"), - ::std::vec![ - ::ethers::core::abi::ethabi::AbiError { - name: ::std::borrow::ToOwned::to_owned( - "StringsInsufficientHexLength", - ), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("value"), - kind: ::ethers::core::abi::ethabi::ParamType::Uint( - 256usize, - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("uint256"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("length"), - kind: ::ethers::core::abi::ethabi::ParamType::Uint( - 256usize, - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("uint256"), - ), - }, - ], - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("UUPSUnauthorizedCallContext"), - ::std::vec![ - ::ethers::core::abi::ethabi::AbiError { - name: ::std::borrow::ToOwned::to_owned( - "UUPSUnauthorizedCallContext", - ), - inputs: ::std::vec![], - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("UUPSUnsupportedProxiableUUID"), - ::std::vec![ - ::ethers::core::abi::ethabi::AbiError { - name: ::std::borrow::ToOwned::to_owned( - "UUPSUnsupportedProxiableUUID", - ), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("slot"), - kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( - 32usize, - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes32"), - ), - }, - ], - }, - ], - ), - ]), - receive: false, - fallback: false, - } - } - ///The parsed JSON ABI of the contract. - pub static ECDSAOWNEDDKIMREGISTRY_ABI: ::ethers::contract::Lazy< - ::ethers::core::abi::Abi, - > = ::ethers::contract::Lazy::new(__abi); - #[rustfmt::skip] - const __BYTECODE: &[u8] = b"`\xA0`@R0`\x80R4\x80\x15`\x13W`\0\x80\xFD[P`\x80Qa/~a\0=`\09`\0\x81\x81a\x115\x01R\x81\x81a\x11^\x01Ra\x13\x7F\x01Ra/~`\0\xF3\xFE`\x80`@R`\x046\x10a\0\xF3W`\x005`\xE0\x1C\x80c\x97\x17\x0F+\x11a\0\x8AW\x80c\xD5\x07\xC3 \x11a\0YW\x80c\xD5\x07\xC3 \x14a\x036W\x80c\xE7\xA7\x97z\x14a\x03\x7FW\x80c\xF2\xFD\xE3\x8B\x14a\x03\xAFW\x80c\xF6\xB4\x93D\x14a\x03\xCFW`\0\x80\xFD[\x80c\x97\x17\x0F+\x14a\x02\x8DW\x80c\xAA\xD2\xB7#\x14a\x02\xADW\x80c\xAD<\xB1\xCC\x14a\x02\xCDW\x80c\xAE\xC7\x93a\x14a\x03\x16W`\0\x80\xFD[\x80cR\xD1\x90-\x11a\0\xC6W\x80cR\xD1\x90-\x14a\x01\xDEW\x80cd#\xF1\xE2\x14a\x02\x01W\x80cqP\x18\xA6\x14a\x02.W\x80c\x8D\xA5\xCB[\x14a\x02CW`\0\x80\xFD[\x80c\x07\xF1\xEA\xF5\x14a\0\xF8W\x80c#\x8A\xC93\x14a\x01WW\x80cH\\\xC9U\x14a\x01\xA9W\x80cO\x1E\xF2\x86\x14a\x01\xCBW[`\0\x80\xFD[4\x80\x15a\x01\x04W`\0\x80\xFD[Pa\x01A`@Q\x80`@\x01`@R\x80`\x04\x81R` \x01\x7FSET:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81RP\x81V[`@Qa\x01N\x91\x90a\x1F\x9CV[`@Q\x80\x91\x03\x90\xF3[4\x80\x15a\x01cW`\0\x80\xFD[P`\x01Ta\x01\x84\x90s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x81V[`@Qs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x81R` \x01a\x01NV[4\x80\x15a\x01\xB5W`\0\x80\xFD[Pa\x01\xC9a\x01\xC46`\x04a\x1F\xD8V[a\x03\xEFV[\0[a\x01\xC9a\x01\xD96`\x04a \xEEV[a\x06\x0BV[4\x80\x15a\x01\xEAW`\0\x80\xFD[Pa\x01\xF3a\x06*V[`@Q\x90\x81R` \x01a\x01NV[4\x80\x15a\x02\rW`\0\x80\xFD[P`\0Ta\x01\x84\x90s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x81V[4\x80\x15a\x02:W`\0\x80\xFD[Pa\x01\xC9a\x06YV[4\x80\x15a\x02OW`\0\x80\xFD[P\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16a\x01\x84V[4\x80\x15a\x02\x99W`\0\x80\xFD[Pa\x01\xC9a\x02\xA86`\x04a!#\xA9f.\xFC\x9C\"\x9Cj\0\x80Th\x01\0\0\0\0\0\0\0\0\x81\x04`\xFF\x16\x15\x90g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16`\0\x81\x15\x80\x15a\x04:WP\x82[\x90P`\0\x82g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16`\x01\x14\x80\x15a\x04WWP0;\x15[\x90P\x81\x15\x80\x15a\x04eWP\x80\x15[\x15a\x04\x9CW`@Q\x7F\xF9.\xE8\xA9\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x84T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x16`\x01\x17\x85U\x83\x15a\x04\xFDW\x84T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16h\x01\0\0\0\0\0\0\0\0\x17\x85U[a\x05\x06\x87a\x11\x0CV[0`@Qa\x05\x13\x90a\x1F!V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x81R` \x01`@Q\x80\x91\x03\x90`\0\xF0\x80\x15\x80\x15a\x05LW=`\0\x80>=`\0\xFD[P`\0\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x90\x81\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x93\x84\x16\x17\x90\x91U`\x01\x80T\x90\x91\x16\x91\x88\x16\x91\x90\x91\x17\x90U\x83\x15a\x06\x02W\x84T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x85U`@Q`\x01\x81R\x7F\xC7\xF5\x05\xB2\xF3q\xAE!u\xEEI\x13\xF4I\x9E\x1F&3\xA7\xB5\x93c!\xEE\xD1\xCD\xAE\xB6\x11Q\x81\xD2\x90` \x01`@Q\x80\x91\x03\x90\xA1[PPPPPPPV[a\x06\x13a\x11\x1DV[a\x06\x1C\x82a\x12!V[a\x06&\x82\x82a\x12)V[PPV[`\0a\x064a\x13gV[P\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\x90V[a\x06aa\x13\xD6V[a\x06k`\0a\x14dV[V[\x83Q`\0\x03a\x06\xDDW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x10`$\x82\x01R\x7FInvalid selector\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01[`@Q\x80\x91\x03\x90\xFD[\x82Q`\0\x03a\x07HW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x13`$\x82\x01R\x7FInvalid domain name\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[\x81a\x07\xAFW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x17`$\x82\x01R\x7FInvalid public key hash\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[a\x07\xB9\x83\x83a\x0C\x1DV[\x15a\x08 W`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x1C`$\x82\x01R\x7FpublicKeyHash is already set\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[`\0T`@Q\x7FB\xD7\xCB\x98\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x84\x90Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x90cB\xD7\xCB\x98\x90`$\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x08\x8FW=`\0\x80>=`\0\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x08\xB3\x91\x90a\"\xD6V[\x15a\t\x1AW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x18`$\x82\x01R\x7FpublicKeyHash is revoked\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[`\0a\t]`@Q\x80`@\x01`@R\x80`\x04\x81R` \x01\x7FSET:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81RP\x86\x86\x86a\x0B\xE3V[\x90P`\0a\tj\x82a\x14\xFAV[\x90P`\0a\tx\x82\x85a\x155V[`\x01T\x90\x91Ps\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x83\x16\x91\x16\x14a\t\xFFW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x11`$\x82\x01R\x7FInvalid signature\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[`\0T`@Q\x7F\xC1\\\xFF\xAB\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x90c\xC1\\\xFF\xAB\x90a\nW\x90\x89\x90\x89\x90`\x04\x01a\"\xF8V[`\0`@Q\x80\x83\x03\x81`\0\x87\x80;\x15\x80\x15a\nqW`\0\x80\xFD[PZ\xF1\x15\x80\x15a\n\x85W=`\0\x80>=`\0\xFD[PPPPPPPPPPPV[a\n\x9Aa\x13\xD6V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16a\x0B\x17W`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x0E`$\x82\x01R\x7FInvalid signer\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[`\x01Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x81\x16\x90\x82\x16\x03a\x0B\x9CW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x0B`$\x82\x01R\x7FSame signer\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[`\x01\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x92\x90\x92\x16\x91\x90\x91\x17\x90UV[``\x84\x84\x84a\x0B\xF1\x85a\x15_V[`@Q` \x01a\x0C\x04\x94\x93\x92\x91\x90a#\x1AV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P\x94\x93PPPPV[`\0\x80T`@Q\x7F\xE7\xA7\x97z\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x90c\xE7\xA7\x97z\x90a\x0Cv\x90\x86\x90\x86\x90`\x04\x01a\"\xF8V[` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x0C\x93W=`\0\x80>=`\0\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x0C\xB7\x91\x90a\"\xD6V[\x90P[\x92\x91PPV[a\x0C\xC8a\x13\xD6V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16a\r\x18W`@Q\x7F\x1EO\xBD\xF7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\0`\x04\x82\x01R`$\x01a\x06\xD4V[a\r!\x81a\x14dV[PV[\x83Q`\0\x03a\r\x8FW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x10`$\x82\x01R\x7FInvalid selector\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[\x82Q`\0\x03a\r\xFAW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x13`$\x82\x01R\x7FInvalid domain name\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[\x81a\x0EaW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x17`$\x82\x01R\x7FInvalid public key hash\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[a\x0Ek\x83\x83a\x0C\x1DV[\x15\x15`\x01\x14a\x0E\xD6W`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x18`$\x82\x01R\x7FpublicKeyHash is not set\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[`\0T`@Q\x7FB\xD7\xCB\x98\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x84\x90Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x90cB\xD7\xCB\x98\x90`$\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x0FEW=`\0\x80>=`\0\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x0Fi\x91\x90a\"\xD6V[\x15a\x0F\xD0W`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01\x81\x90R`$\x82\x01R\x7FpublicKeyHash is already revoked`D\x82\x01R`d\x01a\x06\xD4V[`\0a\x10\x13`@Q\x80`@\x01`@R\x80`\x07\x81R` \x01\x7FREVOKE:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81RP\x86\x86\x86a\x0B\xE3V[\x90P`\0a\x10 \x82a\x14\xFAV[\x90P`\0a\x10.\x82\x85a\x155V[`\x01T\x90\x91Ps\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x83\x16\x91\x16\x14a\x10\xB5W`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x11`$\x82\x01R\x7FInvalid signature\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[`\0T`@Q\x7F\x15\xD2Q.\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x87\x90Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x90c\x15\xD2Q.\x90`$\x01a\nWV[a\x11\x14a\x15vV[a\r!\x81a\x15\xDDV[0s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14\x80a\x11\xEAWP\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16a\x11\xD1\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBCTs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x90V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x14\x15[\x15a\x06kW`@Q\x7F\xE0|\x8D\xBA\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\r!a\x13\xD6V[\x81s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16cR\xD1\x90-`@Q\x81c\xFF\xFF\xFF\xFF\x16`\xE0\x1B\x81R`\x04\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x92PPP\x80\x15a\x12\xAEWP`@\x80Q`\x1F=\x90\x81\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16\x82\x01\x90\x92Ra\x12\xAB\x91\x81\x01\x90a$\x1EV[`\x01[a\x12\xFCW`@Q\x7FL\x9C\x8C\xE3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16`\x04\x82\x01R`$\x01a\x06\xD4V[\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\x81\x14a\x13XW`@Q\x7F\xAA\x1DI\xA4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06\xD4V[a\x13b\x83\x83a\x15\xE5V[PPPV[0s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14a\x06kW`@Q\x7F\xE0|\x8D\xBA\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[3a\x14\x15\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x90V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x14a\x06kW`@Q\x7F\x11\x8C\xDA\xA7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R3`\x04\x82\x01R`$\x01a\x06\xD4V[\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x81\x16\x91\x82\x17\x84U`@Q\x92\x16\x91\x82\x90\x7F\x8B\xE0\x07\x9CS\x16Y\x14\x13D\xCD\x1F\xD0\xA4\xF2\x84\x19I\x7F\x97\"\xA3\xDA\xAF\xE3\xB4\x18okdW\xE0\x90`\0\x90\xA3PPPV[`\0a\x15\x06\x82Qa\x16HV[\x82`@Q` \x01a\x15\x18\x92\x91\x90a$7V[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x80Q\x90` \x01 \x90P\x91\x90PV[`\0\x80`\0\x80a\x15E\x86\x86a\x17\x06V[\x92P\x92P\x92Pa\x15U\x82\x82a\x17SV[P\x90\x94\x93PPPPV[``a\x0C\xBA\x82a\x15n\x84a\x18WV[`\x01\x01a\x18\xC1V[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0Th\x01\0\0\0\0\0\0\0\0\x90\x04`\xFF\x16a\x06kW`@Q\x7F\xD7\xE6\xBC\xF8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x0C\xC8a\x15vV[a\x15\xEE\x82a\x1A\xE7V[`@Qs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16\x90\x7F\xBC|\xD7Z \xEE'\xFD\x9A\xDE\xBA\xB3 A\xF7U!M\xBCk\xFF\xA9\x0C\xC0\"[9\xDA.\\-;\x90`\0\x90\xA2\x80Q\x15a\x16@Wa\x13b\x82\x82a\x1B\xB6V[a\x06&a\x1C9V[```\0a\x16U\x83a\x1CqV[`\x01\x01\x90P`\0\x81g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\x16uWa\x16ua \x0BV[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a\x16\x9FW` \x82\x01\x81\x806\x837\x01\x90P[P\x90P\x81\x81\x01` \x01[\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01\x7F0123456789abcdef\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\n\x86\x06\x1A\x81S`\n\x85\x04\x94P\x84a\x16\xA9WP\x93\x92PPPV[`\0\x80`\0\x83Q`A\x03a\x17@W` \x84\x01Q`@\x85\x01Q``\x86\x01Q`\0\x1Aa\x172\x88\x82\x85\x85a\x1DSV[\x95P\x95P\x95PPPPa\x17LV[PP\x81Q`\0\x91P`\x02\x90[\x92P\x92P\x92V[`\0\x82`\x03\x81\x11\x15a\x17gWa\x17ga$\x92V[\x03a\x17pWPPV[`\x01\x82`\x03\x81\x11\x15a\x17\x84Wa\x17\x84a$\x92V[\x03a\x17\xBBW`@Q\x7F\xF6E\xEE\xDF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02\x82`\x03\x81\x11\x15a\x17\xCFWa\x17\xCFa$\x92V[\x03a\x18\tW`@Q\x7F\xFC\xE6\x98\xF7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06\xD4V[`\x03\x82`\x03\x81\x11\x15a\x18\x1DWa\x18\x1Da$\x92V[\x03a\x06&W`@Q\x7F\xD7\x8B\xCE\x0C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06\xD4V[`\0\x80`\x80\x83\x90\x1C\x15a\x18oW`\x80\x92\x90\x92\x1C\x91`\x10\x01[`@\x83\x90\x1C\x15a\x18\x84W`@\x92\x90\x92\x1C\x91`\x08\x01[` \x83\x90\x1C\x15a\x18\x99W` \x92\x90\x92\x1C\x91`\x04\x01[`\x10\x83\x90\x1C\x15a\x18\xAEW`\x10\x92\x90\x92\x1C\x91`\x02\x01[`\x08\x83\x90\x1C\x15a\x0C\xBAW`\x01\x01\x92\x91PPV[``\x82`\0a\x18\xD1\x84`\x02a$\xF0V[a\x18\xDC\x90`\x02a%\x07V[g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\x18\xF4Wa\x18\xF4a \x0BV[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a\x19\x1EW` \x82\x01\x81\x806\x837\x01\x90P[P\x90P\x7F0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81`\0\x81Q\x81\x10a\x19UWa\x19Ua%\x1AV[` \x01\x01\x90~\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16\x90\x81`\0\x1A\x90SP\x7Fx\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81`\x01\x81Q\x81\x10a\x19\xB8Wa\x19\xB8a%\x1AV[` \x01\x01\x90~\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16\x90\x81`\0\x1A\x90SP`\0a\x19\xF4\x85`\x02a$\xF0V[a\x19\xFF\x90`\x01a%\x07V[\x90P[`\x01\x81\x11\x15a\x1A\x9CW\x7F0123456789abcdef\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x83`\x0F\x16`\x10\x81\x10a\x1A@Wa\x1A@a%\x1AV[\x1A`\xF8\x1B\x82\x82\x81Q\x81\x10a\x1AVWa\x1AVa%\x1AV[` \x01\x01\x90~\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16\x90\x81`\0\x1A\x90SP`\x04\x92\x90\x92\x1C\x91a\x1A\x95\x81a%IV[\x90Pa\x1A\x02V[P\x81\x15a\x1A\xDFW`@Q\x7F\xE2.'\xEB\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x86\x90R`$\x81\x01\x85\x90R`D\x01a\x06\xD4V[\x94\x93PPPPV[\x80s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16;`\0\x03a\x1BPW`@Q\x7FL\x9C\x8C\xE3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x16`\x04\x82\x01R`$\x01a\x06\xD4V[\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x92\x90\x92\x16\x91\x90\x91\x17\x90UV[```\0\x80\x84s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x84`@Qa\x1B\xE0\x91\x90a%~V[`\0`@Q\x80\x83\x03\x81\x85Z\xF4\x91PP=\x80`\0\x81\x14a\x1C\x1BW`@Q\x91P`\x1F\x19`?=\x01\x16\x82\x01`@R=\x82R=`\0` \x84\x01>a\x1C V[``\x91P[P\x91P\x91Pa\x1C0\x85\x83\x83a\x1EMV[\x95\x94PPPPPV[4\x15a\x06kW`@Q\x7F\xB3\x98\x97\x9F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\0\x80z\x18O\x03\xE9?\xF9\xF4\xDA\xA7\x97\xEDn8\xEDd\xBFj\x1F\x01\0\0\0\0\0\0\0\0\x83\x10a\x1C\xBAWz\x18O\x03\xE9?\xF9\xF4\xDA\xA7\x97\xEDn8\xEDd\xBFj\x1F\x01\0\0\0\0\0\0\0\0\x83\x04\x92P`@\x01[m\x04\xEE-mA[\x85\xAC\xEF\x81\0\0\0\0\x83\x10a\x1C\xE6Wm\x04\xEE-mA[\x85\xAC\xEF\x81\0\0\0\0\x83\x04\x92P` \x01[f#\x86\xF2o\xC1\0\0\x83\x10a\x1D\x04Wf#\x86\xF2o\xC1\0\0\x83\x04\x92P`\x10\x01[c\x05\xF5\xE1\0\x83\x10a\x1D\x1CWc\x05\xF5\xE1\0\x83\x04\x92P`\x08\x01[a'\x10\x83\x10a\x1D0Wa'\x10\x83\x04\x92P`\x04\x01[`d\x83\x10a\x1DBW`d\x83\x04\x92P`\x02\x01[`\n\x83\x10a\x0C\xBAW`\x01\x01\x92\x91PPV[`\0\x80\x80\x7F\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF]WnsW\xA4P\x1D\xDF\xE9/Fh\x1B \xA0\x84\x11\x15a\x1D\x8EWP`\0\x91P`\x03\x90P\x82a\x1ECV[`@\x80Q`\0\x80\x82R` \x82\x01\x80\x84R\x8A\x90R`\xFF\x89\x16\x92\x82\x01\x92\x90\x92R``\x81\x01\x87\x90R`\x80\x81\x01\x86\x90R`\x01\x90`\xA0\x01` `@Q` \x81\x03\x90\x80\x84\x03\x90\x85Z\xFA\x15\x80\x15a\x1D\xE2W=`\0\x80>=`\0\xFD[PP`@Q\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x01Q\x91PPs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16a\x1E9WP`\0\x92P`\x01\x91P\x82\x90Pa\x1ECV[\x92P`\0\x91P\x81\x90P[\x94P\x94P\x94\x91PPV[``\x82a\x1EbWa\x1E]\x82a\x1E\xDFV[a\x1E\xD8V[\x81Q\x15\x80\x15a\x1E\x86WPs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x16;\x15[\x15a\x1E\xD5W`@Q\x7F\x99\x96\xB3\x15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x85\x16`\x04\x82\x01R`$\x01a\x06\xD4V[P\x80[\x93\x92PPPV[\x80Q\x15a\x1E\xEFW\x80Q\x80\x82` \x01\xFD[`@Q\x7F\x14%\xEAB\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\t\xAE\x80a%\x9B\x839\x01\x90V[`\0[\x83\x81\x10\x15a\x1FIW\x81\x81\x01Q\x83\x82\x01R` \x01a\x1F1V[PP`\0\x91\x01RV[`\0\x81Q\x80\x84Ra\x1Fj\x81` \x86\x01` \x86\x01a\x1F.V[`\x1F\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16\x92\x90\x92\x01` \x01\x92\x91PPV[` \x81R`\0a\x0C\xB7` \x83\x01\x84a\x1FRV[\x805s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16\x81\x14a\x1F\xD3W`\0\x80\xFD[\x91\x90PV[`\0\x80`@\x83\x85\x03\x12\x15a\x1F\xEBW`\0\x80\xFD[a\x1F\xF4\x83a\x1F\xAFV[\x91Pa \x02` \x84\x01a\x1F\xAFV[\x90P\x92P\x92\x90PV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`A`\x04R`$`\0\xFD[`\0\x82`\x1F\x83\x01\x12a KW`\0\x80\xFD[\x815` \x83\x01`\0\x80g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x11\x15a lWa la \x0BV[P`@Q\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0`\x1F\x85\x01\x81\x16`?\x01\x16\x81\x01\x81\x81\x10g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x11\x17\x15a \xB9Wa \xB9a \x0BV[`@R\x83\x81R\x90P\x80\x82\x84\x01\x87\x10\x15a \xD1W`\0\x80\xFD[\x83\x83` \x83\x017`\0` \x85\x83\x01\x01R\x80\x94PPPPP\x92\x91PPV[`\0\x80`@\x83\x85\x03\x12\x15a!\x01W`\0\x80\xFD[a!\n\x83a\x1F\xAFV[\x91P` \x83\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a!&W`\0\x80\xFD[a!2\x85\x82\x86\x01a :V[\x91PP\x92P\x92\x90PV[`\0\x80`\0\x80`\x80\x85\x87\x03\x12\x15a!RW`\0\x80\xFD[\x845g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a!iW`\0\x80\xFD[a!u\x87\x82\x88\x01a :V[\x94PP` \x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a!\x92W`\0\x80\xFD[a!\x9E\x87\x82\x88\x01a :V[\x93PP`@\x85\x015\x91P``\x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a!\xC2W`\0\x80\xFD[a!\xCE\x87\x82\x88\x01a :V[\x91PP\x92\x95\x91\x94P\x92PV[`\0` \x82\x84\x03\x12\x15a!\xECW`\0\x80\xFD[a\x0C\xB7\x82a\x1F\xAFV[`\0\x80`\0\x80`\x80\x85\x87\x03\x12\x15a\"\x0BW`\0\x80\xFD[\x845g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\"\"W`\0\x80\xFD[a\".\x87\x82\x88\x01a :V[\x94PP` \x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\"KW`\0\x80\xFD[a\"W\x87\x82\x88\x01a :V[\x93PP`@\x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\"tW`\0\x80\xFD[a\"\x80\x87\x82\x88\x01a :V[\x94\x97\x93\x96P\x93\x94``\x015\x93PPPV[`\0\x80`@\x83\x85\x03\x12\x15a\"\xA4W`\0\x80\xFD[\x825g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\"\xBBW`\0\x80\xFD[a\"\xC7\x85\x82\x86\x01a :V[\x95` \x94\x90\x94\x015\x94PPPPV[`\0` \x82\x84\x03\x12\x15a\"\xE8W`\0\x80\xFD[\x81Q\x80\x15\x15\x81\x14a\x1E\xD8W`\0\x80\xFD[`@\x81R`\0a#\x0B`@\x83\x01\x85a\x1FRV[\x90P\x82` \x83\x01R\x93\x92PPPV[`\0\x85Qa#,\x81\x84` \x8A\x01a\x1F.V[\x7Fselector=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x90\x83\x01\x90\x81R\x85Qa#f\x81`\t\x84\x01` \x8A\x01a\x1F.V[\x7F;domain=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\t\x92\x90\x91\x01\x91\x82\x01R\x84Qa#\xA4\x81`\x11\x84\x01` \x89\x01a\x1F.V[`\t\x81\x83\x01\x01\x91PP\x7F;public_key_hash=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\x08\x82\x01R\x83Qa#\xE6\x81`\x19\x84\x01` \x88\x01a\x1F.V[\x7F;\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\x19\x92\x90\x91\x01\x91\x82\x01R`\x1A\x01\x96\x95PPPPPPV[`\0` \x82\x84\x03\x12\x15a$0W`\0\x80\xFD[PQ\x91\x90PV[\x7F\x19Ethereum Signed Message:\n\0\0\0\0\0\0\x81R`\0\x83Qa$o\x81`\x1A\x85\x01` \x88\x01a\x1F.V[\x83Q\x90\x83\x01\x90a$\x86\x81`\x1A\x84\x01` \x88\x01a\x1F.V[\x01`\x1A\x01\x94\x93PPPPV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`!`\x04R`$`\0\xFD[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`\x11`\x04R`$`\0\xFD[\x80\x82\x02\x81\x15\x82\x82\x04\x84\x14\x17a\x0C\xBAWa\x0C\xBAa$\xC1V[\x80\x82\x01\x80\x82\x11\x15a\x0C\xBAWa\x0C\xBAa$\xC1V[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`2`\x04R`$`\0\xFD[`\0\x81a%XWa%Xa$\xC1V[P\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01\x90V[`\0\x82Qa%\x90\x81\x84` \x87\x01a\x1F.V[\x91\x90\x91\x01\x92\x91PPV\xFE`\x80`@R4\x80\x15a\0\x10W`\0\x80\xFD[P`@Qa\t\xAE8\x03\x80a\t\xAE\x839\x81\x01`@\x81\x90Ra\0/\x91a\0\xBEV[\x80`\x01`\x01`\xA0\x1B\x03\x81\x16a\0^W`@Qc\x1EO\xBD\xF7`\xE0\x1B\x81R`\0`\x04\x82\x01R`$\x01`@Q\x80\x91\x03\x90\xFD[a\0g\x81a\0nV[PPa\0\xEEV[`\0\x80T`\x01`\x01`\xA0\x1B\x03\x83\x81\x16`\x01`\x01`\xA0\x1B\x03\x19\x83\x16\x81\x17\x84U`@Q\x91\x90\x92\x16\x92\x83\x91\x7F\x8B\xE0\x07\x9CS\x16Y\x14\x13D\xCD\x1F\xD0\xA4\xF2\x84\x19I\x7F\x97\"\xA3\xDA\xAF\xE3\xB4\x18okdW\xE0\x91\x90\xA3PPV[`\0` \x82\x84\x03\x12\x15a\0\xD0W`\0\x80\xFD[\x81Q`\x01`\x01`\xA0\x1B\x03\x81\x16\x81\x14a\0\xE7W`\0\x80\xFD[\x93\x92PPPV[a\x08\xB1\x80a\0\xFD`\09`\0\xF3\xFE`\x80`@R4\x80\x15a\0\x10W`\0\x80\xFD[P`\x046\x10a\0\xA3W`\x005`\xE0\x1C\x80c\x8D\xA5\xCB[\x11a\0vW\x80c\xE7\xA7\x97z\x11a\0[W\x80c\xE7\xA7\x97z\x14a\x01vW\x80c\xF2\xFD\xE3\x8B\x14a\x01\x89W\x80c\xF4\x9E\xB1d\x14a\x01\x9CW`\0\x80\xFD[\x80c\x8D\xA5\xCB[\x14a\x01;W\x80c\xC1\\\xFF\xAB\x14a\x01cW`\0\x80\xFD[\x80c\x06\x90\xBD8\x14a\0\xA8W\x80c\x15\xD2Q.\x14a\0\xFBW\x80cB\xD7\xCB\x98\x14a\x01\x10W\x80cqP\x18\xA6\x14a\x013W[`\0\x80\xFD[a\0\xE6a\0\xB66`\x04a\x069V[\x81Q` \x81\x84\x01\x81\x01\x80Q`\x01\x82R\x92\x82\x01\x94\x82\x01\x94\x90\x94 \x91\x90\x93R\x90\x91R`\0\x90\x81R`@\x90 T`\xFF\x16\x81V[`@Q\x90\x15\x15\x81R` \x01[`@Q\x80\x91\x03\x90\xF3[a\x01\x0Ea\x01\t6`\x04a\x06~V[a\x01\xAFV[\0[a\0\xE6a\x01\x1E6`\x04a\x06~V[`\x02` R`\0\x90\x81R`@\x90 T`\xFF\x16\x81V[a\x01\x0Ea\x02+V[`\0T`@Qs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x81R` \x01a\0\xF2V[a\x01\x0Ea\x01q6`\x04a\x069V[a\x02?V[a\0\xE6a\x01\x846`\x04a\x069V[a\x03YV[a\x01\x0Ea\x01\x976`\x04a\x06\x97V[a\x03\xBDV[a\x01\x0Ea\x01\xAA6`\x04a\x06\xD4V[a\x04!V[a\x01\xB7a\x04eV[`\0\x81\x81R`\x02` R`@\x90\x81\x90 \x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\x16`\x01\x17\x90UQ\x7F\xB8\x0F\xFF+Lo=\xDF\x80Hw\x92|w\xB2\xFE\x18q\xCE\xCA\xA5\xADC\xD2\xC7\xC4/As1\xF8e\x90a\x02 \x90\x83\x81R` \x01\x90V[`@Q\x80\x91\x03\x90\xA1PV[a\x023a\x04eV[a\x02=`\0a\x04\xB8V[V[a\x02Ga\x04eV[`\0\x81\x81R`\x02` R`@\x90 T`\xFF\x16\x15a\x02\xC5W`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x19`$\x82\x01R\x7Fcannot set revoked pubkey\0\0\0\0\0\0\0`D\x82\x01R`d\x01[`@Q\x80\x91\x03\x90\xFD[`\x01\x80\x83`@Qa\x02\xD6\x91\x90a\x07\xD7V[\x90\x81R`@\x80Q` \x92\x81\x90\x03\x83\x01\x81 `\0\x86\x81R\x93R\x91 \x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\x16\x92\x15\x15\x92\x90\x92\x17\x90\x91U\x7FQ\r\xAC\x88\xEA\xF2\xDF\xBDS\x90BA\xFC\x19\x9A\xD4k c\xE6\xBFl?\xB2\x91\xF8\xCE\x86Cf4\x19\x90a\x03M\x90\x84\x90\x84\x90a\x07\xF3V[`@Q\x80\x91\x03\x90\xA1PPV[`\0\x81\x81R`\x02` R`@\x81 T`\xFF\x16\x15a\x03xWP`\0a\x03\xB7V[`\x01\x83`@Qa\x03\x88\x91\x90a\x07\xD7V[\x90\x81R`@\x80Q` \x92\x81\x90\x03\x83\x01\x90 `\0\x85\x81R\x92R\x90 T`\xFF\x16\x15a\x03\xB3WP`\x01a\x03\xB7V[P`\0[\x92\x91PPV[a\x03\xC5a\x04eV[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16a\x04\x15W`@Q\x7F\x1EO\xBD\xF7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\0`\x04\x82\x01R`$\x01a\x02\xBCV[a\x04\x1E\x81a\x04\xB8V[PV[a\x04)a\x04eV[`\0[\x81Q\x81\x10\x15a\x04`Wa\x04X\x83\x83\x83\x81Q\x81\x10a\x04KWa\x04Ka\x08LV[` \x02` \x01\x01Qa\x02?V[`\x01\x01a\x04,V[PPPV[`\0Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x163\x14a\x02=W`@Q\x7F\x11\x8C\xDA\xA7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R3`\x04\x82\x01R`$\x01a\x02\xBCV[`\0\x80Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x81\x16\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x83\x16\x81\x17\x84U`@Q\x91\x90\x92\x16\x92\x83\x91\x7F\x8B\xE0\x07\x9CS\x16Y\x14\x13D\xCD\x1F\xD0\xA4\xF2\x84\x19I\x7F\x97\"\xA3\xDA\xAF\xE3\xB4\x18okdW\xE0\x91\x90\xA3PPV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`A`\x04R`$`\0\xFD[`@Q`\x1F\x82\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16\x81\x01g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x82\x82\x10\x17\x15a\x05\xA3Wa\x05\xA3a\x05-V[`@R\x91\x90PV[`\0\x82`\x1F\x83\x01\x12a\x05\xBCW`\0\x80\xFD[\x815g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\x05\xD6Wa\x05\xD6a\x05-V[a\x06\x07` \x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0`\x1F\x84\x01\x16\x01a\x05\\V[\x81\x81R\x84` \x83\x86\x01\x01\x11\x15a\x06\x1CW`\0\x80\xFD[\x81` \x85\x01` \x83\x017`\0\x91\x81\x01` \x01\x91\x90\x91R\x93\x92PPPV[`\0\x80`@\x83\x85\x03\x12\x15a\x06LW`\0\x80\xFD[\x825g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\x06cW`\0\x80\xFD[a\x06o\x85\x82\x86\x01a\x05\xABV[\x95` \x94\x90\x94\x015\x94PPPPV[`\0` \x82\x84\x03\x12\x15a\x06\x90W`\0\x80\xFD[P5\x91\x90PV[`\0` \x82\x84\x03\x12\x15a\x06\xA9W`\0\x80\xFD[\x815s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16\x81\x14a\x06\xCDW`\0\x80\xFD[\x93\x92PPPV[`\0\x80`@\x83\x85\x03\x12\x15a\x06\xE7W`\0\x80\xFD[\x825g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\x06\xFEW`\0\x80\xFD[a\x07\n\x85\x82\x86\x01a\x05\xABV[\x92PP` \x83\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\x07'W`\0\x80\xFD[\x83\x01`\x1F\x81\x01\x85\x13a\x078W`\0\x80\xFD[\x805g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\x07RWa\x07Ra\x05-V[\x80`\x05\x1Ba\x07b` \x82\x01a\x05\\V[\x91\x82R` \x81\x84\x01\x81\x01\x92\x90\x81\x01\x90\x88\x84\x11\x15a\x07~W`\0\x80\xFD[` \x85\x01\x94P[\x83\x85\x10\x15a\x07\xA4W\x845\x80\x83R` \x95\x86\x01\x95\x90\x93P\x90\x91\x01\x90a\x07\x85V[\x80\x95PPPPPP\x92P\x92\x90PV[`\0[\x83\x81\x10\x15a\x07\xCEW\x81\x81\x01Q\x83\x82\x01R` \x01a\x07\xB6V[PP`\0\x91\x01RV[`\0\x82Qa\x07\xE9\x81\x84` \x87\x01a\x07\xB3V[\x91\x90\x91\x01\x92\x91PPV[`@\x81R`\0\x83Q\x80`@\x84\x01Ra\x08\x12\x81``\x85\x01` \x88\x01a\x07\xB3V[` \x83\x01\x93\x90\x93RP`\x1F\x91\x90\x91\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16\x01``\x01\x91\x90PV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`2`\x04R`$`\0\xFD\xFE\xA2dipfsX\"\x12 -\x9Ee\xDAg\xA8\x9E\x94XP\xBB\xE47ClV\x95\xD85 \x14\x95XA\xAAs\xAA\x1C\xC4\x15\xD3IdsolcC\0\x08\x1A\x003\xA2dipfsX\"\x12 \x0E[\xF6h\xD37\xAE[\x83m\x7F\x86So\xD0\x05\xCE\xD9Ui~\xD1\xF0\x7F\xC3\xF4C\xC1b\xFE\x136dsolcC\0\x08\x1A\x003"; - /// The bytecode of the contract. - pub static ECDSAOWNEDDKIMREGISTRY_BYTECODE: ::ethers::core::types::Bytes = ::ethers::core::types::Bytes::from_static( - __BYTECODE, - ); - #[rustfmt::skip] - const __DEPLOYED_BYTECODE: &[u8] = b"`\x80`@R`\x046\x10a\0\xF3W`\x005`\xE0\x1C\x80c\x97\x17\x0F+\x11a\0\x8AW\x80c\xD5\x07\xC3 \x11a\0YW\x80c\xD5\x07\xC3 \x14a\x036W\x80c\xE7\xA7\x97z\x14a\x03\x7FW\x80c\xF2\xFD\xE3\x8B\x14a\x03\xAFW\x80c\xF6\xB4\x93D\x14a\x03\xCFW`\0\x80\xFD[\x80c\x97\x17\x0F+\x14a\x02\x8DW\x80c\xAA\xD2\xB7#\x14a\x02\xADW\x80c\xAD<\xB1\xCC\x14a\x02\xCDW\x80c\xAE\xC7\x93a\x14a\x03\x16W`\0\x80\xFD[\x80cR\xD1\x90-\x11a\0\xC6W\x80cR\xD1\x90-\x14a\x01\xDEW\x80cd#\xF1\xE2\x14a\x02\x01W\x80cqP\x18\xA6\x14a\x02.W\x80c\x8D\xA5\xCB[\x14a\x02CW`\0\x80\xFD[\x80c\x07\xF1\xEA\xF5\x14a\0\xF8W\x80c#\x8A\xC93\x14a\x01WW\x80cH\\\xC9U\x14a\x01\xA9W\x80cO\x1E\xF2\x86\x14a\x01\xCBW[`\0\x80\xFD[4\x80\x15a\x01\x04W`\0\x80\xFD[Pa\x01A`@Q\x80`@\x01`@R\x80`\x04\x81R` \x01\x7FSET:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81RP\x81V[`@Qa\x01N\x91\x90a\x1F\x9CV[`@Q\x80\x91\x03\x90\xF3[4\x80\x15a\x01cW`\0\x80\xFD[P`\x01Ta\x01\x84\x90s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x81V[`@Qs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x81R` \x01a\x01NV[4\x80\x15a\x01\xB5W`\0\x80\xFD[Pa\x01\xC9a\x01\xC46`\x04a\x1F\xD8V[a\x03\xEFV[\0[a\x01\xC9a\x01\xD96`\x04a \xEEV[a\x06\x0BV[4\x80\x15a\x01\xEAW`\0\x80\xFD[Pa\x01\xF3a\x06*V[`@Q\x90\x81R` \x01a\x01NV[4\x80\x15a\x02\rW`\0\x80\xFD[P`\0Ta\x01\x84\x90s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x81V[4\x80\x15a\x02:W`\0\x80\xFD[Pa\x01\xC9a\x06YV[4\x80\x15a\x02OW`\0\x80\xFD[P\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16a\x01\x84V[4\x80\x15a\x02\x99W`\0\x80\xFD[Pa\x01\xC9a\x02\xA86`\x04a!#\xA9f.\xFC\x9C\"\x9Cj\0\x80Th\x01\0\0\0\0\0\0\0\0\x81\x04`\xFF\x16\x15\x90g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16`\0\x81\x15\x80\x15a\x04:WP\x82[\x90P`\0\x82g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16`\x01\x14\x80\x15a\x04WWP0;\x15[\x90P\x81\x15\x80\x15a\x04eWP\x80\x15[\x15a\x04\x9CW`@Q\x7F\xF9.\xE8\xA9\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x84T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x16`\x01\x17\x85U\x83\x15a\x04\xFDW\x84T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16h\x01\0\0\0\0\0\0\0\0\x17\x85U[a\x05\x06\x87a\x11\x0CV[0`@Qa\x05\x13\x90a\x1F!V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x81R` \x01`@Q\x80\x91\x03\x90`\0\xF0\x80\x15\x80\x15a\x05LW=`\0\x80>=`\0\xFD[P`\0\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x90\x81\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x93\x84\x16\x17\x90\x91U`\x01\x80T\x90\x91\x16\x91\x88\x16\x91\x90\x91\x17\x90U\x83\x15a\x06\x02W\x84T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x85U`@Q`\x01\x81R\x7F\xC7\xF5\x05\xB2\xF3q\xAE!u\xEEI\x13\xF4I\x9E\x1F&3\xA7\xB5\x93c!\xEE\xD1\xCD\xAE\xB6\x11Q\x81\xD2\x90` \x01`@Q\x80\x91\x03\x90\xA1[PPPPPPPV[a\x06\x13a\x11\x1DV[a\x06\x1C\x82a\x12!V[a\x06&\x82\x82a\x12)V[PPV[`\0a\x064a\x13gV[P\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\x90V[a\x06aa\x13\xD6V[a\x06k`\0a\x14dV[V[\x83Q`\0\x03a\x06\xDDW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x10`$\x82\x01R\x7FInvalid selector\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01[`@Q\x80\x91\x03\x90\xFD[\x82Q`\0\x03a\x07HW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x13`$\x82\x01R\x7FInvalid domain name\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[\x81a\x07\xAFW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x17`$\x82\x01R\x7FInvalid public key hash\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[a\x07\xB9\x83\x83a\x0C\x1DV[\x15a\x08 W`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x1C`$\x82\x01R\x7FpublicKeyHash is already set\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[`\0T`@Q\x7FB\xD7\xCB\x98\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x84\x90Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x90cB\xD7\xCB\x98\x90`$\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x08\x8FW=`\0\x80>=`\0\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x08\xB3\x91\x90a\"\xD6V[\x15a\t\x1AW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x18`$\x82\x01R\x7FpublicKeyHash is revoked\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[`\0a\t]`@Q\x80`@\x01`@R\x80`\x04\x81R` \x01\x7FSET:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81RP\x86\x86\x86a\x0B\xE3V[\x90P`\0a\tj\x82a\x14\xFAV[\x90P`\0a\tx\x82\x85a\x155V[`\x01T\x90\x91Ps\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x83\x16\x91\x16\x14a\t\xFFW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x11`$\x82\x01R\x7FInvalid signature\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[`\0T`@Q\x7F\xC1\\\xFF\xAB\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x90c\xC1\\\xFF\xAB\x90a\nW\x90\x89\x90\x89\x90`\x04\x01a\"\xF8V[`\0`@Q\x80\x83\x03\x81`\0\x87\x80;\x15\x80\x15a\nqW`\0\x80\xFD[PZ\xF1\x15\x80\x15a\n\x85W=`\0\x80>=`\0\xFD[PPPPPPPPPPPV[a\n\x9Aa\x13\xD6V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16a\x0B\x17W`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x0E`$\x82\x01R\x7FInvalid signer\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[`\x01Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x81\x16\x90\x82\x16\x03a\x0B\x9CW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x0B`$\x82\x01R\x7FSame signer\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[`\x01\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x92\x90\x92\x16\x91\x90\x91\x17\x90UV[``\x84\x84\x84a\x0B\xF1\x85a\x15_V[`@Q` \x01a\x0C\x04\x94\x93\x92\x91\x90a#\x1AV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P\x94\x93PPPPV[`\0\x80T`@Q\x7F\xE7\xA7\x97z\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x90c\xE7\xA7\x97z\x90a\x0Cv\x90\x86\x90\x86\x90`\x04\x01a\"\xF8V[` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x0C\x93W=`\0\x80>=`\0\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x0C\xB7\x91\x90a\"\xD6V[\x90P[\x92\x91PPV[a\x0C\xC8a\x13\xD6V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16a\r\x18W`@Q\x7F\x1EO\xBD\xF7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\0`\x04\x82\x01R`$\x01a\x06\xD4V[a\r!\x81a\x14dV[PV[\x83Q`\0\x03a\r\x8FW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x10`$\x82\x01R\x7FInvalid selector\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[\x82Q`\0\x03a\r\xFAW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x13`$\x82\x01R\x7FInvalid domain name\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[\x81a\x0EaW`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x17`$\x82\x01R\x7FInvalid public key hash\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[a\x0Ek\x83\x83a\x0C\x1DV[\x15\x15`\x01\x14a\x0E\xD6W`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x18`$\x82\x01R\x7FpublicKeyHash is not set\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[`\0T`@Q\x7FB\xD7\xCB\x98\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x84\x90Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x90cB\xD7\xCB\x98\x90`$\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x0FEW=`\0\x80>=`\0\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x0Fi\x91\x90a\"\xD6V[\x15a\x0F\xD0W`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01\x81\x90R`$\x82\x01R\x7FpublicKeyHash is already revoked`D\x82\x01R`d\x01a\x06\xD4V[`\0a\x10\x13`@Q\x80`@\x01`@R\x80`\x07\x81R` \x01\x7FREVOKE:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81RP\x86\x86\x86a\x0B\xE3V[\x90P`\0a\x10 \x82a\x14\xFAV[\x90P`\0a\x10.\x82\x85a\x155V[`\x01T\x90\x91Ps\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x83\x16\x91\x16\x14a\x10\xB5W`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x11`$\x82\x01R\x7FInvalid signature\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\xD4V[`\0T`@Q\x7F\x15\xD2Q.\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x87\x90Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x90c\x15\xD2Q.\x90`$\x01a\nWV[a\x11\x14a\x15vV[a\r!\x81a\x15\xDDV[0s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14\x80a\x11\xEAWP\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16a\x11\xD1\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBCTs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x90V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x14\x15[\x15a\x06kW`@Q\x7F\xE0|\x8D\xBA\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\r!a\x13\xD6V[\x81s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16cR\xD1\x90-`@Q\x81c\xFF\xFF\xFF\xFF\x16`\xE0\x1B\x81R`\x04\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x92PPP\x80\x15a\x12\xAEWP`@\x80Q`\x1F=\x90\x81\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16\x82\x01\x90\x92Ra\x12\xAB\x91\x81\x01\x90a$\x1EV[`\x01[a\x12\xFCW`@Q\x7FL\x9C\x8C\xE3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16`\x04\x82\x01R`$\x01a\x06\xD4V[\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\x81\x14a\x13XW`@Q\x7F\xAA\x1DI\xA4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06\xD4V[a\x13b\x83\x83a\x15\xE5V[PPPV[0s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14a\x06kW`@Q\x7F\xE0|\x8D\xBA\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[3a\x14\x15\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x90V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x14a\x06kW`@Q\x7F\x11\x8C\xDA\xA7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R3`\x04\x82\x01R`$\x01a\x06\xD4V[\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x81\x16\x91\x82\x17\x84U`@Q\x92\x16\x91\x82\x90\x7F\x8B\xE0\x07\x9CS\x16Y\x14\x13D\xCD\x1F\xD0\xA4\xF2\x84\x19I\x7F\x97\"\xA3\xDA\xAF\xE3\xB4\x18okdW\xE0\x90`\0\x90\xA3PPPV[`\0a\x15\x06\x82Qa\x16HV[\x82`@Q` \x01a\x15\x18\x92\x91\x90a$7V[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x80Q\x90` \x01 \x90P\x91\x90PV[`\0\x80`\0\x80a\x15E\x86\x86a\x17\x06V[\x92P\x92P\x92Pa\x15U\x82\x82a\x17SV[P\x90\x94\x93PPPPV[``a\x0C\xBA\x82a\x15n\x84a\x18WV[`\x01\x01a\x18\xC1V[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0Th\x01\0\0\0\0\0\0\0\0\x90\x04`\xFF\x16a\x06kW`@Q\x7F\xD7\xE6\xBC\xF8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x0C\xC8a\x15vV[a\x15\xEE\x82a\x1A\xE7V[`@Qs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16\x90\x7F\xBC|\xD7Z \xEE'\xFD\x9A\xDE\xBA\xB3 A\xF7U!M\xBCk\xFF\xA9\x0C\xC0\"[9\xDA.\\-;\x90`\0\x90\xA2\x80Q\x15a\x16@Wa\x13b\x82\x82a\x1B\xB6V[a\x06&a\x1C9V[```\0a\x16U\x83a\x1CqV[`\x01\x01\x90P`\0\x81g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\x16uWa\x16ua \x0BV[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a\x16\x9FW` \x82\x01\x81\x806\x837\x01\x90P[P\x90P\x81\x81\x01` \x01[\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01\x7F0123456789abcdef\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\n\x86\x06\x1A\x81S`\n\x85\x04\x94P\x84a\x16\xA9WP\x93\x92PPPV[`\0\x80`\0\x83Q`A\x03a\x17@W` \x84\x01Q`@\x85\x01Q``\x86\x01Q`\0\x1Aa\x172\x88\x82\x85\x85a\x1DSV[\x95P\x95P\x95PPPPa\x17LV[PP\x81Q`\0\x91P`\x02\x90[\x92P\x92P\x92V[`\0\x82`\x03\x81\x11\x15a\x17gWa\x17ga$\x92V[\x03a\x17pWPPV[`\x01\x82`\x03\x81\x11\x15a\x17\x84Wa\x17\x84a$\x92V[\x03a\x17\xBBW`@Q\x7F\xF6E\xEE\xDF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02\x82`\x03\x81\x11\x15a\x17\xCFWa\x17\xCFa$\x92V[\x03a\x18\tW`@Q\x7F\xFC\xE6\x98\xF7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06\xD4V[`\x03\x82`\x03\x81\x11\x15a\x18\x1DWa\x18\x1Da$\x92V[\x03a\x06&W`@Q\x7F\xD7\x8B\xCE\x0C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06\xD4V[`\0\x80`\x80\x83\x90\x1C\x15a\x18oW`\x80\x92\x90\x92\x1C\x91`\x10\x01[`@\x83\x90\x1C\x15a\x18\x84W`@\x92\x90\x92\x1C\x91`\x08\x01[` \x83\x90\x1C\x15a\x18\x99W` \x92\x90\x92\x1C\x91`\x04\x01[`\x10\x83\x90\x1C\x15a\x18\xAEW`\x10\x92\x90\x92\x1C\x91`\x02\x01[`\x08\x83\x90\x1C\x15a\x0C\xBAW`\x01\x01\x92\x91PPV[``\x82`\0a\x18\xD1\x84`\x02a$\xF0V[a\x18\xDC\x90`\x02a%\x07V[g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\x18\xF4Wa\x18\xF4a \x0BV[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a\x19\x1EW` \x82\x01\x81\x806\x837\x01\x90P[P\x90P\x7F0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81`\0\x81Q\x81\x10a\x19UWa\x19Ua%\x1AV[` \x01\x01\x90~\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16\x90\x81`\0\x1A\x90SP\x7Fx\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81`\x01\x81Q\x81\x10a\x19\xB8Wa\x19\xB8a%\x1AV[` \x01\x01\x90~\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16\x90\x81`\0\x1A\x90SP`\0a\x19\xF4\x85`\x02a$\xF0V[a\x19\xFF\x90`\x01a%\x07V[\x90P[`\x01\x81\x11\x15a\x1A\x9CW\x7F0123456789abcdef\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x83`\x0F\x16`\x10\x81\x10a\x1A@Wa\x1A@a%\x1AV[\x1A`\xF8\x1B\x82\x82\x81Q\x81\x10a\x1AVWa\x1AVa%\x1AV[` \x01\x01\x90~\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16\x90\x81`\0\x1A\x90SP`\x04\x92\x90\x92\x1C\x91a\x1A\x95\x81a%IV[\x90Pa\x1A\x02V[P\x81\x15a\x1A\xDFW`@Q\x7F\xE2.'\xEB\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x86\x90R`$\x81\x01\x85\x90R`D\x01a\x06\xD4V[\x94\x93PPPPV[\x80s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16;`\0\x03a\x1BPW`@Q\x7FL\x9C\x8C\xE3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x16`\x04\x82\x01R`$\x01a\x06\xD4V[\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x92\x90\x92\x16\x91\x90\x91\x17\x90UV[```\0\x80\x84s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x84`@Qa\x1B\xE0\x91\x90a%~V[`\0`@Q\x80\x83\x03\x81\x85Z\xF4\x91PP=\x80`\0\x81\x14a\x1C\x1BW`@Q\x91P`\x1F\x19`?=\x01\x16\x82\x01`@R=\x82R=`\0` \x84\x01>a\x1C V[``\x91P[P\x91P\x91Pa\x1C0\x85\x83\x83a\x1EMV[\x95\x94PPPPPV[4\x15a\x06kW`@Q\x7F\xB3\x98\x97\x9F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\0\x80z\x18O\x03\xE9?\xF9\xF4\xDA\xA7\x97\xEDn8\xEDd\xBFj\x1F\x01\0\0\0\0\0\0\0\0\x83\x10a\x1C\xBAWz\x18O\x03\xE9?\xF9\xF4\xDA\xA7\x97\xEDn8\xEDd\xBFj\x1F\x01\0\0\0\0\0\0\0\0\x83\x04\x92P`@\x01[m\x04\xEE-mA[\x85\xAC\xEF\x81\0\0\0\0\x83\x10a\x1C\xE6Wm\x04\xEE-mA[\x85\xAC\xEF\x81\0\0\0\0\x83\x04\x92P` \x01[f#\x86\xF2o\xC1\0\0\x83\x10a\x1D\x04Wf#\x86\xF2o\xC1\0\0\x83\x04\x92P`\x10\x01[c\x05\xF5\xE1\0\x83\x10a\x1D\x1CWc\x05\xF5\xE1\0\x83\x04\x92P`\x08\x01[a'\x10\x83\x10a\x1D0Wa'\x10\x83\x04\x92P`\x04\x01[`d\x83\x10a\x1DBW`d\x83\x04\x92P`\x02\x01[`\n\x83\x10a\x0C\xBAW`\x01\x01\x92\x91PPV[`\0\x80\x80\x7F\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF]WnsW\xA4P\x1D\xDF\xE9/Fh\x1B \xA0\x84\x11\x15a\x1D\x8EWP`\0\x91P`\x03\x90P\x82a\x1ECV[`@\x80Q`\0\x80\x82R` \x82\x01\x80\x84R\x8A\x90R`\xFF\x89\x16\x92\x82\x01\x92\x90\x92R``\x81\x01\x87\x90R`\x80\x81\x01\x86\x90R`\x01\x90`\xA0\x01` `@Q` \x81\x03\x90\x80\x84\x03\x90\x85Z\xFA\x15\x80\x15a\x1D\xE2W=`\0\x80>=`\0\xFD[PP`@Q\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x01Q\x91PPs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16a\x1E9WP`\0\x92P`\x01\x91P\x82\x90Pa\x1ECV[\x92P`\0\x91P\x81\x90P[\x94P\x94P\x94\x91PPV[``\x82a\x1EbWa\x1E]\x82a\x1E\xDFV[a\x1E\xD8V[\x81Q\x15\x80\x15a\x1E\x86WPs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x16;\x15[\x15a\x1E\xD5W`@Q\x7F\x99\x96\xB3\x15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x85\x16`\x04\x82\x01R`$\x01a\x06\xD4V[P\x80[\x93\x92PPPV[\x80Q\x15a\x1E\xEFW\x80Q\x80\x82` \x01\xFD[`@Q\x7F\x14%\xEAB\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\t\xAE\x80a%\x9B\x839\x01\x90V[`\0[\x83\x81\x10\x15a\x1FIW\x81\x81\x01Q\x83\x82\x01R` \x01a\x1F1V[PP`\0\x91\x01RV[`\0\x81Q\x80\x84Ra\x1Fj\x81` \x86\x01` \x86\x01a\x1F.V[`\x1F\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16\x92\x90\x92\x01` \x01\x92\x91PPV[` \x81R`\0a\x0C\xB7` \x83\x01\x84a\x1FRV[\x805s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16\x81\x14a\x1F\xD3W`\0\x80\xFD[\x91\x90PV[`\0\x80`@\x83\x85\x03\x12\x15a\x1F\xEBW`\0\x80\xFD[a\x1F\xF4\x83a\x1F\xAFV[\x91Pa \x02` \x84\x01a\x1F\xAFV[\x90P\x92P\x92\x90PV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`A`\x04R`$`\0\xFD[`\0\x82`\x1F\x83\x01\x12a KW`\0\x80\xFD[\x815` \x83\x01`\0\x80g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x11\x15a lWa la \x0BV[P`@Q\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0`\x1F\x85\x01\x81\x16`?\x01\x16\x81\x01\x81\x81\x10g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x11\x17\x15a \xB9Wa \xB9a \x0BV[`@R\x83\x81R\x90P\x80\x82\x84\x01\x87\x10\x15a \xD1W`\0\x80\xFD[\x83\x83` \x83\x017`\0` \x85\x83\x01\x01R\x80\x94PPPPP\x92\x91PPV[`\0\x80`@\x83\x85\x03\x12\x15a!\x01W`\0\x80\xFD[a!\n\x83a\x1F\xAFV[\x91P` \x83\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a!&W`\0\x80\xFD[a!2\x85\x82\x86\x01a :V[\x91PP\x92P\x92\x90PV[`\0\x80`\0\x80`\x80\x85\x87\x03\x12\x15a!RW`\0\x80\xFD[\x845g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a!iW`\0\x80\xFD[a!u\x87\x82\x88\x01a :V[\x94PP` \x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a!\x92W`\0\x80\xFD[a!\x9E\x87\x82\x88\x01a :V[\x93PP`@\x85\x015\x91P``\x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a!\xC2W`\0\x80\xFD[a!\xCE\x87\x82\x88\x01a :V[\x91PP\x92\x95\x91\x94P\x92PV[`\0` \x82\x84\x03\x12\x15a!\xECW`\0\x80\xFD[a\x0C\xB7\x82a\x1F\xAFV[`\0\x80`\0\x80`\x80\x85\x87\x03\x12\x15a\"\x0BW`\0\x80\xFD[\x845g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\"\"W`\0\x80\xFD[a\".\x87\x82\x88\x01a :V[\x94PP` \x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\"KW`\0\x80\xFD[a\"W\x87\x82\x88\x01a :V[\x93PP`@\x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\"tW`\0\x80\xFD[a\"\x80\x87\x82\x88\x01a :V[\x94\x97\x93\x96P\x93\x94``\x015\x93PPPV[`\0\x80`@\x83\x85\x03\x12\x15a\"\xA4W`\0\x80\xFD[\x825g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\"\xBBW`\0\x80\xFD[a\"\xC7\x85\x82\x86\x01a :V[\x95` \x94\x90\x94\x015\x94PPPPV[`\0` \x82\x84\x03\x12\x15a\"\xE8W`\0\x80\xFD[\x81Q\x80\x15\x15\x81\x14a\x1E\xD8W`\0\x80\xFD[`@\x81R`\0a#\x0B`@\x83\x01\x85a\x1FRV[\x90P\x82` \x83\x01R\x93\x92PPPV[`\0\x85Qa#,\x81\x84` \x8A\x01a\x1F.V[\x7Fselector=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x90\x83\x01\x90\x81R\x85Qa#f\x81`\t\x84\x01` \x8A\x01a\x1F.V[\x7F;domain=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\t\x92\x90\x91\x01\x91\x82\x01R\x84Qa#\xA4\x81`\x11\x84\x01` \x89\x01a\x1F.V[`\t\x81\x83\x01\x01\x91PP\x7F;public_key_hash=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\x08\x82\x01R\x83Qa#\xE6\x81`\x19\x84\x01` \x88\x01a\x1F.V[\x7F;\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\x19\x92\x90\x91\x01\x91\x82\x01R`\x1A\x01\x96\x95PPPPPPV[`\0` \x82\x84\x03\x12\x15a$0W`\0\x80\xFD[PQ\x91\x90PV[\x7F\x19Ethereum Signed Message:\n\0\0\0\0\0\0\x81R`\0\x83Qa$o\x81`\x1A\x85\x01` \x88\x01a\x1F.V[\x83Q\x90\x83\x01\x90a$\x86\x81`\x1A\x84\x01` \x88\x01a\x1F.V[\x01`\x1A\x01\x94\x93PPPPV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`!`\x04R`$`\0\xFD[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`\x11`\x04R`$`\0\xFD[\x80\x82\x02\x81\x15\x82\x82\x04\x84\x14\x17a\x0C\xBAWa\x0C\xBAa$\xC1V[\x80\x82\x01\x80\x82\x11\x15a\x0C\xBAWa\x0C\xBAa$\xC1V[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`2`\x04R`$`\0\xFD[`\0\x81a%XWa%Xa$\xC1V[P\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01\x90V[`\0\x82Qa%\x90\x81\x84` \x87\x01a\x1F.V[\x91\x90\x91\x01\x92\x91PPV\xFE`\x80`@R4\x80\x15a\0\x10W`\0\x80\xFD[P`@Qa\t\xAE8\x03\x80a\t\xAE\x839\x81\x01`@\x81\x90Ra\0/\x91a\0\xBEV[\x80`\x01`\x01`\xA0\x1B\x03\x81\x16a\0^W`@Qc\x1EO\xBD\xF7`\xE0\x1B\x81R`\0`\x04\x82\x01R`$\x01`@Q\x80\x91\x03\x90\xFD[a\0g\x81a\0nV[PPa\0\xEEV[`\0\x80T`\x01`\x01`\xA0\x1B\x03\x83\x81\x16`\x01`\x01`\xA0\x1B\x03\x19\x83\x16\x81\x17\x84U`@Q\x91\x90\x92\x16\x92\x83\x91\x7F\x8B\xE0\x07\x9CS\x16Y\x14\x13D\xCD\x1F\xD0\xA4\xF2\x84\x19I\x7F\x97\"\xA3\xDA\xAF\xE3\xB4\x18okdW\xE0\x91\x90\xA3PPV[`\0` \x82\x84\x03\x12\x15a\0\xD0W`\0\x80\xFD[\x81Q`\x01`\x01`\xA0\x1B\x03\x81\x16\x81\x14a\0\xE7W`\0\x80\xFD[\x93\x92PPPV[a\x08\xB1\x80a\0\xFD`\09`\0\xF3\xFE`\x80`@R4\x80\x15a\0\x10W`\0\x80\xFD[P`\x046\x10a\0\xA3W`\x005`\xE0\x1C\x80c\x8D\xA5\xCB[\x11a\0vW\x80c\xE7\xA7\x97z\x11a\0[W\x80c\xE7\xA7\x97z\x14a\x01vW\x80c\xF2\xFD\xE3\x8B\x14a\x01\x89W\x80c\xF4\x9E\xB1d\x14a\x01\x9CW`\0\x80\xFD[\x80c\x8D\xA5\xCB[\x14a\x01;W\x80c\xC1\\\xFF\xAB\x14a\x01cW`\0\x80\xFD[\x80c\x06\x90\xBD8\x14a\0\xA8W\x80c\x15\xD2Q.\x14a\0\xFBW\x80cB\xD7\xCB\x98\x14a\x01\x10W\x80cqP\x18\xA6\x14a\x013W[`\0\x80\xFD[a\0\xE6a\0\xB66`\x04a\x069V[\x81Q` \x81\x84\x01\x81\x01\x80Q`\x01\x82R\x92\x82\x01\x94\x82\x01\x94\x90\x94 \x91\x90\x93R\x90\x91R`\0\x90\x81R`@\x90 T`\xFF\x16\x81V[`@Q\x90\x15\x15\x81R` \x01[`@Q\x80\x91\x03\x90\xF3[a\x01\x0Ea\x01\t6`\x04a\x06~V[a\x01\xAFV[\0[a\0\xE6a\x01\x1E6`\x04a\x06~V[`\x02` R`\0\x90\x81R`@\x90 T`\xFF\x16\x81V[a\x01\x0Ea\x02+V[`\0T`@Qs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x91\x16\x81R` \x01a\0\xF2V[a\x01\x0Ea\x01q6`\x04a\x069V[a\x02?V[a\0\xE6a\x01\x846`\x04a\x069V[a\x03YV[a\x01\x0Ea\x01\x976`\x04a\x06\x97V[a\x03\xBDV[a\x01\x0Ea\x01\xAA6`\x04a\x06\xD4V[a\x04!V[a\x01\xB7a\x04eV[`\0\x81\x81R`\x02` R`@\x90\x81\x90 \x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\x16`\x01\x17\x90UQ\x7F\xB8\x0F\xFF+Lo=\xDF\x80Hw\x92|w\xB2\xFE\x18q\xCE\xCA\xA5\xADC\xD2\xC7\xC4/As1\xF8e\x90a\x02 \x90\x83\x81R` \x01\x90V[`@Q\x80\x91\x03\x90\xA1PV[a\x023a\x04eV[a\x02=`\0a\x04\xB8V[V[a\x02Ga\x04eV[`\0\x81\x81R`\x02` R`@\x90 T`\xFF\x16\x15a\x02\xC5W`@Q\x7F\x08\xC3y\xA0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R` `\x04\x82\x01R`\x19`$\x82\x01R\x7Fcannot set revoked pubkey\0\0\0\0\0\0\0`D\x82\x01R`d\x01[`@Q\x80\x91\x03\x90\xFD[`\x01\x80\x83`@Qa\x02\xD6\x91\x90a\x07\xD7V[\x90\x81R`@\x80Q` \x92\x81\x90\x03\x83\x01\x81 `\0\x86\x81R\x93R\x91 \x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\x16\x92\x15\x15\x92\x90\x92\x17\x90\x91U\x7FQ\r\xAC\x88\xEA\xF2\xDF\xBDS\x90BA\xFC\x19\x9A\xD4k c\xE6\xBFl?\xB2\x91\xF8\xCE\x86Cf4\x19\x90a\x03M\x90\x84\x90\x84\x90a\x07\xF3V[`@Q\x80\x91\x03\x90\xA1PPV[`\0\x81\x81R`\x02` R`@\x81 T`\xFF\x16\x15a\x03xWP`\0a\x03\xB7V[`\x01\x83`@Qa\x03\x88\x91\x90a\x07\xD7V[\x90\x81R`@\x80Q` \x92\x81\x90\x03\x83\x01\x90 `\0\x85\x81R\x92R\x90 T`\xFF\x16\x15a\x03\xB3WP`\x01a\x03\xB7V[P`\0[\x92\x91PPV[a\x03\xC5a\x04eV[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16a\x04\x15W`@Q\x7F\x1EO\xBD\xF7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\0`\x04\x82\x01R`$\x01a\x02\xBCV[a\x04\x1E\x81a\x04\xB8V[PV[a\x04)a\x04eV[`\0[\x81Q\x81\x10\x15a\x04`Wa\x04X\x83\x83\x83\x81Q\x81\x10a\x04KWa\x04Ka\x08LV[` \x02` \x01\x01Qa\x02?V[`\x01\x01a\x04,V[PPPV[`\0Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x163\x14a\x02=W`@Q\x7F\x11\x8C\xDA\xA7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R3`\x04\x82\x01R`$\x01a\x02\xBCV[`\0\x80Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x81\x16\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x83\x16\x81\x17\x84U`@Q\x91\x90\x92\x16\x92\x83\x91\x7F\x8B\xE0\x07\x9CS\x16Y\x14\x13D\xCD\x1F\xD0\xA4\xF2\x84\x19I\x7F\x97\"\xA3\xDA\xAF\xE3\xB4\x18okdW\xE0\x91\x90\xA3PPV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`A`\x04R`$`\0\xFD[`@Q`\x1F\x82\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16\x81\x01g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x82\x82\x10\x17\x15a\x05\xA3Wa\x05\xA3a\x05-V[`@R\x91\x90PV[`\0\x82`\x1F\x83\x01\x12a\x05\xBCW`\0\x80\xFD[\x815g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\x05\xD6Wa\x05\xD6a\x05-V[a\x06\x07` \x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0`\x1F\x84\x01\x16\x01a\x05\\V[\x81\x81R\x84` \x83\x86\x01\x01\x11\x15a\x06\x1CW`\0\x80\xFD[\x81` \x85\x01` \x83\x017`\0\x91\x81\x01` \x01\x91\x90\x91R\x93\x92PPPV[`\0\x80`@\x83\x85\x03\x12\x15a\x06LW`\0\x80\xFD[\x825g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\x06cW`\0\x80\xFD[a\x06o\x85\x82\x86\x01a\x05\xABV[\x95` \x94\x90\x94\x015\x94PPPPV[`\0` \x82\x84\x03\x12\x15a\x06\x90W`\0\x80\xFD[P5\x91\x90PV[`\0` \x82\x84\x03\x12\x15a\x06\xA9W`\0\x80\xFD[\x815s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16\x81\x14a\x06\xCDW`\0\x80\xFD[\x93\x92PPPV[`\0\x80`@\x83\x85\x03\x12\x15a\x06\xE7W`\0\x80\xFD[\x825g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\x06\xFEW`\0\x80\xFD[a\x07\n\x85\x82\x86\x01a\x05\xABV[\x92PP` \x83\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\x07'W`\0\x80\xFD[\x83\x01`\x1F\x81\x01\x85\x13a\x078W`\0\x80\xFD[\x805g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a\x07RWa\x07Ra\x05-V[\x80`\x05\x1Ba\x07b` \x82\x01a\x05\\V[\x91\x82R` \x81\x84\x01\x81\x01\x92\x90\x81\x01\x90\x88\x84\x11\x15a\x07~W`\0\x80\xFD[` \x85\x01\x94P[\x83\x85\x10\x15a\x07\xA4W\x845\x80\x83R` \x95\x86\x01\x95\x90\x93P\x90\x91\x01\x90a\x07\x85V[\x80\x95PPPPPP\x92P\x92\x90PV[`\0[\x83\x81\x10\x15a\x07\xCEW\x81\x81\x01Q\x83\x82\x01R` \x01a\x07\xB6V[PP`\0\x91\x01RV[`\0\x82Qa\x07\xE9\x81\x84` \x87\x01a\x07\xB3V[\x91\x90\x91\x01\x92\x91PPV[`@\x81R`\0\x83Q\x80`@\x84\x01Ra\x08\x12\x81``\x85\x01` \x88\x01a\x07\xB3V[` \x83\x01\x93\x90\x93RP`\x1F\x91\x90\x91\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16\x01``\x01\x91\x90PV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`2`\x04R`$`\0\xFD\xFE\xA2dipfsX\"\x12 -\x9Ee\xDAg\xA8\x9E\x94XP\xBB\xE47ClV\x95\xD85 \x14\x95XA\xAAs\xAA\x1C\xC4\x15\xD3IdsolcC\0\x08\x1A\x003\xA2dipfsX\"\x12 \x0E[\xF6h\xD37\xAE[\x83m\x7F\x86So\xD0\x05\xCE\xD9Ui~\xD1\xF0\x7F\xC3\xF4C\xC1b\xFE\x136dsolcC\0\x08\x1A\x003"; - /// The deployed bytecode of the contract. - pub static ECDSAOWNEDDKIMREGISTRY_DEPLOYED_BYTECODE: ::ethers::core::types::Bytes = ::ethers::core::types::Bytes::from_static( - __DEPLOYED_BYTECODE, - ); - pub struct ECDSAOwnedDKIMRegistry(::ethers::contract::Contract); - impl ::core::clone::Clone for ECDSAOwnedDKIMRegistry { - fn clone(&self) -> Self { - Self(::core::clone::Clone::clone(&self.0)) - } - } - impl ::core::ops::Deref for ECDSAOwnedDKIMRegistry { - type Target = ::ethers::contract::Contract; - fn deref(&self) -> &Self::Target { - &self.0 - } - } - impl ::core::ops::DerefMut for ECDSAOwnedDKIMRegistry { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } - } - impl ::core::fmt::Debug for ECDSAOwnedDKIMRegistry { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_tuple(::core::stringify!(ECDSAOwnedDKIMRegistry)) - .field(&self.address()) - .finish() - } - } - impl ECDSAOwnedDKIMRegistry { - /// Creates a new contract instance with the specified `ethers` client at - /// `address`. The contract derefs to a `ethers::Contract` object. - pub fn new>( - address: T, - client: ::std::sync::Arc, - ) -> Self { - Self( - ::ethers::contract::Contract::new( - address.into(), - ECDSAOWNEDDKIMREGISTRY_ABI.clone(), - client, - ), - ) - } - /// Constructs the general purpose `Deployer` instance based on the provided constructor arguments and sends it. - /// Returns a new instance of a deployer that returns an instance of this contract after sending the transaction - /// - /// Notes: - /// - If there are no constructor arguments, you should pass `()` as the argument. - /// - The default poll duration is 7 seconds. - /// - The default number of confirmations is 1 block. - /// - /// - /// # Example - /// - /// Generate contract bindings with `abigen!` and deploy a new contract instance. - /// - /// *Note*: this requires a `bytecode` and `abi` object in the `greeter.json` artifact. - /// - /// ```ignore - /// # async fn deploy(client: ::std::sync::Arc) { - /// abigen!(Greeter, "../greeter.json"); - /// - /// let greeter_contract = Greeter::deploy(client, "Hello world!".to_string()).unwrap().send().await.unwrap(); - /// let msg = greeter_contract.greet().call().await.unwrap(); - /// # } - /// ``` - pub fn deploy( - client: ::std::sync::Arc, - constructor_args: T, - ) -> ::core::result::Result< - ::ethers::contract::builders::ContractDeployer, - ::ethers::contract::ContractError, - > { - let factory = ::ethers::contract::ContractFactory::new( - ECDSAOWNEDDKIMREGISTRY_ABI.clone(), - ECDSAOWNEDDKIMREGISTRY_BYTECODE.clone().into(), - client, - ); - let deployer = factory.deploy(constructor_args)?; - let deployer = ::ethers::contract::ContractDeployer::new(deployer); - Ok(deployer) - } - ///Calls the contract's `REVOKE_PREFIX` (0xd507c320) function - pub fn revoke_prefix( - &self, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([213, 7, 195, 32], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `SET_PREFIX` (0x07f1eaf5) function - pub fn set_prefix( - &self, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([7, 241, 234, 245], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `UPGRADE_INTERFACE_VERSION` (0xad3cb1cc) function - pub fn upgrade_interface_version( - &self, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([173, 60, 177, 204], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `changeSigner` (0xaad2b723) function - pub fn change_signer( - &self, - new_signer: ::ethers::core::types::Address, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([170, 210, 183, 35], new_signer) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `computeSignedMsg` (0xaec79361) function - pub fn compute_signed_msg( - &self, - prefix: ::std::string::String, - selector: ::std::string::String, - domain_name: ::std::string::String, - public_key_hash: [u8; 32], - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash( - [174, 199, 147, 97], - (prefix, selector, domain_name, public_key_hash), - ) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `dkimRegistry` (0x6423f1e2) function - pub fn dkim_registry( - &self, - ) -> ::ethers::contract::builders::ContractCall< - M, - ::ethers::core::types::Address, - > { - self.0 - .method_hash([100, 35, 241, 226], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `initialize` (0x485cc955) function - pub fn initialize( - &self, - initial_owner: ::ethers::core::types::Address, - signer: ::ethers::core::types::Address, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([72, 92, 201, 85], (initial_owner, signer)) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `isDKIMPublicKeyHashValid` (0xe7a7977a) function - pub fn is_dkim_public_key_hash_valid( - &self, - domain_name: ::std::string::String, - public_key_hash: [u8; 32], - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([231, 167, 151, 122], (domain_name, public_key_hash)) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `owner` (0x8da5cb5b) function - pub fn owner( - &self, - ) -> ::ethers::contract::builders::ContractCall< - M, - ::ethers::core::types::Address, - > { - self.0 - .method_hash([141, 165, 203, 91], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `proxiableUUID` (0x52d1902d) function - pub fn proxiable_uuid( - &self, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([82, 209, 144, 45], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `renounceOwnership` (0x715018a6) function - pub fn renounce_ownership( - &self, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([113, 80, 24, 166], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `revokeDKIMPublicKeyHash` (0xf6b49344) function - pub fn revoke_dkim_public_key_hash( - &self, - selector: ::std::string::String, - domain_name: ::std::string::String, - public_key_hash: [u8; 32], - signature: ::ethers::core::types::Bytes, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash( - [246, 180, 147, 68], - (selector, domain_name, public_key_hash, signature), - ) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `setDKIMPublicKeyHash` (0x97170f2b) function - pub fn set_dkim_public_key_hash( - &self, - selector: ::std::string::String, - domain_name: ::std::string::String, - public_key_hash: [u8; 32], - signature: ::ethers::core::types::Bytes, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash( - [151, 23, 15, 43], - (selector, domain_name, public_key_hash, signature), - ) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `signer` (0x238ac933) function - pub fn signer( - &self, - ) -> ::ethers::contract::builders::ContractCall< - M, - ::ethers::core::types::Address, - > { - self.0 - .method_hash([35, 138, 201, 51], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `transferOwnership` (0xf2fde38b) function - pub fn transfer_ownership( - &self, - new_owner: ::ethers::core::types::Address, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([242, 253, 227, 139], new_owner) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `upgradeToAndCall` (0x4f1ef286) function - pub fn upgrade_to_and_call( - &self, - new_implementation: ::ethers::core::types::Address, - data: ::ethers::core::types::Bytes, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([79, 30, 242, 134], (new_implementation, data)) - .expect("method not found (this should never happen)") - } - ///Gets the contract's `Initialized` event - pub fn initialized_filter( - &self, - ) -> ::ethers::contract::builders::Event< - ::std::sync::Arc, - M, - InitializedFilter, - > { - self.0.event() - } - ///Gets the contract's `OwnershipTransferred` event - pub fn ownership_transferred_filter( - &self, - ) -> ::ethers::contract::builders::Event< - ::std::sync::Arc, - M, - OwnershipTransferredFilter, - > { - self.0.event() - } - ///Gets the contract's `Upgraded` event - pub fn upgraded_filter( - &self, - ) -> ::ethers::contract::builders::Event< - ::std::sync::Arc, - M, - UpgradedFilter, - > { - self.0.event() - } - /// Returns an `Event` builder for all the events of this contract. - pub fn events( - &self, - ) -> ::ethers::contract::builders::Event< - ::std::sync::Arc, - M, - ECDSAOwnedDKIMRegistryEvents, - > { - self.0.event_with_filter(::core::default::Default::default()) - } - } - impl From<::ethers::contract::Contract> - for ECDSAOwnedDKIMRegistry { - fn from(contract: ::ethers::contract::Contract) -> Self { - Self::new(contract.address(), contract.client()) - } - } - ///Custom Error type `AddressEmptyCode` with signature `AddressEmptyCode(address)` and selector `0x9996b315` - #[derive( - Clone, - ::ethers::contract::EthError, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[etherror(name = "AddressEmptyCode", abi = "AddressEmptyCode(address)")] - pub struct AddressEmptyCode { - pub target: ::ethers::core::types::Address, - } - ///Custom Error type `ECDSAInvalidSignature` with signature `ECDSAInvalidSignature()` and selector `0xf645eedf` - #[derive( - Clone, - ::ethers::contract::EthError, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[etherror(name = "ECDSAInvalidSignature", abi = "ECDSAInvalidSignature()")] - pub struct ECDSAInvalidSignature; - ///Custom Error type `ECDSAInvalidSignatureLength` with signature `ECDSAInvalidSignatureLength(uint256)` and selector `0xfce698f7` - #[derive( - Clone, - ::ethers::contract::EthError, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[etherror( - name = "ECDSAInvalidSignatureLength", - abi = "ECDSAInvalidSignatureLength(uint256)" - )] - pub struct ECDSAInvalidSignatureLength { - pub length: ::ethers::core::types::U256, - } - ///Custom Error type `ECDSAInvalidSignatureS` with signature `ECDSAInvalidSignatureS(bytes32)` and selector `0xd78bce0c` - #[derive( - Clone, - ::ethers::contract::EthError, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[etherror(name = "ECDSAInvalidSignatureS", abi = "ECDSAInvalidSignatureS(bytes32)")] - pub struct ECDSAInvalidSignatureS { - pub s: [u8; 32], - } - ///Custom Error type `ERC1967InvalidImplementation` with signature `ERC1967InvalidImplementation(address)` and selector `0x4c9c8ce3` - #[derive( - Clone, - ::ethers::contract::EthError, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[etherror( - name = "ERC1967InvalidImplementation", - abi = "ERC1967InvalidImplementation(address)" - )] - pub struct ERC1967InvalidImplementation { - pub implementation: ::ethers::core::types::Address, - } - ///Custom Error type `ERC1967NonPayable` with signature `ERC1967NonPayable()` and selector `0xb398979f` - #[derive( - Clone, - ::ethers::contract::EthError, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[etherror(name = "ERC1967NonPayable", abi = "ERC1967NonPayable()")] - pub struct ERC1967NonPayable; - ///Custom Error type `FailedInnerCall` with signature `FailedInnerCall()` and selector `0x1425ea42` - #[derive( - Clone, - ::ethers::contract::EthError, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[etherror(name = "FailedInnerCall", abi = "FailedInnerCall()")] - pub struct FailedInnerCall; - ///Custom Error type `InvalidInitialization` with signature `InvalidInitialization()` and selector `0xf92ee8a9` - #[derive( - Clone, - ::ethers::contract::EthError, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[etherror(name = "InvalidInitialization", abi = "InvalidInitialization()")] - pub struct InvalidInitialization; - ///Custom Error type `NotInitializing` with signature `NotInitializing()` and selector `0xd7e6bcf8` - #[derive( - Clone, - ::ethers::contract::EthError, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[etherror(name = "NotInitializing", abi = "NotInitializing()")] - pub struct NotInitializing; - ///Custom Error type `OwnableInvalidOwner` with signature `OwnableInvalidOwner(address)` and selector `0x1e4fbdf7` - #[derive( - Clone, - ::ethers::contract::EthError, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[etherror(name = "OwnableInvalidOwner", abi = "OwnableInvalidOwner(address)")] - pub struct OwnableInvalidOwner { - pub owner: ::ethers::core::types::Address, - } - ///Custom Error type `OwnableUnauthorizedAccount` with signature `OwnableUnauthorizedAccount(address)` and selector `0x118cdaa7` - #[derive( - Clone, - ::ethers::contract::EthError, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[etherror( - name = "OwnableUnauthorizedAccount", - abi = "OwnableUnauthorizedAccount(address)" - )] - pub struct OwnableUnauthorizedAccount { - pub account: ::ethers::core::types::Address, - } - ///Custom Error type `StringsInsufficientHexLength` with signature `StringsInsufficientHexLength(uint256,uint256)` and selector `0xe22e27eb` - #[derive( - Clone, - ::ethers::contract::EthError, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[etherror( - name = "StringsInsufficientHexLength", - abi = "StringsInsufficientHexLength(uint256,uint256)" - )] - pub struct StringsInsufficientHexLength { - pub value: ::ethers::core::types::U256, - pub length: ::ethers::core::types::U256, - } - ///Custom Error type `UUPSUnauthorizedCallContext` with signature `UUPSUnauthorizedCallContext()` and selector `0xe07c8dba` - #[derive( - Clone, - ::ethers::contract::EthError, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[etherror( - name = "UUPSUnauthorizedCallContext", - abi = "UUPSUnauthorizedCallContext()" - )] - pub struct UUPSUnauthorizedCallContext; - ///Custom Error type `UUPSUnsupportedProxiableUUID` with signature `UUPSUnsupportedProxiableUUID(bytes32)` and selector `0xaa1d49a4` - #[derive( - Clone, - ::ethers::contract::EthError, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[etherror( - name = "UUPSUnsupportedProxiableUUID", - abi = "UUPSUnsupportedProxiableUUID(bytes32)" - )] - pub struct UUPSUnsupportedProxiableUUID { - pub slot: [u8; 32], - } - ///Container type for all of the contract's custom errors - #[derive(Clone, ::ethers::contract::EthAbiType, Debug, PartialEq, Eq, Hash)] - pub enum ECDSAOwnedDKIMRegistryErrors { - AddressEmptyCode(AddressEmptyCode), - ECDSAInvalidSignature(ECDSAInvalidSignature), - ECDSAInvalidSignatureLength(ECDSAInvalidSignatureLength), - ECDSAInvalidSignatureS(ECDSAInvalidSignatureS), - ERC1967InvalidImplementation(ERC1967InvalidImplementation), - ERC1967NonPayable(ERC1967NonPayable), - FailedInnerCall(FailedInnerCall), - InvalidInitialization(InvalidInitialization), - NotInitializing(NotInitializing), - OwnableInvalidOwner(OwnableInvalidOwner), - OwnableUnauthorizedAccount(OwnableUnauthorizedAccount), - StringsInsufficientHexLength(StringsInsufficientHexLength), - UUPSUnauthorizedCallContext(UUPSUnauthorizedCallContext), - UUPSUnsupportedProxiableUUID(UUPSUnsupportedProxiableUUID), - /// The standard solidity revert string, with selector - /// Error(string) -- 0x08c379a0 - RevertString(::std::string::String), - } - impl ::ethers::core::abi::AbiDecode for ECDSAOwnedDKIMRegistryErrors { - fn decode( - data: impl AsRef<[u8]>, - ) -> ::core::result::Result { - let data = data.as_ref(); - if let Ok(decoded) = <::std::string::String as ::ethers::core::abi::AbiDecode>::decode( - data, - ) { - return Ok(Self::RevertString(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::AddressEmptyCode(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::ECDSAInvalidSignature(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::ECDSAInvalidSignatureLength(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::ECDSAInvalidSignatureS(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::ERC1967InvalidImplementation(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::ERC1967NonPayable(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::FailedInnerCall(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::InvalidInitialization(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::NotInitializing(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::OwnableInvalidOwner(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::OwnableUnauthorizedAccount(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::StringsInsufficientHexLength(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::UUPSUnauthorizedCallContext(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::UUPSUnsupportedProxiableUUID(decoded)); - } - Err(::ethers::core::abi::Error::InvalidData.into()) - } - } - impl ::ethers::core::abi::AbiEncode for ECDSAOwnedDKIMRegistryErrors { - fn encode(self) -> ::std::vec::Vec { - match self { - Self::AddressEmptyCode(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::ECDSAInvalidSignature(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::ECDSAInvalidSignatureLength(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::ECDSAInvalidSignatureS(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::ERC1967InvalidImplementation(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::ERC1967NonPayable(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::FailedInnerCall(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::InvalidInitialization(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::NotInitializing(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::OwnableInvalidOwner(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::OwnableUnauthorizedAccount(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::StringsInsufficientHexLength(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::UUPSUnauthorizedCallContext(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::UUPSUnsupportedProxiableUUID(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::RevertString(s) => ::ethers::core::abi::AbiEncode::encode(s), - } - } - } - impl ::ethers::contract::ContractRevert for ECDSAOwnedDKIMRegistryErrors { - fn valid_selector(selector: [u8; 4]) -> bool { - match selector { - [0x08, 0xc3, 0x79, 0xa0] => true, - _ if selector - == ::selector() => { - true - } - _ if selector - == ::selector() => { - true - } - _ if selector - == ::selector() => { - true - } - _ if selector - == ::selector() => { - true - } - _ if selector - == ::selector() => { - true - } - _ if selector - == ::selector() => { - true - } - _ if selector - == ::selector() => { - true - } - _ if selector - == ::selector() => { - true - } - _ if selector - == ::selector() => { - true - } - _ if selector - == ::selector() => { - true - } - _ if selector - == ::selector() => { - true - } - _ if selector - == ::selector() => { - true - } - _ if selector - == ::selector() => { - true - } - _ if selector - == ::selector() => { - true - } - _ => false, - } - } - } - impl ::core::fmt::Display for ECDSAOwnedDKIMRegistryErrors { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - match self { - Self::AddressEmptyCode(element) => ::core::fmt::Display::fmt(element, f), - Self::ECDSAInvalidSignature(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::ECDSAInvalidSignatureLength(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::ECDSAInvalidSignatureS(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::ERC1967InvalidImplementation(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::ERC1967NonPayable(element) => ::core::fmt::Display::fmt(element, f), - Self::FailedInnerCall(element) => ::core::fmt::Display::fmt(element, f), - Self::InvalidInitialization(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::NotInitializing(element) => ::core::fmt::Display::fmt(element, f), - Self::OwnableInvalidOwner(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::OwnableUnauthorizedAccount(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::StringsInsufficientHexLength(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::UUPSUnauthorizedCallContext(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::UUPSUnsupportedProxiableUUID(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::RevertString(s) => ::core::fmt::Display::fmt(s, f), - } - } - } - impl ::core::convert::From<::std::string::String> for ECDSAOwnedDKIMRegistryErrors { - fn from(value: String) -> Self { - Self::RevertString(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryErrors { - fn from(value: AddressEmptyCode) -> Self { - Self::AddressEmptyCode(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryErrors { - fn from(value: ECDSAInvalidSignature) -> Self { - Self::ECDSAInvalidSignature(value) - } - } - impl ::core::convert::From - for ECDSAOwnedDKIMRegistryErrors { - fn from(value: ECDSAInvalidSignatureLength) -> Self { - Self::ECDSAInvalidSignatureLength(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryErrors { - fn from(value: ECDSAInvalidSignatureS) -> Self { - Self::ECDSAInvalidSignatureS(value) - } - } - impl ::core::convert::From - for ECDSAOwnedDKIMRegistryErrors { - fn from(value: ERC1967InvalidImplementation) -> Self { - Self::ERC1967InvalidImplementation(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryErrors { - fn from(value: ERC1967NonPayable) -> Self { - Self::ERC1967NonPayable(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryErrors { - fn from(value: FailedInnerCall) -> Self { - Self::FailedInnerCall(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryErrors { - fn from(value: InvalidInitialization) -> Self { - Self::InvalidInitialization(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryErrors { - fn from(value: NotInitializing) -> Self { - Self::NotInitializing(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryErrors { - fn from(value: OwnableInvalidOwner) -> Self { - Self::OwnableInvalidOwner(value) - } - } - impl ::core::convert::From - for ECDSAOwnedDKIMRegistryErrors { - fn from(value: OwnableUnauthorizedAccount) -> Self { - Self::OwnableUnauthorizedAccount(value) - } - } - impl ::core::convert::From - for ECDSAOwnedDKIMRegistryErrors { - fn from(value: StringsInsufficientHexLength) -> Self { - Self::StringsInsufficientHexLength(value) - } - } - impl ::core::convert::From - for ECDSAOwnedDKIMRegistryErrors { - fn from(value: UUPSUnauthorizedCallContext) -> Self { - Self::UUPSUnauthorizedCallContext(value) - } - } - impl ::core::convert::From - for ECDSAOwnedDKIMRegistryErrors { - fn from(value: UUPSUnsupportedProxiableUUID) -> Self { - Self::UUPSUnsupportedProxiableUUID(value) - } - } - #[derive( - Clone, - ::ethers::contract::EthEvent, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethevent(name = "Initialized", abi = "Initialized(uint64)")] - pub struct InitializedFilter { - pub version: u64, - } - #[derive( - Clone, - ::ethers::contract::EthEvent, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethevent( - name = "OwnershipTransferred", - abi = "OwnershipTransferred(address,address)" - )] - pub struct OwnershipTransferredFilter { - #[ethevent(indexed)] - pub previous_owner: ::ethers::core::types::Address, - #[ethevent(indexed)] - pub new_owner: ::ethers::core::types::Address, - } - #[derive( - Clone, - ::ethers::contract::EthEvent, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethevent(name = "Upgraded", abi = "Upgraded(address)")] - pub struct UpgradedFilter { - #[ethevent(indexed)] - pub implementation: ::ethers::core::types::Address, - } - ///Container type for all of the contract's events - #[derive(Clone, ::ethers::contract::EthAbiType, Debug, PartialEq, Eq, Hash)] - pub enum ECDSAOwnedDKIMRegistryEvents { - InitializedFilter(InitializedFilter), - OwnershipTransferredFilter(OwnershipTransferredFilter), - UpgradedFilter(UpgradedFilter), - } - impl ::ethers::contract::EthLogDecode for ECDSAOwnedDKIMRegistryEvents { - fn decode_log( - log: &::ethers::core::abi::RawLog, - ) -> ::core::result::Result { - if let Ok(decoded) = InitializedFilter::decode_log(log) { - return Ok(ECDSAOwnedDKIMRegistryEvents::InitializedFilter(decoded)); - } - if let Ok(decoded) = OwnershipTransferredFilter::decode_log(log) { - return Ok( - ECDSAOwnedDKIMRegistryEvents::OwnershipTransferredFilter(decoded), - ); - } - if let Ok(decoded) = UpgradedFilter::decode_log(log) { - return Ok(ECDSAOwnedDKIMRegistryEvents::UpgradedFilter(decoded)); - } - Err(::ethers::core::abi::Error::InvalidData) - } - } - impl ::core::fmt::Display for ECDSAOwnedDKIMRegistryEvents { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - match self { - Self::InitializedFilter(element) => ::core::fmt::Display::fmt(element, f), - Self::OwnershipTransferredFilter(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::UpgradedFilter(element) => ::core::fmt::Display::fmt(element, f), - } - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryEvents { - fn from(value: InitializedFilter) -> Self { - Self::InitializedFilter(value) - } - } - impl ::core::convert::From - for ECDSAOwnedDKIMRegistryEvents { - fn from(value: OwnershipTransferredFilter) -> Self { - Self::OwnershipTransferredFilter(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryEvents { - fn from(value: UpgradedFilter) -> Self { - Self::UpgradedFilter(value) - } - } - ///Container type for all input parameters for the `REVOKE_PREFIX` function with signature `REVOKE_PREFIX()` and selector `0xd507c320` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall(name = "REVOKE_PREFIX", abi = "REVOKE_PREFIX()")] - pub struct RevokePrefixCall; - ///Container type for all input parameters for the `SET_PREFIX` function with signature `SET_PREFIX()` and selector `0x07f1eaf5` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall(name = "SET_PREFIX", abi = "SET_PREFIX()")] - pub struct SetPrefixCall; - ///Container type for all input parameters for the `UPGRADE_INTERFACE_VERSION` function with signature `UPGRADE_INTERFACE_VERSION()` and selector `0xad3cb1cc` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall(name = "UPGRADE_INTERFACE_VERSION", abi = "UPGRADE_INTERFACE_VERSION()")] - pub struct UpgradeInterfaceVersionCall; - ///Container type for all input parameters for the `changeSigner` function with signature `changeSigner(address)` and selector `0xaad2b723` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall(name = "changeSigner", abi = "changeSigner(address)")] - pub struct ChangeSignerCall { - pub new_signer: ::ethers::core::types::Address, - } - ///Container type for all input parameters for the `computeSignedMsg` function with signature `computeSignedMsg(string,string,string,bytes32)` and selector `0xaec79361` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall( - name = "computeSignedMsg", - abi = "computeSignedMsg(string,string,string,bytes32)" - )] - pub struct ComputeSignedMsgCall { - pub prefix: ::std::string::String, - pub selector: ::std::string::String, - pub domain_name: ::std::string::String, - pub public_key_hash: [u8; 32], - } - ///Container type for all input parameters for the `dkimRegistry` function with signature `dkimRegistry()` and selector `0x6423f1e2` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall(name = "dkimRegistry", abi = "dkimRegistry()")] - pub struct DkimRegistryCall; - ///Container type for all input parameters for the `initialize` function with signature `initialize(address,address)` and selector `0x485cc955` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall(name = "initialize", abi = "initialize(address,address)")] - pub struct InitializeCall { - pub initial_owner: ::ethers::core::types::Address, - pub signer: ::ethers::core::types::Address, - } - ///Container type for all input parameters for the `isDKIMPublicKeyHashValid` function with signature `isDKIMPublicKeyHashValid(string,bytes32)` and selector `0xe7a7977a` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall( - name = "isDKIMPublicKeyHashValid", - abi = "isDKIMPublicKeyHashValid(string,bytes32)" - )] - pub struct IsDKIMPublicKeyHashValidCall { - pub domain_name: ::std::string::String, - pub public_key_hash: [u8; 32], - } - ///Container type for all input parameters for the `owner` function with signature `owner()` and selector `0x8da5cb5b` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall(name = "owner", abi = "owner()")] - pub struct OwnerCall; - ///Container type for all input parameters for the `proxiableUUID` function with signature `proxiableUUID()` and selector `0x52d1902d` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall(name = "proxiableUUID", abi = "proxiableUUID()")] - pub struct ProxiableUUIDCall; - ///Container type for all input parameters for the `renounceOwnership` function with signature `renounceOwnership()` and selector `0x715018a6` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall(name = "renounceOwnership", abi = "renounceOwnership()")] - pub struct RenounceOwnershipCall; - ///Container type for all input parameters for the `revokeDKIMPublicKeyHash` function with signature `revokeDKIMPublicKeyHash(string,string,bytes32,bytes)` and selector `0xf6b49344` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall( - name = "revokeDKIMPublicKeyHash", - abi = "revokeDKIMPublicKeyHash(string,string,bytes32,bytes)" - )] - pub struct RevokeDKIMPublicKeyHashCall { - pub selector: ::std::string::String, - pub domain_name: ::std::string::String, - pub public_key_hash: [u8; 32], - pub signature: ::ethers::core::types::Bytes, - } - ///Container type for all input parameters for the `setDKIMPublicKeyHash` function with signature `setDKIMPublicKeyHash(string,string,bytes32,bytes)` and selector `0x97170f2b` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall( - name = "setDKIMPublicKeyHash", - abi = "setDKIMPublicKeyHash(string,string,bytes32,bytes)" - )] - pub struct SetDKIMPublicKeyHashCall { - pub selector: ::std::string::String, - pub domain_name: ::std::string::String, - pub public_key_hash: [u8; 32], - pub signature: ::ethers::core::types::Bytes, - } - ///Container type for all input parameters for the `signer` function with signature `signer()` and selector `0x238ac933` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall(name = "signer", abi = "signer()")] - pub struct SignerCall; - ///Container type for all input parameters for the `transferOwnership` function with signature `transferOwnership(address)` and selector `0xf2fde38b` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall(name = "transferOwnership", abi = "transferOwnership(address)")] - pub struct TransferOwnershipCall { - pub new_owner: ::ethers::core::types::Address, - } - ///Container type for all input parameters for the `upgradeToAndCall` function with signature `upgradeToAndCall(address,bytes)` and selector `0x4f1ef286` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall(name = "upgradeToAndCall", abi = "upgradeToAndCall(address,bytes)")] - pub struct UpgradeToAndCallCall { - pub new_implementation: ::ethers::core::types::Address, - pub data: ::ethers::core::types::Bytes, - } - ///Container type for all of the contract's call - #[derive(Clone, ::ethers::contract::EthAbiType, Debug, PartialEq, Eq, Hash)] - pub enum ECDSAOwnedDKIMRegistryCalls { - RevokePrefix(RevokePrefixCall), - SetPrefix(SetPrefixCall), - UpgradeInterfaceVersion(UpgradeInterfaceVersionCall), - ChangeSigner(ChangeSignerCall), - ComputeSignedMsg(ComputeSignedMsgCall), - DkimRegistry(DkimRegistryCall), - Initialize(InitializeCall), - IsDKIMPublicKeyHashValid(IsDKIMPublicKeyHashValidCall), - Owner(OwnerCall), - ProxiableUUID(ProxiableUUIDCall), - RenounceOwnership(RenounceOwnershipCall), - RevokeDKIMPublicKeyHash(RevokeDKIMPublicKeyHashCall), - SetDKIMPublicKeyHash(SetDKIMPublicKeyHashCall), - Signer(SignerCall), - TransferOwnership(TransferOwnershipCall), - UpgradeToAndCall(UpgradeToAndCallCall), - } - impl ::ethers::core::abi::AbiDecode for ECDSAOwnedDKIMRegistryCalls { - fn decode( - data: impl AsRef<[u8]>, - ) -> ::core::result::Result { - let data = data.as_ref(); - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::RevokePrefix(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::SetPrefix(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::UpgradeInterfaceVersion(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::ChangeSigner(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::ComputeSignedMsg(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::DkimRegistry(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::Initialize(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::IsDKIMPublicKeyHashValid(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::Owner(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::ProxiableUUID(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::RenounceOwnership(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::RevokeDKIMPublicKeyHash(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::SetDKIMPublicKeyHash(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::Signer(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::TransferOwnership(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::UpgradeToAndCall(decoded)); - } - Err(::ethers::core::abi::Error::InvalidData.into()) - } - } - impl ::ethers::core::abi::AbiEncode for ECDSAOwnedDKIMRegistryCalls { - fn encode(self) -> Vec { - match self { - Self::RevokePrefix(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::SetPrefix(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::UpgradeInterfaceVersion(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::ChangeSigner(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::ComputeSignedMsg(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::DkimRegistry(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::Initialize(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::IsDKIMPublicKeyHashValid(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::Owner(element) => ::ethers::core::abi::AbiEncode::encode(element), - Self::ProxiableUUID(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::RenounceOwnership(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::RevokeDKIMPublicKeyHash(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::SetDKIMPublicKeyHash(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::Signer(element) => ::ethers::core::abi::AbiEncode::encode(element), - Self::TransferOwnership(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::UpgradeToAndCall(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - } - } - } - impl ::core::fmt::Display for ECDSAOwnedDKIMRegistryCalls { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - match self { - Self::RevokePrefix(element) => ::core::fmt::Display::fmt(element, f), - Self::SetPrefix(element) => ::core::fmt::Display::fmt(element, f), - Self::UpgradeInterfaceVersion(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::ChangeSigner(element) => ::core::fmt::Display::fmt(element, f), - Self::ComputeSignedMsg(element) => ::core::fmt::Display::fmt(element, f), - Self::DkimRegistry(element) => ::core::fmt::Display::fmt(element, f), - Self::Initialize(element) => ::core::fmt::Display::fmt(element, f), - Self::IsDKIMPublicKeyHashValid(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::Owner(element) => ::core::fmt::Display::fmt(element, f), - Self::ProxiableUUID(element) => ::core::fmt::Display::fmt(element, f), - Self::RenounceOwnership(element) => ::core::fmt::Display::fmt(element, f), - Self::RevokeDKIMPublicKeyHash(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::SetDKIMPublicKeyHash(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::Signer(element) => ::core::fmt::Display::fmt(element, f), - Self::TransferOwnership(element) => ::core::fmt::Display::fmt(element, f), - Self::UpgradeToAndCall(element) => ::core::fmt::Display::fmt(element, f), - } - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryCalls { - fn from(value: RevokePrefixCall) -> Self { - Self::RevokePrefix(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryCalls { - fn from(value: SetPrefixCall) -> Self { - Self::SetPrefix(value) - } - } - impl ::core::convert::From - for ECDSAOwnedDKIMRegistryCalls { - fn from(value: UpgradeInterfaceVersionCall) -> Self { - Self::UpgradeInterfaceVersion(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryCalls { - fn from(value: ChangeSignerCall) -> Self { - Self::ChangeSigner(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryCalls { - fn from(value: ComputeSignedMsgCall) -> Self { - Self::ComputeSignedMsg(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryCalls { - fn from(value: DkimRegistryCall) -> Self { - Self::DkimRegistry(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryCalls { - fn from(value: InitializeCall) -> Self { - Self::Initialize(value) - } - } - impl ::core::convert::From - for ECDSAOwnedDKIMRegistryCalls { - fn from(value: IsDKIMPublicKeyHashValidCall) -> Self { - Self::IsDKIMPublicKeyHashValid(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryCalls { - fn from(value: OwnerCall) -> Self { - Self::Owner(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryCalls { - fn from(value: ProxiableUUIDCall) -> Self { - Self::ProxiableUUID(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryCalls { - fn from(value: RenounceOwnershipCall) -> Self { - Self::RenounceOwnership(value) - } - } - impl ::core::convert::From - for ECDSAOwnedDKIMRegistryCalls { - fn from(value: RevokeDKIMPublicKeyHashCall) -> Self { - Self::RevokeDKIMPublicKeyHash(value) - } - } - impl ::core::convert::From - for ECDSAOwnedDKIMRegistryCalls { - fn from(value: SetDKIMPublicKeyHashCall) -> Self { - Self::SetDKIMPublicKeyHash(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryCalls { - fn from(value: SignerCall) -> Self { - Self::Signer(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryCalls { - fn from(value: TransferOwnershipCall) -> Self { - Self::TransferOwnership(value) - } - } - impl ::core::convert::From for ECDSAOwnedDKIMRegistryCalls { - fn from(value: UpgradeToAndCallCall) -> Self { - Self::UpgradeToAndCall(value) - } - } - ///Container type for all return fields from the `REVOKE_PREFIX` function with signature `REVOKE_PREFIX()` and selector `0xd507c320` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - pub struct RevokePrefixReturn(pub ::std::string::String); - ///Container type for all return fields from the `SET_PREFIX` function with signature `SET_PREFIX()` and selector `0x07f1eaf5` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - pub struct SetPrefixReturn(pub ::std::string::String); - ///Container type for all return fields from the `UPGRADE_INTERFACE_VERSION` function with signature `UPGRADE_INTERFACE_VERSION()` and selector `0xad3cb1cc` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - pub struct UpgradeInterfaceVersionReturn(pub ::std::string::String); - ///Container type for all return fields from the `computeSignedMsg` function with signature `computeSignedMsg(string,string,string,bytes32)` and selector `0xaec79361` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - pub struct ComputeSignedMsgReturn(pub ::std::string::String); - ///Container type for all return fields from the `dkimRegistry` function with signature `dkimRegistry()` and selector `0x6423f1e2` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - pub struct DkimRegistryReturn(pub ::ethers::core::types::Address); - ///Container type for all return fields from the `isDKIMPublicKeyHashValid` function with signature `isDKIMPublicKeyHashValid(string,bytes32)` and selector `0xe7a7977a` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - pub struct IsDKIMPublicKeyHashValidReturn(pub bool); - ///Container type for all return fields from the `owner` function with signature `owner()` and selector `0x8da5cb5b` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - pub struct OwnerReturn(pub ::ethers::core::types::Address); - ///Container type for all return fields from the `proxiableUUID` function with signature `proxiableUUID()` and selector `0x52d1902d` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - pub struct ProxiableUUIDReturn(pub [u8; 32]); - ///Container type for all return fields from the `signer` function with signature `signer()` and selector `0x238ac933` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - pub struct SignerReturn(pub ::ethers::core::types::Address); -} diff --git a/packages/relayer/src/abis/email_account_recovery.rs b/packages/relayer/src/abis/email_account_recovery.rs deleted file mode 100644 index 56e0a90a..00000000 --- a/packages/relayer/src/abis/email_account_recovery.rs +++ /dev/null @@ -1,1512 +0,0 @@ -pub use email_account_recovery::*; -/// This module was auto-generated with ethers-rs Abigen. -/// More information at: -#[allow( - clippy::enum_variant_names, - clippy::too_many_arguments, - clippy::upper_case_acronyms, - clippy::type_complexity, - dead_code, - non_camel_case_types -)] -pub mod email_account_recovery { - #[allow(deprecated)] - fn __abi() -> ::ethers::core::abi::Abi { - ::ethers::core::abi::ethabi::Contract { - constructor: ::core::option::Option::None, - functions: ::core::convert::From::from([ - ( - ::std::borrow::ToOwned::to_owned("acceptanceSubjectTemplates"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("acceptanceSubjectTemplates",), - inputs: ::std::vec![], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Array( - ::std::boxed::Box::new( - ::ethers::core::abi::ethabi::ParamType::Array( - ::std::boxed::Box::new( - ::ethers::core::abi::ethabi::ParamType::String, - ), - ), - ), - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("string[][]"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("completeRecovery"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("completeRecovery"), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("account"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("completeCalldata"), - kind: ::ethers::core::abi::ethabi::ParamType::Bytes, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes"), - ), - }, - ], - outputs: ::std::vec![], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("computeAcceptanceTemplateId"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("computeAcceptanceTemplateId",), - inputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("templateIdx"), - kind: ::ethers::core::abi::ethabi::ParamType::Uint(256usize,), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("uint256"), - ), - },], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Uint(256usize,), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("uint256"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::Pure, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("computeEmailAuthAddress"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("computeEmailAuthAddress",), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("recoveredAccount"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("accountSalt"), - kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes(32usize,), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes32"), - ), - }, - ], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("computeRecoveryTemplateId"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("computeRecoveryTemplateId",), - inputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("templateIdx"), - kind: ::ethers::core::abi::ethabi::ParamType::Uint(256usize,), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("uint256"), - ), - },], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Uint(256usize,), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("uint256"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::Pure, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("dkim"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("dkim"), - inputs: ::std::vec![], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("dkimAddr"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("dkimAddr"), - inputs: ::std::vec![], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("emailAuthImplementation"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("emailAuthImplementation",), - inputs: ::std::vec![], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("emailAuthImplementationAddr"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("emailAuthImplementationAddr",), - inputs: ::std::vec![], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - },], - ), - ( - ::std::borrow::ToOwned::to_owned( - "extractRecoveredAccountFromAcceptanceSubject", - ), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned( - "extractRecoveredAccountFromAcceptanceSubject", - ), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("subjectParams"), - kind: ::ethers::core::abi::ethabi::ParamType::Array( - ::std::boxed::Box::new( - ::ethers::core::abi::ethabi::ParamType::Bytes, - ), - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes[]"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("templateIdx"), - kind: ::ethers::core::abi::ethabi::ParamType::Uint(256usize,), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("uint256"), - ), - }, - ], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("extractRecoveredAccountFromRecoverySubject"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned( - "extractRecoveredAccountFromRecoverySubject", - ), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("subjectParams"), - kind: ::ethers::core::abi::ethabi::ParamType::Array( - ::std::boxed::Box::new( - ::ethers::core::abi::ethabi::ParamType::Bytes, - ), - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes[]"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("templateIdx"), - kind: ::ethers::core::abi::ethabi::ParamType::Uint(256usize,), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("uint256"), - ), - }, - ], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("handleAcceptance"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("handleAcceptance"), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("emailAuthMsg"), - kind: ::ethers::core::abi::ethabi::ParamType::Tuple(::std::vec![ - ::ethers::core::abi::ethabi::ParamType::Uint(256usize), - ::ethers::core::abi::ethabi::ParamType::Array( - ::std::boxed::Box::new( - ::ethers::core::abi::ethabi::ParamType::Bytes, - ), - ), - ::ethers::core::abi::ethabi::ParamType::Uint(256usize), - ::ethers::core::abi::ethabi::ParamType::Tuple(::std::vec![ - ::ethers::core::abi::ethabi::ParamType::String, - ::ethers::core::abi::ethabi::ParamType::FixedBytes(32usize), - ::ethers::core::abi::ethabi::ParamType::Uint(256usize), - ::ethers::core::abi::ethabi::ParamType::String, - ::ethers::core::abi::ethabi::ParamType::FixedBytes(32usize), - ::ethers::core::abi::ethabi::ParamType::FixedBytes(32usize), - ::ethers::core::abi::ethabi::ParamType::Bool, - ::ethers::core::abi::ethabi::ParamType::Bytes, - ],), - ],), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("struct EmailAuthMsg"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("templateIdx"), - kind: ::ethers::core::abi::ethabi::ParamType::Uint(256usize,), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("uint256"), - ), - }, - ], - outputs: ::std::vec![], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("handleRecovery"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("handleRecovery"), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("emailAuthMsg"), - kind: ::ethers::core::abi::ethabi::ParamType::Tuple(::std::vec![ - ::ethers::core::abi::ethabi::ParamType::Uint(256usize), - ::ethers::core::abi::ethabi::ParamType::Array( - ::std::boxed::Box::new( - ::ethers::core::abi::ethabi::ParamType::Bytes, - ), - ), - ::ethers::core::abi::ethabi::ParamType::Uint(256usize), - ::ethers::core::abi::ethabi::ParamType::Tuple(::std::vec![ - ::ethers::core::abi::ethabi::ParamType::String, - ::ethers::core::abi::ethabi::ParamType::FixedBytes(32usize), - ::ethers::core::abi::ethabi::ParamType::Uint(256usize), - ::ethers::core::abi::ethabi::ParamType::String, - ::ethers::core::abi::ethabi::ParamType::FixedBytes(32usize), - ::ethers::core::abi::ethabi::ParamType::FixedBytes(32usize), - ::ethers::core::abi::ethabi::ParamType::Bool, - ::ethers::core::abi::ethabi::ParamType::Bytes, - ],), - ],), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("struct EmailAuthMsg"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("templateIdx"), - kind: ::ethers::core::abi::ethabi::ParamType::Uint(256usize,), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("uint256"), - ), - }, - ], - outputs: ::std::vec![], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("isActivated"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("isActivated"), - inputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("recoveredAccount"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - },], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Bool, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bool"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("proxyBytecodeHash"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("proxyBytecodeHash"), - inputs: ::std::vec![], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes(32usize,), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bytes32"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("isActivated"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("isActivated"), - inputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("recoveredAccount"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - },], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Bool, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bool"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("isActivated"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("isActivated"), - inputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("recoveredAccount"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - },], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Bool, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("bool"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("recoverySubjectTemplates"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("recoverySubjectTemplates",), - inputs: ::std::vec![], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Array( - ::std::boxed::Box::new( - ::ethers::core::abi::ethabi::ParamType::Array( - ::std::boxed::Box::new( - ::ethers::core::abi::ethabi::ParamType::String, - ), - ), - ), - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("string[][]"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("verifier"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("verifier"), - inputs: ::std::vec![], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - },], - ), - ( - ::std::borrow::ToOwned::to_owned("verifierAddr"), - ::std::vec![::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("verifierAddr"), - inputs: ::std::vec![], - outputs: ::std::vec![::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - },], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - },], - ), - ]), - events: ::std::collections::BTreeMap::new(), - errors: ::std::collections::BTreeMap::new(), - receive: false, - fallback: false, - } - } - ///The parsed JSON ABI of the contract. - pub static EMAILACCOUNTRECOVERY_ABI: ::ethers::contract::Lazy<::ethers::core::abi::Abi> = - ::ethers::contract::Lazy::new(__abi); - pub struct EmailAccountRecovery(::ethers::contract::Contract); - impl ::core::clone::Clone for EmailAccountRecovery { - fn clone(&self) -> Self { - Self(::core::clone::Clone::clone(&self.0)) - } - } - impl ::core::ops::Deref for EmailAccountRecovery { - type Target = ::ethers::contract::Contract; - fn deref(&self) -> &Self::Target { - &self.0 - } - } - impl ::core::ops::DerefMut for EmailAccountRecovery { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } - } - impl ::core::fmt::Debug for EmailAccountRecovery { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_tuple(::core::stringify!(EmailAccountRecovery)) - .field(&self.address()) - .finish() - } - } - impl EmailAccountRecovery { - /// Creates a new contract instance with the specified `ethers` client at - /// `address`. The contract derefs to a `ethers::Contract` object. - pub fn new>( - address: T, - client: ::std::sync::Arc, - ) -> Self { - Self(::ethers::contract::Contract::new( - address.into(), - EMAILACCOUNTRECOVERY_ABI.clone(), - client, - )) - } - ///Calls the contract's `acceptanceSubjectTemplates` (0x5bafadda) function - pub fn acceptance_subject_templates( - &self, - ) -> ::ethers::contract::builders::ContractCall< - M, - ::std::vec::Vec<::std::vec::Vec<::std::string::String>>, - > { - self.0 - .method_hash([91, 175, 173, 218], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `completeRecovery` (0xc18d09cf) function - pub fn complete_recovery( - &self, - account: ::ethers::core::types::Address, - complete_calldata: ::ethers::core::types::Bytes, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([193, 141, 9, 207], (account, complete_calldata)) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `computeAcceptanceTemplateId` (0x32ccc2f2) function - pub fn compute_acceptance_template_id( - &self, - template_idx: ::ethers::core::types::U256, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([50, 204, 194, 242], template_idx) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `computeEmailAuthAddress` (0x3a8eab14) function - pub fn compute_email_auth_address( - &self, - recovered_account: ::ethers::core::types::Address, - account_salt: [u8; 32], - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([58, 142, 171, 20], (recovered_account, account_salt)) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `computeRecoveryTemplateId` (0x6da99515) function - pub fn compute_recovery_template_id( - &self, - template_idx: ::ethers::core::types::U256, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([109, 169, 149, 21], template_idx) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `dkim` (0x400ad5ce) function - pub fn dkim( - &self, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([64, 10, 213, 206], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `dkimAddr` (0x73357f85) function - pub fn dkim_addr( - &self, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([115, 53, 127, 133], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `emailAuthImplementation` (0xb6201692) function - pub fn email_auth_implementation( - &self, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([182, 32, 22, 146], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `emailAuthImplementationAddr` (0x1098e02e) function - pub fn email_auth_implementation_addr( - &self, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([16, 152, 224, 46], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `extractRecoveredAccountFromAcceptanceSubject` (0xe81dcaf2) function - pub fn extract_recovered_account_from_acceptance_subject( - &self, - subject_params: ::std::vec::Vec<::ethers::core::types::Bytes>, - template_idx: ::ethers::core::types::U256, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([232, 29, 202, 242], (subject_params, template_idx)) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `extractRecoveredAccountFromRecoverySubject` (0x30e6a5ab) function - pub fn extract_recovered_account_from_recovery_subject( - &self, - subject_params: ::std::vec::Vec<::ethers::core::types::Bytes>, - template_idx: ::ethers::core::types::U256, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([48, 230, 165, 171], (subject_params, template_idx)) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `handleAcceptance` (0x0481af67) function - pub fn handle_acceptance( - &self, - email_auth_msg: EmailAuthMsg, - template_idx: ::ethers::core::types::U256, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([4, 129, 175, 103], (email_auth_msg, template_idx)) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `handleRecovery` (0xb68126fa) function - pub fn handle_recovery( - &self, - email_auth_msg: EmailAuthMsg, - template_idx: ::ethers::core::types::U256, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([182, 129, 38, 250], (email_auth_msg, template_idx)) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `isActivated` (0xc9faa7c5) function - pub fn is_activated( - &self, - recovered_account: ::ethers::core::types::Address, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([201, 250, 167, 197], recovered_account) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `proxyBytecodeHash` (0x85f60f7e) function - pub fn proxy_bytecode_hash( - &self, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([133, 246, 15, 126], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `recoverySubjectTemplates` (0x3e91cdcd) function - pub fn recovery_subject_templates( - &self, - ) -> ::ethers::contract::builders::ContractCall< - M, - ::std::vec::Vec<::std::vec::Vec<::std::string::String>>, - > { - self.0 - .method_hash([62, 145, 205, 205], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `verifier` (0x2b7ac3f3) function - pub fn verifier( - &self, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([43, 122, 195, 243], ()) - .expect("method not found (this should never happen)") - } - ///Calls the contract's `verifierAddr` (0x663ea2e2) function - pub fn verifier_addr( - &self, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([102, 62, 162, 226], ()) - .expect("method not found (this should never happen)") - } - } - impl From<::ethers::contract::Contract> - for EmailAccountRecovery - { - fn from(contract: ::ethers::contract::Contract) -> Self { - Self::new(contract.address(), contract.client()) - } - } - ///Container type for all input parameters for the `acceptanceSubjectTemplates` function with signature `acceptanceSubjectTemplates()` and selector `0x5bafadda` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall( - name = "acceptanceSubjectTemplates", - abi = "acceptanceSubjectTemplates()" - )] - pub struct AcceptanceSubjectTemplatesCall; - ///Container type for all input parameters for the `completeRecovery` function with signature `completeRecovery(address,bytes)` and selector `0xc18d09cf` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall(name = "completeRecovery", abi = "completeRecovery(address,bytes)")] - pub struct CompleteRecoveryCall { - pub account: ::ethers::core::types::Address, - pub complete_calldata: ::ethers::core::types::Bytes, - } - ///Container type for all input parameters for the `computeAcceptanceTemplateId` function with signature `computeAcceptanceTemplateId(uint256)` and selector `0x32ccc2f2` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall( - name = "computeAcceptanceTemplateId", - abi = "computeAcceptanceTemplateId(uint256)" - )] - pub struct ComputeAcceptanceTemplateIdCall { - pub template_idx: ::ethers::core::types::U256, - } - ///Container type for all input parameters for the `computeEmailAuthAddress` function with signature `computeEmailAuthAddress(address,bytes32)` and selector `0x3a8eab14` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall( - name = "computeEmailAuthAddress", - abi = "computeEmailAuthAddress(address,bytes32)" - )] - pub struct ComputeEmailAuthAddressCall { - pub recovered_account: ::ethers::core::types::Address, - pub account_salt: [u8; 32], - } - ///Container type for all input parameters for the `computeRecoveryTemplateId` function with signature `computeRecoveryTemplateId(uint256)` and selector `0x6da99515` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall( - name = "computeRecoveryTemplateId", - abi = "computeRecoveryTemplateId(uint256)" - )] - pub struct ComputeRecoveryTemplateIdCall { - pub template_idx: ::ethers::core::types::U256, - } - ///Container type for all input parameters for the `dkim` function with signature `dkim()` and selector `0x400ad5ce` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall(name = "dkim", abi = "dkim()")] - pub struct DkimCall; - ///Container type for all input parameters for the `dkimAddr` function with signature `dkimAddr()` and selector `0x73357f85` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall(name = "dkimAddr", abi = "dkimAddr()")] - pub struct DkimAddrCall; - ///Container type for all input parameters for the `emailAuthImplementation` function with signature `emailAuthImplementation()` and selector `0xb6201692` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall(name = "emailAuthImplementation", abi = "emailAuthImplementation()")] - pub struct EmailAuthImplementationCall; - ///Container type for all input parameters for the `emailAuthImplementationAddr` function with signature `emailAuthImplementationAddr()` and selector `0x1098e02e` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall( - name = "emailAuthImplementationAddr", - abi = "emailAuthImplementationAddr()" - )] - pub struct EmailAuthImplementationAddrCall; - ///Container type for all input parameters for the `extractRecoveredAccountFromAcceptanceSubject` function with signature `extractRecoveredAccountFromAcceptanceSubject(bytes[],uint256)` and selector `0xe81dcaf2` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall( - name = "extractRecoveredAccountFromAcceptanceSubject", - abi = "extractRecoveredAccountFromAcceptanceSubject(bytes[],uint256)" - )] - pub struct ExtractRecoveredAccountFromAcceptanceSubjectCall { - pub subject_params: ::std::vec::Vec<::ethers::core::types::Bytes>, - pub template_idx: ::ethers::core::types::U256, - } - ///Container type for all input parameters for the `extractRecoveredAccountFromRecoverySubject` function with signature `extractRecoveredAccountFromRecoverySubject(bytes[],uint256)` and selector `0x30e6a5ab` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall( - name = "extractRecoveredAccountFromRecoverySubject", - abi = "extractRecoveredAccountFromRecoverySubject(bytes[],uint256)" - )] - pub struct ExtractRecoveredAccountFromRecoverySubjectCall { - pub subject_params: ::std::vec::Vec<::ethers::core::types::Bytes>, - pub template_idx: ::ethers::core::types::U256, - } - ///Container type for all input parameters for the `handleAcceptance` function with signature `handleAcceptance((uint256,bytes[],uint256,(string,bytes32,uint256,string,bytes32,bytes32,bool,bytes)),uint256)` and selector `0x0481af67` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall( - name = "handleAcceptance", - abi = "handleAcceptance((uint256,bytes[],uint256,(string,bytes32,uint256,string,bytes32,bytes32,bool,bytes)),uint256)" - )] - pub struct HandleAcceptanceCall { - pub email_auth_msg: EmailAuthMsg, - pub template_idx: ::ethers::core::types::U256, - } - ///Container type for all input parameters for the `handleRecovery` function with signature `handleRecovery((uint256,bytes[],uint256,(string,bytes32,uint256,string,bytes32,bytes32,bool,bytes)),uint256)` and selector `0xb68126fa` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall( - name = "handleRecovery", - abi = "handleRecovery((uint256,bytes[],uint256,(string,bytes32,uint256,string,bytes32,bytes32,bool,bytes)),uint256)" - )] - pub struct HandleRecoveryCall { - pub email_auth_msg: EmailAuthMsg, - pub template_idx: ::ethers::core::types::U256, - } - ///Container type for all input parameters for the `isActivated` function with signature `isActivated(address)` and selector `0xc9faa7c5` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall(name = "isActivated", abi = "isActivated(address)")] - pub struct IsActivatedCall { - pub recovered_account: ::ethers::core::types::Address, - } - ///Container type for all input parameters for the `proxyBytecodeHash` function with signature `proxyBytecodeHash()` and selector `0x85f60f7e` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall(name = "proxyBytecodeHash", abi = "proxyBytecodeHash()")] - pub struct ProxyBytecodeHashCall; - ///Container type for all input parameters for the `recoverySubjectTemplates` function with signature `recoverySubjectTemplates()` and selector `0x3e91cdcd` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall(name = "recoverySubjectTemplates", abi = "recoverySubjectTemplates()")] - pub struct RecoverySubjectTemplatesCall; - ///Container type for all input parameters for the `verifier` function with signature `verifier()` and selector `0x2b7ac3f3` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall(name = "verifier", abi = "verifier()")] - pub struct VerifierCall; - ///Container type for all input parameters for the `verifierAddr` function with signature `verifierAddr()` and selector `0x663ea2e2` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - #[ethcall(name = "verifierAddr", abi = "verifierAddr()")] - pub struct VerifierAddrCall; - ///Container type for all of the contract's call - #[derive(Clone, ::ethers::contract::EthAbiType, Debug, PartialEq, Eq, Hash)] - pub enum EmailAccountRecoveryCalls { - AcceptanceSubjectTemplates(AcceptanceSubjectTemplatesCall), - CompleteRecovery(CompleteRecoveryCall), - ComputeAcceptanceTemplateId(ComputeAcceptanceTemplateIdCall), - ComputeEmailAuthAddress(ComputeEmailAuthAddressCall), - ComputeRecoveryTemplateId(ComputeRecoveryTemplateIdCall), - Dkim(DkimCall), - DkimAddr(DkimAddrCall), - EmailAuthImplementation(EmailAuthImplementationCall), - EmailAuthImplementationAddr(EmailAuthImplementationAddrCall), - ExtractRecoveredAccountFromAcceptanceSubject( - ExtractRecoveredAccountFromAcceptanceSubjectCall, - ), - ExtractRecoveredAccountFromRecoverySubject(ExtractRecoveredAccountFromRecoverySubjectCall), - HandleAcceptance(HandleAcceptanceCall), - HandleRecovery(HandleRecoveryCall), - IsActivated(IsActivatedCall), - ProxyBytecodeHash(ProxyBytecodeHashCall), - RecoverySubjectTemplates(RecoverySubjectTemplatesCall), - Verifier(VerifierCall), - VerifierAddr(VerifierAddrCall), - } - impl ::ethers::core::abi::AbiDecode for EmailAccountRecoveryCalls { - fn decode( - data: impl AsRef<[u8]>, - ) -> ::core::result::Result { - let data = data.as_ref(); - if let Ok(decoded) = - ::decode(data) - { - return Ok(Self::AcceptanceSubjectTemplates(decoded)); - } - if let Ok(decoded) = - ::decode(data) - { - return Ok(Self::CompleteRecovery(decoded)); - } - if let Ok(decoded) = - ::decode(data) - { - return Ok(Self::ComputeAcceptanceTemplateId(decoded)); - } - if let Ok(decoded) = - ::decode(data) - { - return Ok(Self::ComputeEmailAuthAddress(decoded)); - } - if let Ok(decoded) = - ::decode(data) - { - return Ok(Self::ComputeRecoveryTemplateId(decoded)); - } - if let Ok(decoded) = ::decode(data) { - return Ok(Self::Dkim(decoded)); - } - if let Ok(decoded) = ::decode(data) { - return Ok(Self::DkimAddr(decoded)); - } - if let Ok(decoded) = - ::decode(data) - { - return Ok(Self::EmailAuthImplementation(decoded)); - } - if let Ok(decoded) = - ::decode(data) - { - return Ok(Self::EmailAuthImplementationAddr(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::ExtractRecoveredAccountFromAcceptanceSubject(decoded)); - } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::ExtractRecoveredAccountFromRecoverySubject(decoded)); - } - if let Ok(decoded) = - ::decode(data) - { - return Ok(Self::HandleAcceptance(decoded)); - } - if let Ok(decoded) = - ::decode(data) - { - return Ok(Self::HandleRecovery(decoded)); - } - if let Ok(decoded) = ::decode(data) { - return Ok(Self::IsActivated(decoded)); - } - if let Ok(decoded) = - ::decode(data) - { - return Ok(Self::ProxyBytecodeHash(decoded)); - } - if let Ok(decoded) = - ::decode(data) - { - return Ok(Self::RecoverySubjectTemplates(decoded)); - } - if let Ok(decoded) = ::decode(data) { - return Ok(Self::Verifier(decoded)); - } - if let Ok(decoded) = ::decode(data) - { - return Ok(Self::VerifierAddr(decoded)); - } - Err(::ethers::core::abi::Error::InvalidData.into()) - } - } - impl ::ethers::core::abi::AbiEncode for EmailAccountRecoveryCalls { - fn encode(self) -> Vec { - match self { - Self::AcceptanceSubjectTemplates(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::CompleteRecovery(element) => ::ethers::core::abi::AbiEncode::encode(element), - Self::ComputeAcceptanceTemplateId(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::ComputeEmailAuthAddress(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::ComputeRecoveryTemplateId(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::Dkim(element) => ::ethers::core::abi::AbiEncode::encode(element), - Self::DkimAddr(element) => ::ethers::core::abi::AbiEncode::encode(element), - Self::EmailAuthImplementation(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::EmailAuthImplementationAddr(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::ExtractRecoveredAccountFromAcceptanceSubject(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::ExtractRecoveredAccountFromRecoverySubject(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::HandleAcceptance(element) => ::ethers::core::abi::AbiEncode::encode(element), - Self::HandleRecovery(element) => ::ethers::core::abi::AbiEncode::encode(element), - Self::IsActivated(element) => ::ethers::core::abi::AbiEncode::encode(element), - Self::ProxyBytecodeHash(element) => ::ethers::core::abi::AbiEncode::encode(element), - Self::RecoverySubjectTemplates(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } - Self::Verifier(element) => ::ethers::core::abi::AbiEncode::encode(element), - Self::VerifierAddr(element) => ::ethers::core::abi::AbiEncode::encode(element), - } - } - } - impl ::core::fmt::Display for EmailAccountRecoveryCalls { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - match self { - Self::AcceptanceSubjectTemplates(element) => ::core::fmt::Display::fmt(element, f), - Self::CompleteRecovery(element) => ::core::fmt::Display::fmt(element, f), - Self::ComputeAcceptanceTemplateId(element) => ::core::fmt::Display::fmt(element, f), - Self::ComputeEmailAuthAddress(element) => ::core::fmt::Display::fmt(element, f), - Self::ComputeRecoveryTemplateId(element) => ::core::fmt::Display::fmt(element, f), - Self::Dkim(element) => ::core::fmt::Display::fmt(element, f), - Self::DkimAddr(element) => ::core::fmt::Display::fmt(element, f), - Self::EmailAuthImplementation(element) => ::core::fmt::Display::fmt(element, f), - Self::EmailAuthImplementationAddr(element) => ::core::fmt::Display::fmt(element, f), - Self::ExtractRecoveredAccountFromAcceptanceSubject(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::ExtractRecoveredAccountFromRecoverySubject(element) => { - ::core::fmt::Display::fmt(element, f) - } - Self::HandleAcceptance(element) => ::core::fmt::Display::fmt(element, f), - Self::HandleRecovery(element) => ::core::fmt::Display::fmt(element, f), - Self::IsActivated(element) => ::core::fmt::Display::fmt(element, f), - Self::ProxyBytecodeHash(element) => ::core::fmt::Display::fmt(element, f), - Self::RecoverySubjectTemplates(element) => ::core::fmt::Display::fmt(element, f), - Self::Verifier(element) => ::core::fmt::Display::fmt(element, f), - Self::VerifierAddr(element) => ::core::fmt::Display::fmt(element, f), - } - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: AcceptanceSubjectTemplatesCall) -> Self { - Self::AcceptanceSubjectTemplates(value) - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: CompleteRecoveryCall) -> Self { - Self::CompleteRecovery(value) - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: ComputeAcceptanceTemplateIdCall) -> Self { - Self::ComputeAcceptanceTemplateId(value) - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: ComputeEmailAuthAddressCall) -> Self { - Self::ComputeEmailAuthAddress(value) - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: ComputeRecoveryTemplateIdCall) -> Self { - Self::ComputeRecoveryTemplateId(value) - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: DkimCall) -> Self { - Self::Dkim(value) - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: DkimAddrCall) -> Self { - Self::DkimAddr(value) - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: EmailAuthImplementationCall) -> Self { - Self::EmailAuthImplementation(value) - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: EmailAuthImplementationAddrCall) -> Self { - Self::EmailAuthImplementationAddr(value) - } - } - impl ::core::convert::From - for EmailAccountRecoveryCalls - { - fn from(value: ExtractRecoveredAccountFromAcceptanceSubjectCall) -> Self { - Self::ExtractRecoveredAccountFromAcceptanceSubject(value) - } - } - impl ::core::convert::From - for EmailAccountRecoveryCalls - { - fn from(value: ExtractRecoveredAccountFromRecoverySubjectCall) -> Self { - Self::ExtractRecoveredAccountFromRecoverySubject(value) - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: HandleAcceptanceCall) -> Self { - Self::HandleAcceptance(value) - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: HandleRecoveryCall) -> Self { - Self::HandleRecovery(value) - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: IsActivatedCall) -> Self { - Self::IsActivated(value) - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: ProxyBytecodeHashCall) -> Self { - Self::ProxyBytecodeHash(value) - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: RecoverySubjectTemplatesCall) -> Self { - Self::RecoverySubjectTemplates(value) - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: VerifierCall) -> Self { - Self::Verifier(value) - } - } - impl ::core::convert::From for EmailAccountRecoveryCalls { - fn from(value: VerifierAddrCall) -> Self { - Self::VerifierAddr(value) - } - } - ///Container type for all return fields from the `acceptanceSubjectTemplates` function with signature `acceptanceSubjectTemplates()` and selector `0x5bafadda` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct AcceptanceSubjectTemplatesReturn( - pub ::std::vec::Vec<::std::vec::Vec<::std::string::String>>, - ); - ///Container type for all return fields from the `computeAcceptanceTemplateId` function with signature `computeAcceptanceTemplateId(uint256)` and selector `0x32ccc2f2` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct ComputeAcceptanceTemplateIdReturn(pub ::ethers::core::types::U256); - ///Container type for all return fields from the `computeEmailAuthAddress` function with signature `computeEmailAuthAddress(address,bytes32)` and selector `0x3a8eab14` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct ComputeEmailAuthAddressReturn(pub ::ethers::core::types::Address); - ///Container type for all return fields from the `computeRecoveryTemplateId` function with signature `computeRecoveryTemplateId(uint256)` and selector `0x6da99515` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct ComputeRecoveryTemplateIdReturn(pub ::ethers::core::types::U256); - ///Container type for all return fields from the `dkim` function with signature `dkim()` and selector `0x400ad5ce` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct DkimReturn(pub ::ethers::core::types::Address); - ///Container type for all return fields from the `dkimAddr` function with signature `dkimAddr()` and selector `0x73357f85` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct DkimAddrReturn(pub ::ethers::core::types::Address); - ///Container type for all return fields from the `emailAuthImplementation` function with signature `emailAuthImplementation()` and selector `0xb6201692` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct EmailAuthImplementationReturn(pub ::ethers::core::types::Address); - ///Container type for all return fields from the `emailAuthImplementationAddr` function with signature `emailAuthImplementationAddr()` and selector `0x1098e02e` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct EmailAuthImplementationAddrReturn(pub ::ethers::core::types::Address); - ///Container type for all return fields from the `extractRecoveredAccountFromAcceptanceSubject` function with signature `extractRecoveredAccountFromAcceptanceSubject(bytes[],uint256)` and selector `0xe81dcaf2` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct ExtractRecoveredAccountFromAcceptanceSubjectReturn( - pub ::ethers::core::types::Address, - ); - ///Container type for all return fields from the `extractRecoveredAccountFromRecoverySubject` function with signature `extractRecoveredAccountFromRecoverySubject(bytes[],uint256)` and selector `0x30e6a5ab` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct ExtractRecoveredAccountFromRecoverySubjectReturn(pub ::ethers::core::types::Address); - ///Container type for all return fields from the `isActivated` function with signature `isActivated(address)` and selector `0xc9faa7c5` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct IsActivatedReturn(pub bool); - ///Container type for all return fields from the `proxyBytecodeHash` function with signature `proxyBytecodeHash()` and selector `0x85f60f7e` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct ProxyBytecodeHashReturn(pub [u8; 32]); - ///Container type for all return fields from the `recoverySubjectTemplates` function with signature `recoverySubjectTemplates()` and selector `0x3e91cdcd` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct RecoverySubjectTemplatesReturn( - pub ::std::vec::Vec<::std::vec::Vec<::std::string::String>>, - ); - ///Container type for all return fields from the `verifier` function with signature `verifier()` and selector `0x2b7ac3f3` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct VerifierReturn(pub ::ethers::core::types::Address); - ///Container type for all return fields from the `verifierAddr` function with signature `verifierAddr()` and selector `0x663ea2e2` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct VerifierAddrReturn(pub ::ethers::core::types::Address); - ///`EmailAuthMsg(uint256,bytes[],uint256,(string,bytes32,uint256,string,bytes32,bytes32,bool,bytes))` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct EmailAuthMsg { - pub template_id: ::ethers::core::types::U256, - pub subject_params: ::std::vec::Vec<::ethers::core::types::Bytes>, - pub skiped_subject_prefix: ::ethers::core::types::U256, - pub proof: EmailProof, - } - ///`EmailProof(string,bytes32,uint256,string,bytes32,bytes32,bool,bytes)` - #[derive( - Clone, - ::ethers::contract::EthAbiType, - ::ethers::contract::EthAbiCodec, - Default, - Debug, - PartialEq, - Eq, - Hash, - )] - pub struct EmailProof { - pub domain_name: ::std::string::String, - pub public_key_hash: [u8; 32], - pub timestamp: ::ethers::core::types::U256, - pub masked_subject: ::std::string::String, - pub email_nullifier: [u8; 32], - pub account_salt: [u8; 32], - pub is_code_exist: bool, - pub proof: ::ethers::core::types::Bytes, - } -} diff --git a/packages/relayer/src/abis/email_auth.rs b/packages/relayer/src/abis/email_auth.rs index 10d27c61..3c2a0707 100644 --- a/packages/relayer/src/abis/email_auth.rs +++ b/packages/relayer/src/abis/email_auth.rs @@ -103,6 +103,45 @@ pub mod email_auth { }, ], ), + ( + ::std::borrow::ToOwned::to_owned("commandTemplates"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("commandTemplates"), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Uint( + 256usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("uint256"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Uint( + 256usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("uint256"), + ), + }, + ], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::String, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("string"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + }, + ], + ), ( ::std::borrow::ToOwned::to_owned("controller"), ::std::vec![ @@ -124,11 +163,11 @@ pub mod email_auth { ], ), ( - ::std::borrow::ToOwned::to_owned("deleteSubjectTemplate"), + ::std::borrow::ToOwned::to_owned("deleteCommandTemplate"), ::std::vec![ ::ethers::core::abi::ethabi::Function { name: ::std::borrow::ToOwned::to_owned( - "deleteSubjectTemplate", + "deleteCommandTemplate", ), inputs: ::std::vec![ ::ethers::core::abi::ethabi::Param { @@ -168,10 +207,10 @@ pub mod email_auth { ], ), ( - ::std::borrow::ToOwned::to_owned("getSubjectTemplate"), + ::std::borrow::ToOwned::to_owned("getCommandTemplate"), ::std::vec![ ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("getSubjectTemplate"), + name: ::std::borrow::ToOwned::to_owned("getCommandTemplate"), inputs: ::std::vec![ ::ethers::core::abi::ethabi::Param { name: ::std::borrow::ToOwned::to_owned("_templateId"), @@ -278,11 +317,11 @@ pub mod email_auth { ], ), ( - ::std::borrow::ToOwned::to_owned("insertSubjectTemplate"), + ::std::borrow::ToOwned::to_owned("insertCommandTemplate"), ::std::vec![ ::ethers::core::abi::ethabi::Function { name: ::std::borrow::ToOwned::to_owned( - "insertSubjectTemplate", + "insertCommandTemplate", ), inputs: ::std::vec![ ::ethers::core::abi::ethabi::Param { @@ -295,7 +334,7 @@ pub mod email_auth { ), }, ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("_subjectTemplate"), + name: ::std::borrow::ToOwned::to_owned("_commandTemplate"), kind: ::ethers::core::abi::ethabi::ParamType::Array( ::std::boxed::Box::new( ::ethers::core::abi::ethabi::ParamType::String, @@ -410,45 +449,6 @@ pub mod email_auth { }, ], ), - ( - ::std::borrow::ToOwned::to_owned("subjectTemplates"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("subjectTemplates"), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Uint( - 256usize, - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("uint256"), - ), - }, - ::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::Uint( - 256usize, - ), - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("uint256"), - ), - }, - ], - outputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::string::String::new(), - kind: ::ethers::core::abi::ethabi::ParamType::String, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("string"), - ), - }, - ], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, - }, - ], - ), ( ::std::borrow::ToOwned::to_owned("timestampCheckEnabled"), ::std::vec![ @@ -492,31 +492,11 @@ pub mod email_auth { ], ), ( - ::std::borrow::ToOwned::to_owned("updateDKIMRegistry"), - ::std::vec![ - ::ethers::core::abi::ethabi::Function { - name: ::std::borrow::ToOwned::to_owned("updateDKIMRegistry"), - inputs: ::std::vec![ - ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("_dkimRegistryAddr"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - internal_type: ::core::option::Option::Some( - ::std::borrow::ToOwned::to_owned("address"), - ), - }, - ], - outputs: ::std::vec![], - constant: ::core::option::Option::None, - state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, - }, - ], - ), - ( - ::std::borrow::ToOwned::to_owned("updateSubjectTemplate"), + ::std::borrow::ToOwned::to_owned("updateCommandTemplate"), ::std::vec![ ::ethers::core::abi::ethabi::Function { name: ::std::borrow::ToOwned::to_owned( - "updateSubjectTemplate", + "updateCommandTemplate", ), inputs: ::std::vec![ ::ethers::core::abi::ethabi::Param { @@ -529,7 +509,7 @@ pub mod email_auth { ), }, ::ethers::core::abi::ethabi::Param { - name: ::std::borrow::ToOwned::to_owned("_subjectTemplate"), + name: ::std::borrow::ToOwned::to_owned("_commandTemplate"), kind: ::ethers::core::abi::ethabi::ParamType::Array( ::std::boxed::Box::new( ::ethers::core::abi::ethabi::ParamType::String, @@ -546,6 +526,26 @@ pub mod email_auth { }, ], ), + ( + ::std::borrow::ToOwned::to_owned("updateDKIMRegistry"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("updateDKIMRegistry"), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("_dkimRegistryAddr"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ], + outputs: ::std::vec![], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, + }, + ], + ), ( ::std::borrow::ToOwned::to_owned("updateVerifier"), ::std::vec![ @@ -646,16 +646,18 @@ pub mod email_auth { ]), events: ::core::convert::From::from([ ( - ::std::borrow::ToOwned::to_owned("DKIMRegistryUpdated"), + ::std::borrow::ToOwned::to_owned("CommandTemplateDeleted"), ::std::vec![ ::ethers::core::abi::ethabi::Event { name: ::std::borrow::ToOwned::to_owned( - "DKIMRegistryUpdated", + "CommandTemplateDeleted", ), inputs: ::std::vec![ ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("dkimRegistry"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, + name: ::std::borrow::ToOwned::to_owned("templateId"), + kind: ::ethers::core::abi::ethabi::ParamType::Uint( + 256usize, + ), indexed: true, }, ], @@ -664,36 +666,19 @@ pub mod email_auth { ], ), ( - ::std::borrow::ToOwned::to_owned("EmailAuthed"), + ::std::borrow::ToOwned::to_owned("CommandTemplateInserted"), ::std::vec![ ::ethers::core::abi::ethabi::Event { - name: ::std::borrow::ToOwned::to_owned("EmailAuthed"), + name: ::std::borrow::ToOwned::to_owned( + "CommandTemplateInserted", + ), inputs: ::std::vec![ - ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("emailNullifier"), - kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( - 32usize, - ), - indexed: true, - }, - ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("accountSalt"), - kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( - 32usize, - ), - indexed: true, - }, - ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("isCodeExist"), - kind: ::ethers::core::abi::ethabi::ParamType::Bool, - indexed: false, - }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("templateId"), kind: ::ethers::core::abi::ethabi::ParamType::Uint( 256usize, ), - indexed: false, + indexed: true, }, ], anonymous: false, @@ -701,15 +686,19 @@ pub mod email_auth { ], ), ( - ::std::borrow::ToOwned::to_owned("Initialized"), + ::std::borrow::ToOwned::to_owned("CommandTemplateUpdated"), ::std::vec![ ::ethers::core::abi::ethabi::Event { - name: ::std::borrow::ToOwned::to_owned("Initialized"), + name: ::std::borrow::ToOwned::to_owned( + "CommandTemplateUpdated", + ), inputs: ::std::vec![ ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("version"), - kind: ::ethers::core::abi::ethabi::ParamType::Uint(64usize), - indexed: false, + name: ::std::borrow::ToOwned::to_owned("templateId"), + kind: ::ethers::core::abi::ethabi::ParamType::Uint( + 256usize, + ), + indexed: true, }, ], anonymous: false, @@ -717,20 +706,15 @@ pub mod email_auth { ], ), ( - ::std::borrow::ToOwned::to_owned("OwnershipTransferred"), + ::std::borrow::ToOwned::to_owned("DKIMRegistryUpdated"), ::std::vec![ ::ethers::core::abi::ethabi::Event { name: ::std::borrow::ToOwned::to_owned( - "OwnershipTransferred", + "DKIMRegistryUpdated", ), inputs: ::std::vec![ ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("previousOwner"), - kind: ::ethers::core::abi::ethabi::ParamType::Address, - indexed: true, - }, - ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("newOwner"), + name: ::std::borrow::ToOwned::to_owned("dkimRegistry"), kind: ::ethers::core::abi::ethabi::ParamType::Address, indexed: true, }, @@ -740,19 +724,36 @@ pub mod email_auth { ], ), ( - ::std::borrow::ToOwned::to_owned("SubjectTemplateDeleted"), + ::std::borrow::ToOwned::to_owned("EmailAuthed"), ::std::vec![ ::ethers::core::abi::ethabi::Event { - name: ::std::borrow::ToOwned::to_owned( - "SubjectTemplateDeleted", - ), + name: ::std::borrow::ToOwned::to_owned("EmailAuthed"), inputs: ::std::vec![ + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("emailNullifier"), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + indexed: true, + }, + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("accountSalt"), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + indexed: true, + }, + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("isCodeExist"), + kind: ::ethers::core::abi::ethabi::ParamType::Bool, + indexed: false, + }, ::ethers::core::abi::ethabi::EventParam { name: ::std::borrow::ToOwned::to_owned("templateId"), kind: ::ethers::core::abi::ethabi::ParamType::Uint( 256usize, ), - indexed: true, + indexed: false, }, ], anonymous: false, @@ -760,19 +761,15 @@ pub mod email_auth { ], ), ( - ::std::borrow::ToOwned::to_owned("SubjectTemplateInserted"), + ::std::borrow::ToOwned::to_owned("Initialized"), ::std::vec![ ::ethers::core::abi::ethabi::Event { - name: ::std::borrow::ToOwned::to_owned( - "SubjectTemplateInserted", - ), + name: ::std::borrow::ToOwned::to_owned("Initialized"), inputs: ::std::vec![ ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("templateId"), - kind: ::ethers::core::abi::ethabi::ParamType::Uint( - 256usize, - ), - indexed: true, + name: ::std::borrow::ToOwned::to_owned("version"), + kind: ::ethers::core::abi::ethabi::ParamType::Uint(64usize), + indexed: false, }, ], anonymous: false, @@ -780,18 +777,21 @@ pub mod email_auth { ], ), ( - ::std::borrow::ToOwned::to_owned("SubjectTemplateUpdated"), + ::std::borrow::ToOwned::to_owned("OwnershipTransferred"), ::std::vec![ ::ethers::core::abi::ethabi::Event { name: ::std::borrow::ToOwned::to_owned( - "SubjectTemplateUpdated", + "OwnershipTransferred", ), inputs: ::std::vec![ ::ethers::core::abi::ethabi::EventParam { - name: ::std::borrow::ToOwned::to_owned("templateId"), - kind: ::ethers::core::abi::ethabi::ParamType::Uint( - 256usize, - ), + name: ::std::borrow::ToOwned::to_owned("previousOwner"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + indexed: true, + }, + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("newOwner"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, indexed: true, }, ], @@ -897,10 +897,10 @@ pub mod email_auth { ], ), ( - ::std::borrow::ToOwned::to_owned("FailedInnerCall"), + ::std::borrow::ToOwned::to_owned("FailedCall"), ::std::vec![ ::ethers::core::abi::ethabi::AbiError { - name: ::std::borrow::ToOwned::to_owned("FailedInnerCall"), + name: ::std::borrow::ToOwned::to_owned("FailedCall"), inputs: ::std::vec![], }, ], @@ -1066,6 +1066,16 @@ pub mod email_auth { .method_hash([173, 63, 95, 155], (email_auth_msg,)) .expect("method not found (this should never happen)") } + ///Calls the contract's `commandTemplates` (0x091c1650) function + pub fn command_templates( + &self, + p0: ::ethers::core::types::U256, + p1: ::ethers::core::types::U256, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([9, 28, 22, 80], (p0, p1)) + .expect("method not found (this should never happen)") + } ///Calls the contract's `controller` (0xf77c4791) function pub fn controller( &self, @@ -1077,13 +1087,13 @@ pub mod email_auth { .method_hash([247, 124, 71, 145], ()) .expect("method not found (this should never happen)") } - ///Calls the contract's `deleteSubjectTemplate` (0x519e50d1) function - pub fn delete_subject_template( + ///Calls the contract's `deleteCommandTemplate` (0x640e8b69) function + pub fn delete_command_template( &self, template_id: ::ethers::core::types::U256, ) -> ::ethers::contract::builders::ContractCall { self.0 - .method_hash([81, 158, 80, 209], template_id) + .method_hash([100, 14, 139, 105], template_id) .expect("method not found (this should never happen)") } ///Calls the contract's `dkimRegistryAddr` (0x1bc01b83) function @@ -1097,8 +1107,8 @@ pub mod email_auth { .method_hash([27, 192, 27, 131], ()) .expect("method not found (this should never happen)") } - ///Calls the contract's `getSubjectTemplate` (0x1e05a028) function - pub fn get_subject_template( + ///Calls the contract's `getCommandTemplate` (0x95e33c08) function + pub fn get_command_template( &self, template_id: ::ethers::core::types::U256, ) -> ::ethers::contract::builders::ContractCall< @@ -1106,7 +1116,7 @@ pub mod email_auth { ::std::vec::Vec<::std::string::String>, > { self.0 - .method_hash([30, 5, 160, 40], template_id) + .method_hash([149, 227, 60, 8], template_id) .expect("method not found (this should never happen)") } ///Calls the contract's `initDKIMRegistry` (0x557cf5ef) function @@ -1141,14 +1151,14 @@ pub mod email_auth { ) .expect("method not found (this should never happen)") } - ///Calls the contract's `insertSubjectTemplate` (0xc4b84df4) function - pub fn insert_subject_template( + ///Calls the contract's `insertCommandTemplate` (0x8ff3730f) function + pub fn insert_command_template( &self, template_id: ::ethers::core::types::U256, - subject_template: ::std::vec::Vec<::std::string::String>, + command_template: ::std::vec::Vec<::std::string::String>, ) -> ::ethers::contract::builders::ContractCall { self.0 - .method_hash([196, 184, 77, 244], (template_id, subject_template)) + .method_hash([143, 243, 115, 15], (template_id, command_template)) .expect("method not found (this should never happen)") } ///Calls the contract's `lastTimestamp` (0x19d8ac61) function @@ -1195,16 +1205,6 @@ pub mod email_auth { .method_hash([228, 83, 192, 243], enabled) .expect("method not found (this should never happen)") } - ///Calls the contract's `subjectTemplates` (0x4bd07760) function - pub fn subject_templates( - &self, - p0: ::ethers::core::types::U256, - p1: ::ethers::core::types::U256, - ) -> ::ethers::contract::builders::ContractCall { - self.0 - .method_hash([75, 208, 119, 96], (p0, p1)) - .expect("method not found (this should never happen)") - } ///Calls the contract's `timestampCheckEnabled` (0x3e56f529) function pub fn timestamp_check_enabled( &self, @@ -1222,23 +1222,23 @@ pub mod email_auth { .method_hash([242, 253, 227, 139], new_owner) .expect("method not found (this should never happen)") } - ///Calls the contract's `updateDKIMRegistry` (0xa500125c) function - pub fn update_dkim_registry( + ///Calls the contract's `updateCommandTemplate` (0x24e33f11) function + pub fn update_command_template( &self, - dkim_registry_addr: ::ethers::core::types::Address, + template_id: ::ethers::core::types::U256, + command_template: ::std::vec::Vec<::std::string::String>, ) -> ::ethers::contract::builders::ContractCall { self.0 - .method_hash([165, 0, 18, 92], dkim_registry_addr) + .method_hash([36, 227, 63, 17], (template_id, command_template)) .expect("method not found (this should never happen)") } - ///Calls the contract's `updateSubjectTemplate` (0x4dbb82f1) function - pub fn update_subject_template( + ///Calls the contract's `updateDKIMRegistry` (0xa500125c) function + pub fn update_dkim_registry( &self, - template_id: ::ethers::core::types::U256, - subject_template: ::std::vec::Vec<::std::string::String>, + dkim_registry_addr: ::ethers::core::types::Address, ) -> ::ethers::contract::builders::ContractCall { self.0 - .method_hash([77, 187, 130, 241], (template_id, subject_template)) + .method_hash([165, 0, 18, 92], dkim_registry_addr) .expect("method not found (this should never happen)") } ///Calls the contract's `updateVerifier` (0x97fc007c) function @@ -1280,73 +1280,73 @@ pub mod email_auth { .method_hash([102, 62, 162, 226], ()) .expect("method not found (this should never happen)") } - ///Gets the contract's `DKIMRegistryUpdated` event - pub fn dkim_registry_updated_filter( + ///Gets the contract's `CommandTemplateDeleted` event + pub fn command_template_deleted_filter( &self, ) -> ::ethers::contract::builders::Event< ::std::sync::Arc, M, - DkimregistryUpdatedFilter, + CommandTemplateDeletedFilter, > { self.0.event() } - ///Gets the contract's `EmailAuthed` event - pub fn email_authed_filter( + ///Gets the contract's `CommandTemplateInserted` event + pub fn command_template_inserted_filter( &self, ) -> ::ethers::contract::builders::Event< ::std::sync::Arc, M, - EmailAuthedFilter, + CommandTemplateInsertedFilter, > { self.0.event() } - ///Gets the contract's `Initialized` event - pub fn initialized_filter( + ///Gets the contract's `CommandTemplateUpdated` event + pub fn command_template_updated_filter( &self, ) -> ::ethers::contract::builders::Event< ::std::sync::Arc, M, - InitializedFilter, + CommandTemplateUpdatedFilter, > { self.0.event() } - ///Gets the contract's `OwnershipTransferred` event - pub fn ownership_transferred_filter( + ///Gets the contract's `DKIMRegistryUpdated` event + pub fn dkim_registry_updated_filter( &self, ) -> ::ethers::contract::builders::Event< ::std::sync::Arc, M, - OwnershipTransferredFilter, + DkimregistryUpdatedFilter, > { self.0.event() } - ///Gets the contract's `SubjectTemplateDeleted` event - pub fn subject_template_deleted_filter( + ///Gets the contract's `EmailAuthed` event + pub fn email_authed_filter( &self, ) -> ::ethers::contract::builders::Event< ::std::sync::Arc, M, - SubjectTemplateDeletedFilter, + EmailAuthedFilter, > { self.0.event() } - ///Gets the contract's `SubjectTemplateInserted` event - pub fn subject_template_inserted_filter( + ///Gets the contract's `Initialized` event + pub fn initialized_filter( &self, ) -> ::ethers::contract::builders::Event< ::std::sync::Arc, M, - SubjectTemplateInsertedFilter, + InitializedFilter, > { self.0.event() } - ///Gets the contract's `SubjectTemplateUpdated` event - pub fn subject_template_updated_filter( + ///Gets the contract's `OwnershipTransferred` event + pub fn ownership_transferred_filter( &self, ) -> ::ethers::contract::builders::Event< ::std::sync::Arc, M, - SubjectTemplateUpdatedFilter, + OwnershipTransferredFilter, > { self.0.event() } @@ -1443,7 +1443,7 @@ pub mod email_auth { )] #[etherror(name = "ERC1967NonPayable", abi = "ERC1967NonPayable()")] pub struct ERC1967NonPayable; - ///Custom Error type `FailedInnerCall` with signature `FailedInnerCall()` and selector `0x1425ea42` + ///Custom Error type `FailedCall` with signature `FailedCall()` and selector `0xd6bda275` #[derive( Clone, ::ethers::contract::EthError, @@ -1454,8 +1454,8 @@ pub mod email_auth { Eq, Hash )] - #[etherror(name = "FailedInnerCall", abi = "FailedInnerCall()")] - pub struct FailedInnerCall; + #[etherror(name = "FailedCall", abi = "FailedCall()")] + pub struct FailedCall; ///Custom Error type `InvalidInitialization` with signature `InvalidInitialization()` and selector `0xf92ee8a9` #[derive( Clone, @@ -1555,7 +1555,7 @@ pub mod email_auth { AddressEmptyCode(AddressEmptyCode), ERC1967InvalidImplementation(ERC1967InvalidImplementation), ERC1967NonPayable(ERC1967NonPayable), - FailedInnerCall(FailedInnerCall), + FailedCall(FailedCall), InvalidInitialization(InvalidInitialization), NotInitializing(NotInitializing), OwnableInvalidOwner(OwnableInvalidOwner), @@ -1591,10 +1591,10 @@ pub mod email_auth { ) { return Ok(Self::ERC1967NonPayable(decoded)); } - if let Ok(decoded) = ::decode( + if let Ok(decoded) = ::decode( data, ) { - return Ok(Self::FailedInnerCall(decoded)); + return Ok(Self::FailedCall(decoded)); } if let Ok(decoded) = ::decode( data, @@ -1641,7 +1641,7 @@ pub mod email_auth { Self::ERC1967NonPayable(element) => { ::ethers::core::abi::AbiEncode::encode(element) } - Self::FailedInnerCall(element) => { + Self::FailedCall(element) => { ::ethers::core::abi::AbiEncode::encode(element) } Self::InvalidInitialization(element) => { @@ -1683,9 +1683,7 @@ pub mod email_auth { true } _ if selector - == ::selector() => { - true - } + == ::selector() => true, _ if selector == ::selector() => { true @@ -1722,7 +1720,7 @@ pub mod email_auth { ::core::fmt::Display::fmt(element, f) } Self::ERC1967NonPayable(element) => ::core::fmt::Display::fmt(element, f), - Self::FailedInnerCall(element) => ::core::fmt::Display::fmt(element, f), + Self::FailedCall(element) => ::core::fmt::Display::fmt(element, f), Self::InvalidInitialization(element) => { ::core::fmt::Display::fmt(element, f) } @@ -1763,9 +1761,9 @@ pub mod email_auth { Self::ERC1967NonPayable(value) } } - impl ::core::convert::From for EmailAuthErrors { - fn from(value: FailedInnerCall) -> Self { - Self::FailedInnerCall(value) + impl ::core::convert::From for EmailAuthErrors { + fn from(value: FailedCall) -> Self { + Self::FailedCall(value) } } impl ::core::convert::From for EmailAuthErrors { @@ -1808,10 +1806,10 @@ pub mod email_auth { Eq, Hash )] - #[ethevent(name = "DKIMRegistryUpdated", abi = "DKIMRegistryUpdated(address)")] - pub struct DkimregistryUpdatedFilter { + #[ethevent(name = "CommandTemplateDeleted", abi = "CommandTemplateDeleted(uint256)")] + pub struct CommandTemplateDeletedFilter { #[ethevent(indexed)] - pub dkim_registry: ::ethers::core::types::Address, + pub template_id: ::ethers::core::types::U256, } #[derive( Clone, @@ -1823,13 +1821,12 @@ pub mod email_auth { Eq, Hash )] - #[ethevent(name = "EmailAuthed", abi = "EmailAuthed(bytes32,bytes32,bool,uint256)")] - pub struct EmailAuthedFilter { - #[ethevent(indexed)] - pub email_nullifier: [u8; 32], + #[ethevent( + name = "CommandTemplateInserted", + abi = "CommandTemplateInserted(uint256)" + )] + pub struct CommandTemplateInsertedFilter { #[ethevent(indexed)] - pub account_salt: [u8; 32], - pub is_code_exist: bool, pub template_id: ::ethers::core::types::U256, } #[derive( @@ -1842,9 +1839,10 @@ pub mod email_auth { Eq, Hash )] - #[ethevent(name = "Initialized", abi = "Initialized(uint64)")] - pub struct InitializedFilter { - pub version: u64, + #[ethevent(name = "CommandTemplateUpdated", abi = "CommandTemplateUpdated(uint256)")] + pub struct CommandTemplateUpdatedFilter { + #[ethevent(indexed)] + pub template_id: ::ethers::core::types::U256, } #[derive( Clone, @@ -1856,15 +1854,10 @@ pub mod email_auth { Eq, Hash )] - #[ethevent( - name = "OwnershipTransferred", - abi = "OwnershipTransferred(address,address)" - )] - pub struct OwnershipTransferredFilter { - #[ethevent(indexed)] - pub previous_owner: ::ethers::core::types::Address, + #[ethevent(name = "DKIMRegistryUpdated", abi = "DKIMRegistryUpdated(address)")] + pub struct DkimregistryUpdatedFilter { #[ethevent(indexed)] - pub new_owner: ::ethers::core::types::Address, + pub dkim_registry: ::ethers::core::types::Address, } #[derive( Clone, @@ -1876,9 +1869,13 @@ pub mod email_auth { Eq, Hash )] - #[ethevent(name = "SubjectTemplateDeleted", abi = "SubjectTemplateDeleted(uint256)")] - pub struct SubjectTemplateDeletedFilter { + #[ethevent(name = "EmailAuthed", abi = "EmailAuthed(bytes32,bytes32,bool,uint256)")] + pub struct EmailAuthedFilter { #[ethevent(indexed)] + pub email_nullifier: [u8; 32], + #[ethevent(indexed)] + pub account_salt: [u8; 32], + pub is_code_exist: bool, pub template_id: ::ethers::core::types::U256, } #[derive( @@ -1891,13 +1888,9 @@ pub mod email_auth { Eq, Hash )] - #[ethevent( - name = "SubjectTemplateInserted", - abi = "SubjectTemplateInserted(uint256)" - )] - pub struct SubjectTemplateInsertedFilter { - #[ethevent(indexed)] - pub template_id: ::ethers::core::types::U256, + #[ethevent(name = "Initialized", abi = "Initialized(uint64)")] + pub struct InitializedFilter { + pub version: u64, } #[derive( Clone, @@ -1909,10 +1902,15 @@ pub mod email_auth { Eq, Hash )] - #[ethevent(name = "SubjectTemplateUpdated", abi = "SubjectTemplateUpdated(uint256)")] - pub struct SubjectTemplateUpdatedFilter { + #[ethevent( + name = "OwnershipTransferred", + abi = "OwnershipTransferred(address,address)" + )] + pub struct OwnershipTransferredFilter { #[ethevent(indexed)] - pub template_id: ::ethers::core::types::U256, + pub previous_owner: ::ethers::core::types::Address, + #[ethevent(indexed)] + pub new_owner: ::ethers::core::types::Address, } #[derive( Clone, @@ -1961,13 +1959,13 @@ pub mod email_auth { ///Container type for all of the contract's events #[derive(Clone, ::ethers::contract::EthAbiType, Debug, PartialEq, Eq, Hash)] pub enum EmailAuthEvents { + CommandTemplateDeletedFilter(CommandTemplateDeletedFilter), + CommandTemplateInsertedFilter(CommandTemplateInsertedFilter), + CommandTemplateUpdatedFilter(CommandTemplateUpdatedFilter), DkimregistryUpdatedFilter(DkimregistryUpdatedFilter), EmailAuthedFilter(EmailAuthedFilter), InitializedFilter(InitializedFilter), OwnershipTransferredFilter(OwnershipTransferredFilter), - SubjectTemplateDeletedFilter(SubjectTemplateDeletedFilter), - SubjectTemplateInsertedFilter(SubjectTemplateInsertedFilter), - SubjectTemplateUpdatedFilter(SubjectTemplateUpdatedFilter), TimestampCheckEnabledFilter(TimestampCheckEnabledFilter), UpgradedFilter(UpgradedFilter), VerifierUpdatedFilter(VerifierUpdatedFilter), @@ -1976,6 +1974,15 @@ pub mod email_auth { fn decode_log( log: &::ethers::core::abi::RawLog, ) -> ::core::result::Result { + if let Ok(decoded) = CommandTemplateDeletedFilter::decode_log(log) { + return Ok(EmailAuthEvents::CommandTemplateDeletedFilter(decoded)); + } + if let Ok(decoded) = CommandTemplateInsertedFilter::decode_log(log) { + return Ok(EmailAuthEvents::CommandTemplateInsertedFilter(decoded)); + } + if let Ok(decoded) = CommandTemplateUpdatedFilter::decode_log(log) { + return Ok(EmailAuthEvents::CommandTemplateUpdatedFilter(decoded)); + } if let Ok(decoded) = DkimregistryUpdatedFilter::decode_log(log) { return Ok(EmailAuthEvents::DkimregistryUpdatedFilter(decoded)); } @@ -1988,15 +1995,6 @@ pub mod email_auth { if let Ok(decoded) = OwnershipTransferredFilter::decode_log(log) { return Ok(EmailAuthEvents::OwnershipTransferredFilter(decoded)); } - if let Ok(decoded) = SubjectTemplateDeletedFilter::decode_log(log) { - return Ok(EmailAuthEvents::SubjectTemplateDeletedFilter(decoded)); - } - if let Ok(decoded) = SubjectTemplateInsertedFilter::decode_log(log) { - return Ok(EmailAuthEvents::SubjectTemplateInsertedFilter(decoded)); - } - if let Ok(decoded) = SubjectTemplateUpdatedFilter::decode_log(log) { - return Ok(EmailAuthEvents::SubjectTemplateUpdatedFilter(decoded)); - } if let Ok(decoded) = TimestampCheckEnabledFilter::decode_log(log) { return Ok(EmailAuthEvents::TimestampCheckEnabledFilter(decoded)); } @@ -2012,21 +2010,21 @@ pub mod email_auth { impl ::core::fmt::Display for EmailAuthEvents { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { match self { - Self::DkimregistryUpdatedFilter(element) => { + Self::CommandTemplateDeletedFilter(element) => { ::core::fmt::Display::fmt(element, f) } - Self::EmailAuthedFilter(element) => ::core::fmt::Display::fmt(element, f), - Self::InitializedFilter(element) => ::core::fmt::Display::fmt(element, f), - Self::OwnershipTransferredFilter(element) => { + Self::CommandTemplateInsertedFilter(element) => { ::core::fmt::Display::fmt(element, f) } - Self::SubjectTemplateDeletedFilter(element) => { + Self::CommandTemplateUpdatedFilter(element) => { ::core::fmt::Display::fmt(element, f) } - Self::SubjectTemplateInsertedFilter(element) => { + Self::DkimregistryUpdatedFilter(element) => { ::core::fmt::Display::fmt(element, f) } - Self::SubjectTemplateUpdatedFilter(element) => { + Self::EmailAuthedFilter(element) => ::core::fmt::Display::fmt(element, f), + Self::InitializedFilter(element) => ::core::fmt::Display::fmt(element, f), + Self::OwnershipTransferredFilter(element) => { ::core::fmt::Display::fmt(element, f) } Self::TimestampCheckEnabledFilter(element) => { @@ -2039,6 +2037,21 @@ pub mod email_auth { } } } + impl ::core::convert::From for EmailAuthEvents { + fn from(value: CommandTemplateDeletedFilter) -> Self { + Self::CommandTemplateDeletedFilter(value) + } + } + impl ::core::convert::From for EmailAuthEvents { + fn from(value: CommandTemplateInsertedFilter) -> Self { + Self::CommandTemplateInsertedFilter(value) + } + } + impl ::core::convert::From for EmailAuthEvents { + fn from(value: CommandTemplateUpdatedFilter) -> Self { + Self::CommandTemplateUpdatedFilter(value) + } + } impl ::core::convert::From for EmailAuthEvents { fn from(value: DkimregistryUpdatedFilter) -> Self { Self::DkimregistryUpdatedFilter(value) @@ -2059,21 +2072,6 @@ pub mod email_auth { Self::OwnershipTransferredFilter(value) } } - impl ::core::convert::From for EmailAuthEvents { - fn from(value: SubjectTemplateDeletedFilter) -> Self { - Self::SubjectTemplateDeletedFilter(value) - } - } - impl ::core::convert::From for EmailAuthEvents { - fn from(value: SubjectTemplateInsertedFilter) -> Self { - Self::SubjectTemplateInsertedFilter(value) - } - } - impl ::core::convert::From for EmailAuthEvents { - fn from(value: SubjectTemplateUpdatedFilter) -> Self { - Self::SubjectTemplateUpdatedFilter(value) - } - } impl ::core::convert::From for EmailAuthEvents { fn from(value: TimestampCheckEnabledFilter) -> Self { Self::TimestampCheckEnabledFilter(value) @@ -2133,6 +2131,22 @@ pub mod email_auth { pub struct AuthEmailCall { pub email_auth_msg: EmailAuthMsg, } + ///Container type for all input parameters for the `commandTemplates` function with signature `commandTemplates(uint256,uint256)` and selector `0x091c1650` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall(name = "commandTemplates", abi = "commandTemplates(uint256,uint256)")] + pub struct CommandTemplatesCall( + pub ::ethers::core::types::U256, + pub ::ethers::core::types::U256, + ); ///Container type for all input parameters for the `controller` function with signature `controller()` and selector `0xf77c4791` #[derive( Clone, @@ -2146,7 +2160,7 @@ pub mod email_auth { )] #[ethcall(name = "controller", abi = "controller()")] pub struct ControllerCall; - ///Container type for all input parameters for the `deleteSubjectTemplate` function with signature `deleteSubjectTemplate(uint256)` and selector `0x519e50d1` + ///Container type for all input parameters for the `deleteCommandTemplate` function with signature `deleteCommandTemplate(uint256)` and selector `0x640e8b69` #[derive( Clone, ::ethers::contract::EthCall, @@ -2157,8 +2171,8 @@ pub mod email_auth { Eq, Hash )] - #[ethcall(name = "deleteSubjectTemplate", abi = "deleteSubjectTemplate(uint256)")] - pub struct DeleteSubjectTemplateCall { + #[ethcall(name = "deleteCommandTemplate", abi = "deleteCommandTemplate(uint256)")] + pub struct DeleteCommandTemplateCall { pub template_id: ::ethers::core::types::U256, } ///Container type for all input parameters for the `dkimRegistryAddr` function with signature `dkimRegistryAddr()` and selector `0x1bc01b83` @@ -2174,7 +2188,7 @@ pub mod email_auth { )] #[ethcall(name = "dkimRegistryAddr", abi = "dkimRegistryAddr()")] pub struct DkimRegistryAddrCall; - ///Container type for all input parameters for the `getSubjectTemplate` function with signature `getSubjectTemplate(uint256)` and selector `0x1e05a028` + ///Container type for all input parameters for the `getCommandTemplate` function with signature `getCommandTemplate(uint256)` and selector `0x95e33c08` #[derive( Clone, ::ethers::contract::EthCall, @@ -2185,8 +2199,8 @@ pub mod email_auth { Eq, Hash )] - #[ethcall(name = "getSubjectTemplate", abi = "getSubjectTemplate(uint256)")] - pub struct GetSubjectTemplateCall { + #[ethcall(name = "getCommandTemplate", abi = "getCommandTemplate(uint256)")] + pub struct GetCommandTemplateCall { pub template_id: ::ethers::core::types::U256, } ///Container type for all input parameters for the `initDKIMRegistry` function with signature `initDKIMRegistry(address)` and selector `0x557cf5ef` @@ -2236,7 +2250,7 @@ pub mod email_auth { pub account_salt: [u8; 32], pub controller: ::ethers::core::types::Address, } - ///Container type for all input parameters for the `insertSubjectTemplate` function with signature `insertSubjectTemplate(uint256,string[])` and selector `0xc4b84df4` + ///Container type for all input parameters for the `insertCommandTemplate` function with signature `insertCommandTemplate(uint256,string[])` and selector `0x8ff3730f` #[derive( Clone, ::ethers::contract::EthCall, @@ -2248,12 +2262,12 @@ pub mod email_auth { Hash )] #[ethcall( - name = "insertSubjectTemplate", - abi = "insertSubjectTemplate(uint256,string[])" + name = "insertCommandTemplate", + abi = "insertCommandTemplate(uint256,string[])" )] - pub struct InsertSubjectTemplateCall { + pub struct InsertCommandTemplateCall { pub template_id: ::ethers::core::types::U256, - pub subject_template: ::std::vec::Vec<::std::string::String>, + pub command_template: ::std::vec::Vec<::std::string::String>, } ///Container type for all input parameters for the `lastTimestamp` function with signature `lastTimestamp()` and selector `0x19d8ac61` #[derive( @@ -2322,22 +2336,6 @@ pub mod email_auth { pub struct SetTimestampCheckEnabledCall { pub enabled: bool, } - ///Container type for all input parameters for the `subjectTemplates` function with signature `subjectTemplates(uint256,uint256)` and selector `0x4bd07760` - #[derive( - Clone, - ::ethers::contract::EthCall, - ::ethers::contract::EthDisplay, - Default, - Debug, - PartialEq, - Eq, - Hash - )] - #[ethcall(name = "subjectTemplates", abi = "subjectTemplates(uint256,uint256)")] - pub struct SubjectTemplatesCall( - pub ::ethers::core::types::U256, - pub ::ethers::core::types::U256, - ); ///Container type for all input parameters for the `timestampCheckEnabled` function with signature `timestampCheckEnabled()` and selector `0x3e56f529` #[derive( Clone, @@ -2366,7 +2364,7 @@ pub mod email_auth { pub struct TransferOwnershipCall { pub new_owner: ::ethers::core::types::Address, } - ///Container type for all input parameters for the `updateDKIMRegistry` function with signature `updateDKIMRegistry(address)` and selector `0xa500125c` + ///Container type for all input parameters for the `updateCommandTemplate` function with signature `updateCommandTemplate(uint256,string[])` and selector `0x24e33f11` #[derive( Clone, ::ethers::contract::EthCall, @@ -2377,11 +2375,15 @@ pub mod email_auth { Eq, Hash )] - #[ethcall(name = "updateDKIMRegistry", abi = "updateDKIMRegistry(address)")] - pub struct UpdateDKIMRegistryCall { - pub dkim_registry_addr: ::ethers::core::types::Address, + #[ethcall( + name = "updateCommandTemplate", + abi = "updateCommandTemplate(uint256,string[])" + )] + pub struct UpdateCommandTemplateCall { + pub template_id: ::ethers::core::types::U256, + pub command_template: ::std::vec::Vec<::std::string::String>, } - ///Container type for all input parameters for the `updateSubjectTemplate` function with signature `updateSubjectTemplate(uint256,string[])` and selector `0x4dbb82f1` + ///Container type for all input parameters for the `updateDKIMRegistry` function with signature `updateDKIMRegistry(address)` and selector `0xa500125c` #[derive( Clone, ::ethers::contract::EthCall, @@ -2392,13 +2394,9 @@ pub mod email_auth { Eq, Hash )] - #[ethcall( - name = "updateSubjectTemplate", - abi = "updateSubjectTemplate(uint256,string[])" - )] - pub struct UpdateSubjectTemplateCall { - pub template_id: ::ethers::core::types::U256, - pub subject_template: ::std::vec::Vec<::std::string::String>, + #[ethcall(name = "updateDKIMRegistry", abi = "updateDKIMRegistry(address)")] + pub struct UpdateDKIMRegistryCall { + pub dkim_registry_addr: ::ethers::core::types::Address, } ///Container type for all input parameters for the `updateVerifier` function with signature `updateVerifier(address)` and selector `0x97fc007c` #[derive( @@ -2463,24 +2461,24 @@ pub mod email_auth { UpgradeInterfaceVersion(UpgradeInterfaceVersionCall), AccountSalt(AccountSaltCall), AuthEmail(AuthEmailCall), + CommandTemplates(CommandTemplatesCall), Controller(ControllerCall), - DeleteSubjectTemplate(DeleteSubjectTemplateCall), + DeleteCommandTemplate(DeleteCommandTemplateCall), DkimRegistryAddr(DkimRegistryAddrCall), - GetSubjectTemplate(GetSubjectTemplateCall), + GetCommandTemplate(GetCommandTemplateCall), InitDKIMRegistry(InitDKIMRegistryCall), InitVerifier(InitVerifierCall), Initialize(InitializeCall), - InsertSubjectTemplate(InsertSubjectTemplateCall), + InsertCommandTemplate(InsertCommandTemplateCall), LastTimestamp(LastTimestampCall), Owner(OwnerCall), ProxiableUUID(ProxiableUUIDCall), RenounceOwnership(RenounceOwnershipCall), SetTimestampCheckEnabled(SetTimestampCheckEnabledCall), - SubjectTemplates(SubjectTemplatesCall), TimestampCheckEnabled(TimestampCheckEnabledCall), TransferOwnership(TransferOwnershipCall), + UpdateCommandTemplate(UpdateCommandTemplateCall), UpdateDKIMRegistry(UpdateDKIMRegistryCall), - UpdateSubjectTemplate(UpdateSubjectTemplateCall), UpdateVerifier(UpdateVerifierCall), UpgradeToAndCall(UpgradeToAndCallCall), UsedNullifiers(UsedNullifiersCall), @@ -2506,25 +2504,30 @@ pub mod email_auth { ) { return Ok(Self::AuthEmail(decoded)); } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::CommandTemplates(decoded)); + } if let Ok(decoded) = ::decode( data, ) { return Ok(Self::Controller(decoded)); } - if let Ok(decoded) = ::decode( + if let Ok(decoded) = ::decode( data, ) { - return Ok(Self::DeleteSubjectTemplate(decoded)); + return Ok(Self::DeleteCommandTemplate(decoded)); } if let Ok(decoded) = ::decode( data, ) { return Ok(Self::DkimRegistryAddr(decoded)); } - if let Ok(decoded) = ::decode( + if let Ok(decoded) = ::decode( data, ) { - return Ok(Self::GetSubjectTemplate(decoded)); + return Ok(Self::GetCommandTemplate(decoded)); } if let Ok(decoded) = ::decode( data, @@ -2541,10 +2544,10 @@ pub mod email_auth { ) { return Ok(Self::Initialize(decoded)); } - if let Ok(decoded) = ::decode( + if let Ok(decoded) = ::decode( data, ) { - return Ok(Self::InsertSubjectTemplate(decoded)); + return Ok(Self::InsertCommandTemplate(decoded)); } if let Ok(decoded) = ::decode( data, @@ -2571,11 +2574,6 @@ pub mod email_auth { ) { return Ok(Self::SetTimestampCheckEnabled(decoded)); } - if let Ok(decoded) = ::decode( - data, - ) { - return Ok(Self::SubjectTemplates(decoded)); - } if let Ok(decoded) = ::decode( data, ) { @@ -2586,15 +2584,15 @@ pub mod email_auth { ) { return Ok(Self::TransferOwnership(decoded)); } - if let Ok(decoded) = ::decode( + if let Ok(decoded) = ::decode( data, ) { - return Ok(Self::UpdateDKIMRegistry(decoded)); + return Ok(Self::UpdateCommandTemplate(decoded)); } - if let Ok(decoded) = ::decode( + if let Ok(decoded) = ::decode( data, ) { - return Ok(Self::UpdateSubjectTemplate(decoded)); + return Ok(Self::UpdateDKIMRegistry(decoded)); } if let Ok(decoded) = ::decode( data, @@ -2631,16 +2629,19 @@ pub mod email_auth { Self::AuthEmail(element) => { ::ethers::core::abi::AbiEncode::encode(element) } + Self::CommandTemplates(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } Self::Controller(element) => { ::ethers::core::abi::AbiEncode::encode(element) } - Self::DeleteSubjectTemplate(element) => { + Self::DeleteCommandTemplate(element) => { ::ethers::core::abi::AbiEncode::encode(element) } Self::DkimRegistryAddr(element) => { ::ethers::core::abi::AbiEncode::encode(element) } - Self::GetSubjectTemplate(element) => { + Self::GetCommandTemplate(element) => { ::ethers::core::abi::AbiEncode::encode(element) } Self::InitDKIMRegistry(element) => { @@ -2652,7 +2653,7 @@ pub mod email_auth { Self::Initialize(element) => { ::ethers::core::abi::AbiEncode::encode(element) } - Self::InsertSubjectTemplate(element) => { + Self::InsertCommandTemplate(element) => { ::ethers::core::abi::AbiEncode::encode(element) } Self::LastTimestamp(element) => { @@ -2668,19 +2669,16 @@ pub mod email_auth { Self::SetTimestampCheckEnabled(element) => { ::ethers::core::abi::AbiEncode::encode(element) } - Self::SubjectTemplates(element) => { - ::ethers::core::abi::AbiEncode::encode(element) - } Self::TimestampCheckEnabled(element) => { ::ethers::core::abi::AbiEncode::encode(element) } Self::TransferOwnership(element) => { ::ethers::core::abi::AbiEncode::encode(element) } - Self::UpdateDKIMRegistry(element) => { + Self::UpdateCommandTemplate(element) => { ::ethers::core::abi::AbiEncode::encode(element) } - Self::UpdateSubjectTemplate(element) => { + Self::UpdateDKIMRegistry(element) => { ::ethers::core::abi::AbiEncode::encode(element) } Self::UpdateVerifier(element) => { @@ -2706,18 +2704,19 @@ pub mod email_auth { } Self::AccountSalt(element) => ::core::fmt::Display::fmt(element, f), Self::AuthEmail(element) => ::core::fmt::Display::fmt(element, f), + Self::CommandTemplates(element) => ::core::fmt::Display::fmt(element, f), Self::Controller(element) => ::core::fmt::Display::fmt(element, f), - Self::DeleteSubjectTemplate(element) => { + Self::DeleteCommandTemplate(element) => { ::core::fmt::Display::fmt(element, f) } Self::DkimRegistryAddr(element) => ::core::fmt::Display::fmt(element, f), - Self::GetSubjectTemplate(element) => { + Self::GetCommandTemplate(element) => { ::core::fmt::Display::fmt(element, f) } Self::InitDKIMRegistry(element) => ::core::fmt::Display::fmt(element, f), Self::InitVerifier(element) => ::core::fmt::Display::fmt(element, f), Self::Initialize(element) => ::core::fmt::Display::fmt(element, f), - Self::InsertSubjectTemplate(element) => { + Self::InsertCommandTemplate(element) => { ::core::fmt::Display::fmt(element, f) } Self::LastTimestamp(element) => ::core::fmt::Display::fmt(element, f), @@ -2727,15 +2726,14 @@ pub mod email_auth { Self::SetTimestampCheckEnabled(element) => { ::core::fmt::Display::fmt(element, f) } - Self::SubjectTemplates(element) => ::core::fmt::Display::fmt(element, f), Self::TimestampCheckEnabled(element) => { ::core::fmt::Display::fmt(element, f) } Self::TransferOwnership(element) => ::core::fmt::Display::fmt(element, f), - Self::UpdateDKIMRegistry(element) => { + Self::UpdateCommandTemplate(element) => { ::core::fmt::Display::fmt(element, f) } - Self::UpdateSubjectTemplate(element) => { + Self::UpdateDKIMRegistry(element) => { ::core::fmt::Display::fmt(element, f) } Self::UpdateVerifier(element) => ::core::fmt::Display::fmt(element, f), @@ -2760,14 +2758,19 @@ pub mod email_auth { Self::AuthEmail(value) } } + impl ::core::convert::From for EmailAuthCalls { + fn from(value: CommandTemplatesCall) -> Self { + Self::CommandTemplates(value) + } + } impl ::core::convert::From for EmailAuthCalls { fn from(value: ControllerCall) -> Self { Self::Controller(value) } } - impl ::core::convert::From for EmailAuthCalls { - fn from(value: DeleteSubjectTemplateCall) -> Self { - Self::DeleteSubjectTemplate(value) + impl ::core::convert::From for EmailAuthCalls { + fn from(value: DeleteCommandTemplateCall) -> Self { + Self::DeleteCommandTemplate(value) } } impl ::core::convert::From for EmailAuthCalls { @@ -2775,9 +2778,9 @@ pub mod email_auth { Self::DkimRegistryAddr(value) } } - impl ::core::convert::From for EmailAuthCalls { - fn from(value: GetSubjectTemplateCall) -> Self { - Self::GetSubjectTemplate(value) + impl ::core::convert::From for EmailAuthCalls { + fn from(value: GetCommandTemplateCall) -> Self { + Self::GetCommandTemplate(value) } } impl ::core::convert::From for EmailAuthCalls { @@ -2795,9 +2798,9 @@ pub mod email_auth { Self::Initialize(value) } } - impl ::core::convert::From for EmailAuthCalls { - fn from(value: InsertSubjectTemplateCall) -> Self { - Self::InsertSubjectTemplate(value) + impl ::core::convert::From for EmailAuthCalls { + fn from(value: InsertCommandTemplateCall) -> Self { + Self::InsertCommandTemplate(value) } } impl ::core::convert::From for EmailAuthCalls { @@ -2825,11 +2828,6 @@ pub mod email_auth { Self::SetTimestampCheckEnabled(value) } } - impl ::core::convert::From for EmailAuthCalls { - fn from(value: SubjectTemplatesCall) -> Self { - Self::SubjectTemplates(value) - } - } impl ::core::convert::From for EmailAuthCalls { fn from(value: TimestampCheckEnabledCall) -> Self { Self::TimestampCheckEnabled(value) @@ -2840,16 +2838,16 @@ pub mod email_auth { Self::TransferOwnership(value) } } + impl ::core::convert::From for EmailAuthCalls { + fn from(value: UpdateCommandTemplateCall) -> Self { + Self::UpdateCommandTemplate(value) + } + } impl ::core::convert::From for EmailAuthCalls { fn from(value: UpdateDKIMRegistryCall) -> Self { Self::UpdateDKIMRegistry(value) } } - impl ::core::convert::From for EmailAuthCalls { - fn from(value: UpdateSubjectTemplateCall) -> Self { - Self::UpdateSubjectTemplate(value) - } - } impl ::core::convert::From for EmailAuthCalls { fn from(value: UpdateVerifierCall) -> Self { Self::UpdateVerifier(value) @@ -2894,7 +2892,7 @@ pub mod email_auth { Hash )] pub struct AccountSaltReturn(pub [u8; 32]); - ///Container type for all return fields from the `controller` function with signature `controller()` and selector `0xf77c4791` + ///Container type for all return fields from the `commandTemplates` function with signature `commandTemplates(uint256,uint256)` and selector `0x091c1650` #[derive( Clone, ::ethers::contract::EthAbiType, @@ -2905,8 +2903,8 @@ pub mod email_auth { Eq, Hash )] - pub struct ControllerReturn(pub ::ethers::core::types::Address); - ///Container type for all return fields from the `dkimRegistryAddr` function with signature `dkimRegistryAddr()` and selector `0x1bc01b83` + pub struct CommandTemplatesReturn(pub ::std::string::String); + ///Container type for all return fields from the `controller` function with signature `controller()` and selector `0xf77c4791` #[derive( Clone, ::ethers::contract::EthAbiType, @@ -2917,8 +2915,8 @@ pub mod email_auth { Eq, Hash )] - pub struct DkimRegistryAddrReturn(pub ::ethers::core::types::Address); - ///Container type for all return fields from the `getSubjectTemplate` function with signature `getSubjectTemplate(uint256)` and selector `0x1e05a028` + pub struct ControllerReturn(pub ::ethers::core::types::Address); + ///Container type for all return fields from the `dkimRegistryAddr` function with signature `dkimRegistryAddr()` and selector `0x1bc01b83` #[derive( Clone, ::ethers::contract::EthAbiType, @@ -2929,8 +2927,8 @@ pub mod email_auth { Eq, Hash )] - pub struct GetSubjectTemplateReturn(pub ::std::vec::Vec<::std::string::String>); - ///Container type for all return fields from the `lastTimestamp` function with signature `lastTimestamp()` and selector `0x19d8ac61` + pub struct DkimRegistryAddrReturn(pub ::ethers::core::types::Address); + ///Container type for all return fields from the `getCommandTemplate` function with signature `getCommandTemplate(uint256)` and selector `0x95e33c08` #[derive( Clone, ::ethers::contract::EthAbiType, @@ -2941,8 +2939,8 @@ pub mod email_auth { Eq, Hash )] - pub struct LastTimestampReturn(pub ::ethers::core::types::U256); - ///Container type for all return fields from the `owner` function with signature `owner()` and selector `0x8da5cb5b` + pub struct GetCommandTemplateReturn(pub ::std::vec::Vec<::std::string::String>); + ///Container type for all return fields from the `lastTimestamp` function with signature `lastTimestamp()` and selector `0x19d8ac61` #[derive( Clone, ::ethers::contract::EthAbiType, @@ -2953,8 +2951,8 @@ pub mod email_auth { Eq, Hash )] - pub struct OwnerReturn(pub ::ethers::core::types::Address); - ///Container type for all return fields from the `proxiableUUID` function with signature `proxiableUUID()` and selector `0x52d1902d` + pub struct LastTimestampReturn(pub ::ethers::core::types::U256); + ///Container type for all return fields from the `owner` function with signature `owner()` and selector `0x8da5cb5b` #[derive( Clone, ::ethers::contract::EthAbiType, @@ -2965,8 +2963,8 @@ pub mod email_auth { Eq, Hash )] - pub struct ProxiableUUIDReturn(pub [u8; 32]); - ///Container type for all return fields from the `subjectTemplates` function with signature `subjectTemplates(uint256,uint256)` and selector `0x4bd07760` + pub struct OwnerReturn(pub ::ethers::core::types::Address); + ///Container type for all return fields from the `proxiableUUID` function with signature `proxiableUUID()` and selector `0x52d1902d` #[derive( Clone, ::ethers::contract::EthAbiType, @@ -2977,7 +2975,7 @@ pub mod email_auth { Eq, Hash )] - pub struct SubjectTemplatesReturn(pub ::std::string::String); + pub struct ProxiableUUIDReturn(pub [u8; 32]); ///Container type for all return fields from the `timestampCheckEnabled` function with signature `timestampCheckEnabled()` and selector `0x3e56f529` #[derive( Clone, @@ -3027,8 +3025,8 @@ pub mod email_auth { )] pub struct EmailAuthMsg { pub template_id: ::ethers::core::types::U256, - pub subject_params: ::std::vec::Vec<::ethers::core::types::Bytes>, - pub skiped_subject_prefix: ::ethers::core::types::U256, + pub command_params: ::std::vec::Vec<::ethers::core::types::Bytes>, + pub skipped_command_prefix: ::ethers::core::types::U256, pub proof: EmailProof, } ///`EmailProof(string,bytes32,uint256,string,bytes32,bytes32,bool,bytes)` @@ -3046,7 +3044,7 @@ pub mod email_auth { pub domain_name: ::std::string::String, pub public_key_hash: [u8; 32], pub timestamp: ::ethers::core::types::U256, - pub masked_subject: ::std::string::String, + pub masked_command: ::std::string::String, pub email_nullifier: [u8; 32], pub account_salt: [u8; 32], pub is_code_exist: bool, diff --git a/packages/relayer/src/abis/mod.rs b/packages/relayer/src/abis/mod.rs index c9a06ccb..b37f68da 100644 --- a/packages/relayer/src/abis/mod.rs +++ b/packages/relayer/src/abis/mod.rs @@ -1,7 +1,12 @@ -pub mod ecdsa_owned_dkim_registry; +#![allow(clippy::all)] + +#[cfg_attr(rustfmt, rustfmt::skip)] pub mod email_account_recovery; +#[cfg_attr(rustfmt, rustfmt::skip)] pub mod email_auth; +#[cfg_attr(rustfmt, rustfmt::skip)] +pub mod user_overridable_dkim_registry; -pub use ecdsa_owned_dkim_registry::*; -pub use email_account_recovery::*; +pub use email_account_recovery::EmailAccountRecovery; pub use email_auth::*; +pub use user_overridable_dkim_registry::UserOverridableDKIMRegistry; diff --git a/packages/relayer/src/abis/user_overridable_dkim_registry.rs b/packages/relayer/src/abis/user_overridable_dkim_registry.rs new file mode 100644 index 00000000..9320b21d --- /dev/null +++ b/packages/relayer/src/abis/user_overridable_dkim_registry.rs @@ -0,0 +1,3421 @@ +pub use user_overridable_dkim_registry::*; +/// This module was auto-generated with ethers-rs Abigen. +/// More information at: +#[allow( + clippy::enum_variant_names, + clippy::too_many_arguments, + clippy::upper_case_acronyms, + clippy::type_complexity, + dead_code, + non_camel_case_types, +)] +pub mod user_overridable_dkim_registry { + #[allow(deprecated)] + fn __abi() -> ::ethers::core::abi::Abi { + ::ethers::core::abi::ethabi::Contract { + constructor: ::core::option::Option::Some(::ethers::core::abi::ethabi::Constructor { + inputs: ::std::vec![], + }), + functions: ::core::convert::From::from([ + ( + ::std::borrow::ToOwned::to_owned("REACTIVATE_PREFIX"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("REACTIVATE_PREFIX"), + inputs: ::std::vec![], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::String, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("string"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("REVOKE_PREFIX"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("REVOKE_PREFIX"), + inputs: ::std::vec![], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::String, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("string"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("SET_PREFIX"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("SET_PREFIX"), + inputs: ::std::vec![], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::String, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("string"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("UPGRADE_INTERFACE_VERSION"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned( + "UPGRADE_INTERFACE_VERSION", + ), + inputs: ::std::vec![], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::String, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("string"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("changeMainAuthorizer"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned( + "changeMainAuthorizer", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("newMainAuthorizer"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ], + outputs: ::std::vec![], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("computeSignedMsg"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("computeSignedMsg"), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("prefix"), + kind: ::ethers::core::abi::ethabi::ParamType::String, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("string"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("domainName"), + kind: ::ethers::core::abi::ethabi::ParamType::String, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("string"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("publicKeyHash"), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes32"), + ), + }, + ], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::String, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("string"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::Pure, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("dkimPublicKeyHashes"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned( + "dkimPublicKeyHashes", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::String, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("string"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes32"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Bool, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bool"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("enabledTimeOfDKIMPublicKeyHash"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned( + "enabledTimeOfDKIMPublicKeyHash", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes32"), + ), + }, + ], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Uint( + 256usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("uint256"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("initialize"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("initialize"), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("_initialOwner"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("_mainAuthorizer"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned( + "_setTimestampDelay", + ), + kind: ::ethers::core::abi::ethabi::ParamType::Uint( + 256usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("uint256"), + ), + }, + ], + outputs: ::std::vec![], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("isDKIMPublicKeyHashValid"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned( + "isDKIMPublicKeyHashValid", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("domainName"), + kind: ::ethers::core::abi::ethabi::ParamType::String, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("string"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("publicKeyHash"), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes32"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("authorizer"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Bool, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bool"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + }, + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned( + "isDKIMPublicKeyHashValid", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("domainName"), + kind: ::ethers::core::abi::ethabi::ParamType::String, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("string"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("publicKeyHash"), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes32"), + ), + }, + ], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Bool, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bool"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("mainAuthorizer"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("mainAuthorizer"), + inputs: ::std::vec![], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("owner"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("owner"), + inputs: ::std::vec![], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("proxiableUUID"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("proxiableUUID"), + inputs: ::std::vec![], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes32"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("reactivateDKIMPublicKeyHash"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned( + "reactivateDKIMPublicKeyHash", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("domainName"), + kind: ::ethers::core::abi::ethabi::ParamType::String, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("string"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("publicKeyHash"), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes32"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("authorizer"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("signature"), + kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes"), + ), + }, + ], + outputs: ::std::vec![], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("reactivatedDKIMPublicKeyHashes"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned( + "reactivatedDKIMPublicKeyHashes", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes32"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Bool, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bool"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("renounceOwnership"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("renounceOwnership"), + inputs: ::std::vec![], + outputs: ::std::vec![], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("revokeDKIMPublicKeyHash"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned( + "revokeDKIMPublicKeyHash", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("domainName"), + kind: ::ethers::core::abi::ethabi::ParamType::String, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("string"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("publicKeyHash"), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes32"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("authorizer"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("signature"), + kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes"), + ), + }, + ], + outputs: ::std::vec![], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("revokedDKIMPublicKeyHashes"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned( + "revokedDKIMPublicKeyHashes", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes32"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Bool, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bool"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("setDKIMPublicKeyHash"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned( + "setDKIMPublicKeyHash", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("domainName"), + kind: ::ethers::core::abi::ethabi::ParamType::String, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("string"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("publicKeyHash"), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes32"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("authorizer"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("signature"), + kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes"), + ), + }, + ], + outputs: ::std::vec![], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("setDKIMPublicKeyHashes"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned( + "setDKIMPublicKeyHashes", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("domainNames"), + kind: ::ethers::core::abi::ethabi::ParamType::Array( + ::std::boxed::Box::new( + ::ethers::core::abi::ethabi::ParamType::String, + ), + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("string[]"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("publicKeyHashes"), + kind: ::ethers::core::abi::ethabi::ParamType::Array( + ::std::boxed::Box::new( + ::ethers::core::abi::ethabi::ParamType::FixedBytes(32usize), + ), + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes32[]"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("authorizers"), + kind: ::ethers::core::abi::ethabi::ParamType::Array( + ::std::boxed::Box::new( + ::ethers::core::abi::ethabi::ParamType::Address, + ), + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address[]"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("signatures"), + kind: ::ethers::core::abi::ethabi::ParamType::Array( + ::std::boxed::Box::new( + ::ethers::core::abi::ethabi::ParamType::Bytes, + ), + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes[]"), + ), + }, + ], + outputs: ::std::vec![], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("setTimestampDelay"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("setTimestampDelay"), + inputs: ::std::vec![], + outputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Uint( + 256usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("uint256"), + ), + }, + ], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("transferOwnership"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("transferOwnership"), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("newOwner"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ], + outputs: ::std::vec![], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::NonPayable, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("upgradeToAndCall"), + ::std::vec![ + ::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("upgradeToAndCall"), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("newImplementation"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("data"), + kind: ::ethers::core::abi::ethabi::ParamType::Bytes, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes"), + ), + }, + ], + outputs: ::std::vec![], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::Payable, + }, + ], + ), + ]), + events: ::core::convert::From::from([ + ( + ::std::borrow::ToOwned::to_owned("DKIMPublicKeyHashReactivated"), + ::std::vec![ + ::ethers::core::abi::ethabi::Event { + name: ::std::borrow::ToOwned::to_owned( + "DKIMPublicKeyHashReactivated", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("publicKeyHash"), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + indexed: true, + }, + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("authorizer"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + indexed: true, + }, + ], + anonymous: false, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("DKIMPublicKeyHashRegistered"), + ::std::vec![ + ::ethers::core::abi::ethabi::Event { + name: ::std::borrow::ToOwned::to_owned( + "DKIMPublicKeyHashRegistered", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("domainName"), + kind: ::ethers::core::abi::ethabi::ParamType::String, + indexed: true, + }, + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("publicKeyHash"), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + indexed: true, + }, + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("authorizer"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + indexed: true, + }, + ], + anonymous: false, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("DKIMPublicKeyHashRevoked"), + ::std::vec![ + ::ethers::core::abi::ethabi::Event { + name: ::std::borrow::ToOwned::to_owned( + "DKIMPublicKeyHashRevoked", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("publicKeyHash"), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + indexed: true, + }, + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("authorizer"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + indexed: true, + }, + ], + anonymous: false, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("Initialized"), + ::std::vec![ + ::ethers::core::abi::ethabi::Event { + name: ::std::borrow::ToOwned::to_owned("Initialized"), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("version"), + kind: ::ethers::core::abi::ethabi::ParamType::Uint(64usize), + indexed: false, + }, + ], + anonymous: false, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("MainAuthorizerChanged"), + ::std::vec![ + ::ethers::core::abi::ethabi::Event { + name: ::std::borrow::ToOwned::to_owned( + "MainAuthorizerChanged", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("newMainAuthorizer"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + indexed: true, + }, + ], + anonymous: false, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("OwnershipTransferred"), + ::std::vec![ + ::ethers::core::abi::ethabi::Event { + name: ::std::borrow::ToOwned::to_owned( + "OwnershipTransferred", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("previousOwner"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + indexed: true, + }, + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("newOwner"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + indexed: true, + }, + ], + anonymous: false, + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("Upgraded"), + ::std::vec![ + ::ethers::core::abi::ethabi::Event { + name: ::std::borrow::ToOwned::to_owned("Upgraded"), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::EventParam { + name: ::std::borrow::ToOwned::to_owned("implementation"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + indexed: true, + }, + ], + anonymous: false, + }, + ], + ), + ]), + errors: ::core::convert::From::from([ + ( + ::std::borrow::ToOwned::to_owned("AddressEmptyCode"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned("AddressEmptyCode"), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("target"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("ECDSAInvalidSignature"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned( + "ECDSAInvalidSignature", + ), + inputs: ::std::vec![], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("ECDSAInvalidSignatureLength"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned( + "ECDSAInvalidSignatureLength", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("length"), + kind: ::ethers::core::abi::ethabi::ParamType::Uint( + 256usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("uint256"), + ), + }, + ], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("ECDSAInvalidSignatureS"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned( + "ECDSAInvalidSignatureS", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("s"), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes32"), + ), + }, + ], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("ERC1967InvalidImplementation"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned( + "ERC1967InvalidImplementation", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("implementation"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("ERC1967NonPayable"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned("ERC1967NonPayable"), + inputs: ::std::vec![], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("FailedCall"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned("FailedCall"), + inputs: ::std::vec![], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("InvalidInitialization"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned( + "InvalidInitialization", + ), + inputs: ::std::vec![], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("NotInitializing"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned("NotInitializing"), + inputs: ::std::vec![], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("OwnableInvalidOwner"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned( + "OwnableInvalidOwner", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("owner"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("OwnableUnauthorizedAccount"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned( + "OwnableUnauthorizedAccount", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("account"), + kind: ::ethers::core::abi::ethabi::ParamType::Address, + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("address"), + ), + }, + ], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("StringsInsufficientHexLength"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned( + "StringsInsufficientHexLength", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("value"), + kind: ::ethers::core::abi::ethabi::ParamType::Uint( + 256usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("uint256"), + ), + }, + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("length"), + kind: ::ethers::core::abi::ethabi::ParamType::Uint( + 256usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("uint256"), + ), + }, + ], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("UUPSUnauthorizedCallContext"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned( + "UUPSUnauthorizedCallContext", + ), + inputs: ::std::vec![], + }, + ], + ), + ( + ::std::borrow::ToOwned::to_owned("UUPSUnsupportedProxiableUUID"), + ::std::vec![ + ::ethers::core::abi::ethabi::AbiError { + name: ::std::borrow::ToOwned::to_owned( + "UUPSUnsupportedProxiableUUID", + ), + inputs: ::std::vec![ + ::ethers::core::abi::ethabi::Param { + name: ::std::borrow::ToOwned::to_owned("slot"), + kind: ::ethers::core::abi::ethabi::ParamType::FixedBytes( + 32usize, + ), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("bytes32"), + ), + }, + ], + }, + ], + ), + ]), + receive: false, + fallback: false, + } + } + ///The parsed JSON ABI of the contract. + pub static USEROVERRIDABLEDKIMREGISTRY_ABI: ::ethers::contract::Lazy< + ::ethers::core::abi::Abi, + > = ::ethers::contract::Lazy::new(__abi); + #[rustfmt::skip] + const __BYTECODE: &[u8] = b"`\xA0`@R0`\x80R4\x80\x15`\x13W`\0\x80\xFD[P`\x80Qa8ra\0=`\09`\0\x81\x81a\"\"\x01R\x81\x81a\"K\x01Ra$l\x01Ra8r`\0\xF3\xFE`\x80`@R`\x046\x10a\x01\x8BW`\x005`\xE0\x1C\x80c}F6H\x11a\0\xD6W\x80c\xAD<\xB1\xCC\x11a\0\x7FW\x80c\xE7\xA7\x97z\x11a\0YW\x80c\xE7\xA7\x97z\x14a\x05\x92W\x80c\xF0\xBF\xB1\x97\x14a\x05\xB2W\x80c\xF2\xFD\xE3\x8B\x14a\x05\xEDW`\0\x80\xFD[\x80c\xAD<\xB1\xCC\x14a\x04\xAFW\x80c\xD5\x07\xC3 \x14a\x04\xF8W\x80c\xE3\x08\xDE\x0C\x14a\x05AW`\0\x80\xFD[\x80c\x81.\x12\xCE\x11a\0\xB0W\x80c\x81.\x12\xCE\x14a\x04/W\x80c\x82\xBF\xF8\xCD\x14a\x04EW\x80c\x8D\xA5\xCB[\x14a\x04eW`\0\x80\xFD[\x80c}F6H\x14a\x03\x90W\x80c\x7F\x8E)\xBA\x14a\x03\xE2W\x80c\x7F\xF1\x03\xDA\x14a\x04\x0FW`\0\x80\xFD[\x80cL\x93\x06\x07\x11a\x018W\x80cWI\0\xDD\x11a\x01\x12W\x80cWI\0\xDD\x14a\x03 W\x80caJD\x85\x14a\x03[W\x80cqP\x18\xA6\x14a\x03{W`\0\x80\xFD[\x80cL\x93\x06\x07\x14a\x02\xCAW\x80cO\x1E\xF2\x86\x14a\x02\xEAW\x80cR\xD1\x90-\x14a\x02\xFDW`\0\x80\xFD[\x80c\"Z\x08\xD4\x11a\x01iW\x80c\"Z\x08\xD4\x14a\x02AW\x80c2\xE1\xE1\x94\x14a\x02\x8AW\x80cK\xCB\xBE\x96\x14a\x02\xAAW`\0\x80\xFD[\x80c\x07\xF1\xEA\xF5\x14a\x01\x90W\x80c\x0BU\xB3|\x14a\x01\xEFW\x80c\x17\x94\xBB<\x14a\x02\x1FW[`\0\x80\xFD[4\x80\x15a\x01\x9CW`\0\x80\xFD[Pa\x01\xD9`@Q\x80`@\x01`@R\x80`\x04\x81R` \x01\x7FSET:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81RP\x81V[`@Qa\x01\xE6\x91\x90a.\xF4V[`@Q\x80\x91\x03\x90\xF3[4\x80\x15a\x01\xFBW`\0\x80\xFD[Pa\x02\x0Fa\x02\n6`\x04a0#\xA9f.\xFC\x9C\"\x9Cj\0\x80Th\x01\0\0\0\0\0\0\0\0\x81\x04`\xFF\x16\x15\x90g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16`\0\x81\x15\x80\x15a\x08hWP\x82[\x90P`\0\x82g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16`\x01\x14\x80\x15a\x08\x85WP0;\x15[\x90P\x81\x15\x80\x15a\x08\x93WP\x80\x15[\x15a\x08\xCAW`@Q\x7F\xF9.\xE8\xA9\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x84T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x16`\x01\x17\x85U\x83\x15a\t+W\x84T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16h\x01\0\0\0\0\0\0\0\0\x17\x85U[a\t4\x88a \x82V[`\0\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x89\x16\x17\x90U`\x01\x86\x90U\x83\x15a\t\xDAW\x84T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x85U`@Q`\x01\x81R\x7F\xC7\xF5\x05\xB2\xF3q\xAE!u\xEEI\x13\xF4I\x9E\x1F&3\xA7\xB5\x93c!\xEE\xD1\xCD\xAE\xB6\x11Q\x81\xD2\x90` \x01`@Q\x80\x91\x03\x90\xA1[PPPPPPPPV[`\0\x84Q\x11a\n5W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1A`$\x82\x01R\x7Fdomain name cannot be zero\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[\x82a\n\x82W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1E`$\x82\x01R\x7Fpublic key hash cannot be zero\0\0`D\x82\x01R`d\x01a\x06[V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x16a\x0B\x0BW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`!`$\x82\x01R\x7Fauthorizer address cannot be zer`D\x82\x01R\x7Fo\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[`\0Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x81\x16\x90\x83\x16\x03a\x0B\x9CW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`4`$\x82\x01R\x7FmainAuthorizer cannot reactivate`D\x82\x01R\x7F the public key hash\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[`\0\x83\x81R`\x04` \x90\x81R`@\x80\x83 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x86\x16\x84R\x90\x91R\x90 T`\xFF\x16\x15a\x0CBW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`&`$\x82\x01R\x7Fpublic key hash is already react`D\x82\x01R\x7Fivated\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[a\x0CL\x83\x83a\x1E\x8FV[`\x01\x14a\x0C\x9BW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1C`$\x82\x01R\x7Frevoke threshold must be one\0\0\0\0`D\x82\x01R`d\x01a\x06[V[`\x02a\x0C\xA8\x85\x85\x85a\x1F\x82V[\x10\x15a\r\x1CW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`%`$\x82\x01R\x7Fset threshold must be larger tha`D\x82\x01R\x7Fn two\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[3s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16\x14a\x0FCW`\0a\r{`@Q\x80`@\x01`@R\x80`\x0B\x81R` \x01\x7FREACTIVATE:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81RP\x86\x86a\x0F\xCBV[\x90P`\0a\r\x88\x82a \x93V[\x90Ps\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x16;\x15a\x0E\xB5W`@Q\x7F\x16&\xBA~\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x85\x16\x90c\x16&\xBA~\x90a\r\xFB\x90\x84\x90\x87\x90`\x04\x01a5tV[` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x0E\x18W=`\0\x80>=`\0\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x0E<\x91\x90a5\x8DV[{\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16c\x16&\xBA~`\xE0\x1B\x14a\x0E\xB0W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x19`$\x82\x01R\x7Finvalid eip1271 signature\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[a\x0F@V[`\0a\x0E\xC1\x82\x85a \xCEV[\x90P\x84s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x81s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x14a\x0F>W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x17`$\x82\x01R\x7Finvalid ecdsa signature\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[P[PP[`\0\x83\x81R`\x04` \x90\x81R`@\x80\x83 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x86\x16\x80\x85R\x92R\x80\x83 \x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\x16`\x01\x17\x90UQ\x90\x91\x85\x91\x7F2\x89\x9A\x1E\xA4\xD8\xE4\x91|k=l\x1Ci\xFDLp\x949C\xB0'\xFE\x9D\x83+ R\xE7\xEF\xF8\xD6\x91\x90\xA3PPPPV[``\x83\x83a\x0F\xD8\x84a \xF8V[`@Q` \x01a\x0F\xEA\x93\x92\x91\x90a5\xCFV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P\x93\x92PPPV[a\x10\na!|V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16a\x10\x93W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`(`$\x82\x01R\x7FnewMainAuthorizer address cannot`D\x82\x01R\x7F be zero\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[`\0Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x81\x16\x90\x82\x16\x03a\x11JW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`J`$\x82\x01R\x7FnewMainAuthorizer address cannot`D\x82\x01R\x7F be the same as the current main`d\x82\x01R\x7FAuthorizer\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\x84\x82\x01R`\xA4\x01a\x06[V[`\0\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16\x90\x81\x17\x82U`@Q\x90\x91\x7F;\xB1\x96\x11\xD1\x15f1\xA8\\Y\xDD\xFEvhT\x1A/\0\xE6\xBA+~q\xCB\x0C`\xEC\xE0\xD5\xE5[\x91\xA2PV[a\x11\xBFa\"\nV[a\x11\xC8\x82a#\x0EV[a\x11\xD2\x82\x82a#\x16V[PPV[`\0a\x11\xE0a$TV[P\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\x90V[`\0\x84Q\x11a\x12VW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1A`$\x82\x01R\x7Fdomain name cannot be zero\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[\x82a\x12\xA3W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1E`$\x82\x01R\x7Fpublic key hash cannot be zero\0\0`D\x82\x01R`d\x01a\x06[V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x16a\x13,W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`!`$\x82\x01R\x7Fauthorizer address cannot be zer`D\x82\x01R\x7Fo\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[`\x02\x84`@Qa\x13<\x91\x90a6\x90V[\x90\x81R`@\x80Q` \x92\x81\x90\x03\x83\x01\x90 `\0\x86\x81R\x90\x83R\x81\x81 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x86\x16\x82R\x90\x92R\x90 T`\xFF\x16\x15a\x13\xC7W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1E`$\x82\x01R\x7Fpublic key hash is already set\0\0`D\x82\x01R`d\x01a\x06[V[`\0\x83\x81R`\x03` \x90\x81R`@\x80\x83 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x86\x16\x84R\x90\x91R\x90 T`\xFF\x16\x15a\x14mW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\"`$\x82\x01R\x7Fpublic key hash is already revok`D\x82\x01R\x7Fed\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[3s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16\x14a\x16\x94W`\0a\x14\xCC`@Q\x80`@\x01`@R\x80`\x04\x81R` \x01\x7FSET:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81RP\x86\x86a\x0F\xCBV[\x90P`\0a\x14\xD9\x82a \x93V[\x90Ps\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x16;\x15a\x16\x06W`@Q\x7F\x16&\xBA~\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x85\x16\x90c\x16&\xBA~\x90a\x15L\x90\x84\x90\x87\x90`\x04\x01a5tV[` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x15iW=`\0\x80>=`\0\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x15\x8D\x91\x90a5\x8DV[{\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16c\x16&\xBA~`\xE0\x1B\x14a\x16\x01W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x19`$\x82\x01R\x7Finvalid eip1271 signature\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[a\x16\x91V[`\0a\x16\x12\x82\x85a \xCEV[\x90P\x84s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x81s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x14a\x16\x8FW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x17`$\x82\x01R\x7Finvalid ecdsa signature\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[P[PP[`\x01`\x02\x85`@Qa\x16\xA6\x91\x90a6\x90V[\x90\x81R`@\x80Q` \x92\x81\x90\x03\x83\x01\x90 `\0\x87\x81R\x90\x83R\x81\x81 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x87\x81\x16\x80\x84R\x91\x90\x94R\x91\x81 \x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\x16\x94\x15\x15\x94\x90\x94\x17\x90\x93U\x91T\x16\x90\x03a\x178W`\x01Ta\x17(\x90Ba6\xDBV[`\0\x84\x81R`\x05` R`@\x90 U[\x81s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x83\x85`@Qa\x17^\x91\x90a6\x90V[`@Q\x90\x81\x90\x03\x81 \x90\x7F}a~\xDC\x9D\n\xDE/\xB7hC\xEF_sr\xBD'0\xE9\0\xFA\x12\xE6t\xBE\xCA\xA8\xAD\x01\xEA\xB6\xCB\x90`\0\x90\xA4PPPPV[a\x17\x9Ca!|V[a\x17\xA6`\0a$\xC3V[V[\x82Q\x84Q\x14a\x17\xF9W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1E`$\x82\x01R\x7Finvalid publicKeyHashes length\0\0`D\x82\x01R`d\x01a\x06[V[\x81Q\x84Q\x14a\x18JW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1A`$\x82\x01R\x7Finvalid authorizers length\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[\x80Q\x84Q\x14a\x18\x9BW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x19`$\x82\x01R\x7Finvalid signatures length\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[`\0[\x84Q\x81\x10\x15a\x19\x1FWa\x19\x17\x85\x82\x81Q\x81\x10a\x18\xBCWa\x18\xBCa6\xEEV[` \x02` \x01\x01Q\x85\x83\x81Q\x81\x10a\x18\xD6Wa\x18\xD6a6\xEEV[` \x02` \x01\x01Q\x85\x84\x81Q\x81\x10a\x18\xF0Wa\x18\xF0a6\xEEV[` \x02` \x01\x01Q\x85\x85\x81Q\x81\x10a\x19\nWa\x19\na6\xEEV[` \x02` \x01\x01Qa\x12\x05V[`\x01\x01a\x18\x9EV[PPPPPV[`\0\x84Q\x11a\x19wW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1A`$\x82\x01R\x7Fdomain name cannot be zero\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[\x82a\x19\xC4W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1E`$\x82\x01R\x7Fpublic key hash cannot be zero\0\0`D\x82\x01R`d\x01a\x06[V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x16a\x1AMW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`!`$\x82\x01R\x7Fauthorizer address cannot be zer`D\x82\x01R\x7Fo\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[`\0\x83\x81R`\x03` \x90\x81R`@\x80\x83 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x86\x16\x84R\x90\x91R\x90 T`\xFF\x16\x15a\x1A\xF3W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\"`$\x82\x01R\x7Fpublic key hash is already revok`D\x82\x01R\x7Fed\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[3s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16\x14a\x1D\x1AW`\0a\x1BR`@Q\x80`@\x01`@R\x80`\x07\x81R` \x01\x7FREVOKE:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81RP\x86\x86a\x0F\xCBV[\x90P`\0a\x1B_\x82a \x93V[\x90Ps\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x16;\x15a\x1C\x8CW`@Q\x7F\x16&\xBA~\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x85\x16\x90c\x16&\xBA~\x90a\x1B\xD2\x90\x84\x90\x87\x90`\x04\x01a5tV[` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x1B\xEFW=`\0\x80>=`\0\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x1C\x13\x91\x90a5\x8DV[{\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16c\x16&\xBA~`\xE0\x1B\x14a\x1C\x87W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x19`$\x82\x01R\x7Finvalid eip1271 signature\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[a\x1D\x17V[`\0a\x1C\x98\x82\x85a \xCEV[\x90P\x84s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x81s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x14a\x1D\x15W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x17`$\x82\x01R\x7Finvalid ecdsa signature\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[P[PP[`\0\x83\x81R`\x03` \x90\x81R`@\x80\x83 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x86\x16\x80\x85R\x92R\x80\x83 \x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\x16`\x01\x17\x90UQ\x90\x91\x85\x91\x7F5P6\xB8\xAD\x96>\x18^\t\xF0t\xE8VU\x96H:\0\x12\xCB\xE6 \xF5\x07\xC0\xF3IP\xA2\xF0\xB3\x91\x90\xA3PPPPV[`\0\x803s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16c\x8D\xA5\xCB[`@Q\x81c\xFF\xFF\xFF\xFF\x16`\xE0\x1B\x81R`\x04\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x1D\xF0W=`\0\x80>=`\0\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x1E\x14\x91\x90a7\x1DV[\x90Pa\x1E!\x84\x84\x83a\x06\rV[\x91PP[\x92\x91PPV[a\x1E3a!|V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16a\x1E\x83W`@Q\x7F\x1EO\xBD\xF7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\0`\x04\x82\x01R`$\x01a\x06[V[a\x1E\x8C\x81a$\xC3V[PV[`\0\x82\x81R`\x03` \x90\x81R`@\x80\x83 \x83Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x84R\x90\x91R\x81 T\x81\x90`\xFF\x16\x15\x15`\x01\x03a\x1E\xDCWa\x1E\xD9`\x01\x82a6\xDBV[\x90P[`\0\x84\x81R`\x03` \x90\x81R`@\x80\x83 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x87\x16\x84R\x90\x91R\x90 T`\xFF\x16\x15\x15`\x01\x03a\x1F&Wa\x1F#`\x02\x82a6\xDBV[\x90P[\x80`\x01\x14\x80\x15a\x1FjWP`\0\x84\x81R`\x04` \x90\x81R`@\x80\x83 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x87\x16\x84R\x90\x91R\x90 T`\xFF\x16\x15\x15`\x01\x14[\x15a\x08\x16Wa\x1Fz`\x01\x82a7:V[\x94\x93PPPPV[`\0\x80`\0\x90P`\x02\x85`@Qa\x1F\x99\x91\x90a6\x90V[\x90\x81R`@\x80Q` \x92\x81\x90\x03\x83\x01\x90 `\0\x87\x81R\x90\x83R\x81\x81 \x81Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x82R\x90\x92R\x90 T`\xFF\x16\x15\x15`\x01\x03a \x17W`\0\x84\x81R`\x05` R`@\x90 TB\x10\x15a \tWa \x02`\x01\x82a6\xDBV[\x90Pa \x17V[a \x14`\x02\x82a6\xDBV[\x90P[`\x02\x85`@Qa '\x91\x90a6\x90V[\x90\x81R`@\x80Q` \x92\x81\x90\x03\x83\x01\x90 `\0\x87\x81R\x90\x83R\x81\x81 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x87\x16\x82R\x90\x92R\x90 T`\xFF\x16\x15\x15`\x01\x03a\x1FzWa y`\x02\x82a6\xDBV[\x95\x94PPPPPV[a \x8Aa%YV[a\x1E\x8C\x81a%\xC0V[`\0a \x9F\x82Qa%\xC8V[\x82`@Q` \x01a \xB1\x92\x91\x90a7MV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x80Q\x90` \x01 \x90P\x91\x90PV[`\0\x80`\0\x80a \xDE\x86\x86a&\x86V[\x92P\x92P\x92Pa \xEE\x82\x82a&\xD3V[P\x90\x94\x93PPPPV[``a\x1E%\x82a!t\x84`\xFF`\x80o\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x11\x90\x81\x02\x92\x90\x92\x1C`@g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x11\x90\x81\x02\x91\x90\x91\x1C` c\xFF\xFF\xFF\xFF\x82\x11\x90\x81\x02\x91\x90\x91\x1Ca\xFF\xFF\x81\x11`\x10\x81\x81\x02\x92\x90\x92\x1C\x94\x90\x94\x11`\x02\x90\x94\x02`\x04\x90\x92\x02`\x08\x90\x93\x02\x94\x02\x93\x90\x93\x01\x01\x91\x90\x91\x01\x01\x90V[`\x01\x01a'\xD7V[3a!\xBB\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x90V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x14a\x17\xA6W`@Q\x7F\x11\x8C\xDA\xA7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R3`\x04\x82\x01R`$\x01a\x06[V[0s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14\x80a\"\xD7WP\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16a\"\xBE\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBCTs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x90V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x14\x15[\x15a\x17\xA6W`@Q\x7F\xE0|\x8D\xBA\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x1E\x8Ca!|V[\x81s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16cR\xD1\x90-`@Q\x81c\xFF\xFF\xFF\xFF\x16`\xE0\x1B\x81R`\x04\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x92PPP\x80\x15a#\x9BWP`@\x80Q`\x1F=\x90\x81\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16\x82\x01\x90\x92Ra#\x98\x91\x81\x01\x90a7\xA8V[`\x01[a#\xE9W`@Q\x7FL\x9C\x8C\xE3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16`\x04\x82\x01R`$\x01a\x06[V[\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\x81\x14a$EW`@Q\x7F\xAA\x1DI\xA4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06[V[a$O\x83\x83a)\xF5V[PPPV[0s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14a\x17\xA6W`@Q\x7F\xE0|\x8D\xBA\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x81\x16\x91\x82\x17\x84U`@Q\x92\x16\x91\x82\x90\x7F\x8B\xE0\x07\x9CS\x16Y\x14\x13D\xCD\x1F\xD0\xA4\xF2\x84\x19I\x7F\x97\"\xA3\xDA\xAF\xE3\xB4\x18okdW\xE0\x90`\0\x90\xA3PPPV[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0Th\x01\0\0\0\0\0\0\0\0\x90\x04`\xFF\x16a\x17\xA6W`@Q\x7F\xD7\xE6\xBC\xF8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x1E3a%YV[```\0a%\xD5\x83a*XV[`\x01\x01\x90P`\0\x81g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a%\xF5Wa%\xF5a/\x07V[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a&\x1FW` \x82\x01\x81\x806\x837\x01\x90P[P\x90P\x81\x81\x01` \x01[\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01\x7F0123456789abcdef\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\n\x86\x06\x1A\x81S`\n\x85\x04\x94P\x84a&)WP\x93\x92PPPV[`\0\x80`\0\x83Q`A\x03a&\xC0W` \x84\x01Q`@\x85\x01Q``\x86\x01Q`\0\x1Aa&\xB2\x88\x82\x85\x85a+:V[\x95P\x95P\x95PPPPa&\xCCV[PP\x81Q`\0\x91P`\x02\x90[\x92P\x92P\x92V[`\0\x82`\x03\x81\x11\x15a&\xE7Wa&\xE7a7\xC1V[\x03a&\xF0WPPV[`\x01\x82`\x03\x81\x11\x15a'\x04Wa'\x04a7\xC1V[\x03a';W`@Q\x7F\xF6E\xEE\xDF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02\x82`\x03\x81\x11\x15a'OWa'Oa7\xC1V[\x03a'\x89W`@Q\x7F\xFC\xE6\x98\xF7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06[V[`\x03\x82`\x03\x81\x11\x15a'\x9DWa'\x9Da7\xC1V[\x03a\x11\xD2W`@Q\x7F\xD7\x8B\xCE\x0C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06[V[``\x82`\0a'\xE7\x84`\x02a7\xF0V[a'\xF2\x90`\x02a6\xDBV[g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a(\nWa(\na/\x07V[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a(4W` \x82\x01\x81\x806\x837\x01\x90P[P\x90P\x7F0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81`\0\x81Q\x81\x10a(kWa(ka6\xEEV[` \x01\x01\x90~\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16\x90\x81`\0\x1A\x90SP\x7Fx\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81`\x01\x81Q\x81\x10a(\xCEWa(\xCEa6\xEEV[` \x01\x01\x90~\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16\x90\x81`\0\x1A\x90SP`\0a)\n\x85`\x02a7\xF0V[a)\x15\x90`\x01a6\xDBV[\x90P[`\x01\x81\x11\x15a)\xB2W\x7F0123456789abcdef\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x83`\x0F\x16`\x10\x81\x10a)VWa)Va6\xEEV[\x1A`\xF8\x1B\x82\x82\x81Q\x81\x10a)lWa)la6\xEEV[` \x01\x01\x90~\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16\x90\x81`\0\x1A\x90SP`\x04\x92\x90\x92\x1C\x91a)\xAB\x81a8\x07V[\x90Pa)\x18V[P\x81\x15a\x1E!W`@Q\x7F\xE2.'\xEB\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x86\x90R`$\x81\x01\x85\x90R`D\x01a\x06[V[a)\xFE\x82a,4V[`@Qs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16\x90\x7F\xBC|\xD7Z \xEE'\xFD\x9A\xDE\xBA\xB3 A\xF7U!M\xBCk\xFF\xA9\x0C\xC0\"[9\xDA.\\-;\x90`\0\x90\xA2\x80Q\x15a*PWa$O\x82\x82a-\x03V[a\x11\xD2a-}V[`\0\x80z\x18O\x03\xE9?\xF9\xF4\xDA\xA7\x97\xEDn8\xEDd\xBFj\x1F\x01\0\0\0\0\0\0\0\0\x83\x10a*\xA1Wz\x18O\x03\xE9?\xF9\xF4\xDA\xA7\x97\xEDn8\xEDd\xBFj\x1F\x01\0\0\0\0\0\0\0\0\x83\x04\x92P`@\x01[m\x04\xEE-mA[\x85\xAC\xEF\x81\0\0\0\0\x83\x10a*\xCDWm\x04\xEE-mA[\x85\xAC\xEF\x81\0\0\0\0\x83\x04\x92P` \x01[f#\x86\xF2o\xC1\0\0\x83\x10a*\xEBWf#\x86\xF2o\xC1\0\0\x83\x04\x92P`\x10\x01[c\x05\xF5\xE1\0\x83\x10a+\x03Wc\x05\xF5\xE1\0\x83\x04\x92P`\x08\x01[a'\x10\x83\x10a+\x17Wa'\x10\x83\x04\x92P`\x04\x01[`d\x83\x10a+)W`d\x83\x04\x92P`\x02\x01[`\n\x83\x10a\x1E%W`\x01\x01\x92\x91PPV[`\0\x80\x80\x7F\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF]WnsW\xA4P\x1D\xDF\xE9/Fh\x1B \xA0\x84\x11\x15a+uWP`\0\x91P`\x03\x90P\x82a,*V[`@\x80Q`\0\x80\x82R` \x82\x01\x80\x84R\x8A\x90R`\xFF\x89\x16\x92\x82\x01\x92\x90\x92R``\x81\x01\x87\x90R`\x80\x81\x01\x86\x90R`\x01\x90`\xA0\x01` `@Q` \x81\x03\x90\x80\x84\x03\x90\x85Z\xFA\x15\x80\x15a+\xC9W=`\0\x80>=`\0\xFD[PP`@Q\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x01Q\x91PPs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16a, WP`\0\x92P`\x01\x91P\x82\x90Pa,*V[\x92P`\0\x91P\x81\x90P[\x94P\x94P\x94\x91PPV[\x80s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16;`\0\x03a,\x9DW`@Q\x7FL\x9C\x8C\xE3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x16`\x04\x82\x01R`$\x01a\x06[V[\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x92\x90\x92\x16\x91\x90\x91\x17\x90UV[```\0\x80\x84s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x84`@Qa--\x91\x90a6\x90V[`\0`@Q\x80\x83\x03\x81\x85Z\xF4\x91PP=\x80`\0\x81\x14a-hW`@Q\x91P`\x1F\x19`?=\x01\x16\x82\x01`@R=\x82R=`\0` \x84\x01>a-mV[``\x91P[P\x91P\x91Pa y\x85\x83\x83a-\xB5V[4\x15a\x17\xA6W`@Q\x7F\xB3\x98\x97\x9F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[``\x82a-\xCAWa-\xC5\x82a.DV[a\x08\x16V[\x81Q\x15\x80\x15a-\xEEWPs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x16;\x15[\x15a.=W`@Q\x7F\x99\x96\xB3\x15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x85\x16`\x04\x82\x01R`$\x01a\x06[V[P\x80a\x08\x16V[\x80Q\x15a.TW\x80Q\x80\x82` \x01\xFD[`@Q\x7F\xD6\xBD\xA2u\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\0[\x83\x81\x10\x15a.\xA1W\x81\x81\x01Q\x83\x82\x01R` \x01a.\x89V[PP`\0\x91\x01RV[`\0\x81Q\x80\x84Ra.\xC2\x81` \x86\x01` \x86\x01a.\x86V[`\x1F\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16\x92\x90\x92\x01` \x01\x92\x91PPV[` \x81R`\0a\x08\x16` \x83\x01\x84a.\xAAV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`A`\x04R`$`\0\xFD[`@Q`\x1F\x82\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16\x81\x01g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x82\x82\x10\x17\x15a/}Wa/}a/\x07V[`@R\x91\x90PV[`\0\x82`\x1F\x83\x01\x12a/\x96W`\0\x80\xFD[\x815` \x83\x01`\0\x80g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x11\x15a/\xB7Wa/\xB7a/\x07V[P`\x1F\x83\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16` \x01a/\xEA\x81a/6V[\x91PP\x82\x81R\x85\x83\x83\x01\x11\x15a/\xFFW`\0\x80\xFD[\x82\x82` \x83\x017`\0\x92\x81\x01` \x01\x92\x90\x92RP\x93\x92PPPV[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16\x81\x14a\x1E\x8CW`\0\x80\xFD[`\0\x80`\0``\x84\x86\x03\x12\x15a0QW`\0\x80\xFD[\x835g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a0hW`\0\x80\xFD[a0t\x86\x82\x87\x01a/\x85V[\x93PP` \x84\x015\x91P`@\x84\x015a0\x8C\x81a0\x1AV[\x80\x91PP\x92P\x92P\x92V[`\0\x80`\0``\x84\x86\x03\x12\x15a0\xACW`\0\x80\xFD[\x835a0\xB7\x81a0\x1AV[\x92P` \x84\x015a0\xC7\x81a0\x1AV[\x92\x95\x92\x94PPP`@\x91\x90\x91\x015\x90V[`\0\x80`\0\x80`\x80\x85\x87\x03\x12\x15a0\xEEW`\0\x80\xFD[\x845g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a1\x05W`\0\x80\xFD[a1\x11\x87\x82\x88\x01a/\x85V[\x94PP` \x85\x015\x92P`@\x85\x015a1)\x81a0\x1AV[\x91P``\x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a1EW`\0\x80\xFD[a1Q\x87\x82\x88\x01a/\x85V[\x91PP\x92\x95\x91\x94P\x92PV[`\0\x80`\0``\x84\x86\x03\x12\x15a1rW`\0\x80\xFD[\x835g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a1\x89W`\0\x80\xFD[a1\x95\x86\x82\x87\x01a/\x85V[\x93PP` \x84\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a1\xB2W`\0\x80\xFD[a1\xBE\x86\x82\x87\x01a/\x85V[\x93\x96\x93\x95PPPP`@\x91\x90\x91\x015\x90V[`\0` \x82\x84\x03\x12\x15a1\xE2W`\0\x80\xFD[\x815a\x08\x16\x81a0\x1AV[`\0\x80`@\x83\x85\x03\x12\x15a2\0W`\0\x80\xFD[\x825a2\x0B\x81a0\x1AV[\x91P` \x83\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a2'W`\0\x80\xFD[a23\x85\x82\x86\x01a/\x85V[\x91PP\x92P\x92\x90PV[`\0\x80`@\x83\x85\x03\x12\x15a2PW`\0\x80\xFD[\x825\x91P` \x83\x015a2b\x81a0\x1AV[\x80\x91PP\x92P\x92\x90PV[`\0` \x82\x84\x03\x12\x15a2\x7FW`\0\x80\xFD[P5\x91\x90PV[`\0g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x11\x15a2\xA0Wa2\xA0a/\x07V[P`\x05\x1B` \x01\x90V[`\0\x82`\x1F\x83\x01\x12a2\xBBW`\0\x80\xFD[\x815a2\xCEa2\xC9\x82a2\x86V[a/6V[\x80\x82\x82R` \x82\x01\x91P` \x83`\x05\x1B\x86\x01\x01\x92P\x85\x83\x11\x15a2\xF0W`\0\x80\xFD[` \x85\x01[\x83\x81\x10\x15a3\rW\x805\x83R` \x92\x83\x01\x92\x01a2\xF5V[P\x95\x94PPPPPV[`\0\x82`\x1F\x83\x01\x12a3(W`\0\x80\xFD[\x815a36a2\xC9\x82a2\x86V[\x80\x82\x82R` \x82\x01\x91P` \x83`\x05\x1B\x86\x01\x01\x92P\x85\x83\x11\x15a3XW`\0\x80\xFD[` \x85\x01[\x83\x81\x10\x15a3\rW\x805a3p\x81a0\x1AV[\x83R` \x92\x83\x01\x92\x01a3]V[`\0\x82`\x1F\x83\x01\x12a3\x8FW`\0\x80\xFD[\x815a3\x9Da2\xC9\x82a2\x86V[\x80\x82\x82R` \x82\x01\x91P` \x83`\x05\x1B\x86\x01\x01\x92P\x85\x83\x11\x15a3\xBFW`\0\x80\xFD[` \x85\x01[\x83\x81\x10\x15a3\rW\x805g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a3\xE3W`\0\x80\xFD[a3\xF2\x88` \x83\x8A\x01\x01a/\x85V[\x84RP` \x92\x83\x01\x92\x01a3\xC4V[`\0\x80`\0\x80`\x80\x85\x87\x03\x12\x15a4\x17W`\0\x80\xFD[\x845g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a4.W`\0\x80\xFD[\x85\x01`\x1F\x81\x01\x87\x13a4?W`\0\x80\xFD[\x805a4Ma2\xC9\x82a2\x86V[\x80\x82\x82R` \x82\x01\x91P` \x83`\x05\x1B\x85\x01\x01\x92P\x89\x83\x11\x15a4oW`\0\x80\xFD[` \x84\x01[\x83\x81\x10\x15a4\xB1W\x805g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a4\x93W`\0\x80\xFD[a4\xA2\x8C` \x83\x89\x01\x01a/\x85V[\x84RP` \x92\x83\x01\x92\x01a4tV[P\x96PPPP` \x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a4\xD1W`\0\x80\xFD[a4\xDD\x87\x82\x88\x01a2\xAAV[\x93PP`@\x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a4\xFAW`\0\x80\xFD[a5\x06\x87\x82\x88\x01a3\x17V[\x92PP``\x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a5#W`\0\x80\xFD[a1Q\x87\x82\x88\x01a3~V[`\0\x80`@\x83\x85\x03\x12\x15a5BW`\0\x80\xFD[\x825g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a5YW`\0\x80\xFD[a5e\x85\x82\x86\x01a/\x85V[\x95` \x94\x90\x94\x015\x94PPPPV[\x82\x81R`@` \x82\x01R`\0a\x1Fz`@\x83\x01\x84a.\xAAV[`\0` \x82\x84\x03\x12\x15a5\x9FW`\0\x80\xFD[\x81Q\x7F\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81\x16\x81\x14a\x08\x16W`\0\x80\xFD[`\0\x84Qa5\xE1\x81\x84` \x89\x01a.\x86V[\x7Fdomain=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x90\x83\x01\x90\x81R\x84Qa6\x1B\x81`\x07\x84\x01` \x89\x01a.\x86V[\x7F;public_key_hash=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\x07\x92\x90\x91\x01\x91\x82\x01R\x83Qa6Y\x81`\x18\x84\x01` \x88\x01a.\x86V[\x7F;\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\x18\x92\x90\x91\x01\x91\x82\x01R`\x19\x01\x95\x94PPPPPV[`\0\x82Qa6\xA2\x81\x84` \x87\x01a.\x86V[\x91\x90\x91\x01\x92\x91PPV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`\x11`\x04R`$`\0\xFD[\x80\x82\x01\x80\x82\x11\x15a\x1E%Wa\x1E%a6\xACV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`2`\x04R`$`\0\xFD[`\0` \x82\x84\x03\x12\x15a7/W`\0\x80\xFD[\x81Qa\x08\x16\x81a0\x1AV[\x81\x81\x03\x81\x81\x11\x15a\x1E%Wa\x1E%a6\xACV[\x7F\x19Ethereum Signed Message:\n\0\0\0\0\0\0\x81R`\0\x83Qa7\x85\x81`\x1A\x85\x01` \x88\x01a.\x86V[\x83Q\x90\x83\x01\x90a7\x9C\x81`\x1A\x84\x01` \x88\x01a.\x86V[\x01`\x1A\x01\x94\x93PPPPV[`\0` \x82\x84\x03\x12\x15a7\xBAW`\0\x80\xFD[PQ\x91\x90PV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`!`\x04R`$`\0\xFD[\x80\x82\x02\x81\x15\x82\x82\x04\x84\x14\x17a\x1E%Wa\x1E%a6\xACV[`\0\x81a8\x16Wa8\x16a6\xACV[P\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01\x90V\xFE\xA2dipfsX\"\x12 q>\xE1\xC5W\xFE\x9D\x8C[\xE2@\x07\x8D\xB2Z\xAAQ\xB4PX\x8F\x10\\I\xA8\x0Bv \x05\x81\x99\x9CdsolcC\0\x08\x1A\x003"; + /// The bytecode of the contract. + pub static USEROVERRIDABLEDKIMREGISTRY_BYTECODE: ::ethers::core::types::Bytes = ::ethers::core::types::Bytes::from_static( + __BYTECODE, + ); + #[rustfmt::skip] + const __DEPLOYED_BYTECODE: &[u8] = b"`\x80`@R`\x046\x10a\x01\x8BW`\x005`\xE0\x1C\x80c}F6H\x11a\0\xD6W\x80c\xAD<\xB1\xCC\x11a\0\x7FW\x80c\xE7\xA7\x97z\x11a\0YW\x80c\xE7\xA7\x97z\x14a\x05\x92W\x80c\xF0\xBF\xB1\x97\x14a\x05\xB2W\x80c\xF2\xFD\xE3\x8B\x14a\x05\xEDW`\0\x80\xFD[\x80c\xAD<\xB1\xCC\x14a\x04\xAFW\x80c\xD5\x07\xC3 \x14a\x04\xF8W\x80c\xE3\x08\xDE\x0C\x14a\x05AW`\0\x80\xFD[\x80c\x81.\x12\xCE\x11a\0\xB0W\x80c\x81.\x12\xCE\x14a\x04/W\x80c\x82\xBF\xF8\xCD\x14a\x04EW\x80c\x8D\xA5\xCB[\x14a\x04eW`\0\x80\xFD[\x80c}F6H\x14a\x03\x90W\x80c\x7F\x8E)\xBA\x14a\x03\xE2W\x80c\x7F\xF1\x03\xDA\x14a\x04\x0FW`\0\x80\xFD[\x80cL\x93\x06\x07\x11a\x018W\x80cWI\0\xDD\x11a\x01\x12W\x80cWI\0\xDD\x14a\x03 W\x80caJD\x85\x14a\x03[W\x80cqP\x18\xA6\x14a\x03{W`\0\x80\xFD[\x80cL\x93\x06\x07\x14a\x02\xCAW\x80cO\x1E\xF2\x86\x14a\x02\xEAW\x80cR\xD1\x90-\x14a\x02\xFDW`\0\x80\xFD[\x80c\"Z\x08\xD4\x11a\x01iW\x80c\"Z\x08\xD4\x14a\x02AW\x80c2\xE1\xE1\x94\x14a\x02\x8AW\x80cK\xCB\xBE\x96\x14a\x02\xAAW`\0\x80\xFD[\x80c\x07\xF1\xEA\xF5\x14a\x01\x90W\x80c\x0BU\xB3|\x14a\x01\xEFW\x80c\x17\x94\xBB<\x14a\x02\x1FW[`\0\x80\xFD[4\x80\x15a\x01\x9CW`\0\x80\xFD[Pa\x01\xD9`@Q\x80`@\x01`@R\x80`\x04\x81R` \x01\x7FSET:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81RP\x81V[`@Qa\x01\xE6\x91\x90a.\xF4V[`@Q\x80\x91\x03\x90\xF3[4\x80\x15a\x01\xFBW`\0\x80\xFD[Pa\x02\x0Fa\x02\n6`\x04a0#\xA9f.\xFC\x9C\"\x9Cj\0\x80Th\x01\0\0\0\0\0\0\0\0\x81\x04`\xFF\x16\x15\x90g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16`\0\x81\x15\x80\x15a\x08hWP\x82[\x90P`\0\x82g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16`\x01\x14\x80\x15a\x08\x85WP0;\x15[\x90P\x81\x15\x80\x15a\x08\x93WP\x80\x15[\x15a\x08\xCAW`@Q\x7F\xF9.\xE8\xA9\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x84T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\x16`\x01\x17\x85U\x83\x15a\t+W\x84T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16h\x01\0\0\0\0\0\0\0\0\x17\x85U[a\t4\x88a \x82V[`\0\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x89\x16\x17\x90U`\x01\x86\x90U\x83\x15a\t\xDAW\x84T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x85U`@Q`\x01\x81R\x7F\xC7\xF5\x05\xB2\xF3q\xAE!u\xEEI\x13\xF4I\x9E\x1F&3\xA7\xB5\x93c!\xEE\xD1\xCD\xAE\xB6\x11Q\x81\xD2\x90` \x01`@Q\x80\x91\x03\x90\xA1[PPPPPPPPV[`\0\x84Q\x11a\n5W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1A`$\x82\x01R\x7Fdomain name cannot be zero\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[\x82a\n\x82W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1E`$\x82\x01R\x7Fpublic key hash cannot be zero\0\0`D\x82\x01R`d\x01a\x06[V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x16a\x0B\x0BW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`!`$\x82\x01R\x7Fauthorizer address cannot be zer`D\x82\x01R\x7Fo\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[`\0Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x81\x16\x90\x83\x16\x03a\x0B\x9CW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`4`$\x82\x01R\x7FmainAuthorizer cannot reactivate`D\x82\x01R\x7F the public key hash\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[`\0\x83\x81R`\x04` \x90\x81R`@\x80\x83 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x86\x16\x84R\x90\x91R\x90 T`\xFF\x16\x15a\x0CBW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`&`$\x82\x01R\x7Fpublic key hash is already react`D\x82\x01R\x7Fivated\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[a\x0CL\x83\x83a\x1E\x8FV[`\x01\x14a\x0C\x9BW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1C`$\x82\x01R\x7Frevoke threshold must be one\0\0\0\0`D\x82\x01R`d\x01a\x06[V[`\x02a\x0C\xA8\x85\x85\x85a\x1F\x82V[\x10\x15a\r\x1CW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`%`$\x82\x01R\x7Fset threshold must be larger tha`D\x82\x01R\x7Fn two\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[3s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16\x14a\x0FCW`\0a\r{`@Q\x80`@\x01`@R\x80`\x0B\x81R` \x01\x7FREACTIVATE:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81RP\x86\x86a\x0F\xCBV[\x90P`\0a\r\x88\x82a \x93V[\x90Ps\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x16;\x15a\x0E\xB5W`@Q\x7F\x16&\xBA~\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x85\x16\x90c\x16&\xBA~\x90a\r\xFB\x90\x84\x90\x87\x90`\x04\x01a5tV[` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x0E\x18W=`\0\x80>=`\0\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x0E<\x91\x90a5\x8DV[{\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16c\x16&\xBA~`\xE0\x1B\x14a\x0E\xB0W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x19`$\x82\x01R\x7Finvalid eip1271 signature\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[a\x0F@V[`\0a\x0E\xC1\x82\x85a \xCEV[\x90P\x84s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x81s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x14a\x0F>W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x17`$\x82\x01R\x7Finvalid ecdsa signature\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[P[PP[`\0\x83\x81R`\x04` \x90\x81R`@\x80\x83 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x86\x16\x80\x85R\x92R\x80\x83 \x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\x16`\x01\x17\x90UQ\x90\x91\x85\x91\x7F2\x89\x9A\x1E\xA4\xD8\xE4\x91|k=l\x1Ci\xFDLp\x949C\xB0'\xFE\x9D\x83+ R\xE7\xEF\xF8\xD6\x91\x90\xA3PPPPV[``\x83\x83a\x0F\xD8\x84a \xF8V[`@Q` \x01a\x0F\xEA\x93\x92\x91\x90a5\xCFV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P\x93\x92PPPV[a\x10\na!|V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16a\x10\x93W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`(`$\x82\x01R\x7FnewMainAuthorizer address cannot`D\x82\x01R\x7F be zero\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[`\0Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x90\x81\x16\x90\x82\x16\x03a\x11JW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`J`$\x82\x01R\x7FnewMainAuthorizer address cannot`D\x82\x01R\x7F be the same as the current main`d\x82\x01R\x7FAuthorizer\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\x84\x82\x01R`\xA4\x01a\x06[V[`\0\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16\x90\x81\x17\x82U`@Q\x90\x91\x7F;\xB1\x96\x11\xD1\x15f1\xA8\\Y\xDD\xFEvhT\x1A/\0\xE6\xBA+~q\xCB\x0C`\xEC\xE0\xD5\xE5[\x91\xA2PV[a\x11\xBFa\"\nV[a\x11\xC8\x82a#\x0EV[a\x11\xD2\x82\x82a#\x16V[PPV[`\0a\x11\xE0a$TV[P\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\x90V[`\0\x84Q\x11a\x12VW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1A`$\x82\x01R\x7Fdomain name cannot be zero\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[\x82a\x12\xA3W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1E`$\x82\x01R\x7Fpublic key hash cannot be zero\0\0`D\x82\x01R`d\x01a\x06[V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x16a\x13,W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`!`$\x82\x01R\x7Fauthorizer address cannot be zer`D\x82\x01R\x7Fo\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[`\x02\x84`@Qa\x13<\x91\x90a6\x90V[\x90\x81R`@\x80Q` \x92\x81\x90\x03\x83\x01\x90 `\0\x86\x81R\x90\x83R\x81\x81 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x86\x16\x82R\x90\x92R\x90 T`\xFF\x16\x15a\x13\xC7W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1E`$\x82\x01R\x7Fpublic key hash is already set\0\0`D\x82\x01R`d\x01a\x06[V[`\0\x83\x81R`\x03` \x90\x81R`@\x80\x83 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x86\x16\x84R\x90\x91R\x90 T`\xFF\x16\x15a\x14mW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\"`$\x82\x01R\x7Fpublic key hash is already revok`D\x82\x01R\x7Fed\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[3s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16\x14a\x16\x94W`\0a\x14\xCC`@Q\x80`@\x01`@R\x80`\x04\x81R` \x01\x7FSET:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81RP\x86\x86a\x0F\xCBV[\x90P`\0a\x14\xD9\x82a \x93V[\x90Ps\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x16;\x15a\x16\x06W`@Q\x7F\x16&\xBA~\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x85\x16\x90c\x16&\xBA~\x90a\x15L\x90\x84\x90\x87\x90`\x04\x01a5tV[` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x15iW=`\0\x80>=`\0\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x15\x8D\x91\x90a5\x8DV[{\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16c\x16&\xBA~`\xE0\x1B\x14a\x16\x01W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x19`$\x82\x01R\x7Finvalid eip1271 signature\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[a\x16\x91V[`\0a\x16\x12\x82\x85a \xCEV[\x90P\x84s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x81s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x14a\x16\x8FW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x17`$\x82\x01R\x7Finvalid ecdsa signature\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[P[PP[`\x01`\x02\x85`@Qa\x16\xA6\x91\x90a6\x90V[\x90\x81R`@\x80Q` \x92\x81\x90\x03\x83\x01\x90 `\0\x87\x81R\x90\x83R\x81\x81 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x87\x81\x16\x80\x84R\x91\x90\x94R\x91\x81 \x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\x16\x94\x15\x15\x94\x90\x94\x17\x90\x93U\x91T\x16\x90\x03a\x178W`\x01Ta\x17(\x90Ba6\xDBV[`\0\x84\x81R`\x05` R`@\x90 U[\x81s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x83\x85`@Qa\x17^\x91\x90a6\x90V[`@Q\x90\x81\x90\x03\x81 \x90\x7F}a~\xDC\x9D\n\xDE/\xB7hC\xEF_sr\xBD'0\xE9\0\xFA\x12\xE6t\xBE\xCA\xA8\xAD\x01\xEA\xB6\xCB\x90`\0\x90\xA4PPPPV[a\x17\x9Ca!|V[a\x17\xA6`\0a$\xC3V[V[\x82Q\x84Q\x14a\x17\xF9W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1E`$\x82\x01R\x7Finvalid publicKeyHashes length\0\0`D\x82\x01R`d\x01a\x06[V[\x81Q\x84Q\x14a\x18JW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1A`$\x82\x01R\x7Finvalid authorizers length\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[\x80Q\x84Q\x14a\x18\x9BW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x19`$\x82\x01R\x7Finvalid signatures length\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[`\0[\x84Q\x81\x10\x15a\x19\x1FWa\x19\x17\x85\x82\x81Q\x81\x10a\x18\xBCWa\x18\xBCa6\xEEV[` \x02` \x01\x01Q\x85\x83\x81Q\x81\x10a\x18\xD6Wa\x18\xD6a6\xEEV[` \x02` \x01\x01Q\x85\x84\x81Q\x81\x10a\x18\xF0Wa\x18\xF0a6\xEEV[` \x02` \x01\x01Q\x85\x85\x81Q\x81\x10a\x19\nWa\x19\na6\xEEV[` \x02` \x01\x01Qa\x12\x05V[`\x01\x01a\x18\x9EV[PPPPPV[`\0\x84Q\x11a\x19wW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1A`$\x82\x01R\x7Fdomain name cannot be zero\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[\x82a\x19\xC4W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1E`$\x82\x01R\x7Fpublic key hash cannot be zero\0\0`D\x82\x01R`d\x01a\x06[V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x16a\x1AMW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`!`$\x82\x01R\x7Fauthorizer address cannot be zer`D\x82\x01R\x7Fo\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[`\0\x83\x81R`\x03` \x90\x81R`@\x80\x83 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x86\x16\x84R\x90\x91R\x90 T`\xFF\x16\x15a\x1A\xF3W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\"`$\x82\x01R\x7Fpublic key hash is already revok`D\x82\x01R\x7Fed\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`d\x82\x01R`\x84\x01a\x06[V[3s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16\x14a\x1D\x1AW`\0a\x1BR`@Q\x80`@\x01`@R\x80`\x07\x81R` \x01\x7FREVOKE:\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81RP\x86\x86a\x0F\xCBV[\x90P`\0a\x1B_\x82a \x93V[\x90Ps\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x16;\x15a\x1C\x8CW`@Q\x7F\x16&\xBA~\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x85\x16\x90c\x16&\xBA~\x90a\x1B\xD2\x90\x84\x90\x87\x90`\x04\x01a5tV[` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x1B\xEFW=`\0\x80>=`\0\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x1C\x13\x91\x90a5\x8DV[{\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16c\x16&\xBA~`\xE0\x1B\x14a\x1C\x87W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x19`$\x82\x01R\x7Finvalid eip1271 signature\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[a\x1D\x17V[`\0a\x1C\x98\x82\x85a \xCEV[\x90P\x84s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x81s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x14a\x1D\x15W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x17`$\x82\x01R\x7Finvalid ecdsa signature\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06[V[P[PP[`\0\x83\x81R`\x03` \x90\x81R`@\x80\x83 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x86\x16\x80\x85R\x92R\x80\x83 \x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\x16`\x01\x17\x90UQ\x90\x91\x85\x91\x7F5P6\xB8\xAD\x96>\x18^\t\xF0t\xE8VU\x96H:\0\x12\xCB\xE6 \xF5\x07\xC0\xF3IP\xA2\xF0\xB3\x91\x90\xA3PPPPV[`\0\x803s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16c\x8D\xA5\xCB[`@Q\x81c\xFF\xFF\xFF\xFF\x16`\xE0\x1B\x81R`\x04\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x1D\xF0W=`\0\x80>=`\0\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x1E\x14\x91\x90a7\x1DV[\x90Pa\x1E!\x84\x84\x83a\x06\rV[\x91PP[\x92\x91PPV[a\x1E3a!|V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16a\x1E\x83W`@Q\x7F\x1EO\xBD\xF7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\0`\x04\x82\x01R`$\x01a\x06[V[a\x1E\x8C\x81a$\xC3V[PV[`\0\x82\x81R`\x03` \x90\x81R`@\x80\x83 \x83Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x84R\x90\x91R\x81 T\x81\x90`\xFF\x16\x15\x15`\x01\x03a\x1E\xDCWa\x1E\xD9`\x01\x82a6\xDBV[\x90P[`\0\x84\x81R`\x03` \x90\x81R`@\x80\x83 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x87\x16\x84R\x90\x91R\x90 T`\xFF\x16\x15\x15`\x01\x03a\x1F&Wa\x1F#`\x02\x82a6\xDBV[\x90P[\x80`\x01\x14\x80\x15a\x1FjWP`\0\x84\x81R`\x04` \x90\x81R`@\x80\x83 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x87\x16\x84R\x90\x91R\x90 T`\xFF\x16\x15\x15`\x01\x14[\x15a\x08\x16Wa\x1Fz`\x01\x82a7:V[\x94\x93PPPPV[`\0\x80`\0\x90P`\x02\x85`@Qa\x1F\x99\x91\x90a6\x90V[\x90\x81R`@\x80Q` \x92\x81\x90\x03\x83\x01\x90 `\0\x87\x81R\x90\x83R\x81\x81 \x81Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x82R\x90\x92R\x90 T`\xFF\x16\x15\x15`\x01\x03a \x17W`\0\x84\x81R`\x05` R`@\x90 TB\x10\x15a \tWa \x02`\x01\x82a6\xDBV[\x90Pa \x17V[a \x14`\x02\x82a6\xDBV[\x90P[`\x02\x85`@Qa '\x91\x90a6\x90V[\x90\x81R`@\x80Q` \x92\x81\x90\x03\x83\x01\x90 `\0\x87\x81R\x90\x83R\x81\x81 s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x87\x16\x82R\x90\x92R\x90 T`\xFF\x16\x15\x15`\x01\x03a\x1FzWa y`\x02\x82a6\xDBV[\x95\x94PPPPPV[a \x8Aa%YV[a\x1E\x8C\x81a%\xC0V[`\0a \x9F\x82Qa%\xC8V[\x82`@Q` \x01a \xB1\x92\x91\x90a7MV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x80Q\x90` \x01 \x90P\x91\x90PV[`\0\x80`\0\x80a \xDE\x86\x86a&\x86V[\x92P\x92P\x92Pa \xEE\x82\x82a&\xD3V[P\x90\x94\x93PPPPV[``a\x1E%\x82a!t\x84`\xFF`\x80o\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x11\x90\x81\x02\x92\x90\x92\x1C`@g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x11\x90\x81\x02\x91\x90\x91\x1C` c\xFF\xFF\xFF\xFF\x82\x11\x90\x81\x02\x91\x90\x91\x1Ca\xFF\xFF\x81\x11`\x10\x81\x81\x02\x92\x90\x92\x1C\x94\x90\x94\x11`\x02\x90\x94\x02`\x04\x90\x92\x02`\x08\x90\x93\x02\x94\x02\x93\x90\x93\x01\x01\x91\x90\x91\x01\x01\x90V[`\x01\x01a'\xD7V[3a!\xBB\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0Ts\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x90V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x14a\x17\xA6W`@Q\x7F\x11\x8C\xDA\xA7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R3`\x04\x82\x01R`$\x01a\x06[V[0s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14\x80a\"\xD7WP\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16a\"\xBE\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBCTs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x90V[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x14\x15[\x15a\x17\xA6W`@Q\x7F\xE0|\x8D\xBA\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x1E\x8Ca!|V[\x81s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16cR\xD1\x90-`@Q\x81c\xFF\xFF\xFF\xFF\x16`\xE0\x1B\x81R`\x04\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x92PPP\x80\x15a#\x9BWP`@\x80Q`\x1F=\x90\x81\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16\x82\x01\x90\x92Ra#\x98\x91\x81\x01\x90a7\xA8V[`\x01[a#\xE9W`@Q\x7FL\x9C\x8C\xE3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16`\x04\x82\x01R`$\x01a\x06[V[\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\x81\x14a$EW`@Q\x7F\xAA\x1DI\xA4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06[V[a$O\x83\x83a)\xF5V[PPPV[0s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14a\x17\xA6W`@Q\x7F\xE0|\x8D\xBA\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x81\x16\x91\x82\x17\x84U`@Q\x92\x16\x91\x82\x90\x7F\x8B\xE0\x07\x9CS\x16Y\x14\x13D\xCD\x1F\xD0\xA4\xF2\x84\x19I\x7F\x97\"\xA3\xDA\xAF\xE3\xB4\x18okdW\xE0\x90`\0\x90\xA3PPPV[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0Th\x01\0\0\0\0\0\0\0\0\x90\x04`\xFF\x16a\x17\xA6W`@Q\x7F\xD7\xE6\xBC\xF8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x1E3a%YV[```\0a%\xD5\x83a*XV[`\x01\x01\x90P`\0\x81g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a%\xF5Wa%\xF5a/\x07V[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a&\x1FW` \x82\x01\x81\x806\x837\x01\x90P[P\x90P\x81\x81\x01` \x01[\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01\x7F0123456789abcdef\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\n\x86\x06\x1A\x81S`\n\x85\x04\x94P\x84a&)WP\x93\x92PPPV[`\0\x80`\0\x83Q`A\x03a&\xC0W` \x84\x01Q`@\x85\x01Q``\x86\x01Q`\0\x1Aa&\xB2\x88\x82\x85\x85a+:V[\x95P\x95P\x95PPPPa&\xCCV[PP\x81Q`\0\x91P`\x02\x90[\x92P\x92P\x92V[`\0\x82`\x03\x81\x11\x15a&\xE7Wa&\xE7a7\xC1V[\x03a&\xF0WPPV[`\x01\x82`\x03\x81\x11\x15a'\x04Wa'\x04a7\xC1V[\x03a';W`@Q\x7F\xF6E\xEE\xDF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02\x82`\x03\x81\x11\x15a'OWa'Oa7\xC1V[\x03a'\x89W`@Q\x7F\xFC\xE6\x98\xF7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06[V[`\x03\x82`\x03\x81\x11\x15a'\x9DWa'\x9Da7\xC1V[\x03a\x11\xD2W`@Q\x7F\xD7\x8B\xCE\x0C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06[V[``\x82`\0a'\xE7\x84`\x02a7\xF0V[a'\xF2\x90`\x02a6\xDBV[g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a(\nWa(\na/\x07V[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a(4W` \x82\x01\x81\x806\x837\x01\x90P[P\x90P\x7F0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81`\0\x81Q\x81\x10a(kWa(ka6\xEEV[` \x01\x01\x90~\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16\x90\x81`\0\x1A\x90SP\x7Fx\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81`\x01\x81Q\x81\x10a(\xCEWa(\xCEa6\xEEV[` \x01\x01\x90~\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16\x90\x81`\0\x1A\x90SP`\0a)\n\x85`\x02a7\xF0V[a)\x15\x90`\x01a6\xDBV[\x90P[`\x01\x81\x11\x15a)\xB2W\x7F0123456789abcdef\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x83`\x0F\x16`\x10\x81\x10a)VWa)Va6\xEEV[\x1A`\xF8\x1B\x82\x82\x81Q\x81\x10a)lWa)la6\xEEV[` \x01\x01\x90~\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16\x90\x81`\0\x1A\x90SP`\x04\x92\x90\x92\x1C\x91a)\xAB\x81a8\x07V[\x90Pa)\x18V[P\x81\x15a\x1E!W`@Q\x7F\xE2.'\xEB\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x81\x01\x86\x90R`$\x81\x01\x85\x90R`D\x01a\x06[V[a)\xFE\x82a,4V[`@Qs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x83\x16\x90\x7F\xBC|\xD7Z \xEE'\xFD\x9A\xDE\xBA\xB3 A\xF7U!M\xBCk\xFF\xA9\x0C\xC0\"[9\xDA.\\-;\x90`\0\x90\xA2\x80Q\x15a*PWa$O\x82\x82a-\x03V[a\x11\xD2a-}V[`\0\x80z\x18O\x03\xE9?\xF9\xF4\xDA\xA7\x97\xEDn8\xEDd\xBFj\x1F\x01\0\0\0\0\0\0\0\0\x83\x10a*\xA1Wz\x18O\x03\xE9?\xF9\xF4\xDA\xA7\x97\xEDn8\xEDd\xBFj\x1F\x01\0\0\0\0\0\0\0\0\x83\x04\x92P`@\x01[m\x04\xEE-mA[\x85\xAC\xEF\x81\0\0\0\0\x83\x10a*\xCDWm\x04\xEE-mA[\x85\xAC\xEF\x81\0\0\0\0\x83\x04\x92P` \x01[f#\x86\xF2o\xC1\0\0\x83\x10a*\xEBWf#\x86\xF2o\xC1\0\0\x83\x04\x92P`\x10\x01[c\x05\xF5\xE1\0\x83\x10a+\x03Wc\x05\xF5\xE1\0\x83\x04\x92P`\x08\x01[a'\x10\x83\x10a+\x17Wa'\x10\x83\x04\x92P`\x04\x01[`d\x83\x10a+)W`d\x83\x04\x92P`\x02\x01[`\n\x83\x10a\x1E%W`\x01\x01\x92\x91PPV[`\0\x80\x80\x7F\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF]WnsW\xA4P\x1D\xDF\xE9/Fh\x1B \xA0\x84\x11\x15a+uWP`\0\x91P`\x03\x90P\x82a,*V[`@\x80Q`\0\x80\x82R` \x82\x01\x80\x84R\x8A\x90R`\xFF\x89\x16\x92\x82\x01\x92\x90\x92R``\x81\x01\x87\x90R`\x80\x81\x01\x86\x90R`\x01\x90`\xA0\x01` `@Q` \x81\x03\x90\x80\x84\x03\x90\x85Z\xFA\x15\x80\x15a+\xC9W=`\0\x80>=`\0\xFD[PP`@Q\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x01Q\x91PPs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16a, WP`\0\x92P`\x01\x91P\x82\x90Pa,*V[\x92P`\0\x91P\x81\x90P[\x94P\x94P\x94\x91PPV[\x80s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16;`\0\x03a,\x9DW`@Q\x7FL\x9C\x8C\xE3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x16`\x04\x82\x01R`$\x01a\x06[V[\x7F6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\x80T\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x92\x90\x92\x16\x91\x90\x91\x17\x90UV[```\0\x80\x84s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x16\x84`@Qa--\x91\x90a6\x90V[`\0`@Q\x80\x83\x03\x81\x85Z\xF4\x91PP=\x80`\0\x81\x14a-hW`@Q\x91P`\x1F\x19`?=\x01\x16\x82\x01`@R=\x82R=`\0` \x84\x01>a-mV[``\x91P[P\x91P\x91Pa y\x85\x83\x83a-\xB5V[4\x15a\x17\xA6W`@Q\x7F\xB3\x98\x97\x9F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[``\x82a-\xCAWa-\xC5\x82a.DV[a\x08\x16V[\x81Q\x15\x80\x15a-\xEEWPs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x16;\x15[\x15a.=W`@Q\x7F\x99\x96\xB3\x15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81Rs\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x85\x16`\x04\x82\x01R`$\x01a\x06[V[P\x80a\x08\x16V[\x80Q\x15a.TW\x80Q\x80\x82` \x01\xFD[`@Q\x7F\xD6\xBD\xA2u\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\0[\x83\x81\x10\x15a.\xA1W\x81\x81\x01Q\x83\x82\x01R` \x01a.\x89V[PP`\0\x91\x01RV[`\0\x81Q\x80\x84Ra.\xC2\x81` \x86\x01` \x86\x01a.\x86V[`\x1F\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16\x92\x90\x92\x01` \x01\x92\x91PPV[` \x81R`\0a\x08\x16` \x83\x01\x84a.\xAAV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`A`\x04R`$`\0\xFD[`@Q`\x1F\x82\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16\x81\x01g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x82\x82\x10\x17\x15a/}Wa/}a/\x07V[`@R\x91\x90PV[`\0\x82`\x1F\x83\x01\x12a/\x96W`\0\x80\xFD[\x815` \x83\x01`\0\x80g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x84\x11\x15a/\xB7Wa/\xB7a/\x07V[P`\x1F\x83\x01\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xE0\x16` \x01a/\xEA\x81a/6V[\x91PP\x82\x81R\x85\x83\x83\x01\x11\x15a/\xFFW`\0\x80\xFD[\x82\x82` \x83\x017`\0\x92\x81\x01` \x01\x92\x90\x92RP\x93\x92PPPV[s\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x16\x81\x14a\x1E\x8CW`\0\x80\xFD[`\0\x80`\0``\x84\x86\x03\x12\x15a0QW`\0\x80\xFD[\x835g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a0hW`\0\x80\xFD[a0t\x86\x82\x87\x01a/\x85V[\x93PP` \x84\x015\x91P`@\x84\x015a0\x8C\x81a0\x1AV[\x80\x91PP\x92P\x92P\x92V[`\0\x80`\0``\x84\x86\x03\x12\x15a0\xACW`\0\x80\xFD[\x835a0\xB7\x81a0\x1AV[\x92P` \x84\x015a0\xC7\x81a0\x1AV[\x92\x95\x92\x94PPP`@\x91\x90\x91\x015\x90V[`\0\x80`\0\x80`\x80\x85\x87\x03\x12\x15a0\xEEW`\0\x80\xFD[\x845g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a1\x05W`\0\x80\xFD[a1\x11\x87\x82\x88\x01a/\x85V[\x94PP` \x85\x015\x92P`@\x85\x015a1)\x81a0\x1AV[\x91P``\x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a1EW`\0\x80\xFD[a1Q\x87\x82\x88\x01a/\x85V[\x91PP\x92\x95\x91\x94P\x92PV[`\0\x80`\0``\x84\x86\x03\x12\x15a1rW`\0\x80\xFD[\x835g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a1\x89W`\0\x80\xFD[a1\x95\x86\x82\x87\x01a/\x85V[\x93PP` \x84\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a1\xB2W`\0\x80\xFD[a1\xBE\x86\x82\x87\x01a/\x85V[\x93\x96\x93\x95PPPP`@\x91\x90\x91\x015\x90V[`\0` \x82\x84\x03\x12\x15a1\xE2W`\0\x80\xFD[\x815a\x08\x16\x81a0\x1AV[`\0\x80`@\x83\x85\x03\x12\x15a2\0W`\0\x80\xFD[\x825a2\x0B\x81a0\x1AV[\x91P` \x83\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a2'W`\0\x80\xFD[a23\x85\x82\x86\x01a/\x85V[\x91PP\x92P\x92\x90PV[`\0\x80`@\x83\x85\x03\x12\x15a2PW`\0\x80\xFD[\x825\x91P` \x83\x015a2b\x81a0\x1AV[\x80\x91PP\x92P\x92\x90PV[`\0` \x82\x84\x03\x12\x15a2\x7FW`\0\x80\xFD[P5\x91\x90PV[`\0g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x82\x11\x15a2\xA0Wa2\xA0a/\x07V[P`\x05\x1B` \x01\x90V[`\0\x82`\x1F\x83\x01\x12a2\xBBW`\0\x80\xFD[\x815a2\xCEa2\xC9\x82a2\x86V[a/6V[\x80\x82\x82R` \x82\x01\x91P` \x83`\x05\x1B\x86\x01\x01\x92P\x85\x83\x11\x15a2\xF0W`\0\x80\xFD[` \x85\x01[\x83\x81\x10\x15a3\rW\x805\x83R` \x92\x83\x01\x92\x01a2\xF5V[P\x95\x94PPPPPV[`\0\x82`\x1F\x83\x01\x12a3(W`\0\x80\xFD[\x815a36a2\xC9\x82a2\x86V[\x80\x82\x82R` \x82\x01\x91P` \x83`\x05\x1B\x86\x01\x01\x92P\x85\x83\x11\x15a3XW`\0\x80\xFD[` \x85\x01[\x83\x81\x10\x15a3\rW\x805a3p\x81a0\x1AV[\x83R` \x92\x83\x01\x92\x01a3]V[`\0\x82`\x1F\x83\x01\x12a3\x8FW`\0\x80\xFD[\x815a3\x9Da2\xC9\x82a2\x86V[\x80\x82\x82R` \x82\x01\x91P` \x83`\x05\x1B\x86\x01\x01\x92P\x85\x83\x11\x15a3\xBFW`\0\x80\xFD[` \x85\x01[\x83\x81\x10\x15a3\rW\x805g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a3\xE3W`\0\x80\xFD[a3\xF2\x88` \x83\x8A\x01\x01a/\x85V[\x84RP` \x92\x83\x01\x92\x01a3\xC4V[`\0\x80`\0\x80`\x80\x85\x87\x03\x12\x15a4\x17W`\0\x80\xFD[\x845g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a4.W`\0\x80\xFD[\x85\x01`\x1F\x81\x01\x87\x13a4?W`\0\x80\xFD[\x805a4Ma2\xC9\x82a2\x86V[\x80\x82\x82R` \x82\x01\x91P` \x83`\x05\x1B\x85\x01\x01\x92P\x89\x83\x11\x15a4oW`\0\x80\xFD[` \x84\x01[\x83\x81\x10\x15a4\xB1W\x805g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a4\x93W`\0\x80\xFD[a4\xA2\x8C` \x83\x89\x01\x01a/\x85V[\x84RP` \x92\x83\x01\x92\x01a4tV[P\x96PPPP` \x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a4\xD1W`\0\x80\xFD[a4\xDD\x87\x82\x88\x01a2\xAAV[\x93PP`@\x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a4\xFAW`\0\x80\xFD[a5\x06\x87\x82\x88\x01a3\x17V[\x92PP``\x85\x015g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a5#W`\0\x80\xFD[a1Q\x87\x82\x88\x01a3~V[`\0\x80`@\x83\x85\x03\x12\x15a5BW`\0\x80\xFD[\x825g\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x81\x11\x15a5YW`\0\x80\xFD[a5e\x85\x82\x86\x01a/\x85V[\x95` \x94\x90\x94\x015\x94PPPPV[\x82\x81R`@` \x82\x01R`\0a\x1Fz`@\x83\x01\x84a.\xAAV[`\0` \x82\x84\x03\x12\x15a5\x9FW`\0\x80\xFD[\x81Q\x7F\xFF\xFF\xFF\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81\x16\x81\x14a\x08\x16W`\0\x80\xFD[`\0\x84Qa5\xE1\x81\x84` \x89\x01a.\x86V[\x7Fdomain=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x90\x83\x01\x90\x81R\x84Qa6\x1B\x81`\x07\x84\x01` \x89\x01a.\x86V[\x7F;public_key_hash=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\x07\x92\x90\x91\x01\x91\x82\x01R\x83Qa6Y\x81`\x18\x84\x01` \x88\x01a.\x86V[\x7F;\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\x18\x92\x90\x91\x01\x91\x82\x01R`\x19\x01\x95\x94PPPPPV[`\0\x82Qa6\xA2\x81\x84` \x87\x01a.\x86V[\x91\x90\x91\x01\x92\x91PPV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`\x11`\x04R`$`\0\xFD[\x80\x82\x01\x80\x82\x11\x15a\x1E%Wa\x1E%a6\xACV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`2`\x04R`$`\0\xFD[`\0` \x82\x84\x03\x12\x15a7/W`\0\x80\xFD[\x81Qa\x08\x16\x81a0\x1AV[\x81\x81\x03\x81\x81\x11\x15a\x1E%Wa\x1E%a6\xACV[\x7F\x19Ethereum Signed Message:\n\0\0\0\0\0\0\x81R`\0\x83Qa7\x85\x81`\x1A\x85\x01` \x88\x01a.\x86V[\x83Q\x90\x83\x01\x90a7\x9C\x81`\x1A\x84\x01` \x88\x01a.\x86V[\x01`\x1A\x01\x94\x93PPPPV[`\0` \x82\x84\x03\x12\x15a7\xBAW`\0\x80\xFD[PQ\x91\x90PV[\x7FNH{q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0R`!`\x04R`$`\0\xFD[\x80\x82\x02\x81\x15\x82\x82\x04\x84\x14\x17a\x1E%Wa\x1E%a6\xACV[`\0\x81a8\x16Wa8\x16a6\xACV[P\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01\x90V\xFE\xA2dipfsX\"\x12 q>\xE1\xC5W\xFE\x9D\x8C[\xE2@\x07\x8D\xB2Z\xAAQ\xB4PX\x8F\x10\\I\xA8\x0Bv \x05\x81\x99\x9CdsolcC\0\x08\x1A\x003"; + /// The deployed bytecode of the contract. + pub static USEROVERRIDABLEDKIMREGISTRY_DEPLOYED_BYTECODE: ::ethers::core::types::Bytes = ::ethers::core::types::Bytes::from_static( + __DEPLOYED_BYTECODE, + ); + pub struct UserOverridableDKIMRegistry(::ethers::contract::Contract); + impl ::core::clone::Clone for UserOverridableDKIMRegistry { + fn clone(&self) -> Self { + Self(::core::clone::Clone::clone(&self.0)) + } + } + impl ::core::ops::Deref for UserOverridableDKIMRegistry { + type Target = ::ethers::contract::Contract; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl ::core::ops::DerefMut for UserOverridableDKIMRegistry { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + impl ::core::fmt::Debug for UserOverridableDKIMRegistry { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + f.debug_tuple(::core::stringify!(UserOverridableDKIMRegistry)) + .field(&self.address()) + .finish() + } + } + impl UserOverridableDKIMRegistry { + /// Creates a new contract instance with the specified `ethers` client at + /// `address`. The contract derefs to a `ethers::Contract` object. + pub fn new>( + address: T, + client: ::std::sync::Arc, + ) -> Self { + Self( + ::ethers::contract::Contract::new( + address.into(), + USEROVERRIDABLEDKIMREGISTRY_ABI.clone(), + client, + ), + ) + } + /// Constructs the general purpose `Deployer` instance based on the provided constructor arguments and sends it. + /// Returns a new instance of a deployer that returns an instance of this contract after sending the transaction + /// + /// Notes: + /// - If there are no constructor arguments, you should pass `()` as the argument. + /// - The default poll duration is 7 seconds. + /// - The default number of confirmations is 1 block. + /// + /// + /// # Example + /// + /// Generate contract bindings with `abigen!` and deploy a new contract instance. + /// + /// *Note*: this requires a `bytecode` and `abi` object in the `greeter.json` artifact. + /// + /// ```ignore + /// # async fn deploy(client: ::std::sync::Arc) { + /// abigen!(Greeter, "../greeter.json"); + /// + /// let greeter_contract = Greeter::deploy(client, "Hello world!".to_string()).unwrap().send().await.unwrap(); + /// let msg = greeter_contract.greet().call().await.unwrap(); + /// # } + /// ``` + pub fn deploy( + client: ::std::sync::Arc, + constructor_args: T, + ) -> ::core::result::Result< + ::ethers::contract::builders::ContractDeployer, + ::ethers::contract::ContractError, + > { + let factory = ::ethers::contract::ContractFactory::new( + USEROVERRIDABLEDKIMREGISTRY_ABI.clone(), + USEROVERRIDABLEDKIMREGISTRY_BYTECODE.clone().into(), + client, + ); + let deployer = factory.deploy(constructor_args)?; + let deployer = ::ethers::contract::ContractDeployer::new(deployer); + Ok(deployer) + } + ///Calls the contract's `REACTIVATE_PREFIX` (0x225a08d4) function + pub fn reactivate_prefix( + &self, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([34, 90, 8, 212], ()) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `REVOKE_PREFIX` (0xd507c320) function + pub fn revoke_prefix( + &self, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([213, 7, 195, 32], ()) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `SET_PREFIX` (0x07f1eaf5) function + pub fn set_prefix( + &self, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([7, 241, 234, 245], ()) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `UPGRADE_INTERFACE_VERSION` (0xad3cb1cc) function + pub fn upgrade_interface_version( + &self, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([173, 60, 177, 204], ()) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `changeMainAuthorizer` (0x4c930607) function + pub fn change_main_authorizer( + &self, + new_main_authorizer: ::ethers::core::types::Address, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([76, 147, 6, 7], new_main_authorizer) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `computeSignedMsg` (0x4bcbbe96) function + pub fn compute_signed_msg( + &self, + prefix: ::std::string::String, + domain_name: ::std::string::String, + public_key_hash: [u8; 32], + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([75, 203, 190, 150], (prefix, domain_name, public_key_hash)) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `dkimPublicKeyHashes` (0xe308de0c) function + pub fn dkim_public_key_hashes( + &self, + p0: ::std::string::String, + p1: [u8; 32], + p2: ::ethers::core::types::Address, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([227, 8, 222, 12], (p0, p1, p2)) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `enabledTimeOfDKIMPublicKeyHash` (0x7f8e29ba) function + pub fn enabled_time_of_dkim_public_key_hash( + &self, + p0: [u8; 32], + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([127, 142, 41, 186], p0) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `initialize` (0x1794bb3c) function + pub fn initialize( + &self, + initial_owner: ::ethers::core::types::Address, + main_authorizer: ::ethers::core::types::Address, + set_timestamp_delay: ::ethers::core::types::U256, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash( + [23, 148, 187, 60], + (initial_owner, main_authorizer, set_timestamp_delay), + ) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `isDKIMPublicKeyHashValid` (0x0b55b37c) function + pub fn is_dkim_public_key_hash_valid_with_domain_name_and_public_key_hash( + &self, + domain_name: ::std::string::String, + public_key_hash: [u8; 32], + authorizer: ::ethers::core::types::Address, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash( + [11, 85, 179, 124], + (domain_name, public_key_hash, authorizer), + ) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `isDKIMPublicKeyHashValid` (0xe7a7977a) function + pub fn is_dkim_public_key_hash_valid( + &self, + domain_name: ::std::string::String, + public_key_hash: [u8; 32], + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([231, 167, 151, 122], (domain_name, public_key_hash)) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `mainAuthorizer` (0x7d463648) function + pub fn main_authorizer( + &self, + ) -> ::ethers::contract::builders::ContractCall< + M, + ::ethers::core::types::Address, + > { + self.0 + .method_hash([125, 70, 54, 72], ()) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `owner` (0x8da5cb5b) function + pub fn owner( + &self, + ) -> ::ethers::contract::builders::ContractCall< + M, + ::ethers::core::types::Address, + > { + self.0 + .method_hash([141, 165, 203, 91], ()) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `proxiableUUID` (0x52d1902d) function + pub fn proxiable_uuid( + &self, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([82, 209, 144, 45], ()) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `reactivateDKIMPublicKeyHash` (0x32e1e194) function + pub fn reactivate_dkim_public_key_hash( + &self, + domain_name: ::std::string::String, + public_key_hash: [u8; 32], + authorizer: ::ethers::core::types::Address, + signature: ::ethers::core::types::Bytes, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash( + [50, 225, 225, 148], + (domain_name, public_key_hash, authorizer, signature), + ) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `reactivatedDKIMPublicKeyHashes` (0x574900dd) function + pub fn reactivated_dkim_public_key_hashes( + &self, + p0: [u8; 32], + p1: ::ethers::core::types::Address, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([87, 73, 0, 221], (p0, p1)) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `renounceOwnership` (0x715018a6) function + pub fn renounce_ownership( + &self, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([113, 80, 24, 166], ()) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `revokeDKIMPublicKeyHash` (0x82bff8cd) function + pub fn revoke_dkim_public_key_hash( + &self, + domain_name: ::std::string::String, + public_key_hash: [u8; 32], + authorizer: ::ethers::core::types::Address, + signature: ::ethers::core::types::Bytes, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash( + [130, 191, 248, 205], + (domain_name, public_key_hash, authorizer, signature), + ) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `revokedDKIMPublicKeyHashes` (0xf0bfb197) function + pub fn revoked_dkim_public_key_hashes( + &self, + p0: [u8; 32], + p1: ::ethers::core::types::Address, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([240, 191, 177, 151], (p0, p1)) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `setDKIMPublicKeyHash` (0x614a4485) function + pub fn set_dkim_public_key_hash( + &self, + domain_name: ::std::string::String, + public_key_hash: [u8; 32], + authorizer: ::ethers::core::types::Address, + signature: ::ethers::core::types::Bytes, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash( + [97, 74, 68, 133], + (domain_name, public_key_hash, authorizer, signature), + ) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `setDKIMPublicKeyHashes` (0x7ff103da) function + pub fn set_dkim_public_key_hashes( + &self, + domain_names: ::std::vec::Vec<::std::string::String>, + public_key_hashes: ::std::vec::Vec<[u8; 32]>, + authorizers: ::std::vec::Vec<::ethers::core::types::Address>, + signatures: ::std::vec::Vec<::ethers::core::types::Bytes>, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash( + [127, 241, 3, 218], + (domain_names, public_key_hashes, authorizers, signatures), + ) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `setTimestampDelay` (0x812e12ce) function + pub fn set_timestamp_delay( + &self, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([129, 46, 18, 206], ()) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `transferOwnership` (0xf2fde38b) function + pub fn transfer_ownership( + &self, + new_owner: ::ethers::core::types::Address, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([242, 253, 227, 139], new_owner) + .expect("method not found (this should never happen)") + } + ///Calls the contract's `upgradeToAndCall` (0x4f1ef286) function + pub fn upgrade_to_and_call( + &self, + new_implementation: ::ethers::core::types::Address, + data: ::ethers::core::types::Bytes, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([79, 30, 242, 134], (new_implementation, data)) + .expect("method not found (this should never happen)") + } + ///Gets the contract's `DKIMPublicKeyHashReactivated` event + pub fn dkim_public_key_hash_reactivated_filter( + &self, + ) -> ::ethers::contract::builders::Event< + ::std::sync::Arc, + M, + DkimpublicKeyHashReactivatedFilter, + > { + self.0.event() + } + ///Gets the contract's `DKIMPublicKeyHashRegistered` event + pub fn dkim_public_key_hash_registered_filter( + &self, + ) -> ::ethers::contract::builders::Event< + ::std::sync::Arc, + M, + DkimpublicKeyHashRegisteredFilter, + > { + self.0.event() + } + ///Gets the contract's `DKIMPublicKeyHashRevoked` event + pub fn dkim_public_key_hash_revoked_filter( + &self, + ) -> ::ethers::contract::builders::Event< + ::std::sync::Arc, + M, + DkimpublicKeyHashRevokedFilter, + > { + self.0.event() + } + ///Gets the contract's `Initialized` event + pub fn initialized_filter( + &self, + ) -> ::ethers::contract::builders::Event< + ::std::sync::Arc, + M, + InitializedFilter, + > { + self.0.event() + } + ///Gets the contract's `MainAuthorizerChanged` event + pub fn main_authorizer_changed_filter( + &self, + ) -> ::ethers::contract::builders::Event< + ::std::sync::Arc, + M, + MainAuthorizerChangedFilter, + > { + self.0.event() + } + ///Gets the contract's `OwnershipTransferred` event + pub fn ownership_transferred_filter( + &self, + ) -> ::ethers::contract::builders::Event< + ::std::sync::Arc, + M, + OwnershipTransferredFilter, + > { + self.0.event() + } + ///Gets the contract's `Upgraded` event + pub fn upgraded_filter( + &self, + ) -> ::ethers::contract::builders::Event< + ::std::sync::Arc, + M, + UpgradedFilter, + > { + self.0.event() + } + /// Returns an `Event` builder for all the events of this contract. + pub fn events( + &self, + ) -> ::ethers::contract::builders::Event< + ::std::sync::Arc, + M, + UserOverridableDKIMRegistryEvents, + > { + self.0.event_with_filter(::core::default::Default::default()) + } + } + impl From<::ethers::contract::Contract> + for UserOverridableDKIMRegistry { + fn from(contract: ::ethers::contract::Contract) -> Self { + Self::new(contract.address(), contract.client()) + } + } + ///Custom Error type `AddressEmptyCode` with signature `AddressEmptyCode(address)` and selector `0x9996b315` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[etherror(name = "AddressEmptyCode", abi = "AddressEmptyCode(address)")] + pub struct AddressEmptyCode { + pub target: ::ethers::core::types::Address, + } + ///Custom Error type `ECDSAInvalidSignature` with signature `ECDSAInvalidSignature()` and selector `0xf645eedf` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[etherror(name = "ECDSAInvalidSignature", abi = "ECDSAInvalidSignature()")] + pub struct ECDSAInvalidSignature; + ///Custom Error type `ECDSAInvalidSignatureLength` with signature `ECDSAInvalidSignatureLength(uint256)` and selector `0xfce698f7` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[etherror( + name = "ECDSAInvalidSignatureLength", + abi = "ECDSAInvalidSignatureLength(uint256)" + )] + pub struct ECDSAInvalidSignatureLength { + pub length: ::ethers::core::types::U256, + } + ///Custom Error type `ECDSAInvalidSignatureS` with signature `ECDSAInvalidSignatureS(bytes32)` and selector `0xd78bce0c` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[etherror(name = "ECDSAInvalidSignatureS", abi = "ECDSAInvalidSignatureS(bytes32)")] + pub struct ECDSAInvalidSignatureS { + pub s: [u8; 32], + } + ///Custom Error type `ERC1967InvalidImplementation` with signature `ERC1967InvalidImplementation(address)` and selector `0x4c9c8ce3` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[etherror( + name = "ERC1967InvalidImplementation", + abi = "ERC1967InvalidImplementation(address)" + )] + pub struct ERC1967InvalidImplementation { + pub implementation: ::ethers::core::types::Address, + } + ///Custom Error type `ERC1967NonPayable` with signature `ERC1967NonPayable()` and selector `0xb398979f` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[etherror(name = "ERC1967NonPayable", abi = "ERC1967NonPayable()")] + pub struct ERC1967NonPayable; + ///Custom Error type `FailedCall` with signature `FailedCall()` and selector `0xd6bda275` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[etherror(name = "FailedCall", abi = "FailedCall()")] + pub struct FailedCall; + ///Custom Error type `InvalidInitialization` with signature `InvalidInitialization()` and selector `0xf92ee8a9` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[etherror(name = "InvalidInitialization", abi = "InvalidInitialization()")] + pub struct InvalidInitialization; + ///Custom Error type `NotInitializing` with signature `NotInitializing()` and selector `0xd7e6bcf8` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[etherror(name = "NotInitializing", abi = "NotInitializing()")] + pub struct NotInitializing; + ///Custom Error type `OwnableInvalidOwner` with signature `OwnableInvalidOwner(address)` and selector `0x1e4fbdf7` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[etherror(name = "OwnableInvalidOwner", abi = "OwnableInvalidOwner(address)")] + pub struct OwnableInvalidOwner { + pub owner: ::ethers::core::types::Address, + } + ///Custom Error type `OwnableUnauthorizedAccount` with signature `OwnableUnauthorizedAccount(address)` and selector `0x118cdaa7` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[etherror( + name = "OwnableUnauthorizedAccount", + abi = "OwnableUnauthorizedAccount(address)" + )] + pub struct OwnableUnauthorizedAccount { + pub account: ::ethers::core::types::Address, + } + ///Custom Error type `StringsInsufficientHexLength` with signature `StringsInsufficientHexLength(uint256,uint256)` and selector `0xe22e27eb` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[etherror( + name = "StringsInsufficientHexLength", + abi = "StringsInsufficientHexLength(uint256,uint256)" + )] + pub struct StringsInsufficientHexLength { + pub value: ::ethers::core::types::U256, + pub length: ::ethers::core::types::U256, + } + ///Custom Error type `UUPSUnauthorizedCallContext` with signature `UUPSUnauthorizedCallContext()` and selector `0xe07c8dba` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[etherror( + name = "UUPSUnauthorizedCallContext", + abi = "UUPSUnauthorizedCallContext()" + )] + pub struct UUPSUnauthorizedCallContext; + ///Custom Error type `UUPSUnsupportedProxiableUUID` with signature `UUPSUnsupportedProxiableUUID(bytes32)` and selector `0xaa1d49a4` + #[derive( + Clone, + ::ethers::contract::EthError, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[etherror( + name = "UUPSUnsupportedProxiableUUID", + abi = "UUPSUnsupportedProxiableUUID(bytes32)" + )] + pub struct UUPSUnsupportedProxiableUUID { + pub slot: [u8; 32], + } + ///Container type for all of the contract's custom errors + #[derive(Clone, ::ethers::contract::EthAbiType, Debug, PartialEq, Eq, Hash)] + pub enum UserOverridableDKIMRegistryErrors { + AddressEmptyCode(AddressEmptyCode), + ECDSAInvalidSignature(ECDSAInvalidSignature), + ECDSAInvalidSignatureLength(ECDSAInvalidSignatureLength), + ECDSAInvalidSignatureS(ECDSAInvalidSignatureS), + ERC1967InvalidImplementation(ERC1967InvalidImplementation), + ERC1967NonPayable(ERC1967NonPayable), + FailedCall(FailedCall), + InvalidInitialization(InvalidInitialization), + NotInitializing(NotInitializing), + OwnableInvalidOwner(OwnableInvalidOwner), + OwnableUnauthorizedAccount(OwnableUnauthorizedAccount), + StringsInsufficientHexLength(StringsInsufficientHexLength), + UUPSUnauthorizedCallContext(UUPSUnauthorizedCallContext), + UUPSUnsupportedProxiableUUID(UUPSUnsupportedProxiableUUID), + /// The standard solidity revert string, with selector + /// Error(string) -- 0x08c379a0 + RevertString(::std::string::String), + } + impl ::ethers::core::abi::AbiDecode for UserOverridableDKIMRegistryErrors { + fn decode( + data: impl AsRef<[u8]>, + ) -> ::core::result::Result { + let data = data.as_ref(); + if let Ok(decoded) = <::std::string::String as ::ethers::core::abi::AbiDecode>::decode( + data, + ) { + return Ok(Self::RevertString(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::AddressEmptyCode(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::ECDSAInvalidSignature(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::ECDSAInvalidSignatureLength(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::ECDSAInvalidSignatureS(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::ERC1967InvalidImplementation(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::ERC1967NonPayable(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::FailedCall(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::InvalidInitialization(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::NotInitializing(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::OwnableInvalidOwner(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::OwnableUnauthorizedAccount(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::StringsInsufficientHexLength(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::UUPSUnauthorizedCallContext(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::UUPSUnsupportedProxiableUUID(decoded)); + } + Err(::ethers::core::abi::Error::InvalidData.into()) + } + } + impl ::ethers::core::abi::AbiEncode for UserOverridableDKIMRegistryErrors { + fn encode(self) -> ::std::vec::Vec { + match self { + Self::AddressEmptyCode(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::ECDSAInvalidSignature(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::ECDSAInvalidSignatureLength(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::ECDSAInvalidSignatureS(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::ERC1967InvalidImplementation(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::ERC1967NonPayable(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::FailedCall(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::InvalidInitialization(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::NotInitializing(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::OwnableInvalidOwner(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::OwnableUnauthorizedAccount(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::StringsInsufficientHexLength(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::UUPSUnauthorizedCallContext(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::UUPSUnsupportedProxiableUUID(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::RevertString(s) => ::ethers::core::abi::AbiEncode::encode(s), + } + } + } + impl ::ethers::contract::ContractRevert for UserOverridableDKIMRegistryErrors { + fn valid_selector(selector: [u8; 4]) -> bool { + match selector { + [0x08, 0xc3, 0x79, 0xa0] => true, + _ if selector + == ::selector() => { + true + } + _ if selector + == ::selector() => { + true + } + _ if selector + == ::selector() => { + true + } + _ if selector + == ::selector() => { + true + } + _ if selector + == ::selector() => { + true + } + _ if selector + == ::selector() => { + true + } + _ if selector + == ::selector() => true, + _ if selector + == ::selector() => { + true + } + _ if selector + == ::selector() => { + true + } + _ if selector + == ::selector() => { + true + } + _ if selector + == ::selector() => { + true + } + _ if selector + == ::selector() => { + true + } + _ if selector + == ::selector() => { + true + } + _ if selector + == ::selector() => { + true + } + _ => false, + } + } + } + impl ::core::fmt::Display for UserOverridableDKIMRegistryErrors { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + match self { + Self::AddressEmptyCode(element) => ::core::fmt::Display::fmt(element, f), + Self::ECDSAInvalidSignature(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::ECDSAInvalidSignatureLength(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::ECDSAInvalidSignatureS(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::ERC1967InvalidImplementation(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::ERC1967NonPayable(element) => ::core::fmt::Display::fmt(element, f), + Self::FailedCall(element) => ::core::fmt::Display::fmt(element, f), + Self::InvalidInitialization(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::NotInitializing(element) => ::core::fmt::Display::fmt(element, f), + Self::OwnableInvalidOwner(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::OwnableUnauthorizedAccount(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::StringsInsufficientHexLength(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::UUPSUnauthorizedCallContext(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::UUPSUnsupportedProxiableUUID(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::RevertString(s) => ::core::fmt::Display::fmt(s, f), + } + } + } + impl ::core::convert::From<::std::string::String> + for UserOverridableDKIMRegistryErrors { + fn from(value: String) -> Self { + Self::RevertString(value) + } + } + impl ::core::convert::From for UserOverridableDKIMRegistryErrors { + fn from(value: AddressEmptyCode) -> Self { + Self::AddressEmptyCode(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryErrors { + fn from(value: ECDSAInvalidSignature) -> Self { + Self::ECDSAInvalidSignature(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryErrors { + fn from(value: ECDSAInvalidSignatureLength) -> Self { + Self::ECDSAInvalidSignatureLength(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryErrors { + fn from(value: ECDSAInvalidSignatureS) -> Self { + Self::ECDSAInvalidSignatureS(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryErrors { + fn from(value: ERC1967InvalidImplementation) -> Self { + Self::ERC1967InvalidImplementation(value) + } + } + impl ::core::convert::From for UserOverridableDKIMRegistryErrors { + fn from(value: ERC1967NonPayable) -> Self { + Self::ERC1967NonPayable(value) + } + } + impl ::core::convert::From for UserOverridableDKIMRegistryErrors { + fn from(value: FailedCall) -> Self { + Self::FailedCall(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryErrors { + fn from(value: InvalidInitialization) -> Self { + Self::InvalidInitialization(value) + } + } + impl ::core::convert::From for UserOverridableDKIMRegistryErrors { + fn from(value: NotInitializing) -> Self { + Self::NotInitializing(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryErrors { + fn from(value: OwnableInvalidOwner) -> Self { + Self::OwnableInvalidOwner(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryErrors { + fn from(value: OwnableUnauthorizedAccount) -> Self { + Self::OwnableUnauthorizedAccount(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryErrors { + fn from(value: StringsInsufficientHexLength) -> Self { + Self::StringsInsufficientHexLength(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryErrors { + fn from(value: UUPSUnauthorizedCallContext) -> Self { + Self::UUPSUnauthorizedCallContext(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryErrors { + fn from(value: UUPSUnsupportedProxiableUUID) -> Self { + Self::UUPSUnsupportedProxiableUUID(value) + } + } + #[derive( + Clone, + ::ethers::contract::EthEvent, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethevent( + name = "DKIMPublicKeyHashReactivated", + abi = "DKIMPublicKeyHashReactivated(bytes32,address)" + )] + pub struct DkimpublicKeyHashReactivatedFilter { + #[ethevent(indexed)] + pub public_key_hash: [u8; 32], + #[ethevent(indexed)] + pub authorizer: ::ethers::core::types::Address, + } + #[derive( + Clone, + ::ethers::contract::EthEvent, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethevent( + name = "DKIMPublicKeyHashRegistered", + abi = "DKIMPublicKeyHashRegistered(string,bytes32,address)" + )] + pub struct DkimpublicKeyHashRegisteredFilter { + #[ethevent(indexed)] + pub domain_name: ::ethers::core::types::H256, + #[ethevent(indexed)] + pub public_key_hash: [u8; 32], + #[ethevent(indexed)] + pub authorizer: ::ethers::core::types::Address, + } + #[derive( + Clone, + ::ethers::contract::EthEvent, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethevent( + name = "DKIMPublicKeyHashRevoked", + abi = "DKIMPublicKeyHashRevoked(bytes32,address)" + )] + pub struct DkimpublicKeyHashRevokedFilter { + #[ethevent(indexed)] + pub public_key_hash: [u8; 32], + #[ethevent(indexed)] + pub authorizer: ::ethers::core::types::Address, + } + #[derive( + Clone, + ::ethers::contract::EthEvent, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethevent(name = "Initialized", abi = "Initialized(uint64)")] + pub struct InitializedFilter { + pub version: u64, + } + #[derive( + Clone, + ::ethers::contract::EthEvent, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethevent(name = "MainAuthorizerChanged", abi = "MainAuthorizerChanged(address)")] + pub struct MainAuthorizerChangedFilter { + #[ethevent(indexed)] + pub new_main_authorizer: ::ethers::core::types::Address, + } + #[derive( + Clone, + ::ethers::contract::EthEvent, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethevent( + name = "OwnershipTransferred", + abi = "OwnershipTransferred(address,address)" + )] + pub struct OwnershipTransferredFilter { + #[ethevent(indexed)] + pub previous_owner: ::ethers::core::types::Address, + #[ethevent(indexed)] + pub new_owner: ::ethers::core::types::Address, + } + #[derive( + Clone, + ::ethers::contract::EthEvent, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethevent(name = "Upgraded", abi = "Upgraded(address)")] + pub struct UpgradedFilter { + #[ethevent(indexed)] + pub implementation: ::ethers::core::types::Address, + } + ///Container type for all of the contract's events + #[derive(Clone, ::ethers::contract::EthAbiType, Debug, PartialEq, Eq, Hash)] + pub enum UserOverridableDKIMRegistryEvents { + DkimpublicKeyHashReactivatedFilter(DkimpublicKeyHashReactivatedFilter), + DkimpublicKeyHashRegisteredFilter(DkimpublicKeyHashRegisteredFilter), + DkimpublicKeyHashRevokedFilter(DkimpublicKeyHashRevokedFilter), + InitializedFilter(InitializedFilter), + MainAuthorizerChangedFilter(MainAuthorizerChangedFilter), + OwnershipTransferredFilter(OwnershipTransferredFilter), + UpgradedFilter(UpgradedFilter), + } + impl ::ethers::contract::EthLogDecode for UserOverridableDKIMRegistryEvents { + fn decode_log( + log: &::ethers::core::abi::RawLog, + ) -> ::core::result::Result { + if let Ok(decoded) = DkimpublicKeyHashReactivatedFilter::decode_log(log) { + return Ok( + UserOverridableDKIMRegistryEvents::DkimpublicKeyHashReactivatedFilter( + decoded, + ), + ); + } + if let Ok(decoded) = DkimpublicKeyHashRegisteredFilter::decode_log(log) { + return Ok( + UserOverridableDKIMRegistryEvents::DkimpublicKeyHashRegisteredFilter( + decoded, + ), + ); + } + if let Ok(decoded) = DkimpublicKeyHashRevokedFilter::decode_log(log) { + return Ok( + UserOverridableDKIMRegistryEvents::DkimpublicKeyHashRevokedFilter( + decoded, + ), + ); + } + if let Ok(decoded) = InitializedFilter::decode_log(log) { + return Ok(UserOverridableDKIMRegistryEvents::InitializedFilter(decoded)); + } + if let Ok(decoded) = MainAuthorizerChangedFilter::decode_log(log) { + return Ok( + UserOverridableDKIMRegistryEvents::MainAuthorizerChangedFilter( + decoded, + ), + ); + } + if let Ok(decoded) = OwnershipTransferredFilter::decode_log(log) { + return Ok( + UserOverridableDKIMRegistryEvents::OwnershipTransferredFilter( + decoded, + ), + ); + } + if let Ok(decoded) = UpgradedFilter::decode_log(log) { + return Ok(UserOverridableDKIMRegistryEvents::UpgradedFilter(decoded)); + } + Err(::ethers::core::abi::Error::InvalidData) + } + } + impl ::core::fmt::Display for UserOverridableDKIMRegistryEvents { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + match self { + Self::DkimpublicKeyHashReactivatedFilter(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::DkimpublicKeyHashRegisteredFilter(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::DkimpublicKeyHashRevokedFilter(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::InitializedFilter(element) => ::core::fmt::Display::fmt(element, f), + Self::MainAuthorizerChangedFilter(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::OwnershipTransferredFilter(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::UpgradedFilter(element) => ::core::fmt::Display::fmt(element, f), + } + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryEvents { + fn from(value: DkimpublicKeyHashReactivatedFilter) -> Self { + Self::DkimpublicKeyHashReactivatedFilter(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryEvents { + fn from(value: DkimpublicKeyHashRegisteredFilter) -> Self { + Self::DkimpublicKeyHashRegisteredFilter(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryEvents { + fn from(value: DkimpublicKeyHashRevokedFilter) -> Self { + Self::DkimpublicKeyHashRevokedFilter(value) + } + } + impl ::core::convert::From for UserOverridableDKIMRegistryEvents { + fn from(value: InitializedFilter) -> Self { + Self::InitializedFilter(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryEvents { + fn from(value: MainAuthorizerChangedFilter) -> Self { + Self::MainAuthorizerChangedFilter(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryEvents { + fn from(value: OwnershipTransferredFilter) -> Self { + Self::OwnershipTransferredFilter(value) + } + } + impl ::core::convert::From for UserOverridableDKIMRegistryEvents { + fn from(value: UpgradedFilter) -> Self { + Self::UpgradedFilter(value) + } + } + ///Container type for all input parameters for the `REACTIVATE_PREFIX` function with signature `REACTIVATE_PREFIX()` and selector `0x225a08d4` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall(name = "REACTIVATE_PREFIX", abi = "REACTIVATE_PREFIX()")] + pub struct ReactivatePrefixCall; + ///Container type for all input parameters for the `REVOKE_PREFIX` function with signature `REVOKE_PREFIX()` and selector `0xd507c320` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall(name = "REVOKE_PREFIX", abi = "REVOKE_PREFIX()")] + pub struct RevokePrefixCall; + ///Container type for all input parameters for the `SET_PREFIX` function with signature `SET_PREFIX()` and selector `0x07f1eaf5` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall(name = "SET_PREFIX", abi = "SET_PREFIX()")] + pub struct SetPrefixCall; + ///Container type for all input parameters for the `UPGRADE_INTERFACE_VERSION` function with signature `UPGRADE_INTERFACE_VERSION()` and selector `0xad3cb1cc` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall(name = "UPGRADE_INTERFACE_VERSION", abi = "UPGRADE_INTERFACE_VERSION()")] + pub struct UpgradeInterfaceVersionCall; + ///Container type for all input parameters for the `changeMainAuthorizer` function with signature `changeMainAuthorizer(address)` and selector `0x4c930607` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall(name = "changeMainAuthorizer", abi = "changeMainAuthorizer(address)")] + pub struct ChangeMainAuthorizerCall { + pub new_main_authorizer: ::ethers::core::types::Address, + } + ///Container type for all input parameters for the `computeSignedMsg` function with signature `computeSignedMsg(string,string,bytes32)` and selector `0x4bcbbe96` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall( + name = "computeSignedMsg", + abi = "computeSignedMsg(string,string,bytes32)" + )] + pub struct ComputeSignedMsgCall { + pub prefix: ::std::string::String, + pub domain_name: ::std::string::String, + pub public_key_hash: [u8; 32], + } + ///Container type for all input parameters for the `dkimPublicKeyHashes` function with signature `dkimPublicKeyHashes(string,bytes32,address)` and selector `0xe308de0c` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall( + name = "dkimPublicKeyHashes", + abi = "dkimPublicKeyHashes(string,bytes32,address)" + )] + pub struct DkimPublicKeyHashesCall( + pub ::std::string::String, + pub [u8; 32], + pub ::ethers::core::types::Address, + ); + ///Container type for all input parameters for the `enabledTimeOfDKIMPublicKeyHash` function with signature `enabledTimeOfDKIMPublicKeyHash(bytes32)` and selector `0x7f8e29ba` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall( + name = "enabledTimeOfDKIMPublicKeyHash", + abi = "enabledTimeOfDKIMPublicKeyHash(bytes32)" + )] + pub struct EnabledTimeOfDKIMPublicKeyHashCall(pub [u8; 32]); + ///Container type for all input parameters for the `initialize` function with signature `initialize(address,address,uint256)` and selector `0x1794bb3c` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall(name = "initialize", abi = "initialize(address,address,uint256)")] + pub struct InitializeCall { + pub initial_owner: ::ethers::core::types::Address, + pub main_authorizer: ::ethers::core::types::Address, + pub set_timestamp_delay: ::ethers::core::types::U256, + } + ///Container type for all input parameters for the `isDKIMPublicKeyHashValid` function with signature `isDKIMPublicKeyHashValid(string,bytes32,address)` and selector `0x0b55b37c` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall( + name = "isDKIMPublicKeyHashValid", + abi = "isDKIMPublicKeyHashValid(string,bytes32,address)" + )] + pub struct IsDkimPublicKeyHashValidWithDomainNameAndPublicKeyHashCall { + pub domain_name: ::std::string::String, + pub public_key_hash: [u8; 32], + pub authorizer: ::ethers::core::types::Address, + } + ///Container type for all input parameters for the `isDKIMPublicKeyHashValid` function with signature `isDKIMPublicKeyHashValid(string,bytes32)` and selector `0xe7a7977a` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall( + name = "isDKIMPublicKeyHashValid", + abi = "isDKIMPublicKeyHashValid(string,bytes32)" + )] + pub struct IsDKIMPublicKeyHashValidCall { + pub domain_name: ::std::string::String, + pub public_key_hash: [u8; 32], + } + ///Container type for all input parameters for the `mainAuthorizer` function with signature `mainAuthorizer()` and selector `0x7d463648` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall(name = "mainAuthorizer", abi = "mainAuthorizer()")] + pub struct MainAuthorizerCall; + ///Container type for all input parameters for the `owner` function with signature `owner()` and selector `0x8da5cb5b` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall(name = "owner", abi = "owner()")] + pub struct OwnerCall; + ///Container type for all input parameters for the `proxiableUUID` function with signature `proxiableUUID()` and selector `0x52d1902d` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall(name = "proxiableUUID", abi = "proxiableUUID()")] + pub struct ProxiableUUIDCall; + ///Container type for all input parameters for the `reactivateDKIMPublicKeyHash` function with signature `reactivateDKIMPublicKeyHash(string,bytes32,address,bytes)` and selector `0x32e1e194` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall( + name = "reactivateDKIMPublicKeyHash", + abi = "reactivateDKIMPublicKeyHash(string,bytes32,address,bytes)" + )] + pub struct ReactivateDKIMPublicKeyHashCall { + pub domain_name: ::std::string::String, + pub public_key_hash: [u8; 32], + pub authorizer: ::ethers::core::types::Address, + pub signature: ::ethers::core::types::Bytes, + } + ///Container type for all input parameters for the `reactivatedDKIMPublicKeyHashes` function with signature `reactivatedDKIMPublicKeyHashes(bytes32,address)` and selector `0x574900dd` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall( + name = "reactivatedDKIMPublicKeyHashes", + abi = "reactivatedDKIMPublicKeyHashes(bytes32,address)" + )] + pub struct ReactivatedDKIMPublicKeyHashesCall( + pub [u8; 32], + pub ::ethers::core::types::Address, + ); + ///Container type for all input parameters for the `renounceOwnership` function with signature `renounceOwnership()` and selector `0x715018a6` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall(name = "renounceOwnership", abi = "renounceOwnership()")] + pub struct RenounceOwnershipCall; + ///Container type for all input parameters for the `revokeDKIMPublicKeyHash` function with signature `revokeDKIMPublicKeyHash(string,bytes32,address,bytes)` and selector `0x82bff8cd` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall( + name = "revokeDKIMPublicKeyHash", + abi = "revokeDKIMPublicKeyHash(string,bytes32,address,bytes)" + )] + pub struct RevokeDKIMPublicKeyHashCall { + pub domain_name: ::std::string::String, + pub public_key_hash: [u8; 32], + pub authorizer: ::ethers::core::types::Address, + pub signature: ::ethers::core::types::Bytes, + } + ///Container type for all input parameters for the `revokedDKIMPublicKeyHashes` function with signature `revokedDKIMPublicKeyHashes(bytes32,address)` and selector `0xf0bfb197` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall( + name = "revokedDKIMPublicKeyHashes", + abi = "revokedDKIMPublicKeyHashes(bytes32,address)" + )] + pub struct RevokedDKIMPublicKeyHashesCall( + pub [u8; 32], + pub ::ethers::core::types::Address, + ); + ///Container type for all input parameters for the `setDKIMPublicKeyHash` function with signature `setDKIMPublicKeyHash(string,bytes32,address,bytes)` and selector `0x614a4485` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall( + name = "setDKIMPublicKeyHash", + abi = "setDKIMPublicKeyHash(string,bytes32,address,bytes)" + )] + pub struct SetDKIMPublicKeyHashCall { + pub domain_name: ::std::string::String, + pub public_key_hash: [u8; 32], + pub authorizer: ::ethers::core::types::Address, + pub signature: ::ethers::core::types::Bytes, + } + ///Container type for all input parameters for the `setDKIMPublicKeyHashes` function with signature `setDKIMPublicKeyHashes(string[],bytes32[],address[],bytes[])` and selector `0x7ff103da` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall( + name = "setDKIMPublicKeyHashes", + abi = "setDKIMPublicKeyHashes(string[],bytes32[],address[],bytes[])" + )] + pub struct SetDKIMPublicKeyHashesCall { + pub domain_names: ::std::vec::Vec<::std::string::String>, + pub public_key_hashes: ::std::vec::Vec<[u8; 32]>, + pub authorizers: ::std::vec::Vec<::ethers::core::types::Address>, + pub signatures: ::std::vec::Vec<::ethers::core::types::Bytes>, + } + ///Container type for all input parameters for the `setTimestampDelay` function with signature `setTimestampDelay()` and selector `0x812e12ce` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall(name = "setTimestampDelay", abi = "setTimestampDelay()")] + pub struct SetTimestampDelayCall; + ///Container type for all input parameters for the `transferOwnership` function with signature `transferOwnership(address)` and selector `0xf2fde38b` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall(name = "transferOwnership", abi = "transferOwnership(address)")] + pub struct TransferOwnershipCall { + pub new_owner: ::ethers::core::types::Address, + } + ///Container type for all input parameters for the `upgradeToAndCall` function with signature `upgradeToAndCall(address,bytes)` and selector `0x4f1ef286` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + #[ethcall(name = "upgradeToAndCall", abi = "upgradeToAndCall(address,bytes)")] + pub struct UpgradeToAndCallCall { + pub new_implementation: ::ethers::core::types::Address, + pub data: ::ethers::core::types::Bytes, + } + ///Container type for all of the contract's call + #[derive(Clone, ::ethers::contract::EthAbiType, Debug, PartialEq, Eq, Hash)] + pub enum UserOverridableDKIMRegistryCalls { + ReactivatePrefix(ReactivatePrefixCall), + RevokePrefix(RevokePrefixCall), + SetPrefix(SetPrefixCall), + UpgradeInterfaceVersion(UpgradeInterfaceVersionCall), + ChangeMainAuthorizer(ChangeMainAuthorizerCall), + ComputeSignedMsg(ComputeSignedMsgCall), + DkimPublicKeyHashes(DkimPublicKeyHashesCall), + EnabledTimeOfDKIMPublicKeyHash(EnabledTimeOfDKIMPublicKeyHashCall), + Initialize(InitializeCall), + IsDkimPublicKeyHashValidWithDomainNameAndPublicKeyHash( + IsDkimPublicKeyHashValidWithDomainNameAndPublicKeyHashCall, + ), + IsDKIMPublicKeyHashValid(IsDKIMPublicKeyHashValidCall), + MainAuthorizer(MainAuthorizerCall), + Owner(OwnerCall), + ProxiableUUID(ProxiableUUIDCall), + ReactivateDKIMPublicKeyHash(ReactivateDKIMPublicKeyHashCall), + ReactivatedDKIMPublicKeyHashes(ReactivatedDKIMPublicKeyHashesCall), + RenounceOwnership(RenounceOwnershipCall), + RevokeDKIMPublicKeyHash(RevokeDKIMPublicKeyHashCall), + RevokedDKIMPublicKeyHashes(RevokedDKIMPublicKeyHashesCall), + SetDKIMPublicKeyHash(SetDKIMPublicKeyHashCall), + SetDKIMPublicKeyHashes(SetDKIMPublicKeyHashesCall), + SetTimestampDelay(SetTimestampDelayCall), + TransferOwnership(TransferOwnershipCall), + UpgradeToAndCall(UpgradeToAndCallCall), + } + impl ::ethers::core::abi::AbiDecode for UserOverridableDKIMRegistryCalls { + fn decode( + data: impl AsRef<[u8]>, + ) -> ::core::result::Result { + let data = data.as_ref(); + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::ReactivatePrefix(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::RevokePrefix(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::SetPrefix(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::UpgradeInterfaceVersion(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::ChangeMainAuthorizer(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::ComputeSignedMsg(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::DkimPublicKeyHashes(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::EnabledTimeOfDKIMPublicKeyHash(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::Initialize(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok( + Self::IsDkimPublicKeyHashValidWithDomainNameAndPublicKeyHash(decoded), + ); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::IsDKIMPublicKeyHashValid(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::MainAuthorizer(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::Owner(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::ProxiableUUID(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::ReactivateDKIMPublicKeyHash(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::ReactivatedDKIMPublicKeyHashes(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::RenounceOwnership(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::RevokeDKIMPublicKeyHash(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::RevokedDKIMPublicKeyHashes(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::SetDKIMPublicKeyHash(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::SetDKIMPublicKeyHashes(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::SetTimestampDelay(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::TransferOwnership(decoded)); + } + if let Ok(decoded) = ::decode( + data, + ) { + return Ok(Self::UpgradeToAndCall(decoded)); + } + Err(::ethers::core::abi::Error::InvalidData.into()) + } + } + impl ::ethers::core::abi::AbiEncode for UserOverridableDKIMRegistryCalls { + fn encode(self) -> Vec { + match self { + Self::ReactivatePrefix(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::RevokePrefix(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::SetPrefix(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::UpgradeInterfaceVersion(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::ChangeMainAuthorizer(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::ComputeSignedMsg(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::DkimPublicKeyHashes(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::EnabledTimeOfDKIMPublicKeyHash(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::Initialize(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::IsDkimPublicKeyHashValidWithDomainNameAndPublicKeyHash(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::IsDKIMPublicKeyHashValid(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::MainAuthorizer(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::Owner(element) => ::ethers::core::abi::AbiEncode::encode(element), + Self::ProxiableUUID(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::ReactivateDKIMPublicKeyHash(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::ReactivatedDKIMPublicKeyHashes(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::RenounceOwnership(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::RevokeDKIMPublicKeyHash(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::RevokedDKIMPublicKeyHashes(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::SetDKIMPublicKeyHash(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::SetDKIMPublicKeyHashes(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::SetTimestampDelay(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::TransferOwnership(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + Self::UpgradeToAndCall(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } + } + } + } + impl ::core::fmt::Display for UserOverridableDKIMRegistryCalls { + fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + match self { + Self::ReactivatePrefix(element) => ::core::fmt::Display::fmt(element, f), + Self::RevokePrefix(element) => ::core::fmt::Display::fmt(element, f), + Self::SetPrefix(element) => ::core::fmt::Display::fmt(element, f), + Self::UpgradeInterfaceVersion(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::ChangeMainAuthorizer(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::ComputeSignedMsg(element) => ::core::fmt::Display::fmt(element, f), + Self::DkimPublicKeyHashes(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::EnabledTimeOfDKIMPublicKeyHash(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::Initialize(element) => ::core::fmt::Display::fmt(element, f), + Self::IsDkimPublicKeyHashValidWithDomainNameAndPublicKeyHash(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::IsDKIMPublicKeyHashValid(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::MainAuthorizer(element) => ::core::fmt::Display::fmt(element, f), + Self::Owner(element) => ::core::fmt::Display::fmt(element, f), + Self::ProxiableUUID(element) => ::core::fmt::Display::fmt(element, f), + Self::ReactivateDKIMPublicKeyHash(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::ReactivatedDKIMPublicKeyHashes(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::RenounceOwnership(element) => ::core::fmt::Display::fmt(element, f), + Self::RevokeDKIMPublicKeyHash(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::RevokedDKIMPublicKeyHashes(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::SetDKIMPublicKeyHash(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::SetDKIMPublicKeyHashes(element) => { + ::core::fmt::Display::fmt(element, f) + } + Self::SetTimestampDelay(element) => ::core::fmt::Display::fmt(element, f), + Self::TransferOwnership(element) => ::core::fmt::Display::fmt(element, f), + Self::UpgradeToAndCall(element) => ::core::fmt::Display::fmt(element, f), + } + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: ReactivatePrefixCall) -> Self { + Self::ReactivatePrefix(value) + } + } + impl ::core::convert::From for UserOverridableDKIMRegistryCalls { + fn from(value: RevokePrefixCall) -> Self { + Self::RevokePrefix(value) + } + } + impl ::core::convert::From for UserOverridableDKIMRegistryCalls { + fn from(value: SetPrefixCall) -> Self { + Self::SetPrefix(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: UpgradeInterfaceVersionCall) -> Self { + Self::UpgradeInterfaceVersion(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: ChangeMainAuthorizerCall) -> Self { + Self::ChangeMainAuthorizer(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: ComputeSignedMsgCall) -> Self { + Self::ComputeSignedMsg(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: DkimPublicKeyHashesCall) -> Self { + Self::DkimPublicKeyHashes(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: EnabledTimeOfDKIMPublicKeyHashCall) -> Self { + Self::EnabledTimeOfDKIMPublicKeyHash(value) + } + } + impl ::core::convert::From for UserOverridableDKIMRegistryCalls { + fn from(value: InitializeCall) -> Self { + Self::Initialize(value) + } + } + impl ::core::convert::From< + IsDkimPublicKeyHashValidWithDomainNameAndPublicKeyHashCall, + > for UserOverridableDKIMRegistryCalls { + fn from( + value: IsDkimPublicKeyHashValidWithDomainNameAndPublicKeyHashCall, + ) -> Self { + Self::IsDkimPublicKeyHashValidWithDomainNameAndPublicKeyHash(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: IsDKIMPublicKeyHashValidCall) -> Self { + Self::IsDKIMPublicKeyHashValid(value) + } + } + impl ::core::convert::From for UserOverridableDKIMRegistryCalls { + fn from(value: MainAuthorizerCall) -> Self { + Self::MainAuthorizer(value) + } + } + impl ::core::convert::From for UserOverridableDKIMRegistryCalls { + fn from(value: OwnerCall) -> Self { + Self::Owner(value) + } + } + impl ::core::convert::From for UserOverridableDKIMRegistryCalls { + fn from(value: ProxiableUUIDCall) -> Self { + Self::ProxiableUUID(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: ReactivateDKIMPublicKeyHashCall) -> Self { + Self::ReactivateDKIMPublicKeyHash(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: ReactivatedDKIMPublicKeyHashesCall) -> Self { + Self::ReactivatedDKIMPublicKeyHashes(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: RenounceOwnershipCall) -> Self { + Self::RenounceOwnership(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: RevokeDKIMPublicKeyHashCall) -> Self { + Self::RevokeDKIMPublicKeyHash(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: RevokedDKIMPublicKeyHashesCall) -> Self { + Self::RevokedDKIMPublicKeyHashes(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: SetDKIMPublicKeyHashCall) -> Self { + Self::SetDKIMPublicKeyHash(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: SetDKIMPublicKeyHashesCall) -> Self { + Self::SetDKIMPublicKeyHashes(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: SetTimestampDelayCall) -> Self { + Self::SetTimestampDelay(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: TransferOwnershipCall) -> Self { + Self::TransferOwnership(value) + } + } + impl ::core::convert::From + for UserOverridableDKIMRegistryCalls { + fn from(value: UpgradeToAndCallCall) -> Self { + Self::UpgradeToAndCall(value) + } + } + ///Container type for all return fields from the `REACTIVATE_PREFIX` function with signature `REACTIVATE_PREFIX()` and selector `0x225a08d4` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + pub struct ReactivatePrefixReturn(pub ::std::string::String); + ///Container type for all return fields from the `REVOKE_PREFIX` function with signature `REVOKE_PREFIX()` and selector `0xd507c320` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + pub struct RevokePrefixReturn(pub ::std::string::String); + ///Container type for all return fields from the `SET_PREFIX` function with signature `SET_PREFIX()` and selector `0x07f1eaf5` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + pub struct SetPrefixReturn(pub ::std::string::String); + ///Container type for all return fields from the `UPGRADE_INTERFACE_VERSION` function with signature `UPGRADE_INTERFACE_VERSION()` and selector `0xad3cb1cc` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + pub struct UpgradeInterfaceVersionReturn(pub ::std::string::String); + ///Container type for all return fields from the `computeSignedMsg` function with signature `computeSignedMsg(string,string,bytes32)` and selector `0x4bcbbe96` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + pub struct ComputeSignedMsgReturn(pub ::std::string::String); + ///Container type for all return fields from the `dkimPublicKeyHashes` function with signature `dkimPublicKeyHashes(string,bytes32,address)` and selector `0xe308de0c` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + pub struct DkimPublicKeyHashesReturn(pub bool); + ///Container type for all return fields from the `enabledTimeOfDKIMPublicKeyHash` function with signature `enabledTimeOfDKIMPublicKeyHash(bytes32)` and selector `0x7f8e29ba` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + pub struct EnabledTimeOfDKIMPublicKeyHashReturn(pub ::ethers::core::types::U256); + ///Container type for all return fields from the `isDKIMPublicKeyHashValid` function with signature `isDKIMPublicKeyHashValid(string,bytes32,address)` and selector `0x0b55b37c` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + pub struct IsDkimPublicKeyHashValidWithDomainNameAndPublicKeyHashReturn(pub bool); + ///Container type for all return fields from the `isDKIMPublicKeyHashValid` function with signature `isDKIMPublicKeyHashValid(string,bytes32)` and selector `0xe7a7977a` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + pub struct IsDKIMPublicKeyHashValidReturn(pub bool); + ///Container type for all return fields from the `mainAuthorizer` function with signature `mainAuthorizer()` and selector `0x7d463648` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + pub struct MainAuthorizerReturn(pub ::ethers::core::types::Address); + ///Container type for all return fields from the `owner` function with signature `owner()` and selector `0x8da5cb5b` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + pub struct OwnerReturn(pub ::ethers::core::types::Address); + ///Container type for all return fields from the `proxiableUUID` function with signature `proxiableUUID()` and selector `0x52d1902d` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + pub struct ProxiableUUIDReturn(pub [u8; 32]); + ///Container type for all return fields from the `reactivatedDKIMPublicKeyHashes` function with signature `reactivatedDKIMPublicKeyHashes(bytes32,address)` and selector `0x574900dd` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + pub struct ReactivatedDKIMPublicKeyHashesReturn(pub bool); + ///Container type for all return fields from the `revokedDKIMPublicKeyHashes` function with signature `revokedDKIMPublicKeyHashes(bytes32,address)` and selector `0xf0bfb197` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + pub struct RevokedDKIMPublicKeyHashesReturn(pub bool); + ///Container type for all return fields from the `setTimestampDelay` function with signature `setTimestampDelay()` and selector `0x812e12ce` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + Default, + Debug, + PartialEq, + Eq, + Hash + )] + pub struct SetTimestampDelayReturn(pub ::ethers::core::types::U256); +} diff --git a/packages/relayer/src/chain.rs b/packages/relayer/src/chain.rs index 21f2ff70..004a250f 100644 --- a/packages/relayer/src/chain.rs +++ b/packages/relayer/src/chain.rs @@ -4,22 +4,29 @@ use ethers::middleware::Middleware; use ethers::prelude::*; use ethers::signers::Signer; use relayer_utils::converters::u64_to_u8_array_32; -use relayer_utils::LOG; +use relayer_utils::TemplateValue; const CONFIRMATIONS: usize = 1; type SignerM = SignerMiddleware, LocalWallet>; +/// Represents a client for interacting with the blockchain. #[derive(Debug, Clone)] pub struct ChainClient { pub client: Arc, } impl ChainClient { + /// Sets up a new ChainClient. + /// + /// # Returns + /// + /// A `Result` containing the new `ChainClient` if successful, or an error if not. pub async fn setup() -> Result { let wallet: LocalWallet = PRIVATE_KEY.get().unwrap().parse()?; let provider = Provider::::try_from(CHAIN_RPC_PROVIDER.get().unwrap())?; + // Create a new SignerMiddleware with the provider and wallet let client = Arc::new(SignerMiddleware::new( provider, wallet.with_chain_id(*CHAIN_ID.get().unwrap()), @@ -28,75 +35,150 @@ impl ChainClient { Ok(Self { client }) } + /// Sets the DKIM public key hash. + /// + /// # Arguments + /// + /// * `selector` - The selector string. + /// * `domain_name` - The domain name. + /// * `public_key_hash` - The public key hash as a 32-byte array. + /// * `signature` - The signature as Bytes. + /// * `dkim` - The ECDSA Owned DKIM Registry. + /// + /// # Returns + /// + /// A `Result` containing the transaction hash as a String if successful, or an error if not. pub async fn set_dkim_public_key_hash( &self, - selector: String, domain_name: String, public_key_hash: [u8; 32], signature: Bytes, - dkim: ECDSAOwnedDKIMRegistry, + dkim: UserOverridableDKIMRegistry, ) -> Result { // Mutex is used to prevent nonce conflicts. let mut mutex = SHARED_MUTEX.lock().await; *mutex += 1; - let call = dkim.set_dkim_public_key_hash(selector, domain_name, public_key_hash, signature); + let main_authorizer = dkim.main_authorizer().call().await?; + let call = + dkim.set_dkim_public_key_hash(domain_name, public_key_hash, main_authorizer, signature); let tx = call.send().await?; + + // Wait for the transaction to be confirmed let receipt = tx .log() .confirmations(CONFIRMATIONS) .await? .ok_or(anyhow!("No receipt"))?; + + // Format the transaction hash let tx_hash = receipt.transaction_hash; let tx_hash = format!("0x{}", hex::encode(tx_hash.as_bytes())); Ok(tx_hash) } + /// Checks if a DKIM public key hash is valid. + /// + /// # Arguments + /// + /// * `domain_name` - The domain name. + /// * `public_key_hash` - The public key hash as a 32-byte array. + /// * `dkim` - The ECDSA Owned DKIM Registry. + /// + /// # Returns + /// + /// A `Result` containing a boolean indicating if the hash is valid. pub async fn check_if_dkim_public_key_hash_valid( &self, domain_name: ::std::string::String, public_key_hash: [u8; 32], - dkim: ECDSAOwnedDKIMRegistry, + dkim: UserOverridableDKIMRegistry, ) -> Result { - let is_valid = dkim - .is_dkim_public_key_hash_valid(domain_name, public_key_hash) + // Call the contract method to check if the hash is valid + let main_authorizer = dkim.main_authorizer().call().await?; + let is_set = dkim + .dkim_public_key_hashes(domain_name, public_key_hash, main_authorizer) .call() .await?; - Ok(is_valid) + Ok(is_set) } - pub async fn get_dkim_from_wallet( + /// Gets the DKIM from a controller. + /// + /// # Arguments + /// + /// * `controller_eth_addr` - The controller Ethereum address as a string. + /// + /// # Returns + /// + /// A `Result` containing the ECDSA Owned DKIM Registry if successful, or an error if not. + pub async fn get_dkim_from_controller( &self, - controller_eth_addr: &String, - ) -> Result, anyhow::Error> { + controller_eth_addr: &str, + ) -> Result, anyhow::Error> { let controller_eth_addr: H160 = controller_eth_addr.parse()?; + + // Create a new EmailAccountRecovery contract instance let contract = EmailAccountRecovery::new(controller_eth_addr, self.client.clone()); + + // Call the dkim method to get the DKIM registry address let dkim = contract.dkim().call().await?; - Ok(ECDSAOwnedDKIMRegistry::new(dkim, self.client.clone())) + Ok(UserOverridableDKIMRegistry::new(dkim, self.client.clone())) } + /// Gets the DKIM from an email auth address. + /// + /// # Arguments + /// + /// * `email_auth_addr` - The email auth address as a string. + /// + /// # Returns + /// + /// A `Result` containing the ECDSA Owned DKIM Registry if successful, or an error if not. pub async fn get_dkim_from_email_auth( &self, - email_auth_addr: &String, - ) -> Result, anyhow::Error> { + email_auth_addr: &str, + ) -> Result, anyhow::Error> { let email_auth_address: H160 = email_auth_addr.parse()?; + + // Create a new EmailAuth contract instance let contract = EmailAuth::new(email_auth_address, self.client.clone()); + + // Call the dkim_registry_addr method to get the DKIM registry address let dkim = contract.dkim_registry_addr().call().await?; - Ok(ECDSAOwnedDKIMRegistry::new(dkim, self.client.clone())) + Ok(UserOverridableDKIMRegistry::new(dkim, self.client.clone())) } + /// Gets the email auth address from a wallet. + /// + /// # Arguments + /// + /// * `controller_eth_addr` - The controller Ethereum address as a string. + /// * `wallet_addr` - The wallet address as a string. + /// * `account_salt` - The account salt as a string. + /// + /// # Returns + /// + /// A `Result` containing the email auth address as H160 if successful, or an error if not. pub async fn get_email_auth_addr_from_wallet( &self, - controller_eth_addr: &String, - wallet_addr: &String, - account_salt: &String, + controller_eth_addr: &str, + wallet_addr: &str, + account_salt: &str, ) -> Result { + // Parse the controller and wallet Ethereum addresses let controller_eth_addr: H160 = controller_eth_addr.parse()?; let wallet_address: H160 = wallet_addr.parse()?; + + // Create a new EmailAccountRecovery contract instance let contract = EmailAccountRecovery::new(controller_eth_addr, self.client.clone()); + + // Decode the account salt let account_salt_bytes = hex::decode(account_salt.trim_start_matches("0x")) .map_err(|e| anyhow!("Failed to decode account_salt: {}", e))?; + + // Compute the email auth address let email_auth_addr = contract .compute_email_auth_address( wallet_address, @@ -108,197 +190,432 @@ impl ChainClient { Ok(email_auth_addr) } - pub async fn is_wallet_deployed(&self, wallet_addr_str: &String) -> bool { - let wallet_addr: H160 = wallet_addr_str.parse().unwrap(); + /// Checks if a wallet is deployed. + /// + /// # Arguments + /// + /// * `wallet_addr_str` - The wallet address as a string. + /// + /// # Returns + /// + /// A `Result` containing a boolean indicating if the wallet is deployed. + pub async fn is_wallet_deployed(&self, wallet_addr_str: &str) -> Result { + // Parse the wallet address + let wallet_addr: H160 = wallet_addr_str.parse().map_err(ChainError::HexError)?; + + // Get the bytecode at the wallet address match self.client.get_code(wallet_addr, None).await { - Ok(code) => !code.is_empty(), + Ok(code) => Ok(!code.is_empty()), Err(e) => { // Log the error or handle it as needed - error!(LOG, "Error querying contract code: {:?}", e); - false + Err(ChainError::signer_middleware_error( + "Failed to check if wallet is deployed", + e, + )) } } } - pub async fn get_acceptance_subject_templates( + /// Gets the acceptance command templates. + /// + /// # Arguments + /// + /// * `controller_eth_addr` - The controller Ethereum address as a string. + /// * `template_idx` - The template index. + /// + /// # Returns + /// + /// A `Result` containing a vector of acceptance command templates. + pub async fn get_acceptance_command_templates( &self, - controller_eth_addr: &String, + controller_eth_addr: &str, template_idx: u64, - ) -> Result, anyhow::Error> { - let controller_eth_addr: H160 = controller_eth_addr.parse()?; + ) -> Result, ChainError> { + // Parse the controller Ethereum address + let controller_eth_addr: H160 = + controller_eth_addr.parse().map_err(ChainError::HexError)?; + + // Create a new EmailAccountRecovery contract instance let contract = EmailAccountRecovery::new(controller_eth_addr, self.client.clone()); + + // Get the acceptance command templates let templates = contract - .acceptance_subject_templates() + .acceptance_command_templates() .call() .await - .map_err(|e| anyhow::Error::from(e))?; + .map_err(|e| { + ChainError::contract_error("Failed to get acceptance subject templates", e) + })?; Ok(templates[template_idx as usize].clone()) } - pub async fn get_recovery_subject_templates( + /// Gets the recovery command templates. + /// + /// # Arguments + /// + /// * `controller_eth_addr` - The controller Ethereum address as a string. + /// * `template_idx` - The template index. + /// + /// # Returns + /// + /// A `Result` containing a vector of recovery command templates. + pub async fn get_recovery_command_templates( &self, - controller_eth_addr: &String, + controller_eth_addr: &str, template_idx: u64, - ) -> Result, anyhow::Error> { - let controller_eth_addr: H160 = controller_eth_addr.parse()?; + ) -> Result, ChainError> { + // Parse the controller Ethereum address + let controller_eth_addr: H160 = + controller_eth_addr.parse().map_err(ChainError::HexError)?; + + // Create a new EmailAccountRecovery contract instance let contract = EmailAccountRecovery::new(controller_eth_addr, self.client.clone()); + + // Get the recovery command templates let templates = contract - .recovery_subject_templates() + .recovery_command_templates() .call() .await - .map_err(|e| anyhow::Error::from(e))?; + .map_err(|e| { + ChainError::contract_error("Failed to get recovery command templates", e) + })?; Ok(templates[template_idx as usize].clone()) } + /// Completes the recovery process. + /// + /// # Arguments + /// + /// * `controller_eth_addr` - The controller Ethereum address as a string. + /// * `account_eth_addr` - The account Ethereum address as a string. + /// * `complete_calldata` - The complete calldata as a string. + /// + /// # Returns + /// + /// A `Result` containing a boolean indicating if the recovery was successful. pub async fn complete_recovery( &self, - controller_eth_addr: &String, - account_eth_addr: &String, - complete_calldata: &String, - ) -> Result { - let controller_eth_addr: H160 = controller_eth_addr.parse()?; + controller_eth_addr: &str, + account_eth_addr: &str, + complete_calldata: &str, + ) -> Result { + // Parse the controller and account Ethereum addresses + let controller_eth_addr: H160 = + controller_eth_addr.parse().map_err(ChainError::HexError)?; + + // Create a new EmailAccountRecovery contract instance let contract = EmailAccountRecovery::new(controller_eth_addr, self.client.clone()); + + // Decode the complete calldata let decoded_calldata = - hex::decode(&complete_calldata.trim_start_matches("0x")).expect("Decoding failed"); - let call = contract.complete_recovery( - account_eth_addr - .parse::() - .expect("Invalid H160 address"), - Bytes::from(decoded_calldata), - ); - let tx = call.send().await?; - // If the transaction is successful, the function will return true and false otherwise. + hex::decode(complete_calldata.trim_start_matches("0x")).expect("Decoding failed"); + + let account_eth_addr = account_eth_addr + .parse::() + .map_err(ChainError::HexError)?; + + // Call the complete_recovery method + let call = contract.complete_recovery(account_eth_addr, Bytes::from(decoded_calldata)); + + let tx = call + .send() + .await + .map_err(|e| ChainError::contract_error("Failed to call complete_recovery", e))?; + + // Wait for the transaction to be confirmed let receipt = tx .log() .confirmations(CONFIRMATIONS) - .await? + .await + .map_err(|e| { + ChainError::provider_error( + "Failed to get receipt after calling complete_recovery", + e, + ) + })? .ok_or(anyhow!("No receipt"))?; + + // Check if the transaction was successful Ok(receipt .status .map(|status| status == U64::from(1)) .unwrap_or(false)) } + /// Handles the acceptance process. + /// + /// # Arguments + /// + /// * `controller_eth_addr` - The controller Ethereum address as a string. + /// * `email_auth_msg` - The email authentication message. + /// * `template_idx` - The template index. + /// + /// # Returns + /// + /// A `Result` containing a boolean indicating if the acceptance was successful. pub async fn handle_acceptance( &self, - controller_eth_addr: &String, + controller_eth_addr: &str, email_auth_msg: EmailAuthMsg, template_idx: u64, - ) -> Result { + ) -> std::result::Result { + // Parse the controller Ethereum address let controller_eth_addr: H160 = controller_eth_addr.parse()?; + + // Create a new EmailAccountRecovery contract instance let contract = EmailAccountRecovery::new(controller_eth_addr, self.client.clone()); + + // Call the handle_acceptance method let call = contract.handle_acceptance(email_auth_msg, template_idx.into()); - let tx = call.send().await?; - // If the transaction is successful, the function will return true and false otherwise. + let tx = call + .send() + .await + .map_err(|e| ChainError::contract_error("Failed to call handle_acceptance", e))?; + + // Wait for the transaction to be confirmed let receipt = tx .log() .confirmations(CONFIRMATIONS) - .await? + .await + .map_err(|e| { + ChainError::provider_error( + "Failed to get receipt after calling handle_acceptance", + e, + ) + })? .ok_or(anyhow!("No receipt"))?; + + // Check if the transaction was successful Ok(receipt .status .map(|status| status == U64::from(1)) .unwrap_or(false)) } + /// Handles the recovery process. + /// + /// # Arguments + /// + /// * `controller_eth_addr` - The controller Ethereum address as a string. + /// * `email_auth_msg` - The email authentication message. + /// * `template_idx` - The template index. + /// + /// # Returns + /// + /// A `Result` containing a boolean indicating if the recovery was successful. pub async fn handle_recovery( &self, - controller_eth_addr: &String, + controller_eth_addr: &str, email_auth_msg: EmailAuthMsg, template_idx: u64, - ) -> Result { + ) -> std::result::Result { + // Parse the controller Ethereum address let controller_eth_addr: H160 = controller_eth_addr.parse()?; + + // Create a new EmailAccountRecovery contract instance let contract = EmailAccountRecovery::new(controller_eth_addr, self.client.clone()); + + // Call the handle_recovery method let call = contract.handle_recovery(email_auth_msg, template_idx.into()); - let tx = call.send().await?; - // If the transaction is successful, the function will return true and false otherwise. + let tx = call + .send() + .await + .map_err(|e| ChainError::contract_error("Failed to call handle_recovery", e))?; + + // Wait for the transaction to be confirmed let receipt = tx .log() .confirmations(CONFIRMATIONS) - .await? + .await + .map_err(|e| { + ChainError::provider_error("Failed to get receipt after calling handle_recovery", e) + })? .ok_or(anyhow!("No receipt"))?; + + // Check if the transaction was successful Ok(receipt .status .map(|status| status == U64::from(1)) .unwrap_or(false)) } - pub async fn get_bytecode(&self, wallet_addr: &String) -> Result { - let wallet_address: H160 = wallet_addr.parse()?; - Ok(self.client.get_code(wallet_address, None).await?) + /// Gets the bytecode of a wallet. + /// + /// # Arguments + /// + /// * `wallet_addr` - The wallet address as a string. + /// + /// # Returns + /// + /// A `Result` containing the bytecode as Bytes. + pub async fn get_bytecode(&self, wallet_addr: &str) -> std::result::Result { + // Parse the wallet address + let wallet_address: H160 = wallet_addr.parse().map_err(ChainError::HexError)?; + + // Get the bytecode at the wallet address + let client_code = self + .client + .get_code(wallet_address, None) + .await + .map_err(|e| ChainError::signer_middleware_error("Failed to get bytecode", e))?; + Ok(client_code) } + /// Gets the storage at a specific slot for a wallet. + /// + /// # Arguments + /// + /// * `wallet_addr` - The wallet address as a string. + /// * `slot` - The storage slot. + /// + /// # Returns + /// + /// A `Result` containing the storage value as H256. pub async fn get_storage_at( &self, - wallet_addr: &String, + wallet_addr: &str, slot: u64, ) -> Result { + // Parse the wallet address let wallet_address: H160 = wallet_addr.parse()?; + + // Get the storage at the specified slot Ok(self .client .get_storage_at(wallet_address, u64_to_u8_array_32(slot).into(), None) .await?) } - pub async fn get_recovered_account_from_acceptance_subject( + /// Gets the recovered account from an acceptance command. + /// + /// # Arguments + /// + /// * `controller_eth_addr` - The controller Ethereum address as a string. + /// * `command_params` - The command parameters. + /// * `template_idx` - The template index. + /// + /// # Returns + /// + /// A `Result` containing the recovered account address as H160. + pub async fn get_recovered_account_from_acceptance_command( &self, - controller_eth_addr: &String, - subject_params: Vec, + controller_eth_addr: &str, + command_params: Vec, template_idx: u64, - ) -> Result { - let controller_eth_addr: H160 = controller_eth_addr.parse()?; + ) -> Result { + // Parse the controller Ethereum address + let controller_eth_addr: H160 = + controller_eth_addr.parse().map_err(ChainError::HexError)?; + + // Create a new EmailAccountRecovery contract instance let contract = EmailAccountRecovery::new(controller_eth_addr, self.client.clone()); - let subject_params_bytes = subject_params - .iter() // Change here: use iter() instead of map() directly on Vec + + // Encode the command parameters + let command_params_bytes = command_params + .iter() .map(|s| { - s.abi_encode(None) // Assuming decimal_size is not needed or can be None + s.abi_encode(None) .unwrap_or_else(|_| Bytes::from("Error encoding".as_bytes().to_vec())) - }) // Error handling + }) .collect::>(); + + // Call the extract_recovered_account_from_acceptance_command method let recovered_account = contract - .extract_recovered_account_from_acceptance_subject( - subject_params_bytes, + .extract_recovered_account_from_acceptance_command( + command_params_bytes, template_idx.into(), ) .call() - .await?; + .await + .map_err(|e| { + ChainError::contract_error( + "Failed to get recovered account from acceptance subject", + e, + ) + })?; Ok(recovered_account) } - pub async fn get_recovered_account_from_recovery_subject( + /// Gets the recovered account from a recovery command. + /// + /// # Arguments + /// + /// * `controller_eth_addr` - The controller Ethereum address as a string. + /// * `command_params` - The command parameters. + /// * `template_idx` - The template index. + /// + /// # Returns + /// + /// A `Result` containing the recovered account address as H160. + pub async fn get_recovered_account_from_recovery_command( &self, - controller_eth_addr: &String, - subject_params: Vec, + controller_eth_addr: &str, + command_params: Vec, template_idx: u64, - ) -> Result { - let controller_eth_addr: H160 = controller_eth_addr.parse()?; + ) -> Result { + // Parse the controller Ethereum address + let controller_eth_addr: H160 = + controller_eth_addr.parse().map_err(ChainError::HexError)?; + + // Create a new EmailAccountRecovery contract instance let contract = EmailAccountRecovery::new(controller_eth_addr, self.client.clone()); - let subject_params_bytes = subject_params - .iter() // Change here: use iter() instead of map() directly on Vec + + // Encode the command parameters + let command_params_bytes = command_params + .iter() .map(|s| { - s.abi_encode(None) // Assuming decimal_size is not needed or can be None - .unwrap_or_else(|_| Bytes::from("Error encoding".as_bytes().to_vec())) - }) // Error handling - .collect::>(); + s.abi_encode(None).map_err(|_| { + ChainError::Validation("Error encoding subject parameters".to_string()) + }) + }) + .collect::, ChainError>>()?; + + // Call the extract_recovered_account_from_recovery_command method let recovered_account = contract - .extract_recovered_account_from_recovery_subject( - subject_params_bytes, + .extract_recovered_account_from_recovery_command( + command_params_bytes, template_idx.into(), ) .call() - .await?; + .await + .map_err(|e| { + ChainError::contract_error( + "Failed to get recovered account from recovery subject", + e, + ) + })?; Ok(recovered_account) } + /// Checks if an account is activated. + /// + /// # Arguments + /// + /// * `controller_eth_addr` - The controller Ethereum address as a string. + /// * `account_eth_addr` - The account Ethereum address as a string. + /// + /// # Returns + /// + /// A `Result` containing a boolean indicating if the account is activated. pub async fn get_is_activated( &self, - controller_eth_addr: &String, - account_eth_addr: &String, - ) -> Result { - let controller_eth_addr: H160 = controller_eth_addr.parse()?; - let account_eth_addr: H160 = account_eth_addr.parse()?; + controller_eth_addr: &str, + account_eth_addr: &str, + ) -> Result { + // Parse the controller and account Ethereum addresses + let controller_eth_addr: H160 = + controller_eth_addr.parse().map_err(ChainError::HexError)?; + let account_eth_addr: H160 = account_eth_addr.parse().map_err(ChainError::HexError)?; + + // Create a new EmailAccountRecovery contract instance let contract = EmailAccountRecovery::new(controller_eth_addr, self.client.clone()); - let is_activated = contract.is_activated(account_eth_addr).call().await?; + + // Call the is_activated method + let is_activated = contract + .is_activated(account_eth_addr) + .call() + .await + .map_err(|e| ChainError::contract_error("Failed to check if is activated", e))?; Ok(is_activated) } } diff --git a/packages/relayer/src/config.rs b/packages/relayer/src/config.rs index bed30ff4..803e445a 100644 --- a/packages/relayer/src/config.rs +++ b/packages/relayer/src/config.rs @@ -4,13 +4,17 @@ use std::{env, path::PathBuf}; use dotenv::dotenv; +/// Configuration struct for the Relayer service. +/// +/// This struct holds various configuration parameters needed for the Relayer service, +/// including SMTP settings, database path, web server address, and blockchain-related information. #[derive(Clone)] pub struct RelayerConfig { pub smtp_server: String, pub relayer_email_addr: String, pub db_path: String, pub web_server_address: String, - pub circuits_dir_path: PathBuf, + pub regex_json_dir_path: PathBuf, pub prover_address: String, pub chain_rpc_provider: String, pub chain_rpc_explorer: String, @@ -18,18 +22,29 @@ pub struct RelayerConfig { pub private_key: String, pub email_account_recovery_version_id: u8, pub email_templates: String, + pub error_email_addr: String, } impl RelayerConfig { + /// Creates a new instance of RelayerConfig. + /// + /// This function loads environment variables using dotenv and populates + /// the RelayerConfig struct with the values. + /// + /// # Returns + /// + /// A new instance of RelayerConfig. pub fn new() -> Self { + // Load environment variables from .env file dotenv().ok(); + // Construct and return the RelayerConfig instance Self { smtp_server: env::var(SMTP_SERVER_KEY).unwrap(), relayer_email_addr: env::var(RELAYER_EMAIL_ADDR_KEY).unwrap(), db_path: env::var(DATABASE_PATH_KEY).unwrap(), web_server_address: env::var(WEB_SERVER_ADDRESS_KEY).unwrap(), - circuits_dir_path: env::var(CIRCUITS_DIR_PATH_KEY).unwrap().into(), + regex_json_dir_path: env::var(REGEX_JSON_DIR_PATH_KEY).unwrap().into(), prover_address: env::var(PROVER_ADDRESS_KEY).unwrap(), chain_rpc_provider: env::var(CHAIN_RPC_PROVIDER_KEY).unwrap(), chain_rpc_explorer: env::var(CHAIN_RPC_EXPLORER_KEY).unwrap(), @@ -40,11 +55,19 @@ impl RelayerConfig { .parse() .unwrap(), email_templates: env::var(EMAIL_TEMPLATES_PATH_KEY).unwrap(), + error_email_addr: env::var(ERROR_EMAIL_ADDR_KEY).unwrap(), } } } impl Default for RelayerConfig { + /// Provides a default instance of RelayerConfig. + /// + /// This implementation simply calls the `new()` method to create a default instance. + /// + /// # Returns + /// + /// A default instance of RelayerConfig. fn default() -> Self { Self::new() } diff --git a/packages/relayer/src/core.rs b/packages/relayer/src/core.rs index 00e1c195..56639900 100644 --- a/packages/relayer/src/core.rs +++ b/packages/relayer/src/core.rs @@ -1,6 +1,8 @@ #![allow(clippy::upper_case_acronyms)] #![allow(clippy::identity_op)] +use std::fs; + use crate::abis::email_account_recovery::{EmailAuthMsg, EmailProof}; use crate::*; @@ -8,55 +10,81 @@ use ethers::{ abi::{encode, Token}, utils::keccak256, }; -use relayer_utils::{extract_substr_idxes, generate_email_auth_input, LOG}; +use relayer_utils::{ + extract_substr_idxes, extract_template_vals_from_command, generate_email_circuit_input, + generate_proof, EmailCircuitParams, LOG, +}; const DOMAIN_FIELDS: usize = 9; -const SUBJECT_FIELDS: usize = 20; +const COMMAND_FIELDS: usize = 20; const EMAIL_ADDR_FIELDS: usize = 9; -#[named] -pub async fn handle_email(email: String) -> Result { +/// Handles an incoming email for authentication or recovery. +/// +/// # Arguments +/// +/// * `email` - The raw email string to be processed. +/// +/// # Returns +/// +/// A `Result` containing an `EmailAuthEvent` on success, or an `EmailError` on failure. +pub async fn handle_email(email: String) -> Result { let parsed_email = ParsedEmail::new_from_raw_email(&email).await?; - trace!(LOG, "email: {}", email; "func" => function_name!()); + trace!(LOG, "email: {}", email); let guardian_email_addr = parsed_email.get_from_addr()?; let padded_from_addr = PaddedEmailAddr::from_email_addr(&guardian_email_addr); - trace!(LOG, "From address: {}", guardian_email_addr; "func" => function_name!()); - let subject = parsed_email.get_subject_all()?; - - let request_decomposed_def = - serde_json::from_str(include_str!("./regex_json/request_def.json"))?; - let request_idxes = extract_substr_idxes(&email, &request_decomposed_def)?; + trace!(LOG, "From address: {}", guardian_email_addr); + let email_body = parsed_email.get_cleaned_body()?; + + let request_def_path = + PathBuf::from(REGEX_JSON_DIR_PATH.get().unwrap()).join("request_def.json"); + let request_def_contents = fs::read_to_string(&request_def_path).map_err(|e| { + anyhow!( + "Failed to read file {:?}: {}", + request_def_path.display(), + e + ) + })?; + let request_decomposed_def = serde_json::from_str(&request_def_contents) + .map_err(|e| EmailError::Parse(format!("Failed to parse request_def.json: {}", e)))?; + let request_idxes = extract_substr_idxes(&email, &request_decomposed_def, false)?; if request_idxes.is_empty() { - bail!(WRONG_SUBJECT_FORMAT); + return Err(EmailError::Body(WRONG_COMMAND_FORMAT.to_string())); } - info!(LOG, "Request idxes: {:?}", request_idxes; "func" => function_name!()); + info!(LOG, "Request idxes: {:?}", request_idxes); let request_id = &email[request_idxes[0].0..request_idxes[0].1]; let request_id_u32 = request_id .parse::() - .map_err(|e| anyhow!("Failed to parse request_id to u64: {}", e))?; - let request_record = DB.get_request(request_id_u32).await?; - if request_record.is_none() { - return Ok(EmailAuthEvent::Error { - email_addr: guardian_email_addr, - error: format!("Request {} not found", request_id), - }); - } - let request = request_record.unwrap(); + .map_err(|e| EmailError::Parse(format!("Failed to parse request_id to u64: {}", e)))?; + let request = match DB.get_request(request_id_u32).await? { + Some(req) => req, + None => { + let original_subject = parsed_email.get_subject_all()?; + return Ok(EmailAuthEvent::Error { + email_addr: guardian_email_addr, + error: format!("Request {} not found", request_id), + original_subject, + original_message_id: parsed_email.get_message_id().ok(), + email_request_context: *Box::new(None), + command: None, + }); + } + }; if request.guardian_email_addr != guardian_email_addr { - return Err(anyhow!( + return Err(EmailError::EmailAddress(format!( "Guardian email address in the request {} is not equal to the one in the email {}", - request.guardian_email_addr, - guardian_email_addr - )); + request.guardian_email_addr, guardian_email_addr + ))); } + let account_code_str = DB .get_account_code_from_wallet_and_email(&request.account_eth_addr, &guardian_email_addr) .await? - .ok_or(anyhow!( + .ok_or(EmailError::NotFound(format!( "The user of the wallet address {} and the email address {} is not registered.", - request.account_eth_addr, - guardian_email_addr - ))?; + request.account_eth_addr, guardian_email_addr + )))?; + check_and_update_dkim( &email, &parsed_email, @@ -64,423 +92,413 @@ pub async fn handle_email(email: String) -> Result { &request.account_eth_addr, request.account_salt.as_deref().unwrap_or_default(), ) - .await?; - - if let Ok(invitation_code) = parsed_email.get_invitation_code() { - trace!(LOG, "Email with account code"; "func" => function_name!()); - - if account_code_str != invitation_code { - return Err(anyhow!( - "Stored account code is not equal to one in the email. Stored: {}, Email: {}", - account_code_str, - invitation_code - )); - } + .await + .map_err(|e| EmailError::Dkim(e.to_string()))?; + + let invitation_code = match parsed_email.get_invitation_code(false) { + Ok(code) => Some(code), + Err(_) => None, + }; + + let params = EmailRequestContext { + request, + email_body, + account_code_str, + email, + parsed_email, + }; + + handle_email_request(params, invitation_code).await +} - if !request.is_for_recovery { - let subject_template = CLIENT - .get_acceptance_subject_templates( - &request.controller_eth_addr, - request.template_idx, - ) - .await?; - - let result = extract_template_vals_and_skipped_subject_idx(&subject, subject_template); - let (subject_params, skipped_subject_prefix) = match result { - Ok((subject_params, skipped_subject_prefix)) => { - (subject_params, skipped_subject_prefix) - } - Err(e) => { - return Ok(EmailAuthEvent::Error { - email_addr: guardian_email_addr, - error: format!("Invalid Subject, {}", e), - }); - } +/// Handles the email request based on the presence of an invitation code and whether it's for recovery. +/// +/// # Arguments +/// +/// * `params` - The `EmailRequestContext` containing request details. +/// * `invitation_code` - An optional invitation code. +/// +/// # Returns +/// +/// A `Result` containing an `EmailAuthEvent` or an `EmailError`. +async fn handle_email_request( + params: EmailRequestContext, + invitation_code: Option, +) -> Result { + match (invitation_code, params.request.is_for_recovery) { + (Some(invitation_code), is_for_recovery) if !is_for_recovery => { + if params.account_code_str != invitation_code { + return Err(EmailError::Body(format!( + "Stored account code is not equal to one in the email. Stored: {}, Email: {}", + params.account_code_str, invitation_code + ))); }; + trace!(LOG, "Email with account code"); + accept(params, invitation_code).await + } + (None, is_for_recovery) if is_for_recovery => recover(params).await, + (Some(_), _) => { + let original_subject = params.parsed_email.get_subject_all()?; + Ok(EmailAuthEvent::Error { + email_addr: params.request.guardian_email_addr, + error: "Account code found and for recovery".to_string(), + original_subject, + original_message_id: params.parsed_email.get_message_id().ok(), + email_request_context: *Box::new(None), + command: None, + }) + } + (None, _) => { + let original_subject = params.parsed_email.get_subject_all()?; + Ok(EmailAuthEvent::Error { + email_addr: params.request.guardian_email_addr, + error: "No account code found and not for recovery".to_string(), + original_subject, + original_message_id: params.parsed_email.get_message_id().ok(), + email_request_context: *Box::new(None), + command: None, + }) + } + } +} - let subject_params_encoded: Vec = subject_params - .iter() - .map(|param| param.abi_encode(None).unwrap()) - .collect(); - - let tokens = vec![ - Token::Uint((*EMAIL_ACCOUNT_RECOVERY_VERSION_ID.get().unwrap()).into()), - Token::String("ACCEPTANCE".to_string()), - Token::Uint(request.template_idx.into()), - ]; +/// Handles the acceptance of an email authentication request. +/// +/// # Arguments +/// +/// * `params` - The `EmailRequestContext` containing request details. +/// * `invitation_code` - The invitation code from the email. +/// +/// # Returns +/// +/// A `Result` containing an `EmailAuthEvent` or an `EmailError`. +async fn accept( + params: EmailRequestContext, + invitation_code: String, +) -> Result { + let (email_auth_msg, email_proof, account_salt) = get_email_auth_msg(¶ms).await?; + // It's needed for error message + let email_auth_msg_clone = email_auth_msg.clone(); + + info!(LOG, "Email Auth Msg: {:?}", email_auth_msg); + info!(LOG, "Request: {:?}", params.request); + + // Handle the acceptance with the client + let is_accepted = CLIENT + .handle_acceptance( + ¶ms.request.controller_eth_addr, + email_auth_msg, + params.request.template_idx, + ) + .await?; + + update_request( + ¶ms, + is_accepted, + email_proof.email_nullifier, + account_salt, + ) + .await?; - let template_id = keccak256(encode(&tokens)); + let original_subject = params.parsed_email.get_subject_all()?; + if is_accepted { + let creds = Credentials { + account_code: invitation_code, + account_eth_addr: params.request.account_eth_addr.clone(), + guardian_email_addr: params.request.guardian_email_addr.clone(), + is_set: true, + }; + DB.update_credentials_of_account_code(&creds).await?; + + Ok(EmailAuthEvent::AcceptanceSuccess { + account_eth_addr: params.request.account_eth_addr, + guardian_email_addr: params.request.guardian_email_addr, + request_id: params.request.request_id, + original_subject, + original_message_id: params.parsed_email.get_message_id().ok(), + }) + } else { + let original_subject = params.parsed_email.get_subject_all()?; + Ok(EmailAuthEvent::Error { + email_addr: params.request.guardian_email_addr.clone(), + error: "Failed to handle acceptance".to_string(), + original_subject, + original_message_id: params.parsed_email.get_message_id().ok(), + email_request_context: Some(Box::new(params)), + command: Some(email_auth_msg_clone.proof.masked_command), + }) + } +} - let circuit_input = generate_email_auth_input( - &email, - &AccountCode::from(hex2field(&format!("0x{}", &account_code_str))?), - ) - .await?; - - let (proof, public_signals) = - generate_proof(&circuit_input, "email_auth", PROVER_ADDRESS.get().unwrap()).await?; - - let account_salt = u256_to_bytes32(&public_signals[SUBJECT_FIELDS + DOMAIN_FIELDS + 3]); - let is_code_exist = public_signals[SUBJECT_FIELDS + DOMAIN_FIELDS + 4] == 1u8.into(); - let masked_subject = get_masked_subject(public_signals.clone(), DOMAIN_FIELDS + 3)?; - - let email_proof = EmailProof { - proof: proof, - domain_name: parsed_email.get_email_domain()?, - public_key_hash: u256_to_bytes32(&public_signals[DOMAIN_FIELDS + 0]), - timestamp: u256_to_bytes32(&public_signals[DOMAIN_FIELDS + 2]).into(), - masked_subject, - email_nullifier: u256_to_bytes32(&public_signals[DOMAIN_FIELDS + 1]), - account_salt, - is_code_exist, - }; +/// Handles the recovery process for an email authentication request. +/// +/// # Arguments +/// +/// * `params` - The `EmailRequestContext` containing request details. +/// +/// # Returns +/// +/// A `Result` containing an `EmailAuthEvent` or an `EmailError`. +async fn recover(params: EmailRequestContext) -> Result { + let (email_auth_msg, email_proof, account_salt) = get_email_auth_msg(¶ms).await?; + // It's needed for error message + let email_auth_msg_clone = email_auth_msg.clone(); + + info!(LOG, "Email Auth Msg: {:?}", email_auth_msg); + info!(LOG, "Request: {:?}", params.request); + + // Handle the recovery with the client + let is_success = CLIENT + .handle_recovery( + ¶ms.request.controller_eth_addr, + email_auth_msg, + params.request.template_idx, + ) + .await?; + + update_request( + ¶ms, + is_success, + email_proof.email_nullifier, + account_salt, + ) + .await?; - let email_auth_msg = EmailAuthMsg { - template_id: template_id.into(), - subject_params: subject_params_encoded, - skiped_subject_prefix: skipped_subject_prefix.into(), - proof: email_proof.clone(), - }; + let original_subject = params.parsed_email.get_subject_all()?; + if is_success { + Ok(EmailAuthEvent::RecoverySuccess { + account_eth_addr: params.request.account_eth_addr, + guardian_email_addr: params.request.guardian_email_addr, + request_id: params.request.request_id, + original_subject, + original_message_id: params.parsed_email.get_message_id().ok(), + }) + } else { + let original_subject = params.parsed_email.get_subject_all()?; + Ok(EmailAuthEvent::Error { + email_addr: params.request.guardian_email_addr.clone(), + error: "Failed to handle recovery".to_string(), + original_subject, + original_message_id: params.parsed_email.get_message_id().ok(), + email_request_context: Some(Box::new(params)), + command: Some(email_auth_msg_clone.proof.masked_command), + }) + } +} - info!(LOG, "Email Auth Msg: {:?}", email_auth_msg; "func" => function_name!()); - info!(LOG, "Request: {:?}", request; "func" => function_name!()); - - match CLIENT - .handle_acceptance( - &request.controller_eth_addr, - email_auth_msg, - request.template_idx, - ) - .await - { - Ok(true) => { - let creds = Credentials { - account_code: invitation_code, - account_eth_addr: request.account_eth_addr.clone(), - guardian_email_addr: guardian_email_addr.clone(), - is_set: true, - }; - - DB.update_credentials_of_account_code(&creds).await?; - - let updated_request = Request { - account_eth_addr: request.account_eth_addr.clone(), - controller_eth_addr: request.controller_eth_addr.clone(), - guardian_email_addr: guardian_email_addr.clone(), - template_idx: request.template_idx, - is_for_recovery: request.is_for_recovery, - is_processed: true, - request_id: request.request_id, - is_success: Some(true), - email_nullifier: Some(field2hex( - &bytes32_to_fr(&email_proof.email_nullifier).unwrap(), - )), - account_salt: Some(bytes32_to_hex(&account_salt)), - }; - - DB.update_request(&updated_request).await?; - - Ok(EmailAuthEvent::AcceptanceSuccess { - account_eth_addr: request.account_eth_addr, - guardian_email_addr, - request_id: request_id_u32, - }) - } - Ok(false) => { - let updated_request = Request { - account_eth_addr: request.account_eth_addr.clone(), - controller_eth_addr: request.controller_eth_addr.clone(), - guardian_email_addr: guardian_email_addr.clone(), - template_idx: request.template_idx, - is_for_recovery: request.is_for_recovery, - is_processed: true, - request_id: request.request_id, - is_success: Some(false), - email_nullifier: Some(field2hex( - &bytes32_to_fr(&email_proof.email_nullifier).unwrap(), - )), - account_salt: Some(bytes32_to_hex(&account_salt)), - }; - - DB.update_request(&updated_request).await?; - - Ok(EmailAuthEvent::Error { - email_addr: guardian_email_addr, - error: "Failed to handle acceptance".to_string(), - }) - } - Err(e) => Err(anyhow!("Failed to handle acceptance: {}", e)), - } - } else { - let subject_template = CLIENT - .get_recovery_subject_templates(&request.controller_eth_addr, request.template_idx) - .await?; - - let result = extract_template_vals_and_skipped_subject_idx(&subject, subject_template); - let (subject_params, skipped_subject_prefix) = match result { - Ok((subject_params, skipped_subject_prefix)) => { - (subject_params, skipped_subject_prefix) - } - Err(e) => { - return Ok(EmailAuthEvent::Error { - email_addr: guardian_email_addr, - error: format!("Invalid Subject, {}", e), - }); - } - }; +/// Extracts the masked command from public signals. +/// +/// # Arguments +/// +/// * `public_signals` - The vector of public signals. +/// * `start_idx` - The starting index for command extraction. +/// +/// # Returns +/// +/// A `Result` containing the masked command as a `String` or an error. +fn get_masked_command(public_signals: Vec, start_idx: usize) -> Result { + // Gather signals from start_idx to start_idx + COMMAND_FIELDS + let command_bytes: Vec = public_signals + .iter() + .skip(start_idx) + .take(COMMAND_FIELDS) + .take_while(|&signal| *signal != U256::zero()) + .flat_map(u256_to_bytes32_little) + .collect(); - let subject_params_encoded: Vec = subject_params - .iter() - .map(|param| param.abi_encode(None).unwrap()) - .collect(); + // Bytes to string, removing null bytes + let command = String::from_utf8(command_bytes.into_iter().filter(|&b| b != 0u8).collect()) + .map_err(|e| anyhow!("Failed to convert bytes to string: {}", e))?; - let tokens = vec![ - Token::Uint((*EMAIL_ACCOUNT_RECOVERY_VERSION_ID.get().unwrap()).into()), - Token::String("RECOVERY".to_string()), - Token::Uint(request.template_idx.into()), - ]; + Ok(command) +} - let template_id = keccak256(encode(&tokens)); +/// Updates the request status in the database. +/// +/// # Arguments +/// +/// * `params` - The `EmailRequestContext` containing request details. +/// * `is_success` - A boolean indicating whether the request was successful. +/// * `email_nullifier` - The email nullifier as a byte array. +/// * `account_salt` - The account salt as a byte array. +/// +/// # Returns +/// +/// A `Result` indicating success or an `EmailError`. +async fn update_request( + params: &EmailRequestContext, + is_success: bool, + email_nullifier: [u8; 32], + account_salt: [u8; 32], +) -> Result<(), EmailError> { + let updated_request = Request { + account_eth_addr: params.request.account_eth_addr.clone(), + controller_eth_addr: params.request.controller_eth_addr.clone(), + guardian_email_addr: params.request.guardian_email_addr.clone(), + template_idx: params.request.template_idx, + is_for_recovery: params.request.is_for_recovery, + is_processed: true, + request_id: params.request.request_id, + is_success: Some(is_success), + email_nullifier: Some(field_to_hex(&bytes32_to_fr(&email_nullifier)?)), + account_salt: Some(bytes32_to_hex(&account_salt)), + }; + + DB.update_request(&updated_request).await?; + Ok(()) +} - let circuit_input = generate_email_auth_input( - &email, - &AccountCode::from(hex2field(&format!("0x{}", &account_code_str))?), - ) - .await?; - - let (proof, public_signals) = - generate_proof(&circuit_input, "email_auth", PROVER_ADDRESS.get().unwrap()).await?; - - let account_salt = u256_to_bytes32(&public_signals[SUBJECT_FIELDS + DOMAIN_FIELDS + 3]); - let is_code_exist = public_signals[SUBJECT_FIELDS + DOMAIN_FIELDS + 4] == 1u8.into(); - let masked_subject = get_masked_subject(public_signals.clone(), DOMAIN_FIELDS + 3)?; - - let email_proof = EmailProof { - proof: proof, - domain_name: parsed_email.get_email_domain()?, - public_key_hash: u256_to_bytes32(&public_signals[DOMAIN_FIELDS + 0]), - timestamp: u256_to_bytes32(&public_signals[DOMAIN_FIELDS + 2]).into(), - masked_subject, - email_nullifier: u256_to_bytes32(&public_signals[DOMAIN_FIELDS + 1]), - account_salt, - is_code_exist, - }; +/// Generates the email proof for authentication. +/// +/// # Arguments +/// +/// * `params` - The `EmailRequestContext` containing request details. +/// +/// # Returns +/// +/// A `Result` containing the `EmailProof` and account salt, or an `EmailError`. +async fn generate_email_proof( + params: &EmailRequestContext, +) -> Result<(EmailProof, [u8; 32]), EmailError> { + let circuit_input = generate_email_circuit_input( + ¶ms.email, + &AccountCode::from(hex_to_field(&format!("0x{}", ¶ms.account_code_str))?), + Some(EmailCircuitParams { + max_header_length: Some(1024), + max_body_length: Some(1024), + sha_precompute_selector: Some(SHA_PRECOMPUTE_SELECTOR.to_string()), + ignore_body_hash_check: Some(false), + }), + ) + .await?; - let email_auth_msg = EmailAuthMsg { - template_id: template_id.into(), - subject_params: subject_params_encoded, - skiped_subject_prefix: skipped_subject_prefix.into(), - proof: email_proof.clone(), - }; + let (proof, public_signals) = + generate_proof(&circuit_input, "email_auth", PROVER_ADDRESS.get().unwrap()).await?; - info!(LOG, "Email Auth Msg: {:?}", email_auth_msg; "func" => function_name!()); - info!(LOG, "Request: {:?}", request; "func" => function_name!()); - - match CLIENT - .handle_recovery( - &request.controller_eth_addr, - email_auth_msg, - request.template_idx, - ) - .await - { - Ok(true) => { - let updated_request = Request { - account_eth_addr: request.account_eth_addr.clone(), - controller_eth_addr: request.controller_eth_addr.clone(), - guardian_email_addr: guardian_email_addr.clone(), - template_idx: request.template_idx, - is_for_recovery: request.is_for_recovery, - is_processed: true, - request_id: request.request_id, - is_success: Some(true), - email_nullifier: Some(field2hex( - &bytes32_to_fr(&email_proof.email_nullifier).unwrap(), - )), - account_salt: Some(bytes32_to_hex(&account_salt)), - }; - - DB.update_request(&updated_request).await?; - - Ok(EmailAuthEvent::RecoverySuccess { - account_eth_addr: request.account_eth_addr, - guardian_email_addr, - request_id: request_id_u32, - }) - } - Ok(false) => { - let updated_request = Request { - account_eth_addr: request.account_eth_addr.clone(), - controller_eth_addr: request.controller_eth_addr.clone(), - guardian_email_addr: guardian_email_addr.clone(), - template_idx: request.template_idx, - is_for_recovery: request.is_for_recovery, - is_processed: true, - request_id: request.request_id, - is_success: Some(false), - email_nullifier: Some(field2hex( - &bytes32_to_fr(&email_proof.email_nullifier).unwrap(), - )), - account_salt: Some(bytes32_to_hex(&account_salt)), - }; - - DB.update_request(&updated_request).await?; - - Ok(EmailAuthEvent::Error { - email_addr: guardian_email_addr, - error: "Failed to handle recovery".to_string(), - }) - } - Err(e) => Err(anyhow!("Failed to handle recovery: {}", e)), - } - } - } else { - if request.is_for_recovery { - let subject_template = CLIENT - .get_recovery_subject_templates(&request.controller_eth_addr, request.template_idx) - .await?; - - let result = extract_template_vals_and_skipped_subject_idx(&subject, subject_template); - let (subject_params, skipped_subject_prefix) = match result { - Ok((subject_params, skipped_subject_prefix)) => { - (subject_params, skipped_subject_prefix) - } - Err(e) => { - return Ok(EmailAuthEvent::Error { - email_addr: guardian_email_addr, - error: format!("Invalid Subject, {}", e), - }); - } - }; + info!(LOG, "Public signals: {:?}", public_signals); - let subject_params_encoded: Vec = subject_params - .iter() - .map(|param| param.abi_encode(None).unwrap()) - .collect(); + let account_salt = u256_to_bytes32(&public_signals[COMMAND_FIELDS + DOMAIN_FIELDS + 3]); + let is_code_exist = public_signals[COMMAND_FIELDS + DOMAIN_FIELDS + 4] == 1u8.into(); + let masked_command = get_masked_command(public_signals.clone(), DOMAIN_FIELDS + 3)?; - let tokens = vec![ - Token::Uint((*EMAIL_ACCOUNT_RECOVERY_VERSION_ID.get().unwrap()).into()), - Token::String("RECOVERY".to_string()), - Token::Uint(request.template_idx.into()), - ]; + let email_proof = EmailProof { + proof, + domain_name: params.parsed_email.get_email_domain()?, + public_key_hash: u256_to_bytes32(&public_signals[DOMAIN_FIELDS + 0]), + timestamp: u256_to_bytes32(&public_signals[DOMAIN_FIELDS + 2]).into(), + masked_command, + email_nullifier: u256_to_bytes32(&public_signals[DOMAIN_FIELDS + 1]), + account_salt, + is_code_exist, + }; - let template_id = keccak256(encode(&tokens)); + Ok((email_proof, account_salt)) +} - let circuit_input = generate_email_auth_input( - &email, - &AccountCode::from(hex2field(&format!("0x{}", &account_code_str))?), - ) - .await?; - - let (proof, public_signals) = - generate_proof(&circuit_input, "email_auth", PROVER_ADDRESS.get().unwrap()).await?; - - let account_salt = u256_to_bytes32(&public_signals[SUBJECT_FIELDS + DOMAIN_FIELDS + 3]); - let is_code_exist = public_signals[SUBJECT_FIELDS + DOMAIN_FIELDS + 4] == 1u8.into(); - let masked_subject = get_masked_subject(public_signals.clone(), DOMAIN_FIELDS + 3)?; - - let email_proof = EmailProof { - proof: proof, - domain_name: parsed_email.get_email_domain()?, - public_key_hash: u256_to_bytes32(&public_signals[DOMAIN_FIELDS + 0]), - timestamp: u256_to_bytes32(&public_signals[DOMAIN_FIELDS + 2]).into(), - masked_subject, - email_nullifier: u256_to_bytes32(&public_signals[DOMAIN_FIELDS + 1]), - account_salt, - is_code_exist, - }; +/// Generates the template ID for the email authentication request. +/// +/// # Arguments +/// +/// * `params` - The `EmailRequestContext` containing request details. +/// +/// # Returns +/// +/// A 32-byte array representing the template ID. +fn get_template_id(params: &EmailRequestContext) -> [u8; 32] { + let action = if params.request.is_for_recovery { + "RECOVERY".to_string() + } else { + "ACCEPTANCE".to_string() + }; - let email_auth_msg = EmailAuthMsg { - template_id: template_id.into(), - subject_params: subject_params_encoded, - skiped_subject_prefix: skipped_subject_prefix.into(), - proof: email_proof.clone(), - }; + let tokens = vec![ + Token::Uint((*EMAIL_ACCOUNT_RECOVERY_VERSION_ID.get().unwrap()).into()), + // TODO: Continue here + Token::String(action), + Token::Uint(params.request.template_idx.into()), + ]; - info!(LOG, "Email Auth Msg: {:?}", email_auth_msg; "func" => function_name!()); - info!(LOG, "Request: {:?}", request; "func" => function_name!()); - - match CLIENT - .handle_recovery( - &request.controller_eth_addr, - email_auth_msg, - request.template_idx, - ) - .await - { - Ok(true) => { - let updated_request = Request { - account_eth_addr: request.account_eth_addr.clone(), - controller_eth_addr: request.controller_eth_addr.clone(), - guardian_email_addr: guardian_email_addr.clone(), - template_idx: request.template_idx, - is_for_recovery: request.is_for_recovery, - is_processed: true, - request_id: request.request_id, - is_success: Some(true), - email_nullifier: Some(field2hex( - &bytes32_to_fr(&email_proof.email_nullifier).unwrap(), - )), - account_salt: Some(bytes32_to_hex(&account_salt)), - }; - - DB.update_request(&updated_request).await?; - - Ok(EmailAuthEvent::RecoverySuccess { - account_eth_addr: request.account_eth_addr, - guardian_email_addr, - request_id: request_id_u32, - }) - } - Ok(false) => { - let updated_request = Request { - account_eth_addr: request.account_eth_addr.clone(), - controller_eth_addr: request.controller_eth_addr.clone(), - guardian_email_addr: guardian_email_addr.clone(), - template_idx: request.template_idx, - is_for_recovery: request.is_for_recovery, - is_processed: true, - request_id: request.request_id, - is_success: Some(false), - email_nullifier: Some(field2hex( - &bytes32_to_fr(&email_proof.email_nullifier).unwrap(), - )), - account_salt: Some(bytes32_to_hex(&account_salt)), - }; - - DB.update_request(&updated_request).await?; - - Ok(EmailAuthEvent::Error { - email_addr: guardian_email_addr, - error: "Failed to handle recovery".to_string(), - }) - } - Err(e) => Err(anyhow!("Failed to handle recovery: {}", e)), - } - } else { - return Ok(EmailAuthEvent::Error { - email_addr: guardian_email_addr, - error: "No account code found".to_string(), - }); - } - } + keccak256(encode(&tokens)) } -pub fn get_masked_subject(public_signals: Vec, start_idx: usize) -> Result { - // Gather signals from start_idx to start_idx + SUBJECT_FIELDS - let mut subject_bytes = Vec::new(); - for i in start_idx..start_idx + SUBJECT_FIELDS { - let signal = public_signals[i as usize]; - if signal == U256::zero() { - break; - } - let bytes = u256_to_bytes32_little(&signal); - subject_bytes.extend_from_slice(&bytes); - } +/// Retrieves and encodes the command parameters for the email authentication request. +/// +/// # Arguments +/// +/// * `params` - The `EmailRequestContext` containing request details. +/// +/// # Returns +/// +/// A `Result` containing a vector of encoded command parameters or an `EmailError`. +async fn get_encoded_command_params( + params: &EmailRequestContext, +) -> Result, EmailError> { + let command_template = if params.request.is_for_recovery { + CLIENT + .get_recovery_command_templates( + ¶ms.request.controller_eth_addr, + params.request.template_idx, + ) + .await + } else { + CLIENT + .get_acceptance_command_templates( + ¶ms.request.controller_eth_addr, + params.request.template_idx, + ) + .await + }?; + + let command_params = extract_template_vals_from_command(¶ms.email_body, command_template) + .map_err(|e| EmailError::Body(format!("Invalid commad: {}", e)))?; + + let command_params_encoded = command_params + .iter() + .map(|param| { + param + .abi_encode(None) + .map_err(|e| EmailError::AbiError(e.to_string())) + }) + .collect::, EmailError>>()?; + + Ok(command_params_encoded) +} - // Bytes to string, removing null bytes - let subject = String::from_utf8(subject_bytes.into_iter().filter(|&b| b != 0u8).collect()) - .map_err(|e| anyhow!("Failed to convert bytes to string: {}", e))?; +/// Generates the email authentication message. +/// +/// # Arguments +/// +/// * `params` - The `EmailRequestContext` containing request details. +/// +/// # Returns +/// +/// A `Result` containing the `EmailAuthMsg`, `EmailProof`, and account salt, or an `EmailError`. +async fn get_email_auth_msg( + params: &EmailRequestContext, +) -> Result<(EmailAuthMsg, EmailProof, [u8; 32]), EmailError> { + let command_params_encoded = get_encoded_command_params(params).await?; + let template_id = get_template_id(params); + let (email_proof, account_salt) = generate_email_proof(params).await?; + let email_auth_msg = EmailAuthMsg { + template_id: template_id.into(), + command_params: command_params_encoded, + skipped_command_prefix: U256::zero(), + proof: email_proof.clone(), + }; + Ok((email_auth_msg, email_proof, account_salt)) +} - Ok(subject) +/// Represents the context for an email authentication request. +#[derive(Debug, Clone)] +pub struct EmailRequestContext { + /// The request details. + pub request: Request, + /// The body of the email. + email_body: String, + /// The account code as a string. + account_code_str: String, + /// The full raw email. + pub email: String, + /// The parsed email. + parsed_email: ParsedEmail, } diff --git a/packages/relayer/src/database.rs b/packages/relayer/src/database.rs index 51f13499..29729903 100644 --- a/packages/relayer/src/database.rs +++ b/packages/relayer/src/database.rs @@ -3,33 +3,59 @@ use crate::*; use relayer_utils::LOG; use sqlx::{postgres::PgPool, Row}; +/// Represents the credentials for a user account. #[derive(Debug, Clone)] pub struct Credentials { + /// The unique code associated with the account. pub account_code: String, + /// The Ethereum address of the account. pub account_eth_addr: String, + /// The email address of the guardian. pub guardian_email_addr: String, + /// Indicates whether the credentials are set. pub is_set: bool, } +/// Represents a request in the system. #[derive(Debug, Clone)] pub struct Request { + /// The unique identifier for the request. pub request_id: u32, + /// The Ethereum address of the account. pub account_eth_addr: String, + /// The Ethereum address of the controller. pub controller_eth_addr: String, + /// The email address of the guardian. pub guardian_email_addr: String, + /// Indicates whether the request is for recovery. pub is_for_recovery: bool, + /// The index of the template used for the request. pub template_idx: u64, + /// Indicates whether the request has been processed. pub is_processed: bool, + /// Indicates the success status of the request, if available. pub is_success: Option, + /// The nullifier for the email, if available. pub email_nullifier: Option, + /// The salt for the account, if available. pub account_salt: Option, } +/// Represents the database connection and operations. pub struct Database { db: PgPool, } impl Database { + /// Opens a new database connection. + /// + /// # Arguments + /// + /// * `path` - The connection string for the database. + /// + /// # Returns + /// + /// A `Result` containing the `Database` struct if successful, or an error if the connection fails. pub async fn open(path: &str) -> Result { let res = Self { db: PgPool::connect(path) @@ -42,7 +68,13 @@ impl Database { Ok(res) } + /// Sets up the database by creating necessary tables if they don't exist. + /// + /// # Returns + /// + /// A `Result` indicating success or failure of the setup process. pub async fn setup_database(&self) -> Result<()> { + // Create credentials table sqlx::query( "CREATE TABLE IF NOT EXISTS credentials ( account_code TEXT PRIMARY KEY, @@ -54,6 +86,7 @@ impl Database { .execute(&self.db) .await?; + // Create requests table sqlx::query( "CREATE TABLE IF NOT EXISTS requests ( request_id BIGINT PRIMARY KEY, @@ -70,10 +103,57 @@ impl Database { ) .execute(&self.db) .await?; + + // Create expected_replies table + sqlx::query( + "CREATE TABLE IF NOT EXISTS expected_replies ( + message_id VARCHAR(255) PRIMARY KEY, + request_id VARCHAR(255), + has_reply BOOLEAN DEFAULT FALSE, + created_at TIMESTAMP DEFAULT (NOW() AT TIME ZONE 'UTC') + );", + ) + .execute(&self.db) + .await?; Ok(()) } - #[named] + /// Tests the database connection by attempting to execute a simple query. + /// + /// # Returns + /// + /// A `Result` indicating success or failure of the connection test. + pub(crate) async fn test_db_connection(&self) -> Result<()> { + // Try up to 3 times + for i in 1..4 { + match sqlx::query("SELECT 1").execute(&self.db).await { + Ok(_) => { + info!(LOG, "Connected successfully to database"); + return Ok(()); + } + Err(e) => { + error!( + LOG, + "Failed to initialize connection to the database: {:?}. Retrying...", e + ); + tokio::time::sleep(Duration::from_secs(i * i)).await; + } + } + } + Err(anyhow::anyhow!( + "Failed to initialize database connection after 3 attempts" + )) + } + + /// Retrieves credentials for a given account code. + /// + /// # Arguments + /// + /// * `account_code` - The unique code associated with the account. + /// + /// # Returns + /// + /// A `Result` containing an `Option` if successful, or an error if the query fails. pub(crate) async fn get_credentials(&self, account_code: &str) -> Result> { let row = sqlx::query("SELECT * FROM credentials WHERE account_code = $1") .bind(account_code) @@ -82,6 +162,7 @@ impl Database { match row { Some(row) => { + // Extract values from the row let account_code: String = row.get("account_code"); let account_eth_addr: String = row.get("account_eth_addr"); let guardian_email_addr: String = row.get("guardian_email_addr"); @@ -92,18 +173,28 @@ impl Database { guardian_email_addr, is_set, }; - info!(LOG, "row {:?}", codes_row; "func" => function_name!()); + info!(LOG, "row {:?}", codes_row); Ok(Some(codes_row)) } None => Ok(None), } } + /// Checks if a wallet and email combination is registered in the database. + /// + /// # Arguments + /// + /// * `account_eth_addr` - The Ethereum address of the account. + /// * `email_addr` - The email address to check. + /// + /// # Returns + /// + /// A `Result` containing a boolean indicating if the combination is registered. pub(crate) async fn is_wallet_and_email_registered( &self, account_eth_addr: &str, email_addr: &str, - ) -> bool { + ) -> std::result::Result { let row = sqlx::query( "SELECT * FROM credentials WHERE account_eth_addr = $1 AND guardian_email_addr = $2", ) @@ -111,58 +202,103 @@ impl Database { .bind(email_addr) .fetch_optional(&self.db) .await - .unwrap(); + .map_err(|e| DatabaseError::new("Failed to check if wallet and email are registered", e))?; - match row { - Some(_) => true, - None => false, - } + Ok(row.is_some()) } - pub(crate) async fn update_credentials_of_account_code(&self, row: &Credentials) -> Result<()> { - let res = sqlx::query("UPDATE credentials SET account_eth_addr = $1, guardian_email_addr = $2, is_set = $3 WHERE account_code = $4") + /// Updates the credentials for a given account code. + /// + /// # Arguments + /// + /// * `row` - The `Credentials` struct containing the updated information. + /// + /// # Returns + /// + /// A `Result` indicating success or failure of the update operation. + pub(crate) async fn update_credentials_of_account_code( + &self, + row: &Credentials, + ) -> std::result::Result<(), DatabaseError> { + sqlx::query("UPDATE credentials SET account_eth_addr = $1, guardian_email_addr = $2, is_set = $3 WHERE account_code = $4") .bind(&row.account_eth_addr) .bind(&row.guardian_email_addr) .bind(row.is_set) .bind(&row.account_code) .execute(&self.db) - .await?; + .await + .map_err(|e| { + DatabaseError::new("Failed to update credentials of account code", e) + })?; Ok(()) } + /// Updates the credentials for a given wallet and email combination. + /// + /// # Arguments + /// + /// * `row` - The `Credentials` struct containing the updated information. + /// + /// # Returns + /// + /// A `Result` indicating success or failure of the update operation. pub(crate) async fn update_credentials_of_wallet_and_email( &self, row: &Credentials, - ) -> Result<()> { - let res = sqlx::query("UPDATE credentials SET account_code = $1, is_set = $2 WHERE account_eth_addr = $3 AND guardian_email_addr = $4") + ) -> std::result::Result<(), DatabaseError> { + sqlx::query("UPDATE credentials SET account_code = $1, is_set = $2 WHERE account_eth_addr = $3 AND guardian_email_addr = $4") .bind(&row.account_code) .bind(row.is_set) .bind(&row.account_eth_addr) .bind(&row.guardian_email_addr) .execute(&self.db) - .await?; + .await + .map_err(|e| { + DatabaseError::new("Failed to insert credentials of wallet and email", e) + })?; Ok(()) } + /// Updates the credentials of an inactive guardian. + /// + /// # Arguments + /// + /// * `is_set` - The new value for the `is_set` field. + /// * `account_eth_addr` - The Ethereum address of the account. + /// + /// # Returns + /// + /// A `Result` indicating success or failure of the update operation. pub(crate) async fn update_credentials_of_inactive_guardian( &self, is_set: bool, account_eth_addr: &str, - ) -> Result<()> { - let res = sqlx::query( + ) -> std::result::Result<(), DatabaseError> { + sqlx::query( "UPDATE credentials SET is_set = $1 WHERE account_eth_addr = $2 AND is_set = true", ) .bind(is_set) .bind(account_eth_addr) .execute(&self.db) - .await?; + .await + .map_err(|e| DatabaseError::new("Failed to update credentials of inactive guardian", e))?; Ok(()) } - #[named] - pub(crate) async fn insert_credentials(&self, row: &Credentials) -> Result<()> { - info!(LOG, "insert row {:?}", row; "func" => function_name!()); - let row = sqlx::query( + /// Inserts new credentials into the database. + /// + /// # Arguments + /// + /// * `row` - The `Credentials` struct containing the new information. + /// + /// # Returns + /// + /// A `Result` indicating success or failure of the insert operation. + pub(crate) async fn insert_credentials( + &self, + row: &Credentials, + ) -> std::result::Result<(), DatabaseError> { + sqlx::query( "INSERT INTO credentials (account_code, account_eth_addr, guardian_email_addr, is_set) VALUES ($1, $2, $3, $4) RETURNING *", ) .bind(&row.account_code) @@ -170,38 +306,59 @@ impl Database { .bind(&row.guardian_email_addr) .bind(row.is_set) .fetch_one(&self.db) - .await?; - info!( - LOG, - "{} row inserted", - row.len(); "func" => function_name!() - ); + .await + .map_err(|e| DatabaseError::new("Failed to insert credentials", e))?; + info!(LOG, "Credentials inserted"); Ok(()) } - pub async fn is_guardian_set(&self, account_eth_addr: &str, guardian_email_addr: &str) -> bool { + /// Checks if a guardian is set for a given account and email address. + /// + /// # Arguments + /// + /// * `account_eth_addr` - The Ethereum address of the account. + /// * `guardian_email_addr` - The email address of the guardian. + /// + /// # Returns + /// + /// A `Result` containing a boolean indicating whether the guardian is set. + pub async fn is_guardian_set( + &self, + account_eth_addr: &str, + guardian_email_addr: &str, + ) -> std::result::Result { let row = sqlx::query("SELECT * FROM credentials WHERE account_eth_addr = $1 AND guardian_email_addr = $2 AND is_set = TRUE") .bind(account_eth_addr) .bind(guardian_email_addr) .fetch_optional(&self.db) .await - .unwrap(); + .map_err(|e| DatabaseError::new("Failed to check if guardian is set", e))?; - match row { - Some(_) => true, - None => false, - } + Ok(row.is_some()) } - #[named] - pub(crate) async fn get_request(&self, request_id: u32) -> Result> { + /// Retrieves a request from the database based on the request ID. + /// + /// # Arguments + /// + /// * `request_id` - The unique identifier of the request. + /// + /// # Returns + /// + /// A `Result` containing an `Option` if successful, or an error if the query fails. + pub(crate) async fn get_request( + &self, + request_id: u32, + ) -> std::result::Result, DatabaseError> { let row = sqlx::query("SELECT * FROM requests WHERE request_id = $1") .bind(request_id as i64) .fetch_optional(&self.db) - .await?; + .await + .map_err(|e| DatabaseError::new("Failed to get request", e))?; match row { Some(row) => { + // Extract values from the row let request_id: i64 = row.get("request_id"); let account_eth_addr: String = row.get("account_eth_addr"); let controller_eth_addr: String = row.get("controller_eth_addr"); @@ -224,15 +381,27 @@ impl Database { email_nullifier, account_salt, }; - info!(LOG, "row {:?}", requests_row; "func" => function_name!()); + info!(LOG, "row {:?}", requests_row); Ok(Some(requests_row)) } None => Ok(None), } } - pub(crate) async fn update_request(&self, row: &Request) -> Result<()> { - let res = sqlx::query("UPDATE requests SET account_eth_addr = $1, controller_eth_addr = $2, guardian_email_addr = $3, is_for_recovery = $4, template_idx = $5, is_processed = $6, is_success = $7, email_nullifier = $8, account_salt = $9 WHERE request_id = $10") + /// Updates an existing request in the database. + /// + /// # Arguments + /// + /// * `row` - The `Request` struct containing the updated information. + /// + /// # Returns + /// + /// A `Result` indicating success or failure of the update operation. + pub(crate) async fn update_request( + &self, + row: &Request, + ) -> std::result::Result<(), DatabaseError> { + sqlx::query("UPDATE requests SET account_eth_addr = $1, controller_eth_addr = $2, guardian_email_addr = $3, is_for_recovery = $4, template_idx = $5, is_processed = $6, is_success = $7, email_nullifier = $8, account_salt = $9 WHERE request_id = $10") .bind(&row.account_eth_addr) .bind(&row.controller_eth_addr) .bind(&row.guardian_email_addr) @@ -244,22 +413,34 @@ impl Database { .bind(&row.account_salt) .bind(row.request_id as i64) .execute(&self.db) - .await?; + .await + .map_err(|e| DatabaseError::new("Failed to update request", e))?; Ok(()) } + /// Retrieves the account code for a given wallet and email combination. + /// + /// # Arguments + /// + /// * `account_eth_addr` - The Ethereum address of the account. + /// * `email_addr` - The email address associated with the account. + /// + /// # Returns + /// + /// A `Result` containing an `Option` with the account code if found, or an error if the query fails. pub(crate) async fn get_account_code_from_wallet_and_email( &self, account_eth_addr: &str, email_addr: &str, - ) -> Result> { + ) -> std::result::Result, DatabaseError> { let row = sqlx::query( "SELECT * FROM credentials WHERE account_eth_addr = $1 AND guardian_email_addr = $2", ) .bind(account_eth_addr) .bind(email_addr) .fetch_optional(&self.db) - .await?; + .await + .map_err(|e| DatabaseError::new("Failed to get account code from wallet and email", e))?; match row { Some(row) => { @@ -270,22 +451,33 @@ impl Database { } } - #[named] + /// Retrieves the credentials for a given wallet and email combination. + /// + /// # Arguments + /// + /// * `account_eth_addr` - The Ethereum address of the account. + /// * `email_addr` - The email address associated with the account. + /// + /// # Returns + /// + /// A `Result` containing an `Option` if found, or an error if the query fails. pub(crate) async fn get_credentials_from_wallet_and_email( &self, account_eth_addr: &str, email_addr: &str, - ) -> Result> { + ) -> std::result::Result, DatabaseError> { let row = sqlx::query( "SELECT * FROM credentials WHERE account_eth_addr = $1 AND guardian_email_addr = $2", ) .bind(account_eth_addr) .bind(email_addr) .fetch_optional(&self.db) - .await?; + .await + .map_err(|e| DatabaseError::new("Failed to get credentials from wallet and email", e))?; match row { Some(row) => { + // Extract values from the row let account_code: String = row.get("account_code"); let account_eth_addr: String = row.get("account_eth_addr"); let guardian_email_addr: String = row.get("guardian_email_addr"); @@ -296,17 +488,28 @@ impl Database { guardian_email_addr, is_set, }; - info!(LOG, "row {:?}", codes_row; "func" => function_name!()); + info!(LOG, "row {:?}", codes_row); Ok(Some(codes_row)) } None => Ok(None), } } - #[named] - pub(crate) async fn insert_request(&self, row: &Request) -> Result<()> { - info!(LOG, "insert row {:?}", row; "func" => function_name!()); - let row = sqlx::query( + /// Inserts a new request into the database. + /// + /// # Arguments + /// + /// * `row` - The `Request` struct containing the new request information. + /// + /// # Returns + /// + /// A `Result` indicating success or failure of the insert operation. + pub(crate) async fn insert_request( + &self, + row: &Request, + ) -> std::result::Result<(), DatabaseError> { + let request_id = row.request_id; + sqlx::query( "INSERT INTO requests (request_id, account_eth_addr, controller_eth_addr, guardian_email_addr, is_for_recovery, template_idx, is_processed, is_success, email_nullifier, account_salt) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING *", ) .bind(row.request_id as i64) @@ -320,12 +523,63 @@ impl Database { .bind(&row.email_nullifier) .bind(&row.account_salt) .fetch_one(&self.db) - .await?; - info!( - LOG, - "{} row inserted", - row.len(); "func" => function_name!() - ); + .await + .map_err(|e| DatabaseError::new("Failed to insert request", e))?; + info!(LOG, "Request inserted with request_id: {}", request_id); + Ok(()) + } + + /// Adds an expected reply to the database. + /// + /// # Arguments + /// + /// * `message_id` - The unique identifier of the message. + /// * `request_id` - An optional request ID associated with the reply. + /// + /// # Returns + /// + /// A `Result` indicating success or failure of the insert operation. + pub(crate) async fn add_expected_reply( + &self, + message_id: &str, + request_id: Option, + ) -> Result<(), DatabaseError> { + let query = " + INSERT INTO expected_replies (message_id, request_id) + VALUES ($1, $2); + "; + sqlx::query(query) + .bind(message_id) + .bind(request_id) + .execute(&self.db) + .await + .map_err(|e| DatabaseError::new("Failed to insert expected_reply", e))?; Ok(()) } + + /// Checks if the given message_id corresponds to a valid reply. + /// + /// This function updates the `has_reply` field to true if the message_id exists and hasn't been replied to yet. + /// + /// # Arguments + /// + /// * `message_id` - The unique identifier of the message. + /// + /// # Returns + /// + /// A `Result` containing a boolean indicating if the reply is valid (true if the update was successful). + pub(crate) async fn is_valid_reply(&self, message_id: &str) -> Result { + let query = " + UPDATE expected_replies + SET has_reply = true + WHERE message_id = $1 AND has_reply = false + RETURNING *; + "; + let result = sqlx::query(query) + .bind(message_id) + .execute(&self.db) + .await + .map_err(|e| DatabaseError::new("Failed to validate reply", e))?; + Ok(result.rows_affected() > 0) + } } diff --git a/packages/relayer/src/lib.rs b/packages/relayer/src/lib.rs index 8245264d..02590d6e 100644 --- a/packages/relayer/src/lib.rs +++ b/packages/relayer/src/lib.rs @@ -8,7 +8,7 @@ pub mod config; pub mod core; pub mod database; pub mod modules; -pub mod utils; +pub mod strings; pub use abis::*; pub use chain::*; @@ -17,12 +17,11 @@ pub use core::*; pub use database::*; pub use modules::*; use relayer_utils::LOG; -pub use utils::*; +pub use strings::*; -use ::function_name::named; -use tokio::sync::Mutex; +use tokio::sync::{Mutex, OnceCell}; -use anyhow::{anyhow, bail, Result}; +use anyhow::{anyhow, Result}; use dotenv::dotenv; use ethers::prelude::*; use lazy_static::lazy_static; @@ -33,7 +32,7 @@ use std::path::PathBuf; use std::sync::{Arc, OnceLock}; use tokio::time::Duration; -pub static CIRCUITS_DIR_PATH: OnceLock = OnceLock::new(); +pub static REGEX_JSON_DIR_PATH: OnceLock = OnceLock::new(); pub static WEB_SERVER_ADDRESS: OnceLock = OnceLock::new(); pub static PROVER_ADDRESS: OnceLock = OnceLock::new(); pub static PRIVATE_KEY: OnceLock = OnceLock::new(); @@ -44,18 +43,40 @@ pub static CHAIN_RPC_EXPLORER: OnceLock = OnceLock::new(); pub static EMAIL_TEMPLATES: OnceLock = OnceLock::new(); pub static RELAYER_EMAIL_ADDRESS: OnceLock = OnceLock::new(); pub static SMTP_SERVER: OnceLock = OnceLock::new(); +pub static ERROR_EMAIL_ADDR: OnceLock = OnceLock::new(); + +static DB_CELL: OnceCell> = OnceCell::const_new(); + +/// Wrapper struct for database access +struct DBWrapper; + +impl DBWrapper { + /// Retrieves the database instance. + /// + /// # Returns + /// + /// A reference to the `Arc`. + /// + /// # Panics + /// + /// Panics if the database is not initialized. + fn get() -> &'static Arc { + DB_CELL.get().expect("Database not initialized") + } +} + +impl std::ops::Deref for DBWrapper { + type Target = Database; + + fn deref(&self) -> &Self::Target { + Self::get() + } +} + +static DB: DBWrapper = DBWrapper; lazy_static! { - pub static ref DB: Arc = { - dotenv().ok(); - let db = tokio::task::block_in_place(|| { - tokio::runtime::Runtime::new() - .unwrap() - .block_on(Database::open(&env::var(DATABASE_PATH_KEY).unwrap())) - }) - .unwrap(); - Arc::new(db) - }; + /// Shared instance of the `ChainClient`. pub static ref CLIENT: Arc = { dotenv().ok(); let client = tokio::task::block_in_place(|| { @@ -66,14 +87,24 @@ lazy_static! { .unwrap(); Arc::new(client) }; + /// Shared mutex for synchronization. pub static ref SHARED_MUTEX: Arc> = Arc::new(Mutex::new(0)); } -#[named] +/// Runs the relayer with the given configuration. +/// +/// # Arguments +/// +/// * `config` - The configuration for the relayer. +/// +/// # Returns +/// +/// A `Result` indicating success or failure. pub async fn run(config: RelayerConfig) -> Result<()> { - info!(LOG, "Starting relayer"; "func" => function_name!()); + info!(LOG, "Starting relayer"); - CIRCUITS_DIR_PATH.set(config.circuits_dir_path).unwrap(); + // Initialize global configuration + REGEX_JSON_DIR_PATH.set(config.regex_json_dir_path).unwrap(); WEB_SERVER_ADDRESS.set(config.web_server_address).unwrap(); PROVER_ADDRESS.set(config.prover_address).unwrap(); PRIVATE_KEY.set(config.private_key).unwrap(); @@ -88,23 +119,26 @@ pub async fn run(config: RelayerConfig) -> Result<()> { .set(config.relayer_email_addr) .unwrap(); SMTP_SERVER.set(config.smtp_server).unwrap(); + ERROR_EMAIL_ADDR.set(config.error_email_addr).unwrap(); + // Spawn the API server task let api_server_task = tokio::task::spawn(async move { loop { match run_server().await { Ok(_) => { - info!(LOG, "run_server exited normally"; "func" => function_name!()); + info!(LOG, "run_server exited normally"); break; // Exit loop if run_server exits normally } Err(err) => { - error!(LOG, "Error api server: {}", err; "func" => function_name!()); - // Optionally, add a delay before restarting + error!(LOG, "Error api server: {}", err); + // Add a delay before restarting to prevent rapid restart loops tokio::time::sleep(Duration::from_secs(5)).await; } } } }); + // Wait for the API server task to complete let _ = tokio::join!(api_server_task); Ok(()) diff --git a/packages/relayer/src/modules/dkim.rs b/packages/relayer/src/modules/dkim.rs index 1be188ef..431ce6f7 100644 --- a/packages/relayer/src/modules/dkim.rs +++ b/packages/relayer/src/modules/dkim.rs @@ -1,5 +1,9 @@ +use std::fs; + use anyhow::anyhow; +use candid::Encode; use relayer_utils::extract_substr_idxes; +use relayer_utils::DecomposedRegexConfig; use relayer_utils::LOG; use crate::*; @@ -10,27 +14,54 @@ use ic_agent::agent::http_transport::ReqwestTransport; use ic_agent::agent::*; use ic_agent::identity::*; use ic_utils::canister::*; - +use ic_utils::interfaces::WalletCanister; use serde::Deserialize; +pub const SIGN_CHARGED_CYCLE: u128 = 39_246_898_590; + +/// Represents a client for interacting with the DKIM Oracle. #[derive(Debug, Clone)] pub struct DkimOracleClient<'a> { - pub canister: Canister<'a>, + /// The dkim oracle canister. + pub dkim_canister: Canister<'a>, + /// The wallet canister. + pub wallet_canister: WalletCanister<'a>, } +/// Represents a signed DKIM public key. #[derive(Default, CandidType, Deserialize, Debug, Clone)] pub struct SignedDkimPublicKey { + /// The selector for the DKIM key pub selector: String, + /// The domain for the DKIM key pub domain: String, + /// The signature of the DKIM key pub signature: String, + /// The public key pub public_key: String, + /// The hash of the public key pub public_key_hash: String, } impl<'a> DkimOracleClient<'a> { + /// Generates an agent for the DKIM Oracle Client. + /// + /// # Arguments + /// + /// * `pem_path` - The path to the PEM file. + /// * `replica_url` - The URL of the replica. + /// + /// # Returns + /// + /// An `anyhow::Result`. pub fn gen_agent(pem_path: &str, replica_url: &str) -> anyhow::Result { + // Create identity from PEM file let identity = Secp256k1Identity::from_pem_file(pem_path)?; + + // Create transport using the replica URL let transport = ReqwestTransport::create(replica_url)?; + + // Build and return the agent let agent = AgentBuilder::default() .with_identity(identity) .with_transport(transport) @@ -38,34 +69,86 @@ impl<'a> DkimOracleClient<'a> { Ok(agent) } - pub fn new(canister_id: &str, agent: &'a Agent) -> anyhow::Result { - let canister = CanisterBuilder::new() + /// Creates a new DkimOracleClient. + /// + /// # Arguments + /// + /// * `dkim_canister_id` - The ID of the dkim canister. + /// * `wallet_canister_id` - The ID of the wallet canister. + /// * `agent` - The agent to use for communication. + /// + /// # Returns + /// + /// An `anyhow::Result`. + pub async fn new( + canister_id: &str, + wallet_canister_id: &str, + agent: &'a Agent, + ) -> anyhow::Result { + // Build the canister using the provided ID and agent + let dkim_canister = CanisterBuilder::new() .with_canister_id(canister_id) - .with_agent(&agent) + .with_agent(agent) .build()?; - Ok(Self { canister }) + let wallet_canister = WalletCanister::from_canister( + ic_utils::Canister::builder() + .with_agent(agent) + .with_canister_id(wallet_canister_id) + .build()?, + ) + .await?; + Ok(Self { + dkim_canister, + wallet_canister, + }) } + /// Requests a signature for a DKIM public key. + /// + /// # Arguments + /// + /// * `selector` - The selector for the DKIM key. + /// * `domain` - The domain for the DKIM key. + /// + /// # Returns + /// + /// An `anyhow::Result`. pub async fn request_signature( &self, selector: &str, domain: &str, ) -> anyhow::Result { - let request = self - .canister - .update("sign_dkim_public_key") - .with_args((selector, domain)) - .build::<(Result,)>(); - let response = request - .call_and_wait_one::>() - .await? - .map_err(|e| anyhow!(format!("Error from canister: {:?}", e)))?; - - Ok(response) + // Build the request to sign the DKIM public key + let mut arg = Argument::new(); + arg.set_raw_arg(Encode!(&selector, &domain).unwrap()); + let (response,) = self + .wallet_canister + .call128::<(Result,), _>( + *self.dkim_canister.canister_id(), + "sign_dkim_public_key", + arg, + SIGN_CHARGED_CYCLE, + ) + .call_and_wait() + .await?; + let sign = response.map_err(|e| anyhow!(format!("Error from canister: {:?}", e)))?; + Ok(sign) } } -#[named] +/// Checks and updates the DKIM for a given email. +/// +/// # Arguments +/// +/// * `email` - The email address. +/// * `parsed_email` - The parsed email data. +/// * `controller_eth_addr` - The Ethereum address of the controller. +/// * `wallet_addr` - The address of the wallet. +/// * `account_salt` - The salt for the account. +/// +/// # Returns +/// +/// A `Result<()>`. pub async fn check_and_update_dkim( email: &str, parsed_email: &ParsedEmail, @@ -73,31 +156,36 @@ pub async fn check_and_update_dkim( wallet_addr: &str, account_salt: &str, ) -> Result<()> { + // Generate public key hash let mut public_key_n = parsed_email.public_key.clone(); public_key_n.reverse(); let public_key_hash = public_key_hash(&public_key_n)?; - info!(LOG, "public_key_hash {:?}", public_key_hash; "func" => function_name!()); + info!(LOG, "public_key_hash {:?}", public_key_hash); + + // Get email domain let domain = parsed_email.get_email_domain()?; - info!(LOG, "domain {:?}", domain; "func" => function_name!()); - if CLIENT.get_bytecode(&wallet_addr.to_string()).await? == Bytes::from(vec![0u8; 20]) { - info!(LOG, "wallet not deployed"; "func" => function_name!()); + info!(LOG, "domain {:?}", domain); + + // Check if wallet is deployed + if CLIENT.get_bytecode(wallet_addr).await? == Bytes::from_static(&[0u8; 20]) { + info!(LOG, "wallet not deployed"); return Ok(()); } + + // Get email auth address from controller let email_auth_addr = CLIENT - .get_email_auth_addr_from_wallet( - &controller_eth_addr.to_string(), - &wallet_addr.to_string(), - &account_salt.to_string(), - ) + .get_email_auth_addr_from_wallet(controller_eth_addr, wallet_addr, account_salt) .await?; let email_auth_addr = format!("0x{:x}", email_auth_addr); - let mut dkim = CLIENT - .get_dkim_from_wallet(&controller_eth_addr.to_string()) - .await?; - if CLIENT.get_bytecode(&email_auth_addr).await? != Bytes::from(vec![]) { + + // Get DKIM from controller or email auth + let mut dkim = CLIENT.get_dkim_from_controller(controller_eth_addr).await?; + if CLIENT.get_bytecode(&email_auth_addr).await? != Bytes::new() { dkim = CLIENT.get_dkim_from_email_auth(&email_auth_addr).await?; } - info!(LOG, "dkim {:?}", dkim; "func" => function_name!()); + info!(LOG, "dkim {:?}", dkim); + + // Check if DKIM public key hash is valid if CLIENT .check_if_dkim_public_key_hash_valid( domain.clone(), @@ -106,38 +194,65 @@ pub async fn check_and_update_dkim( ) .await? { - info!(LOG, "public key registered"; "func" => function_name!()); + info!(LOG, "public key registered"); return Ok(()); } - let selector_decomposed_def = - serde_json::from_str(include_str!("../regex_json/selector_def.json")).unwrap(); + + // Get selector + let selector_def_path = + PathBuf::from(env::var(REGEX_JSON_DIR_PATH_KEY).unwrap()).join("selector_def.json"); + let selector_def_contents = fs::read_to_string(&selector_def_path) + .map_err(|e| anyhow!("Failed to read file {}: {}", selector_def_path.display(), e))?; + let selector_decomposed_def: DecomposedRegexConfig = + serde_json::from_str(&selector_def_contents).map_err(|e| { + anyhow!( + "Failed to parse JSON from file {}: {}", + selector_def_path.display(), + e + ) + })?; let selector = { - let idxes = - extract_substr_idxes(&parsed_email.canonicalized_header, &selector_decomposed_def)?[0]; - let str = parsed_email.canonicalized_header[idxes.0..idxes.1].to_string(); - str + let idxes = extract_substr_idxes( + &parsed_email.canonicalized_header, + &selector_decomposed_def, + false, + )?[0]; + parsed_email.canonicalized_header[idxes.0..idxes.1].to_string() }; - info!(LOG, "selector {}", selector; "func" => function_name!()); + + info!(LOG, "selector {}", selector); + + // Generate IC agent and create oracle client let ic_agent = DkimOracleClient::gen_agent( &env::var(PEM_PATH_KEY).unwrap(), &env::var(IC_REPLICA_URL_KEY).unwrap(), )?; - let oracle_client = DkimOracleClient::new(&env::var(CANISTER_ID_KEY).unwrap(), &ic_agent)?; + let oracle_client = DkimOracleClient::new( + &env::var(DKIM_CANISTER_ID_KEY).unwrap(), + &env::var(WALLET_CANISTER_ID_KEY).unwrap(), + &ic_agent, + ) + .await?; + + // Request signature from oracle let oracle_result = oracle_client.request_signature(&selector, &domain).await?; - info!(LOG, "DKIM oracle result {:?}", oracle_result; "func" => function_name!()); + info!(LOG, "DKIM oracle result {:?}", oracle_result); + + // Process oracle response let public_key_hash = hex::decode(&oracle_result.public_key_hash[2..])?; - info!(LOG, "public_key_hash from oracle {:?}", public_key_hash; "func" => function_name!()); + info!(LOG, "public_key_hash from oracle {:?}", public_key_hash); let signature = Bytes::from_hex(&oracle_result.signature[2..])?; - info!(LOG, "signature {:?}", signature; "func" => function_name!()); + info!(LOG, "signature {:?}", signature); + + // Set DKIM public key hash let tx_hash = CLIENT .set_dkim_public_key_hash( - selector, domain, TryInto::<[u8; 32]>::try_into(public_key_hash).unwrap(), signature, dkim, ) .await?; - info!(LOG, "DKIM registry updated {:?}", tx_hash; "func" => function_name!()); + info!(LOG, "DKIM registry updated {:?}", tx_hash); Ok(()) } diff --git a/packages/relayer/src/modules/mail.rs b/packages/relayer/src/modules/mail.rs index d9c114d5..2d82f091 100644 --- a/packages/relayer/src/modules/mail.rs +++ b/packages/relayer/src/modules/mail.rs @@ -1,16 +1,18 @@ +use crate::core::EmailRequestContext; use crate::*; use handlebars::Handlebars; use serde::{Deserialize, Serialize}; use serde_json::Value; use tokio::fs::read_to_string; +/// Represents different types of email authentication events. #[derive(Debug, Clone)] pub enum EmailAuthEvent { AcceptanceRequest { account_eth_addr: String, guardian_email_addr: String, request_id: u32, - subject: String, + command: String, account_code: String, }, GuardianAlreadyExists { @@ -20,22 +22,30 @@ pub enum EmailAuthEvent { Error { email_addr: String, error: String, + original_subject: String, + original_message_id: Option, + email_request_context: Option>, + command: Option, }, RecoveryRequest { account_eth_addr: String, guardian_email_addr: String, request_id: u32, - subject: String, + command: String, }, AcceptanceSuccess { account_eth_addr: String, guardian_email_addr: String, request_id: u32, + original_subject: String, + original_message_id: Option, }, RecoverySuccess { account_eth_addr: String, guardian_email_addr: String, request_id: u32, + original_subject: String, + original_message_id: Option, }, GuardianNotSet { account_eth_addr: String, @@ -44,17 +54,19 @@ pub enum EmailAuthEvent { GuardianNotRegistered { account_eth_addr: String, guardian_email_addr: String, - subject: String, + command: String, request_id: u32, }, Ack { email_addr: String, - subject: String, + command: String, original_message_id: Option, + original_subject: String, }, NoOp, } +/// Represents an email message to be sent. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct EmailMessage { pub to: String, @@ -66,6 +78,7 @@ pub struct EmailMessage { pub body_attachments: Option>, } +/// Represents an attachment in an email message. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct EmailAttachment { pub inline_id: String, @@ -73,32 +86,49 @@ pub struct EmailAttachment { pub contents: Vec, } -pub async fn handle_email_event(event: EmailAuthEvent) -> Result<()> { +/// Handles all possible email events and requests. +/// +/// # Arguments +/// +/// * `event` - The `EmailAuthEvent` to be handled. +/// +/// # Returns +/// +/// A `Result` indicating success or an `EmailError`. +pub async fn handle_email_event(event: EmailAuthEvent) -> Result<(), EmailError> { match event { EmailAuthEvent::AcceptanceRequest { account_eth_addr, guardian_email_addr, request_id, - subject, + command, account_code, } => { - let subject = format!("{} Code {}", subject, account_code); + // Prepare the command with the account code + let command = format!("{} Code {}", command, account_code); + // Create the plain text body let body_plain = format!( "You have received an guardian request from the wallet address {}. \ + {} Code {}. \ Reply \"Confirm\" to this email to accept the request. \ Your request ID is #{}. \ If you did not initiate this request, please contact us immediately.", - account_eth_addr, request_id + account_eth_addr, command, account_code, request_id ); + let subject = "[Reply Needed] Recovery: Acceptance Request".to_string(); + + // Prepare data for HTML rendering let render_data = serde_json::json!({ "userEmailAddr": guardian_email_addr, "walletAddress": account_eth_addr, + "command": command, "requestId": request_id, }); let body_html = render_html("acceptance_request.html", render_data).await?; + // Create and send the email let email = EmailMessage { to: guardian_email_addr, subject, @@ -109,33 +139,93 @@ pub async fn handle_email_event(event: EmailAuthEvent) -> Result<()> { body_attachments: None, }; - send_email(email).await?; + send_email(email, Some(ExpectsReply::new(request_id))).await?; } - EmailAuthEvent::Error { email_addr, error } => { - let subject = "Error"; + EmailAuthEvent::Error { + email_addr, + error, + original_subject, + original_message_id, + email_request_context, + command, + } => { + // Send error notification to system user if this is a contract call error + if let (Some(email_request_context), Some(command)) = (email_request_context, command) { + let recipient_email = ERROR_EMAIL_ADDR + .get() + .expect("ERROR_EMAIL_ADDR must be set before use") + .clone(); + + let body_plain = format!( + "Error: {}\n\n\ + Request ID: {}\n\ + Command: {}\n\ + Account Address: {}\n\ + Controller Address: {}\n\n\ + Email:\n{}", + error, + email_request_context.request.request_id, + command, + email_request_context.request.account_eth_addr, + email_request_context.request.controller_eth_addr, + email_request_context.email + ); + + let render_data = serde_json::json!({ + "error": error, + "requestId": email_request_context.request.request_id, + "command": command, + "account_address": email_request_context.request.account_eth_addr, + "controller_address": email_request_context.request.controller_eth_addr, + "email": email_request_context.email, + }); + + let subject = format!( + "[Error] Request ID: {}", + email_request_context.request.request_id + ); + let body_html = render_html("error_for_admin.html", render_data).await?; + + let email = EmailMessage { + to: recipient_email, + subject, + reference: None, + reply_to: None, + body_plain, + body_html, + body_attachments: None, + }; + + send_email(email, None).await?; + } + + let subject = format!("Re: {}", original_subject); + let body_plain = format!( "An error occurred while processing your request. \ Error: {}", error ); + // Prepare data for HTML rendering let render_data = serde_json::json!({ "error": error, "userEmailAddr": email_addr, }); let body_html = render_html("error.html", render_data).await?; + // Create and send the email let email = EmailMessage { to: email_addr, - subject: subject.to_string(), - reference: None, - reply_to: None, + subject, + reference: original_message_id.clone(), + reply_to: original_message_id, body_plain, body_html, body_attachments: None, }; - send_email(email).await?; + send_email(email, None).await?; } EmailAuthEvent::GuardianAlreadyExists { account_eth_addr, @@ -148,12 +238,14 @@ pub async fn handle_email_event(event: EmailAuthEvent) -> Result<()> { guardian_email_addr, account_eth_addr ); + // Prepare data for HTML rendering let render_data = serde_json::json!({ "walletAddress": account_eth_addr, "userEmailAddr": guardian_email_addr, }); let body_html = render_html("guardian_already_exists.html", render_data).await?; + // Create and send the email let email = EmailMessage { to: guardian_email_addr, subject: subject.to_string(), @@ -164,13 +256,13 @@ pub async fn handle_email_event(event: EmailAuthEvent) -> Result<()> { body_attachments: None, }; - send_email(email).await?; + send_email(email, None).await?; } EmailAuthEvent::RecoveryRequest { account_eth_addr, guardian_email_addr, request_id, - subject, + command, } => { let body_plain = format!( "You have received a recovery request from the wallet address {}. \ @@ -180,13 +272,18 @@ pub async fn handle_email_event(event: EmailAuthEvent) -> Result<()> { account_eth_addr, request_id ); + let subject = "[Reply Needed] Recovery: Recovery Request".to_string(); + + // Prepare data for HTML rendering let render_data = serde_json::json!({ "userEmailAddr": guardian_email_addr, "walletAddress": account_eth_addr, + "command": command, "requestId": request_id, }); let body_html = render_html("recovery_request.html", render_data).await?; + // Create and send the email let email = EmailMessage { to: guardian_email_addr, subject, @@ -197,20 +294,23 @@ pub async fn handle_email_event(event: EmailAuthEvent) -> Result<()> { body_attachments: None, }; - send_email(email).await?; + send_email(email, Some(ExpectsReply::new(request_id))).await?; } EmailAuthEvent::AcceptanceSuccess { account_eth_addr, guardian_email_addr, request_id, + original_subject, + original_message_id, } => { - let subject = "Acceptance Success"; + let subject = format!("Re: {}", original_subject); let body_plain = format!( "Your guardian request for the wallet address {} has been set. \ Your request ID is #{} is now complete.", account_eth_addr, request_id ); + // Prepare data for HTML rendering let render_data = serde_json::json!({ "walletAddress": account_eth_addr, "userEmailAddr": guardian_email_addr, @@ -218,30 +318,34 @@ pub async fn handle_email_event(event: EmailAuthEvent) -> Result<()> { }); let body_html = render_html("acceptance_success.html", render_data).await?; + // Create and send the email let email = EmailMessage { to: guardian_email_addr, subject: subject.to_string(), - reference: None, - reply_to: None, + reference: original_message_id.clone(), + reply_to: original_message_id, body_plain, body_html, body_attachments: None, }; - send_email(email).await?; + send_email(email, None).await?; } EmailAuthEvent::RecoverySuccess { account_eth_addr, guardian_email_addr, request_id, + original_subject, + original_message_id, } => { - let subject = "Recovery Success"; + let subject = format!("Re: {}", original_subject); let body_plain = format!( "Your recovery request for the wallet address {} is successful. \ Your request ID is #{}.", account_eth_addr, request_id ); + // Prepare data for HTML rendering let render_data = serde_json::json!({ "walletAddress": account_eth_addr, "userEmailAddr": guardian_email_addr, @@ -249,17 +353,18 @@ pub async fn handle_email_event(event: EmailAuthEvent) -> Result<()> { }); let body_html = render_html("recovery_success.html", render_data).await?; + // Create and send the email let email = EmailMessage { to: guardian_email_addr, subject: subject.to_string(), - reference: None, - reply_to: None, + reference: original_message_id.clone(), + reply_to: original_message_id, body_plain, body_html, body_attachments: None, }; - send_email(email).await?; + send_email(email, None).await?; } EmailAuthEvent::GuardianNotSet { account_eth_addr, @@ -268,12 +373,14 @@ pub async fn handle_email_event(event: EmailAuthEvent) -> Result<()> { let subject = "Guardian Not Set"; let body_plain = format!("Guardian not set for wallet address {}", account_eth_addr); + // Prepare data for HTML rendering let render_data = serde_json::json!({ "walletAddress": account_eth_addr, "userEmailAddr": guardian_email_addr, }); let body_html = render_html("guardian_not_set.html", render_data).await?; + // Create and send the email let email = EmailMessage { to: guardian_email_addr, subject: subject.to_string(), @@ -284,31 +391,36 @@ pub async fn handle_email_event(event: EmailAuthEvent) -> Result<()> { body_attachments: None, }; - send_email(email).await?; + send_email(email, None).await?; } EmailAuthEvent::GuardianNotRegistered { account_eth_addr, guardian_email_addr, - subject, + command, request_id, } => { - let subject = format!("{} Code ", subject); + let command = format!("{} Code ", command); let body_plain = format!( "You have received an guardian request from the wallet address {}. \ - Add the guardian's account code in the subject and reply to this email. \ + Reply to this email. \ Your request ID is #{}. \ If you did not initiate this request, please contact us immediately.", account_eth_addr, request_id ); + // Prepare data for HTML rendering let render_data = serde_json::json!({ "userEmailAddr": guardian_email_addr, "walletAddress": account_eth_addr, "requestId": request_id, + "command": command, }); + + let subject = "Guardian Not Registered".to_string(); let body_html = render_html("credential_not_present.html", render_data).await?; + // Create and send the email let email = EmailMessage { to: guardian_email_addr, subject, @@ -319,20 +431,23 @@ pub async fn handle_email_event(event: EmailAuthEvent) -> Result<()> { body_attachments: None, }; - send_email(email).await?; + send_email(email, Some(ExpectsReply::new(request_id))).await?; } EmailAuthEvent::Ack { email_addr, - subject, + command, original_message_id, + original_subject, } => { let body_plain = format!( - "Hi {}!\nYour email with the subject {} is received.", - email_addr, subject + "Hi {}!\nYour email with the command {} is received.", + email_addr, command ); - let render_data = serde_json::json!({"userEmailAddr": email_addr, "request": subject}); + // Prepare data for HTML rendering + let render_data = serde_json::json!({"userEmailAddr": email_addr, "request": command}); let body_html = render_html("acknowledgement.html", render_data).await?; - let subject = format!("Re: {}", subject); + let subject = format!("Re: {}", original_subject); + // Create and send the email let email = EmailMessage { to: email_addr, subject, @@ -342,7 +457,7 @@ pub async fn handle_email_event(event: EmailAuthEvent) -> Result<()> { reply_to: original_message_id, body_attachments: None, }; - send_email(email).await?; + send_email(email, None).await?; } EmailAuthEvent::NoOp => {} } @@ -350,20 +465,53 @@ pub async fn handle_email_event(event: EmailAuthEvent) -> Result<()> { Ok(()) } -pub async fn render_html(template_name: &str, render_data: Value) -> Result { +/// Renders an HTML template with the given data. +/// +/// # Arguments +/// +/// * `template_name` - The name of the template file. +/// * `render_data` - The data to be used in rendering the template. +/// +/// # Returns +/// +/// A `Result` containing the rendered HTML string or an `EmailError`. +async fn render_html(template_name: &str, render_data: Value) -> Result { + // Construct the full path to the email template let email_template_filename = PathBuf::new() .join(EMAIL_TEMPLATES.get().unwrap()) .join(template_name); - let email_template = read_to_string(&email_template_filename).await?; + // Read the email template file + let email_template = read_to_string(&email_template_filename) + .await + .map_err(|e| { + EmailError::FileNotFound(format!( + "Could not get email template {}: {}", + template_name, e + )) + })?; + + // Create a new Handlebars instance let reg = Handlebars::new(); - Ok(reg.render_template(&email_template, &render_data)?) + // Render the template with the provided data + let template = reg.render_template(&email_template, &render_data)?; + Ok(template) } -pub fn parse_error(error: String) -> Result> { +/// Parses an error string and returns a more user-friendly error message. +/// +/// # Arguments +/// +/// * `error` - The error string to be parsed. +/// +/// # Returns +/// +/// A `Result` containing an `Option` with the parsed error message. +fn parse_error(error: String) -> Result> { let mut error = error; if error.contains("Contract call reverted with data: ") { + // Extract and decode the revert data let revert_data = error .replace("Contract call reverted with data: ", "") .split_at(10) @@ -372,11 +520,12 @@ pub fn parse_error(error: String) -> Result> { let revert_bytes = hex::decode(revert_data) .unwrap() .into_iter() - .filter(|&b| b >= 0x20 && b <= 0x7E) + .filter(|&b| (0x20..=0x7E).contains(&b)) .collect(); error = String::from_utf8(revert_bytes).unwrap().trim().to_string(); } + // Match known error messages and provide user-friendly responses match error.as_str() { "Account is already created" => Ok(Some(error)), "insufficient balance" => Ok(Some("You don't have sufficient balance".to_string())), @@ -384,7 +533,20 @@ pub fn parse_error(error: String) -> Result> { } } -pub async fn send_email(email: EmailMessage) -> Result<()> { +/// Sends an email using the configured SMTP server. +/// +/// # Arguments +/// +/// * `email` - The `EmailMessage` to be sent. +/// * `expects_reply` - An optional `ExpectsReply` struct indicating if a reply is expected. +/// +/// # Returns +/// +/// A `Result` indicating success or an `EmailError`. +async fn send_email( + email: EmailMessage, + expects_reply: Option, +) -> Result<(), EmailError> { let smtp_server = SMTP_SERVER.get().unwrap(); // Send POST request to email server @@ -394,14 +556,85 @@ pub async fn send_email(email: EmailMessage) -> Result<()> { .json(&email) .send() .await - .map_err(|e| anyhow!("Failed to send email: {}", e))?; + .map_err(|e| EmailError::Send(format!("Failed to send email: {}", e)))?; + // Check if the email was sent successfully if !response.status().is_success() { - return Err(anyhow!( + return Err(EmailError::Send(format!( "Failed to send email: {}", response.text().await.unwrap_or_default() - )); + ))); + } + + // Handle expected reply if necessary + if let Some(expects_reply) = expects_reply { + let response_body: EmailResponse = response + .json() + .await + .map_err(|e| EmailError::Parse(format!("Failed to parse response JSON: {}", e)))?; + + let message_id = response_body.message_id; + DB.add_expected_reply(&message_id, expects_reply.request_id) + .await?; } Ok(()) } + +/// Represents the response from the email server after sending an email. +#[derive(Debug, Clone, Serialize, Deserialize)] +struct EmailResponse { + status: String, + message_id: String, +} + +/// Represents an expectation of a reply to an email. +pub struct ExpectsReply { + request_id: Option, +} + +impl ExpectsReply { + /// Creates a new `ExpectsReply` instance with a request ID. + /// + /// # Arguments + /// + /// * `request_id` - The ID of the request expecting a reply. + fn new(request_id: u32) -> Self { + Self { + request_id: Some(request_id.to_string()), + } + } + + /// Creates a new `ExpectsReply` instance without a request ID. + fn new_no_request_id() -> Self { + Self { request_id: None } + } +} + +/// Checks if the email is a reply to a command that expects a reply. +/// Will return false for duplicate replies. +/// Will return true if the email is not a reply. +/// +/// # Arguments +/// +/// * `email` - The `ParsedEmail` to be checked. +/// +/// # Returns +/// +/// A `Result` containing a boolean indicating if the request is valid. +pub async fn check_is_valid_request(email: &ParsedEmail) -> Result { + // Check if the email is a reply by looking for the "In-Reply-To" header + let reply_message_id = match email + .headers + .get_header("In-Reply-To") + .and_then(|v| v.first().cloned()) + { + Some(id) => id, + // Email is not a reply, so it's valid + None => return Ok(true), + }; + + // Check if the reply is valid (not a duplicate) using the database + let is_valid = DB.is_valid_reply(&reply_message_id).await?; + Ok(is_valid) +} diff --git a/packages/relayer/src/modules/mod.rs b/packages/relayer/src/modules/mod.rs index 5ace1b92..eaf1adc5 100644 --- a/packages/relayer/src/modules/mod.rs +++ b/packages/relayer/src/modules/mod.rs @@ -1,3 +1,5 @@ +//! This module contains the dkim, mail and web_server modules. + pub mod dkim; pub mod mail; pub mod web_server; diff --git a/packages/relayer/src/modules/web_server/mod.rs b/packages/relayer/src/modules/web_server/mod.rs index 7dffbb07..3a48beb6 100644 --- a/packages/relayer/src/modules/web_server/mod.rs +++ b/packages/relayer/src/modules/web_server/mod.rs @@ -1,5 +1,9 @@ +//! This module contains the axum web server and its routes and custom errors. + +pub mod relayer_errors; pub mod rest_api; pub mod server; +pub use relayer_errors::*; pub use rest_api::*; pub use server::*; diff --git a/packages/relayer/src/modules/web_server/relayer_errors.rs b/packages/relayer/src/modules/web_server/relayer_errors.rs new file mode 100644 index 00000000..8b49462a --- /dev/null +++ b/packages/relayer/src/modules/web_server/relayer_errors.rs @@ -0,0 +1,223 @@ +use crate::*; +use axum::{ + response::{IntoResponse, Response}, + Json, +}; +use handlebars::RenderError; +use relayer_utils::ExtractSubstrssError; +use reqwest::StatusCode; +use rustc_hex::FromHexError; +use serde_json::json; +use thiserror::Error; + +/// Custom error type for API-related errors +#[derive(Error, Debug)] +pub enum ApiError { + #[error("Database error: {0}")] + Database(#[from] DatabaseError), + #[error("Sqlx error: {0}")] + SqlxError(#[from] sqlx::Error), + #[error("Validation error: {0}")] + Validation(String), + #[error("Chain error: {0}")] + Chain(#[from] ChainError), + // #[error("Not found: {0}")] + // NotFound(String), + #[error("Anyhow error: {0}")] + Anyhow(#[from] anyhow::Error), + #[error("Internal error: {0}")] + Internal(String), + #[error("Error recieving email: {0}")] + Email(#[from] EmailError), +} + +/// Custom error type for email-related errors +#[derive(Error, Debug)] +pub enum EmailError { + #[error("Email body error: {0}")] + Body(String), + #[error("Email address error: {0}")] + EmailAddress(String), + #[error("Parse error: {0}")] + Parse(String), + #[error("DKIM error: {0}")] + Dkim(String), + #[error("ZkRegex error: {0}")] + ZkRegex(#[from] ExtractSubstrssError), + #[error("Database error: {0}")] + Database(#[from] DatabaseError), + #[error("Not found: {0}")] + NotFound(String), + #[error("Circuit error: {0}")] + Circuit(String), + #[error("Chain error: {0}")] + Chain(#[from] ChainError), + #[error("File not found error: {0}")] + FileNotFound(String), + #[error("Render error: {0}")] + Render(#[from] RenderError), + #[error("Failed to send email: {0}")] + Send(String), + #[error("Hex error: {0}")] + HexError(#[from] hex::FromHexError), + #[error("ABI encode error: {0}")] + AbiError(String), + // Currently used with some relayer-utils errors + #[error("Anyhow error: {0}")] + Anyhow(#[from] anyhow::Error), +} + +/// Custom error type for blockchain-related errors +#[derive(Error, Debug)] +pub enum ChainError { + #[error("Contract error: {0}")] + Contract(ContractErrorWrapper), + #[error("Signer middleware error: {0}")] + SignerMiddleware(SignerMiddlewareErrorWrapper), + #[error("Hex error: {0}")] + HexError(#[from] FromHexError), + #[error("Provider error: {0}")] + Provider(ProviderErrorWrapper), + #[error("Anyhow error: {0}")] + Anyhow(#[from] anyhow::Error), + #[error("Validation error: {0}")] + Validation(String), +} + +impl ChainError { + pub fn contract_error(msg: &str, err: ContractError) -> Self { + Self::Contract(ContractErrorWrapper::new(msg.to_string(), err)) + } + + pub fn signer_middleware_error( + msg: &str, + err: signer::SignerMiddlewareError, + ) -> Self { + Self::SignerMiddleware(SignerMiddlewareErrorWrapper::new(msg.to_string(), err)) + } + + pub fn provider_error(msg: &str, err: ethers::providers::ProviderError) -> Self { + Self::Provider(ProviderErrorWrapper::new(msg.to_string(), err)) + } +} + +/// Custom error type for database-related errors +#[derive(Debug, thiserror::Error)] +#[error("{msg}: {source}")] +pub struct DatabaseError { + #[source] + pub source: sqlx::Error, + pub msg: String, +} + +impl DatabaseError { + pub fn new(msg: &str, source: sqlx::Error) -> Self { + Self { + source, + msg: msg.to_string(), + } + } +} + +/// Wrapper for contract-related errors +#[derive(Debug)] +pub struct ContractErrorWrapper { + msg: String, + source: String, +} + +impl std::fmt::Display for ContractErrorWrapper { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}: {}", self.msg, self.source) + } +} + +impl ContractErrorWrapper { + pub fn new(msg: String, err: ContractError) -> Self { + ContractErrorWrapper { + msg, + source: err.to_string(), + } + } +} + +/// Wrapper for signer middleware-related errors +#[derive(Debug)] +pub struct SignerMiddlewareErrorWrapper { + msg: String, + source: String, +} + +impl std::fmt::Display for SignerMiddlewareErrorWrapper { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}: {}", self.msg, self.source) + } +} + +impl SignerMiddlewareErrorWrapper { + pub fn new( + msg: String, + err: signer::SignerMiddlewareError, + ) -> Self { + SignerMiddlewareErrorWrapper { + msg, + source: err.to_string(), + } + } +} + +/// Wrapper for provider-related errors +#[derive(Debug)] +pub struct ProviderErrorWrapper { + msg: String, + source: ethers::providers::ProviderError, +} + +impl std::fmt::Display for ProviderErrorWrapper { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}: {}", self.msg, self.source) + } +} + +impl ProviderErrorWrapper { + pub fn new(msg: String, err: ethers::providers::ProviderError) -> Self { + ProviderErrorWrapper { msg, source: err } + } +} + +impl ApiError { + pub fn database_error(msg: &str, source: sqlx::Error) -> Self { + Self::Database(DatabaseError::new(msg, source)) + } +} + +impl IntoResponse for ApiError { + fn into_response(self) -> Response { + let (status, error_message) = match self { + ApiError::Database(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + ApiError::Chain(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + ApiError::SqlxError(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + ApiError::Validation(e) => (StatusCode::BAD_REQUEST, e.to_string()), + ApiError::Anyhow(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + ApiError::Internal(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + ApiError::Email(e) => match e { + EmailError::Body(e) => (StatusCode::BAD_REQUEST, e.to_string()), + EmailError::EmailAddress(e) => (StatusCode::BAD_REQUEST, e.to_string()), + EmailError::Parse(e) => (StatusCode::BAD_REQUEST, e.to_string()), + EmailError::NotFound(e) => (StatusCode::BAD_REQUEST, e.to_string()), + EmailError::Dkim(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + EmailError::ZkRegex(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + EmailError::Database(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + EmailError::HexError(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + EmailError::AbiError(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + EmailError::Circuit(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + EmailError::Chain(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + EmailError::FileNotFound(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + EmailError::Render(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + EmailError::Send(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + EmailError::Anyhow(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + }, + }; + (status, Json(json!({ "error": error_message }))).into_response() + } +} diff --git a/packages/relayer/src/modules/web_server/rest_api.rs b/packages/relayer/src/modules/web_server/rest_api.rs index f9668bc7..39661929 100644 --- a/packages/relayer/src/modules/web_server/rest_api.rs +++ b/packages/relayer/src/modules/web_server/rest_api.rs @@ -1,95 +1,29 @@ use crate::*; use anyhow::Result; -use axum::{body::Body, response::Response}; +use axum::Json; use hex::decode; use rand::Rng; -use relayer_utils::LOG; -use reqwest::StatusCode; +use relayer_utils::{ + calculate_account_salt, extract_template_vals_from_command, TemplateValue, LOG, +}; use serde::{Deserialize, Serialize}; -use slog::log; use std::str; -#[derive(Serialize, Deserialize)] -pub struct RequestStatusRequest { - pub request_id: u32, -} - -#[derive(Serialize, Deserialize)] -pub enum RequestStatus { - NotExist = 0, - Pending = 1, - Processed = 2, -} - -#[derive(Serialize, Deserialize)] -pub struct RequestStatusResponse { - pub request_id: u32, - pub status: RequestStatus, - pub is_success: bool, - pub email_nullifier: Option, - pub account_salt: Option, -} - -#[derive(Serialize, Deserialize)] -pub struct AcceptanceRequest { - pub controller_eth_addr: String, - pub guardian_email_addr: String, - pub account_code: String, - pub template_idx: u64, - pub subject: String, -} - -#[derive(Serialize, Deserialize)] -pub struct AcceptanceResponse { - pub request_id: u32, - pub subject_params: Vec, -} - -#[derive(Serialize, Deserialize)] -pub struct RecoveryRequest { - pub controller_eth_addr: String, - pub guardian_email_addr: String, - pub template_idx: u64, - pub subject: String, -} - -#[derive(Serialize, Deserialize)] -pub struct RecoveryResponse { - pub request_id: u32, - pub subject_params: Vec, -} - -#[derive(Serialize, Deserialize)] -pub struct CompleteRecoveryRequest { - pub account_eth_addr: String, - pub controller_eth_addr: String, - pub complete_calldata: String, -} - -#[derive(Serialize, Deserialize)] -pub struct GetAccountSaltRequest { - pub account_code: String, - pub email_addr: String, -} - -#[derive(Deserialize)] -struct PermittedWallet { - wallet_name: String, - controller_eth_addr: String, - hash_of_bytecode_of_proxy: String, - impl_contract_address: String, - slot_location: String, -} - -#[derive(Serialize, Deserialize)] -pub struct InactiveGuardianRequest { - pub account_eth_addr: String, - pub controller_eth_addr: String, -} - -// Create request status API -pub async fn request_status_api(payload: RequestStatusRequest) -> Result { +/// Retrieves the status of a request. +/// +/// # Arguments +/// +/// * `payload` - A JSON payload containing the request ID. +/// +/// # Returns +/// +/// A `Result` containing a JSON `RequestStatusResponse` or an `ApiError`. +pub async fn request_status_api( + Json(payload): Json, +) -> Result, ApiError> { let row = DB.get_request(payload.request_id).await?; + + // Determine the status based on the retrieved row let status = if let Some(ref row) = row { if row.is_processed { RequestStatus::Processed @@ -99,7 +33,8 @@ pub async fn request_status_api(payload: RequestStatusRequest) -> Result Result Response { - let subject_template = CLIENT - .get_acceptance_subject_templates(&payload.controller_eth_addr, payload.template_idx) - .await - .unwrap(); - - let subject_params = extract_template_vals(&payload.subject, subject_template); - - if subject_params.is_err() { - return Response::builder() - .status(StatusCode::BAD_REQUEST) - .body(Body::from("Invalid subject")) - .unwrap(); - } - - let subject_params = subject_params.unwrap(); - +/// Handles an acceptance request for a wallet. +/// +/// # Arguments +/// +/// * `payload` - A JSON payload containing the acceptance request details. +/// +/// # Returns +/// +/// A `Result` containing a JSON `AcceptanceResponse` or an `ApiError`. +pub async fn handle_acceptance_request( + Json(payload): Json, +) -> Result, ApiError> { + let command_template = CLIENT + .get_acceptance_command_templates(&payload.controller_eth_addr, payload.template_idx) + .await?; + + // Extract and validate command parameters + let command_params = extract_template_vals_from_command(&payload.command, command_template) + .map_err(|_| ApiError::Validation("Invalid command".to_string()))?; + + // Recover the account address let account_eth_addr = CLIENT - .get_recovered_account_from_acceptance_subject( + .get_recovered_account_from_acceptance_command( &payload.controller_eth_addr, - subject_params.clone(), + command_params.clone(), payload.template_idx, ) - .await - .unwrap(); + .await?; let account_eth_addr = format!("0x{:x}", account_eth_addr); - if !CLIENT.is_wallet_deployed(&account_eth_addr).await { - return Response::builder() - .status(StatusCode::BAD_REQUEST) - .body(Body::from("Wallet not deployed")) - .unwrap(); + // Check if the wallet is deployed + if !CLIENT.is_wallet_deployed(&account_eth_addr).await? { + return Err(ApiError::Validation("Wallet not deployed".to_string())); } - // Check if hash of bytecode of proxy contract is equal or not - let bytecode = CLIENT.get_bytecode(&account_eth_addr).await.unwrap(); - let bytecode_hash = format!("0x{}", hex::encode(keccak256(bytecode.as_ref()))); - - // let permitted_wallets: Vec = - // serde_json::from_str(include_str!("../../permitted_wallets.json")).unwrap(); - // let permitted_wallet = permitted_wallets - // .iter() - // .find(|w| w.hash_of_bytecode_of_proxy == bytecode_hash); - - // if let Some(permitted_wallet) = permitted_wallet { - // let slot_location = permitted_wallet.slot_location.parse::().unwrap(); - // let impl_contract_from_proxy = { - // let raw_hex = hex::encode( - // CLIENT - // .get_storage_at(&account_eth_addr, slot_location) - // .await - // .unwrap(), - // ); - // format!("0x{}", &raw_hex[24..]) - // }; - - // if !permitted_wallet - // .impl_contract_address - // .eq_ignore_ascii_case(&impl_contract_from_proxy) - // { - // return Response::builder() - // .status(StatusCode::BAD_REQUEST) - // .body(Body::from( - // "Invalid bytecode, impl contract address mismatch", - // )) - // .unwrap(); - // } - - // if !permitted_wallet - // .controller_eth_addr - // .eq_ignore_ascii_case(&payload.controller_eth_addr) - // { - // return Response::builder() - // .status(StatusCode::BAD_REQUEST) - // .body(Body::from("Invalid controller eth addr")) - // .unwrap(); - // } - // } else { - // return Response::builder() - // .status(StatusCode::BAD_REQUEST) - // .body(Body::from("Wallet not permitted")) - // .unwrap(); - // } - + // Check if the account code is already used if let Ok(Some(creds)) = DB.get_credentials(&payload.account_code).await { - return Response::builder() - .status(StatusCode::BAD_REQUEST) - .body(Body::from("Account code already used")) - .unwrap(); + return Err(ApiError::Validation( + "Account code already used".to_string(), + )); } + // Generate a unique request ID let mut request_id = rand::thread_rng().gen::(); while let Ok(Some(request)) = DB.get_request(request_id).await { request_id = rand::thread_rng().gen::(); @@ -209,227 +96,140 @@ pub async fn handle_acceptance_request(payload: AcceptanceRequest) -> Response Response { - let subject_template = CLIENT - .get_recovery_subject_templates(&payload.controller_eth_addr, payload.template_idx) - .await - .unwrap(); - - let subject_params = extract_template_vals(&payload.subject, subject_template); - - if subject_params.is_err() { - return Response::builder() - .status(StatusCode::BAD_REQUEST) - .body(Body::from("Invalid subject")) - .unwrap(); - } - - let subject_params = subject_params.unwrap(); - +/// Handles a recovery request for a wallet. +/// +/// # Arguments +/// +/// * `payload` - A JSON payload containing the recovery request details. +/// +/// # Returns +/// +/// A `Result` containing a JSON `RecoveryResponse` or an `ApiError`. +pub async fn handle_recovery_request( + Json(payload): Json, +) -> Result, ApiError> { + // Fetch the command template + let command_template = CLIENT + .get_recovery_command_templates(&payload.controller_eth_addr, payload.template_idx) + .await?; + + // Extract and validate command parameters + let command_params = extract_template_vals_from_command(&payload.command, command_template) + .map_err(|_| ApiError::Validation("Invalid command".to_string()))?; + + // Recover the account address let account_eth_addr = CLIENT - .get_recovered_account_from_recovery_subject( + .get_recovered_account_from_recovery_command( &payload.controller_eth_addr, - subject_params.clone(), + command_params.clone(), payload.template_idx, ) - .await - .unwrap(); + .await?; let account_eth_addr = format!("0x{:x}", account_eth_addr); - if !CLIENT.is_wallet_deployed(&account_eth_addr).await { - return Response::builder() - .status(StatusCode::BAD_REQUEST) - .body(Body::from("Wallet not deployed")) - .unwrap(); + // Check if the wallet is deployed + if !CLIENT.is_wallet_deployed(&account_eth_addr).await? { + return Err(ApiError::Validation("Wallet not deployed".to_string())); } - // Check if hash of bytecode of proxy contract is equal or not - let bytecode = CLIENT.get_bytecode(&account_eth_addr).await.unwrap(); - let bytecode_hash = format!("0x{}", hex::encode(keccak256(bytecode.as_ref()))); - - // let permitted_wallets: Vec = - // serde_json::from_str(include_str!("../../permitted_wallets.json")).unwrap(); - // let permitted_wallet = permitted_wallets - // .iter() - // .find(|w| w.hash_of_bytecode_of_proxy == bytecode_hash); - - // if let Some(permitted_wallet) = permitted_wallet { - // let slot_location = permitted_wallet.slot_location.parse::().unwrap(); - // let impl_contract_from_proxy = { - // let raw_hex = hex::encode( - // CLIENT - // .get_storage_at(&account_eth_addr, slot_location) - // .await - // .unwrap(), - // ); - // format!("0x{}", &raw_hex[24..]) - // }; - - // if !permitted_wallet - // .impl_contract_address - // .eq_ignore_ascii_case(&impl_contract_from_proxy) - // { - // return Response::builder() - // .status(StatusCode::BAD_REQUEST) - // .body(Body::from( - // "Invalid bytecode, impl contract address mismatch", - // )) - // .unwrap(); - // } - - // if !permitted_wallet - // .controller_eth_addr - // .eq_ignore_ascii_case(&payload.controller_eth_addr) - // { - // return Response::builder() - // .status(StatusCode::BAD_REQUEST) - // .body(Body::from("Invalid controller eth addr")) - // .unwrap(); - // } - // } else { - // return Response::builder() - // .status(StatusCode::BAD_REQUEST) - // .body(Body::from("Wallet not permitted")) - // .unwrap(); - // } - + // Generate a unique request ID let mut request_id = rand::thread_rng().gen::(); while let Ok(Some(request)) = DB.get_request(request_id).await { request_id = rand::thread_rng().gen::(); } + // Fetch account details and calculate account salt let account = DB .get_credentials_from_wallet_and_email(&account_eth_addr, &payload.guardian_email_addr) - .await; + .await?; - let account_salt = if let Ok(Some(account_details)) = account { + let account_salt = if let Some(account_details) = account { calculate_account_salt(&payload.guardian_email_addr, &account_details.account_code) } else { - return Response::builder() - .status(StatusCode::BAD_REQUEST) - .body(Body::from("Account details not found")) - .unwrap(); + return Err(ApiError::Validation("Wallet not deployed".to_string())); }; + // Handle the case when wallet and email are not registered if !DB .is_wallet_and_email_registered(&account_eth_addr, &payload.guardian_email_addr) - .await + .await? { DB.insert_request(&Request { - request_id: request_id.clone(), + request_id, account_eth_addr: account_eth_addr.clone(), controller_eth_addr: payload.controller_eth_addr.clone(), guardian_email_addr: payload.guardian_email_addr.clone(), @@ -440,103 +240,85 @@ pub async fn handle_recovery_request(payload: RecoveryRequest) -> Response email_nullifier: None, account_salt: Some(account_salt.clone()), }) - .await - .expect("Failed to insert request"); + .await?; handle_email_event(EmailAuthEvent::GuardianNotRegistered { account_eth_addr, guardian_email_addr: payload.guardian_email_addr.clone(), - subject: payload.subject.clone(), + command: payload.command.clone(), request_id, }) - .await - .expect("Failed to send GuardianNotRegistered event"); - - return Response::builder() - .status(StatusCode::OK) - .body(Body::from( - serde_json::to_string(&RecoveryResponse { - request_id, - subject_params, - }) - .unwrap(), - )) - .unwrap(); + .await?; + + return Ok(Json(RecoveryResponse { + request_id, + command_params, + })); } + // Insert the recovery request + DB.insert_request(&Request { + request_id, + account_eth_addr: account_eth_addr.clone(), + controller_eth_addr: payload.controller_eth_addr.clone(), + guardian_email_addr: payload.guardian_email_addr.clone(), + is_for_recovery: true, + template_idx: payload.template_idx, + is_processed: false, + is_success: None, + email_nullifier: None, + account_salt: Some(account_salt.clone()), + }) + .await?; + + // Handle different scenarios based on guardian status if DB .is_guardian_set(&account_eth_addr, &payload.guardian_email_addr) - .await + .await? { - DB.insert_request(&Request { - request_id: request_id.clone(), - account_eth_addr: account_eth_addr.clone(), - controller_eth_addr: payload.controller_eth_addr.clone(), - guardian_email_addr: payload.guardian_email_addr.clone(), - is_for_recovery: true, - template_idx: payload.template_idx, - is_processed: false, - is_success: None, - email_nullifier: None, - account_salt: Some(account_salt.clone()), - }) - .await - .expect("Failed to insert request"); - handle_email_event(EmailAuthEvent::RecoveryRequest { account_eth_addr, guardian_email_addr: payload.guardian_email_addr.clone(), request_id, - subject: payload.subject.clone(), + command: payload.command.clone(), }) .await + // TODO: Add custom error for handle_email_event .expect("Failed to send Recovery event"); } else { - DB.insert_request(&Request { - request_id: request_id.clone(), - account_eth_addr: account_eth_addr.clone(), - controller_eth_addr: payload.controller_eth_addr.clone(), - guardian_email_addr: payload.guardian_email_addr.clone(), - is_for_recovery: true, - template_idx: payload.template_idx, - is_processed: false, - is_success: None, - email_nullifier: None, - account_salt: Some(account_salt.clone()), - }) - .await - .expect("Failed to insert request"); - handle_email_event(EmailAuthEvent::GuardianNotSet { account_eth_addr, guardian_email_addr: payload.guardian_email_addr.clone(), - // request_id, - // subject: payload.subject.clone(), }) .await + // TODO: Add error handling .expect("Failed to send Recovery event"); } - Response::builder() - .status(StatusCode::OK) - .body(Body::from( - serde_json::to_string(&RecoveryResponse { - request_id, - subject_params, - }) - .unwrap(), - )) - .unwrap() + Ok(Json(RecoveryResponse { + request_id, + command_params, + })) } -pub async fn handle_complete_recovery_request(payload: CompleteRecoveryRequest) -> Response { - if !CLIENT.is_wallet_deployed(&payload.account_eth_addr).await { - return Response::builder() - .status(StatusCode::BAD_REQUEST) - .body(Body::from("Wallet not deployed")) - .unwrap(); +/// Handles the completion of a recovery request. +/// +/// # Arguments +/// +/// * `payload` - A JSON payload containing the complete recovery request details. +/// +/// # Returns +/// +/// A `Result` containing a `String` message or an `ApiError`. +pub async fn handle_complete_recovery_request( + Json(payload): Json, +) -> Result { + // Check if the wallet is deployed + if !CLIENT.is_wallet_deployed(&payload.account_eth_addr).await? { + return Err(ApiError::Validation("Wallet not deployed".to_string())); } + // Attempt to complete the recovery match CLIENT .complete_recovery( &payload.controller_eth_addr, @@ -545,14 +327,8 @@ pub async fn handle_complete_recovery_request(payload: CompleteRecoveryRequest) ) .await { - Ok(true) => Response::builder() - .status(StatusCode::OK) - .body(Body::from("Recovery completed")) - .unwrap(), - Ok(false) => Response::builder() - .status(StatusCode::BAD_REQUEST) - .body(Body::from("Recovery failed")) - .unwrap(), + Ok(true) => Ok("Recovery completed".to_string()), + Ok(false) => Err(ApiError::Validation("Recovery failed".to_string())), Err(e) => { // Parse the error message if it follows the known format let error_message = if e @@ -568,56 +344,74 @@ pub async fn handle_complete_recovery_request(payload: CompleteRecoveryRequest) .chars() .filter(|c| c.is_ascii()) .collect::(); - Response::builder() - .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from(error_message)) - .unwrap() + Err(ApiError::Internal(error_message)) } } } -pub async fn get_account_salt(payload: GetAccountSaltRequest) -> Response { +/// Retrieves the account salt for a given email address and account code. +/// +/// # Arguments +/// +/// * `payload` - A JSON payload containing the email address and account code. +/// +/// # Returns +/// +/// A `Result` containing the account salt as a `String` or an `ApiError`. +pub async fn get_account_salt( + Json(payload): Json, +) -> Result { let account_salt = calculate_account_salt(&payload.email_addr, &payload.account_code); - - Response::builder() - .status(StatusCode::OK) - .body(Body::from(account_salt)) - .unwrap() + Ok(account_salt) } -pub async fn inactive_guardian(payload: InactiveGuardianRequest) -> Response { +/// Marks a guardian as inactive for a given wallet. +/// +/// # Arguments +/// +/// * `payload` - A JSON payload containing the account and controller Ethereum addresses. +/// +/// # Returns +/// +/// A `Result` containing a `String` message or an `ApiError`. +pub async fn inactive_guardian( + Json(payload): Json, +) -> Result { + // Check if the wallet is activated let is_activated = CLIENT .get_is_activated(&payload.controller_eth_addr, &payload.account_eth_addr) - .await; - match is_activated { - Ok(true) => { - return Response::builder() - .status(StatusCode::BAD_REQUEST) - .body(Body::from("Wallet is activated")) - .unwrap() - } - Ok(false) => {} - Err(e) => { - return Response::builder() - .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from(e.to_string())) - .unwrap() - } + .await?; + + if is_activated { + return Ok("Wallet is activated".to_string()); } - trace!(LOG, "Inactive guardian"; "is_activated" => is_activated.unwrap()); - let account_eth_addr: Address = payload.account_eth_addr.parse().unwrap(); + + trace!(LOG, "Inactive guardian"; "is_activated" => is_activated); + + // Parse and format the account Ethereum address + let account_eth_addr: Address = payload + .account_eth_addr + .parse() + .map_err(|e| ApiError::Validation(format!("Failed to parse account_eth_addr: {}", e)))?; let account_eth_addr = format!("0x{:x}", &account_eth_addr); trace!(LOG, "Inactive guardian"; "account_eth_addr" => &account_eth_addr); + + // Update the credentials of the inactive guardian DB.update_credentials_of_inactive_guardian(false, &account_eth_addr) - .await - .expect("Failed to update credentials"); + .await?; - Response::builder() - .status(StatusCode::OK) - .body(Body::from("Guardian inactivated")) - .unwrap() + Ok("Guardian inactivated".to_string()) } +/// Parses an error message from contract call data. +/// +/// # Arguments +/// +/// * `error_data` - The error data as a `String`. +/// +/// # Returns +/// +/// A `String` containing the parsed error message or a default error message. fn parse_error_message(error_data: String) -> String { // Attempt to extract and decode the error message if let Some(hex_error) = error_data.split(" ").last() { @@ -632,14 +426,31 @@ fn parse_error_message(error_data: String) -> String { format!("Failed to parse contract error: {}", error_data) } -pub async fn receive_email_api_fn(email: String) -> Result<()> { - let parsed_email = ParsedEmail::new_from_raw_email(&email).await.unwrap(); - let from_addr = parsed_email.get_from_addr().unwrap(); +/// Receives and processes an email. +/// +/// # Arguments +/// +/// * `email` - The raw email as a `String`. +/// +/// # Returns +/// +/// A `Result` containing `()` or an `ApiError`. +pub async fn receive_email_api_fn(email: String) -> Result<(), ApiError> { + let parsed_email = ParsedEmail::new_from_raw_email(&email).await?; + let from_addr = parsed_email.get_from_addr()?; + let original_subject = parsed_email.get_subject_all()?; tokio::spawn(async move { + if !check_is_valid_request(&parsed_email).await.unwrap() { + trace!(LOG, "Got a non valid email request. Ignoring."); + return; + } + + // Send acknowledgment email match handle_email_event(EmailAuthEvent::Ack { email_addr: from_addr.clone(), - subject: parsed_email.get_subject_all().unwrap_or_default(), + command: parsed_email.get_command(false).unwrap_or_default(), original_message_id: parsed_email.get_message_id().ok(), + original_subject, }) .await { @@ -650,6 +461,8 @@ pub async fn receive_email_api_fn(email: String) -> Result<()> { error!(LOG, "Error handling email event: {:?}", e); } } + + // Process the email match handle_email(email.clone()).await { Ok(event) => match handle_email_event(event).await { Ok(_) => {} @@ -659,9 +472,16 @@ pub async fn receive_email_api_fn(email: String) -> Result<()> { }, Err(e) => { error!(LOG, "Error handling email: {:?}", e); + let original_subject = parsed_email + .get_subject_all() + .unwrap_or("Unknown Error".to_string()); match handle_email_event(EmailAuthEvent::Error { email_addr: from_addr, error: e.to_string(), + original_subject, + original_message_id: parsed_email.get_message_id().ok(), + email_request_context: *Box::new(None), + command: None, }) .await { @@ -675,3 +495,126 @@ pub async fn receive_email_api_fn(email: String) -> Result<()> { }); Ok(()) } + +/// Request status request structure. +#[derive(Serialize, Deserialize)] +pub struct RequestStatusRequest { + /// The unique identifier for the request. + pub request_id: u32, +} + +/// Enum representing the possible statuses of a request. +#[derive(Serialize, Deserialize)] +pub enum RequestStatus { + /// The request does not exist. + NotExist = 0, + /// The request is pending processing. + Pending = 1, + /// The request has been processed. + Processed = 2, +} + +/// Response structure for a request status query. +#[derive(Serialize, Deserialize)] +pub struct RequestStatusResponse { + /// The unique identifier for the request. + pub request_id: u32, + /// The current status of the request. + pub status: RequestStatus, + /// Indicates whether the request was successful. + pub is_success: bool, + /// The email nullifier, if available. + pub email_nullifier: Option, + /// The account salt, if available. + pub account_salt: Option, +} + +/// Request structure for an acceptance request. +#[derive(Serialize, Deserialize)] +pub struct AcceptanceRequest { + /// The Ethereum address of the controller. + pub controller_eth_addr: String, + /// The email address of the guardian. + pub guardian_email_addr: String, + /// The unique account code. + pub account_code: String, + /// The index of the template to use. + pub template_idx: u64, + /// The command to execute. + pub command: String, +} + +/// Response structure for an acceptance request. +#[derive(Serialize, Deserialize)] +pub struct AcceptanceResponse { + /// The unique identifier for the request. + pub request_id: u32, + /// The parameters extracted from the command. + pub command_params: Vec, +} + +/// Request structure for a recovery request. +#[derive(Serialize, Deserialize, Debug)] +pub struct RecoveryRequest { + /// The Ethereum address of the controller. + pub controller_eth_addr: String, + /// The email address of the guardian. + pub guardian_email_addr: String, + /// The index of the template to use. + pub template_idx: u64, + /// The command to execute. + pub command: String, +} + +/// Response structure for a recovery request. +#[derive(Serialize, Deserialize)] +pub struct RecoveryResponse { + /// The unique identifier for the request. + pub request_id: u32, + /// The parameters extracted from the command. + pub command_params: Vec, +} + +/// Request structure for completing a recovery. +#[derive(Serialize, Deserialize)] +pub struct CompleteRecoveryRequest { + /// The Ethereum address of the account to recover. + pub account_eth_addr: String, + /// The Ethereum address of the controller. + pub controller_eth_addr: String, + /// The calldata to complete the recovery. + pub complete_calldata: String, +} + +/// Request structure for retrieving an account salt. +#[derive(Serialize, Deserialize)] +pub struct GetAccountSaltRequest { + /// The unique account code. + pub account_code: String, + /// The email address associated with the account. + pub email_addr: String, +} + +/// Structure representing a permitted wallet. +#[derive(Deserialize)] +struct PermittedWallet { + /// The name of the wallet. + wallet_name: String, + /// The Ethereum address of the controller. + controller_eth_addr: String, + /// The hash of the bytecode of the proxy contract. + hash_of_bytecode_of_proxy: String, + /// The address of the implementation contract. + impl_contract_address: String, + /// The slot location in storage. + slot_location: String, +} + +/// Request structure for marking a guardian as inactive. +#[derive(Serialize, Deserialize)] +pub struct InactiveGuardianRequest { + /// The Ethereum address of the account. + pub account_eth_addr: String, + /// The Ethereum address of the controller. + pub controller_eth_addr: String, +} diff --git a/packages/relayer/src/modules/web_server/server.rs b/packages/relayer/src/modules/web_server/server.rs index da6c5a59..b8f371c3 100644 --- a/packages/relayer/src/modules/web_server/server.rs +++ b/packages/relayer/src/modules/web_server/server.rs @@ -1,183 +1,50 @@ use crate::*; -use axum::Router; +use axum::{routing::post, Router}; use relayer_utils::LOG; use tower_http::cors::{AllowHeaders, AllowMethods, Any, CorsLayer}; -#[named] +/// Runs the server and sets up the API routes. +/// +/// # Returns +/// +/// A `Result` indicating success or failure. pub async fn run_server() -> Result<()> { let addr = WEB_SERVER_ADDRESS.get().unwrap(); + // Initialize the global DB ref before starting the server + DB_CELL + .get_or_init(|| async { + dotenv::dotenv().ok(); + let db = Database::open(&std::env::var("DATABASE_URL").unwrap()) + .await + .unwrap(); + Arc::new(db) + }) + .await; + + info!(LOG, "Testing connection to database"); + if let Err(e) = DB.test_db_connection().await { + error!(LOG, "Failed to initialize db with e: {}", e); + panic!("Forcing panic, since connection to DB could not be established"); + }; + info!(LOG, "Testing connection to database successfull"); + + // Initialize the API routes let mut app = Router::new() .route( "/api/echo", axum::routing::get(move || async move { "Hello, world!" }), ) - .route( - "/api/requestStatus", - axum::routing::post(move |payload: String| async move { - let payload: Result = - serde_json::from_str(&payload).map_err(|e| anyhow::Error::from(e)); - match payload { - Ok(payload) => { - let response = request_status_api(payload).await; - match response { - Ok(response) => { - let body = serde_json::to_string(&response) - .map_err(|e| axum::http::StatusCode::INTERNAL_SERVER_ERROR) - .unwrap(); - Ok::<_, axum::response::Response>( - axum::http::Response::builder() - .status(axum::http::StatusCode::OK) - .body(axum::body::Body::from(body)) - .unwrap(), - ) - } - Err(e) => { - let error_message = serde_json::to_string(&e.to_string()) - .map_err(|_| axum::http::StatusCode::INTERNAL_SERVER_ERROR) - .unwrap(); - Ok(axum::http::Response::builder() - .status(axum::http::StatusCode::INTERNAL_SERVER_ERROR) - .body(serde_json::to_string(&e.to_string()).unwrap().into()) - .unwrap()) - } - } - } - Err(e) => { - let error_message = serde_json::to_string(&e.to_string()) - .map_err(|_| axum::http::StatusCode::INTERNAL_SERVER_ERROR) - .unwrap(); - Ok(axum::http::Response::builder() - .status(axum::http::StatusCode::INTERNAL_SERVER_ERROR) - .body(serde_json::to_string(&e.to_string()).unwrap().into()) - .unwrap()) - } - } - }), - ) - .route( - "/api/acceptanceRequest", - axum::routing::post(move |payload: String| async move { - let payload: Result = - serde_json::from_str(&payload).map_err(|e| anyhow::Error::from(e)); - match payload { - Ok(payload) => { - let acceptance_response = handle_acceptance_request(payload).await; - Ok::<_, axum::response::Response>(acceptance_response) - } - Err(e) => { - let error_message = serde_json::to_string(&e.to_string()) - .map_err(|_| axum::http::StatusCode::INTERNAL_SERVER_ERROR) - .unwrap(); - Ok(axum::http::Response::builder() - .status(axum::http::StatusCode::INTERNAL_SERVER_ERROR) - .body(serde_json::to_string(&e.to_string()).unwrap().into()) - .unwrap()) - } - } - }), - ) - .route( - "/api/recoveryRequest", - axum::routing::post(move |payload: String| async move { - let payload: Result = - serde_json::from_str(&payload).map_err(|e| anyhow::Error::from(e)); - match payload { - Ok(payload) => { - let recovery_response = handle_recovery_request(payload).await; - Ok::<_, axum::response::Response>(recovery_response) - } - Err(e) => { - let error_message = serde_json::to_string(&e.to_string()) - .map_err(|_| axum::http::StatusCode::INTERNAL_SERVER_ERROR) - .unwrap(); - Ok(axum::http::Response::builder() - .status(axum::http::StatusCode::INTERNAL_SERVER_ERROR) - .body(serde_json::to_string(&e.to_string()).unwrap().into()) - .unwrap()) - } - } - }), - ) + .route("/api/requestStatus", post(request_status_api)) + .route("/api/acceptanceRequest", post(handle_acceptance_request)) + .route("/api/recoveryRequest", post(handle_recovery_request)) .route( "/api/completeRequest", - axum::routing::post(move |payload: String| async move { - let payload: Result = - serde_json::from_str(&payload).map_err(|e| anyhow::Error::from(e)); - match payload { - Ok(payload) => { - let recovery_response = handle_complete_recovery_request(payload).await; - Ok::<_, axum::response::Response>(recovery_response) - } - Err(e) => { - let error_message = serde_json::to_string(&e.to_string()) - .map_err(|_| axum::http::StatusCode::INTERNAL_SERVER_ERROR) - .unwrap(); - Ok(axum::http::Response::builder() - .status(axum::http::StatusCode::INTERNAL_SERVER_ERROR) - .body(serde_json::to_string(&e.to_string()).unwrap().into()) - .unwrap()) - } - } - }), - ) - .route( - "/api/getAccountSalt", - axum::routing::post(move |payload: String| async move { - let payload: Result = - serde_json::from_str(&payload).map_err(|e| anyhow::Error::from(e)); - match payload { - Ok(payload) => { - let response = get_account_salt(payload).await; - Ok::<_, axum::response::Response>(response) - } - Err(e) => { - let error_message = serde_json::to_string(&e.to_string()) - .map_err(|_| axum::http::StatusCode::INTERNAL_SERVER_ERROR) - .unwrap(); - Ok(axum::http::Response::builder() - .status(axum::http::StatusCode::INTERNAL_SERVER_ERROR) - .body(serde_json::to_string(&e.to_string()).unwrap().into()) - .unwrap()) - } - } - }), + post(handle_complete_recovery_request), ) - .route( - "/api/inactiveGuardian", - axum::routing::post(move |payload: String| async move { - let payload: Result = - serde_json::from_str(&payload).map_err(|e| anyhow::Error::from(e)); - match payload { - Ok(payload) => { - let response = inactive_guardian(payload).await; - Ok::<_, axum::response::Response>(response) - } - Err(e) => { - let error_message = serde_json::to_string(&e.to_string()) - .map_err(|_| axum::http::StatusCode::INTERNAL_SERVER_ERROR) - .unwrap(); - Ok(axum::http::Response::builder() - .status(axum::http::StatusCode::INTERNAL_SERVER_ERROR) - .body(serde_json::to_string(&e.to_string()).unwrap().into()) - .unwrap()) - } - } - }), - ) - .route( - "/api/receiveEmail", - axum::routing::post::<_, _, (), _>(move |payload: String| async move { - info!(LOG, "Receive email payload: {}", payload); - match receive_email_api_fn(payload).await { - Ok(_) => "Request processed".to_string(), - Err(err) => { - error!(LOG, "Failed to complete the receive email request: {}", err); - err.to_string() - } - } - }), - ); + .route("/api/getAccountSalt", post(get_account_salt)) + .route("/api/inactiveGuardian", post(inactive_guardian)) + .route("/api/receiveEmail", post(receive_email_api_fn)); app = app.layer( CorsLayer::new() @@ -186,7 +53,8 @@ pub async fn run_server() -> Result<()> { .allow_origin(Any), ); - trace!(LOG, "Listening API at {}", addr; "func" => function_name!()); + // Start the server + trace!(LOG, "Listening API at {}", addr); axum::Server::bind(&addr.parse()?) .serve(app.into_make_service()) .await?; diff --git a/packages/relayer/src/utils/strings.rs b/packages/relayer/src/strings.rs similarity index 69% rename from packages/relayer/src/utils/strings.rs rename to packages/relayer/src/strings.rs index b92bbc97..4bb45ae7 100644 --- a/packages/relayer/src/utils/strings.rs +++ b/packages/relayer/src/strings.rs @@ -3,7 +3,6 @@ pub const SMTP_SERVER_KEY: &str = "SMTP_SERVER"; pub const RELAYER_EMAIL_ADDR_KEY: &str = "RELAYER_EMAIL_ADDR"; pub const DATABASE_PATH_KEY: &str = "DATABASE_URL"; pub const WEB_SERVER_ADDRESS_KEY: &str = "WEB_SERVER_ADDRESS"; -pub const CIRCUITS_DIR_PATH_KEY: &str = "CIRCUITS_DIR_PATH"; pub const PROVER_ADDRESS_KEY: &str = "PROVER_ADDRESS"; pub const CHAIN_RPC_PROVIDER_KEY: &str = "CHAIN_RPC_PROVIDER"; pub const CHAIN_RPC_EXPLORER_KEY: &str = "CHAIN_RPC_EXPLORER"; @@ -11,6 +10,8 @@ pub const PRIVATE_KEY_KEY: &str = "PRIVATE_KEY"; pub const CHAIN_ID_KEY: &str = "CHAIN_ID"; pub const EMAIL_ACCOUNT_RECOVERY_VERSION_ID_KEY: &str = "EMAIL_ACCOUNT_RECOVERY_VERSION_ID"; pub const EMAIL_TEMPLATES_PATH_KEY: &str = "EMAIL_TEMPLATES_PATH"; +pub const REGEX_JSON_DIR_PATH_KEY: &str = "REGEX_JSON_DIR_PATH"; +pub const ERROR_EMAIL_ADDR_KEY: &str = "ERROR_EMAIL_ADDR"; // Log strings pub const JSON_LOGGER_KEY: &str = "JSON_LOGGER"; @@ -21,7 +22,7 @@ pub const IMAP_RECONNECT_ERROR: &str = "Failed to reconnect"; pub const SMTP_RECONNECT_ERROR: &str = "Failed to reconnect"; pub const CANNOT_GET_EMAIL_FROM_QUEUE: &str = "Cannot get email from mpsc in handle email task"; pub const NOT_MY_SENDER: &str = "NOT_MY_SENDER"; -pub const WRONG_SUBJECT_FORMAT: &str = "Wrong subject format"; +pub const WRONG_COMMAND_FORMAT: &str = "Wrong command format"; // Core REGEX'es and Commands pub const STRING_REGEX: &str = r"\S+"; @@ -29,8 +30,10 @@ pub const UINT_REGEX: &str = r"\d+"; pub const INT_REGEX: &str = r"-?\d+"; pub const ETH_ADDR_REGEX: &str = r"0x[a-fA-F0-9]{40}"; pub const DECIMALS_REGEX: &str = r"\d+\.\d+"; +pub const SHA_PRECOMPUTE_SELECTOR: &str = r#"(<(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)? (=\r\n)?i(=\r\n)?d(=\r\n)?=3D(=\r\n)?\"(=\r\n)?[^\"]*(=\r\n)?z(=\r\n)?k(=\r\n)?e(=\r\n)?m(=\r\n)?a(=\r\n)?i(=\r\n)?l(=\r\n)?[^\"]*(=\r\n)?\"(=\r\n)?[^>]*(=\r\n)?>(=\r\n)?)(=\r\n)?([^<>\/]+)(<(=\r\n)?\/(=\r\n)?d(=\r\n)?i(=\r\n)?v(=\r\n)?>(=\r\n)?)"#; // DKIM ORACLE ARGS -pub const CANISTER_ID_KEY: &str = "CANISTER_ID"; +pub const DKIM_CANISTER_ID_KEY: &str = "DKIM_CANISTER_ID"; +pub const WALLET_CANISTER_ID_KEY: &str = "WALLET_CANISTER_ID"; pub const PEM_PATH_KEY: &str = "PEM_PATH"; pub const IC_REPLICA_URL_KEY: &str = "IC_REPLICA_URL"; diff --git a/packages/relayer/src/utils/mod.rs b/packages/relayer/src/utils/mod.rs deleted file mode 100644 index 361a451a..00000000 --- a/packages/relayer/src/utils/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod strings; -pub mod subject_templates; -pub mod utils; - -pub use strings::*; -pub use subject_templates::*; -pub use utils::*; diff --git a/packages/relayer/src/utils/subject_templates.rs b/packages/relayer/src/utils/subject_templates.rs deleted file mode 100644 index 621bb408..00000000 --- a/packages/relayer/src/utils/subject_templates.rs +++ /dev/null @@ -1,236 +0,0 @@ -#![allow(clippy::upper_case_acronyms)] - -use crate::*; - -use ethers::abi::{self, Token}; -use ethers::types::{Address, Bytes, I256, U256}; -use regex::Regex; -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum TemplateValue { - String(String), - Uint(U256), - Int(I256), - Decimals(String), - EthAddr(Address), - Fixed(String), -} - -impl TemplateValue { - pub fn abi_encode(&self, decimal_size: Option) -> Result { - match self { - Self::String(string) => Ok(Bytes::from(abi::encode(&[Token::String(string.clone())]))), - Self::Uint(uint) => Ok(Bytes::from(abi::encode(&[Token::Uint(*uint)]))), - Self::Int(int) => Ok(Bytes::from(abi::encode(&[Token::Int(int.into_raw())]))), - Self::Decimals(string) => Ok(Bytes::from(abi::encode(&[Token::Uint( - Self::decimals_str_to_uint(&string, decimal_size.unwrap_or(18)), - )]))), - Self::EthAddr(address) => Ok(Bytes::from(abi::encode(&[Token::Address(*address)]))), - Self::Fixed(string) => Err(anyhow!("Fixed value must not be passed to abi_encode")), - } - } - - pub fn decimals_str_to_uint(str: &str, decimal_size: u8) -> U256 { - let decimal_size = decimal_size as usize; - let dot = Regex::new("\\.").unwrap().find(str); - let (before_dot_str, mut after_dot_str) = match dot { - Some(dot_match) => ( - str[0..dot_match.start()].to_string(), - str[dot_match.end()..].to_string(), - ), - None => (str.to_string(), "".to_string()), - }; - assert!(after_dot_str.len() <= decimal_size); - let num_leading_zeros = decimal_size - after_dot_str.len(); - after_dot_str.push_str(&"0".repeat(num_leading_zeros)); - U256::from_dec_str(&(before_dot_str + &after_dot_str)) - .expect("composed amount string is not valid decimal") - } -} - -pub fn extract_template_vals_and_skipped_subject_idx( - input: &str, - templates: Vec, -) -> Result<(Vec, usize), anyhow::Error> { - // Convert the template to a regex pattern, escaping necessary characters and replacing placeholders - let pattern = templates - .iter() - .map(|template| match template.as_str() { - "{string}" => STRING_REGEX.to_string(), - "{uint}" => UINT_REGEX.to_string(), - "{int}" => INT_REGEX.to_string(), - "{decimals}" => DECIMALS_REGEX.to_string(), - "{ethAddr}" => ETH_ADDR_REGEX.to_string(), - _ => regex::escape(template), - }) - .collect::>() - .join("\\s+"); - - let regex = Regex::new(&pattern).map_err(|e| anyhow!("Regex compilation failed: {}", e))?; - - // Attempt to find the pattern in the input - if let Some(matched) = regex.find(input) { - // Calculate the number of bytes to skip before the match - let skipped_bytes = matched.start(); - - // Extract the values based on the matched pattern - let current_input = &input[skipped_bytes..]; - match extract_template_vals(current_input, templates) { - Ok(vals) => Ok((vals, skipped_bytes)), - Err(e) => Err(e), - } - } else { - // If there's no match, return an error indicating no match was found - Err(anyhow!("Unable to match templates with input")) - } -} - -pub fn extract_template_vals(input: &str, templates: Vec) -> Result> { - let input_decomposed: Vec<&str> = input.split_whitespace().collect(); - let mut template_vals = Vec::new(); - let mut input_idx = 0; - - for template in templates.iter() { - if input_idx >= input_decomposed.len() { - break; // Prevents index out of bounds if input is shorter than template - } - - match template.as_str() { - "{string}" => { - let string_match = Regex::new(STRING_REGEX) - .unwrap() - .find(input_decomposed[input_idx]) - .ok_or(anyhow!("No string found"))?; - if string_match.start() != 0 - || string_match.end() != input_decomposed[input_idx].len() - { - return Err(anyhow!("String must be the whole word")); - } - let string = string_match.as_str().to_string(); - template_vals.push(TemplateValue::String(string)); - } - "{uint}" => { - let uint_match = Regex::new(UINT_REGEX) - .unwrap() - .find(input_decomposed[input_idx]) - .ok_or(anyhow!("No uint found"))?; - if uint_match.start() != 0 || uint_match.end() != input_decomposed[input_idx].len() - { - return Err(anyhow!("Uint must be the whole word")); - } - let uint = U256::from_dec_str(uint_match.as_str()).unwrap(); - template_vals.push(TemplateValue::Uint(uint)); - } - "{int}" => { - let int_match = Regex::new(INT_REGEX) - .unwrap() - .find(input_decomposed[input_idx]) - .ok_or(anyhow!("No int found"))?; - if int_match.start() != 0 || int_match.end() != input_decomposed[input_idx].len() { - return Err(anyhow!("Int must be the whole word")); - } - let int = I256::from_dec_str(int_match.as_str()).unwrap(); - template_vals.push(TemplateValue::Int(int)); - } - "{decimals}" => { - let decimals_match = Regex::new(DECIMALS_REGEX) - .unwrap() - .find(input_decomposed[input_idx]) - .ok_or(anyhow!("No decimals found"))?; - if decimals_match.start() != 0 - || decimals_match.end() != input_decomposed[input_idx].len() - { - return Err(anyhow!("Decimals must be the whole word")); - } - let decimals = decimals_match.as_str().to_string(); - template_vals.push(TemplateValue::Decimals(decimals)); - } - "{ethAddr}" => { - let address_match = Regex::new(ETH_ADDR_REGEX) - .unwrap() - .find(input_decomposed[input_idx]) - .ok_or(anyhow!("No address found"))?; - if address_match.start() != 0 - || address_match.end() != input_decomposed[input_idx].len() - { - return Err(anyhow!("Address must be the whole word")); - } - let address = address_match.as_str().parse::
().unwrap(); - template_vals.push(TemplateValue::EthAddr(address)); - } - _ => {} // Skip unknown placeholders - } - - input_idx += 1; // Move to the next piece of input - } - - Ok(template_vals) -} - -// Generated by Github Copilot! -pub fn uint_to_decimal_string(uint: u128, decimal: usize) -> String { - // Convert amount to string in wei format (no decimals) - let uint_str = uint.to_string(); - let uint_length = uint_str.len(); - - // Create result vector with max length - // If less than 18 decimals, then 2 extra for "0.", otherwise one extra for "." - let mut result = vec![ - '0'; - if uint_length > decimal { - uint_length + 1 - } else { - decimal + 2 - } - ]; - let result_length = result.len(); - - // Difference between result and amount array index when copying - // If more than 18, then 1 index diff for ".", otherwise actual diff in length - let mut delta = if uint_length > decimal { - 1 - } else { - result_length - uint_length - }; - - // Boolean to indicate if we found a non-zero digit when scanning from last to first index - let mut found_non_zero_decimal = false; - - let mut actual_result_len = 0; - - // In each iteration we fill one index of result array (starting from end) - for i in (0..result_length).rev() { - // Check if we have reached the index where we need to add decimal point - if i == result_length - decimal - 1 { - // No need to add "." if there was no value in decimal places - if found_non_zero_decimal { - result[i] = '.'; - actual_result_len += 1; - } - // Set delta to 0, as we have already added decimal point (only for amount_length > 18) - delta = 0; - } - // If amountLength < 18 and we have copied everything, fill zeros - else if uint_length <= decimal && i < result_length - uint_length { - result[i] = '0'; - actual_result_len += 1; - } - // If non-zero decimal is found, or decimal point inserted (delta == 0), copy from amount array - else if found_non_zero_decimal || delta == 0 { - result[i] = uint_str.chars().nth(i - delta).unwrap(); - actual_result_len += 1; - } - // If we find non-zero decimal for the first time (trailing zeros are skipped) - else if uint_str.chars().nth(i - delta).unwrap() != '0' { - result[i] = uint_str.chars().nth(i - delta).unwrap(); - actual_result_len += 1; - found_non_zero_decimal = true; - } - } - - // Create final result string with correct length - let compact_result: String = result.into_iter().take(actual_result_len).collect(); - - compact_result -} diff --git a/packages/relayer/src/utils/utils.rs b/packages/relayer/src/utils/utils.rs deleted file mode 100644 index f2dffca8..00000000 --- a/packages/relayer/src/utils/utils.rs +++ /dev/null @@ -1,99 +0,0 @@ -#![allow(clippy::upper_case_acronyms)] -#![allow(clippy::identity_op)] - -use crate::*; -use ethers::abi::Token; -use ethers::types::{Bytes, U256}; - -use ::serde::Deserialize; - -use relayer_utils::*; -use std::collections::hash_map::DefaultHasher; -use std::hash::{Hash, Hasher}; - -const DOMAIN_FIELDS: usize = 9; -const SUBJECT_FIELDS: usize = 17; -const EMAIL_ADDR_FIELDS: usize = 9; - -#[derive(Debug, Clone, Deserialize)] -pub struct ProverRes { - proof: ProofJson, - pub_signals: Vec, -} - -#[derive(Debug, Clone, Deserialize)] -pub struct ProofJson { - pi_a: Vec, - pi_b: Vec>, - pi_c: Vec, -} - -impl ProofJson { - pub fn to_eth_bytes(&self) -> Result { - let pi_a = Token::FixedArray(vec![ - Token::Uint(U256::from_dec_str(self.pi_a[0].as_str())?), - Token::Uint(U256::from_dec_str(self.pi_a[1].as_str())?), - ]); - let pi_b = Token::FixedArray(vec![ - Token::FixedArray(vec![ - Token::Uint(U256::from_dec_str(self.pi_b[0][1].as_str())?), - Token::Uint(U256::from_dec_str(self.pi_b[0][0].as_str())?), - ]), - Token::FixedArray(vec![ - Token::Uint(U256::from_dec_str(self.pi_b[1][1].as_str())?), - Token::Uint(U256::from_dec_str(self.pi_b[1][0].as_str())?), - ]), - ]); - let pi_c = Token::FixedArray(vec![ - Token::Uint(U256::from_dec_str(self.pi_c[0].as_str())?), - Token::Uint(U256::from_dec_str(self.pi_c[1].as_str())?), - ]); - Ok(Bytes::from(abi::encode(&[pi_a, pi_b, pi_c]))) - } -} - -#[named] -pub async fn generate_proof( - input: &str, - request: &str, - address: &str, -) -> Result<(Bytes, Vec)> { - let client = reqwest::Client::new(); - info!(LOG, "prover input {}", input; "func" => function_name!()); - let res = client - .post(format!("{}/prove/{}", address, request)) - .json(&serde_json::json!({ "input": input })) - .send() - .await? - .error_for_status()?; - let res_json = res.json::().await?; - info!(LOG, "prover response {:?}", res_json; "func" => function_name!()); - let proof = res_json.proof.to_eth_bytes()?; - let pub_signals = res_json - .pub_signals - .into_iter() - .map(|str| U256::from_dec_str(&str).expect("pub signal should be u256")) - .collect(); - Ok((proof, pub_signals)) -} - -pub fn calculate_default_hash(input: &str) -> String { - let mut hasher = DefaultHasher::new(); - input.hash(&mut hasher); - let hash_code = hasher.finish(); - - hash_code.to_string() -} - -pub fn calculate_account_salt(email_addr: &str, account_code: &str) -> String { - let padded_email_addr = PaddedEmailAddr::from_email_addr(&email_addr); - let account_code = if account_code.starts_with("0x") { - hex2field(&account_code).unwrap() - } else { - hex2field(&format!("0x{}", account_code)).unwrap() - }; - let account_code = AccountCode::from(account_code); - let account_salt = AccountSalt::new(&padded_email_addr, account_code).unwrap(); - - field2hex(&account_salt.0) -} diff --git a/rust-toolchain b/rust-toolchain index 837f16a7..97e98527 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.73.0 \ No newline at end of file +1.80.1 diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 00000000..b8116019 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,4 @@ +max_width = 100 +use_small_heuristics = "Default" +reorder_imports = true +reorder_modules = true diff --git a/yarn.lock b/yarn.lock index 5f8ca2fd..c9d2c928 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,96 +10,98 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" - integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" + integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== dependencies: - "@babel/highlight" "^7.24.7" + "@babel/helper-validator-identifier" "^7.25.9" + js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.2", "@babel/compat-data@^7.25.4": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.4.tgz#7d2a80ce229890edcf4cc259d4d696cb4dae2fcb" - integrity sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ== +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.9", "@babel/compat-data@^7.26.0": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.2.tgz#278b6b13664557de95b8f35b90d96785850bb56e" + integrity sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg== "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.22.5", "@babel/core@^7.23.9": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.2.tgz#ed8eec275118d7613e77a352894cd12ded8eba77" - integrity sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA== + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.0.tgz#d78b6023cc8f3114ccf049eb219613f74a747b40" + integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.25.0" - "@babel/helper-compilation-targets" "^7.25.2" - "@babel/helper-module-transforms" "^7.25.2" - "@babel/helpers" "^7.25.0" - "@babel/parser" "^7.25.0" - "@babel/template" "^7.25.0" - "@babel/traverse" "^7.25.2" - "@babel/types" "^7.25.2" + "@babel/code-frame" "^7.26.0" + "@babel/generator" "^7.26.0" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-module-transforms" "^7.26.0" + "@babel/helpers" "^7.26.0" + "@babel/parser" "^7.26.0" + "@babel/template" "^7.25.9" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.26.0" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.25.0", "@babel/generator@^7.25.6", "@babel/generator@^7.7.2": - version "7.25.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.6.tgz#0df1ad8cb32fe4d2b01d8bf437f153d19342a87c" - integrity sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw== +"@babel/generator@^7.25.9", "@babel/generator@^7.26.0", "@babel/generator@^7.7.2": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.2.tgz#87b75813bec87916210e5e01939a4c823d6bb74f" + integrity sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw== dependencies: - "@babel/types" "^7.25.6" + "@babel/parser" "^7.26.2" + "@babel/types" "^7.26.0" "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" - jsesc "^2.5.1" + jsesc "^3.0.2" -"@babel/helper-annotate-as-pure@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz#5373c7bc8366b12a033b4be1ac13a206c6656aab" - integrity sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg== +"@babel/helper-annotate-as-pure@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz#d8eac4d2dc0d7b6e11fa6e535332e0d3184f06b4" + integrity sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g== dependencies: - "@babel/types" "^7.24.7" + "@babel/types" "^7.25.9" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz#37d66feb012024f2422b762b9b2a7cfe27c7fba3" - integrity sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz#f41752fe772a578e67286e6779a68a5a92de1ee9" + integrity sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g== dependencies: - "@babel/traverse" "^7.24.7" - "@babel/types" "^7.24.7" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" -"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.7", "@babel/helper-compilation-targets@^7.24.8", "@babel/helper-compilation-targets@^7.25.2": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz#e1d9410a90974a3a5a66e84ff55ef62e3c02d06c" - integrity sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw== +"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz#55af025ce365be3cdc0c1c1e56c6af617ce88875" + integrity sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ== dependencies: - "@babel/compat-data" "^7.25.2" - "@babel/helper-validator-option" "^7.24.8" - browserslist "^4.23.1" + "@babel/compat-data" "^7.25.9" + "@babel/helper-validator-option" "^7.25.9" + browserslist "^4.24.0" lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.24.7", "@babel/helper-create-class-features-plugin@^7.25.0", "@babel/helper-create-class-features-plugin@^7.25.4": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz#57eaf1af38be4224a9d9dd01ddde05b741f50e14" - integrity sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-member-expression-to-functions" "^7.24.8" - "@babel/helper-optimise-call-expression" "^7.24.7" - "@babel/helper-replace-supers" "^7.25.0" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" - "@babel/traverse" "^7.25.4" +"@babel/helper-create-class-features-plugin@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz#7644147706bb90ff613297d49ed5266bde729f83" + integrity sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-member-expression-to-functions" "^7.25.9" + "@babel/helper-optimise-call-expression" "^7.25.9" + "@babel/helper-replace-supers" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/traverse" "^7.25.9" semver "^6.3.1" -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.24.7", "@babel/helper-create-regexp-features-plugin@^7.25.0", "@babel/helper-create-regexp-features-plugin@^7.25.2": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz#24c75974ed74183797ffd5f134169316cd1808d9" - integrity sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g== +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz#3e8999db94728ad2b2458d7a470e7770b7764e26" + integrity sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - regexpu-core "^5.3.1" + "@babel/helper-annotate-as-pure" "^7.25.9" + regexpu-core "^6.1.1" semver "^6.3.1" "@babel/helper-define-polyfill-provider@^0.6.2": @@ -113,165 +115,154 @@ lodash.debounce "^4.0.8" resolve "^1.14.2" -"@babel/helper-member-expression-to-functions@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz#6155e079c913357d24a4c20480db7c712a5c3fb6" - integrity sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA== - dependencies: - "@babel/traverse" "^7.24.8" - "@babel/types" "^7.24.8" - -"@babel/helper-module-imports@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b" - integrity sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA== - dependencies: - "@babel/traverse" "^7.24.7" - "@babel/types" "^7.24.7" - -"@babel/helper-module-transforms@^7.24.7", "@babel/helper-module-transforms@^7.24.8", "@babel/helper-module-transforms@^7.25.0", "@babel/helper-module-transforms@^7.25.2": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz#ee713c29768100f2776edf04d4eb23b8d27a66e6" - integrity sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ== - dependencies: - "@babel/helper-module-imports" "^7.24.7" - "@babel/helper-simple-access" "^7.24.7" - "@babel/helper-validator-identifier" "^7.24.7" - "@babel/traverse" "^7.25.2" - -"@babel/helper-optimise-call-expression@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz#8b0a0456c92f6b323d27cfd00d1d664e76692a0f" - integrity sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A== - dependencies: - "@babel/types" "^7.24.7" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.24.8", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz#94ee67e8ec0e5d44ea7baeb51e571bd26af07878" - integrity sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg== - -"@babel/helper-remap-async-to-generator@^7.24.7", "@babel/helper-remap-async-to-generator@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz#d2f0fbba059a42d68e5e378feaf181ef6055365e" - integrity sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-wrap-function" "^7.25.0" - "@babel/traverse" "^7.25.0" - -"@babel/helper-replace-supers@^7.24.7", "@babel/helper-replace-supers@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz#ff44deac1c9f619523fe2ca1fd650773792000a9" - integrity sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.24.8" - "@babel/helper-optimise-call-expression" "^7.24.7" - "@babel/traverse" "^7.25.0" - -"@babel/helper-simple-access@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz#bcade8da3aec8ed16b9c4953b74e506b51b5edb3" - integrity sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg== - dependencies: - "@babel/traverse" "^7.24.7" - "@babel/types" "^7.24.7" - -"@babel/helper-skip-transparent-expression-wrappers@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz#5f8fa83b69ed5c27adc56044f8be2b3ea96669d9" - integrity sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ== - dependencies: - "@babel/traverse" "^7.24.7" - "@babel/types" "^7.24.7" - -"@babel/helper-string-parser@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" - integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== - -"@babel/helper-validator-identifier@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" - integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== - -"@babel/helper-validator-option@^7.24.7", "@babel/helper-validator-option@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d" - integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q== - -"@babel/helper-wrap-function@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz#dab12f0f593d6ca48c0062c28bcfb14ebe812f81" - integrity sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ== - dependencies: - "@babel/template" "^7.25.0" - "@babel/traverse" "^7.25.0" - "@babel/types" "^7.25.0" - -"@babel/helpers@^7.25.0": - version "7.25.6" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.6.tgz#57ee60141829ba2e102f30711ffe3afab357cc60" - integrity sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q== - dependencies: - "@babel/template" "^7.25.0" - "@babel/types" "^7.25.6" - -"@babel/highlight@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" - integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== - dependencies: - "@babel/helper-validator-identifier" "^7.24.7" - chalk "^2.4.2" - js-tokens "^4.0.0" - picocolors "^1.0.0" +"@babel/helper-member-expression-to-functions@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz#9dfffe46f727005a5ea29051ac835fb735e4c1a3" + integrity sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ== + dependencies: + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" + +"@babel/helper-module-imports@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz#e7f8d20602ebdbf9ebbea0a0751fb0f2a4141715" + integrity sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw== + dependencies: + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" + +"@babel/helper-module-transforms@^7.25.9", "@babel/helper-module-transforms@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz#8ce54ec9d592695e58d84cd884b7b5c6a2fdeeae" + integrity sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw== + dependencies: + "@babel/helper-module-imports" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + "@babel/traverse" "^7.25.9" + +"@babel/helper-optimise-call-expression@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz#3324ae50bae7e2ab3c33f60c9a877b6a0146b54e" + integrity sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ== + dependencies: + "@babel/types" "^7.25.9" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.25.9", "@babel/helper-plugin-utils@^7.8.0": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz#9cbdd63a9443a2c92a725cca7ebca12cc8dd9f46" + integrity sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw== + +"@babel/helper-remap-async-to-generator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz#e53956ab3d5b9fb88be04b3e2f31b523afd34b92" + integrity sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-wrap-function" "^7.25.9" + "@babel/traverse" "^7.25.9" + +"@babel/helper-replace-supers@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz#ba447224798c3da3f8713fc272b145e33da6a5c5" + integrity sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.25.9" + "@babel/helper-optimise-call-expression" "^7.25.9" + "@babel/traverse" "^7.25.9" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.25.0", "@babel/parser@^7.25.6": - version "7.25.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.6.tgz#85660c5ef388cbbf6e3d2a694ee97a38f18afe2f" - integrity sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q== +"@babel/helper-simple-access@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz#6d51783299884a2c74618d6ef0f86820ec2e7739" + integrity sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q== dependencies: - "@babel/types" "^7.25.6" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.3": - version "7.25.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz#dca427b45a6c0f5c095a1c639dfe2476a3daba7f" - integrity sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA== +"@babel/helper-skip-transparent-expression-wrappers@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz#0b2e1b62d560d6b1954893fd2b705dc17c91f0c9" + integrity sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/traverse" "^7.25.3" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" -"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz#cd0c583e01369ef51676bdb3d7b603e17d2b3f73" - integrity sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA== +"@babel/helper-string-parser@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c" + integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== + +"@babel/helper-validator-identifier@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" + integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== + +"@babel/helper-validator-option@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz#86e45bd8a49ab7e03f276577f96179653d41da72" + integrity sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw== + +"@babel/helper-wrap-function@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz#d99dfd595312e6c894bd7d237470025c85eea9d0" + integrity sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g== + dependencies: + "@babel/template" "^7.25.9" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" + +"@babel/helpers@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.0.tgz#30e621f1eba5aa45fe6f4868d2e9154d884119a4" + integrity sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw== + dependencies: + "@babel/template" "^7.25.9" + "@babel/types" "^7.26.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.25.9", "@babel/parser@^7.26.0", "@babel/parser@^7.26.2": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.2.tgz#fd7b6f487cfea09889557ef5d4eeb9ff9a5abd11" + integrity sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ== + dependencies: + "@babel/types" "^7.26.0" + +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz#cc2e53ebf0a0340777fff5ed521943e253b4d8fe" + integrity sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/traverse" "^7.25.9" + +"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz#af9e4fb63ccb8abcb92375b2fcfe36b60c774d30" + integrity sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz#749bde80356b295390954643de7635e0dffabe73" - integrity sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz#e8dc26fcd616e6c5bf2bd0d5a2c151d4f92a9137" + integrity sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz#e4eabdd5109acc399b38d7999b2ef66fc2022f89" - integrity sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz#807a667f9158acac6f6164b4beb85ad9ebc9e1d1" + integrity sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" - "@babel/plugin-transform-optional-chaining" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/plugin-transform-optional-chaining" "^7.25.9" -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz#3a82a70e7cb7294ad2559465ebcb871dfbf078fb" - integrity sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw== +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz#de7093f1e7deaf68eadd7cc6b07f2ab82543269e" + integrity sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/traverse" "^7.25.0" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/traverse" "^7.25.9" "@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": version "7.21.0-placeholder-for-preset-env.2" @@ -306,33 +297,19 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-dynamic-import@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-export-namespace-from@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" - integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== +"@babel/plugin-syntax-import-assertions@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz#620412405058efa56e4a564903b79355020f445f" + integrity sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg== dependencies: - "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-syntax-import-assertions@^7.24.7": - version "7.25.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz#bb918905c58711b86f9710d74a3744b6c56573b5" - integrity sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ== +"@babel/plugin-syntax-import-attributes@^7.24.7", "@babel/plugin-syntax-import-attributes@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz#3b1412847699eea739b4f2602c74ce36f6b0b0f7" + integrity sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" - -"@babel/plugin-syntax-import-attributes@^7.24.7": - version "7.25.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz#6d4c78f042db0e82fd6436cd65fec5dc78ad2bde" - integrity sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ== - dependencies: - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-plugin-utils" "^7.25.9" "@babel/plugin-syntax-import-meta@^7.10.4": version "7.10.4" @@ -348,12 +325,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.24.7", "@babel/plugin-syntax-jsx@^7.7.2": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz#39a1fa4a7e3d3d7f34e2acc6be585b718d30e02d" - integrity sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ== +"@babel/plugin-syntax-jsx@^7.25.9", "@babel/plugin-syntax-jsx@^7.7.2": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz#a34313a178ea56f1951599b929c1ceacee719290" + integrity sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4": version "7.10.4" @@ -411,12 +388,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.24.7", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz#04db9ce5a9043d9c635e75ae7969a2cd50ca97ff" - integrity sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg== +"@babel/plugin-syntax-typescript@^7.25.9", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz#67dda2b74da43727cf21d46cf9afef23f4365399" + integrity sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-plugin-utils" "^7.25.9" "@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" @@ -426,530 +403,512 @@ "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-arrow-functions@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz#4f6886c11e423bd69f3ce51dbf42424a5f275514" - integrity sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ== +"@babel/plugin-transform-arrow-functions@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz#7821d4410bee5daaadbb4cdd9a6649704e176845" + integrity sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-async-generator-functions@^7.25.4": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz#2afd4e639e2d055776c9f091b6c0c180ed8cf083" - integrity sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg== +"@babel/plugin-transform-async-generator-functions@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz#1b18530b077d18a407c494eb3d1d72da505283a2" + integrity sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/helper-remap-async-to-generator" "^7.25.0" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/traverse" "^7.25.4" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-remap-async-to-generator" "^7.25.9" + "@babel/traverse" "^7.25.9" -"@babel/plugin-transform-async-to-generator@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz#72a3af6c451d575842a7e9b5a02863414355bdcc" - integrity sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA== +"@babel/plugin-transform-async-to-generator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz#c80008dacae51482793e5a9c08b39a5be7e12d71" + integrity sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ== dependencies: - "@babel/helper-module-imports" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/helper-remap-async-to-generator" "^7.24.7" + "@babel/helper-module-imports" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-remap-async-to-generator" "^7.25.9" -"@babel/plugin-transform-block-scoped-functions@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz#a4251d98ea0c0f399dafe1a35801eaba455bbf1f" - integrity sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ== +"@babel/plugin-transform-block-scoped-functions@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz#5700691dbd7abb93de300ca7be94203764fce458" + integrity sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-block-scoping@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz#23a6ed92e6b006d26b1869b1c91d1b917c2ea2ac" - integrity sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ== +"@babel/plugin-transform-block-scoping@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz#c33665e46b06759c93687ca0f84395b80c0473a1" + integrity sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-class-properties@^7.25.4": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz#bae7dbfcdcc2e8667355cd1fb5eda298f05189fd" - integrity sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g== +"@babel/plugin-transform-class-properties@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz#a8ce84fedb9ad512549984101fa84080a9f5f51f" + integrity sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q== dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.4" - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-class-static-block@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz#c82027ebb7010bc33c116d4b5044fbbf8c05484d" - integrity sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ== +"@babel/plugin-transform-class-static-block@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz#6c8da219f4eb15cae9834ec4348ff8e9e09664a0" + integrity sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-classes@^7.25.4": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz#d29dbb6a72d79f359952ad0b66d88518d65ef89a" - integrity sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg== +"@babel/plugin-transform-classes@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz#7152457f7880b593a63ade8a861e6e26a4469f52" + integrity sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-compilation-targets" "^7.25.2" - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/helper-replace-supers" "^7.25.0" - "@babel/traverse" "^7.25.4" + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-replace-supers" "^7.25.9" + "@babel/traverse" "^7.25.9" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz#4cab3214e80bc71fae3853238d13d097b004c707" - integrity sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ== +"@babel/plugin-transform-computed-properties@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz#db36492c78460e534b8852b1d5befe3c923ef10b" + integrity sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/template" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/template" "^7.25.9" -"@babel/plugin-transform-destructuring@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz#c828e814dbe42a2718a838c2a2e16a408e055550" - integrity sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ== +"@babel/plugin-transform-destructuring@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz#966ea2595c498224340883602d3cfd7a0c79cea1" + integrity sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-dotall-regex@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz#5f8bf8a680f2116a7207e16288a5f974ad47a7a0" - integrity sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw== +"@babel/plugin-transform-dotall-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz#bad7945dd07734ca52fe3ad4e872b40ed09bb09a" + integrity sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-duplicate-keys@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz#dd20102897c9a2324e5adfffb67ff3610359a8ee" - integrity sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw== +"@babel/plugin-transform-duplicate-keys@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz#8850ddf57dce2aebb4394bb434a7598031059e6d" + integrity sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz#809af7e3339466b49c034c683964ee8afb3e2604" - integrity sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g== +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz#6f7259b4de127721a08f1e5165b852fcaa696d31" + integrity sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.0" - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-dynamic-import@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz#4d8b95e3bae2b037673091aa09cd33fecd6419f4" - integrity sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg== +"@babel/plugin-transform-dynamic-import@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz#23e917de63ed23c6600c5dd06d94669dce79f7b8" + integrity sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-exponentiation-operator@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz#b629ee22645f412024297d5245bce425c31f9b0d" - integrity sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ== +"@babel/plugin-transform-exponentiation-operator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz#ece47b70d236c1d99c263a1e22b62dc20a4c8b0f" + integrity sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-export-namespace-from@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz#176d52d8d8ed516aeae7013ee9556d540c53f197" - integrity sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA== +"@babel/plugin-transform-export-namespace-from@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz#90745fe55053394f554e40584cda81f2c8a402a2" + integrity sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-for-of@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz#f25b33f72df1d8be76399e1b8f3f9d366eb5bc70" - integrity sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g== +"@babel/plugin-transform-for-of@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz#4bdc7d42a213397905d89f02350c5267866d5755" + integrity sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" -"@babel/plugin-transform-function-name@^7.25.1": - version "7.25.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz#b85e773097526c1a4fc4ba27322748643f26fc37" - integrity sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA== +"@babel/plugin-transform-function-name@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz#939d956e68a606661005bfd550c4fc2ef95f7b97" + integrity sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA== dependencies: - "@babel/helper-compilation-targets" "^7.24.8" - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/traverse" "^7.25.1" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/traverse" "^7.25.9" -"@babel/plugin-transform-json-strings@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz#f3e9c37c0a373fee86e36880d45b3664cedaf73a" - integrity sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw== +"@babel/plugin-transform-json-strings@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz#c86db407cb827cded902a90c707d2781aaa89660" + integrity sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-literals@^7.25.2": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz#deb1ad14fc5490b9a65ed830e025bca849d8b5f3" - integrity sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw== +"@babel/plugin-transform-literals@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz#1a1c6b4d4aa59bc4cad5b6b3a223a0abd685c9de" + integrity sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-logical-assignment-operators@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz#a58fb6eda16c9dc8f9ff1c7b1ba6deb7f4694cb0" - integrity sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw== +"@babel/plugin-transform-logical-assignment-operators@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz#b19441a8c39a2fda0902900b306ea05ae1055db7" + integrity sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-member-expression-literals@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz#3b4454fb0e302e18ba4945ba3246acb1248315df" - integrity sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw== +"@babel/plugin-transform-member-expression-literals@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz#63dff19763ea64a31f5e6c20957e6a25e41ed5de" + integrity sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-modules-amd@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz#65090ed493c4a834976a3ca1cde776e6ccff32d7" - integrity sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg== +"@babel/plugin-transform-modules-amd@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz#49ba478f2295101544abd794486cd3088dddb6c5" + integrity sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw== dependencies: - "@babel/helper-module-transforms" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-module-transforms" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-modules-commonjs@^7.22.15", "@babel/plugin-transform-modules-commonjs@^7.24.7", "@babel/plugin-transform-modules-commonjs@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz#ab6421e564b717cb475d6fff70ae7f103536ea3c" - integrity sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA== +"@babel/plugin-transform-modules-commonjs@^7.22.15", "@babel/plugin-transform-modules-commonjs@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz#d165c8c569a080baf5467bda88df6425fc060686" + integrity sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg== dependencies: - "@babel/helper-module-transforms" "^7.24.8" - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/helper-simple-access" "^7.24.7" + "@babel/helper-module-transforms" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-simple-access" "^7.25.9" -"@babel/plugin-transform-modules-systemjs@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz#8f46cdc5f9e5af74f3bd019485a6cbe59685ea33" - integrity sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw== +"@babel/plugin-transform-modules-systemjs@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz#8bd1b43836269e3d33307151a114bcf3ba6793f8" + integrity sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA== dependencies: - "@babel/helper-module-transforms" "^7.25.0" - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/helper-validator-identifier" "^7.24.7" - "@babel/traverse" "^7.25.0" + "@babel/helper-module-transforms" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + "@babel/traverse" "^7.25.9" -"@babel/plugin-transform-modules-umd@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz#edd9f43ec549099620df7df24e7ba13b5c76efc8" - integrity sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A== +"@babel/plugin-transform-modules-umd@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz#6710079cdd7c694db36529a1e8411e49fcbf14c9" + integrity sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw== dependencies: - "@babel/helper-module-transforms" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-module-transforms" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-named-capturing-groups-regex@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz#9042e9b856bc6b3688c0c2e4060e9e10b1460923" - integrity sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g== +"@babel/plugin-transform-named-capturing-groups-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz#454990ae6cc22fd2a0fa60b3a2c6f63a38064e6a" + integrity sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-new-target@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz#31ff54c4e0555cc549d5816e4ab39241dfb6ab00" - integrity sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA== +"@babel/plugin-transform-new-target@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz#42e61711294b105c248336dcb04b77054ea8becd" + integrity sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-nullish-coalescing-operator@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz#1de4534c590af9596f53d67f52a92f12db984120" - integrity sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ== +"@babel/plugin-transform-nullish-coalescing-operator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz#bcb1b0d9e948168102d5f7104375ca21c3266949" + integrity sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-numeric-separator@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz#bea62b538c80605d8a0fac9b40f48e97efa7de63" - integrity sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA== +"@babel/plugin-transform-numeric-separator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz#bfed75866261a8b643468b0ccfd275f2033214a1" + integrity sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-object-rest-spread@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz#d13a2b93435aeb8a197e115221cab266ba6e55d6" - integrity sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q== +"@babel/plugin-transform-object-rest-spread@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz#0203725025074164808bcf1a2cfa90c652c99f18" + integrity sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg== dependencies: - "@babel/helper-compilation-targets" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.24.7" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/plugin-transform-parameters" "^7.25.9" -"@babel/plugin-transform-object-super@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz#66eeaff7830bba945dd8989b632a40c04ed625be" - integrity sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg== +"@babel/plugin-transform-object-super@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz#385d5de135162933beb4a3d227a2b7e52bb4cf03" + integrity sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/helper-replace-supers" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-replace-supers" "^7.25.9" -"@babel/plugin-transform-optional-catch-binding@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz#00eabd883d0dd6a60c1c557548785919b6e717b4" - integrity sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA== +"@babel/plugin-transform-optional-catch-binding@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz#10e70d96d52bb1f10c5caaac59ac545ea2ba7ff3" + integrity sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-optional-chaining@^7.24.7", "@babel/plugin-transform-optional-chaining@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz#bb02a67b60ff0406085c13d104c99a835cdf365d" - integrity sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw== +"@babel/plugin-transform-optional-chaining@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz#e142eb899d26ef715435f201ab6e139541eee7dd" + integrity sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" -"@babel/plugin-transform-parameters@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz#5881f0ae21018400e320fc7eb817e529d1254b68" - integrity sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA== +"@babel/plugin-transform-parameters@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz#b856842205b3e77e18b7a7a1b94958069c7ba257" + integrity sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-private-methods@^7.25.4": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz#9bbefbe3649f470d681997e0b64a4b254d877242" - integrity sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw== +"@babel/plugin-transform-private-methods@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz#847f4139263577526455d7d3223cd8bda51e3b57" + integrity sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.4" - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-private-property-in-object@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz#4eec6bc701288c1fab5f72e6a4bbc9d67faca061" - integrity sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA== +"@babel/plugin-transform-private-property-in-object@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz#9c8b73e64e6cc3cbb2743633885a7dd2c385fe33" + integrity sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-create-class-features-plugin" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-property-literals@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz#f0d2ed8380dfbed949c42d4d790266525d63bbdc" - integrity sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA== +"@babel/plugin-transform-property-literals@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz#d72d588bd88b0dec8b62e36f6fda91cedfe28e3f" + integrity sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-react-display-name@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz#9caff79836803bc666bcfe210aeb6626230c293b" - integrity sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg== +"@babel/plugin-transform-react-display-name@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.9.tgz#4b79746b59efa1f38c8695065a92a9f5afb24f7d" + integrity sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-react-jsx-development@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz#eaee12f15a93f6496d852509a850085e6361470b" - integrity sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ== +"@babel/plugin-transform-react-jsx-development@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.9.tgz#8fd220a77dd139c07e25225a903b8be8c829e0d7" + integrity sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw== dependencies: - "@babel/plugin-transform-react-jsx" "^7.24.7" + "@babel/plugin-transform-react-jsx" "^7.25.9" -"@babel/plugin-transform-react-jsx@^7.24.7": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.2.tgz#e37e8ebfa77e9f0b16ba07fadcb6adb47412227a" - integrity sha512-KQsqEAVBpU82NM/B/N9j9WOdphom1SZH3R+2V7INrQUH+V9EBFwZsEJl8eBIVeQE62FxJCc70jzEZwqU7RcVqA== +"@babel/plugin-transform-react-jsx@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.9.tgz#06367940d8325b36edff5e2b9cbe782947ca4166" + integrity sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-module-imports" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/plugin-syntax-jsx" "^7.24.7" - "@babel/types" "^7.25.2" + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-module-imports" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/plugin-syntax-jsx" "^7.25.9" + "@babel/types" "^7.25.9" -"@babel/plugin-transform-react-pure-annotations@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz#bdd9d140d1c318b4f28b29a00fb94f97ecab1595" - integrity sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA== +"@babel/plugin-transform-react-pure-annotations@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.9.tgz#ea1c11b2f9dbb8e2d97025f43a3b5bc47e18ae62" + integrity sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-regenerator@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz#021562de4534d8b4b1851759fd7af4e05d2c47f8" - integrity sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA== +"@babel/plugin-transform-regenerator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz#03a8a4670d6cebae95305ac6defac81ece77740b" + integrity sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" regenerator-transform "^0.15.2" -"@babel/plugin-transform-reserved-words@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz#80037fe4fbf031fc1125022178ff3938bb3743a4" - integrity sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ== +"@babel/plugin-transform-regexp-modifiers@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz#2f5837a5b5cd3842a919d8147e9903cc7455b850" + integrity sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/plugin-transform-reserved-words@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz#0398aed2f1f10ba3f78a93db219b27ef417fb9ce" + integrity sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-shorthand-properties@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz#85448c6b996e122fa9e289746140aaa99da64e73" - integrity sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA== +"@babel/plugin-transform-shorthand-properties@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz#bb785e6091f99f826a95f9894fc16fde61c163f2" + integrity sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-spread@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz#e8a38c0fde7882e0fb8f160378f74bd885cc7bb3" - integrity sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng== +"@babel/plugin-transform-spread@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz#24a35153931b4ba3d13cec4a7748c21ab5514ef9" + integrity sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" -"@babel/plugin-transform-sticky-regex@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz#96ae80d7a7e5251f657b5cf18f1ea6bf926f5feb" - integrity sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g== +"@babel/plugin-transform-sticky-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz#c7f02b944e986a417817b20ba2c504dfc1453d32" + integrity sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-template-literals@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz#a05debb4a9072ae8f985bcf77f3f215434c8f8c8" - integrity sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw== +"@babel/plugin-transform-template-literals@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz#6dbd4a24e8fad024df76d1fac6a03cf413f60fe1" + integrity sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-typeof-symbol@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz#383dab37fb073f5bfe6e60c654caac309f92ba1c" - integrity sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw== +"@babel/plugin-transform-typeof-symbol@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz#224ba48a92869ddbf81f9b4a5f1204bbf5a2bc4b" + integrity sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-typescript@^7.24.7": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.2.tgz#237c5d10de6d493be31637c6b9fa30b6c5461add" - integrity sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A== +"@babel/plugin-transform-typescript@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.9.tgz#69267905c2b33c2ac6d8fe765e9dc2ddc9df3849" + integrity sha512-7PbZQZP50tzv2KGGnhh82GSyMB01yKY9scIjf1a+GfZCtInOWqUH5+1EBU4t9fyR5Oykkkc9vFTs4OHrhHXljQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-create-class-features-plugin" "^7.25.0" - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" - "@babel/plugin-syntax-typescript" "^7.24.7" + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/plugin-syntax-typescript" "^7.25.9" -"@babel/plugin-transform-unicode-escapes@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz#2023a82ced1fb4971630a2e079764502c4148e0e" - integrity sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw== +"@babel/plugin-transform-unicode-escapes@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz#a75ef3947ce15363fccaa38e2dd9bc70b2788b82" + integrity sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-unicode-property-regex@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz#9073a4cd13b86ea71c3264659590ac086605bbcd" - integrity sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w== +"@babel/plugin-transform-unicode-property-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz#a901e96f2c1d071b0d1bb5dc0d3c880ce8f53dd3" + integrity sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-unicode-regex@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz#dfc3d4a51127108099b19817c0963be6a2adf19f" - integrity sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg== +"@babel/plugin-transform-unicode-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz#5eae747fe39eacf13a8bd006a4fb0b5d1fa5e9b1" + integrity sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-unicode-sets-regex@^7.25.4": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz#be664c2a0697ffacd3423595d5edef6049e8946c" - integrity sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA== +"@babel/plugin-transform-unicode-sets-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz#65114c17b4ffc20fa5b163c63c70c0d25621fabe" + integrity sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.2" - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" "@babel/preset-env@^7.22.2", "@babel/preset-env@^7.22.20": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.25.4.tgz#be23043d43a34a2721cd0f676c7ba6f1481f6af6" - integrity sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw== - dependencies: - "@babel/compat-data" "^7.25.4" - "@babel/helper-compilation-targets" "^7.25.2" - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/helper-validator-option" "^7.24.8" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.25.3" - "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.25.0" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.25.0" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.24.7" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.25.0" + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.26.0.tgz#30e5c6bc1bcc54865bff0c5a30f6d4ccdc7fa8b1" + integrity sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw== + dependencies: + "@babel/compat-data" "^7.26.0" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-validator-option" "^7.25.9" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.25.9" + "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.25.9" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.25.9" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.25.9" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.25.9" "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.24.7" - "@babel/plugin-syntax-import-attributes" "^7.24.7" - "@babel/plugin-syntax-import-meta" "^7.10.4" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-syntax-import-assertions" "^7.26.0" + "@babel/plugin-syntax-import-attributes" "^7.26.0" "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" - "@babel/plugin-transform-arrow-functions" "^7.24.7" - "@babel/plugin-transform-async-generator-functions" "^7.25.4" - "@babel/plugin-transform-async-to-generator" "^7.24.7" - "@babel/plugin-transform-block-scoped-functions" "^7.24.7" - "@babel/plugin-transform-block-scoping" "^7.25.0" - "@babel/plugin-transform-class-properties" "^7.25.4" - "@babel/plugin-transform-class-static-block" "^7.24.7" - "@babel/plugin-transform-classes" "^7.25.4" - "@babel/plugin-transform-computed-properties" "^7.24.7" - "@babel/plugin-transform-destructuring" "^7.24.8" - "@babel/plugin-transform-dotall-regex" "^7.24.7" - "@babel/plugin-transform-duplicate-keys" "^7.24.7" - "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.25.0" - "@babel/plugin-transform-dynamic-import" "^7.24.7" - "@babel/plugin-transform-exponentiation-operator" "^7.24.7" - "@babel/plugin-transform-export-namespace-from" "^7.24.7" - "@babel/plugin-transform-for-of" "^7.24.7" - "@babel/plugin-transform-function-name" "^7.25.1" - "@babel/plugin-transform-json-strings" "^7.24.7" - "@babel/plugin-transform-literals" "^7.25.2" - "@babel/plugin-transform-logical-assignment-operators" "^7.24.7" - "@babel/plugin-transform-member-expression-literals" "^7.24.7" - "@babel/plugin-transform-modules-amd" "^7.24.7" - "@babel/plugin-transform-modules-commonjs" "^7.24.8" - "@babel/plugin-transform-modules-systemjs" "^7.25.0" - "@babel/plugin-transform-modules-umd" "^7.24.7" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.24.7" - "@babel/plugin-transform-new-target" "^7.24.7" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.24.7" - "@babel/plugin-transform-numeric-separator" "^7.24.7" - "@babel/plugin-transform-object-rest-spread" "^7.24.7" - "@babel/plugin-transform-object-super" "^7.24.7" - "@babel/plugin-transform-optional-catch-binding" "^7.24.7" - "@babel/plugin-transform-optional-chaining" "^7.24.8" - "@babel/plugin-transform-parameters" "^7.24.7" - "@babel/plugin-transform-private-methods" "^7.25.4" - "@babel/plugin-transform-private-property-in-object" "^7.24.7" - "@babel/plugin-transform-property-literals" "^7.24.7" - "@babel/plugin-transform-regenerator" "^7.24.7" - "@babel/plugin-transform-reserved-words" "^7.24.7" - "@babel/plugin-transform-shorthand-properties" "^7.24.7" - "@babel/plugin-transform-spread" "^7.24.7" - "@babel/plugin-transform-sticky-regex" "^7.24.7" - "@babel/plugin-transform-template-literals" "^7.24.7" - "@babel/plugin-transform-typeof-symbol" "^7.24.8" - "@babel/plugin-transform-unicode-escapes" "^7.24.7" - "@babel/plugin-transform-unicode-property-regex" "^7.24.7" - "@babel/plugin-transform-unicode-regex" "^7.24.7" - "@babel/plugin-transform-unicode-sets-regex" "^7.25.4" + "@babel/plugin-transform-arrow-functions" "^7.25.9" + "@babel/plugin-transform-async-generator-functions" "^7.25.9" + "@babel/plugin-transform-async-to-generator" "^7.25.9" + "@babel/plugin-transform-block-scoped-functions" "^7.25.9" + "@babel/plugin-transform-block-scoping" "^7.25.9" + "@babel/plugin-transform-class-properties" "^7.25.9" + "@babel/plugin-transform-class-static-block" "^7.26.0" + "@babel/plugin-transform-classes" "^7.25.9" + "@babel/plugin-transform-computed-properties" "^7.25.9" + "@babel/plugin-transform-destructuring" "^7.25.9" + "@babel/plugin-transform-dotall-regex" "^7.25.9" + "@babel/plugin-transform-duplicate-keys" "^7.25.9" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.25.9" + "@babel/plugin-transform-dynamic-import" "^7.25.9" + "@babel/plugin-transform-exponentiation-operator" "^7.25.9" + "@babel/plugin-transform-export-namespace-from" "^7.25.9" + "@babel/plugin-transform-for-of" "^7.25.9" + "@babel/plugin-transform-function-name" "^7.25.9" + "@babel/plugin-transform-json-strings" "^7.25.9" + "@babel/plugin-transform-literals" "^7.25.9" + "@babel/plugin-transform-logical-assignment-operators" "^7.25.9" + "@babel/plugin-transform-member-expression-literals" "^7.25.9" + "@babel/plugin-transform-modules-amd" "^7.25.9" + "@babel/plugin-transform-modules-commonjs" "^7.25.9" + "@babel/plugin-transform-modules-systemjs" "^7.25.9" + "@babel/plugin-transform-modules-umd" "^7.25.9" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.25.9" + "@babel/plugin-transform-new-target" "^7.25.9" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.25.9" + "@babel/plugin-transform-numeric-separator" "^7.25.9" + "@babel/plugin-transform-object-rest-spread" "^7.25.9" + "@babel/plugin-transform-object-super" "^7.25.9" + "@babel/plugin-transform-optional-catch-binding" "^7.25.9" + "@babel/plugin-transform-optional-chaining" "^7.25.9" + "@babel/plugin-transform-parameters" "^7.25.9" + "@babel/plugin-transform-private-methods" "^7.25.9" + "@babel/plugin-transform-private-property-in-object" "^7.25.9" + "@babel/plugin-transform-property-literals" "^7.25.9" + "@babel/plugin-transform-regenerator" "^7.25.9" + "@babel/plugin-transform-regexp-modifiers" "^7.26.0" + "@babel/plugin-transform-reserved-words" "^7.25.9" + "@babel/plugin-transform-shorthand-properties" "^7.25.9" + "@babel/plugin-transform-spread" "^7.25.9" + "@babel/plugin-transform-sticky-regex" "^7.25.9" + "@babel/plugin-transform-template-literals" "^7.25.9" + "@babel/plugin-transform-typeof-symbol" "^7.25.9" + "@babel/plugin-transform-unicode-escapes" "^7.25.9" + "@babel/plugin-transform-unicode-property-regex" "^7.25.9" + "@babel/plugin-transform-unicode-regex" "^7.25.9" + "@babel/plugin-transform-unicode-sets-regex" "^7.25.9" "@babel/preset-modules" "0.1.6-no-external-plugins" babel-plugin-polyfill-corejs2 "^0.4.10" babel-plugin-polyfill-corejs3 "^0.10.6" babel-plugin-polyfill-regenerator "^0.6.1" - core-js-compat "^3.37.1" + core-js-compat "^3.38.1" semver "^6.3.1" "@babel/preset-modules@0.1.6-no-external-plugins": @@ -962,70 +921,64 @@ esutils "^2.0.2" "@babel/preset-react@^7.22.0": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.24.7.tgz#480aeb389b2a798880bf1f889199e3641cbb22dc" - integrity sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag== + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.25.9.tgz#5f473035dc2094bcfdbc7392d0766bd42dce173e" + integrity sha512-D3to0uSPiWE7rBrdIICCd0tJSIGpLaaGptna2+w7Pft5xMqLpA1sz99DK5TZ1TjGbdQ/VI1eCSZ06dv3lT4JOw== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/helper-validator-option" "^7.24.7" - "@babel/plugin-transform-react-display-name" "^7.24.7" - "@babel/plugin-transform-react-jsx" "^7.24.7" - "@babel/plugin-transform-react-jsx-development" "^7.24.7" - "@babel/plugin-transform-react-pure-annotations" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-validator-option" "^7.25.9" + "@babel/plugin-transform-react-display-name" "^7.25.9" + "@babel/plugin-transform-react-jsx" "^7.25.9" + "@babel/plugin-transform-react-jsx-development" "^7.25.9" + "@babel/plugin-transform-react-pure-annotations" "^7.25.9" "@babel/preset-typescript@^7.21.5", "@babel/preset-typescript@^7.23.0": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz#66cd86ea8f8c014855671d5ea9a737139cbbfef1" - integrity sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ== + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz#4a570f1b8d104a242d923957ffa1eaff142a106d" + integrity sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/helper-validator-option" "^7.24.7" - "@babel/plugin-syntax-jsx" "^7.24.7" - "@babel/plugin-transform-modules-commonjs" "^7.24.7" - "@babel/plugin-transform-typescript" "^7.24.7" - -"@babel/regjsgen@^0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" - integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-validator-option" "^7.25.9" + "@babel/plugin-syntax-jsx" "^7.25.9" + "@babel/plugin-transform-modules-commonjs" "^7.25.9" + "@babel/plugin-transform-typescript" "^7.25.9" "@babel/runtime@^7.8.4": - version "7.25.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.6.tgz#9afc3289f7184d8d7f98b099884c26317b9264d2" - integrity sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ== + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1" + integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw== dependencies: regenerator-runtime "^0.14.0" -"@babel/template@^7.24.7", "@babel/template@^7.25.0", "@babel/template@^7.3.3": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.0.tgz#e733dc3134b4fede528c15bc95e89cb98c52592a" - integrity sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q== - dependencies: - "@babel/code-frame" "^7.24.7" - "@babel/parser" "^7.25.0" - "@babel/types" "^7.25.0" - -"@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.1", "@babel/traverse@^7.25.2", "@babel/traverse@^7.25.3", "@babel/traverse@^7.25.4": - version "7.25.6" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.6.tgz#04fad980e444f182ecf1520504941940a90fea41" - integrity sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ== - dependencies: - "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.25.6" - "@babel/parser" "^7.25.6" - "@babel/template" "^7.25.0" - "@babel/types" "^7.25.6" +"@babel/template@^7.25.9", "@babel/template@^7.3.3": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.9.tgz#ecb62d81a8a6f5dc5fe8abfc3901fc52ddf15016" + integrity sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg== + dependencies: + "@babel/code-frame" "^7.25.9" + "@babel/parser" "^7.25.9" + "@babel/types" "^7.25.9" + +"@babel/traverse@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84" + integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw== + dependencies: + "@babel/code-frame" "^7.25.9" + "@babel/generator" "^7.25.9" + "@babel/parser" "^7.25.9" + "@babel/template" "^7.25.9" + "@babel/types" "^7.25.9" debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.24.7", "@babel/types@^7.24.8", "@babel/types@^7.25.0", "@babel/types@^7.25.2", "@babel/types@^7.25.6", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.25.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.6.tgz#893942ddb858f32ae7a004ec9d3a76b3463ef8e6" - integrity sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw== +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.0.tgz#deabd08d6b753bc8e0f198f8709fb575e31774ff" + integrity sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA== dependencies: - "@babel/helper-string-parser" "^7.24.8" - "@babel/helper-validator-identifier" "^7.24.7" - to-fast-properties "^2.0.0" + "@babel/helper-string-parser" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" "@bcoe/v8-coverage@^0.2.3": version "0.2.3" @@ -1671,14 +1624,14 @@ url-template "^2.0.8" "@openzeppelin/contracts-upgradeable@^5.0.0": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.0.2.tgz#3e5321a2ecdd0b206064356798c21225b6ec7105" - integrity sha512-0MmkHSHiW2NRFiT9/r5Lu4eJq5UJ4/tzlOgYXNAIj/ONkQTVnz22pLxDvp4C4uZ9he7ZFvGn3Driptn1/iU7tQ== + version "5.1.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.1.0.tgz#4d37648b7402929c53e2ff6e45749ecff91eb2b6" + integrity sha512-AIElwP5Ck+cslNE+Hkemf5SxjJoF4wBvvjxc27Rp+9jaPs/CLIaUBMYe1FNzhdiN0cYuwGRmYaRHmmntuiju4Q== "@openzeppelin/contracts@^5.0.0": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.0.2.tgz#b1d03075e49290d06570b2fd42154d76c2a5d210" - integrity sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA== + version "5.1.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.1.0.tgz#4e61162f2a2bf414c4e10c45eca98ce5f1aadbd4" + integrity sha512-p1ULhl7BXzjjbha5aqst+QMLY+4/LCWADXOCsmLHRM77AqiPjnd9vvUN9sosUfhL9JGKpZ0TjEGxgvnizmWGSA== "@sinclair/typebox@^0.27.8": version "0.27.8" @@ -1771,19 +1724,19 @@ "@types/istanbul-lib-report" "*" "@types/jest@^29.5.4": - version "29.5.12" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.12.tgz#7f7dc6eb4cf246d2474ed78744b05d06ce025544" - integrity sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw== + version "29.5.14" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.14.tgz#2b910912fa1d6856cadcd0c1f95af7df1d6049e5" + integrity sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ== dependencies: expect "^29.0.0" pretty-format "^29.0.0" "@types/node@*": - version "22.5.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.4.tgz#83f7d1f65bc2ed223bdbf57c7884f1d5a4fa84e8" - integrity sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg== + version "22.8.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.8.6.tgz#e8a0c0871623283d8b3ef7d7b9b1bfdfd3028e22" + integrity sha512-tosuJYKrIqjQIlVCM4PEGxOmyg3FCPa/fViuJChnGeEIhjA46oy8FMVoF9su1/v8PNs2a8Q0iFNyOx0uOF91nw== dependencies: - undici-types "~6.19.2" + undici-types "~6.19.8" "@types/stack-utils@^2.0.0": version "2.0.3" @@ -1802,47 +1755,39 @@ dependencies: "@types/yargs-parser" "*" -"@zk-email/circuits@=6.1.5": - version "6.1.5" - resolved "https://registry.yarnpkg.com/@zk-email/circuits/-/circuits-6.1.5.tgz#53462456638edf97bbc206ead01c302ba11e7850" - integrity sha512-Hx+R7ARIZ1JLJ6Ba3qqkWdGweOS63P2VyldVgZ5z0KZ5PvgAsM1ka8AUWzq1RFZCmgbluY8yiHLzWREbQm9bOQ== +"@zk-email/circuits@=6.3.0": + version "6.3.0" + resolved "https://registry.yarnpkg.com/@zk-email/circuits/-/circuits-6.3.0.tgz#9e1be249fe0b04471d75c7f38be3782d9cfc8183" + integrity sha512-6ksOxRTNaZmuIesoWUsZpaN1p5+VK9QucOUpAry9Y5NWZtHJ0GKzIvDzI0DYfPCy+BicT8PnrNpIoJRnXS+22Q== dependencies: - "@zk-email/zk-regex-circom" "^2.1.0" + "@zk-email/zk-regex-circom" "^2.3.0" circomlib "^2.0.5" -"@zk-email/contracts@^6.1.5": - version "6.1.5" - resolved "https://registry.yarnpkg.com/@zk-email/contracts/-/contracts-6.1.5.tgz#979c2aaa30cdcdb7433ff37d74c396df0cb60107" - integrity sha512-1RW3dpYGBQXjmIlcTGMtYsux7FQoR1MezA0D0pssrNEaCO2CuQd6oAxJLpbCxFQWPbujLKn8PiEVcjP+eiGvVw== +"@zk-email/contracts@^6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@zk-email/contracts/-/contracts-6.3.1.tgz#bb8c29181819974f766e0669c7bb7e012be32fff" + integrity sha512-SiSSaHvn6BrT0vFFPA48r7jdoZi+2ZmRfU4QEQamtMqBlzVbs3ZmgTzgR4SFWz2/1SP+IIzDs9pfkkqf+6Wqcw== dependencies: "@openzeppelin/contracts" "^5.0.0" + "@openzeppelin/contracts-upgradeable" "^5.0.0" dotenv "^16.3.1" -"@zk-email/relayer-utils@=0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@zk-email/relayer-utils/-/relayer-utils-0.2.4.tgz#5f452bb2867e1efe8700a19351dbb7796f9a081f" - integrity sha512-T1N4hBL2NI7omerONdgS2HIYydNP0cRSKpyKEMRzWxelgam7HP3TgG7jYbehQn9BlCyL7o4ifNnyH9sQPaC0zA== +"@zk-email/relayer-utils@=0.3.7": + version "0.3.7" + resolved "https://registry.yarnpkg.com/@zk-email/relayer-utils/-/relayer-utils-0.3.7.tgz#a3cdcc02e3607ac2fe9a9c1d90077df702011a02" + integrity sha512-+/SYjuwO22kKp9n0syoOeRoifx7RDzZ8ycr1mAAIpEKgnySibTfGJpcFEkBTpv5eIK/a7vEev8KE6uG1Sj49EQ== dependencies: "@mapbox/node-pre-gyp" "^1.0" - "@zk-email/relayer-utils" "github:zkemail/relayer-utils" cargo-cp-artifact "^0.1" node-pre-gyp-github "https://github.com/ultamatt/node-pre-gyp-github.git" -"@zk-email/relayer-utils@github:zkemail/relayer-utils": - version "0.3.2" - resolved "https://codeload.github.com/zkemail/relayer-utils/tar.gz/aefb00fdcfbfde7fced50e5a0b086e5cc2ff64cd" - dependencies: - "@mapbox/node-pre-gyp" "^1.0" - cargo-cp-artifact "^0.1" - node-pre-gyp-github "https://github.com/ultamatt/node-pre-gyp-github.git" - -"@zk-email/zk-regex-circom@=2.1.1", "@zk-email/zk-regex-circom@^2.1.0": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@zk-email/zk-regex-circom/-/zk-regex-circom-2.1.1.tgz#e4f41fd873905d27dd05a9f07613717be4b2e5d1" - integrity sha512-tuU2Kb08fwYkAPDemL8RRvLTEKNGyUt2odYr5awkVKGCZGCV1hxIy/wke6+2fIOR8Lu82MnXVtdBk+G3gRZLbg== +"@zk-email/zk-regex-circom@=2.3.0", "@zk-email/zk-regex-circom@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@zk-email/zk-regex-circom/-/zk-regex-circom-2.3.0.tgz#9db949c53737bfddbae3ea1db0737783987a0ed5" + integrity sha512-puEcLa5og+vwf2gx2zULJ2A3R8mu89hw87Kq0O0g5+8ojL1hKGMDKY9+oIwOhg6uCJesq9/9TETXcR4JW2/Zog== dependencies: commander "^11.0.0" - snarkjs "^0.7.0" + snarkjs "^0.7.5" abbrev@1: version "1.1.1" @@ -1905,13 +1850,6 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -1995,9 +1933,9 @@ available-typed-arrays@^1.0.7: possible-typed-array-names "^1.0.0" b4a@^1.0.1: - version "1.6.6" - resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.6.tgz#a4cc349a3851987c3c4ac2d7785c18744f6da9ba" - integrity sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg== + version "1.6.7" + resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.7.tgz#a99587d4ebbfbd5a6e3b21bdb5d5fa385767abe4" + integrity sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg== babel-jest@^29.5.0, babel-jest@^29.7.0: version "29.7.0" @@ -2189,15 +2127,15 @@ browser-stdout@^1.3.1: resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== -browserslist@^4.23.1, browserslist@^4.23.3: - version "4.23.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" - integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== +browserslist@^4.24.0, browserslist@^4.24.2: + version "4.24.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580" + integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg== dependencies: - caniuse-lite "^1.0.30001646" - electron-to-chromium "^1.5.4" + caniuse-lite "^1.0.30001669" + electron-to-chromium "^1.5.41" node-releases "^2.0.18" - update-browserslist-db "^1.1.0" + update-browserslist-db "^1.1.1" bs-logger@^0.2.6: version "0.2.6" @@ -2249,10 +2187,10 @@ camelcase@^6.0.0, camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001646: - version "1.0.30001655" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz#0ce881f5a19a2dcfda2ecd927df4d5c1684b982f" - integrity sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg== +caniuse-lite@^1.0.30001669: + version "1.0.30001676" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001676.tgz#fe133d41fe74af8f7cc93b8a714c3e86a86e6f04" + integrity sha512-Qz6zwGCiPghQXGJvgQAem79esjitvJ+CxSbSQkW9H/UX5hg8XM88d4lp2W+MEQ81j+Hip58Il+jGVdazk1z9cw== cargo-cp-artifact@^0.1: version "0.1.9" @@ -2272,15 +2210,6 @@ chai@^4.3.6, chai@^4.3.7: pathval "^1.1.1" type-detect "^4.1.0" -chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -2306,11 +2235,6 @@ check-types@^11.2.3: resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.2.3.tgz#1ffdf68faae4e941fce252840b1787b8edc93b71" integrity sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg== -child_process@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/child_process/-/child_process-1.0.2.tgz#b1f7e7fc73d25e7fd1d455adc94e143830182b5a" - integrity sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g== - chokidar@^3.5.3: version "3.6.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" @@ -2336,33 +2260,25 @@ ci-info@^3.2.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== -circom_runtime@0.1.21: - version "0.1.21" - resolved "https://registry.yarnpkg.com/circom_runtime/-/circom_runtime-0.1.21.tgz#0ee93bb798b5afb8ecec30725ed14d94587a999b" - integrity sha512-qTkud630B/GK8y76hnOaaS1aNuF6prfV0dTrkeRsiJKnlP1ryQbP2FWLgDOPqn6aKyaPlam+Z+DTbBhkEzh8dA== +circom_runtime@0.1.28: + version "0.1.28" + resolved "https://registry.yarnpkg.com/circom_runtime/-/circom_runtime-0.1.28.tgz#4ea4606956eeac4499f71f65354f45b54faa93fe" + integrity sha512-ACagpQ7zBRLKDl5xRZ4KpmYIcZDUjOiNRuxvXLqhnnlLSVY1Dbvh73TI853nqoR0oEbihtWmMSjgc5f+pXf/jQ== dependencies: - ffjavascript "0.2.56" + ffjavascript "0.3.1" -circom_runtime@0.1.25: - version "0.1.25" - resolved "https://registry.yarnpkg.com/circom_runtime/-/circom_runtime-0.1.25.tgz#62a33b371f4633f30238db7a326c43d988e3a170" - integrity sha512-xBGsBFF5Uv6AKvbpgExYqpHfmfawH2HKe+LyjfKSRevqEV8u63i9KGHVIILsbJNW+0c5bm/66f0PUYQ7qZSkJA== - dependencies: - ffjavascript "0.3.0" - -circom_tester@^0.0.19: - version "0.0.19" - resolved "https://registry.yarnpkg.com/circom_tester/-/circom_tester-0.0.19.tgz#e8bed494d080f8186bd0ac6571755d00ccec83bd" - integrity sha512-SNHaBsGxcBH6XsVWfsRbRPA7NF8m8AMKJI9dtJJCFGUtOTT2+zsoIqAwi50z6XCnO4TtjyXq7AeXa1PLHqT0tw== +circom_tester@^0.0.20: + version "0.0.20" + resolved "https://registry.yarnpkg.com/circom_tester/-/circom_tester-0.0.20.tgz#066227923594c722169646c685e72ba6e1b85939" + integrity sha512-hhtqh3z1+/4RqhbAQxQTzekDvANFNd0M0+D8OdpxM1Ud4yQXoM+1n06AhJ7sULfCUD+LQrmnSjK5GD783KRSxg== dependencies: chai "^4.3.6" - child_process "^1.0.2" - ffjavascript "^0.2.56" + ffjavascript "^0.2.60" fnv-plus "^1.3.1" - r1csfile "^0.0.41" - snarkjs "0.5.0" + r1csfile "^0.0.47" + snarkjs "^0.7.0" tmp-promise "^3.0.3" - util "^0.12.4" + util "^0.12.5" circomlib@^2.0.5: version "2.0.5" @@ -2380,9 +2296,9 @@ circomlibjs@^0.1.2: ffjavascript "^0.2.45" cjs-module-lexer@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.0.tgz#677de7ed7efff67cc40c9bf1897fea79d41b5215" - integrity sha512-N1NGmowPlGBLsOZLPvm48StN04V4YvQRL0i6b7ctrVY3epjP/ct7hFLOItz6pDIvRjwpfPxi52a2UWV2ziir8g== + version "1.4.1" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz#707413784dbb3a72aa11c2f2b042a0bef4004170" + integrity sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA== cliui@^7.0.2: version "7.0.4" @@ -2412,13 +2328,6 @@ collect-v8-coverage@^1.0.0: resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -2426,11 +2335,6 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" @@ -2451,6 +2355,11 @@ commander@^11.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-11.1.0.tgz#62fdce76006a68e5c1ab3314dc92e800eb83d906" integrity sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ== +commander@^12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-12.1.0.tgz#01423b36f501259fdaac4d0e4d60c96c991585d3" + integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA== + commander@^2.17.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -2471,12 +2380,12 @@ convert-source-map@^2.0.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== -core-js-compat@^3.37.1, core-js-compat@^3.38.0: - version "3.38.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.38.1.tgz#2bc7a298746ca5a7bcb9c164bcb120f2ebc09a09" - integrity sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw== +core-js-compat@^3.38.0, core-js-compat@^3.38.1: + version "3.39.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.39.0.tgz#b12dccb495f2601dc860bdbe7b4e3ffa8ba63f61" + integrity sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw== dependencies: - browserslist "^4.23.3" + browserslist "^4.24.2" cosmiconfig@^8.0.0: version "8.3.6" @@ -2529,11 +2438,11 @@ debug@3.1.0: ms "2.0.0" debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.5: - version "4.3.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" - integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== dependencies: - ms "2.1.2" + ms "^2.1.3" debug@^3.1.0: version "3.2.7" @@ -2619,10 +2528,10 @@ ejs@^3.1.10, ejs@^3.1.6: dependencies: jake "^10.8.5" -electron-to-chromium@^1.5.4: - version "1.5.14" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.14.tgz#8de5fd941f4deede999f90503c4b5923fbe1962b" - integrity sha512-bEfPECb3fJ15eaDnu9LEJ2vPGD6W1vt7vZleSVyFhYuMIKm3vz/g9lt7IvEzgdwj58RjbPKUF2rXTCN/UW47tQ== +electron-to-chromium@^1.5.41: + version "1.5.50" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.50.tgz#d9ba818da7b2b5ef1f3dd32bce7046feb7e93234" + integrity sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw== elliptic@6.5.4: version "6.5.4" @@ -2685,16 +2594,11 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -escalade@^3.1.1, escalade@^3.1.2: +escalade@^3.1.1, escalade@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - escape-string-regexp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" @@ -2838,9 +2742,9 @@ fast-levenshtein@~2.0.6: integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fast-uri@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.1.tgz#cddd2eecfc83a71c1be2cc2ef2061331be8a7134" - integrity sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw== + version "3.0.3" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.3.tgz#892a1c91802d5d7860de728f18608a0573142241" + integrity sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw== fastfile@0.0.20: version "0.0.20" @@ -2854,16 +2758,16 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" -ffjavascript@0.2.56: - version "0.2.56" - resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.2.56.tgz#3509f98fcbd3e44ea93cd23519071b76d6eae433" - integrity sha512-em6G5Lrj7ucIqj4TYEgyoHs/j99Urwwqa4+YxEVY2hggnpRimVj+noX5pZQTxI1pvtiekZI4rG65JBf0xraXrg== +ffjavascript@0.2.60: + version "0.2.60" + resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.2.60.tgz#4d8ae613d6bf4e98b3cc29ba10c626f5853854cf" + integrity sha512-T/9bnEL5xAZRDbQoEMf+pM9nrhK+C3JyZNmqiWub26EQorW7Jt+jR54gpqDhceA4Nj0YctPQwYnl8xa52/A26A== dependencies: wasmbuilder "0.0.16" - wasmcurves "0.2.0" + wasmcurves "0.2.2" web-worker "^1.2.0" -ffjavascript@0.3.0, ffjavascript@^0.3.0: +ffjavascript@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.3.0.tgz#442cd8fbb1ee4cbb1be9d26fd7b2951a1ea45d6a" integrity sha512-l7sR5kmU3gRwDy8g0Z2tYBXy5ttmafRPFOqY7S6af5cq51JqJWt5eQ/lSR/rs2wQNbDYaYlQr5O+OSUf/oMLoQ== @@ -2872,7 +2776,16 @@ ffjavascript@0.3.0, ffjavascript@^0.3.0: wasmcurves "0.2.2" web-worker "1.2.0" -ffjavascript@^0.2.45, ffjavascript@^0.2.48, ffjavascript@^0.2.56, ffjavascript@^0.2.59: +ffjavascript@0.3.1, ffjavascript@^0.3.0, ffjavascript@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.3.1.tgz#3761bbb3f4a67b58a94a463080272bf6b5877b03" + integrity sha512-4PbK1WYodQtuF47D4pRI5KUg3Q392vuP5WjE1THSnceHdXwU3ijaoS0OqxTzLknCtz4Z2TtABzkBdBdMn3B/Aw== + dependencies: + wasmbuilder "0.0.16" + wasmcurves "0.2.2" + web-worker "1.2.0" + +ffjavascript@^0.2.45, ffjavascript@^0.2.48, ffjavascript@^0.2.60: version "0.2.63" resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.2.63.tgz#0c1216a1f123dc9181df69e144473704d2f115eb" integrity sha512-dBgdsfGks58b66JnUZeZpGxdMIDQ4QsD3VYlRJyFVrKQHb2kJy4R2gufx5oetrTxXPT+aEjg0dOvOLg1N0on4A== @@ -2929,8 +2842,8 @@ for-each@^0.3.3: is-callable "^1.1.3" "forge-std@https://github.com/foundry-rs/forge-std": - version "1.9.2" - resolved "https://github.com/foundry-rs/forge-std#1ce7535a517406b9aec7ea1ea27c1b41376f712c" + version "1.9.4" + resolved "https://github.com/foundry-rs/forge-std#1eea5bae12ae557d589f9f0f0edae2faa47cb262" fs-minipass@^2.0.0: version "2.1.0" @@ -3059,11 +2972,6 @@ graceful-fs@^4.2.9: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" @@ -3749,15 +3657,10 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== +jsesc@^3.0.2, jsesc@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" + integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== json-parse-even-better-errors@^2.3.0: version "2.3.1" @@ -3983,9 +3886,9 @@ mkdirp@^1.0.3: integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== mocha@^10.2.0: - version "10.7.3" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.7.3.tgz#ae32003cabbd52b59aece17846056a68eb4b0752" - integrity sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A== + version "10.8.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.8.2.tgz#8d8342d016ed411b12a429eb731b825f961afb96" + integrity sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg== dependencies: ansi-colors "^4.1.3" browser-stdout "^1.3.1" @@ -4013,11 +3916,6 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" @@ -4060,9 +3958,9 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -"node-pre-gyp-github@https://github.com/ultamatt/node-pre-gyp-github.git": +"node-pre-gyp-github@git+https://github.com/ultamatt/node-pre-gyp-github.git": version "1.4.3" - resolved "https://github.com/ultamatt/node-pre-gyp-github.git#e4961827f77751489bc8d4760a0479f3f985f34f" + resolved "git+https://github.com/ultamatt/node-pre-gyp-github.git#e4961827f77751489bc8d4760a0479f3f985f34f" dependencies: "@octokit/rest" "^15.9.5" commander "^2.17.0" @@ -4238,10 +4136,10 @@ pathval@^1.1.1: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== -picocolors@^1.0.0, picocolors@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59" - integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== +picocolors@^1.0.0, picocolors@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" @@ -4311,9 +4209,9 @@ prompts@^2.0.1: sisteransi "^1.0.5" pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + version "3.0.2" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.2.tgz#836f3edd6bc2ee599256c924ffe0d88573ddcbf8" + integrity sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw== dependencies: end-of-stream "^1.1.0" once "^1.3.1" @@ -4328,16 +4226,6 @@ pure-rand@^6.0.0: resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== -r1csfile@0.0.41, r1csfile@^0.0.41: - version "0.0.41" - resolved "https://registry.yarnpkg.com/r1csfile/-/r1csfile-0.0.41.tgz#e3d2709d36923156dd1fc2db9858987b30c92948" - integrity sha512-Q1WDF3u1vYeAwjHo4YuddkA8Aq0TulbKjmGm99+Atn13Lf5fTsMZBnBV9T741w8iSyPFG6Uh6sapQby77sREqA== - dependencies: - "@iden3/bigarray" "0.0.2" - "@iden3/binfileutils" "0.0.11" - fastfile "0.0.20" - ffjavascript "0.2.56" - r1csfile@0.0.48: version "0.0.48" resolved "https://registry.yarnpkg.com/r1csfile/-/r1csfile-0.0.48.tgz#a317fc75407a9da92631666c75bdfc13f0a7835a" @@ -4348,6 +4236,16 @@ r1csfile@0.0.48: fastfile "0.0.20" ffjavascript "0.3.0" +r1csfile@^0.0.47: + version "0.0.47" + resolved "https://registry.yarnpkg.com/r1csfile/-/r1csfile-0.0.47.tgz#ed95a0dc8e910e9c070253906f7a31bd8c5333c8" + integrity sha512-oI4mAwuh1WwuFg95eJDNDDL8hCaZkwnPuNZrQdLBWvDoRU7EG+L/MOHL7SwPW2Y+ZuYcTLpj3rBkgllBQZN/JA== + dependencies: + "@iden3/bigarray" "0.0.2" + "@iden3/binfileutils" "0.0.11" + fastfile "0.0.20" + ffjavascript "0.2.60" + randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -4376,10 +4274,10 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -regenerate-unicode-properties@^10.1.0: - version "10.1.1" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480" - integrity sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q== +regenerate-unicode-properties@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz#626e39df8c372338ea9b8028d1f99dc3fd9c3db0" + integrity sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA== dependencies: regenerate "^1.4.2" @@ -4400,24 +4298,29 @@ regenerator-transform@^0.15.2: dependencies: "@babel/runtime" "^7.8.4" -regexpu-core@^5.3.1: - version "5.3.2" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" - integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== +regexpu-core@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.1.1.tgz#b469b245594cb2d088ceebc6369dceb8c00becac" + integrity sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw== dependencies: - "@babel/regjsgen" "^0.8.0" regenerate "^1.4.2" - regenerate-unicode-properties "^10.1.0" - regjsparser "^0.9.1" + regenerate-unicode-properties "^10.2.0" + regjsgen "^0.8.0" + regjsparser "^0.11.0" unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.1.0" -regjsparser@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" - integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== +regjsgen@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.8.0.tgz#df23ff26e0c5b300a6470cad160a9d090c3a37ab" + integrity sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q== + +regjsparser@^0.11.0: + version "0.11.2" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.11.2.tgz#7404ad42be00226d72bcf1f003f1f441861913d8" + integrity sha512-3OGZZ4HoLJkkAZx/48mTXJNlmqTGOzc0o9OWQPuWpkOlXXPbyN6OafCcoXUnBqE2D3f/T5L+pWc1kdEmnfnRsA== dependencies: - jsesc "~0.5.0" + jsesc "~3.0.2" require-directory@^2.1.1: version "2.1.1" @@ -4564,34 +4467,18 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" -snarkjs@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/snarkjs/-/snarkjs-0.5.0.tgz#cf26bf1d3835eb16b4b330a438bad9824837d6b0" - integrity sha512-KWz8mZ2Y+6wvn6GGkQo6/ZlKwETdAGohd40Lzpwp5TUZCn6N6O4Az1SuX1rw/qREGL6Im+ycb19suCFE8/xaKA== - dependencies: - "@iden3/binfileutils" "0.0.11" - bfj "^7.0.2" - blake2b-wasm "^2.4.0" - circom_runtime "0.1.21" - ejs "^3.1.6" - fastfile "0.0.20" - ffjavascript "0.2.56" - js-sha3 "^0.8.0" - logplease "^1.2.15" - r1csfile "0.0.41" - -snarkjs@^0.7.0, snarkjs@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/snarkjs/-/snarkjs-0.7.4.tgz#b9ad5813f055ab84d33f1831a6f1f34a71b6cd46" - integrity sha512-x4cOCR4YXSyBlLtfnUUwfbZrw8wFd/Y0lk83eexJzKwZB8ELdpH+10ts8YtDsm2/a3WK7c7p514bbE8NpqxW8w== +snarkjs@=0.7.5, snarkjs@^0.7.0, snarkjs@^0.7.5: + version "0.7.5" + resolved "https://registry.yarnpkg.com/snarkjs/-/snarkjs-0.7.5.tgz#334d83b61468bdffbbf922b20734ca47be50b8ab" + integrity sha512-h+3c4rXZKLhLuHk4LHydZCk/h5GcNvk5GjVKRRkHmfb6Ntf8gHOA9zea3g656iclRuhqQ3iKDWFgiD9ypLrKiA== dependencies: "@iden3/binfileutils" "0.0.12" bfj "^7.0.2" blake2b-wasm "^2.4.0" - circom_runtime "0.1.25" + circom_runtime "0.1.28" ejs "^3.1.6" fastfile "0.0.20" - ffjavascript "0.3.0" + ffjavascript "0.3.1" js-sha3 "^0.8.0" logplease "^1.2.15" r1csfile "0.0.48" @@ -4626,6 +4513,10 @@ solhint@^3.6.1: optionalDependencies: prettier "^2.8.3" +"solidity-stringutils@github:LayerZero-Labs/solidity-stringutils": + version "0.0.1" + resolved "https://codeload.github.com/LayerZero-Labs/solidity-stringutils/tar.gz/eb21d6b502c2741145ab2a90f5f5b4fda9dfb218" + source-map-support@0.5.13: version "0.5.13" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" @@ -4709,13 +4600,6 @@ strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -4789,11 +4673,6 @@ tmpl@1.0.5: resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -4858,15 +4737,15 @@ underscore@1.12.1: resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.12.1.tgz#7bb8cc9b3d397e201cf8553336d262544ead829e" integrity sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw== -undici-types@~6.19.2: +undici-types@~6.19.8: version "6.19.8" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== unicode-canonical-property-names-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" - integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz#cb3173fe47ca743e228216e4a3ddc4c84d628cc2" + integrity sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg== unicode-match-property-ecmascript@^2.0.0: version "2.0.0" @@ -4877,9 +4756,9 @@ unicode-match-property-ecmascript@^2.0.0: unicode-property-aliases-ecmascript "^2.0.0" unicode-match-property-value-ecmascript@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" - integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== + version "2.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz#a0401aee72714598f739b68b104e4fe3a0cb3c71" + integrity sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg== unicode-property-aliases-ecmascript@^2.0.0: version "2.1.0" @@ -4893,13 +4772,13 @@ universal-user-agent@^2.0.0: dependencies: os-name "^3.0.0" -update-browserslist-db@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" - integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== +update-browserslist-db@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5" + integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A== dependencies: - escalade "^3.1.2" - picocolors "^1.0.1" + escalade "^3.2.0" + picocolors "^1.1.0" uri-js@^4.2.2: version "4.4.1" @@ -4918,7 +4797,7 @@ util-deprecate@^1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -util@^0.12.4: +util@^0.12.5: version "0.12.5" resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== @@ -4950,13 +4829,6 @@ wasmbuilder@0.0.16: resolved "https://registry.yarnpkg.com/wasmbuilder/-/wasmbuilder-0.0.16.tgz#f34c1f2c047d2f6e1065cbfec5603988f16d8549" integrity sha512-Qx3lEFqaVvp1cEYW7Bfi+ebRJrOiwz2Ieu7ZG2l7YyeSJIok/reEQCQCuicj/Y32ITIJuGIM9xZQppGx5LrQdA== -wasmcurves@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/wasmcurves/-/wasmcurves-0.2.0.tgz#ccfc5a7d3778b6e0768b82a9336c80054f9bc0cf" - integrity sha512-3e2rbxdujOwaod657gxgmdhZNn+i1qKdHO3Y/bK+8E7bV8ttV/fu5FO4/WLBACF375cK0QDLOP+65Na63qYuWA== - dependencies: - wasmbuilder "0.0.16" - wasmcurves@0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/wasmcurves/-/wasmcurves-0.2.2.tgz#ca444f6a6f6e2a5cbe6629d98ff478a62b4ccb2b"