From b9a6d5f47c0f16db8d36bdfc0c3571e46266f53f Mon Sep 17 00:00:00 2001 From: wshino Date: Wed, 13 Mar 2024 22:15:27 +0900 Subject: [PATCH 01/42] Add ECDSAOwnedDKIMRegistry. --- packages/contracts/foundry.toml | 17 + packages/contracts/package.json | 24 + packages/contracts/remappings.txt | 7 + .../src/utils/ECDSAOwnedDKIMRegistry.sol | 89 + yarn.lock | 2057 ++--------------- 5 files changed, 377 insertions(+), 1817 deletions(-) create mode 100644 packages/contracts/foundry.toml create mode 100644 packages/contracts/package.json create mode 100644 packages/contracts/remappings.txt create mode 100644 packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol diff --git a/packages/contracts/foundry.toml b/packages/contracts/foundry.toml new file mode 100644 index 00000000..aa9e36de --- /dev/null +++ b/packages/contracts/foundry.toml @@ -0,0 +1,17 @@ +[profile.default] +src = "src" +out = "artifacts" +libs = ["../../node_modules", "lib"] +optimizer = true +# via-ir = true +optimizer-runs = 20_000 +fs_permissions = [ + { access = "read", path = "./artifacts/WETH9.sol/WETH9.json" }, + { access = "read", path = "./test/build_integration" }, +] + +# See more config options https://github.com/foundry-rs/foundry/tree/master/config + +# OpenZeppelin +build_info = true +extra_output = ["storageLayout"] diff --git a/packages/contracts/package.json b/packages/contracts/package.json new file mode 100644 index 00000000..3db084a7 --- /dev/null +++ b/packages/contracts/package.json @@ -0,0 +1,24 @@ +{ + "name": "@ether-email-auth/contracts", + "version": "1.0.0", + "license": "MIT", + "scripts": { + "build": "forge build", + "test": "forge test --no-match-test \"testIntegration\"", + "lint": "solhint 'src/**/*.sol'" + }, + "dependencies": { + "@openzeppelin/contracts": "^4.9.2", + "@openzeppelin/contracts-upgradeable": "^4.9.2", + "@uniswap/v3-core": "https://github.com/Uniswap/v3-core#0.8", + "@uniswap/v3-periphery": "https://github.com/Uniswap/v3-periphery.git", + "@zk-email/contracts": "^4.1.0", + "accountabstraction": "eth-infinitism/account-abstraction#v0.6.0", + "solady": "^0.0.123" + }, + "devDependencies": { + "ds-test": "https://github.com/dapphub/ds-test", + "forge-std": "https://github.com/foundry-rs/forge-std", + "solhint": "^3.6.1" + } +} diff --git a/packages/contracts/remappings.txt b/packages/contracts/remappings.txt new file mode 100644 index 00000000..842959c0 --- /dev/null +++ b/packages/contracts/remappings.txt @@ -0,0 +1,7 @@ +@openzeppelin/=../../node_modules/@openzeppelin +@zk-email/=../../node_modules/@zk-email +@uniswap/=../../node_modules/@uniswap +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 diff --git a/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol b/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol new file mode 100644 index 00000000..45f8bc84 --- /dev/null +++ b/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "@openzeppelin/contracts/utils/Strings.sol"; +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import "@zk-email/contracts/DKIMRegistry.sol"; + +/// @title ECDSAOwnedDKIMRegistry +/// @notice A DKIM Registry that could be updated by predefined ECDSA signer +contract ECDSAOwnedDKIMRegistry is IDKIMRegistry { + using Strings for *; + using ECDSA for *; + + DKIMRegistry public dkimRegistry; + address public signer; + + string public constant SET_PREFIX = "SET:"; + string public constant REVOKE_PREFIX = "REVOKE:"; + + constructor(address _signer) { + dkimRegistry = new DKIMRegistry(); + signer = _signer; + } + + function isDKIMPublicKeyHashValid(string memory domainName, bytes32 publicKeyHash) public view returns (bool) { + return dkimRegistry.isDKIMPublicKeyHashValid(domainName, publicKeyHash); + } + + function setDKIMPublicKeyHash( + string memory selector, + string memory domainName, + bytes32 publicKeyHash, + bytes memory signature + ) public { + require(bytes(selector).length != 0, "Invalid selector"); + require(bytes(domainName).length != 0, "Invalid domain name"); + require(publicKeyHash != bytes32(0), "Invalid public key hash"); + require(isDKIMPublicKeyHashValid(domainName, publicKeyHash) == false, "publicKeyHash is already set"); + require(dkimRegistry.revokedDKIMPublicKeyHashes(publicKeyHash) == false, "publicKeyHash is revoked"); + + string memory signedMsg = computeSignedMsg(SET_PREFIX, selector, domainName, publicKeyHash); + bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); + address recoveredSigner = digest.recover(signature); + require(recoveredSigner == signer, "Invalid signature"); + + dkimRegistry.setDKIMPublicKeyHash(domainName, publicKeyHash); + } + + function revokeDKIMPublicKeyHash( + string memory selector, + string memory domainName, + bytes32 publicKeyHash, + bytes memory signature + ) public { + require(bytes(selector).length != 0, "Invalid selector"); + require(bytes(domainName).length != 0, "Invalid domain name"); + require(publicKeyHash != bytes32(0), "Invalid public key hash"); + require(isDKIMPublicKeyHashValid(domainName, publicKeyHash) == true, "publicKeyHash is not set"); + require(dkimRegistry.revokedDKIMPublicKeyHashes(publicKeyHash) == false, "publicKeyHash is already revoked"); + + string memory signedMsg = computeSignedMsg(REVOKE_PREFIX, selector, domainName, publicKeyHash); + bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); + address recoveredSigner = digest.recover(signature); + require(recoveredSigner == signer, "Invalid signature"); + + dkimRegistry.revokeDKIMPublicKeyHash(publicKeyHash); + } + + function computeSignedMsg( + string memory prefix, + string memory selector, + string memory domainName, + bytes32 publicKeyHash + ) public view returns (string memory) { + return + string.concat( + prefix, + "chain_id=", + block.chainid.toString(), + ";selector=", + selector, + ";domain=", + domainName, + ";public_key_hash=", + uint256(publicKeyHash).toHexString(), + ";" + ); + } +} diff --git a/yarn.lock b/yarn.lock index 70e2f672..b9a376ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,11 +7,6 @@ resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7" integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== -"@adraffy/ens-normalize@1.10.1": - version "1.10.1" - resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" - integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== - "@ampproject/remapping@^2.2.0": version "2.2.1" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" @@ -1031,11 +1026,6 @@ "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" -"@balena/dockerignore@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@balena/dockerignore/-/dockerignore-1.0.2.tgz#9ffe4726915251e8eb69f44ef3547e0da2c03e0d" - integrity sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q== - "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -1397,11 +1387,6 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" -"@fastify/busboy@^2.0.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.0.tgz#0709e9f4cb252351c609c6e6d8d6779a8d25edff" - integrity sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA== - "@gnosis.pm/safe-contracts@^1.3.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@gnosis.pm/safe-contracts/-/safe-contracts-1.3.0.tgz#316741a7690d8751a1f701538cfc9ec80866eedc" @@ -1420,18 +1405,6 @@ fastfile "0.0.20" ffjavascript "^0.2.48" -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -1672,94 +1645,6 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@matterlabs/hardhat-zksync-deploy@^1.1.2": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-deploy/-/hardhat-zksync-deploy-1.2.0.tgz#c4033ee5044c9f7dd1fbb64e1d3ed693f71cc777" - integrity sha512-gFKW26nXtO38/axxY9tNXya7nj8a3UCS+iB3pK/b2/GHtlO1ykBg2zubnjqJqfXlcyIzz/rqOlka0VAceQoh6w== - dependencies: - "@matterlabs/hardhat-zksync-solc" "^1.0.4" - chai "^4.3.6" - chalk "4.1.2" - fs-extra "^11.2.0" - glob "^10.3.10" - lodash "^4.17.21" - ts-morph "^21.0.1" - -"@matterlabs/hardhat-zksync-node@^1.0.1": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-node/-/hardhat-zksync-node-1.0.2.tgz#b9b1c2641ddef4ab0b97be1b73d6d1bb0eb25fab" - integrity sha512-doE5Y4chhhHAg9bv8c686XkiQMeBNfV39I4xZjiavBd6R8L7q791j1MDAvPpRqku1V2eijjR5V3ScO0stQau+w== - dependencies: - "@matterlabs/hardhat-zksync-solc" "^1.0.5" - axios "^1.6.2" - chai "^4.3.6" - chalk "4.1.2" - fs-extra "^11.1.1" - proxyquire "^2.1.3" - sinon "^17.0.1" - sinon-chai "^3.7.0" - undici "^5.14.0" - -"@matterlabs/hardhat-zksync-solc@^1.0.4", "@matterlabs/hardhat-zksync-solc@^1.0.5", "@matterlabs/hardhat-zksync-solc@^1.0.6", "@matterlabs/hardhat-zksync-solc@^1.1.4": - version "1.1.4" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-1.1.4.tgz#04a2fad6fb6b6944c64ad969080ee65b9af3f617" - integrity sha512-4/usbogh9neewR2/v8Dn2OzqVblZMUuT/iH2MyPZgPRZYQlL4SlZtMvokU9UQjZT6iSoaKCbbdWESHDHSzfUjA== - dependencies: - "@nomiclabs/hardhat-docker" "^2.0.0" - chai "^4.3.6" - chalk "4.1.2" - debug "^4.3.4" - dockerode "^4.0.2" - fs-extra "^11.1.1" - proper-lockfile "^4.1.2" - semver "^7.5.1" - sinon "^17.0.1" - sinon-chai "^3.7.0" - undici "^5.14.0" - -"@matterlabs/hardhat-zksync-verify@^1.2.2": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-verify/-/hardhat-zksync-verify-1.4.0.tgz#00f0f0d4d5c3992844f6a0dec8e339a795c03768" - integrity sha512-92mYB6AyZH0cT/rgegsvWx3N7wvbggcnEQBU7vdfSfEZ7ViTNr5SPtTJeWOVmnS4gvjZ42U42QMw5yX2P8ukbg== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@ethersproject/address" "5.7.0" - "@matterlabs/hardhat-zksync-solc" "^1.1.4" - "@nomicfoundation/hardhat-verify" "^2.0.0" - "@openzeppelin/contracts" "^4.9.2" - axios "^1.6.2" - cbor "^8.1.0" - chai "^4.3.6" - chalk "4.1.2" - debug "^4.1.1" - hardhat "^2.19.4" - sinon "^17.0.1" - sinon-chai "^3.7.0" - zksync-ethers "^6.0.0" - -"@matterlabs/zksync-contracts@^0.6.1": - version "0.6.1" - resolved "https://registry.yarnpkg.com/@matterlabs/zksync-contracts/-/zksync-contracts-0.6.1.tgz#39f061959d5890fd0043a2f1ae710f764b172230" - integrity sha512-+hucLw4DhGmTmQlXOTEtpboYCaOm/X2VJcWmnW4abNcOgQXEHX+mTxQrxEfPjIZT0ZE6z5FTUrOK9+RgUZwBMQ== - -"@metamask/eth-sig-util@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088" - integrity sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ== - dependencies: - ethereumjs-abi "^0.6.8" - ethereumjs-util "^6.2.1" - ethjs-util "^0.1.6" - tweetnacl "^1.0.3" - tweetnacl-util "^0.15.1" - -"@noble/curves@1.1.0", "@noble/curves@~1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" - integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== - dependencies: - "@noble/hashes" "1.3.1" - "@noble/curves@1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" @@ -1767,25 +1652,22 @@ dependencies: "@noble/hashes" "1.3.2" -"@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" - integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== - -"@noble/hashes@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" - integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== +"@noble/curves@1.3.0", "@noble/curves@~1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.3.0.tgz#01be46da4fd195822dab821e72f71bf4aeec635e" + integrity sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA== + dependencies: + "@noble/hashes" "1.3.3" -"@noble/hashes@1.3.2", "@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1": +"@noble/hashes@1.3.2": version "1.3.2" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== -"@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" - integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== +"@noble/hashes@1.3.3", "@noble/hashes@~1.3.2": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" + integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -1808,232 +1690,6 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@nomicfoundation/ethereumjs-block@5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.4.tgz#ff2acb98a86b9290e35e315a6abfb9aebb9cf39e" - integrity sha512-AcyacJ9eX/uPEvqsPiB+WO1ymE+kyH48qGGiGV+YTojdtas8itUTW5dehDSOXEEItWGbbzEJ4PRqnQZlWaPvDw== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-trie" "6.0.4" - "@nomicfoundation/ethereumjs-tx" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-blockchain@7.0.4": - version "7.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.4.tgz#b77511b389290b186c8d999e70f4b15c27ef44ea" - integrity sha512-jYsd/kwzbmpnxx86tXsYV8wZ5xGvFL+7/P0c6OlzpClHsbFzeF41KrYA9scON8Rg6bZu3ZTv6JOAgj3t7USUfg== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.4" - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-ethash" "3.0.4" - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-trie" "6.0.4" - "@nomicfoundation/ethereumjs-tx" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - lru-cache "^10.0.0" - -"@nomicfoundation/ethereumjs-common@4.0.4": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz#9901f513af2d4802da87c66d6f255b510bef5acb" - integrity sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg== - dependencies: - "@nomicfoundation/ethereumjs-util" "9.0.4" - -"@nomicfoundation/ethereumjs-ethash@3.0.4": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.4.tgz#06cb2502b3012fb6c11cffd44af08aecf71310da" - integrity sha512-xvIrwIMl9sSaiYKRem68+O7vYdj7Q2XWv5P7JXiIkn83918QzWHvqbswTRsH7+r6X1UEvdsURRnZbvZszEjAaQ== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.4" - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - bigint-crypto-utils "^3.2.2" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-evm@2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.4.tgz#c9c761767283ac53946185474362230b169f8f63" - integrity sha512-lTyZZi1KpeMHzaO6cSVisR2tjiTTedjo7PcmhI/+GNFo9BmyY6QYzGeSti0sFttmjbEMioHgXxl5yrLNRg6+1w== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-statemanager" "2.0.4" - "@nomicfoundation/ethereumjs-tx" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - "@types/debug" "^4.1.9" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - rustbn-wasm "^0.2.0" - -"@nomicfoundation/ethereumjs-rlp@5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz#66c95256fc3c909f6fb18f6a586475fc9762fa30" - integrity sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw== - -"@nomicfoundation/ethereumjs-statemanager@2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.4.tgz#bf14415e1f31b5ea8b98a0c027c547d0555059b6" - integrity sha512-HPDjeFrxw6llEi+BzqXkZ+KkvFnTOPczuHBtk21hRlDiuKuZz32dPzlhpRsDBGV1b5JTmRDUVqCS1lp3Gghw4Q== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-trie" "6.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - js-sdsl "^4.1.4" - lru-cache "^10.0.0" - -"@nomicfoundation/ethereumjs-trie@6.0.4": - version "6.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.4.tgz#688a3f76646c209365ee6d959c3d7330ede5e609" - integrity sha512-3nSwQiFMvr2VFe/aZUyinuohYvtytUqZCUCvIWcPJ/BwJH6oQdZRB42aNFBJ/8nAh2s3OcroWpBLskzW01mFKA== - dependencies: - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - "@types/readable-stream" "^2.3.13" - ethereum-cryptography "0.1.3" - lru-cache "^10.0.0" - readable-stream "^3.6.0" - -"@nomicfoundation/ethereumjs-tx@5.0.4": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz#b0ceb58c98cc34367d40a30d255d6315b2f456da" - integrity sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-util@9.0.4": - version "9.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz#84c5274e82018b154244c877b76bc049a4ed7b38" - integrity sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q== - dependencies: - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-verkle@0.0.2": - version "0.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-verkle/-/ethereumjs-verkle-0.0.2.tgz#7686689edec775b2efea5a71548f417c18f7dea4" - integrity sha512-bjnfZElpYGK/XuuVRmLS3yDvr+cDs85D9oonZ0YUa5A3lgFgokWMp76zXrxX2jVQ0BfHaw12y860n1+iOi6yFQ== - dependencies: - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - lru-cache "^10.0.0" - rust-verkle-wasm "^0.0.1" - -"@nomicfoundation/ethereumjs-vm@7.0.4": - version "7.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.4.tgz#e5a6eec4877dc62dda93003c6d7afd1fe4b9625b" - integrity sha512-gsA4IhmtWHI4BofKy3kio9W+dqZQs5Ji5mLjLYxHCkat+JQBUt5szjRKra2F9nGDJ2XcI/wWb0YWUFNgln4zRQ== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.4" - "@nomicfoundation/ethereumjs-blockchain" "7.0.4" - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-evm" "2.0.4" - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-statemanager" "2.0.4" - "@nomicfoundation/ethereumjs-trie" "6.0.4" - "@nomicfoundation/ethereumjs-tx" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/hardhat-verify@^2.0.0": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.4.tgz#65b86787fc7b47d38fd941862266065c7eb9bca4" - integrity sha512-B8ZjhOrmbbRWqJi65jvQblzjsfYktjqj2vmOm+oc2Vu8drZbT2cjeSCRHZKbS7lOtfW78aJZSFvw+zRLCiABJA== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@ethersproject/address" "^5.0.2" - cbor "^8.1.0" - chalk "^2.4.2" - debug "^4.1.1" - lodash.clonedeep "^4.5.0" - semver "^6.3.0" - table "^6.8.0" - undici "^5.14.0" - -"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz#4c858096b1c17fe58a474fe81b46815f93645c15" - integrity sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w== - -"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz#6e25ccdf6e2d22389c35553b64fe6f3fdaec432c" - integrity sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA== - -"@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz#0a224ea50317139caeebcdedd435c28a039d169c" - integrity sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA== - -"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz#dfa085d9ffab9efb2e7b383aed3f557f7687ac2b" - integrity sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg== - -"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz#c9e06b5d513dd3ab02a7ac069c160051675889a4" - integrity sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w== - -"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz#8d328d16839e52571f72f2998c81e46bf320f893" - integrity sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA== - -"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz#9b49d0634b5976bb5ed1604a1e1b736f390959bb" - integrity sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w== - -"@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz#e2867af7264ebbcc3131ef837878955dd6a3676f" - integrity sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg== - -"@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz#0685f78608dd516c8cdfb4896ed451317e559585" - integrity sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ== - -"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz#c9a44f7108646f083b82e851486e0f6aeb785836" - integrity sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw== - -"@nomicfoundation/solidity-analyzer@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz#f5f4d36d3f66752f59a57e7208cd856f3ddf6f2d" - integrity sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg== - optionalDependencies: - "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.1" - "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.1" - "@nomicfoundation/solidity-analyzer-freebsd-x64" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.1" - "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.1" - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc" "0.1.1" - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.1" - "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.1" - -"@nomiclabs/hardhat-docker@^2.0.0": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-docker/-/hardhat-docker-2.0.2.tgz#ae964be17951275a55859ff7358e9e7c77448846" - integrity sha512-XgGEpRT3wlA1VslyB57zyAHV+oll8KnV1TjwnxxC1tpAL04/lbdwpdO5KxInVN8irMSepqFpsiSkqlcnvbE7Ng== - dependencies: - dockerode "^2.5.8" - fs-extra "^7.0.1" - node-fetch "^2.6.0" - "@nomiclabs/hardhat-etherscan@^2.1.6": version "2.1.8" resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-2.1.8.tgz#e206275e96962cd15e5ba9148b44388bc922d8c2" @@ -2047,26 +1703,10 @@ node-fetch "^2.6.0" semver "^6.3.0" -"@nomiclabs/hardhat-etherscan@^3.1.7": - version "3.1.8" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.8.tgz#3c12ee90b3733e0775e05111146ef9418d4f5a38" - integrity sha512-v5F6IzQhrsjHh6kQz4uNrym49brK9K5bYCq2zQZ729RYRaifI9hHbtmK+KkIVevfhut7huQFEQ77JLRMAzWYjQ== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@ethersproject/address" "^5.0.2" - cbor "^8.1.0" - chalk "^2.4.2" - debug "^4.1.1" - fs-extra "^7.0.1" - lodash "^4.17.11" - semver "^6.3.0" - table "^6.8.0" - undici "^5.14.0" - "@openzeppelin/contracts-upgradeable@^4.9.2": - version "4.9.3" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.3.tgz#ff17a80fb945f5102571f8efecb5ce5915cc4811" - integrity sha512-jjaHAVRMrE4UuZNfDwjlLGDxTHWIOwTJS2ldnc278a0gevfXfPr8hxKEVBGFBE96kl2G3VHDZhUimw/+G3TG2A== + version "4.9.6" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.6.tgz#38b21708a719da647de4bb0e4802ee235a0d24df" + integrity sha512-m4iHazOsOCv1DgM7eD7GupTJ+NFVujRZt1wzddDPSVGpWdKq1SKkla5htKG7+IS4d2XOCtzkUNwRZ7Vq5aEUMA== "@openzeppelin/contracts@3.4.2-solc-0.7": version "3.4.2-solc-0.7" @@ -2074,139 +1714,37 @@ integrity sha512-W6QmqgkADuFcTLzHL8vVoNBtkwjvQRpYIAom7KiUNoLKghyx3FgH0GBjt8NRvigV1ZmMOBllvE1By1C+bi8WpA== "@openzeppelin/contracts@^4.2.0", "@openzeppelin/contracts@^4.9.2", "@openzeppelin/contracts@^4.9.3": - version "4.9.3" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.3.tgz#00d7a8cf35a475b160b3f0293a6403c511099364" - integrity sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg== + version "4.9.6" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.6.tgz#2a880a24eb19b4f8b25adc2a5095f2aa27f39677" + integrity sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA== -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - -"@scure/base@^1.1.1": +"@scure/base@~1.1.4": version "1.1.5" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.5.tgz#1d85d17269fe97694b9c592552dd9e5e33552157" integrity sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ== -"@scure/base@~1.1.0": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.3.tgz#8584115565228290a6c6c4961973e0903bb3df2f" - integrity sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q== - -"@scure/bip32@1.1.5": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.5.tgz#d2ccae16dcc2e75bc1d75f5ef3c66a338d1ba300" - integrity sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw== - dependencies: - "@noble/hashes" "~1.2.0" - "@noble/secp256k1" "~1.7.0" - "@scure/base" "~1.1.0" - -"@scure/bip32@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.1.tgz#7248aea723667f98160f593d621c47e208ccbb10" - integrity sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A== +"@scure/bip32@1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.3.tgz#a9624991dc8767087c57999a5d79488f48eae6c8" + integrity sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ== dependencies: - "@noble/curves" "~1.1.0" - "@noble/hashes" "~1.3.1" - "@scure/base" "~1.1.0" + "@noble/curves" "~1.3.0" + "@noble/hashes" "~1.3.2" + "@scure/base" "~1.1.4" -"@scure/bip39@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" - integrity sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg== +"@scure/bip39@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.2.tgz#f3426813f4ced11a47489cbcf7294aa963966527" + integrity sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA== dependencies: - "@noble/hashes" "~1.2.0" - "@scure/base" "~1.1.0" - -"@scure/bip39@1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a" - integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg== - dependencies: - "@noble/hashes" "~1.3.0" - "@scure/base" "~1.1.0" - -"@sentry/core@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" - integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== - dependencies: - "@sentry/hub" "5.30.0" - "@sentry/minimal" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/hub@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" - integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== - dependencies: - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/minimal@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" - integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== - dependencies: - "@sentry/hub" "5.30.0" - "@sentry/types" "5.30.0" - tslib "^1.9.3" - -"@sentry/node@^5.18.1": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.30.0.tgz#4ca479e799b1021285d7fe12ac0858951c11cd48" - integrity sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg== - dependencies: - "@sentry/core" "5.30.0" - "@sentry/hub" "5.30.0" - "@sentry/tracing" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - cookie "^0.4.1" - https-proxy-agent "^5.0.0" - lru_map "^0.3.3" - tslib "^1.9.3" - -"@sentry/tracing@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" - integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== - dependencies: - "@sentry/hub" "5.30.0" - "@sentry/minimal" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/types@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" - integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== - -"@sentry/utils@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" - integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== - dependencies: - "@sentry/types" "5.30.0" - tslib "^1.9.3" + "@noble/hashes" "~1.3.2" + "@scure/base" "~1.1.4" "@sinclair/typebox@^0.27.8": version "0.27.8" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== -"@sinonjs/commons@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" - integrity sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg== - dependencies: - type-detect "4.0.8" - "@sinonjs/commons@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.0.tgz#beb434fe875d965265e04722ccfc21df7f755d72" @@ -2221,27 +1759,6 @@ dependencies: "@sinonjs/commons" "^3.0.0" -"@sinonjs/fake-timers@^11.2.2": - version "11.2.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz#50063cc3574f4a27bd8453180a04171c85cc9699" - integrity sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw== - dependencies: - "@sinonjs/commons" "^3.0.0" - -"@sinonjs/samsam@^8.0.0": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-8.0.0.tgz#0d488c91efb3fa1442e26abea81759dfc8b5ac60" - integrity sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew== - dependencies: - "@sinonjs/commons" "^2.0.0" - lodash.get "^4.4.2" - type-detect "^4.0.8" - -"@sinonjs/text-encoding@^0.7.2": - version "0.7.2" - resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz#5981a8db18b56ba38ef0efb7d995b12aa7b51918" - integrity sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ== - "@solidity-parser/parser@^0.16.0": version "0.16.1" resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.1.tgz#f7c8a686974e1536da0105466c4db6727311253c" @@ -2249,6 +1766,11 @@ dependencies: antlr4ts "^0.5.0-alpha.4" +"@solidity-parser/parser@^0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.18.0.tgz#8e77a02a09ecce957255a2f48c9a7178ec191908" + integrity sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA== + "@thehubbleproject/bls@^0.5.1": version "0.5.1" resolved "https://registry.yarnpkg.com/@thehubbleproject/bls/-/bls-0.5.1.tgz#6b0565f56fc9c8896dcf3c8f0e2214b69a06167f" @@ -2257,16 +1779,6 @@ ethers "^5.5.3" mcl-wasm "^1.0.0" -"@ts-morph/common@~0.22.0": - version "0.22.0" - resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.22.0.tgz#8951d451622a26472fbc3a227d6c3a90e687a683" - integrity sha512-HqNBuV/oIlMKdkLshXd1zKBqNQCsuPEsgQOkfFQ/eUKjRlwndXW1AjN9LVkBEIukm00gGXSRmfkl0Wv5VXLnlw== - dependencies: - fast-glob "^3.3.2" - minimatch "^9.0.3" - mkdirp "^3.0.1" - path-browserify "^1.0.1" - "@typechain/hardhat@^2.3.0": version "2.3.1" resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-2.3.1.tgz#1e8a6e3795e115a5d5348526282b5c597fab0b78" @@ -2307,13 +1819,6 @@ dependencies: "@babel/types" "^7.20.7" -"@types/bn.js@^4.11.3": - version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" - integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== - dependencies: - "@types/node" "*" - "@types/bn.js@^5.1.0": version "5.1.5" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.5.tgz#2e0dacdcce2c0f16b905d20ff87aedbc6f7b4bf0" @@ -2321,13 +1826,6 @@ dependencies: "@types/node" "*" -"@types/debug@^4.1.9": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" - integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== - dependencies: - "@types/ms" "*" - "@types/glob@^7.1.1": version "7.2.0" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" @@ -2370,11 +1868,6 @@ expect "^29.0.0" pretty-format "^29.0.0" -"@types/lru-cache@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" - integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== - "@types/minimatch@*": version "5.1.2" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" @@ -2385,12 +1878,7 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== -"@types/ms@*": - version "0.7.33" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.33.tgz#80bf1da64b15f21fd8c1dc387c31929317d99ee9" - integrity sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ== - -"@types/node@*", "@types/node@^20.2.5": +"@types/node@*": version "20.8.10" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.10.tgz#a5448b895c753ae929c26ce85cab557c6d4a365e" integrity sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w== @@ -2402,30 +1890,29 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== +"@types/node@^20.2.5": + version "20.11.26" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.26.tgz#3fbda536e51d5c79281e1d9657dcb0131baabd2d" + integrity sha512-YwOMmyhNnAWijOBQweOJnQPl068Oqd4K3OFbTc6AHJwzweUwwWG3GIFY74OKks2PJUDkQPeddOQES9mLn1CTEQ== + dependencies: + undici-types "~5.26.4" + "@types/pbkdf2@^3.0.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.1.tgz#c290c1f0d3dc364af94c2c5ee92046a13b7f89fd" - integrity sha512-4HCoGwR3221nOc7G0Z/6KgTNGgaaFGkbGrtUJsB+zlKX2LBVjFHHIUkieMBgHHXgBH5Gq6dZHJKdBYdtlhBQvw== + version "3.1.2" + resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.2.tgz#2dc43808e9985a2c69ff02e2d2027bd4fe33e8dc" + integrity sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew== dependencies: "@types/node" "*" "@types/qs@^6.9.7": - version "6.9.9" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.9.tgz#66f7b26288f6799d279edf13da7ccd40d2fa9197" - integrity sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg== - -"@types/readable-stream@^2.3.13": - version "2.3.15" - resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.15.tgz#3d79c9ceb1b6a57d5f6e6976f489b9b5384321ae" - integrity sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ== - dependencies: - "@types/node" "*" - safe-buffer "~5.1.1" + version "6.9.12" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.12.tgz#afa96b383a3a6fdc859453a1892d41b607fc7756" + integrity sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg== "@types/secp256k1@^4.0.1": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.5.tgz#14b1766b4fbc198b0af5599d9fd21c89056633ce" - integrity sha512-aIonTBMErtE3T9MxDvTZRzcrT/mCqpEZBw3CCY/i+oG9n57N/+7obBkhFgavUAIrX21bU0LHg1XRgtaLdelBhA== + version "4.0.6" + resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.6.tgz#d60ba2349a51c2cbc5e816dcd831a42029d376bf" + integrity sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ== dependencies: "@types/node" "*" @@ -2524,14 +2011,6 @@ commander "^11.0.0" snarkjs "^0.7.0" -JSONStream@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea" - integrity sha512-mn0KSip7N4e0UDPZHnqDsHECo5uGQrixQKnAskOM1BIB8hd7QKbd6il8IPRPudPHOeHiECoCFqhyMaRO9+nWyA== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -2561,21 +2040,11 @@ accountabstraction@eth-infinitism/account-abstraction#v0.6.0: table "^6.8.0" typescript "^4.3.5" -address@^1.0.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" - integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== - addressparser@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/addressparser/-/addressparser-1.0.1.tgz#47afbe1a2a9262191db6838e4fd1d39b40821746" integrity sha512-aQX7AISOMM7HFE0iZ3+YnD07oIeJqWGVnJ+ZIKaBZAk03ftmVYVqsGas/rbXKR21n4D/hKCSHypvcyOkds/xzg== -adm-zip@^0.4.16: - version "0.4.16" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" - integrity sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg== - aes-js@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" @@ -2591,21 +2060,6 @@ aes-js@^3.1.2: resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - ajv@^6.12.6: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -2631,13 +2085,6 @@ amdefine@>=0.0.4: resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg== -ansi-align@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" - integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== - dependencies: - string-width "^4.1.0" - ansi-colors@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" @@ -2648,7 +2095,7 @@ ansi-colors@^4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== -ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: +ansi-escapes@^4.2.1: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -2660,11 +2107,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-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -2684,11 +2126,6 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - antlr4@^4.11.0: version "4.13.1" resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.13.1.tgz#1e0a1830a08faeb86217cb2e6c34716004e4253d" @@ -2724,13 +2161,6 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -asn1@^0.2.6: - version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" @@ -2783,15 +2213,6 @@ axios@^0.21.1: dependencies: follow-redirects "^1.14.0" -axios@^1.6.2: - version "1.6.7" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.7.tgz#7b48c2e27c96f9c68a2f8f31e2ab19f59b06b0a7" - integrity sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA== - dependencies: - follow-redirects "^1.15.4" - form-data "^4.0.0" - proxy-from-env "^1.1.0" - b4a@^1.0.1: version "1.6.4" resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.4.tgz#ef1c1422cae5ce6535ec191baeed7567443f36c9" @@ -2893,23 +2314,11 @@ base-x@^3.0.2: dependencies: safe-buffer "^5.0.1" -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - base64-sol@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/base64-sol/-/base64-sol-1.0.1.tgz#91317aa341f0bc763811783c5729f1c2574600f6" integrity sha512-ld3cCNMeXt4uJXmLZBHFGMvVpK9KsLVEhPpFRXnvSVAqABKbuNZg/+dsq3NuM+wxFLb/UrVkz7m1ciWmkMfTbg== -bcrypt-pbkdf@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== - dependencies: - tweetnacl "^0.14.3" - bech32@1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" @@ -2926,11 +2335,6 @@ bfj@^7.0.2: jsonpath "^1.1.1" tryer "^1.0.1" -bigint-crypto-utils@^3.2.2: - version "3.3.0" - resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" - integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== - bignumber.js@^9.0.1: version "9.1.2" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" @@ -2941,23 +2345,6 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bl@^1.0.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" - integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== - dependencies: - readable-stream "^2.3.5" - safe-buffer "^5.1.1" - -bl@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - blake-hash@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/blake-hash/-/blake-hash-2.0.0.tgz#af184dce641951126d05b7d1c3de3224f538d66e" @@ -2998,7 +2385,7 @@ bn.js@4.11.6: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" integrity sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA== -bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9: +bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== @@ -3008,20 +2395,6 @@ bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== -boxen@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" - integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== - dependencies: - ansi-align "^3.0.0" - camelcase "^6.2.0" - chalk "^4.1.0" - cli-boxes "^2.2.1" - string-width "^4.2.2" - type-fest "^0.20.2" - widest-line "^3.1.0" - wrap-ansi "^7.0.0" - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -3106,24 +2479,6 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" -buffer-alloc-unsafe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" - integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== - -buffer-alloc@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" - integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== - dependencies: - buffer-alloc-unsafe "^1.1.0" - buffer-fill "^1.0.0" - -buffer-fill@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" - integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== - buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -3134,25 +2489,7 @@ buffer-xor@^1.0.3: resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -buildcheck@~0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.6.tgz#89aa6e417cfd1e2196e3f8fe915eb709d2fe4238" - integrity sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A== - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4: +call-bind@^1.0.2, call-bind@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== @@ -3161,6 +2498,17 @@ call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4: get-intrinsic "^1.2.1" set-function-length "^1.1.1" +call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -3194,13 +2542,6 @@ cbor@^5.0.2: bignumber.js "^9.0.1" nofilter "^1.0.4" -cbor@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.1.0.tgz#cfc56437e770b73417a2ecbfc9caf6b771af60d5" - integrity sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg== - dependencies: - nofilter "^3.1.0" - chai@^4.3.6, chai@^4.3.7: version "4.3.10" resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.10.tgz#d784cec635e3b7e2ffb66446a63b4e33bd390384" @@ -3214,14 +2555,6 @@ chai@^4.3.6, chai@^4.3.7: pathval "^1.1.1" type-detect "^4.0.8" -chalk@4.1.2, 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" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -3231,6 +2564,14 @@ chalk@^2.4.2: 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" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + char-regex@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" @@ -3253,7 +2594,7 @@ child_process@^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, chokidar@^3.5.2: +chokidar@3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -3268,7 +2609,7 @@ chokidar@3.5.3, chokidar@^3.5.2: optionalDependencies: fsevents "~2.3.2" -chokidar@^3.4.0: +chokidar@^3.5.2: version "3.6.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== @@ -3283,16 +2624,6 @@ chokidar@^3.4.0: optionalDependencies: fsevents "~2.3.2" -chownr@^1.0.1, chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - ci-info@^3.2.0: version "3.9.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" @@ -3354,16 +2685,6 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cli-boxes@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== - cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -3387,11 +2708,6 @@ co@^4.6.0: resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== -code-block-writer@^12.0.0: - version "12.0.0" - resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-12.0.0.tgz#4dd58946eb4234105aff7f0035977b2afdc2a770" - integrity sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w== - collect-v8-coverage@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" @@ -3428,16 +2744,6 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -command-exists@^1.2.8: - version "1.2.9" - resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" - integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== - -commander@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" - integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== - commander@^10.0.0: version "10.0.1" resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" @@ -3453,26 +2759,11 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -concat-stream@~1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - convert-source-map@^2.0.0: version "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== -cookie@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" - integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== - core-js-compat@^3.31.0, core-js-compat@^3.33.1: version "3.33.2" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.2.tgz#3ea4563bfd015ad4e4b52442865b02c62aba5085" @@ -3480,11 +2771,6 @@ core-js-compat@^3.31.0, core-js-compat@^3.33.1: dependencies: browserslist "^4.22.1" -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - cosmiconfig@^8.0.0: version "8.3.6" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" @@ -3495,14 +2781,6 @@ cosmiconfig@^8.0.0: parse-json "^5.2.0" path-type "^4.0.0" -cpu-features@~0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.9.tgz#5226b92f0f1c63122b0a3eb84cb8335a4de499fc" - integrity sha512-AKjgn2rP2yJyfbepsmLfiYcmtNn/2eUvocUyM/09yB0YDiz39HteK/5/T4Onf0pmdYDMgkBoGvRLvEguzyL7wQ== - dependencies: - buildcheck "~0.0.6" - nan "^2.17.0" - create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" @@ -3539,7 +2817,7 @@ create-jest@^29.7.0: jest-util "^29.7.0" prompts "^2.0.1" -cross-spawn@^7.0.0, cross-spawn@^7.0.3: +cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -3553,20 +2831,13 @@ death@^1.1.0: resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" integrity sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w== -debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: +debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@^3.2.6: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - decamelize@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" @@ -3603,29 +2874,25 @@ define-data-property@^1.1.1: gopd "^1.0.1" has-property-descriptors "^1.0.0" +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -detect-port@^1.3.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" - integrity sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ== - dependencies: - address "^1.0.1" - debug "4" - diff-sequences@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" @@ -3636,11 +2903,6 @@ diff@5.0.0: resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== -diff@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" - integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== - difflib@^0.2.4: version "0.2.4" resolved "https://registry.yarnpkg.com/difflib/-/difflib-0.2.4.tgz#b5e30361a6db023176d562892db85940a718f47e" @@ -3655,58 +2917,15 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" -docker-modem@^1.0.8: - version "1.0.9" - resolved "https://registry.yarnpkg.com/docker-modem/-/docker-modem-1.0.9.tgz#a1f13e50e6afb6cf3431b2d5e7aac589db6aaba8" - integrity sha512-lVjqCSCIAUDZPAZIeyM125HXfNvOmYYInciphNrLrylUtKyW66meAjSPXWchKVzoIYZx69TPnAepVSSkeawoIw== - dependencies: - JSONStream "1.3.2" - debug "^3.2.6" - readable-stream "~1.0.26-4" - split-ca "^1.0.0" - -docker-modem@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/docker-modem/-/docker-modem-5.0.3.tgz#50c06f11285289f58112b5c4c4d89824541c41d0" - integrity sha512-89zhop5YVhcPEt5FpUFGr3cDyceGhq/F9J+ZndQ4KfqNvfbJpPMfgeixFgUj5OjCYAboElqODxY5Z1EBsSa6sg== - dependencies: - debug "^4.1.1" - readable-stream "^3.5.0" - split-ca "^1.0.1" - ssh2 "^1.15.0" - -dockerode@^2.5.8: - version "2.5.8" - resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-2.5.8.tgz#1b661e36e1e4f860e25f56e0deabe9f87f1d0acc" - integrity sha512-+7iOUYBeDTScmOmQqpUYQaE7F4vvIt6+gIZNHWhqAQEI887tiPFB9OvXI/HzQYqfUNvukMK+9myLW63oTJPZpw== - dependencies: - concat-stream "~1.6.2" - docker-modem "^1.0.8" - tar-fs "~1.16.3" - -dockerode@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-4.0.2.tgz#dedc8529a1db3ac46d186f5912389899bc309f7d" - integrity sha512-9wM1BVpVMFr2Pw3eJNXrYYt6DT9k0xMcsSCjtPvyQ+xa1iPg/Mo3T/gUcwI0B2cczqCeCYRPF8yFYDwtFXT0+w== - dependencies: - "@balena/dockerignore" "^1.0.2" - docker-modem "^5.0.3" - tar-fs "~2.0.1" - dotenv@^16.3.1: - version "16.3.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" - integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== + version "16.4.5" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== "ds-test@https://github.com/dapphub/ds-test": version "1.0.0" resolved "https://github.com/dapphub/ds-test#e282159d5170298eb2455a6c05280ab5a73a4ef0" -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - ejs@^3.1.6: version "3.1.9" resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" @@ -3719,7 +2938,7 @@ electron-to-chromium@^1.4.535: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.576.tgz#0c6940fdc0d60f7e34bd742b29d8fa847c9294d1" integrity sha512-yXsZyXJfAqzWk1WKryr0Wl0MN2D47xodPvEEwlVePBnhU5E7raevLQR+E6b9JAD3GfL/7MbAL9ZtWQQPcLx7wA== -elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: +elliptic@6.5.4: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== @@ -3732,9 +2951,22 @@ elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" -emittery@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" +elliptic@^6.5.4: + version "6.5.5" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.5.tgz#c715e09f78b6923977610d4c2346d6ce22e6dded" + integrity sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== emoji-regex@^8.0.0: @@ -3742,11 +2974,6 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - encode-utf8@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda" @@ -3757,14 +2984,7 @@ encoding-japanese@2.0.0: resolved "https://registry.yarnpkg.com/encoding-japanese/-/encoding-japanese-2.0.0.tgz#fa0226e5469e7b5b69a04fea7d5481bd1fa56936" integrity sha512-++P0RhebUC8MJAwJOsT93dT+5oc5oPImp1HubZpAuCZ5kTLnhuuBhKHj2jJeO/Gj93idPBWmIuQ9QWMe5rX3pQ== -end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -enquirer@^2.3.0, enquirer@^2.3.6: +enquirer@^2.3.6: version "2.4.1" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== @@ -3772,11 +2992,6 @@ enquirer@^2.3.0, enquirer@^2.3.6: ansi-colors "^4.1.1" strip-ansi "^6.0.1" -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -3784,6 +2999,18 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -3865,7 +3092,7 @@ ethereum-bloom-filters@^1.0.6: dependencies: js-sha3 "^0.8.0" -ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: +ethereum-cryptography@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== @@ -3886,46 +3113,15 @@ ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: secp256k1 "^4.0.1" setimmediate "^1.0.5" -ethereum-cryptography@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz#5ccfa183e85fdaf9f9b299a79430c044268c9b3a" - integrity sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw== - dependencies: - "@noble/hashes" "1.2.0" - "@noble/secp256k1" "1.7.1" - "@scure/bip32" "1.1.5" - "@scure/bip39" "1.1.1" - ethereum-cryptography@^2.0.0, ethereum-cryptography@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz#18fa7108622e56481157a5cb7c01c0c6a672eb67" - integrity sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug== - dependencies: - "@noble/curves" "1.1.0" - "@noble/hashes" "1.3.1" - "@scure/bip32" "1.3.1" - "@scure/bip39" "1.2.1" - -ethereumjs-abi@^0.6.8: - version "0.6.8" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" - integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== - dependencies: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - -ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" - integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== + version "2.1.3" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz#1352270ed3b339fe25af5ceeadcf1b9c8e30768a" + integrity sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA== dependencies: - "@types/bn.js" "^4.11.3" - bn.js "^4.11.0" - create-hash "^1.1.2" - elliptic "^6.5.2" - ethereum-cryptography "^0.1.3" - ethjs-util "0.1.6" - rlp "^2.2.3" + "@noble/curves" "1.3.0" + "@noble/hashes" "1.3.3" + "@scure/bip32" "1.3.3" + "@scure/bip39" "1.2.2" ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.2: version "7.1.5" @@ -4001,19 +3197,6 @@ ethers@^6.8.0: tslib "2.4.0" ws "8.5.0" -ethers@^6.9.0: - version "6.11.1" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.11.1.tgz#96aae00b627c2e35f9b0a4d65c7ab658259ee6af" - integrity sha512-mxTAE6wqJQAbp5QAe/+o+rXOID7Nw91OZXvgpjDa1r4fAbq2Nu314oEZSbjoRLacuCzs7kUC3clEvkCQowffGg== - dependencies: - "@adraffy/ens-normalize" "1.10.1" - "@noble/curves" "1.2.0" - "@noble/hashes" "1.3.2" - "@types/node" "18.15.13" - aes-js "4.0.0-beta.5" - tslib "2.4.0" - ws "8.5.0" - ethjs-unit@0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" @@ -4022,14 +3205,6 @@ ethjs-unit@0.1.6: bn.js "4.11.6" number-to-bn "1.7.0" -ethjs-util@0.1.6, ethjs-util@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" - integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== - dependencies: - is-hex-prefixed "1.0.0" - strip-hex-prefix "1.0.0" - evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" @@ -4079,7 +3254,7 @@ fast-diff@^1.2.0: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== -fast-glob@^3.0.3, fast-glob@^3.3.2: +fast-glob@^3.0.3: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -4106,9 +3281,9 @@ fastfile@0.0.20: integrity sha512-r5ZDbgImvVWCP0lA/cGNgQcZqR+aYdFx3u+CtJqUE510pBUVGMn4ulL/iRTI4tACTYsNJ736uzFxEBXesPAktA== fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== dependencies: reusify "^1.0.4" @@ -4153,14 +3328,6 @@ filelist@^1.0.4: dependencies: minimatch "^5.0.1" -fill-keys@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/fill-keys/-/fill-keys-1.0.2.tgz#9a8fa36f4e8ad634e3bf6b4f3c8882551452eb20" - integrity sha512-tcgI872xXjwFF4xgQmLxi76GnwJG3g/3isB1l4/G5Z4zrbddGpBjqZCO9oEAcB5wX0Hj/5iQB3toxfO7in1hHA== - dependencies: - is-object "~1.0.1" - merge-descriptors "~1.0.0" - fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -4176,13 +3343,6 @@ find-up@5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== - dependencies: - locate-path "^2.0.0" - find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" @@ -4208,16 +3368,11 @@ fnv-plus@^1.3.1: resolved "https://registry.yarnpkg.com/fnv-plus/-/fnv-plus-1.3.1.tgz#c34cb4572565434acb08ba257e4044ce2b006d67" integrity sha512-Gz1EvfOneuFfk4yG458dJ3TLJ7gV19q3OM/vVvvHf7eT02Hm1DleB4edsia6ahbKgAYxO9gvyQ1ioWZR+a00Yw== -follow-redirects@^1.12.1, follow-redirects@^1.15.4: +follow-redirects@^1.14.0: version "1.15.5" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== -follow-redirects@^1.14.0: - version "1.15.3" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" - integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== - for-each@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" @@ -4225,17 +3380,9 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" -foreground-child@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" - integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^4.0.1" - "forge-std@https://github.com/foundry-rs/forge-std": - version "1.7.1" - resolved "https://github.com/foundry-rs/forge-std#267acd30a625086b3f16e1a28cfe0c5097fa46b8" + version "1.7.6" + resolved "https://github.com/foundry-rs/forge-std#b6a506db2262cad5ff982a87789ee6d1558ec861" form-data@^4.0.0: version "4.0.0" @@ -4246,32 +3393,6 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -fp-ts@1.19.3: - version "1.19.3" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" - integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== - -fp-ts@^1.0.0: - version "1.19.5" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" - integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs-extra@^0.30.0: - version "0.30.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" - integrity sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - fs-extra@^10.0.0: version "10.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" @@ -4281,15 +3402,6 @@ fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^11.1.1, fs-extra@^11.2.0: - version "11.2.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" - integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - fs-extra@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" @@ -4348,7 +3460,7 @@ get-func-name@^2.0.1, get-func-name@^2.0.2: resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: +get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== @@ -4358,6 +3470,17 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@ has-symbols "^1.0.3" hasown "^2.0.0" +get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" @@ -4395,28 +3518,6 @@ glob@7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@8.1.0, glob@^8.0.3: - version "8.1.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" - integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -glob@^10.3.10: - version "10.3.10" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" - integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== - dependencies: - foreground-child "^3.1.0" - jackspeak "^2.3.5" - minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry "^1.10.1" - glob@^5.0.15: version "5.0.15" resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" @@ -4440,6 +3541,17 @@ glob@^7.0.0, glob@^7.1.3, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^8.0.3: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + global-modules@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" @@ -4482,7 +3594,7 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9: version "4.2.11" 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== @@ -4505,9 +3617,9 @@ hardhat-deploy-ethers@^0.3.0-beta.11: integrity sha512-PdWVcKB9coqWV1L7JTpfXRCI91Cgwsm7KLmBcwZ8f0COSm1xtABHZTyz3fvF6p42cTnz1VM0QnfDvMFlIRkSNw== hardhat-deploy@^0.11.23: - version "0.11.43" - resolved "https://registry.yarnpkg.com/hardhat-deploy/-/hardhat-deploy-0.11.43.tgz#b22ff15b3ea201b72ba0f17f4b2e182cc950e73e" - integrity sha512-D760CjDtinwjOCpKOvdyRtIJYLQIYXmhfgkFe+AkxlYM9bPZ/T4tZ/xIB2tR89ZT+z0hF1YuZFBXIL3/G/9T5g== + version "0.11.45" + resolved "https://registry.yarnpkg.com/hardhat-deploy/-/hardhat-deploy-0.11.45.tgz#bed86118175a38a03bb58aba2ce1ed5e80a20bc8" + integrity sha512-aC8UNaq3JcORnEUIwV945iJuvBwi65tjHVDU3v6mOcqik7WAzHVCJ7cwmkkipsHrWysrB5YvGF1q9S1vIph83w== dependencies: "@ethersproject/abi" "^5.7.0" "@ethersproject/abstract-signer" "^5.7.0" @@ -4534,62 +3646,6 @@ hardhat-deploy@^0.11.23: qs "^6.9.4" zksync-web3 "^0.14.3" -hardhat@^2.19.4, hardhat@^2.20.1: - version "2.20.1" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.20.1.tgz#3ad8f2b003a96c9ce80a55fec3575580ff2ddcd4" - integrity sha512-q75xDQiQtCZcTMBwjTovrXEU5ECr49baxr4/OBkIu/ULTPzlB20yk1dRWNmD2IFbAeAeXggaWvQAdpiScaHtPw== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@metamask/eth-sig-util" "^4.0.0" - "@nomicfoundation/ethereumjs-block" "5.0.4" - "@nomicfoundation/ethereumjs-blockchain" "7.0.4" - "@nomicfoundation/ethereumjs-common" "4.0.4" - "@nomicfoundation/ethereumjs-evm" "2.0.4" - "@nomicfoundation/ethereumjs-rlp" "5.0.4" - "@nomicfoundation/ethereumjs-statemanager" "2.0.4" - "@nomicfoundation/ethereumjs-trie" "6.0.4" - "@nomicfoundation/ethereumjs-tx" "5.0.4" - "@nomicfoundation/ethereumjs-util" "9.0.4" - "@nomicfoundation/ethereumjs-verkle" "0.0.2" - "@nomicfoundation/ethereumjs-vm" "7.0.4" - "@nomicfoundation/solidity-analyzer" "^0.1.0" - "@sentry/node" "^5.18.1" - "@types/bn.js" "^5.1.0" - "@types/lru-cache" "^5.1.0" - adm-zip "^0.4.16" - aggregate-error "^3.0.0" - ansi-escapes "^4.3.0" - boxen "^5.1.2" - chalk "^2.4.2" - chokidar "^3.4.0" - ci-info "^2.0.0" - debug "^4.1.1" - enquirer "^2.3.0" - env-paths "^2.2.0" - ethereum-cryptography "^1.0.3" - ethereumjs-abi "^0.6.8" - find-up "^2.1.0" - fp-ts "1.19.3" - fs-extra "^7.0.1" - glob "7.2.0" - immutable "^4.0.0-rc.12" - io-ts "1.10.4" - keccak "^3.0.2" - lodash "^4.17.11" - mnemonist "^0.38.0" - mocha "^10.0.0" - p-map "^4.0.0" - raw-body "^2.4.1" - resolve "1.17.0" - semver "^6.3.0" - solc "0.7.3" - source-map-support "^0.5.13" - stacktrace-parser "^0.1.10" - tsort "0.0.1" - undici "^5.14.0" - uuid "^8.3.2" - ws "^7.4.6" - has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" @@ -4612,6 +3668,13 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.2.2" +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + has-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" @@ -4682,37 +3745,11 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - iconv-lite@0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" @@ -4720,26 +3757,16 @@ iconv-lite@0.6.3: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - ignore@^5.1.1, ignore@^5.2.4: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== immediate@~3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== -immutable@^4.0.0-rc.12: - version "4.3.5" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.5.tgz#f8b436e66d59f99760dc577f5c99a4fd2a5cc5a0" - integrity sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw== - import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -4766,11 +3793,6 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -4779,7 +3801,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -4794,13 +3816,6 @@ interpret@^1.0.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== -io-ts@1.10.4: - version "1.10.4" - resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" - integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== - dependencies: - fp-ts "^1.0.0" - is-arguments@^1.0.4: version "1.1.1" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" @@ -4872,11 +3887,6 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-object@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" - integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== - is-plain-obj@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" @@ -4899,16 +3909,6 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -4967,15 +3967,6 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jackspeak@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" - integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - jake@^10.8.5: version "10.8.7" resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" @@ -5344,11 +4335,6 @@ jest@^29.5.0: import-local "^3.0.2" jest-cli "^29.7.0" -js-sdsl@^4.1.4: - version "4.4.2" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.2.tgz#2e3c031b1f47d3aca8b775532e3ebb0818e7f847" - integrity sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w== - js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" @@ -5404,13 +4390,6 @@ json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw== - optionalDependencies: - graceful-fs "^4.1.6" - jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -5427,11 +4406,6 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsonparse@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== - jsonpath@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/jsonpath/-/jsonpath-1.1.1.tgz#0ca1ed8fb65bb3309248cc9d5466d12d5b0b9901" @@ -5446,12 +4420,7 @@ jsonschema@^1.2.4: resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== -just-extend@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-6.2.0.tgz#b816abfb3d67ee860482e7401564672558163947" - integrity sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw== - -keccak@^3.0.0, keccak@^3.0.2: +keccak@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.4.tgz#edc09b89e633c0549da444432ecf062ffadee86d" integrity sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q== @@ -5465,13 +4434,6 @@ kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw== - optionalDependencies: - graceful-fs "^4.1.9" - kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" @@ -5529,14 +4491,6 @@ localforage@^1.10.0: dependencies: lie "3.1.1" -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -5551,21 +4505,11 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== - lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== -lodash.get@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== - lodash.memoize@4.x: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -5576,7 +4520,7 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== -lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.21: +lodash@^4.17.15, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -5601,11 +4545,6 @@ loupe@^2.3.6: dependencies: get-func-name "^2.0.1" -lru-cache@^10.0.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" - integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -5620,16 +4559,6 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -"lru-cache@^9.1.1 || ^10.0.0": - version "10.0.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" - integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== - -lru_map@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" - integrity sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ== - make-dir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" @@ -5670,16 +4599,6 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" -memorystream@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== - -merge-descriptors@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" - integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== - merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -5751,48 +4670,19 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.1, minimatch@^9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - minimist@^1.2.5, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": - version "7.0.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" - integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== - -mkdirp-classic@^0.5.2: - version "0.5.3" - resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" - integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== - -mkdirp@0.5.x, mkdirp@^0.5.1: +mkdirp@0.5.x: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== dependencies: minimist "^1.2.6" -mkdirp@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" - integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== - -mnemonist@^0.38.0: - version "0.38.5" - resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" - integrity sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg== - dependencies: - obliterator "^2.0.0" - -mocha@10.2.0, mocha@^10.2.0: +mocha@^10.2.0: version "10.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== @@ -5819,43 +4709,12 @@ mocha@10.2.0, mocha@^10.2.0: yargs-parser "20.2.4" yargs-unparser "2.0.0" -mocha@^10.0.0: - version "10.3.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.3.0.tgz#0e185c49e6dccf582035c05fa91084a4ff6e3fe9" - integrity sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg== - dependencies: - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "8.1.0" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -module-not-found-error@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/module-not-found-error/-/module-not-found-error-1.0.1.tgz#cf8b4ff4f29640674d6cdd02b0e3bc523c2bbdc0" - integrity sha512-pEk4ECWQXV6z2zjhRZUongnLJNUeGQJ3w6OQ5ctGwD+i5o93qjRQUk2Rt6VdNeu3sEP0AB4LcfvdebpxBRVr4g== - 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.3, ms@^2.1.1: +ms@2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -5869,11 +4728,6 @@ murmur-128@^0.2.1: fmix "^0.1.0" imul "^1.0.0" -nan@^2.17.0, nan@^2.18.0: - version "2.18.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.18.0.tgz#26a6faae7ffbeb293a39660e88a76b82e30b7554" - integrity sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w== - nanoassert@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/nanoassert/-/nanoassert-2.0.0.tgz#a05f86de6c7a51618038a620f88878ed1e490c09" @@ -5894,17 +4748,6 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -nise@^5.1.5: - version "5.1.9" - resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.9.tgz#0cb73b5e4499d738231a473cd89bd8afbb618139" - integrity sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww== - dependencies: - "@sinonjs/commons" "^3.0.0" - "@sinonjs/fake-timers" "^11.2.2" - "@sinonjs/text-encoding" "^0.7.2" - just-extend "^6.2.0" - path-to-regexp "^6.2.1" - node-addon-api@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" @@ -5934,7 +4777,12 @@ node-forge@^1.3.1: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== -node-gyp-build@^4.2.0, node-gyp-build@^4.2.2: +node-gyp-build@^4.2.0: + version "4.8.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.0.tgz#3fee9c1731df4581a3f9ead74664369ff00d26dd" + integrity sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og== + +node-gyp-build@^4.2.2: version "4.6.1" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.1.tgz#24b6d075e5e391b8d5539d98c7fc5c210cac8a3e" integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ== @@ -5954,11 +4802,6 @@ nofilter@^1.0.4: resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-1.0.4.tgz#78d6f4b6a613e7ced8b015cec534625f7667006e" integrity sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA== -nofilter@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.1.0.tgz#c757ba68801d41ff930ba2ec55bab52ca184aa66" - integrity sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g== - nopt@3.x: version "3.0.6" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" @@ -5986,17 +4829,12 @@ number-to-bn@1.7.0: bn.js "4.11.6" strip-hex-prefix "1.0.0" -object-inspect@^1.9.0: +object-inspect@^1.13.1: version "1.13.1" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== -obliterator@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" - integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== - -once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@1.x, once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -6022,18 +4860,6 @@ optionator@^0.8.1: type-check "~0.3.2" word-wrap "~1.2.3" -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -6048,13 +4874,6 @@ p-limit@^3.0.2, p-limit@^3.1.0: dependencies: yocto-queue "^0.1.0" -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== - dependencies: - p-limit "^1.1.0" - p-locate@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" @@ -6069,18 +4888,6 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== - p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -6108,16 +4915,6 @@ parse-json@^5.2.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" -path-browserify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" - integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== - path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -6133,24 +4930,11 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.6, path-parse@^1.0.7: +path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.10.1: - version "1.10.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" - integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== - dependencies: - lru-cache "^9.1.1 || ^10.0.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - -path-to-regexp@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz#d54934d6798eb9e5ef14e7af7962c945906918e5" - integrity sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== - path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -6242,11 +5026,6 @@ pretty-format@^29.0.0, pretty-format@^29.7.0: ansi-styles "^5.0.0" react-is "^18.0.0" -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - prompts@^2.0.1: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" @@ -6255,50 +5034,11 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" -proper-lockfile@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz#c8b9de2af6b2f1601067f98e01ac66baa223141f" - integrity sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA== - dependencies: - graceful-fs "^4.2.4" - retry "^0.12.0" - signal-exit "^3.0.2" - -proxy-from-env@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== - -proxyquire@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/proxyquire/-/proxyquire-2.1.3.tgz#2049a7eefa10a9a953346a18e54aab2b4268df39" - integrity sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg== - dependencies: - fill-keys "^1.0.2" - module-not-found-error "^1.0.1" - resolve "^1.11.1" - psl@^1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== -pump@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" - integrity sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -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== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - punycode@^2.1.0: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" @@ -6310,11 +5050,11 @@ pure-rand@^6.0.0: integrity sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA== qs@^6.9.4: - version "6.11.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" - integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== + version "6.12.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.12.0.tgz#edd40c3b823995946a8a0b1f208669c7a200db77" + integrity sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg== dependencies: - side-channel "^1.0.4" + side-channel "^1.0.6" queue-microtask@^1.2.2: version "1.2.3" @@ -6348,35 +5088,12 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -raw-body@^2.4.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" - integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - react-is@^18.0.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== -readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0: +readable-stream@^3.6.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -6385,16 +5102,6 @@ readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@~1.0.26-4: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -6464,7 +5171,7 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== -require-from-string@^2.0.0, require-from-string@^2.0.2: +require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== @@ -6496,14 +5203,7 @@ resolve@1.1.x: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg== -resolve@1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - -resolve@^1.1.6, resolve@^1.11.1, resolve@^1.14.2, resolve@^1.20.0: +resolve@^1.1.6, resolve@^1.14.2, resolve@^1.20.0: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -6512,23 +5212,11 @@ resolve@^1.1.6, resolve@^1.11.1, resolve@^1.14.2, resolve@^1.20.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== - reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@^2.2.8: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - rimraf@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -6544,7 +5232,7 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -rlp@^2.2.3, rlp@^2.2.4: +rlp@^2.2.4: version "2.2.7" resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf" integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ== @@ -6558,29 +5246,12 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rust-verkle-wasm@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/rust-verkle-wasm/-/rust-verkle-wasm-0.0.1.tgz#fd8396a7060d8ee8ea10da50ab6e862948095a74" - integrity sha512-BN6fiTsxcd2dCECz/cHtGTt9cdLJR925nh7iAuRcj8ymKw7OOaPmCneQZ7JePOJ/ia27TjEL91VdOi88Yf+mcA== - -rustbn-wasm@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/rustbn-wasm/-/rustbn-wasm-0.2.0.tgz#0407521fb55ae69eeb4968d01885d63efd1c4ff9" - integrity sha512-FThvYFNTqrEKGqXuseeg0zR7yROh/6U1617mCHF68OVqrN1tNKRN7Tdwy4WayPVsCmmK+eMxtIZX1qL6JxTkMg== - dependencies: - "@scure/base" "^1.1.1" - safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -6619,30 +5290,25 @@ secp256k1@^4.0.1: node-addon-api "^2.0.0" node-gyp-build "^4.2.0" -semver@^5.5.0: - version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.4, semver@^7.3.8, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -semver@^7.5.1: +semver@^7.3.4, semver@^7.5.2: version "7.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== dependencies: lru-cache "^6.0.0" +semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -6660,16 +5326,23 @@ set-function-length@^1.1.1: gopd "^1.0.1" has-property-descriptors "^1.0.0" +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.11" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" @@ -6699,42 +5372,21 @@ shelljs@^0.8.3: interpret "^1.0.0" rechoir "^0.6.2" -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== +side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" -signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: +signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -signal-exit@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - -sinon-chai@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-3.7.0.tgz#cfb7dec1c50990ed18c153f1840721cf13139783" - integrity sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g== - -sinon@^17.0.1: - version "17.0.1" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-17.0.1.tgz#26b8ef719261bf8df43f925924cccc96748e407a" - integrity sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g== - dependencies: - "@sinonjs/commons" "^3.0.0" - "@sinonjs/fake-timers" "^11.2.2" - "@sinonjs/samsam" "^8.0.0" - diff "^5.1.0" - nise "^5.1.5" - supports-color "^7.2.0" - sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -6791,21 +5443,6 @@ solady@^0.0.123: resolved "https://registry.yarnpkg.com/solady/-/solady-0.0.123.tgz#7ef95767c1570e3efde7550da2a8b439b2f413d2" integrity sha512-F/B8OMCplGsS4FrdPrnEG0xdg8HKede5PwC+Rum8soj/LWxfKckA0p+Uwnlbgey2iI82IHvmSOCNhsdbA+lUrw== -solc@0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" - integrity sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA== - dependencies: - command-exists "^1.2.8" - commander "3.0.2" - follow-redirects "^1.12.1" - fs-extra "^0.30.0" - js-sha3 "0.8.0" - memorystream "^0.3.1" - require-from-string "^2.0.0" - semver "^5.5.0" - tmp "0.0.33" - solhint@^3.6.1: version "3.6.2" resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.6.2.tgz#2b2acbec8fdc37b2c68206a71ba89c7f519943fe" @@ -6837,15 +5474,14 @@ solidity-comments-extractor@^0.0.7: integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== solidity-coverage@^0.8.2: - version "0.8.5" - resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.5.tgz#64071c3a0c06a0cecf9a7776c35f49edc961e875" - integrity sha512-6C6N6OV2O8FQA0FWA95FdzVH+L16HU94iFgg5wAFZ29UpLFkgNI/DRR2HotG1bC0F4gAc/OMs2BJI44Q/DYlKQ== + version "0.8.11" + resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.11.tgz#c95798f2c3e885c49dcfc9c43ee570d112214785" + integrity sha512-yy0Yk+olovBbXn0Me8BWULmmv7A69ZKkP5aTOJGOO8u61Tu2zS989erfjtFlUjDnfWtxRAVkd8BsQD704yLWHw== dependencies: "@ethersproject/abi" "^5.0.9" - "@solidity-parser/parser" "^0.16.0" + "@solidity-parser/parser" "^0.18.0" chalk "^2.4.2" death "^1.1.0" - detect-port "^1.3.0" difflib "^0.2.4" fs-extra "^8.1.0" ghost-testrpc "^0.0.2" @@ -6853,7 +5489,7 @@ solidity-coverage@^0.8.2: globby "^10.0.1" jsonschema "^1.2.4" lodash "^4.17.15" - mocha "10.2.0" + mocha "^10.2.0" node-emoji "^1.10.0" pify "^4.0.1" recursive-readdir "^2.2.2" @@ -6870,7 +5506,7 @@ source-map-support@0.5.13: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@^0.5.13, source-map-support@^0.5.19: +source-map-support@^0.5.19: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -6890,27 +5526,11 @@ source-map@~0.2.0: dependencies: amdefine ">=0.0.4" -split-ca@^1.0.0, split-ca@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/split-ca/-/split-ca-1.0.1.tgz#6c83aff3692fa61256e0cd197e05e9de157691a6" - integrity sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ== - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== -ssh2@^1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.15.0.tgz#2f998455036a7f89e0df5847efb5421748d9871b" - integrity sha512-C0PHgX4h6lBxYx7hcXwu3QWdh4tg6tZZsTfXcdvc5caW/EMxaB4H9dWsl7qk+F7LAW762hp8VbXOX7x4xUYvEw== - dependencies: - asn1 "^0.2.6" - bcrypt-pbkdf "^1.0.2" - optionalDependencies: - cpu-features "~0.0.9" - nan "^2.18.0" - stack-utils@^2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" @@ -6918,13 +5538,6 @@ stack-utils@^2.0.3: dependencies: escape-string-regexp "^2.0.0" -stacktrace-parser@^0.1.10: - version "0.1.10" - resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" - integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== - dependencies: - type-fest "^0.7.1" - static-eval@2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-2.0.2.tgz#2d1759306b1befa688938454c546b7871f806a42" @@ -6932,11 +5545,6 @@ static-eval@2.0.2: dependencies: escodegen "^1.8.1" -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - string-length@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" @@ -6945,7 +5553,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -6954,15 +5562,6 @@ string-length@^4.0.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -6970,32 +5569,13 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - strip-bom@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" @@ -7039,7 +5619,7 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.1.0, supports-color@^7.2.0: +supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -7062,50 +5642,6 @@ table@^6.8.0, table@^6.8.1: string-width "^4.2.3" strip-ansi "^6.0.1" -tar-fs@~1.16.3: - version "1.16.3" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.3.tgz#966a628841da2c4010406a82167cbd5e0c72d509" - integrity sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw== - dependencies: - chownr "^1.0.1" - mkdirp "^0.5.1" - pump "^1.0.0" - tar-stream "^1.1.2" - -tar-fs@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.1.tgz#e44086c1c60d31a4f0cf893b1c4e155dabfae9e2" - integrity sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA== - dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.0.0" - -tar-stream@^1.1.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" - integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== - dependencies: - bl "^1.0.0" - buffer-alloc "^1.2.0" - end-of-stream "^1.0.0" - fs-constants "^1.0.0" - readable-stream "^2.3.0" - to-buffer "^1.1.1" - xtend "^4.0.0" - -tar-stream@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" @@ -7120,11 +5656,6 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== -"through@>=2.2.7 <3": - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - tmp-promise@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7" @@ -7132,13 +5663,6 @@ tmp-promise@^3.0.3: dependencies: tmp "^0.2.0" -tmp@0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - tmp@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" @@ -7151,11 +5675,6 @@ tmpl@1.0.5: resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== -to-buffer@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" - integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== - 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" @@ -7168,11 +5687,6 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -7197,44 +5711,11 @@ ts-jest@^29.1.1: semver "^7.5.3" yargs-parser "^21.0.1" -ts-morph@^21.0.1: - version "21.0.1" - resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-21.0.1.tgz#712302a0f6e9dbf1aa8d9cf33a4386c4b18c2006" - integrity sha512-dbDtVdEAncKctzrVZ+Nr7kHpHkv+0JDJb2MjjpBaj8bFeCkePU9rHfMklmhuLFnpeq/EJZk2IhStY6NzqgjOkg== - dependencies: - "@ts-morph/common" "~0.22.0" - code-block-writer "^12.0.0" - tslib@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== -tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tsort@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" - integrity sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw== - -tweetnacl-util@^0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" - integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== - -tweetnacl@^0.14.3: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== - -tweetnacl@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -7247,26 +5728,11 @@ type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -type-fest@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" - integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== - typescript@^4.3.5, typescript@^4.5.4, typescript@^4.8.3: version "4.9.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" @@ -7287,13 +5753,6 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== -undici@^5.14.0: - version "5.28.3" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.3.tgz#a731e0eff2c3fcfd41c1169a869062be222d1e5b" - integrity sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA== - dependencies: - "@fastify/busboy" "^2.0.0" - 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" @@ -7327,11 +5786,6 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== -unpipe@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - update-browserslist-db@^1.0.13: version "1.0.13" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" @@ -7352,7 +5806,7 @@ utf8@3.0.0, utf8@^3.0.0: resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== -util-deprecate@^1.0.1, util-deprecate@~1.0.1: +util-deprecate@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== @@ -7414,9 +5868,9 @@ web-worker@^1.2.0: integrity sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA== web3-utils@^1.3.6: - version "1.10.3" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.3.tgz#f1db99c82549c7d9f8348f04ffe4e0188b449714" - integrity sha512-OqcUrEE16fDBbGoQtZXWdavsPzbGIDc5v3VrRTZ0XrIpefC/viZ1ZU9bGEemazyS0catk/3rkOOxpzTfY+XsyQ== + version "1.10.4" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.4.tgz#0daee7d6841641655d8b3726baf33b08eda1cbec" + integrity sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A== dependencies: "@ethereumjs/util" "^8.1.0" bn.js "^5.2.1" @@ -7465,13 +5919,6 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== - dependencies: - string-width "^4.0.0" - word-wrap@~1.2.3: version "1.2.5" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" @@ -7487,7 +5934,7 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -7496,15 +5943,6 @@ workerpool@6.2.1: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -7528,16 +5966,6 @@ ws@8.5.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== -ws@^7.4.6: - version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== - -xtend@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" @@ -7609,11 +6037,6 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -zksync-ethers@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-6.3.0.tgz#604c57250974ccad121510a2c84c1dd8b990722f" - integrity sha512-ApQIJSFevxFNVQTO1MxkmXxmx9N0qZHNvMzjFvu5v40QPFGkpUt09pY/WHy3b5BlsXzybQ3q2YnHaz/c/TgilA== - zksync-web3@^0.14.3: version "0.14.4" resolved "https://registry.yarnpkg.com/zksync-web3/-/zksync-web3-0.14.4.tgz#0b70a7e1a9d45cc57c0971736079185746d46b1f" From 355c9a265b27c55265364cc04b771a7e6069c5b4 Mon Sep 17 00:00:00 2001 From: wshino Date: Thu, 14 Mar 2024 02:41:16 +0900 Subject: [PATCH 02/42] Update dev-setup.ts that generates Groth16Verifier.sol. --- packages/circuits/scripts/dev-setup.ts | 45 ++++---------------------- 1 file changed, 6 insertions(+), 39 deletions(-) diff --git a/packages/circuits/scripts/dev-setup.ts b/packages/circuits/scripts/dev-setup.ts index ee9e68f5..e8466c31 100644 --- a/packages/circuits/scripts/dev-setup.ts +++ b/packages/circuits/scripts/dev-setup.ts @@ -140,47 +140,14 @@ async function exec() { await downloadPhase1(phase1Path); log("✓ Phase 1:", phase1Path); - const accountCreationR1csPath = path.join(buildDir, "account_creation/account_creation.r1cs"); - if (!fs.existsSync(accountCreationR1csPath)) { - throw new Error(`${accountCreationR1csPath} does not exist.`); + const emailAuthR1csPath = path.join(buildDir, "email_auth.r1cs"); + if (!fs.existsSync(emailAuthR1csPath)) { + throw new Error(`${emailAuthR1csPath} does not exist.`); } - await generateKeys(phase1Path, accountCreationR1csPath, path.join(buildDir, "account_creation.zkey"), path.join(buildDir, "account_creation.vkey"), path.join(buildDir, "AccountCreationVerifier.sol")); - log("✓ Keys for account creation circuit generated"); - - // const accountInitR1csPath = path.join(buildDir, "account_init/account_init.r1cs"); - // if (!fs.existsSync(accountInitR1csPath)) { - // throw new Error(`${accountInitR1csPath} does not exist.`); - // } - // await generateKeys(phase1Path, accountInitR1csPath, path.join(buildDir, "account_init.zkey"), path.join(buildDir, "account_init.vkey"), path.join(buildDir, "AccountInitVerifier.sol")); - // log("✓ Keys for account init circuit generated"); - - // const accountTransportR1csPath = path.join(buildDir, "account_transport/account_transport.r1cs"); - // if (!fs.existsSync(accountTransportR1csPath)) { - // throw new Error(`${accountTransportR1csPath} does not exist.`); - // } - // await generateKeys(phase1Path, accountTransportR1csPath, path.join(buildDir, "account_transport.zkey"), path.join(buildDir, "account_transport.vkey"), path.join(buildDir, "AccountTransportVerifier.sol")); - // log("✓ Keys for account transport circuit generated"); - - const claimR1csPath = path.join(buildDir, "claim/claim.r1cs"); - if (!fs.existsSync(claimR1csPath)) { - throw new Error(`${claimR1csPath} does not exist.`); - } - await generateKeys(phase1Path, claimR1csPath, path.join(buildDir, "claim.zkey"), path.join(buildDir, "claim.vkey"), path.join(buildDir, "ClaimVerifier.sol")); - log("✓ Keys for claim circuit generated"); - - const emailSenderR1csPath = path.join(buildDir, "email_sender/email_sender.r1cs"); - if (!fs.existsSync(emailSenderR1csPath)) { - throw new Error(`${emailSenderR1csPath} does not exist.`); - } - await generateKeys(phase1Path, emailSenderR1csPath, path.join(buildDir, "email_sender.zkey"), path.join(buildDir, "email_sender.vkey"), path.join(buildDir, "EmailSenderVerifier.sol")); - log("✓ Keys for email sender 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"); - const announcementR1csPath = path.join(buildDir, "announcement/announcement.r1cs"); - if (!fs.existsSync(announcementR1csPath)) { - throw new Error(`${announcementR1csPath} does not exist.`); - } - await generateKeys(phase1Path, announcementR1csPath, path.join(buildDir, "announcement.zkey"), path.join(buildDir, "announcement.vkey"), path.join(buildDir, "AnnouncementVerifier.sol")); - log("✓ Keys for announcement circuit generated"); + } From 814ac9cf622ba330ece847282416c1952ae43f6c Mon Sep 17 00:00:00 2001 From: wshino Date: Thu, 14 Mar 2024 02:41:51 +0900 Subject: [PATCH 03/42] Implement verifyEmailProof function. --- .../contracts/src/utils/Groth16Verifier.sol | 401 ++++++++++++++++++ packages/contracts/src/utils/Verifier.sol | 98 +++++ .../contracts/test/mocks/TestDKIMRegistry.sol | 11 + 3 files changed, 510 insertions(+) create mode 100644 packages/contracts/src/utils/Groth16Verifier.sol create mode 100644 packages/contracts/src/utils/Verifier.sol create mode 100644 packages/contracts/test/mocks/TestDKIMRegistry.sol diff --git a/packages/contracts/src/utils/Groth16Verifier.sol b/packages/contracts/src/utils/Groth16Verifier.sol new file mode 100644 index 00000000..7834aaa5 --- /dev/null +++ b/packages/contracts/src/utils/Groth16Verifier.sol @@ -0,0 +1,401 @@ +// SPDX-License-Identifier: GPL-3.0 +/* + Copyright 2021 0KIMS association. + + This file is generated with [snarkJS](https://github.com/iden3/snarkjs). + + snarkJS is a free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + snarkJS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with snarkJS. If not, see . +*/ + +pragma solidity >=0.7.0 <0.9.0; + +contract Groth16Verifier { + // Scalar field size + uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617; + // Base field size + uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; + + // Verification Key data + uint256 constant alphax = 20491192805390485299153009773594534940189261866228447918068658471970481763042; + uint256 constant alphay = 9383485363053290200918347156157836566562967994039712273449902621266178545958; + uint256 constant betax1 = 4252822878758300859123897981450591353533073413197771768651442665752259397132; + uint256 constant betax2 = 6375614351688725206403948262868962793625744043794305715222011528459656738731; + uint256 constant betay1 = 21847035105528745403288232691147584728191162732299865338377159692350059136679; + uint256 constant betay2 = 10505242626370262277552901082094356697409835680220590971873171140371331206856; + uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634; + uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; + uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; + uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930; + uint256 constant deltax1 = 10954366828219920598275631511874109139704726399812948670801940368943621648319; + uint256 constant deltax2 = 21324907562351316234232877683468151501516381985392872741645251279204064702931; + uint256 constant deltay1 = 18482258673210683573944019122601559566291977892508024479883530881997647434509; + uint256 constant deltay2 = 7722038556480149325085286096508221352261199536637674464951808613229560436306; + + + uint256 constant IC0x = 16574539456559230992114437405247020869688093066008885296935800431598549754271; + uint256 constant IC0y = 6582170259246930443472445853193936509612913397968208942995206335313256772669; + + uint256 constant IC1x = 4808179402447708287615521894566707949385656351330115478568410932828626133498; + uint256 constant IC1y = 11192780342767924659813011397631422217139241141887946338221685389313294137055; + + uint256 constant IC2x = 18712536455113401242166725599926018227501537410696163371186150287407884159274; + uint256 constant IC2y = 8226363004699024636907935712886376534070525223104886495035434945963431550677; + + uint256 constant IC3x = 5525728767826740479533632158517879343874633641133067193231828149796323926074; + uint256 constant IC3y = 20216889476420837287462963482510441738183094399866480033686966677531230112199; + + uint256 constant IC4x = 19009979743068783710183513981562006201043554087798187683149723640538489369795; + uint256 constant IC4y = 18380837042735451429820313470655035539984045901261307868989520583690420329553; + + uint256 constant IC5x = 11800021613302746315078345266979727253441303523217844358758776404934621284969; + uint256 constant IC5y = 5552627847190879688690884947875949286679127676579489026263183051950936911049; + + uint256 constant IC6x = 20536313306009874074947145053719820749486870997381336862627487580013565559491; + uint256 constant IC6y = 12711313804499722236550904237548158455754474168988617941571547442976063920096; + + uint256 constant IC7x = 4425936472530441395965884686031324525711609773170148186646244452200283229770; + uint256 constant IC7y = 1061595758657853301857389925101009636892064733255307544748906042618704434338; + + uint256 constant IC8x = 10155875897728692253686193239509851911589650992390316926220239966489856356772; + uint256 constant IC8y = 4676487083958629767906177287440562921261522549855724753069050267462738267779; + + uint256 constant IC9x = 18076733756169415004280419895754337255912979161476160233820383214343559136951; + uint256 constant IC9y = 3377508909700546665496110592578574506519316225484513731414363569931925595195; + + uint256 constant IC10x = 11317008030217376109539821911712933985761704961144063824128630759333709243087; + uint256 constant IC10y = 13668899703039526880112748721387422884601240691268823176766576494982141347695; + + uint256 constant IC11x = 11359204960157932631830970637444237245788114829005994332310082943451608645555; + uint256 constant IC11y = 2334190495452324539987241351284112610318709408508174260330115582687913867496; + + uint256 constant IC12x = 2975987120379426805902369720367344369451564971704354145292338140239197186222; + uint256 constant IC12y = 14594242469123473606225997914332954438390194577664627818897197983478341158452; + + uint256 constant IC13x = 4018148902220828220532669764290130744309563793380687826532671172447865135797; + uint256 constant IC13y = 16217931666978126451653431812313879837567251770943153104246176239981507546120; + + uint256 constant IC14x = 15248815070804210837362123734509950517193128740321296376090017977229546434201; + uint256 constant IC14y = 20874402362039288740322295432714768850415440595261420415136594386440000805472; + + uint256 constant IC15x = 184215137103263824927792083653151366961493141115507378570545194414115319597; + uint256 constant IC15y = 7046461909096292801283414654130145780333111987651719245987730429663779545861; + + uint256 constant IC16x = 18080736123918754464230709936262206775388487854254198113766918476151341543386; + uint256 constant IC16y = 446148367845068015717390166805552567927596132164836881761524550251826364135; + + uint256 constant IC17x = 1534340754187140859139685302587180628752162653552366187366374180697869637374; + uint256 constant IC17y = 13731129709809544498945856186890414670098540609958232916278851992053826174420; + + uint256 constant IC18x = 21775370689754268902887177062346511347751941867300716036906435030907493997858; + uint256 constant IC18y = 19301665077349083013097167335348111180470218240773113041527466425622049179892; + + uint256 constant IC19x = 11635940937217102712732048025733746892191325102263618279403588660770142333544; + uint256 constant IC19y = 8576917688887871267170119763304876045314668502343805375889313573514080036228; + + uint256 constant IC20x = 20006996550547604082545176730384098459007628099012850949434822374546339451078; + uint256 constant IC20y = 4597726399930358015865174544234916364474061025590422236723625434924206785636; + + uint256 constant IC21x = 3114468224969205430464146710478841067496946923476998513793771645186102267319; + uint256 constant IC21y = 9742761368401377432169043503063016638695625132157325258951119245133312122816; + + uint256 constant IC22x = 10555368626644151934153186988613070223665152831331536461802480468633324065205; + uint256 constant IC22y = 20624044651064953699623026914245314987310012387502388011971209808272542829304; + + uint256 constant IC23x = 5070128471248818670932373963274320409840160095469390573692364137256773403970; + uint256 constant IC23y = 12110776441003724768993603161572065610467199076615091939124262227064046870129; + + uint256 constant IC24x = 5266755028714022754912427866871744256558467716512468087980728393513375234252; + uint256 constant IC24y = 19316881479947876252903121663642174330739742638830832989972224412643455143650; + + uint256 constant IC25x = 19628930876339427854052779075324970269342889362578340399919157892524940741022; + uint256 constant IC25y = 2088966831699507424008771862026864014133676222322627395317071588352669541963; + + uint256 constant IC26x = 20285762967755833379099368754997171672301375701365680387318890775289094404239; + uint256 constant IC26y = 20993214094593506472331818213515185351280861846089320315513952592305315803407; + + uint256 constant IC27x = 10057583801221855541500288051363216180893138868799874225904852728382088360422; + uint256 constant IC27y = 5386421598799472841467457846905224899181603094154111536494760519350528533278; + + uint256 constant IC28x = 16473463128623172053697682047994279770229908199497842325911299171923014826977; + uint256 constant IC28y = 21288160761716596278540023630063748972307384453836431950624496039826334131669; + + uint256 constant IC29x = 21638131594863716614157629605463585179360468401086649311699156897876753941800; + uint256 constant IC29y = 16427641097716660394929990103203425443660595164319793354629895015304577827072; + + uint256 constant IC30x = 15006616093026265455921487202440896059163943612341058809212643108696803693949; + uint256 constant IC30y = 21639729012202301859145061736309269905820646014674250972917770681197873837674; + + uint256 constant IC31x = 5637017587583037775855444353964065840763219389682518196250998291229767189452; + uint256 constant IC31y = 19708998051076531356994075801477289284024748787022499630790823127153597801746; + + uint256 constant IC32x = 11786412624601698177573137563308552293229122392470949009030209663634360959100; + uint256 constant IC32y = 3525006067419153997466506573185539981981981404726200464981456451320393135138; + + uint256 constant IC33x = 8842915247240519087491681345580464704990637853851632260749029221862964993204; + uint256 constant IC33y = 6912129862210202429284336963804844266574743113814701231899003687391563954678; + + uint256 constant IC34x = 11122508802234453254655719684600485291093997375492900313852970247412543996812; + uint256 constant IC34y = 13743597114991162899240697983131925316352407102889585180432451035712663718087; + + + // 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) { + assembly { + function checkField(v) { + if iszero(lt(v, q)) { + mstore(0, 0) + return(0, 0x20) + } + } + + // G1 function to multiply a G1 value(x,y) to value in an address + function g1_mulAccC(pR, x, y, s) { + let success + let mIn := mload(0x40) + mstore(mIn, x) + mstore(add(mIn, 32), y) + mstore(add(mIn, 64), s) + + success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64) + + if iszero(success) { + mstore(0, 0) + return(0, 0x20) + } + + mstore(add(mIn, 64), mload(pR)) + mstore(add(mIn, 96), mload(add(pR, 32))) + + success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64) + + if iszero(success) { + mstore(0, 0) + return(0, 0x20) + } + } + + function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk { + let _pPairing := add(pMem, pPairing) + let _pVk := add(pMem, pVk) + + mstore(_pVk, IC0x) + mstore(add(_pVk, 32), IC0y) + + // Compute the linear combination vk_x + + g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0))) + + g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32))) + + g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64))) + + g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96))) + + g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128))) + + g1_mulAccC(_pVk, IC6x, IC6y, calldataload(add(pubSignals, 160))) + + g1_mulAccC(_pVk, IC7x, IC7y, calldataload(add(pubSignals, 192))) + + g1_mulAccC(_pVk, IC8x, IC8y, calldataload(add(pubSignals, 224))) + + g1_mulAccC(_pVk, IC9x, IC9y, calldataload(add(pubSignals, 256))) + + g1_mulAccC(_pVk, IC10x, IC10y, calldataload(add(pubSignals, 288))) + + g1_mulAccC(_pVk, IC11x, IC11y, calldataload(add(pubSignals, 320))) + + g1_mulAccC(_pVk, IC12x, IC12y, calldataload(add(pubSignals, 352))) + + g1_mulAccC(_pVk, IC13x, IC13y, calldataload(add(pubSignals, 384))) + + g1_mulAccC(_pVk, IC14x, IC14y, calldataload(add(pubSignals, 416))) + + g1_mulAccC(_pVk, IC15x, IC15y, calldataload(add(pubSignals, 448))) + + g1_mulAccC(_pVk, IC16x, IC16y, calldataload(add(pubSignals, 480))) + + g1_mulAccC(_pVk, IC17x, IC17y, calldataload(add(pubSignals, 512))) + + g1_mulAccC(_pVk, IC18x, IC18y, calldataload(add(pubSignals, 544))) + + g1_mulAccC(_pVk, IC19x, IC19y, calldataload(add(pubSignals, 576))) + + g1_mulAccC(_pVk, IC20x, IC20y, calldataload(add(pubSignals, 608))) + + g1_mulAccC(_pVk, IC21x, IC21y, calldataload(add(pubSignals, 640))) + + 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)) + + // B + mstore(add(_pPairing, 64), calldataload(pB)) + mstore(add(_pPairing, 96), calldataload(add(pB, 32))) + mstore(add(_pPairing, 128), calldataload(add(pB, 64))) + mstore(add(_pPairing, 160), calldataload(add(pB, 96))) + + // alpha1 + mstore(add(_pPairing, 192), alphax) + mstore(add(_pPairing, 224), alphay) + + // beta2 + mstore(add(_pPairing, 256), betax1) + mstore(add(_pPairing, 288), betax2) + mstore(add(_pPairing, 320), betay1) + mstore(add(_pPairing, 352), betay2) + + // vk_x + mstore(add(_pPairing, 384), mload(add(pMem, pVk))) + mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32)))) + + + // gamma2 + mstore(add(_pPairing, 448), gammax1) + mstore(add(_pPairing, 480), gammax2) + mstore(add(_pPairing, 512), gammay1) + mstore(add(_pPairing, 544), gammay2) + + // C + mstore(add(_pPairing, 576), calldataload(pC)) + mstore(add(_pPairing, 608), calldataload(add(pC, 32))) + + // delta2 + mstore(add(_pPairing, 640), deltax1) + mstore(add(_pPairing, 672), deltax2) + mstore(add(_pPairing, 704), deltay1) + mstore(add(_pPairing, 736), deltay2) + + + let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20) + + isOk := and(success, mload(_pPairing)) + } + + let pMem := mload(0x40) + mstore(0x40, add(pMem, pLastMem)) + + // Validate that all evaluations ∈ F + + checkField(calldataload(add(_pubSignals, 0))) + + checkField(calldataload(add(_pubSignals, 32))) + + checkField(calldataload(add(_pubSignals, 64))) + + checkField(calldataload(add(_pubSignals, 96))) + + checkField(calldataload(add(_pubSignals, 128))) + + checkField(calldataload(add(_pubSignals, 160))) + + checkField(calldataload(add(_pubSignals, 192))) + + checkField(calldataload(add(_pubSignals, 224))) + + checkField(calldataload(add(_pubSignals, 256))) + + checkField(calldataload(add(_pubSignals, 288))) + + checkField(calldataload(add(_pubSignals, 320))) + + checkField(calldataload(add(_pubSignals, 352))) + + checkField(calldataload(add(_pubSignals, 384))) + + checkField(calldataload(add(_pubSignals, 416))) + + checkField(calldataload(add(_pubSignals, 448))) + + checkField(calldataload(add(_pubSignals, 480))) + + checkField(calldataload(add(_pubSignals, 512))) + + checkField(calldataload(add(_pubSignals, 544))) + + checkField(calldataload(add(_pubSignals, 576))) + + checkField(calldataload(add(_pubSignals, 608))) + + checkField(calldataload(add(_pubSignals, 640))) + + 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) + } + } + } diff --git a/packages/contracts/src/utils/Verifier.sol b/packages/contracts/src/utils/Verifier.sol new file mode 100644 index 00000000..876b4573 --- /dev/null +++ b/packages/contracts/src/utils/Verifier.sol @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +import "./Groth16Verifier.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 email to prevent re-run + bytes32 accountSalt; // Salt of the account + bool isCodeExist; // Check if the code is exist + bytes proof; // ZK Proof of Email +} + +contract Verifier { + + mapping(bytes32=>bool) usedNullifiers; + Groth16Verifier 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; + + function verifyEmailProof(EmailProof memory proof) public returns (bool) { + if(isUsedNullifier(proof.emailNullifier)) { + return false; + } + + usedNullifiers[proof.emailNullifier] = true; + + (uint256[2] memory pA, 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; + uint256[] memory stringFields; + stringFields = _packBytes2Fields(bytes(proof.domainName), DOMAIN_BYTES); + for (uint256 i = 0; i < DOMAIN_FIELDS; i++) { + pubSignals[i] = stringFields[i]; + } + pubSignals[DOMAIN_FIELDS] = uint256(proof.publicKeyHash); + pubSignals[DOMAIN_FIELDS + 1] = uint256(proof.emailNullifier); + pubSignals[DOMAIN_FIELDS + 2] = uint256(proof.timestamp); + stringFields = _packBytes2Fields(bytes(proof.maskedSubject), SUBJECT_BYTES); + for (uint256 i = 0; i < SUBJECT_FIELDS; i++) { + pubSignals[DOMAIN_FIELDS + 3 + i] = stringFields[i]; + } + pubSignals[DOMAIN_FIELDS + 3 + SUBJECT_FIELDS] = uint256(proof.accountSalt); + pubSignals[DOMAIN_FIELDS + 3 + SUBJECT_FIELDS + 1] = proof.isCodeExist ? 1 : 0; + + return groth16Verifier.verifyProof(pA, pB, pC, pubSignals); + } + + // Check if the nullifier is used + function isUsedNullifier(bytes32 emailNullifier) public view returns (bool) { + return usedNullifiers[emailNullifier]; + } + + function validateEmailProof(EmailProof memory proof) public pure returns (bool) { + + } + + function _packBytes2Fields(bytes memory _bytes, uint256 _paddedSize) public pure returns (uint256[] memory) { + uint256 remain = _paddedSize % 31; + uint256 numFields = (_paddedSize - remain) / 31; + if (remain > 0) { + numFields += 1; + } + uint256[] memory fields = new uint[](numFields); + uint256 idx = 0; + uint256 byteVal = 0; + for (uint256 i = 0; i < numFields; i++) { + for (uint256 j = 0; j < 31; j++) { + idx = i * 31 + j; + if (idx >= _paddedSize) { + break; + } + if (idx >= _bytes.length) { + byteVal = 0; + } else { + byteVal = uint256(uint8(_bytes[idx])); + } + if (j == 0) { + fields[i] = byteVal; + } else { + fields[i] += (byteVal << (8 * j)); + } + } + } + return fields; + } + +} + diff --git a/packages/contracts/test/mocks/TestDKIMRegistry.sol b/packages/contracts/test/mocks/TestDKIMRegistry.sol new file mode 100644 index 00000000..82afbbe5 --- /dev/null +++ b/packages/contracts/test/mocks/TestDKIMRegistry.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +import "@zk-email/contracts/interfaces/IDKIMRegistry.sol"; + +contract TestDKIMRegistry is IDKIMRegistry { + function isDKIMPublicKeyHashValid(string memory domainName, bytes32 publicKeyHash) external pure returns (bool) { + domainName; + return bytes32(uint256(123)) == publicKeyHash; + } +} From e5a9ca676c5b44652c4461740d745c2835820f1d Mon Sep 17 00:00:00 2001 From: wshino Date: Fri, 15 Mar 2024 18:55:37 +0900 Subject: [PATCH 04/42] [WIP] Add implementations regarding authEmail function till step 7. --- packages/contracts/src/EmailAuth.sol | 142 +++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 packages/contracts/src/EmailAuth.sol diff --git a/packages/contracts/src/EmailAuth.sol b/packages/contracts/src/EmailAuth.sol new file mode 100644 index 00000000..8070a412 --- /dev/null +++ b/packages/contracts/src/EmailAuth.sol @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {EmailProof} from "./utils/Verifier.sol"; +import {ECDSAOwnedDKIMRegistry} from "./utils/ECDSAOwnedDKIMRegistry.sol"; +import {Verifier} from "./utils/Verifier.sol"; +import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; + +struct EmailAuthMsg{ + uint templateId; + bytes[] subjectParams; + uint skipedSubjectPrefix; + EmailProof proof; +} + +contract EmailAuth { + + address owner; + ECDSAOwnedDKIMRegistry dkim; + Verifier verifier; + mapping(uint => string[]) subjectTemplates; + mapping(bytes32 => bytes32) authedHash; + uint lastTimestamp; + + constructor(address _dkim, address _verifier) { + owner = msg.sender; + dkim = ECDSAOwnedDKIMRegistry(_dkim); + verifier = Verifier(_verifier); + } + + function dkimRegistryAddr() public view returns (address) { + return address(dkim); + } + + function verifierAddr() public view returns (address) { + return address(verifier); + } + + function updateVerifier(address _verifierAddr) public { + require(msg.sender == owner, "only owner can update verifier"); + require(_verifierAddr != address(0), "invalid verifier address"); + verifier = Verifier(_verifierAddr); + } + + function updateDKIMRegistry(address _dkimRegistryAddr) public { + require(msg.sender == owner, "only owner can update dkim registry"); + require(_dkimRegistryAddr != address(0), "invalid dkim registry address"); + dkim = ECDSAOwnedDKIMRegistry(_dkimRegistryAddr); + } + + function insertSubjectTemplate(uint _templateId, string[] memory _subjectTemplate) public { + require(msg.sender == owner, "only owner can insert subject template"); + require(_subjectTemplate.length > 0, "subject template is empty"); + require(subjectTemplates[_templateId].length == 0, "template id already exists"); + subjectTemplates[_templateId] = _subjectTemplate; + } + + function updateSubjectTemplate(uint _templateId, string[] memory _subjectTemplate) public { + require(msg.sender == owner, "only owner can update subject template"); + require(_subjectTemplate.length > 0, "subject template is empty"); + require(subjectTemplates[_templateId].length > 0, "template id not exists"); + subjectTemplates[_templateId] = _subjectTemplate; + } + + function deleteSubjectTemplate(uint _templateId) public { + require(msg.sender == owner, "only owner can delete subject template"); + require(subjectTemplates[_templateId].length > 0, "template id not exists"); + delete subjectTemplates[_templateId]; + } + + function computeMsgHash(bytes32 accountSalt, bool isCodeExist, uint templateId, bytes[] memory subjectParams) public pure returns (bytes32) { + return keccak256(abi.encode(accountSalt, isCodeExist, templateId, subjectParams)); + } + + function authEmail(EmailAuthMsg memory emailAuthMsg) public returns (address, bytes32) { + require(msg.sender == owner, "only owner can auth email"); + string[] memory template = subjectTemplates[emailAuthMsg.templateId]; + require(template.length > 0, "template id not exists"); + require( + dkim.isDKIMPublicKeyHashValid( + emailAuthMsg.proof.domainName, + emailAuthMsg.proof.publicKeyHash + ) == true, + "invalid dkim public key hash"); + require(emailAuthMsg.proof.timestamp > 0 && emailAuthMsg.proof.timestamp > lastTimestamp, "invalid timestamp"); + lastTimestamp = emailAuthMsg.proof.timestamp; + + // Construct an expectedSubject from template and the values of emailAuthMsg.subjectParams. + string memory expectedSubject; + uint8 nextParamIndex = 0; + string memory stringParam; + for (uint8 i = 0; i < template.length; i++) { + + if(Strings.equal(template[i], "{string}")) { + string memory param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (string)); + stringParam = param; + // expectedSubject = string(abi.encodePacked(expectedSubject, param)); + } else if(Strings.equal(template[i], "{uint}")) { + uint256 param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (uint256)); + stringParam = Strings.toString(param); + // expectedSubject = string(abi.encodePacked(expectedSubject, Strings.toString(param))); + } else if(Strings.equal(template[i], "{int}")) { + int256 param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (int256)); + stringParam = Strings.toString(param); + // expectedSubject = string(abi.encodePacked(expectedSubject, Strings.toString(param))); + } else if(Strings.equal(template[i], "{decimals}")) { + uint256 param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (uint256)); + stringParam = Strings.toString(param); + // expectedSubject = string(abi.encodePacked(expectedSubject, Strings.toString(param))); + } else if(Strings.equal(template[i], "{decimals}")) { + uint256 param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (uint256)); + stringParam = Strings.toString(param); + // expectedSubject = string(abi.encodePacked(expectedSubject, Strings.toString(param))); + } else if(Strings.equal(template[i], "{ethAddr}")) { + address param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (address)); + stringParam = Strings.toHexString(param); + } else { + continue; + } + + if(i > 0) { + expectedSubject = string(abi.encodePacked(expectedSubject, " ")); + } + expectedSubject = string(abi.encodePacked(expectedSubject, stringParam)); + nextParamIndex++; + } + + + bytes32 msgHash = computeMsgHash( + emailAuthMsg.proof.accountSalt, + emailAuthMsg.proof.isCodeExist, + emailAuthMsg.templateId, + emailAuthMsg.subjectParams + ); + require(authedHash[emailAuthMsg.proof.emailNullifier] == bytes32(0), "email already authed"); + authedHash[emailAuthMsg.proof.emailNullifier] = msgHash; + } +} + From 86a1cdc5d0ab175ea2351f2cd710adb12d804cd6 Mon Sep 17 00:00:00 2001 From: wshino Date: Fri, 15 Mar 2024 19:43:38 +0900 Subject: [PATCH 05/42] Add isValidSignature function. --- packages/contracts/src/EmailAuth.sol | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/contracts/src/EmailAuth.sol b/packages/contracts/src/EmailAuth.sol index 8070a412..0377f221 100644 --- a/packages/contracts/src/EmailAuth.sol +++ b/packages/contracts/src/EmailAuth.sol @@ -137,6 +137,25 @@ contract EmailAuth { ); require(authedHash[emailAuthMsg.proof.emailNullifier] == bytes32(0), "email already authed"); authedHash[emailAuthMsg.proof.emailNullifier] = msgHash; + + // TBD + } + + function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4) { + ( + bytes32 emailNullifier, + bytes32 accountSalt, + uint templateId, + bool isCodeExist, + bytes[] memory subjectParams + ) = abi.decode(_signature, (bytes32, bytes32, uint, bool, bytes[])); + + bytes32 msgHash = computeMsgHash(accountSalt, isCodeExist, templateId, subjectParams); + if(authedHash[emailNullifier] == msgHash) { + return 0x1626ba7e; + } else { + return 0xffffffff; + } } } From c835942885d67c491006b6c4a24187618b90077a Mon Sep 17 00:00:00 2001 From: wshino Date: Fri, 15 Mar 2024 21:23:39 +0900 Subject: [PATCH 06/42] Add EmailAccountRecovery. --- .../contracts/src/EmailAccountRecovery.sol | 78 +++++++++++++++++++ packages/contracts/src/EmailAuth.sol | 6 +- 2 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 packages/contracts/src/EmailAccountRecovery.sol diff --git a/packages/contracts/src/EmailAccountRecovery.sol b/packages/contracts/src/EmailAccountRecovery.sol new file mode 100644 index 00000000..569cbee2 --- /dev/null +++ b/packages/contracts/src/EmailAccountRecovery.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "./EmailAuth.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/utils/Create2.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; + +abstract contract EmailAccountRecovery { + + uint8 constant EMAIL_ACCOUNT_RECOVERY_VERSION_ID = 1; + + function verifier() public view virtual returns (address) { + return 0x0000000000000000000000000000000000000000; + } + + function dkim() public view virtual returns (address) { + return 0x0000000000000000000000000000000000000000; + } + + function emailAuthImplementation() public view virtual returns (address) { + return 0x0000000000000000000000000000000000000000; + } + + function acceptanceSubjectTemplates() public view virtual returns (string[][] memory) { + return new string[][](0); + } + + function recoverySubjectTemplates() public view virtual returns (string[][] memory) { + return new string[][](0); + } + + function acceptGuardian(address guardian, uint templateIdx, bytes[] memory subjectParams, bytes32 emailNullifier) public virtual; + function recoverWallet(address guardian, uint templateIdx, bytes[] memory subjectParams, bytes32 emailNullifier) public virtual; + + function handleAcceptance(EmailAuthMsg memory emailAuthMsg, uint templateIdx) external { + address guardian = Create2.computeAddress(emailAuthMsg.proof.accountSalt, bytes32(bytes20(emailAuthImplementation()))); + require(Address.isContract(guardian), "guardian is not deployed"); + uint templateId = uint256(keccak256(abi.encode(EMAIL_ACCOUNT_RECOVERY_VERSION_ID, "ACCEPTANCE", templateIdx))); + require(templateId == emailAuthMsg.templateId, "invalid template id"); + require(emailAuthMsg.proof.isCodeExist == true, "isCodeExist is false"); + + // Deploy proxy + ERC1967Proxy proxy = new ERC1967Proxy(address(emailAuthImplementation()), abi.encode(dkim(), verifier())); + EmailAuth newEmailAuth = EmailAuth(payable(address(proxy))); + EmailAuth guardianEmailAuth = EmailAuth(payable(address(guardian))); + + for (uint i = 0; i < acceptanceSubjectTemplates().length; i++) { + guardianEmailAuth.insertSubjectTemplate(i, acceptanceSubjectTemplates()[i]); + } + + for (uint i = 0; i < recoverySubjectTemplates().length; i++) { + guardianEmailAuth.insertSubjectTemplate(i, acceptanceSubjectTemplates()[i]); + } + + // An assertion to confirm that the authEmail function is executed successfully + // and does not return an error. + guardianEmailAuth.authEmail(emailAuthMsg); + + acceptGuardian(guardian, templateIdx, emailAuthMsg.subjectParams, emailAuthMsg.proof.emailNullifier); + } + + function handleRecovery(EmailAuthMsg memory emailAuthMsg, uint templateIdx) external { + address guardian = Create2.computeAddress(emailAuthMsg.proof.accountSalt, bytes32(bytes20(emailAuthImplementation()))); + require(Address.isContract(guardian), "guardian is not deployed"); + uint templateId = uint256(keccak256(abi.encode(EMAIL_ACCOUNT_RECOVERY_VERSION_ID, "RECOVERY", templateIdx))); + require(templateId == emailAuthMsg.templateId, "invalid template id"); + + EmailAuth guardianEmailAuth = EmailAuth(payable(address(guardian))); + + // An assertion to confirm that the authEmail function is executed successfully + // and does not return an error. + guardianEmailAuth.authEmail(emailAuthMsg); + + recoverWallet(guardian, templateIdx, emailAuthMsg.subjectParams, emailAuthMsg.proof.emailNullifier); + } +} + diff --git a/packages/contracts/src/EmailAuth.sol b/packages/contracts/src/EmailAuth.sol index 0377f221..77ac1fe0 100644 --- a/packages/contracts/src/EmailAuth.sol +++ b/packages/contracts/src/EmailAuth.sol @@ -1,15 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.12; -import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; -import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import {EmailProof} from "./utils/Verifier.sol"; import {ECDSAOwnedDKIMRegistry} from "./utils/ECDSAOwnedDKIMRegistry.sol"; import {Verifier} from "./utils/Verifier.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -struct EmailAuthMsg{ +struct EmailAuthMsg { uint templateId; bytes[] subjectParams; uint skipedSubjectPrefix; From cd9da35abe48ed87366738ad75b77f8425c12bf0 Mon Sep 17 00:00:00 2001 From: wshino Date: Sun, 17 Mar 2024 11:02:43 +0900 Subject: [PATCH 07/42] Move usedNullifiers from Verifier to EmailAuth. --- packages/contracts/src/EmailAuth.sol | 55 ++++++++++++++++------- packages/contracts/src/utils/Verifier.sol | 18 +------- 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/packages/contracts/src/EmailAuth.sol b/packages/contracts/src/EmailAuth.sol index 77ac1fe0..763cfb10 100644 --- a/packages/contracts/src/EmailAuth.sol +++ b/packages/contracts/src/EmailAuth.sol @@ -6,6 +6,7 @@ import {ECDSAOwnedDKIMRegistry} from "./utils/ECDSAOwnedDKIMRegistry.sol"; import {Verifier} from "./utils/Verifier.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; struct EmailAuthMsg { uint templateId; @@ -17,16 +18,19 @@ struct EmailAuthMsg { contract EmailAuth { address owner; + bytes32 accountSalt; ECDSAOwnedDKIMRegistry dkim; Verifier verifier; mapping(uint => string[]) subjectTemplates; mapping(bytes32 => bytes32) authedHash; uint lastTimestamp; + mapping(bytes32=>bool) usedNullifiers; + bool timestampCheckEnabled; - constructor(address _dkim, address _verifier) { + constructor(bytes32 _accountSalt) { owner = msg.sender; - dkim = ECDSAOwnedDKIMRegistry(_dkim); - verifier = Verifier(_verifier); + accountSalt = _accountSalt; + timestampCheckEnabled = true; } function dkimRegistryAddr() public view returns (address) { @@ -69,11 +73,11 @@ contract EmailAuth { delete subjectTemplates[_templateId]; } - function computeMsgHash(bytes32 accountSalt, bool isCodeExist, uint templateId, bytes[] memory subjectParams) public pure returns (bytes32) { - return keccak256(abi.encode(accountSalt, isCodeExist, templateId, subjectParams)); + function computeMsgHash(bytes32 _accountSalt, bool _isCodeExist, uint _templateId, bytes[] memory _subjectParams) public pure returns (bytes32) { + return keccak256(abi.encode(_accountSalt, _isCodeExist, _templateId, _subjectParams)); } - function authEmail(EmailAuthMsg memory emailAuthMsg) public returns (address, bytes32) { + function authEmail(EmailAuthMsg memory emailAuthMsg) public returns (bytes32) { require(msg.sender == owner, "only owner can auth email"); string[] memory template = subjectTemplates[emailAuthMsg.templateId]; require(template.length > 0, "template id not exists"); @@ -83,6 +87,9 @@ contract EmailAuth { emailAuthMsg.proof.publicKeyHash ) == true, "invalid dkim public key hash"); + require(usedNullifiers[emailAuthMsg.proof.emailNullifier] == false, "email nullifier already used"); + usedNullifiers[emailAuthMsg.proof.emailNullifier] = true; + require(accountSalt == emailAuthMsg.proof.accountSalt, "invalid account salt"); require(emailAuthMsg.proof.timestamp > 0 && emailAuthMsg.proof.timestamp > lastTimestamp, "invalid timestamp"); lastTimestamp = emailAuthMsg.proof.timestamp; @@ -125,35 +132,51 @@ contract EmailAuth { expectedSubject = string(abi.encodePacked(expectedSubject, stringParam)); nextParamIndex++; } - - + string memory trimmedSubject = removePrefix(emailAuthMsg.proof.maskedSubject, emailAuthMsg.skipedSubjectPrefix); + require(Strings.equal(expectedSubject, trimmedSubject), "invalid subject"); + require(verifier.verifyEmailProof(emailAuthMsg.proof) == true, "invalid email proof"); + bytes32 msgHash = computeMsgHash( emailAuthMsg.proof.accountSalt, emailAuthMsg.proof.isCodeExist, emailAuthMsg.templateId, emailAuthMsg.subjectParams ); + require(authedHash[emailAuthMsg.proof.emailNullifier] == bytes32(0), "email already authed"); authedHash[emailAuthMsg.proof.emailNullifier] = msgHash; - // TBD + return msgHash; } function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4) { ( - bytes32 emailNullifier, - bytes32 accountSalt, - uint templateId, - bool isCodeExist, - bytes[] memory subjectParams + bytes32 _emailNullifier, + bytes32 _accountSalt, + uint _templateId, + bool _isCodeExist, + bytes[] memory _subjectParams ) = abi.decode(_signature, (bytes32, bytes32, uint, bool, bytes[])); - bytes32 msgHash = computeMsgHash(accountSalt, isCodeExist, templateId, subjectParams); - if(authedHash[emailNullifier] == msgHash) { + bytes32 msgHash = computeMsgHash(_accountSalt, _isCodeExist, _templateId, _subjectParams); + if(authedHash[_emailNullifier] == msgHash) { return 0x1626ba7e; } else { return 0xffffffff; } } + + function removePrefix(string memory str, uint numChars) private pure returns (string memory) { + require(numChars <= bytes(str).length, "Invalid number of characters"); + + bytes memory strBytes = bytes(str); + bytes memory result = new bytes(strBytes.length - numChars); + + for (uint i = numChars; i < strBytes.length; i++) { + result[i - numChars] = strBytes[i]; + } + + return string(result); + } } diff --git a/packages/contracts/src/utils/Verifier.sol b/packages/contracts/src/utils/Verifier.sol index 876b4573..a741e4be 100644 --- a/packages/contracts/src/utils/Verifier.sol +++ b/packages/contracts/src/utils/Verifier.sol @@ -16,7 +16,6 @@ struct EmailProof { contract Verifier { - mapping(bytes32=>bool) usedNullifiers; Groth16Verifier groth16Verifier; uint256 public constant DOMAIN_FIELDS = 9; @@ -24,13 +23,7 @@ contract Verifier { uint256 public constant SUBJECT_FIELDS = 20; uint256 public constant SUBJECT_BYTES = 605; - function verifyEmailProof(EmailProof memory proof) public returns (bool) { - if(isUsedNullifier(proof.emailNullifier)) { - return false; - } - - usedNullifiers[proof.emailNullifier] = true; - + function verifyEmailProof(EmailProof memory proof) public view returns (bool) { (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC) = abi.decode( proof.proof, (uint256[2], uint256[2][2], uint256[2]) @@ -55,15 +48,6 @@ contract Verifier { return groth16Verifier.verifyProof(pA, pB, pC, pubSignals); } - // Check if the nullifier is used - function isUsedNullifier(bytes32 emailNullifier) public view returns (bool) { - return usedNullifiers[emailNullifier]; - } - - function validateEmailProof(EmailProof memory proof) public pure returns (bool) { - - } - function _packBytes2Fields(bytes memory _bytes, uint256 _paddedSize) public pure returns (uint256[] memory) { uint256 remain = _paddedSize % 31; uint256 numFields = (_paddedSize - remain) / 31; From d638c2202020c53dcc73d4a28385b9d51ec42143 Mon Sep 17 00:00:00 2001 From: wshino Date: Sun, 17 Mar 2024 11:07:43 +0900 Subject: [PATCH 08/42] Tweak variable name. --- packages/contracts/src/EmailAuth.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/contracts/src/EmailAuth.sol b/packages/contracts/src/EmailAuth.sol index 763cfb10..3994b690 100644 --- a/packages/contracts/src/EmailAuth.sol +++ b/packages/contracts/src/EmailAuth.sol @@ -132,8 +132,8 @@ contract EmailAuth { expectedSubject = string(abi.encodePacked(expectedSubject, stringParam)); nextParamIndex++; } - string memory trimmedSubject = removePrefix(emailAuthMsg.proof.maskedSubject, emailAuthMsg.skipedSubjectPrefix); - require(Strings.equal(expectedSubject, trimmedSubject), "invalid subject"); + string memory trimmedMaskedSubject = removePrefix(emailAuthMsg.proof.maskedSubject, emailAuthMsg.skipedSubjectPrefix); + require(Strings.equal(expectedSubject, trimmedMaskedSubject), "invalid subject"); require(verifier.verifyEmailProof(emailAuthMsg.proof) == true, "invalid email proof"); bytes32 msgHash = computeMsgHash( From 31260e2b543eee2822766be597a29cb7f187809a Mon Sep 17 00:00:00 2001 From: wshino Date: Sun, 17 Mar 2024 17:27:48 +0900 Subject: [PATCH 09/42] Update correct timestamp validation condition. --- packages/contracts/src/EmailAuth.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/src/EmailAuth.sol b/packages/contracts/src/EmailAuth.sol index 3994b690..8f3eb74d 100644 --- a/packages/contracts/src/EmailAuth.sol +++ b/packages/contracts/src/EmailAuth.sol @@ -90,7 +90,7 @@ contract EmailAuth { require(usedNullifiers[emailAuthMsg.proof.emailNullifier] == false, "email nullifier already used"); usedNullifiers[emailAuthMsg.proof.emailNullifier] = true; require(accountSalt == emailAuthMsg.proof.accountSalt, "invalid account salt"); - require(emailAuthMsg.proof.timestamp > 0 && emailAuthMsg.proof.timestamp > lastTimestamp, "invalid timestamp"); + require(emailAuthMsg.proof.timestamp > 0 || emailAuthMsg.proof.timestamp > lastTimestamp, "invalid timestamp"); lastTimestamp = emailAuthMsg.proof.timestamp; // Construct an expectedSubject from template and the values of emailAuthMsg.subjectParams. From 577a2a14738ec79e2907e8b85a5c78f8e0c2b18c Mon Sep 17 00:00:00 2001 From: wshino Date: Sun, 17 Mar 2024 17:59:33 +0900 Subject: [PATCH 10/42] Update isValidSignature function. --- packages/contracts/src/EmailAuth.sol | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/packages/contracts/src/EmailAuth.sol b/packages/contracts/src/EmailAuth.sol index 8f3eb74d..8dcc9a0e 100644 --- a/packages/contracts/src/EmailAuth.sol +++ b/packages/contracts/src/EmailAuth.sol @@ -150,16 +150,8 @@ contract EmailAuth { } function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4) { - ( - bytes32 _emailNullifier, - bytes32 _accountSalt, - uint _templateId, - bool _isCodeExist, - bytes[] memory _subjectParams - ) = abi.decode(_signature, (bytes32, bytes32, uint, bool, bytes[])); - - bytes32 msgHash = computeMsgHash(_accountSalt, _isCodeExist, _templateId, _subjectParams); - if(authedHash[_emailNullifier] == msgHash) { + bytes32 _emailNullifier = abi.decode(_signature, (bytes32)); + if(authedHash[_emailNullifier] == _hash) { return 0x1626ba7e; } else { return 0xffffffff; From a21a33ea7e152cf13024962431aeaf2375f98481 Mon Sep 17 00:00:00 2001 From: wshino Date: Sun, 17 Mar 2024 18:43:34 +0900 Subject: [PATCH 11/42] Add unit test functions. --- packages/contracts/src/EmailAuth.sol | 12 ++-- packages/contracts/test/EmailAuth.t.sol | 88 +++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 packages/contracts/test/EmailAuth.t.sol diff --git a/packages/contracts/src/EmailAuth.sol b/packages/contracts/src/EmailAuth.sol index 8dcc9a0e..ede069c2 100644 --- a/packages/contracts/src/EmailAuth.sol +++ b/packages/contracts/src/EmailAuth.sol @@ -41,18 +41,18 @@ contract EmailAuth { return address(verifier); } - function updateVerifier(address _verifierAddr) public { - require(msg.sender == owner, "only owner can update verifier"); - require(_verifierAddr != address(0), "invalid verifier address"); - verifier = Verifier(_verifierAddr); - } - function updateDKIMRegistry(address _dkimRegistryAddr) public { require(msg.sender == owner, "only owner can update dkim registry"); require(_dkimRegistryAddr != address(0), "invalid dkim registry address"); dkim = ECDSAOwnedDKIMRegistry(_dkimRegistryAddr); } + function updateVerifier(address _verifierAddr) public { + require(msg.sender == owner, "only owner can update verifier"); + require(_verifierAddr != address(0), "invalid verifier address"); + verifier = Verifier(_verifierAddr); + } + function insertSubjectTemplate(uint _templateId, string[] memory _subjectTemplate) public { require(msg.sender == owner, "only owner can insert subject template"); require(_subjectTemplate.length > 0, "subject template is empty"); diff --git a/packages/contracts/test/EmailAuth.t.sol b/packages/contracts/test/EmailAuth.t.sol new file mode 100644 index 00000000..78a77e3e --- /dev/null +++ b/packages/contracts/test/EmailAuth.t.sol @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; + +import "../src/EmailAuth.sol"; +import "../src/utils/Verifier.sol"; +import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; + +contract EmailAuthTest is Test { + EmailAuth emailAuth; + Verifier verifier; + ECDSAOwnedDKIMRegistry dkim; + + bytes32 accountSalt; + uint templateId; + string[] subjectTemplate; + string[] newSubjectTemplate; + + function setUp() public { + dkim = new ECDSAOwnedDKIMRegistry(msg.sender); + verifier = new Verifier(); + + accountSalt = 0x103e3424744866f18867633cd0a8ec593f8dfab09f4cddbfaeda05414b1a5986; + emailAuth = new EmailAuth(accountSalt); + + emailAuth.updateVerifier(address(verifier)); + emailAuth.updateDKIMRegistry(address(dkim)); + + templateId = 1; + subjectTemplate = ["Send", "{decimals}", "ETH", "to", "{ethAddr}"]; + newSubjectTemplate = ["Send", "{decimals}", "USDC", "to", "{ethAddr}"]; + } + + function testDkimRegistryAddr() public view { + address dkimAddr = emailAuth.dkimRegistryAddr(); + assertEq(dkimAddr, address(dkim)); + } + + function testVerifierAddr() public view { + address verifierAddr = emailAuth.verifierAddr(); + assertEq(verifierAddr, address(verifier)); + } + + function testUpdateDKIMRegistry() public { + ECDSAOwnedDKIMRegistry newDKIM = new ECDSAOwnedDKIMRegistry(msg.sender); + emailAuth.updateDKIMRegistry(address(newDKIM)); + assertEq(emailAuth.dkimRegistryAddr(), address(newDKIM)); + } + + function testUpdateVerifier() public { + Verifier newVerifier = new Verifier(); + emailAuth.updateVerifier(address(newVerifier)); + assertEq(emailAuth.verifierAddr(), address(newVerifier)); + } + + function testInsertSubjectTemplate() public { + emailAuth.insertSubjectTemplate(templateId, subjectTemplate); + } + + function testUpdateSubjectTemplate() public { + this.testInsertSubjectTemplate(); + emailAuth.updateSubjectTemplate(templateId, newSubjectTemplate); + } + + function testDeleteSubjectTemplate() public { + this.testInsertSubjectTemplate(); + emailAuth.deleteSubjectTemplate(templateId); + } + + function testComputeMsgHash() public view { + bytes[] memory subjectParams = new bytes[](2); + subjectParams[0] = abi.encode(1); + subjectParams[1] = abi.encode(vm.addr(1)); + bytes32 msgHash = emailAuth.computeMsgHash(accountSalt, true, templateId, subjectParams); + assertEq(msgHash, 0x34cf6244c520f5e41b21f35403a92f8b2005bf696a72aeb0c0f3f77d95fa0a0e); + } + + // function testAuthEmail() public { + // this.testInsertSubjectTemplate(); + // bytes[] memory subjectParams = new bytes[](2); + // subjectParams[0] = abi.encode(1); + // subjectParams[1] = abi.encode(vm.addr(1)); + // emailAuth.authEmail(accountSalt, true, templateId, subjectParams, signature); + // } +} + From c84c5593500d7e4d73e6ce786b0ed4592df7fa5a Mon Sep 17 00:00:00 2001 From: wshino Date: Sun, 17 Mar 2024 20:29:08 +0900 Subject: [PATCH 12/42] Add testAuthEmail. --- packages/contracts/src/EmailAuth.sol | 15 +- packages/contracts/test/EmailAuth.t.sol | 71 ++++++-- .../test/utils/ECDSAOwnedDKIMRegistry.t.sol | 157 ++++++++++++++++++ 3 files changed, 222 insertions(+), 21 deletions(-) create mode 100644 packages/contracts/test/utils/ECDSAOwnedDKIMRegistry.t.sol diff --git a/packages/contracts/src/EmailAuth.sol b/packages/contracts/src/EmailAuth.sol index ede069c2..ea03c5ae 100644 --- a/packages/contracts/src/EmailAuth.sol +++ b/packages/contracts/src/EmailAuth.sol @@ -97,40 +97,39 @@ contract EmailAuth { string memory expectedSubject; uint8 nextParamIndex = 0; string memory stringParam; + bool isParamExist; for (uint8 i = 0; i < template.length; i++) { - + isParamExist = true; if(Strings.equal(template[i], "{string}")) { string memory param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (string)); stringParam = param; - // expectedSubject = string(abi.encodePacked(expectedSubject, param)); } else if(Strings.equal(template[i], "{uint}")) { uint256 param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (uint256)); stringParam = Strings.toString(param); - // expectedSubject = string(abi.encodePacked(expectedSubject, Strings.toString(param))); } else if(Strings.equal(template[i], "{int}")) { int256 param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (int256)); stringParam = Strings.toString(param); - // expectedSubject = string(abi.encodePacked(expectedSubject, Strings.toString(param))); } else if(Strings.equal(template[i], "{decimals}")) { uint256 param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (uint256)); stringParam = Strings.toString(param); - // expectedSubject = string(abi.encodePacked(expectedSubject, Strings.toString(param))); } else if(Strings.equal(template[i], "{decimals}")) { uint256 param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (uint256)); stringParam = Strings.toString(param); - // expectedSubject = string(abi.encodePacked(expectedSubject, Strings.toString(param))); } else if(Strings.equal(template[i], "{ethAddr}")) { address param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (address)); stringParam = Strings.toHexString(param); } else { - continue; + isParamExist = false; + stringParam = template[i]; } if(i > 0) { expectedSubject = string(abi.encodePacked(expectedSubject, " ")); } expectedSubject = string(abi.encodePacked(expectedSubject, stringParam)); - nextParamIndex++; + if(isParamExist) { + nextParamIndex++; + } } string memory trimmedMaskedSubject = removePrefix(emailAuthMsg.proof.maskedSubject, emailAuthMsg.skipedSubjectPrefix); require(Strings.equal(expectedSubject, trimmedMaskedSubject), "invalid subject"); diff --git a/packages/contracts/test/EmailAuth.t.sol b/packages/contracts/test/EmailAuth.t.sol index 78a77e3e..d1ebb484 100644 --- a/packages/contracts/test/EmailAuth.t.sol +++ b/packages/contracts/test/EmailAuth.t.sol @@ -4,11 +4,14 @@ pragma solidity ^0.8.12; import "forge-std/Test.sol"; import "forge-std/console.sol"; +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "../src/EmailAuth.sol"; import "../src/utils/Verifier.sol"; import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; contract EmailAuthTest is Test { + using ECDSA for *; + EmailAuth emailAuth; Verifier verifier; ECDSAOwnedDKIMRegistry dkim; @@ -17,20 +20,35 @@ contract EmailAuthTest is Test { uint templateId; string[] subjectTemplate; string[] newSubjectTemplate; + bytes mockProof = abi.encodePacked(bytes1(0x01)); + string selector = "12345"; + string domainName = "gmail.com"; + bytes32 publicKeyHash = 0x0ea9c777dc7110e5a9e89b13f0cfc540e3845ba120b2b6dc24024d61488d4788; function setUp() public { - dkim = new ECDSAOwnedDKIMRegistry(msg.sender); + address signer = vm.addr(1); + + // Create DKIM registry + dkim = new ECDSAOwnedDKIMRegistry(signer); + string memory signedMsg = dkim.computeSignedMsg(dkim.SET_PREFIX(), selector, domainName, publicKeyHash); + bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); + (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 = new Verifier(); + accountSalt = 0x2c3abbf3d1171bfefee99c13bf9c47f1e8447576afd89096652a34f27b297971; - accountSalt = 0x103e3424744866f18867633cd0a8ec593f8dfab09f4cddbfaeda05414b1a5986; + // Create EmailAuth emailAuth = new EmailAuth(accountSalt); - emailAuth.updateVerifier(address(verifier)); emailAuth.updateDKIMRegistry(address(dkim)); + templateId = 1; - subjectTemplate = ["Send", "{decimals}", "ETH", "to", "{ethAddr}"]; - newSubjectTemplate = ["Send", "{decimals}", "USDC", "to", "{ethAddr}"]; + subjectTemplate = ["Send", "{decimals}", "ETH", "to", "{string}"]; + newSubjectTemplate = ["Send", "{decimals}", "USDC", "to", "{string}"]; } function testDkimRegistryAddr() public view { @@ -74,15 +92,42 @@ contract EmailAuthTest is Test { subjectParams[0] = abi.encode(1); subjectParams[1] = abi.encode(vm.addr(1)); bytes32 msgHash = emailAuth.computeMsgHash(accountSalt, true, templateId, subjectParams); - assertEq(msgHash, 0x34cf6244c520f5e41b21f35403a92f8b2005bf696a72aeb0c0f3f77d95fa0a0e); + assertEq(msgHash, 0xe7f92de45c5ad2716ecefebf444d57aba480764d104b92d2a1bb7820f344bb22); } - // function testAuthEmail() public { - // this.testInsertSubjectTemplate(); - // bytes[] memory subjectParams = new bytes[](2); - // subjectParams[0] = abi.encode(1); - // subjectParams[1] = abi.encode(vm.addr(1)); - // emailAuth.authEmail(accountSalt, true, templateId, subjectParams, signature); - // } + function testAuthEmail() public { + this.testInsertSubjectTemplate(); + + bytes[] memory subjectParams = new bytes[](2); + subjectParams[0] = abi.encode(1); + subjectParams[1] = abi.encode("alice@gmail.com"); + + EmailProof memory emailProof = EmailProof({ + domainName: "gmail.com", + publicKeyHash: 0x0ea9c777dc7110e5a9e89b13f0cfc540e3845ba120b2b6dc24024d61488d4788, + timestamp: 1694989812, + maskedSubject: "Send 1 ETH to alice@gmail.com", + emailNullifier: 0x00a83fce3d4b1c9ef0f600644c1ecc6c8115b57b1596e0e3295e2c5105fbfd8a, + accountSalt: accountSalt, + isCodeExist: true, + proof: mockProof + }); + + EmailAuthMsg memory emailAuthMsg = EmailAuthMsg({ + templateId: templateId, + subjectParams: subjectParams, + skipedSubjectPrefix: 0, + proof: emailProof + }); + + // TODO: This mockCall should be removed + vm.mockCall( + address(verifier), + abi.encodeWithSelector(Verifier.verifyEmailProof.selector, emailProof), + abi.encode(true) + ); + bytes32 msgHash = emailAuth.authEmail(emailAuthMsg); + assertEq(msgHash, 0x8f11137c4bc94c224197349b9ebc44da5e5b9786d4a0117ea5794b5a90d51968); + } } diff --git a/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry.t.sol b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry.t.sol new file mode 100644 index 00000000..2ffa439a --- /dev/null +++ b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry.t.sol @@ -0,0 +1,157 @@ +// 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"; + +contract ECDSAOwnedDKIMRegistryTest is Test { + ECDSAOwnedDKIMRegistry registry; + 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); + registry = new ECDSAOwnedDKIMRegistry(signer); + } + + function test_SetDKIMPublicKeyHash() public { + vm.chainId(1); + string memory signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); + require(registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), "Invalid public key hash"); + } + + function test_SetDKIMPublicKeyHashMultiDomain() public { + vm.chainId(1); + string memory signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); + require(registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), "Invalid public key hash"); + + selector = "67890"; + domainName = "example2.com"; + publicKeyHash = bytes32(uint256(2)); + signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + digest = bytes(signedMsg).toEthSignedMessageHash(); + (v, r, s) = vm.sign(1, digest); + signature = abi.encodePacked(r, s, v); + registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); + require(registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), "Invalid public key hash"); + } + + function test_RevokeDKIMPublicKeyHash() public { + vm.chainId(1); + string memory signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); + + // Revoke + string memory revokeMsg = registry.computeSignedMsg( + registry.REVOKE_PREFIX(), + selector, + domainName, + publicKeyHash + ); + (uint8 v1, bytes32 r1, bytes32 s1) = vm.sign(1, bytes(revokeMsg).toEthSignedMessageHash()); + bytes memory revokeSig = abi.encodePacked(r1, s1, v1); + registry.revokeDKIMPublicKeyHash(selector, domainName, publicKeyHash, revokeSig); + + require(!registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash)); + } + + function test_RevertIfDuplicated() public { + vm.chainId(1); + string memory signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); + require(registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), "Invalid public key hash"); + + (uint8 v1, bytes32 r1, bytes32 s1) = vm.sign(1, digest); + bytes memory signature1 = abi.encodePacked(r1, s1, v1); + vm.expectRevert("publicKeyHash is already set"); + registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature1); + } + + function test_RevertIfRevorked() public { + vm.chainId(1); + string memory signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); + bytes memory signature = abi.encodePacked(r, s, v); + registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); + require(registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), "Invalid public key hash"); + + // Revoke + string memory revokeMsg = registry.computeSignedMsg( + registry.REVOKE_PREFIX(), + selector, + domainName, + publicKeyHash + ); + (uint8 v1, bytes32 r1, bytes32 s1) = vm.sign(1, bytes(revokeMsg).toEthSignedMessageHash()); + bytes memory revokeSig = abi.encodePacked(r1, s1, v1); + registry.revokeDKIMPublicKeyHash(selector, domainName, publicKeyHash, revokeSig); + require(!registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash)); + + signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + (uint8 v2, bytes32 r2, bytes32 s2) = vm.sign(1, digest); + bytes memory signature2 = abi.encodePacked(r2, s2, v2); + vm.expectRevert("publicKeyHash is revoked"); + registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature2); + } + + function test_RevertIfSignatureInvalid() public { + vm.chainId(1); + string memory signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(2, digest); + bytes memory signature = abi.encodePacked(r, s, v); + vm.expectRevert("Invalid signature"); + registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); + } + + function test_RevertIfChainIdInvalid() public { + vm.chainId(10); + string memory signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(2, digest); + bytes memory signature = abi.encodePacked(r, s, v); + vm.expectRevert("Invalid signature"); + registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); + } + + function test_Dfinity_Oracle_Response() public { + vm.chainId(1); + registry = new ECDSAOwnedDKIMRegistry(0x2F6e79a6E1a982a49CA248B70b02F76e921aF400); + selector = "20230601"; + domainName = "gmail.com"; + publicKeyHash = 0x0ea9c777dc7110e5a9e89b13f0cfc540e3845ba120b2b6dc24024d61488d4788; + registry.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + vm.parseBytes( + "0x39473ba3651237ac631a099ee737aa062f8bd14c8ee22c785452d50f977d5b4477c352187fa427a3d9ab5cf6b2c37b49670018523a4de753406fe442bef720ef1b" + ) + ); + require(registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), "Invalid public key hash"); + } +} From e55ce440a09f3d0d7222ff17ad75364d9cb7ddfc Mon Sep 17 00:00:00 2001 From: wshino Date: Mon, 18 Mar 2024 14:10:01 +0900 Subject: [PATCH 13/42] Remove comment. --- packages/contracts/test/EmailAuth.t.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/contracts/test/EmailAuth.t.sol b/packages/contracts/test/EmailAuth.t.sol index d1ebb484..686ad3bc 100644 --- a/packages/contracts/test/EmailAuth.t.sol +++ b/packages/contracts/test/EmailAuth.t.sol @@ -120,7 +120,6 @@ contract EmailAuthTest is Test { proof: emailProof }); - // TODO: This mockCall should be removed vm.mockCall( address(verifier), abi.encodeWithSelector(Verifier.verifyEmailProof.selector, emailProof), From afd29dff5eaa9aae21d2381aa3279855a88101eb Mon Sep 17 00:00:00 2001 From: wshino Date: Mon, 18 Mar 2024 14:11:56 +0900 Subject: [PATCH 14/42] Delete unused mock directory. --- packages/contracts/test/mocks/TestDKIMRegistry.sol | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 packages/contracts/test/mocks/TestDKIMRegistry.sol diff --git a/packages/contracts/test/mocks/TestDKIMRegistry.sol b/packages/contracts/test/mocks/TestDKIMRegistry.sol deleted file mode 100644 index 82afbbe5..00000000 --- a/packages/contracts/test/mocks/TestDKIMRegistry.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.9; - -import "@zk-email/contracts/interfaces/IDKIMRegistry.sol"; - -contract TestDKIMRegistry is IDKIMRegistry { - function isDKIMPublicKeyHashValid(string memory domainName, bytes32 publicKeyHash) external pure returns (bool) { - domainName; - return bytes32(uint256(123)) == publicKeyHash; - } -} From 37b973e7f101529e5af5fdbd37fc77a1a0538147 Mon Sep 17 00:00:00 2001 From: wshino Date: Tue, 19 Mar 2024 14:28:05 +0900 Subject: [PATCH 15/42] Add testIsValidSignature. --- packages/contracts/test/EmailAuth.t.sol | 71 +++++++++++++++++++------ 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/packages/contracts/test/EmailAuth.t.sol b/packages/contracts/test/EmailAuth.t.sol index 686ad3bc..4acf83cb 100644 --- a/packages/contracts/test/EmailAuth.t.sol +++ b/packages/contracts/test/EmailAuth.t.sol @@ -24,17 +24,30 @@ contract EmailAuthTest is Test { string selector = "12345"; string domainName = "gmail.com"; - bytes32 publicKeyHash = 0x0ea9c777dc7110e5a9e89b13f0cfc540e3845ba120b2b6dc24024d61488d4788; + bytes32 publicKeyHash = + 0x0ea9c777dc7110e5a9e89b13f0cfc540e3845ba120b2b6dc24024d61488d4788; + bytes32 emailNullifier = + 0x00a83fce3d4b1c9ef0f600644c1ecc6c8115b57b1596e0e3295e2c5105fbfd8a; function setUp() public { address signer = vm.addr(1); // Create DKIM registry dkim = new ECDSAOwnedDKIMRegistry(signer); - string memory signedMsg = dkim.computeSignedMsg(dkim.SET_PREFIX(), selector, domainName, publicKeyHash); + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + selector, + domainName, + publicKeyHash + ); bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); bytes memory signature = abi.encodePacked(r, s, v); - dkim.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); + dkim.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); // Create Verifier verifier = new Verifier(); @@ -45,7 +58,6 @@ contract EmailAuthTest is Test { emailAuth.updateVerifier(address(verifier)); emailAuth.updateDKIMRegistry(address(dkim)); - templateId = 1; subjectTemplate = ["Send", "{decimals}", "ETH", "to", "{string}"]; newSubjectTemplate = ["Send", "{decimals}", "USDC", "to", "{string}"]; @@ -55,7 +67,7 @@ contract EmailAuthTest is Test { address dkimAddr = emailAuth.dkimRegistryAddr(); assertEq(dkimAddr, address(dkim)); } - + function testVerifierAddr() public view { address verifierAddr = emailAuth.verifierAddr(); assertEq(verifierAddr, address(verifier)); @@ -66,14 +78,14 @@ contract EmailAuthTest is Test { emailAuth.updateDKIMRegistry(address(newDKIM)); assertEq(emailAuth.dkimRegistryAddr(), address(newDKIM)); } - + function testUpdateVerifier() public { Verifier newVerifier = new Verifier(); emailAuth.updateVerifier(address(newVerifier)); assertEq(emailAuth.verifierAddr(), address(newVerifier)); } - function testInsertSubjectTemplate() public { + function testInsertSubjectTemplate() public { emailAuth.insertSubjectTemplate(templateId, subjectTemplate); } @@ -91,8 +103,16 @@ contract EmailAuthTest is Test { bytes[] memory subjectParams = new bytes[](2); subjectParams[0] = abi.encode(1); subjectParams[1] = abi.encode(vm.addr(1)); - bytes32 msgHash = emailAuth.computeMsgHash(accountSalt, true, templateId, subjectParams); - assertEq(msgHash, 0xe7f92de45c5ad2716ecefebf444d57aba480764d104b92d2a1bb7820f344bb22); + bytes32 msgHash = emailAuth.computeMsgHash( + accountSalt, + true, + templateId, + subjectParams + ); + assertEq( + msgHash, + 0xe7f92de45c5ad2716ecefebf444d57aba480764d104b92d2a1bb7820f344bb22 + ); } function testAuthEmail() public { @@ -104,10 +124,10 @@ contract EmailAuthTest is Test { EmailProof memory emailProof = EmailProof({ domainName: "gmail.com", - publicKeyHash: 0x0ea9c777dc7110e5a9e89b13f0cfc540e3845ba120b2b6dc24024d61488d4788, + publicKeyHash: publicKeyHash, timestamp: 1694989812, maskedSubject: "Send 1 ETH to alice@gmail.com", - emailNullifier: 0x00a83fce3d4b1c9ef0f600644c1ecc6c8115b57b1596e0e3295e2c5105fbfd8a, + emailNullifier: emailNullifier, accountSalt: accountSalt, isCodeExist: true, proof: mockProof @@ -122,11 +142,32 @@ contract EmailAuthTest is Test { vm.mockCall( address(verifier), - abi.encodeWithSelector(Verifier.verifyEmailProof.selector, emailProof), + abi.encodeWithSelector( + Verifier.verifyEmailProof.selector, + emailProof + ), abi.encode(true) ); bytes32 msgHash = emailAuth.authEmail(emailAuthMsg); - assertEq(msgHash, 0x8f11137c4bc94c224197349b9ebc44da5e5b9786d4a0117ea5794b5a90d51968); - } -} + assertEq( + msgHash, + 0x8f11137c4bc94c224197349b9ebc44da5e5b9786d4a0117ea5794b5a90d51968 + ); + } + + function testIsValidSignature() public { + testAuthEmail(); + bytes32 msgHash = 0x8f11137c4bc94c224197349b9ebc44da5e5b9786d4a0117ea5794b5a90d51968; + bytes memory signature = abi.encodePacked(emailNullifier); + bytes4 result = emailAuth.isValidSignature(msgHash, signature); + assertEq(result, bytes4(0x1626ba7e)); + } + function testIsValidSignatureReturnsFalse() public { + testAuthEmail(); + bytes32 msgHash = 0x0; + bytes memory signature = abi.encodePacked(emailNullifier); + bytes4 result = emailAuth.isValidSignature(msgHash, signature); + assertEq(result, bytes4(0xffffffff)); + } +} From 58804ab774d741a8ac9520d3ae26ceece2c9a847 Mon Sep 17 00:00:00 2001 From: wshino Date: Tue, 19 Mar 2024 14:29:42 +0900 Subject: [PATCH 16/42] Format solidity files. --- .../contracts/src/EmailAccountRecovery.sol | 107 ++++++++-- packages/contracts/src/EmailAuth.sol | 176 +++++++++++----- .../src/utils/ECDSAOwnedDKIMRegistry.sol | 39 +++- packages/contracts/src/utils/Verifier.sol | 40 ++-- .../test/utils/ECDSAOwnedDKIMRegistry.t.sol | 191 +++++++++++++++--- 5 files changed, 433 insertions(+), 120 deletions(-) diff --git a/packages/contracts/src/EmailAccountRecovery.sol b/packages/contracts/src/EmailAccountRecovery.sol index 569cbee2..b2ee2845 100644 --- a/packages/contracts/src/EmailAccountRecovery.sol +++ b/packages/contracts/src/EmailAccountRecovery.sol @@ -7,7 +7,6 @@ import "@openzeppelin/contracts/utils/Create2.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; abstract contract EmailAccountRecovery { - uint8 constant EMAIL_ACCOUNT_RECOVERY_VERSION_ID = 1; function verifier() public view virtual returns (address) { @@ -22,57 +21,123 @@ abstract contract EmailAccountRecovery { return 0x0000000000000000000000000000000000000000; } - function acceptanceSubjectTemplates() public view virtual returns (string[][] memory) { + function acceptanceSubjectTemplates() + public + view + virtual + returns (string[][] memory) + { return new string[][](0); } - function recoverySubjectTemplates() public view virtual returns (string[][] memory) { + function recoverySubjectTemplates() + public + view + virtual + returns (string[][] memory) + { return new string[][](0); } - function acceptGuardian(address guardian, uint templateIdx, bytes[] memory subjectParams, bytes32 emailNullifier) public virtual; - function recoverWallet(address guardian, uint templateIdx, bytes[] memory subjectParams, bytes32 emailNullifier) public virtual; - - function handleAcceptance(EmailAuthMsg memory emailAuthMsg, uint templateIdx) external { - address guardian = Create2.computeAddress(emailAuthMsg.proof.accountSalt, bytes32(bytes20(emailAuthImplementation()))); + function acceptGuardian( + address guardian, + uint templateIdx, + bytes[] memory subjectParams, + bytes32 emailNullifier + ) public virtual; + function recoverWallet( + address guardian, + uint templateIdx, + bytes[] memory subjectParams, + bytes32 emailNullifier + ) public virtual; + + function handleAcceptance( + EmailAuthMsg memory emailAuthMsg, + uint templateIdx + ) external { + address guardian = Create2.computeAddress( + emailAuthMsg.proof.accountSalt, + bytes32(bytes20(emailAuthImplementation())) + ); require(Address.isContract(guardian), "guardian is not deployed"); - uint templateId = uint256(keccak256(abi.encode(EMAIL_ACCOUNT_RECOVERY_VERSION_ID, "ACCEPTANCE", templateIdx))); + uint templateId = uint256( + keccak256( + abi.encode( + EMAIL_ACCOUNT_RECOVERY_VERSION_ID, + "ACCEPTANCE", + templateIdx + ) + ) + ); require(templateId == emailAuthMsg.templateId, "invalid template id"); require(emailAuthMsg.proof.isCodeExist == true, "isCodeExist is false"); - // Deploy proxy - ERC1967Proxy proxy = new ERC1967Proxy(address(emailAuthImplementation()), abi.encode(dkim(), verifier())); + // Deploy proxy + ERC1967Proxy proxy = new ERC1967Proxy( + address(emailAuthImplementation()), + abi.encode(dkim(), verifier()) + ); EmailAuth newEmailAuth = EmailAuth(payable(address(proxy))); EmailAuth guardianEmailAuth = EmailAuth(payable(address(guardian))); for (uint i = 0; i < acceptanceSubjectTemplates().length; i++) { - guardianEmailAuth.insertSubjectTemplate(i, acceptanceSubjectTemplates()[i]); + guardianEmailAuth.insertSubjectTemplate( + i, + acceptanceSubjectTemplates()[i] + ); } for (uint i = 0; i < recoverySubjectTemplates().length; i++) { - guardianEmailAuth.insertSubjectTemplate(i, acceptanceSubjectTemplates()[i]); + guardianEmailAuth.insertSubjectTemplate( + i, + acceptanceSubjectTemplates()[i] + ); } - // An assertion to confirm that the authEmail function is executed successfully + // An assertion to confirm that the authEmail function is executed successfully // and does not return an error. guardianEmailAuth.authEmail(emailAuthMsg); - acceptGuardian(guardian, templateIdx, emailAuthMsg.subjectParams, emailAuthMsg.proof.emailNullifier); + acceptGuardian( + guardian, + templateIdx, + emailAuthMsg.subjectParams, + emailAuthMsg.proof.emailNullifier + ); } - function handleRecovery(EmailAuthMsg memory emailAuthMsg, uint templateIdx) external { - address guardian = Create2.computeAddress(emailAuthMsg.proof.accountSalt, bytes32(bytes20(emailAuthImplementation()))); + function handleRecovery( + EmailAuthMsg memory emailAuthMsg, + uint templateIdx + ) external { + address guardian = Create2.computeAddress( + emailAuthMsg.proof.accountSalt, + bytes32(bytes20(emailAuthImplementation())) + ); require(Address.isContract(guardian), "guardian is not deployed"); - uint templateId = uint256(keccak256(abi.encode(EMAIL_ACCOUNT_RECOVERY_VERSION_ID, "RECOVERY", templateIdx))); + uint templateId = uint256( + keccak256( + abi.encode( + EMAIL_ACCOUNT_RECOVERY_VERSION_ID, + "RECOVERY", + templateIdx + ) + ) + ); require(templateId == emailAuthMsg.templateId, "invalid template id"); EmailAuth guardianEmailAuth = EmailAuth(payable(address(guardian))); - // An assertion to confirm that the authEmail function is executed successfully + // An assertion to confirm that the authEmail function is executed successfully // and does not return an error. guardianEmailAuth.authEmail(emailAuthMsg); - recoverWallet(guardian, templateIdx, emailAuthMsg.subjectParams, emailAuthMsg.proof.emailNullifier); + recoverWallet( + guardian, + templateIdx, + emailAuthMsg.subjectParams, + emailAuthMsg.proof.emailNullifier + ); } } - diff --git a/packages/contracts/src/EmailAuth.sol b/packages/contracts/src/EmailAuth.sol index ea03c5ae..36b654b4 100644 --- a/packages/contracts/src/EmailAuth.sol +++ b/packages/contracts/src/EmailAuth.sol @@ -16,7 +16,6 @@ struct EmailAuthMsg { } contract EmailAuth { - address owner; bytes32 accountSalt; ECDSAOwnedDKIMRegistry dkim; @@ -24,9 +23,9 @@ contract EmailAuth { mapping(uint => string[]) subjectTemplates; mapping(bytes32 => bytes32) authedHash; uint lastTimestamp; - mapping(bytes32=>bool) usedNullifiers; + mapping(bytes32 => bool) usedNullifiers; bool timestampCheckEnabled; - + constructor(bytes32 _accountSalt) { owner = msg.sender; accountSalt = _accountSalt; @@ -43,7 +42,10 @@ contract EmailAuth { function updateDKIMRegistry(address _dkimRegistryAddr) public { require(msg.sender == owner, "only owner can update dkim registry"); - require(_dkimRegistryAddr != address(0), "invalid dkim registry address"); + require( + _dkimRegistryAddr != address(0), + "invalid dkim registry address" + ); dkim = ECDSAOwnedDKIMRegistry(_dkimRegistryAddr); } @@ -53,46 +55,87 @@ contract EmailAuth { verifier = Verifier(_verifierAddr); } - function insertSubjectTemplate(uint _templateId, string[] memory _subjectTemplate) public { + function insertSubjectTemplate( + uint _templateId, + string[] memory _subjectTemplate + ) public { require(msg.sender == owner, "only owner can insert subject template"); require(_subjectTemplate.length > 0, "subject template is empty"); - require(subjectTemplates[_templateId].length == 0, "template id already exists"); + require( + subjectTemplates[_templateId].length == 0, + "template id already exists" + ); subjectTemplates[_templateId] = _subjectTemplate; } - function updateSubjectTemplate(uint _templateId, string[] memory _subjectTemplate) public { + function updateSubjectTemplate( + uint _templateId, + string[] memory _subjectTemplate + ) public { require(msg.sender == owner, "only owner can update subject template"); require(_subjectTemplate.length > 0, "subject template is empty"); - require(subjectTemplates[_templateId].length > 0, "template id not exists"); + require( + subjectTemplates[_templateId].length > 0, + "template id not exists" + ); subjectTemplates[_templateId] = _subjectTemplate; } function deleteSubjectTemplate(uint _templateId) public { require(msg.sender == owner, "only owner can delete subject template"); - require(subjectTemplates[_templateId].length > 0, "template id not exists"); + require( + subjectTemplates[_templateId].length > 0, + "template id not exists" + ); delete subjectTemplates[_templateId]; } - function computeMsgHash(bytes32 _accountSalt, bool _isCodeExist, uint _templateId, bytes[] memory _subjectParams) public pure returns (bytes32) { - return keccak256(abi.encode(_accountSalt, _isCodeExist, _templateId, _subjectParams)); + function computeMsgHash( + bytes32 _accountSalt, + bool _isCodeExist, + uint _templateId, + bytes[] memory _subjectParams + ) public pure returns (bytes32) { + return + keccak256( + abi.encode( + _accountSalt, + _isCodeExist, + _templateId, + _subjectParams + ) + ); } - function authEmail(EmailAuthMsg memory emailAuthMsg) public returns (bytes32) { + function authEmail( + EmailAuthMsg memory emailAuthMsg + ) public returns (bytes32) { require(msg.sender == owner, "only owner can auth email"); string[] memory template = subjectTemplates[emailAuthMsg.templateId]; require(template.length > 0, "template id not exists"); require( dkim.isDKIMPublicKeyHashValid( - emailAuthMsg.proof.domainName, + emailAuthMsg.proof.domainName, emailAuthMsg.proof.publicKeyHash - ) == true, - "invalid dkim public key hash"); - require(usedNullifiers[emailAuthMsg.proof.emailNullifier] == false, "email nullifier already used"); + ) == true, + "invalid dkim public key hash" + ); + require( + usedNullifiers[emailAuthMsg.proof.emailNullifier] == false, + "email nullifier already used" + ); usedNullifiers[emailAuthMsg.proof.emailNullifier] = true; - require(accountSalt == emailAuthMsg.proof.accountSalt, "invalid account salt"); - require(emailAuthMsg.proof.timestamp > 0 || emailAuthMsg.proof.timestamp > lastTimestamp, "invalid timestamp"); + require( + accountSalt == emailAuthMsg.proof.accountSalt, + "invalid account salt" + ); + require( + emailAuthMsg.proof.timestamp > 0 || + emailAuthMsg.proof.timestamp > lastTimestamp, + "invalid timestamp" + ); lastTimestamp = emailAuthMsg.proof.timestamp; - + // Construct an expectedSubject from template and the values of emailAuthMsg.subjectParams. string memory expectedSubject; uint8 nextParamIndex = 0; @@ -100,64 +143,104 @@ contract EmailAuth { bool isParamExist; for (uint8 i = 0; i < template.length; i++) { isParamExist = true; - if(Strings.equal(template[i], "{string}")) { - string memory param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (string)); + if (Strings.equal(template[i], "{string}")) { + string memory param = abi.decode( + emailAuthMsg.subjectParams[nextParamIndex], + (string) + ); stringParam = param; - } else if(Strings.equal(template[i], "{uint}")) { - uint256 param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (uint256)); + } else if (Strings.equal(template[i], "{uint}")) { + uint256 param = abi.decode( + emailAuthMsg.subjectParams[nextParamIndex], + (uint256) + ); stringParam = Strings.toString(param); - } else if(Strings.equal(template[i], "{int}")) { - int256 param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (int256)); + } else if (Strings.equal(template[i], "{int}")) { + int256 param = abi.decode( + emailAuthMsg.subjectParams[nextParamIndex], + (int256) + ); stringParam = Strings.toString(param); - } else if(Strings.equal(template[i], "{decimals}")) { - uint256 param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (uint256)); + } else if (Strings.equal(template[i], "{decimals}")) { + uint256 param = abi.decode( + emailAuthMsg.subjectParams[nextParamIndex], + (uint256) + ); stringParam = Strings.toString(param); - } else if(Strings.equal(template[i], "{decimals}")) { - uint256 param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (uint256)); + } else if (Strings.equal(template[i], "{decimals}")) { + uint256 param = abi.decode( + emailAuthMsg.subjectParams[nextParamIndex], + (uint256) + ); stringParam = Strings.toString(param); - } else if(Strings.equal(template[i], "{ethAddr}")) { - address param = abi.decode(emailAuthMsg.subjectParams[nextParamIndex], (address)); + } else if (Strings.equal(template[i], "{ethAddr}")) { + address param = abi.decode( + emailAuthMsg.subjectParams[nextParamIndex], + (address) + ); stringParam = Strings.toHexString(param); } else { isParamExist = false; stringParam = template[i]; } - if(i > 0) { - expectedSubject = string(abi.encodePacked(expectedSubject, " ")); + if (i > 0) { + expectedSubject = string( + abi.encodePacked(expectedSubject, " ") + ); } - expectedSubject = string(abi.encodePacked(expectedSubject, stringParam)); - if(isParamExist) { + expectedSubject = string( + abi.encodePacked(expectedSubject, stringParam) + ); + if (isParamExist) { nextParamIndex++; } } - string memory trimmedMaskedSubject = removePrefix(emailAuthMsg.proof.maskedSubject, emailAuthMsg.skipedSubjectPrefix); - require(Strings.equal(expectedSubject, trimmedMaskedSubject), "invalid subject"); - require(verifier.verifyEmailProof(emailAuthMsg.proof) == true, "invalid email proof"); + string memory trimmedMaskedSubject = removePrefix( + emailAuthMsg.proof.maskedSubject, + emailAuthMsg.skipedSubjectPrefix + ); + require( + Strings.equal(expectedSubject, trimmedMaskedSubject), + "invalid subject" + ); + require( + verifier.verifyEmailProof(emailAuthMsg.proof) == true, + "invalid email proof" + ); bytes32 msgHash = computeMsgHash( - emailAuthMsg.proof.accountSalt, - emailAuthMsg.proof.isCodeExist, - emailAuthMsg.templateId, + emailAuthMsg.proof.accountSalt, + emailAuthMsg.proof.isCodeExist, + emailAuthMsg.templateId, emailAuthMsg.subjectParams ); - require(authedHash[emailAuthMsg.proof.emailNullifier] == bytes32(0), "email already authed"); + require( + authedHash[emailAuthMsg.proof.emailNullifier] == bytes32(0), + "email already authed" + ); authedHash[emailAuthMsg.proof.emailNullifier] = msgHash; return msgHash; } - function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4) { + function isValidSignature( + bytes32 _hash, + bytes memory _signature + ) public view returns (bytes4) { bytes32 _emailNullifier = abi.decode(_signature, (bytes32)); - if(authedHash[_emailNullifier] == _hash) { + if (authedHash[_emailNullifier] == _hash) { return 0x1626ba7e; } else { return 0xffffffff; } } - - function removePrefix(string memory str, uint numChars) private pure returns (string memory) { + + function removePrefix( + string memory str, + uint numChars + ) private pure returns (string memory) { require(numChars <= bytes(str).length, "Invalid number of characters"); bytes memory strBytes = bytes(str); @@ -170,4 +253,3 @@ contract EmailAuth { return string(result); } } - diff --git a/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol b/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol index 45f8bc84..0aeb0b2f 100644 --- a/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol +++ b/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol @@ -22,7 +22,10 @@ contract ECDSAOwnedDKIMRegistry is IDKIMRegistry { signer = _signer; } - function isDKIMPublicKeyHashValid(string memory domainName, bytes32 publicKeyHash) public view returns (bool) { + function isDKIMPublicKeyHashValid( + string memory domainName, + bytes32 publicKeyHash + ) public view returns (bool) { return dkimRegistry.isDKIMPublicKeyHashValid(domainName, publicKeyHash); } @@ -35,10 +38,21 @@ contract ECDSAOwnedDKIMRegistry is IDKIMRegistry { require(bytes(selector).length != 0, "Invalid selector"); require(bytes(domainName).length != 0, "Invalid domain name"); require(publicKeyHash != bytes32(0), "Invalid public key hash"); - require(isDKIMPublicKeyHashValid(domainName, publicKeyHash) == false, "publicKeyHash is already set"); - require(dkimRegistry.revokedDKIMPublicKeyHashes(publicKeyHash) == false, "publicKeyHash is revoked"); + require( + isDKIMPublicKeyHashValid(domainName, publicKeyHash) == false, + "publicKeyHash is already set" + ); + require( + dkimRegistry.revokedDKIMPublicKeyHashes(publicKeyHash) == false, + "publicKeyHash is revoked" + ); - string memory signedMsg = computeSignedMsg(SET_PREFIX, selector, domainName, publicKeyHash); + string memory signedMsg = computeSignedMsg( + SET_PREFIX, + selector, + domainName, + publicKeyHash + ); bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); address recoveredSigner = digest.recover(signature); require(recoveredSigner == signer, "Invalid signature"); @@ -55,10 +69,21 @@ contract ECDSAOwnedDKIMRegistry is IDKIMRegistry { require(bytes(selector).length != 0, "Invalid selector"); require(bytes(domainName).length != 0, "Invalid domain name"); require(publicKeyHash != bytes32(0), "Invalid public key hash"); - require(isDKIMPublicKeyHashValid(domainName, publicKeyHash) == true, "publicKeyHash is not set"); - require(dkimRegistry.revokedDKIMPublicKeyHashes(publicKeyHash) == false, "publicKeyHash is already revoked"); + require( + isDKIMPublicKeyHashValid(domainName, publicKeyHash) == true, + "publicKeyHash is not set" + ); + require( + dkimRegistry.revokedDKIMPublicKeyHashes(publicKeyHash) == false, + "publicKeyHash is already revoked" + ); - string memory signedMsg = computeSignedMsg(REVOKE_PREFIX, selector, domainName, publicKeyHash); + string memory signedMsg = computeSignedMsg( + REVOKE_PREFIX, + selector, + domainName, + publicKeyHash + ); bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); address recoveredSigner = digest.recover(signature); require(recoveredSigner == signer, "Invalid signature"); diff --git a/packages/contracts/src/utils/Verifier.sol b/packages/contracts/src/utils/Verifier.sol index a741e4be..b0138e1a 100644 --- a/packages/contracts/src/utils/Verifier.sol +++ b/packages/contracts/src/utils/Verifier.sol @@ -15,19 +15,21 @@ struct EmailProof { } contract Verifier { - Groth16Verifier 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; - - function verifyEmailProof(EmailProof memory proof) public view returns (bool) { - (uint256[2] memory pA, uint256[2][2] memory pB, uint256[2] memory pC) = abi.decode( - proof.proof, - (uint256[2], uint256[2][2], uint256[2]) - ); + + function verifyEmailProof( + EmailProof memory proof + ) public view returns (bool) { + ( + uint256[2] memory pA, + 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; uint256[] memory stringFields; @@ -38,17 +40,27 @@ contract Verifier { pubSignals[DOMAIN_FIELDS] = uint256(proof.publicKeyHash); pubSignals[DOMAIN_FIELDS + 1] = uint256(proof.emailNullifier); pubSignals[DOMAIN_FIELDS + 2] = uint256(proof.timestamp); - stringFields = _packBytes2Fields(bytes(proof.maskedSubject), SUBJECT_BYTES); + stringFields = _packBytes2Fields( + bytes(proof.maskedSubject), + SUBJECT_BYTES + ); for (uint256 i = 0; i < SUBJECT_FIELDS; i++) { pubSignals[DOMAIN_FIELDS + 3 + i] = stringFields[i]; } - pubSignals[DOMAIN_FIELDS + 3 + SUBJECT_FIELDS] = uint256(proof.accountSalt); - pubSignals[DOMAIN_FIELDS + 3 + SUBJECT_FIELDS + 1] = proof.isCodeExist ? 1 : 0; - + pubSignals[DOMAIN_FIELDS + 3 + SUBJECT_FIELDS] = uint256( + proof.accountSalt + ); + pubSignals[DOMAIN_FIELDS + 3 + SUBJECT_FIELDS + 1] = proof.isCodeExist + ? 1 + : 0; + return groth16Verifier.verifyProof(pA, pB, pC, pubSignals); } - - function _packBytes2Fields(bytes memory _bytes, uint256 _paddedSize) public pure returns (uint256[] memory) { + + function _packBytes2Fields( + bytes memory _bytes, + uint256 _paddedSize + ) public pure returns (uint256[] memory) { uint256 remain = _paddedSize % 31; uint256 numFields = (_paddedSize - remain) / 31; if (remain > 0) { @@ -77,6 +89,4 @@ contract Verifier { } return fields; } - } - diff --git a/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry.t.sol b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry.t.sol index 2ffa439a..7500e04e 100644 --- a/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry.t.sol +++ b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry.t.sol @@ -25,41 +25,90 @@ contract ECDSAOwnedDKIMRegistryTest is Test { function test_SetDKIMPublicKeyHash() public { vm.chainId(1); - string memory signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + string memory signedMsg = registry.computeSignedMsg( + registry.SET_PREFIX(), + selector, + domainName, + publicKeyHash + ); bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); bytes memory signature = abi.encodePacked(r, s, v); - registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); - require(registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), "Invalid public key hash"); + registry.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + require( + registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), + "Invalid public key hash" + ); } function test_SetDKIMPublicKeyHashMultiDomain() public { vm.chainId(1); - string memory signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + string memory signedMsg = registry.computeSignedMsg( + registry.SET_PREFIX(), + selector, + domainName, + publicKeyHash + ); bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); bytes memory signature = abi.encodePacked(r, s, v); - registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); - require(registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), "Invalid public key hash"); + registry.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + require( + registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), + "Invalid public key hash" + ); selector = "67890"; domainName = "example2.com"; publicKeyHash = bytes32(uint256(2)); - signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + signedMsg = registry.computeSignedMsg( + registry.SET_PREFIX(), + selector, + domainName, + publicKeyHash + ); digest = bytes(signedMsg).toEthSignedMessageHash(); (v, r, s) = vm.sign(1, digest); signature = abi.encodePacked(r, s, v); - registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); - require(registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), "Invalid public key hash"); + registry.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + require( + registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), + "Invalid public key hash" + ); } function test_RevokeDKIMPublicKeyHash() public { vm.chainId(1); - string memory signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + string memory signedMsg = registry.computeSignedMsg( + registry.SET_PREFIX(), + selector, + domainName, + publicKeyHash + ); bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); bytes memory signature = abi.encodePacked(r, s, v); - registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); + registry.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); // Revoke string memory revokeMsg = registry.computeSignedMsg( @@ -68,36 +117,75 @@ contract ECDSAOwnedDKIMRegistryTest is Test { domainName, publicKeyHash ); - (uint8 v1, bytes32 r1, bytes32 s1) = vm.sign(1, bytes(revokeMsg).toEthSignedMessageHash()); + (uint8 v1, bytes32 r1, bytes32 s1) = vm.sign( + 1, + bytes(revokeMsg).toEthSignedMessageHash() + ); bytes memory revokeSig = abi.encodePacked(r1, s1, v1); - registry.revokeDKIMPublicKeyHash(selector, domainName, publicKeyHash, revokeSig); + registry.revokeDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + revokeSig + ); require(!registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash)); } function test_RevertIfDuplicated() public { vm.chainId(1); - string memory signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + string memory signedMsg = registry.computeSignedMsg( + registry.SET_PREFIX(), + selector, + domainName, + publicKeyHash + ); bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); bytes memory signature = abi.encodePacked(r, s, v); - registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); - require(registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), "Invalid public key hash"); + registry.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + require( + registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), + "Invalid public key hash" + ); (uint8 v1, bytes32 r1, bytes32 s1) = vm.sign(1, digest); bytes memory signature1 = abi.encodePacked(r1, s1, v1); vm.expectRevert("publicKeyHash is already set"); - registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature1); + registry.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature1 + ); } function test_RevertIfRevorked() public { vm.chainId(1); - string memory signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + string memory signedMsg = registry.computeSignedMsg( + registry.SET_PREFIX(), + selector, + domainName, + publicKeyHash + ); bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); bytes memory signature = abi.encodePacked(r, s, v); - registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); - require(registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), "Invalid public key hash"); + registry.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + require( + registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), + "Invalid public key hash" + ); // Revoke string memory revokeMsg = registry.computeSignedMsg( @@ -106,41 +194,81 @@ contract ECDSAOwnedDKIMRegistryTest is Test { domainName, publicKeyHash ); - (uint8 v1, bytes32 r1, bytes32 s1) = vm.sign(1, bytes(revokeMsg).toEthSignedMessageHash()); + (uint8 v1, bytes32 r1, bytes32 s1) = vm.sign( + 1, + bytes(revokeMsg).toEthSignedMessageHash() + ); bytes memory revokeSig = abi.encodePacked(r1, s1, v1); - registry.revokeDKIMPublicKeyHash(selector, domainName, publicKeyHash, revokeSig); + registry.revokeDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + revokeSig + ); require(!registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash)); - signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + signedMsg = registry.computeSignedMsg( + registry.SET_PREFIX(), + selector, + domainName, + publicKeyHash + ); (uint8 v2, bytes32 r2, bytes32 s2) = vm.sign(1, digest); bytes memory signature2 = abi.encodePacked(r2, s2, v2); vm.expectRevert("publicKeyHash is revoked"); - registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature2); + registry.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature2 + ); } function test_RevertIfSignatureInvalid() public { vm.chainId(1); - string memory signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + string memory signedMsg = registry.computeSignedMsg( + registry.SET_PREFIX(), + selector, + domainName, + publicKeyHash + ); bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); (uint8 v, bytes32 r, bytes32 s) = vm.sign(2, digest); bytes memory signature = abi.encodePacked(r, s, v); vm.expectRevert("Invalid signature"); - registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); + registry.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); } function test_RevertIfChainIdInvalid() public { vm.chainId(10); - string memory signedMsg = registry.computeSignedMsg(registry.SET_PREFIX(), selector, domainName, publicKeyHash); + string memory signedMsg = registry.computeSignedMsg( + registry.SET_PREFIX(), + selector, + domainName, + publicKeyHash + ); bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); (uint8 v, bytes32 r, bytes32 s) = vm.sign(2, digest); bytes memory signature = abi.encodePacked(r, s, v); vm.expectRevert("Invalid signature"); - registry.setDKIMPublicKeyHash(selector, domainName, publicKeyHash, signature); + registry.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); } function test_Dfinity_Oracle_Response() public { vm.chainId(1); - registry = new ECDSAOwnedDKIMRegistry(0x2F6e79a6E1a982a49CA248B70b02F76e921aF400); + registry = new ECDSAOwnedDKIMRegistry( + 0x2F6e79a6E1a982a49CA248B70b02F76e921aF400 + ); selector = "20230601"; domainName = "gmail.com"; publicKeyHash = 0x0ea9c777dc7110e5a9e89b13f0cfc540e3845ba120b2b6dc24024d61488d4788; @@ -152,6 +280,9 @@ contract ECDSAOwnedDKIMRegistryTest is Test { "0x39473ba3651237ac631a099ee737aa062f8bd14c8ee22c785452d50f977d5b4477c352187fa427a3d9ab5cf6b2c37b49670018523a4de753406fe442bef720ef1b" ) ); - require(registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), "Invalid public key hash"); + require( + registry.isDKIMPublicKeyHashValid(domainName, publicKeyHash), + "Invalid public key hash" + ); } } From 594e51da873bc2dc2dac12c4025e9cf302940e4e Mon Sep 17 00:00:00 2001 From: wshino Date: Tue, 19 Mar 2024 15:08:32 +0900 Subject: [PATCH 17/42] Add deploy script. --- packages/contracts/.env.sample | 11 ++++ packages/contracts/foundry.toml | 9 +++ .../contracts/script/DeployEmailAuth.s.sol | 63 +++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 packages/contracts/.env.sample create mode 100644 packages/contracts/script/DeployEmailAuth.s.sol diff --git a/packages/contracts/.env.sample b/packages/contracts/.env.sample new file mode 100644 index 00000000..5470dcb7 --- /dev/null +++ b/packages/contracts/.env.sample @@ -0,0 +1,11 @@ +LOCALHOST_RPC_URL=http://127.0.0.1:8545 +SEPOLIA_RPC_URL=https://sepolia.base.org +MAINNET_RPC_URL=https://mainnet.base.org + +PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +ETHERSCAN_API_KEY= + +SELECTOR=12345 +DOMAIN_NAME=gmail.com +PUBLIC_KEY_HASH=0x0ea9c777dc7110e5a9e89b13f0cfc540e3845ba120b2b6dc24024d61488d4788 +ACCOUNT_SALT=0x2c3abbf3d1171bfefee99c13bf9c47f1e8447576afd89096652a34f27b297971 \ No newline at end of file diff --git a/packages/contracts/foundry.toml b/packages/contracts/foundry.toml index aa9e36de..7a7042c7 100644 --- a/packages/contracts/foundry.toml +++ b/packages/contracts/foundry.toml @@ -15,3 +15,12 @@ fs_permissions = [ # OpenZeppelin build_info = true extra_output = ["storageLayout"] + +[rpc_endpoints] +localhost = "${LOCALHOST_RPC_URL}" +sepolia = "${SEPOLIA_RPC_URL}" +mainnet = "${MAINNET_RPC_URL}" + +[etherscan] +sepolia = { key = "${ETHERSCAN_API_KEY}" } +mainnet = { key = "${ETHERSCAN_API_KEY}" } \ No newline at end of file diff --git a/packages/contracts/script/DeployEmailAuth.s.sol b/packages/contracts/script/DeployEmailAuth.s.sol new file mode 100644 index 00000000..65d4094b --- /dev/null +++ b/packages/contracts/script/DeployEmailAuth.s.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "forge-std/Script.sol"; + +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import "../src/EmailAuth.sol"; +import "../src/utils/Verifier.sol"; +import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; + +contract DeployEmailAuth is Script { + using ECDSA for *; + + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + vm.startBroadcast(deployerPrivateKey); + + // Deploy DKIM registry + ECDSAOwnedDKIMRegistry dkim = new ECDSAOwnedDKIMRegistry( + vm.addr(deployerPrivateKey) + ); + string memory selector = vm.envString("SELECTOR"); + string memory domainName = vm.envString("DOMAIN_NAME"); + bytes32 publicKeyHash = vm.envBytes32("PUBLIC_KEY_HASH"); + + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + selector, + domainName, + publicKeyHash + ); + bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(deployerPrivateKey, digest); + bytes memory signature = abi.encodePacked(r, s, v); + dkim.setDKIMPublicKeyHash( + selector, + domainName, + publicKeyHash, + signature + ); + + // Create Verifier + Verifier verifier = new Verifier(); + bytes32 accountSalt = vm.envBytes32("ACCOUNT_SALT"); + + // Create EmailAuth + EmailAuth emailAuth = new EmailAuth(accountSalt); + emailAuth.updateVerifier(address(verifier)); + emailAuth.updateDKIMRegistry(address(dkim)); + + // Insert first subject template + uint256 templateId = 1; + string[] memory subjectTemplate = new string[](5); + subjectTemplate[0] = "Send"; + subjectTemplate[1] = "{decimals}"; + subjectTemplate[2] = "ETH"; + subjectTemplate[3] = "to"; + subjectTemplate[4] = "{string}"; + emailAuth.insertSubjectTemplate(templateId, subjectTemplate); + + vm.stopBroadcast(); + } +} From 34354957b1baaedea8339adba78e4b7fadd2da6f Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Wed, 20 Mar 2024 01:27:51 +0900 Subject: [PATCH 18/42] Modify ECSDSAOwnedDKIMRegistry to be independent of the chain id. --- .../src/utils/ECDSAOwnedDKIMRegistry.sol | 4 +-- packages/contracts/src/utils/Verifier.sol | 6 ++-- packages/contracts/test/EmailAuth.t.sol | 6 ++-- .../test/utils/ECDSAOwnedDKIMRegistry.t.sol | 35 +++++-------------- 4 files changed, 15 insertions(+), 36 deletions(-) diff --git a/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol b/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol index 0aeb0b2f..5ef523c7 100644 --- a/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol +++ b/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol @@ -100,9 +100,7 @@ contract ECDSAOwnedDKIMRegistry is IDKIMRegistry { return string.concat( prefix, - "chain_id=", - block.chainid.toString(), - ";selector=", + "selector=", selector, ";domain=", domainName, diff --git a/packages/contracts/src/utils/Verifier.sol b/packages/contracts/src/utils/Verifier.sol index b0138e1a..2fe79b6f 100644 --- a/packages/contracts/src/utils/Verifier.sol +++ b/packages/contracts/src/utils/Verifier.sol @@ -8,9 +8,9 @@ struct EmailProof { 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 email to prevent re-run - bytes32 accountSalt; // Salt of the account - bool isCodeExist; // Check if the code is exist + 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 } diff --git a/packages/contracts/test/EmailAuth.t.sol b/packages/contracts/test/EmailAuth.t.sol index 4acf83cb..7e544924 100644 --- a/packages/contracts/test/EmailAuth.t.sol +++ b/packages/contracts/test/EmailAuth.t.sol @@ -63,12 +63,12 @@ contract EmailAuthTest is Test { newSubjectTemplate = ["Send", "{decimals}", "USDC", "to", "{string}"]; } - function testDkimRegistryAddr() public view { + function testDkimRegistryAddr() public { address dkimAddr = emailAuth.dkimRegistryAddr(); assertEq(dkimAddr, address(dkim)); } - function testVerifierAddr() public view { + function testVerifierAddr() public { address verifierAddr = emailAuth.verifierAddr(); assertEq(verifierAddr, address(verifier)); } @@ -99,7 +99,7 @@ contract EmailAuthTest is Test { emailAuth.deleteSubjectTemplate(templateId); } - function testComputeMsgHash() public view { + function testComputeMsgHash() public { bytes[] memory subjectParams = new bytes[](2); subjectParams[0] = abi.encode(1); subjectParams[1] = abi.encode(vm.addr(1)); diff --git a/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry.t.sol b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry.t.sol index 7500e04e..ccdf7f36 100644 --- a/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry.t.sol +++ b/packages/contracts/test/utils/ECDSAOwnedDKIMRegistry.t.sol @@ -24,7 +24,7 @@ contract ECDSAOwnedDKIMRegistryTest is Test { } function test_SetDKIMPublicKeyHash() public { - vm.chainId(1); + // vm.chainId(1); string memory signedMsg = registry.computeSignedMsg( registry.SET_PREFIX(), selector, @@ -47,7 +47,7 @@ contract ECDSAOwnedDKIMRegistryTest is Test { } function test_SetDKIMPublicKeyHashMultiDomain() public { - vm.chainId(1); + // vm.chainId(1); string memory signedMsg = registry.computeSignedMsg( registry.SET_PREFIX(), selector, @@ -93,7 +93,7 @@ contract ECDSAOwnedDKIMRegistryTest is Test { } function test_RevokeDKIMPublicKeyHash() public { - vm.chainId(1); + // vm.chainId(1); string memory signedMsg = registry.computeSignedMsg( registry.SET_PREFIX(), selector, @@ -133,7 +133,7 @@ contract ECDSAOwnedDKIMRegistryTest is Test { } function test_RevertIfDuplicated() public { - vm.chainId(1); + // vm.chainId(1); string memory signedMsg = registry.computeSignedMsg( registry.SET_PREFIX(), selector, @@ -166,7 +166,7 @@ contract ECDSAOwnedDKIMRegistryTest is Test { } function test_RevertIfRevorked() public { - vm.chainId(1); + // vm.chainId(1); string memory signedMsg = registry.computeSignedMsg( registry.SET_PREFIX(), selector, @@ -225,7 +225,7 @@ contract ECDSAOwnedDKIMRegistryTest is Test { } function test_RevertIfSignatureInvalid() public { - vm.chainId(1); + // vm.chainId(1); string memory signedMsg = registry.computeSignedMsg( registry.SET_PREFIX(), selector, @@ -244,30 +244,11 @@ contract ECDSAOwnedDKIMRegistryTest is Test { ); } - function test_RevertIfChainIdInvalid() public { - vm.chainId(10); - string memory signedMsg = registry.computeSignedMsg( - registry.SET_PREFIX(), - selector, - domainName, - publicKeyHash - ); - bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(2, digest); - bytes memory signature = abi.encodePacked(r, s, v); - vm.expectRevert("Invalid signature"); - registry.setDKIMPublicKeyHash( - selector, - domainName, - publicKeyHash, - signature - ); - } function test_Dfinity_Oracle_Response() public { vm.chainId(1); registry = new ECDSAOwnedDKIMRegistry( - 0x2F6e79a6E1a982a49CA248B70b02F76e921aF400 + 0x69Bec2Dd161d6Bbcc91ec32AA44D9333EBc864c0 ); selector = "20230601"; domainName = "gmail.com"; @@ -277,7 +258,7 @@ contract ECDSAOwnedDKIMRegistryTest is Test { domainName, publicKeyHash, vm.parseBytes( - "0x39473ba3651237ac631a099ee737aa062f8bd14c8ee22c785452d50f977d5b4477c352187fa427a3d9ab5cf6b2c37b49670018523a4de753406fe442bef720ef1b" + "0xe5fb9c45bd6468877e8ec7e04063b03e8ac89206354060e757b15d6269f7754e6c515b5825fbb6be4e939f92d1ad62dc7f548607fe4349033ed51f8da8a18c4c1c" ) ); require( From f0f0d4c2bac5ce03eb9c5518ee27430e6c37c5f1 Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Wed, 20 Mar 2024 02:46:30 +0900 Subject: [PATCH 19/42] Refactor EmailAuth contracts. --- .../contracts/script/DeployEmailAuth.s.sol | 52 ++---- packages/contracts/src/EmailAuth.sol | 128 +++++---------- .../contracts/src/libraries/DecimalUtils.sol | 84 ++++++++++ .../contracts/src/libraries/SubjectUtils.sol | 134 ++++++++++++++++ .../contracts/src/utils/Groth16Verifier.sol | 148 +++++++++--------- packages/contracts/src/utils/Verifier.sol | 4 + packages/contracts/test/EmailAuth.t.sol | 9 +- 7 files changed, 358 insertions(+), 201 deletions(-) create mode 100644 packages/contracts/src/libraries/DecimalUtils.sol create mode 100644 packages/contracts/src/libraries/SubjectUtils.sol diff --git a/packages/contracts/script/DeployEmailAuth.s.sol b/packages/contracts/script/DeployEmailAuth.s.sol index 65d4094b..a20f90bd 100644 --- a/packages/contracts/script/DeployEmailAuth.s.sol +++ b/packages/contracts/script/DeployEmailAuth.s.sol @@ -13,51 +13,33 @@ contract DeployEmailAuth is Script { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + if (deployerPrivateKey == 0) { + console.log("PRIVATE_KEY env var not set"); + return; + } vm.startBroadcast(deployerPrivateKey); // Deploy DKIM registry + address signer = vm.envAddress("SIGNER"); + if (signer == address(0)) { + console.log("SIGNER env var not set"); + return; + } ECDSAOwnedDKIMRegistry dkim = new ECDSAOwnedDKIMRegistry( - vm.addr(deployerPrivateKey) - ); - string memory selector = vm.envString("SELECTOR"); - string memory domainName = vm.envString("DOMAIN_NAME"); - bytes32 publicKeyHash = vm.envBytes32("PUBLIC_KEY_HASH"); - - string memory signedMsg = dkim.computeSignedMsg( - dkim.SET_PREFIX(), - selector, - domainName, - publicKeyHash - ); - bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(deployerPrivateKey, digest); - bytes memory signature = abi.encodePacked(r, s, v); - dkim.setDKIMPublicKeyHash( - selector, - domainName, - publicKeyHash, - signature + signer ); + console.log("ECDSAOwnedDKIMRegistry deployed at: %s", address(dkim)); - // Create Verifier + // Deploy Verifier Verifier verifier = new Verifier(); - bytes32 accountSalt = vm.envBytes32("ACCOUNT_SALT"); + console.log("ECDSAOwnedDKIMRegistry deployed at: %s", address(verifier)); + - // Create EmailAuth - EmailAuth emailAuth = new EmailAuth(accountSalt); + // Deploy EmailAuth + EmailAuth emailAuth = new EmailAuth(); + console.log("EmailAuth deployed at: %s", address(emailAuth)); emailAuth.updateVerifier(address(verifier)); emailAuth.updateDKIMRegistry(address(dkim)); - - // Insert first subject template - uint256 templateId = 1; - string[] memory subjectTemplate = new string[](5); - subjectTemplate[0] = "Send"; - subjectTemplate[1] = "{decimals}"; - subjectTemplate[2] = "ETH"; - subjectTemplate[3] = "to"; - subjectTemplate[4] = "{string}"; - emailAuth.insertSubjectTemplate(templateId, subjectTemplate); - vm.stopBroadcast(); } } diff --git a/packages/contracts/src/EmailAuth.sol b/packages/contracts/src/EmailAuth.sol index 36b654b4..17b3b537 100644 --- a/packages/contracts/src/EmailAuth.sol +++ b/packages/contracts/src/EmailAuth.sol @@ -4,9 +4,10 @@ pragma solidity ^0.8.12; import {EmailProof} from "./utils/Verifier.sol"; import {ECDSAOwnedDKIMRegistry} from "./utils/ECDSAOwnedDKIMRegistry.sol"; import {Verifier} from "./utils/Verifier.sol"; +import {SubjectUtils} from "./libraries/SubjectUtils.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.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"; struct EmailAuthMsg { uint templateId; @@ -15,19 +16,21 @@ struct EmailAuthMsg { EmailProof proof; } -contract EmailAuth { - address owner; - bytes32 accountSalt; - ECDSAOwnedDKIMRegistry dkim; - Verifier verifier; - mapping(uint => string[]) subjectTemplates; - mapping(bytes32 => bytes32) authedHash; - uint lastTimestamp; - mapping(bytes32 => bool) usedNullifiers; - bool timestampCheckEnabled; - - constructor(bytes32 _accountSalt) { - owner = msg.sender; +contract EmailAuth is OwnableUpgradeable, UUPSUpgradeable { + bytes32 public accountSalt; + ECDSAOwnedDKIMRegistry public dkim; + Verifier public verifier; + mapping(uint => string[]) public subjectTemplates; + mapping(bytes32 => bytes32) public authedHash; + uint public lastTimestamp; + mapping(bytes32 => bool) public usedNullifiers; + bool public timestampCheckEnabled; + + constructor() {} + + /// @notice Initialize the contract + function initialize(bytes32 _accountSalt) public initializer { + __Ownable_init(); accountSalt = _accountSalt; timestampCheckEnabled = true; } @@ -40,8 +43,7 @@ contract EmailAuth { return address(verifier); } - function updateDKIMRegistry(address _dkimRegistryAddr) public { - require(msg.sender == owner, "only owner can update dkim registry"); + function updateDKIMRegistry(address _dkimRegistryAddr) public onlyOwner { require( _dkimRegistryAddr != address(0), "invalid dkim registry address" @@ -49,8 +51,7 @@ contract EmailAuth { dkim = ECDSAOwnedDKIMRegistry(_dkimRegistryAddr); } - function updateVerifier(address _verifierAddr) public { - require(msg.sender == owner, "only owner can update verifier"); + function updateVerifier(address _verifierAddr) public onlyOwner { require(_verifierAddr != address(0), "invalid verifier address"); verifier = Verifier(_verifierAddr); } @@ -59,7 +60,6 @@ contract EmailAuth { uint _templateId, string[] memory _subjectTemplate ) public { - require(msg.sender == owner, "only owner can insert subject template"); require(_subjectTemplate.length > 0, "subject template is empty"); require( subjectTemplates[_templateId].length == 0, @@ -71,8 +71,7 @@ contract EmailAuth { function updateSubjectTemplate( uint _templateId, string[] memory _subjectTemplate - ) public { - require(msg.sender == owner, "only owner can update subject template"); + ) public onlyOwner { require(_subjectTemplate.length > 0, "subject template is empty"); require( subjectTemplates[_templateId].length > 0, @@ -81,8 +80,7 @@ contract EmailAuth { subjectTemplates[_templateId] = _subjectTemplate; } - function deleteSubjectTemplate(uint _templateId) public { - require(msg.sender == owner, "only owner can delete subject template"); + function deleteSubjectTemplate(uint _templateId) public onlyOwner { require( subjectTemplates[_templateId].length > 0, "template id not exists" @@ -109,8 +107,7 @@ contract EmailAuth { function authEmail( EmailAuthMsg memory emailAuthMsg - ) public returns (bytes32) { - require(msg.sender == owner, "only owner can auth email"); + ) public onlyOwner returns (bytes32) { string[] memory template = subjectTemplates[emailAuthMsg.templateId]; require(template.length > 0, "template id not exists"); require( @@ -124,78 +121,23 @@ contract EmailAuth { usedNullifiers[emailAuthMsg.proof.emailNullifier] == false, "email nullifier already used" ); - usedNullifiers[emailAuthMsg.proof.emailNullifier] = true; require( accountSalt == emailAuthMsg.proof.accountSalt, "invalid account salt" ); require( - emailAuthMsg.proof.timestamp > 0 || + timestampCheckEnabled == false || + emailAuthMsg.proof.timestamp == 0 || emailAuthMsg.proof.timestamp > lastTimestamp, "invalid timestamp" ); - lastTimestamp = emailAuthMsg.proof.timestamp; + // Construct an expectedSubject from template and the values of emailAuthMsg.subjectParams. - string memory expectedSubject; - uint8 nextParamIndex = 0; - string memory stringParam; - bool isParamExist; - for (uint8 i = 0; i < template.length; i++) { - isParamExist = true; - if (Strings.equal(template[i], "{string}")) { - string memory param = abi.decode( - emailAuthMsg.subjectParams[nextParamIndex], - (string) - ); - stringParam = param; - } else if (Strings.equal(template[i], "{uint}")) { - uint256 param = abi.decode( - emailAuthMsg.subjectParams[nextParamIndex], - (uint256) - ); - stringParam = Strings.toString(param); - } else if (Strings.equal(template[i], "{int}")) { - int256 param = abi.decode( - emailAuthMsg.subjectParams[nextParamIndex], - (int256) - ); - stringParam = Strings.toString(param); - } else if (Strings.equal(template[i], "{decimals}")) { - uint256 param = abi.decode( - emailAuthMsg.subjectParams[nextParamIndex], - (uint256) - ); - stringParam = Strings.toString(param); - } else if (Strings.equal(template[i], "{decimals}")) { - uint256 param = abi.decode( - emailAuthMsg.subjectParams[nextParamIndex], - (uint256) - ); - stringParam = Strings.toString(param); - } else if (Strings.equal(template[i], "{ethAddr}")) { - address param = abi.decode( - emailAuthMsg.subjectParams[nextParamIndex], - (address) - ); - stringParam = Strings.toHexString(param); - } else { - isParamExist = false; - stringParam = template[i]; - } - - if (i > 0) { - expectedSubject = string( - abi.encodePacked(expectedSubject, " ") - ); - } - expectedSubject = string( - abi.encodePacked(expectedSubject, stringParam) - ); - if (isParamExist) { - nextParamIndex++; - } - } + string memory expectedSubject = SubjectUtils.computeExpectedSubject( + emailAuthMsg.subjectParams, + template + ); string memory trimmedMaskedSubject = removePrefix( emailAuthMsg.proof.maskedSubject, emailAuthMsg.skipedSubjectPrefix @@ -220,6 +162,8 @@ contract EmailAuth { authedHash[emailAuthMsg.proof.emailNullifier] == bytes32(0), "email already authed" ); + usedNullifiers[emailAuthMsg.proof.emailNullifier] = true; + lastTimestamp = emailAuthMsg.proof.timestamp; authedHash[emailAuthMsg.proof.emailNullifier] = msgHash; return msgHash; @@ -237,6 +181,14 @@ contract EmailAuth { } } + function setTimestampCheckEnabled(bool _enabled) public onlyOwner { + timestampCheckEnabled = _enabled; + } + + /// @notice Upgrade the implementation of the proxy + /// @param newImplementation Address of the new implementation + function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} + function removePrefix( string memory str, uint numChars diff --git a/packages/contracts/src/libraries/DecimalUtils.sol b/packages/contracts/src/libraries/DecimalUtils.sol new file mode 100644 index 00000000..2669bf7c --- /dev/null +++ b/packages/contracts/src/libraries/DecimalUtils.sol @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +import "@openzeppelin/contracts/utils/Strings.sol"; + +/// @title DecimalUtils +/// @notice DecimalUtils library for converting uint256 to string with decimal places +library DecimalUtils { + /// @notice Convert uint256 to human readable string with decimal places + /// @param value uint256 value to convert + /// @return string representation of value with decimal places + function uintToDecimalString(uint256 value) public pure returns (string memory) { + return uintToDecimalString(value, 18); + } + + /// @notice Convert uint256 to human readable string with decimal places + /// @param value uint256 value to convert + /// @param decimal number of decimal places + /// @return string representation of value with decimal places + function uintToDecimalString(uint256 value, uint decimal) public pure returns (string memory) { + // Convert value to string in wei format (no decimals) + bytes memory valueBytes = bytes(Strings.toString(value)); + uint8 valueLength = uint8(valueBytes.length); + + // Create result array with max length + // If less than 18 decimals, then 2 extra for "0.", otherwise one extra for "." + bytes memory result = new bytes(valueLength > decimal ? valueLength + 1 : decimal + 2); + uint8 resultLength = uint8(result.length); + + // We will be populating result array by copying from value array from last to first index + // Difference between result and value array index when copying + // If more than 18, then 1 index diff for ".", otherwise actual diff in length + uint delta = valueLength > decimal ? 1 : resultLength - valueLength; + + // Boolean to indicate if we found a non-zero digit when scanning from last to first index + bool foundNonZeroDecimal; + + uint8 actualResultLen = 0; + + // In each iteration we fill one index of result array (starting from end) + for (uint8 i = resultLength - 1; i >= 0; i--) { + // Check if we have reached the index where we need to add decimal point + if (i == resultLength - decimal - 1) { + // No need to add "." if there was no value in decimal places + if (foundNonZeroDecimal) { + result[i] = "."; + actualResultLen++; + } + // Set delta to 0, as we have already added decimal point (only for valueLength > 18) + delta = 0; + } + // If valueLength < 18 and we have copied everything, fill zeros + else if (valueLength <= decimal && i < resultLength - valueLength) { + result[i] = "0"; + actualResultLen++; + } + // If non-zero decimal is found, or decimal point inserted (delta == 0), copy from value array + else if (foundNonZeroDecimal || delta == 0) { + result[i] = valueBytes[i - delta]; + actualResultLen++; + } + // If we find non-zero decumal for the first time (trailing zeros are skipped) + else if (valueBytes[i - delta] != "0") { + result[i] = valueBytes[i - delta]; + actualResultLen++; + foundNonZeroDecimal = true; + } + + // To prevent the last i-- underflow + if (i == 0) { + break; + } + } + + // Create final result array with correct length + bytes memory compactResult = new bytes(actualResultLen); + for (uint8 i = 0; i < actualResultLen; i++) { + compactResult[i] = result[i]; + } + + return string(compactResult); + } +} + diff --git a/packages/contracts/src/libraries/SubjectUtils.sol b/packages/contracts/src/libraries/SubjectUtils.sol new file mode 100644 index 00000000..0ab73f52 --- /dev/null +++ b/packages/contracts/src/libraries/SubjectUtils.sol @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.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"; + +library SubjectUtils { + bytes16 private constant LOWER_HEX_DIGITS = "0123456789abcdef"; + bytes16 private constant UPPER_HEX_DIGITS = "0123456789ABCDEF"; + string public constant STRING_MATCHER = "{string}"; + string public constant UINT_MATCHER = "{uint}"; + string public constant INT_MATCHER = "{int}"; + string public constant DECIMALS_MATCHER = "{decimals}"; + string public constant ETH_ADDR_MATCHER = "{ethAddr}"; + + function addressToChecksumHexString(address addr) internal pure returns (string memory) { + string memory lowerCaseAddrWithOx = Strings.toHexString(addr); + + bytes memory lowerCaseAddr = new bytes(40); // Remove 0x added by the OZ lib + for (uint8 i = 2; i < 42; i++) { + lowerCaseAddr[i - 2] = bytes(lowerCaseAddrWithOx)[i]; + } + + // Hash of lowercase addr + uint256 lowerCaseHash = uint256(keccak256(abi.encodePacked(lowerCaseAddr))); + + // Result hex = 42 chars with 0x prefix + bytes memory result = new bytes(42); + result[0] = "0"; + result[1] = "x"; + + // Shift 24 bytes (96 bits) to the right; as we only need first 20 bytes of the hash to compare + lowerCaseHash >>= 24 * 4; + + uint256 intAddr = uint256(uint160(addr)); + + for (uint8 i = 41; i > 1; --i) { + uint8 hashChar = uint8(lowerCaseHash & 0xf); // Get last char of the hex + uint8 addrChar = uint8(intAddr & 0xf); // Get last char of the address + + if (hashChar >= 8) { + result[i] = UPPER_HEX_DIGITS[addrChar]; + } else { + result[i] = LOWER_HEX_DIGITS[addrChar]; + } + + // Remove last char from both hash and addr + intAddr >>= 4; + lowerCaseHash >>= 4; + } + + return string(result); + } + + /// @notice Convert bytes to hex string without 0x prefix + /// @param data bytes to convert + function bytesToHexString(bytes memory data) public pure returns (string memory) { + bytes memory hexChars = "0123456789abcdef"; + bytes memory hexString = new bytes(2 * data.length); + + for (uint256 i = 0; i < data.length; i++) { + uint256 value = uint256(uint8(data[i])); + hexString[2 * i] = hexChars[value >> 4]; + hexString[2 * i + 1] = hexChars[value & 0xf]; + } + + 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 + function computeExpectedSubject( + bytes[] memory subjectParams, + string[] memory template + ) public view returns (string memory expectedSubject) { + // Construct an expectedSubject from template and the values of emailAuthMsg.subjectParams. + uint8 nextParamIndex = 0; + string memory stringParam; + bool isParamExist; + for (uint8 i = 0; i < template.length; i++) { + isParamExist = true; + if (Strings.equal(template[i], STRING_MATCHER)) { + string memory param = abi.decode( + subjectParams[nextParamIndex], + (string) + ); + stringParam = param; + } else if (Strings.equal(template[i], UINT_MATCHER)) { + uint256 param = abi.decode( + subjectParams[nextParamIndex], + (uint256) + ); + stringParam = Strings.toString(param); + } else if (Strings.equal(template[i], INT_MATCHER)) { + int256 param = abi.decode( + subjectParams[nextParamIndex], + (int256) + ); + stringParam = Strings.toString(param); + } else if (Strings.equal(template[i], DECIMALS_MATCHER)) { + uint256 param = abi.decode( + subjectParams[nextParamIndex], + (uint256) + ); + stringParam = DecimalUtils.uintToDecimalString(param); + } else if (Strings.equal(template[i], ETH_ADDR_MATCHER)) { + address param = abi.decode( + subjectParams[nextParamIndex], + (address) + ); + stringParam = addressToChecksumHexString(param); + } else { + isParamExist = false; + stringParam = template[i]; + } + + if (i > 0) { + expectedSubject = string( + abi.encodePacked(expectedSubject, " ") + ); + } + expectedSubject = string( + abi.encodePacked(expectedSubject, stringParam) + ); + if (isParamExist) { + nextParamIndex++; + } + } + return expectedSubject; + } +} diff --git a/packages/contracts/src/utils/Groth16Verifier.sol b/packages/contracts/src/utils/Groth16Verifier.sol index 7834aaa5..a6960d33 100644 --- a/packages/contracts/src/utils/Groth16Verifier.sol +++ b/packages/contracts/src/utils/Groth16Verifier.sol @@ -37,116 +37,116 @@ contract Groth16Verifier { uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930; - uint256 constant deltax1 = 10954366828219920598275631511874109139704726399812948670801940368943621648319; - uint256 constant deltax2 = 21324907562351316234232877683468151501516381985392872741645251279204064702931; - uint256 constant deltay1 = 18482258673210683573944019122601559566291977892508024479883530881997647434509; - uint256 constant deltay2 = 7722038556480149325085286096508221352261199536637674464951808613229560436306; + uint256 constant deltax1 = 19378677032800300253321765128070207344114232849596143606479382519857822848179; + uint256 constant deltax2 = 960493340684006291780639907740521128124066371578611670456259231950112608856; + uint256 constant deltay1 = 707321561242641502318247120686044129733961936778425747245592502022561588706; + uint256 constant deltay2 = 906648798918687791528309058870559612016450056396136091661128832168522104024; - uint256 constant IC0x = 16574539456559230992114437405247020869688093066008885296935800431598549754271; - uint256 constant IC0y = 6582170259246930443472445853193936509612913397968208942995206335313256772669; + uint256 constant IC0x = 11403395364844092073898287051441590269639035349832801575305448956555898189485; + uint256 constant IC0y = 7987377098002512490363489065894235810124910190689297467975733407897650124274; - uint256 constant IC1x = 4808179402447708287615521894566707949385656351330115478568410932828626133498; - uint256 constant IC1y = 11192780342767924659813011397631422217139241141887946338221685389313294137055; + uint256 constant IC1x = 19970349493151374875793850465364756216296859365106448163304043498653868948396; + uint256 constant IC1y = 7354947324833629681703491741404690151441837591196879347510104098513538563939; - uint256 constant IC2x = 18712536455113401242166725599926018227501537410696163371186150287407884159274; - uint256 constant IC2y = 8226363004699024636907935712886376534070525223104886495035434945963431550677; + uint256 constant IC2x = 6601321659792123150661728200330654029751433638096639327003776678899256405065; + uint256 constant IC2y = 5787025801944802546755634709739964131395447580769563006453319565215699737152; - uint256 constant IC3x = 5525728767826740479533632158517879343874633641133067193231828149796323926074; - uint256 constant IC3y = 20216889476420837287462963482510441738183094399866480033686966677531230112199; + uint256 constant IC3x = 14786441504972962102595252435524938360766818272311031519783302127874034635598; + uint256 constant IC3y = 7263574437900534125825733162428932803295530168406366964719997184009491498667; - uint256 constant IC4x = 19009979743068783710183513981562006201043554087798187683149723640538489369795; - uint256 constant IC4y = 18380837042735451429820313470655035539984045901261307868989520583690420329553; + uint256 constant IC4x = 19375830445311358980282436806871584323322276448079881638691559240245282530721; + uint256 constant IC4y = 17318811088837838309059961808619142218183737694662955481260362152107708083062; - uint256 constant IC5x = 11800021613302746315078345266979727253441303523217844358758776404934621284969; - uint256 constant IC5y = 5552627847190879688690884947875949286679127676579489026263183051950936911049; + uint256 constant IC5x = 3908227178212770389553921608205338222911059589553208283649167492849523282345; + uint256 constant IC5y = 8243748932599724059484995795741695102111754510915071330829401474670457928650; - uint256 constant IC6x = 20536313306009874074947145053719820749486870997381336862627487580013565559491; - uint256 constant IC6y = 12711313804499722236550904237548158455754474168988617941571547442976063920096; + uint256 constant IC6x = 15439278021703347151433503379992310851576978215602018333651893780355077291845; + uint256 constant IC6y = 21638430297043622123317246766715330304056281051508740200264186302710354377616; - uint256 constant IC7x = 4425936472530441395965884686031324525711609773170148186646244452200283229770; - uint256 constant IC7y = 1061595758657853301857389925101009636892064733255307544748906042618704434338; + uint256 constant IC7x = 12614103461207067723818290400900871937981485144306233479485282703564757523327; + uint256 constant IC7y = 2737120747640126912662625084039805926692259047896278598795372237156151273318; - uint256 constant IC8x = 10155875897728692253686193239509851911589650992390316926220239966489856356772; - uint256 constant IC8y = 4676487083958629767906177287440562921261522549855724753069050267462738267779; + uint256 constant IC8x = 15301183870052143551620186414376410062664451990889671784420365756444494392325; + uint256 constant IC8y = 4650698488466967485773224735285319520384787418399204639031566674273247603131; - uint256 constant IC9x = 18076733756169415004280419895754337255912979161476160233820383214343559136951; - uint256 constant IC9y = 3377508909700546665496110592578574506519316225484513731414363569931925595195; + uint256 constant IC9x = 21754156616385732298740390360467956414568776103529844468119786993545110783064; + uint256 constant IC9y = 16184446846961693609726275447321514238507287886109687792410351138135250274144; - uint256 constant IC10x = 11317008030217376109539821911712933985761704961144063824128630759333709243087; - uint256 constant IC10y = 13668899703039526880112748721387422884601240691268823176766576494982141347695; + uint256 constant IC10x = 244135444354636500241781120121461553791792444355025240108322368710180522317; + uint256 constant IC10y = 2502520855082041491808837191614596123009056536282647176762486196242326912440; - uint256 constant IC11x = 11359204960157932631830970637444237245788114829005994332310082943451608645555; - uint256 constant IC11y = 2334190495452324539987241351284112610318709408508174260330115582687913867496; + uint256 constant IC11x = 21775882581895783644266592948550034589672533233069670861804731728949339352238; + uint256 constant IC11y = 11881400815743694635896824745111667035477824478303686605652795964490344532799; - uint256 constant IC12x = 2975987120379426805902369720367344369451564971704354145292338140239197186222; - uint256 constant IC12y = 14594242469123473606225997914332954438390194577664627818897197983478341158452; + uint256 constant IC12x = 3312179889940052232204751898979833097517557003027876142751774737404346769486; + uint256 constant IC12y = 21374632894304888129661426640165240436413284427338075262260399838612492997131; - uint256 constant IC13x = 4018148902220828220532669764290130744309563793380687826532671172447865135797; - uint256 constant IC13y = 16217931666978126451653431812313879837567251770943153104246176239981507546120; + uint256 constant IC13x = 7528626507625376052925073583344030864021221821172063769053410245035129716312; + uint256 constant IC13y = 9166096334755065092764176720997273246795251892031153588688410906044526198171; - uint256 constant IC14x = 15248815070804210837362123734509950517193128740321296376090017977229546434201; - uint256 constant IC14y = 20874402362039288740322295432714768850415440595261420415136594386440000805472; + uint256 constant IC14x = 6369530737509876846946090390455741937023125890510750661735149513809418509605; + uint256 constant IC14y = 9280745716541780368193317986861227250950780074033868300480845563855753398269; - uint256 constant IC15x = 184215137103263824927792083653151366961493141115507378570545194414115319597; - uint256 constant IC15y = 7046461909096292801283414654130145780333111987651719245987730429663779545861; + uint256 constant IC15x = 12558224684088018750215250798503126445875846848169703467438387530529151184093; + uint256 constant IC15y = 6438447722525942451152734025293335130203657459750071579867825017750662264543; - uint256 constant IC16x = 18080736123918754464230709936262206775388487854254198113766918476151341543386; - uint256 constant IC16y = 446148367845068015717390166805552567927596132164836881761524550251826364135; + uint256 constant IC16x = 21760172767678989053712974210946185954416464325269741202502365558511569730969; + uint256 constant IC16y = 14328555534854937419599307487887607109383935995961943164869104475259737674952; - uint256 constant IC17x = 1534340754187140859139685302587180628752162653552366187366374180697869637374; - uint256 constant IC17y = 13731129709809544498945856186890414670098540609958232916278851992053826174420; + uint256 constant IC17x = 12721450965857647842653598818060523209655807544582142503114340239875644094169; + uint256 constant IC17y = 509291315940844110919310141621160761306967491284754194278419723289372915824; - uint256 constant IC18x = 21775370689754268902887177062346511347751941867300716036906435030907493997858; - uint256 constant IC18y = 19301665077349083013097167335348111180470218240773113041527466425622049179892; + uint256 constant IC18x = 11821091968722472223052893420629266585896381860398218548505450239066680784138; + uint256 constant IC18y = 637629613665587078024011533283160236803183532182389013399718830046110157867; - uint256 constant IC19x = 11635940937217102712732048025733746892191325102263618279403588660770142333544; - uint256 constant IC19y = 8576917688887871267170119763304876045314668502343805375889313573514080036228; + uint256 constant IC19x = 15171686905454021445617486794000410115298497039166377603938555414739376699278; + uint256 constant IC19y = 9367860372950551907843497084251870484664401058060747979299880821479072333651; - uint256 constant IC20x = 20006996550547604082545176730384098459007628099012850949434822374546339451078; - uint256 constant IC20y = 4597726399930358015865174544234916364474061025590422236723625434924206785636; + uint256 constant IC20x = 13453885302087699738578768621050293444980598938635823846236227865376091470051; + uint256 constant IC20y = 4114932099627848758644340520348411173109495028640015773993131575914340470444; - uint256 constant IC21x = 3114468224969205430464146710478841067496946923476998513793771645186102267319; - uint256 constant IC21y = 9742761368401377432169043503063016638695625132157325258951119245133312122816; + uint256 constant IC21x = 7816164550596800024128197318709984983746028547286775312210385941824772819678; + uint256 constant IC21y = 11907598145362082980231488040519763420460629270042988114575694207123419480799; - uint256 constant IC22x = 10555368626644151934153186988613070223665152831331536461802480468633324065205; - uint256 constant IC22y = 20624044651064953699623026914245314987310012387502388011971209808272542829304; + uint256 constant IC22x = 7026291121711518717885133396634431504702598004699717987639781623426372406068; + uint256 constant IC22y = 2934217034199305782699570943807041161901569272146498895183569827812876684414; - uint256 constant IC23x = 5070128471248818670932373963274320409840160095469390573692364137256773403970; - uint256 constant IC23y = 12110776441003724768993603161572065610467199076615091939124262227064046870129; + uint256 constant IC23x = 5696885153673563482639795878703782890060885577257079837208380543842190305806; + uint256 constant IC23y = 17677490074850382391167178977789148501419703191123700226733359751191884925088; - uint256 constant IC24x = 5266755028714022754912427866871744256558467716512468087980728393513375234252; - uint256 constant IC24y = 19316881479947876252903121663642174330739742638830832989972224412643455143650; + uint256 constant IC24x = 2611683639773662474624629722305165059188459747093556135898769696357331487500; + uint256 constant IC24y = 10044388249493140225865522073559488567982324265722702513571966586506538669872; - uint256 constant IC25x = 19628930876339427854052779075324970269342889362578340399919157892524940741022; - uint256 constant IC25y = 2088966831699507424008771862026864014133676222322627395317071588352669541963; + uint256 constant IC25x = 5214009542610232932442041067813113650632680623992721376070046067376709227182; + uint256 constant IC25y = 10185071351439460276090510663428745483434923234173869867480387557540646341686; - uint256 constant IC26x = 20285762967755833379099368754997171672301375701365680387318890775289094404239; - uint256 constant IC26y = 20993214094593506472331818213515185351280861846089320315513952592305315803407; + uint256 constant IC26x = 4636491635078988706441689757212385869973641936706839840615699323767584705656; + uint256 constant IC26y = 5385588163483057776915996860882717516859067158972572817291591123171461874905; - uint256 constant IC27x = 10057583801221855541500288051363216180893138868799874225904852728382088360422; - uint256 constant IC27y = 5386421598799472841467457846905224899181603094154111536494760519350528533278; + uint256 constant IC27x = 18705809007834830886982817327652431135135881045537983411955656556286258722805; + uint256 constant IC27y = 15760086357718846365304413904138098736915444207916507230376426657348004828234; - uint256 constant IC28x = 16473463128623172053697682047994279770229908199497842325911299171923014826977; - uint256 constant IC28y = 21288160761716596278540023630063748972307384453836431950624496039826334131669; + uint256 constant IC28x = 19182077652075606448764076721233989088126556417897799020951367435544174328839; + uint256 constant IC28y = 9136270306453077808755194696108953703001292400385038364957275580855848746843; - uint256 constant IC29x = 21638131594863716614157629605463585179360468401086649311699156897876753941800; - uint256 constant IC29y = 16427641097716660394929990103203425443660595164319793354629895015304577827072; + uint256 constant IC29x = 18485427693577943108144538953927906684343832918965223721720202393052827398914; + uint256 constant IC29y = 18575738887044959080624252642810238700989315891377197214187365412313209252763; - uint256 constant IC30x = 15006616093026265455921487202440896059163943612341058809212643108696803693949; - uint256 constant IC30y = 21639729012202301859145061736309269905820646014674250972917770681197873837674; + uint256 constant IC30x = 4223202583040339035072354022171586822138322889663701017950037645370876520845; + uint256 constant IC30y = 11856130485182396243929365545262884496878630681794480179341681754292009988063; - uint256 constant IC31x = 5637017587583037775855444353964065840763219389682518196250998291229767189452; - uint256 constant IC31y = 19708998051076531356994075801477289284024748787022499630790823127153597801746; + uint256 constant IC31x = 19407812422219942955336266485712702970841716137575998392385328696244122346627; + uint256 constant IC31y = 6785055681044554372605737518388942189987917619986273461429790568638918699867; - uint256 constant IC32x = 11786412624601698177573137563308552293229122392470949009030209663634360959100; - uint256 constant IC32y = 3525006067419153997466506573185539981981981404726200464981456451320393135138; + uint256 constant IC32x = 14993212179101104565462829595748725448512808800293815566424165418121053284398; + uint256 constant IC32y = 4083889862604497566428910703229716185418233528250337149121364790918693829394; - uint256 constant IC33x = 8842915247240519087491681345580464704990637853851632260749029221862964993204; - uint256 constant IC33y = 6912129862210202429284336963804844266574743113814701231899003687391563954678; + uint256 constant IC33x = 19535193266806328470942118649012700164578795620538913542594738691400891335098; + uint256 constant IC33y = 12775783114117041065841750751628812939076814753172334426229780042733013690673; - uint256 constant IC34x = 11122508802234453254655719684600485291093997375492900313852970247412543996812; - uint256 constant IC34y = 13743597114991162899240697983131925316352407102889585180432451035712663718087; + uint256 constant IC34x = 3062181060286810160747070144635312664862371094982947559639250577939387406466; + uint256 constant IC34y = 4596414785886448742196272188716315360063739806767099479393366426606524993331; // Memory data diff --git a/packages/contracts/src/utils/Verifier.sol b/packages/contracts/src/utils/Verifier.sol index 2fe79b6f..e9ecd2f2 100644 --- a/packages/contracts/src/utils/Verifier.sol +++ b/packages/contracts/src/utils/Verifier.sol @@ -22,6 +22,10 @@ contract Verifier { uint256 public constant SUBJECT_FIELDS = 20; uint256 public constant SUBJECT_BYTES = 605; + constructor() { + groth16Verifier = new Groth16Verifier(); + } + function verifyEmailProof( EmailProof memory proof ) public view returns (bool) { diff --git a/packages/contracts/test/EmailAuth.t.sol b/packages/contracts/test/EmailAuth.t.sol index 7e544924..0d8f4a14 100644 --- a/packages/contracts/test/EmailAuth.t.sol +++ b/packages/contracts/test/EmailAuth.t.sol @@ -54,13 +54,14 @@ contract EmailAuthTest is Test { accountSalt = 0x2c3abbf3d1171bfefee99c13bf9c47f1e8447576afd89096652a34f27b297971; // Create EmailAuth - emailAuth = new EmailAuth(accountSalt); + emailAuth = new EmailAuth(); emailAuth.updateVerifier(address(verifier)); emailAuth.updateDKIMRegistry(address(dkim)); - templateId = 1; - subjectTemplate = ["Send", "{decimals}", "ETH", "to", "{string}"]; - newSubjectTemplate = ["Send", "{decimals}", "USDC", "to", "{string}"]; + uint templateIdx = 1; + templateId = uint256(keccak256(abi.encodePacked("TEST", templateIdx))); + subjectTemplate = ["Send", "{decimals}", "ETH", "to", "{ethAddr}"]; + newSubjectTemplate = ["Send", "{decimals}", "USDC", "to", "{ethAddr}"]; } function testDkimRegistryAddr() public { From 1ec9ca75f9ca56048021cc13e841595854f0e0d0 Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Wed, 20 Mar 2024 03:09:47 +0900 Subject: [PATCH 20/42] Refactor EmailAccountRecovery. --- .../contracts/src/EmailAccountRecovery.sol | 88 ++++++++++++------- .../contracts/src/libraries/SubjectUtils.sol | 2 +- .../src/utils/ECDSAOwnedDKIMRegistry.sol | 2 +- 3 files changed, 59 insertions(+), 33 deletions(-) diff --git a/packages/contracts/src/EmailAccountRecovery.sol b/packages/contracts/src/EmailAccountRecovery.sol index b2ee2845..8dbb7eac 100644 --- a/packages/contracts/src/EmailAccountRecovery.sol +++ b/packages/contracts/src/EmailAccountRecovery.sol @@ -25,19 +25,13 @@ abstract contract EmailAccountRecovery { public view virtual - returns (string[][] memory) - { - return new string[][](0); - } + returns (string[][] memory); function recoverySubjectTemplates() public view virtual - returns (string[][] memory) - { - return new string[][](0); - } + returns (string[][] memory); function acceptGuardian( address guardian, @@ -45,6 +39,7 @@ abstract contract EmailAccountRecovery { bytes[] memory subjectParams, bytes32 emailNullifier ) public virtual; + function recoverWallet( address guardian, uint templateIdx, @@ -52,16 +47,24 @@ abstract contract EmailAccountRecovery { bytes32 emailNullifier ) public virtual; - function handleAcceptance( - EmailAuthMsg memory emailAuthMsg, - uint templateIdx - ) external { - address guardian = Create2.computeAddress( - emailAuthMsg.proof.accountSalt, - bytes32(bytes20(emailAuthImplementation())) + function computeEmailAuthAddress(bytes32 accountSalt) + public + view + returns (address) + { + return Create2.computeAddress( + accountSalt, + keccak256(abi.encodePacked( + type(ERC1967Proxy).creationCode, + abi.encode(emailAuthImplementation(), abi.encodeCall(EmailAuth.initialize, (accountSalt))) + )) ); - require(Address.isContract(guardian), "guardian is not deployed"); - uint templateId = uint256( + } + + function computeAcceptanceTemplateId( + uint templateIdx + ) public pure returns (uint) { + return uint256( keccak256( abi.encode( EMAIL_ACCOUNT_RECOVERY_VERSION_ID, @@ -70,28 +73,50 @@ abstract contract EmailAccountRecovery { ) ) ); + } + + function computeRecoveryTemplateId( + uint templateIdx + ) public pure returns (uint) { + return uint256( + keccak256( + abi.encode( + EMAIL_ACCOUNT_RECOVERY_VERSION_ID, + "RECOVERY", + templateIdx + ) + ) + ); + } + + function handleAcceptance( + EmailAuthMsg memory emailAuthMsg, + uint templateIdx + ) external { + address guardian = computeEmailAuthAddress(emailAuthMsg.proof.accountSalt); + require(!Address.isContract(guardian), "guardian is already deployed"); + uint templateId = computeAcceptanceTemplateId(templateIdx); require(templateId == emailAuthMsg.templateId, "invalid template id"); require(emailAuthMsg.proof.isCodeExist == true, "isCodeExist is false"); - // Deploy proxy - ERC1967Proxy proxy = new ERC1967Proxy( - address(emailAuthImplementation()), - abi.encode(dkim(), verifier()) + // Deploy proxy of the guardian's EmailAuth contract + ERC1967Proxy proxy = new ERC1967Proxy{salt: emailAuthMsg.proof.accountSalt}( + emailAuthImplementation(), + abi.encodeCall(EmailAuth.initialize, (emailAuthMsg.proof.accountSalt)) ); - EmailAuth newEmailAuth = EmailAuth(payable(address(proxy))); - EmailAuth guardianEmailAuth = EmailAuth(payable(address(guardian))); - - for (uint i = 0; i < acceptanceSubjectTemplates().length; i++) { + EmailAuth guardianEmailAuth = EmailAuth(address(proxy)); + guardianEmailAuth.updateDKIMRegistry(dkim()); + guardianEmailAuth.updateVerifier(verifier()); + for (uint idx = 0; idx < acceptanceSubjectTemplates().length; idx++) { guardianEmailAuth.insertSubjectTemplate( - i, - acceptanceSubjectTemplates()[i] + computeAcceptanceTemplateId(idx), + acceptanceSubjectTemplates()[idx] ); } - - for (uint i = 0; i < recoverySubjectTemplates().length; i++) { + for (uint idx = 0; idx < recoverySubjectTemplates().length; idx++) { guardianEmailAuth.insertSubjectTemplate( - i, - acceptanceSubjectTemplates()[i] + computeRecoveryTemplateId(idx), + acceptanceSubjectTemplates()[idx] ); } @@ -140,4 +165,5 @@ abstract contract EmailAccountRecovery { emailAuthMsg.proof.emailNullifier ); } + } diff --git a/packages/contracts/src/libraries/SubjectUtils.sol b/packages/contracts/src/libraries/SubjectUtils.sol index 0ab73f52..5e55a5f2 100644 --- a/packages/contracts/src/libraries/SubjectUtils.sol +++ b/packages/contracts/src/libraries/SubjectUtils.sol @@ -75,7 +75,7 @@ library SubjectUtils { function computeExpectedSubject( bytes[] memory subjectParams, string[] memory template - ) public view returns (string memory expectedSubject) { + ) public pure returns (string memory expectedSubject) { // Construct an expectedSubject from template and the values of emailAuthMsg.subjectParams. uint8 nextParamIndex = 0; string memory stringParam; diff --git a/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol b/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol index 5ef523c7..ba390d17 100644 --- a/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol +++ b/packages/contracts/src/utils/ECDSAOwnedDKIMRegistry.sol @@ -96,7 +96,7 @@ contract ECDSAOwnedDKIMRegistry is IDKIMRegistry { string memory selector, string memory domainName, bytes32 publicKeyHash - ) public view returns (string memory) { + ) public pure returns (string memory) { return string.concat( prefix, From aa48c7d7decea6d406c1d48143d24da0ba07522d Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Wed, 20 Mar 2024 04:02:10 +0900 Subject: [PATCH 21/42] Add simple wallet to be recovered with emails. --- .../contracts/src/EmailAccountRecovery.sol | 18 +-- .../contracts/test/helpers/SimpleWallet.sol | 138 ++++++++++++++++++ 2 files changed, 147 insertions(+), 9 deletions(-) create mode 100644 packages/contracts/test/helpers/SimpleWallet.sol diff --git a/packages/contracts/src/EmailAccountRecovery.sol b/packages/contracts/src/EmailAccountRecovery.sol index 8dbb7eac..8530c4e1 100644 --- a/packages/contracts/src/EmailAccountRecovery.sol +++ b/packages/contracts/src/EmailAccountRecovery.sol @@ -8,17 +8,20 @@ import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.s abstract contract EmailAccountRecovery { uint8 constant EMAIL_ACCOUNT_RECOVERY_VERSION_ID = 1; + address public verifierAddr; + address public dkimAddr; + address public emailAuthImplementationAddr; function verifier() public view virtual returns (address) { - return 0x0000000000000000000000000000000000000000; + return verifierAddr; } function dkim() public view virtual returns (address) { - return 0x0000000000000000000000000000000000000000; + return dkimAddr; } function emailAuthImplementation() public view virtual returns (address) { - return 0x0000000000000000000000000000000000000000; + return emailAuthImplementationAddr; } function acceptanceSubjectTemplates() @@ -38,14 +41,14 @@ abstract contract EmailAccountRecovery { uint templateIdx, bytes[] memory subjectParams, bytes32 emailNullifier - ) public virtual; + ) internal virtual; function recoverWallet( address guardian, uint templateIdx, bytes[] memory subjectParams, bytes32 emailNullifier - ) public virtual; + ) internal virtual; function computeEmailAuthAddress(bytes32 accountSalt) public @@ -136,10 +139,7 @@ abstract contract EmailAccountRecovery { EmailAuthMsg memory emailAuthMsg, uint templateIdx ) external { - address guardian = Create2.computeAddress( - emailAuthMsg.proof.accountSalt, - bytes32(bytes20(emailAuthImplementation())) - ); + address guardian = computeEmailAuthAddress(emailAuthMsg.proof.accountSalt); require(Address.isContract(guardian), "guardian is not deployed"); uint templateId = uint256( keccak256( diff --git a/packages/contracts/test/helpers/SimpleWallet.sol b/packages/contracts/test/helpers/SimpleWallet.sol new file mode 100644 index 00000000..2632508e --- /dev/null +++ b/packages/contracts/test/helpers/SimpleWallet.sol @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {EmailAccountRecovery} from "../../src/EmailAccountRecovery.sol"; + +contract SimpleWallet is OwnableUpgradeable, EmailAccountRecovery { + enum GuardianStatus {NONE, REQUESTED, ACCEPTED} + uint public constant TIMELOCK_PERIOD = 3 days; + + bool isRecovering; + address newSignerCandidate; + mapping(address => GuardianStatus) public guardians; + uint timelock; + + modifier onlyNotRecoveringOwner() { + require(msg.sender == owner(), "only owner"); + require(!isRecovering, "recovery in progress"); + _; + } + + /// @notice Fallback function to receive ETH + fallback() external payable { + require(!isRecovering, "recovery in progress"); + } + + /// @notice Function to receive ETH + receive() external payable { + require(!isRecovering, "recovery in progress"); + } + + constructor(address _verifier, address _dkim, address _emailAuthImplementation) { + verifierAddr = _verifier; + dkimAddr = _dkim; + emailAuthImplementationAddr = _emailAuthImplementation; + } + + function initialize() public initializer { + __Ownable_init(); + isRecovering = false; + } + + function transfer(address to, uint256 amount) public onlyNotRecoveringOwner { + require(address(this).balance >= amount, "insufficient balance"); + payable(to).transfer(amount); + } + + function withdraw(uint256 amount) public onlyNotRecoveringOwner { + transfer(msg.sender, amount); + } + + function acceptanceSubjectTemplates() + public + pure + override + returns (string[][] memory) { + string[][] memory templates = new string[][](1); + templates[0][0] = "Accept"; + templates[0][1] = "guardian"; + templates[0][2] = "request"; + templates[0][3] = "for"; + templates[0][4] = "{ethAddr}"; + return templates; + } + + function recoverySubjectTemplates() + public + pure + override + returns (string[][] memory) { + string[][] memory templates = new string[][](1); + templates[0][0] = "Set"; + templates[0][1] = "the"; + templates[0][2] = "new"; + templates[0][3] = "signer"; + templates[0][4] = "of"; + templates[0][5] = "{ethAddr}"; + templates[0][6] = "to"; + templates[0][7] = "{ethAddr}"; + return templates; + } + + function requestGuardian(address guardian) public onlyNotRecoveringOwner { + require(guardian != address(0), "invalid guardian"); + require(guardians[guardian] == GuardianStatus.NONE, "invalid guardian status"); + guardians[guardian] = GuardianStatus.REQUESTED; + } + + function acceptGuardian( + address guardian, + uint templateIdx, + bytes[] memory subjectParams, + bytes32 + ) internal override onlyNotRecoveringOwner { + require(guardian != address(0), "invalid guardian"); + require(guardians[guardian] == GuardianStatus.REQUESTED, "invalid guardian status"); + require(templateIdx == 0, "invalid template index"); + require(subjectParams.length == 1, "invalid subject params"); + (address guardianInEmail) = abi.decode(subjectParams[0], (address)); + require(guardianInEmail == guardian, "invalid guardian in email"); + guardians[guardian] = GuardianStatus.ACCEPTED; + } + + function recoverWallet( + address guardian, + uint templateIdx, + bytes[] memory subjectParams, + bytes32 + ) internal override onlyNotRecoveringOwner { + require(guardian != address(0), "invalid guardian"); + require(guardians[guardian] == GuardianStatus.ACCEPTED, "invalid guardian status"); + require(templateIdx == 0, "invalid template index"); + require(subjectParams.length == 2, "invalid subject params"); + (address guardianInEmail, address newSigner) = abi.decode(subjectParams[0], (address, address)); + require(guardianInEmail == guardian, "invalid guardian in email"); + require(newSigner != address(0), "invalid new signer"); + isRecovering = true; + newSignerCandidate = newSigner; + timelock = block.timestamp + TIMELOCK_PERIOD; + } + + function rejectRecovery() public onlyOwner { + require(isRecovering, "recovery not in progress"); + require(timelock > block.timestamp, "timelock expired"); + isRecovering = false; + newSignerCandidate = address(0); + timelock = 0; + } + + function completeRecovery() public { + require(isRecovering, "recovery not in progress"); + require(timelock <= block.timestamp, "timelock not expired"); + isRecovering = false; + timelock = 0; + _transferOwnership(newSignerCandidate); + newSignerCandidate = address(0); + } +} \ No newline at end of file From d5cc39ff151b5ee0be5783998476fba1a2fccb7f Mon Sep 17 00:00:00 2001 From: wshino Date: Wed, 20 Mar 2024 19:20:37 +0900 Subject: [PATCH 22/42] Fix EmailAuth.t.sol. --- packages/contracts/test/EmailAuth.t.sol | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/contracts/test/EmailAuth.t.sol b/packages/contracts/test/EmailAuth.t.sol index 0d8f4a14..c0d2fcc2 100644 --- a/packages/contracts/test/EmailAuth.t.sol +++ b/packages/contracts/test/EmailAuth.t.sol @@ -8,6 +8,7 @@ import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "../src/EmailAuth.sol"; import "../src/utils/Verifier.sol"; import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; contract EmailAuthTest is Test { using ECDSA for *; @@ -54,10 +55,16 @@ contract EmailAuthTest is Test { accountSalt = 0x2c3abbf3d1171bfefee99c13bf9c47f1e8447576afd89096652a34f27b297971; // Create EmailAuth - emailAuth = new EmailAuth(); + EmailAuth emailAuthImpl = new EmailAuth(); + ERC1967Proxy emailAuthProxy = new ERC1967Proxy(address(emailAuthImpl), abi.encodeCall(emailAuthImpl.initialize, + accountSalt + )); + emailAuth = EmailAuth(payable(address(emailAuthProxy))); emailAuth.updateVerifier(address(verifier)); emailAuth.updateDKIMRegistry(address(dkim)); + + uint templateIdx = 1; templateId = uint256(keccak256(abi.encodePacked("TEST", templateIdx))); subjectTemplate = ["Send", "{decimals}", "ETH", "to", "{ethAddr}"]; @@ -112,7 +119,7 @@ contract EmailAuthTest is Test { ); assertEq( msgHash, - 0xe7f92de45c5ad2716ecefebf444d57aba480764d104b92d2a1bb7820f344bb22 + 0x8fa6859241092e7cf73d038bc981b370be69b49dc7bfcd91015308ed2c72d979 ); } @@ -120,14 +127,14 @@ contract EmailAuthTest is Test { this.testInsertSubjectTemplate(); bytes[] memory subjectParams = new bytes[](2); - subjectParams[0] = abi.encode(1); - subjectParams[1] = abi.encode("alice@gmail.com"); + subjectParams[0] = abi.encode(1 ether); + subjectParams[1] = abi.encode("0x0000000000000000000000000000000000000020"); EmailProof memory emailProof = EmailProof({ domainName: "gmail.com", publicKeyHash: publicKeyHash, timestamp: 1694989812, - maskedSubject: "Send 1 ETH to alice@gmail.com", + maskedSubject: "Send 1 ETH to 0x0000000000000000000000000000000000000020", emailNullifier: emailNullifier, accountSalt: accountSalt, isCodeExist: true, @@ -152,13 +159,13 @@ contract EmailAuthTest is Test { bytes32 msgHash = emailAuth.authEmail(emailAuthMsg); assertEq( msgHash, - 0x8f11137c4bc94c224197349b9ebc44da5e5b9786d4a0117ea5794b5a90d51968 + 0x97728a843151c01762d4f116e4d630f769faceda03589271805006ab8c512bcb ); } function testIsValidSignature() public { testAuthEmail(); - bytes32 msgHash = 0x8f11137c4bc94c224197349b9ebc44da5e5b9786d4a0117ea5794b5a90d51968; + bytes32 msgHash = 0x97728a843151c01762d4f116e4d630f769faceda03589271805006ab8c512bcb; bytes memory signature = abi.encodePacked(emailNullifier); bytes4 result = emailAuth.isValidSignature(msgHash, signature); assertEq(result, bytes4(0x1626ba7e)); From f4df9d9c1224899e26755db28ffba0ee5631875c Mon Sep 17 00:00:00 2001 From: wshino Date: Wed, 20 Mar 2024 19:29:59 +0900 Subject: [PATCH 23/42] Add DeploymentHelper. --- packages/contracts/test/EmailAuth.t.sol | 62 +--------------- .../test/helpers/DeploymentHelper.sol | 73 +++++++++++++++++++ 2 files changed, 77 insertions(+), 58 deletions(-) create mode 100644 packages/contracts/test/helpers/DeploymentHelper.sol diff --git a/packages/contracts/test/EmailAuth.t.sol b/packages/contracts/test/EmailAuth.t.sol index c0d2fcc2..cab1c1f6 100644 --- a/packages/contracts/test/EmailAuth.t.sol +++ b/packages/contracts/test/EmailAuth.t.sol @@ -9,66 +9,12 @@ import "../src/EmailAuth.sol"; import "../src/utils/Verifier.sol"; import "../src/utils/ECDSAOwnedDKIMRegistry.sol"; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import "./helpers/DeploymentHelper.sol"; -contract EmailAuthTest is Test { - using ECDSA for *; - - EmailAuth emailAuth; - Verifier verifier; - ECDSAOwnedDKIMRegistry dkim; - - bytes32 accountSalt; - uint templateId; - string[] subjectTemplate; - string[] newSubjectTemplate; - bytes mockProof = abi.encodePacked(bytes1(0x01)); - - string selector = "12345"; - string domainName = "gmail.com"; - bytes32 publicKeyHash = - 0x0ea9c777dc7110e5a9e89b13f0cfc540e3845ba120b2b6dc24024d61488d4788; - bytes32 emailNullifier = - 0x00a83fce3d4b1c9ef0f600644c1ecc6c8115b57b1596e0e3295e2c5105fbfd8a; - function setUp() public { - address signer = vm.addr(1); - - // Create DKIM registry - dkim = new ECDSAOwnedDKIMRegistry(signer); - string memory signedMsg = dkim.computeSignedMsg( - dkim.SET_PREFIX(), - selector, - domainName, - publicKeyHash - ); - bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(1, digest); - bytes memory signature = abi.encodePacked(r, s, v); - dkim.setDKIMPublicKeyHash( - selector, - domainName, - publicKeyHash, - signature - ); +contract EmailAuthTest is DeploymentHelper { - // Create Verifier - verifier = new Verifier(); - accountSalt = 0x2c3abbf3d1171bfefee99c13bf9c47f1e8447576afd89096652a34f27b297971; - - // Create EmailAuth - EmailAuth emailAuthImpl = new EmailAuth(); - ERC1967Proxy emailAuthProxy = new ERC1967Proxy(address(emailAuthImpl), abi.encodeCall(emailAuthImpl.initialize, - accountSalt - )); - emailAuth = EmailAuth(payable(address(emailAuthProxy))); - emailAuth.updateVerifier(address(verifier)); - emailAuth.updateDKIMRegistry(address(dkim)); - - - - uint templateIdx = 1; - templateId = uint256(keccak256(abi.encodePacked("TEST", templateIdx))); - subjectTemplate = ["Send", "{decimals}", "ETH", "to", "{ethAddr}"]; - newSubjectTemplate = ["Send", "{decimals}", "USDC", "to", "{ethAddr}"]; + function setUp() public override{ + super.setUp(); } function testDkimRegistryAddr() public { diff --git a/packages/contracts/test/helpers/DeploymentHelper.sol b/packages/contracts/test/helpers/DeploymentHelper.sol new file mode 100644 index 00000000..84a613d4 --- /dev/null +++ b/packages/contracts/test/helpers/DeploymentHelper.sol @@ -0,0 +1,73 @@ +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; + +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import "../../src/EmailAuth.sol"; +import "../../src/utils/Verifier.sol"; +import "../../src/utils/ECDSAOwnedDKIMRegistry.sol"; +import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; + +contract DeploymentHelper is Test { + using ECDSA for *; + + EmailAuth emailAuth; + Verifier verifier; + ECDSAOwnedDKIMRegistry dkim; + + bytes32 accountSalt; + uint templateId; + string[] subjectTemplate; + string[] newSubjectTemplate; + bytes mockProof = abi.encodePacked(bytes1(0x01)); + + string selector = "12345"; + string domainName = "gmail.com"; + bytes32 publicKeyHash = + 0x0ea9c777dc7110e5a9e89b13f0cfc540e3845ba120b2b6dc24024d61488d4788; + bytes32 emailNullifier = + 0x00a83fce3d4b1c9ef0f600644c1ecc6c8115b57b1596e0e3295e2c5105fbfd8a; + + function setUp() public virtual { + address signer = vm.addr(1); + + // Create DKIM registry + dkim = new ECDSAOwnedDKIMRegistry(signer); + string memory signedMsg = dkim.computeSignedMsg( + dkim.SET_PREFIX(), + selector, + domainName, + publicKeyHash + ); + bytes32 digest = bytes(signedMsg).toEthSignedMessageHash(); + (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 = new Verifier(); + accountSalt = 0x2c3abbf3d1171bfefee99c13bf9c47f1e8447576afd89096652a34f27b297971; + + // Create EmailAuth + EmailAuth emailAuthImpl = new EmailAuth(); + ERC1967Proxy emailAuthProxy = new ERC1967Proxy(address(emailAuthImpl), abi.encodeCall(emailAuthImpl.initialize, + accountSalt + )); + emailAuth = EmailAuth(payable(address(emailAuthProxy))); + emailAuth.updateVerifier(address(verifier)); + emailAuth.updateDKIMRegistry(address(dkim)); + + + + uint templateIdx = 1; + templateId = uint256(keccak256(abi.encodePacked("TEST", templateIdx))); + subjectTemplate = ["Send", "{decimals}", "ETH", "to", "{ethAddr}"]; + newSubjectTemplate = ["Send", "{decimals}", "USDC", "to", "{ethAddr}"]; + } +} \ No newline at end of file From 1883702ff49a9be13bb1ea9ba84a88777f3c2b5e Mon Sep 17 00:00:00 2001 From: wshino Date: Wed, 20 Mar 2024 19:45:02 +0900 Subject: [PATCH 24/42] Add create SimpleWallet instance in setUp function. --- .../test/helpers/DeploymentHelper.sol | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/contracts/test/helpers/DeploymentHelper.sol b/packages/contracts/test/helpers/DeploymentHelper.sol index 84a613d4..462cfe13 100644 --- a/packages/contracts/test/helpers/DeploymentHelper.sol +++ b/packages/contracts/test/helpers/DeploymentHelper.sol @@ -7,6 +7,8 @@ import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "../../src/EmailAuth.sol"; import "../../src/utils/Verifier.sol"; import "../../src/utils/ECDSAOwnedDKIMRegistry.sol"; +import "./SimpleWallet.sol"; + import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; contract DeploymentHelper is Test { @@ -15,6 +17,7 @@ contract DeploymentHelper is Test { EmailAuth emailAuth; Verifier verifier; ECDSAOwnedDKIMRegistry dkim; + SimpleWallet simpleWallet; bytes32 accountSalt; uint templateId; @@ -56,18 +59,29 @@ contract DeploymentHelper is Test { // Create EmailAuth EmailAuth emailAuthImpl = new EmailAuth(); - ERC1967Proxy emailAuthProxy = new ERC1967Proxy(address(emailAuthImpl), abi.encodeCall(emailAuthImpl.initialize, - accountSalt - )); + ERC1967Proxy emailAuthProxy = new ERC1967Proxy( + address(emailAuthImpl), + abi.encodeWithSelector(emailAuthImpl.initialize.selector, accountSalt) + ); emailAuth = EmailAuth(payable(address(emailAuthProxy))); emailAuth.updateVerifier(address(verifier)); emailAuth.updateDKIMRegistry(address(dkim)); - - uint templateIdx = 1; templateId = uint256(keccak256(abi.encodePacked("TEST", templateIdx))); subjectTemplate = ["Send", "{decimals}", "ETH", "to", "{ethAddr}"]; newSubjectTemplate = ["Send", "{decimals}", "USDC", "to", "{ethAddr}"]; + + // Create SimpleWallet as EmailAccountRecovery implementation + SimpleWallet simpleWalletImpl = new SimpleWallet( + address(verifier), + address(dkim), + address(emailAuth) + ); + ERC1967Proxy simpleWalletProxy = new ERC1967Proxy( + address(simpleWalletImpl), + abi.encodeWithSelector(simpleWalletImpl.initialize.selector) + ); + simpleWallet = SimpleWallet(payable(address(simpleWalletProxy))); } -} \ No newline at end of file +} From 7ef11637f05368e31540105c6b55e9afd880c19a Mon Sep 17 00:00:00 2001 From: wshino Date: Wed, 20 Mar 2024 22:25:14 +0900 Subject: [PATCH 25/42] Add test EmailAccountRecovery. --- .../contracts/test/EmailAccountRecoery.t.sol | 72 +++++++++++++++++++ packages/contracts/test/EmailAuth.t.sol | 10 +++ .../test/helpers/DeploymentHelper.sol | 9 ++- .../contracts/test/helpers/SimpleWallet.sol | 4 +- 4 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 packages/contracts/test/EmailAccountRecoery.t.sol diff --git a/packages/contracts/test/EmailAccountRecoery.t.sol b/packages/contracts/test/EmailAccountRecoery.t.sol new file mode 100644 index 00000000..74c53a10 --- /dev/null +++ b/packages/contracts/test/EmailAccountRecoery.t.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; +import "./helpers/DeploymentHelper.sol"; + +contract EmailAccountRecoveryTest is DeploymentHelper { + + function setUp() public override { + super.setUp(); + } + + function testTransfer() public { + + vm.startPrank(deployer); + assertEq(receiver.balance, 0 ether); + simpleWallet.transfer(receiver, 1 ether); + assertEq(receiver.balance, 1 ether); + vm.stopPrank(); + } + + function testFailTransfer() public { + assertEq(receiver.balance, 0 ether); + simpleWallet.transfer(receiver, 1 ether); + } + + function testWithdraw() public { + vm.startPrank(deployer); + assertEq(deployer.balance, 0 ether); + simpleWallet.withdraw(1 ether); + assertEq(deployer.balance, 1 ether); + vm.stopPrank(); + } + + function testFailWithdraw() public { + assertEq(deployer.balance, 0 ether); + simpleWallet.withdraw(1 ether); + } + + function testAcceptanceSubjectTemplates() public { + string[][] memory res = simpleWallet.acceptanceSubjectTemplates(); + assertEq(res[0][0], "Accept"); + assertEq(res[0][1], "guardian"); + assertEq(res[0][2], "request"); + assertEq(res[0][3], "for"); + assertEq(res[0][4], "{ethAddr}"); + } + + function testRecoverySubjectTemplates() public { + string[][] memory res = simpleWallet.recoverySubjectTemplates(); + assertEq(res[0][0], "Set"); + assertEq(res[0][1], "the"); + assertEq(res[0][2], "new"); + assertEq(res[0][3], "signer"); + assertEq(res[0][4], "of"); + assertEq(res[0][5], "{ethAddr}"); + assertEq(res[0][6], "to"); + assertEq(res[0][7], "{ethAddr}"); + } + + function testRequestGuardian() public { + vm.startPrank(deployer); + simpleWallet.requestGuardian(guardian); + vm.stopPrank(); + } + + function testFailRequestGuardian() public { + simpleWallet.requestGuardian(guardian); + } +} + diff --git a/packages/contracts/test/EmailAuth.t.sol b/packages/contracts/test/EmailAuth.t.sol index cab1c1f6..91997997 100644 --- a/packages/contracts/test/EmailAuth.t.sol +++ b/packages/contracts/test/EmailAuth.t.sol @@ -28,15 +28,19 @@ contract EmailAuthTest is DeploymentHelper { } function testUpdateDKIMRegistry() public { + vm.startPrank(deployer); ECDSAOwnedDKIMRegistry newDKIM = new ECDSAOwnedDKIMRegistry(msg.sender); emailAuth.updateDKIMRegistry(address(newDKIM)); assertEq(emailAuth.dkimRegistryAddr(), address(newDKIM)); + vm.stopPrank(); } function testUpdateVerifier() public { + vm.startPrank(deployer); Verifier newVerifier = new Verifier(); emailAuth.updateVerifier(address(newVerifier)); assertEq(emailAuth.verifierAddr(), address(newVerifier)); + vm.stopPrank(); } function testInsertSubjectTemplate() public { @@ -44,13 +48,17 @@ contract EmailAuthTest is DeploymentHelper { } function testUpdateSubjectTemplate() public { + vm.startPrank(deployer); this.testInsertSubjectTemplate(); emailAuth.updateSubjectTemplate(templateId, newSubjectTemplate); + vm.stopPrank(); } function testDeleteSubjectTemplate() public { + vm.startPrank(deployer); this.testInsertSubjectTemplate(); emailAuth.deleteSubjectTemplate(templateId); + vm.stopPrank(); } function testComputeMsgHash() public { @@ -70,6 +78,7 @@ contract EmailAuthTest is DeploymentHelper { } function testAuthEmail() public { + vm.startPrank(deployer); this.testInsertSubjectTemplate(); bytes[] memory subjectParams = new bytes[](2); @@ -107,6 +116,7 @@ contract EmailAuthTest is DeploymentHelper { msgHash, 0x97728a843151c01762d4f116e4d630f769faceda03589271805006ab8c512bcb ); + vm.stopPrank(); } function testIsValidSignature() public { diff --git a/packages/contracts/test/helpers/DeploymentHelper.sol b/packages/contracts/test/helpers/DeploymentHelper.sol index 462cfe13..747ad211 100644 --- a/packages/contracts/test/helpers/DeploymentHelper.sol +++ b/packages/contracts/test/helpers/DeploymentHelper.sol @@ -19,6 +19,10 @@ contract DeploymentHelper is Test { ECDSAOwnedDKIMRegistry dkim; SimpleWallet simpleWallet; + address deployer = vm.addr(1); + address receiver = vm.addr(2); + address guardian = vm.addr(3); + bytes32 accountSalt; uint templateId; string[] subjectTemplate; @@ -33,7 +37,8 @@ contract DeploymentHelper is Test { 0x00a83fce3d4b1c9ef0f600644c1ecc6c8115b57b1596e0e3295e2c5105fbfd8a; function setUp() public virtual { - address signer = vm.addr(1); + vm.startPrank(deployer); + address signer = deployer; // Create DKIM registry dkim = new ECDSAOwnedDKIMRegistry(signer); @@ -83,5 +88,7 @@ contract DeploymentHelper is Test { abi.encodeWithSelector(simpleWalletImpl.initialize.selector) ); simpleWallet = SimpleWallet(payable(address(simpleWalletProxy))); + vm.deal(address(simpleWallet), 1 ether); + vm.stopPrank(); } } diff --git a/packages/contracts/test/helpers/SimpleWallet.sol b/packages/contracts/test/helpers/SimpleWallet.sol index 2632508e..500d073d 100644 --- a/packages/contracts/test/helpers/SimpleWallet.sol +++ b/packages/contracts/test/helpers/SimpleWallet.sol @@ -55,13 +55,14 @@ contract SimpleWallet is OwnableUpgradeable, EmailAccountRecovery { override returns (string[][] memory) { string[][] memory templates = new string[][](1); + templates[0] = new string[](5); templates[0][0] = "Accept"; templates[0][1] = "guardian"; templates[0][2] = "request"; templates[0][3] = "for"; templates[0][4] = "{ethAddr}"; return templates; - } + } function recoverySubjectTemplates() public @@ -69,6 +70,7 @@ contract SimpleWallet is OwnableUpgradeable, EmailAccountRecovery { override returns (string[][] memory) { string[][] memory templates = new string[][](1); + templates[0] = new string[](8); templates[0][0] = "Set"; templates[0][1] = "the"; templates[0][2] = "new"; From 73b1de79e11d332214d7bba057466789e34f8fd0 Mon Sep 17 00:00:00 2001 From: wshino Date: Wed, 20 Mar 2024 23:44:32 +0900 Subject: [PATCH 26/42] Fix EmailAccountRecovery.t.sol. --- .../contracts/test/EmailAccountRecoery.t.sol | 122 +++++++++++++++--- .../contracts/test/helpers/SimpleWallet.sol | 1 + 2 files changed, 107 insertions(+), 16 deletions(-) diff --git a/packages/contracts/test/EmailAccountRecoery.t.sol b/packages/contracts/test/EmailAccountRecoery.t.sol index 74c53a10..ea9a7905 100644 --- a/packages/contracts/test/EmailAccountRecoery.t.sol +++ b/packages/contracts/test/EmailAccountRecoery.t.sol @@ -5,41 +5,65 @@ import "forge-std/Test.sol"; import "forge-std/console.sol"; import "./helpers/DeploymentHelper.sol"; -contract EmailAccountRecoveryTest is DeploymentHelper { +contract EmailAccountRecoveryTest is SimpleWallet, Test { + address deployer = vm.addr(1); + address receiver = vm.addr(2); + address guardian = vm.addr(3); + address newSigner = vm.addr(4); - function setUp() public override { - super.setUp(); + constructor() SimpleWallet(address(0x0), address(0x0), address(0x0)) {} + + function setUpForInternal() public { + vm.startPrank(deployer); + initialize(); + vm.deal(address(this), 1 ether); + vm.stopPrank(); + } + + function setUpForPublic() public { + vm.startPrank(deployer); + this.initialize(); + vm.deal(address(this), 1 ether); + vm.stopPrank(); } function testTransfer() public { - + setUpForPublic(); vm.startPrank(deployer); assertEq(receiver.balance, 0 ether); - simpleWallet.transfer(receiver, 1 ether); + this.transfer(receiver, 1 ether); assertEq(receiver.balance, 1 ether); vm.stopPrank(); } function testFailTransfer() public { + setUpForPublic(); + vm.startPrank(receiver); assertEq(receiver.balance, 0 ether); - simpleWallet.transfer(receiver, 1 ether); + this.transfer(receiver, 1 ether); + vm.stopPrank(); } function testWithdraw() public { + setUpForPublic(); vm.startPrank(deployer); assertEq(deployer.balance, 0 ether); - simpleWallet.withdraw(1 ether); + this.withdraw(1 ether); assertEq(deployer.balance, 1 ether); vm.stopPrank(); - } + } - function testFailWithdraw() public { + function testFailWithdraw() public { + setUpForPublic(); + vm.startPrank(receiver); assertEq(deployer.balance, 0 ether); - simpleWallet.withdraw(1 ether); - } + this.withdraw(1 ether); + vm.stopPrank(); + } function testAcceptanceSubjectTemplates() public { - string[][] memory res = simpleWallet.acceptanceSubjectTemplates(); + setUpForPublic(); + string[][] memory res = acceptanceSubjectTemplates(); assertEq(res[0][0], "Accept"); assertEq(res[0][1], "guardian"); assertEq(res[0][2], "request"); @@ -48,7 +72,8 @@ contract EmailAccountRecoveryTest is DeploymentHelper { } function testRecoverySubjectTemplates() public { - string[][] memory res = simpleWallet.recoverySubjectTemplates(); + setUpForPublic(); + string[][] memory res = recoverySubjectTemplates(); assertEq(res[0][0], "Set"); assertEq(res[0][1], "the"); assertEq(res[0][2], "new"); @@ -60,13 +85,78 @@ contract EmailAccountRecoveryTest is DeploymentHelper { } function testRequestGuardian() public { + setUpForInternal(); + vm.startPrank(deployer); - simpleWallet.requestGuardian(guardian); + requestGuardian(guardian); vm.stopPrank(); } function testFailRequestGuardian() public { - simpleWallet.requestGuardian(guardian); + setUpForPublic(); + + vm.startPrank(receiver); + this.requestGuardian(guardian); + vm.stopPrank(); } -} + function testAcceptGuardian() public { + testRequestGuardian(); + + vm.startPrank(deployer); + uint templateIdx = 0; + bytes[] memory subjectParams = new bytes[](1); + subjectParams[0] = abi.encode(guardian); + acceptGuardian(guardian, templateIdx, subjectParams, 0x0); + vm.stopPrank(); + } + + function testRecoverWallet() public { + testAcceptGuardian(); + + vm.startPrank(deployer); + uint templateIdx = 0; + bytes[] memory subjectParams = new bytes[](2); + subjectParams[0] = abi.encode(guardian, newSigner); + subjectParams[1] = abi.encode(newSigner); + recoverWallet(guardian, templateIdx, subjectParams, 0x0); + vm.stopPrank(); + } + + function testRejectRecovery() public { + testRecoverWallet(); + + vm.startPrank(deployer); + rejectRecovery(); + vm.stopPrank(); + } + + function testExpectRevertRejectRecovery() public { + testRecoverWallet(); + + vm.startPrank(deployer); + vm.warp(4 days); + vm.expectRevert(bytes("timelock expired")); + rejectRecovery(); + + vm.stopPrank(); + } + + function testCompleteRecovery() public { + testRecoverWallet(); + + vm.startPrank(deployer); + vm.warp(4 days); + completeRecovery(); + vm.stopPrank(); + } + + function testExpectRevertCompleteRecovery() public { + testRecoverWallet(); + + vm.startPrank(deployer); + vm.expectRevert(bytes("timelock not expired")); + completeRecovery(); + vm.stopPrank(); + } +} diff --git a/packages/contracts/test/helpers/SimpleWallet.sol b/packages/contracts/test/helpers/SimpleWallet.sol index 500d073d..974c4804 100644 --- a/packages/contracts/test/helpers/SimpleWallet.sol +++ b/packages/contracts/test/helpers/SimpleWallet.sol @@ -113,6 +113,7 @@ contract SimpleWallet is OwnableUpgradeable, EmailAccountRecovery { require(guardians[guardian] == GuardianStatus.ACCEPTED, "invalid guardian status"); require(templateIdx == 0, "invalid template index"); require(subjectParams.length == 2, "invalid subject params"); + // TODO Is the following implementation correct? (address guardianInEmail, address newSigner) = abi.decode(subjectParams[0], (address, address)); require(guardianInEmail == guardian, "invalid guardian in email"); require(newSigner != address(0), "invalid new signer"); From 5d406c46b9abd3b0a2d991dd2b1d471d0e7496a6 Mon Sep 17 00:00:00 2001 From: wshino Date: Thu, 21 Mar 2024 12:23:27 +0900 Subject: [PATCH 27/42] Fix parameter decoding in recoverWallet method. --- packages/contracts/test/EmailAccountRecoery.t.sol | 2 +- packages/contracts/test/helpers/SimpleWallet.sol | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/contracts/test/EmailAccountRecoery.t.sol b/packages/contracts/test/EmailAccountRecoery.t.sol index ea9a7905..d1054e8a 100644 --- a/packages/contracts/test/EmailAccountRecoery.t.sol +++ b/packages/contracts/test/EmailAccountRecoery.t.sol @@ -117,7 +117,7 @@ contract EmailAccountRecoveryTest is SimpleWallet, Test { vm.startPrank(deployer); uint templateIdx = 0; bytes[] memory subjectParams = new bytes[](2); - subjectParams[0] = abi.encode(guardian, newSigner); + subjectParams[0] = abi.encode(address(this)); subjectParams[1] = abi.encode(newSigner); recoverWallet(guardian, templateIdx, subjectParams, 0x0); vm.stopPrank(); diff --git a/packages/contracts/test/helpers/SimpleWallet.sol b/packages/contracts/test/helpers/SimpleWallet.sol index 974c4804..ca002fe1 100644 --- a/packages/contracts/test/helpers/SimpleWallet.sol +++ b/packages/contracts/test/helpers/SimpleWallet.sol @@ -113,12 +113,12 @@ contract SimpleWallet is OwnableUpgradeable, EmailAccountRecovery { require(guardians[guardian] == GuardianStatus.ACCEPTED, "invalid guardian status"); require(templateIdx == 0, "invalid template index"); require(subjectParams.length == 2, "invalid subject params"); - // TODO Is the following implementation correct? - (address guardianInEmail, address newSigner) = abi.decode(subjectParams[0], (address, address)); - require(guardianInEmail == guardian, "invalid guardian in email"); - require(newSigner != address(0), "invalid new signer"); + (address walletAddrInEmail) = abi.decode(subjectParams[0], (address)); + (address newSignerInEmail) = abi.decode(subjectParams[1], (address)); + require(walletAddrInEmail == address(this), "invalid guardian in email"); + require(newSignerInEmail != address(0), "invalid new signer"); isRecovering = true; - newSignerCandidate = newSigner; + newSignerCandidate = newSignerInEmail; timelock = block.timestamp + TIMELOCK_PERIOD; } From d66dcde4f7c1a8132f50c8b9b784c38f17804d3b Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Fri, 22 Mar 2024 05:44:48 +0900 Subject: [PATCH 28/42] Rename recoverWallet to processRecovery and add completeRecovery. --- packages/contracts/src/EmailAccountRecovery.sol | 6 ++++-- packages/contracts/test/EmailAccountRecoery.t.sol | 2 +- packages/contracts/test/helpers/SimpleWallet.sol | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/contracts/src/EmailAccountRecovery.sol b/packages/contracts/src/EmailAccountRecovery.sol index 8530c4e1..faa33e1f 100644 --- a/packages/contracts/src/EmailAccountRecovery.sol +++ b/packages/contracts/src/EmailAccountRecovery.sol @@ -43,13 +43,15 @@ abstract contract EmailAccountRecovery { bytes32 emailNullifier ) internal virtual; - function recoverWallet( + function processRecovery( address guardian, uint templateIdx, bytes[] memory subjectParams, bytes32 emailNullifier ) internal virtual; + function completeRecovery() external virtual; + function computeEmailAuthAddress(bytes32 accountSalt) public view @@ -158,7 +160,7 @@ abstract contract EmailAccountRecovery { // and does not return an error. guardianEmailAuth.authEmail(emailAuthMsg); - recoverWallet( + processRecovery( guardian, templateIdx, emailAuthMsg.subjectParams, diff --git a/packages/contracts/test/EmailAccountRecoery.t.sol b/packages/contracts/test/EmailAccountRecoery.t.sol index d1054e8a..74a4f326 100644 --- a/packages/contracts/test/EmailAccountRecoery.t.sol +++ b/packages/contracts/test/EmailAccountRecoery.t.sol @@ -119,7 +119,7 @@ contract EmailAccountRecoveryTest is SimpleWallet, Test { bytes[] memory subjectParams = new bytes[](2); subjectParams[0] = abi.encode(address(this)); subjectParams[1] = abi.encode(newSigner); - recoverWallet(guardian, templateIdx, subjectParams, 0x0); + processRecovery(guardian, templateIdx, subjectParams, 0x0); vm.stopPrank(); } diff --git a/packages/contracts/test/helpers/SimpleWallet.sol b/packages/contracts/test/helpers/SimpleWallet.sol index ca002fe1..0279326b 100644 --- a/packages/contracts/test/helpers/SimpleWallet.sol +++ b/packages/contracts/test/helpers/SimpleWallet.sol @@ -103,7 +103,7 @@ contract SimpleWallet is OwnableUpgradeable, EmailAccountRecovery { guardians[guardian] = GuardianStatus.ACCEPTED; } - function recoverWallet( + function processRecovery( address guardian, uint templateIdx, bytes[] memory subjectParams, @@ -130,7 +130,7 @@ contract SimpleWallet is OwnableUpgradeable, EmailAccountRecovery { timelock = 0; } - function completeRecovery() public { + function completeRecovery() public override { require(isRecovering, "recovery not in progress"); require(timelock <= block.timestamp, "timelock not expired"); isRecovering = false; From 6e7d0d83b820996540cf5c2071ad1f02fdd7b947 Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Sat, 23 Mar 2024 12:30:13 +0900 Subject: [PATCH 29/42] Add recipient's email address commitment to the circuit. --- packages/circuits/helpers/recipient.ts | 28 +++ packages/circuits/package.json | 4 +- packages/circuits/src/email_auth.circom | 162 +-------------- .../circuits/src/email_auth_template.circom | 191 ++++++++++++++++++ .../src/utils/email_addr_commit.circom | 18 ++ .../circuits/email_auth_with_recipient.circom | 5 + .../test_invitation_code_regex.circom | 2 + .../circuits/tests/recipient_enabled.test.ts | 191 ++++++++++++++++++ .../contracts/src/utils/Groth16Verifier.sol | 148 +++++++------- packages/utils/src/cryptos.rs | 65 ++++++ packages/utils/src/lib.rs | 6 + packages/utils/src/parse_email.rs | 23 +-- yarn.lock | 16 +- 13 files changed, 594 insertions(+), 265 deletions(-) create mode 100644 packages/circuits/helpers/recipient.ts create mode 100644 packages/circuits/src/email_auth_template.circom create mode 100644 packages/circuits/src/utils/email_addr_commit.circom create mode 100644 packages/circuits/tests/circuits/email_auth_with_recipient.circom create mode 100644 packages/circuits/tests/recipient_enabled.test.ts diff --git a/packages/circuits/helpers/recipient.ts b/packages/circuits/helpers/recipient.ts new file mode 100644 index 00000000..b727ab0f --- /dev/null +++ b/packages/circuits/helpers/recipient.ts @@ -0,0 +1,28 @@ +import fs from "fs"; +import { promisify } from "util"; +import { generateCircuitInputs } from "@zk-email/helpers/dist/input-helpers"; +const emailWalletUtils = require("../../utils"); + + +export async function genRecipientInput(emailFilePath: string): + Promise<{ + subject_email_addr_idx: number, + rand: string + }> { + const emailRaw = await promisify(fs.readFile)(emailFilePath, "utf8"); + const parsedEmail = await emailWalletUtils.parseEmail(emailRaw); + const subjectEmailIdxes = emailWalletUtils.extractSubjectAllIdxes(parsedEmail.canonicalizedHeader)[0]; + const subject = parsedEmail.canonicalizedHeader.slice(subjectEmailIdxes[0], subjectEmailIdxes[1]); + let subjectEmailAddrIdx = 0; + try { + subjectEmailAddrIdx = emailWalletUtils.extractEmailAddrIdxes(subject)[0][0]; + } catch (e) { + console.log("No email address in subject"); + subjectEmailAddrIdx = 0; + } + const rand = emailWalletUtils.extractRandFromSignature(parsedEmail.signature); + return { + subject_email_addr_idx: subjectEmailAddrIdx, + rand: rand + } +} diff --git a/packages/circuits/package.json b/packages/circuits/package.json index 7faacb79..9029bd69 100644 --- a/packages/circuits/package.json +++ b/packages/circuits/package.json @@ -11,9 +11,9 @@ "test": "NODE_OPTIONS=--max_old_space_size=8192 jest" }, "dependencies": { - "@zk-email/circuits": "^3.2.3", + "@zk-email/circuits": "^3.2.4", "@zk-email/helpers": "^3.1.3", - "@zk-email/zk-regex-circom": "^1.2.2", + "@zk-email/zk-regex-circom": "^1.3.0", "commander": "^11.0.0", "snarkjs": "^0.7.0" }, diff --git a/packages/circuits/src/email_auth.circom b/packages/circuits/src/email_auth.circom index e66fea3d..e77821ce 100644 --- a/packages/circuits/src/email_auth.circom +++ b/packages/circuits/src/email_auth.circom @@ -1,163 +1,5 @@ - pragma circom 2.1.5; -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/helpers/extract.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 "./regexes/invitation_code_with_prefix_regex.circom"; -include "./regexes/invitation_code_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. -// * 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 -template EmailAuth(n, k, max_header_bytes, max_subject_bytes) { - 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 sender_relayer_rand; // Private randomness of the relayer - 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_filed_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_filed_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); - email_verifier.in_padded <== padded_header; - email_verifier.pubkey <== public_key; - email_verifier.signature <== signature; - email_verifier.in_len_padded_bytes <== padded_header_len; - signal header_hash[256] <== email_verifier.sha; - public_key_hash <== email_verifier.pubkey_hash; - - // 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 from_email_addr[email_max_bytes]; - from_email_addr <== VarShiftMaskedStr(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 domain_name_bytes[domain_len]; - domain_name_bytes <== VarShiftMaskedStr(email_max_bytes, domain_len)(domain_regex_reveal, domain_idx); - domain_name <== Bytes2Ints(domain_len)(domain_name_bytes); - - 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 subject_all[max_subject_bytes]; - subject_all <== VarShiftMaskedStr(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); - // timestamp_regex_out === 1; - signal timestamp_str[timestamp_len]; - timestamp_str <== VarShiftMaskedStr(max_header_bytes, timestamp_len)(timestamp_regex_reveal, timestamp_idx); - signal raw_timestamp <== Digit2Int(timestamp_len)(timestamp_str); - timestamp <== timestamp_regex_out * raw_timestamp; - - 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 <== IsZero()(prefixed_code_regex_out-1); - 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]; - } - 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 <== IsZero()(subject_email_addr_regex_out-1); - 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); - signal code_consistency <== IsZero()(is_code_exist * (1 - code_regex_out)); - code_consistency === 1; - 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 +// * 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) { + 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 sender_relayer_rand; // Private randomness of the relayer + 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_filed_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_filed_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); + email_verifier.in_padded <== padded_header; + email_verifier.pubkey <== public_key; + email_verifier.signature <== signature; + email_verifier.in_len_padded_bytes <== padded_header_len; + signal header_hash[256] <== email_verifier.sha; + public_key_hash <== email_verifier.pubkey_hash; + + // 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 from_email_addr[email_max_bytes]; + from_email_addr <== VarShiftMaskedStr(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 domain_name_bytes[domain_len]; + domain_name_bytes <== VarShiftMaskedStr(email_max_bytes, domain_len)(domain_regex_reveal, domain_idx); + domain_name <== Bytes2Ints(domain_len)(domain_name_bytes); + + 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 subject_all[max_subject_bytes]; + subject_all <== VarShiftMaskedStr(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); + // timestamp_regex_out === 1; + signal timestamp_str[timestamp_len]; + timestamp_str <== VarShiftMaskedStr(max_header_bytes, timestamp_len)(timestamp_regex_reveal, timestamp_idx); + signal raw_timestamp <== Digit2Int(timestamp_len)(timestamp_str); + timestamp <== timestamp_regex_out * raw_timestamp; + + 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 <== IsZero()(prefixed_code_regex_out-1); + 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]; + } + 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 <== IsZero()(subject_email_addr_regex_out-1); + 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); + signal code_consistency <== IsZero()(is_code_exist * (1 - code_regex_out)); + code_consistency === 1; + signal replaced_code_regex_reveal[max_header_bytes]; + for(var i=0; i { + 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 emailWalletUtils.parseEmail(emailRaw); + console.log(parsedEmail.canonicalizedHeader); + const accountCode = await emailWalletUtils.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 circuit = await wasm_tester(path.join(__dirname, "./circuits/email_auth_with_recipient.circom"), option); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + const domainName = "gmail.com"; + const paddedDomain = emailWalletUtils.padString(domainName, 255); + const domainFields = emailWalletUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + const expectedPubKeyHash = emailWalletUtils.publicKeyHash(parsedEmail.publicKey); + expect(BigInt(expectedPubKeyHash)).toEqual(witness[1 + domainFields.length]); + const expectedEmailNullifier = emailWalletUtils.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 = emailWalletUtils.padString(maskedSubject, 605); + const maskedSubjectFields = emailWalletUtils.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 = emailWalletUtils.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 = emailWalletUtils.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 emailWalletUtils.parseEmail(emailRaw); + console.log(parsedEmail.canonicalizedHeader); + const accountCode = await emailWalletUtils.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 circuit = await wasm_tester(path.join(__dirname, "./circuits/email_auth_with_recipient.circom"), option); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + const domainName = "gmail.com"; + const paddedDomain = emailWalletUtils.padString(domainName, 255); + const domainFields = emailWalletUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + const expectedPubKeyHash = emailWalletUtils.publicKeyHash(parsedEmail.publicKey); + expect(BigInt(expectedPubKeyHash)).toEqual(witness[1 + domainFields.length]); + const expectedEmailNullifier = emailWalletUtils.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 = emailWalletUtils.padString(maskedSubject, 605); + const maskedSubjectFields = emailWalletUtils.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 = emailWalletUtils.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 = emailWalletUtils.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 emailWalletUtils.parseEmail(emailRaw); + console.log(parsedEmail.canonicalizedHeader); + const accountCode = await emailWalletUtils.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 circuit = await wasm_tester(path.join(__dirname, "./circuits/email_auth_with_recipient.circom"), option); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + const domainName = "gmail.com"; + const paddedDomain = emailWalletUtils.padString(domainName, 255); + const domainFields = emailWalletUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + const expectedPubKeyHash = emailWalletUtils.publicKeyHash(parsedEmail.publicKey); + expect(BigInt(expectedPubKeyHash)).toEqual(witness[1 + domainFields.length]); + const expectedEmailNullifier = emailWalletUtils.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 = emailWalletUtils.padString(maskedSubject, 605); + const maskedSubjectFields = emailWalletUtils.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 = emailWalletUtils.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 = emailWalletUtils.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 emailWalletUtils.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 circuit = await wasm_tester(path.join(__dirname, "./circuits/email_auth_with_recipient.circom"), option); + const witness = await circuit.calculateWitness(circuitInputs); + await circuit.checkConstraints(witness); + const domainName = "gmail.com"; + const paddedDomain = emailWalletUtils.padString(domainName, 255); + const domainFields = emailWalletUtils.bytes2Fields(paddedDomain); + for (let idx = 0; idx < domainFields.length; ++idx) { + expect(BigInt(domainFields[idx])).toEqual(witness[1 + idx]); + } + const expectedPubKeyHash = emailWalletUtils.publicKeyHash(parsedEmail.publicKey); + expect(BigInt(expectedPubKeyHash)).toEqual(witness[1 + domainFields.length]); + const expectedEmailNullifier = emailWalletUtils.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 = emailWalletUtils.padString(maskedSubject, 605); + const maskedSubjectFields = emailWalletUtils.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 = emailWalletUtils.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 = emailWalletUtils.emailAddrCommitWithSignature(recipientEmailAddr, parsedEmail.signature); + expect(BigInt(emailAddrCommit)).toEqual(witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 3]); + }); +}); \ No newline at end of file diff --git a/packages/contracts/src/utils/Groth16Verifier.sol b/packages/contracts/src/utils/Groth16Verifier.sol index a6960d33..e2a1e125 100644 --- a/packages/contracts/src/utils/Groth16Verifier.sol +++ b/packages/contracts/src/utils/Groth16Verifier.sol @@ -37,116 +37,116 @@ contract Groth16Verifier { uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930; - uint256 constant deltax1 = 19378677032800300253321765128070207344114232849596143606479382519857822848179; - uint256 constant deltax2 = 960493340684006291780639907740521128124066371578611670456259231950112608856; - uint256 constant deltay1 = 707321561242641502318247120686044129733961936778425747245592502022561588706; - uint256 constant deltay2 = 906648798918687791528309058870559612016450056396136091661128832168522104024; + uint256 constant deltax1 = 14784386233008920595048077630934558866623582586411442419884328384455364370206; + uint256 constant deltax2 = 6290603912353949177270096577890711250425081775637348791274473469351769670156; + uint256 constant deltay1 = 11167948527412530455970458333061862011172534158240288037990367063361950360819; + uint256 constant deltay2 = 13185416231312492310470683918957975663311737621386061858158607715832283734869; - uint256 constant IC0x = 11403395364844092073898287051441590269639035349832801575305448956555898189485; - uint256 constant IC0y = 7987377098002512490363489065894235810124910190689297467975733407897650124274; + uint256 constant IC0x = 21263619542713778996788860415398367608596813869337780657743924330185474368286; + uint256 constant IC0y = 20016986896738437123542241581422521467585270135865628544771094475384975057014; - uint256 constant IC1x = 19970349493151374875793850465364756216296859365106448163304043498653868948396; - uint256 constant IC1y = 7354947324833629681703491741404690151441837591196879347510104098513538563939; + uint256 constant IC1x = 21571198805623217150553519797365730486590088889675619388312667456900293011999; + uint256 constant IC1y = 3678551958513361152025012592181477447432955332666539925072044466035056317965; - uint256 constant IC2x = 6601321659792123150661728200330654029751433638096639327003776678899256405065; - uint256 constant IC2y = 5787025801944802546755634709739964131395447580769563006453319565215699737152; + uint256 constant IC2x = 3826203964938489334843652494383817850544017144219339541895430335436386080158; + uint256 constant IC2y = 6393076789623250285412306028079931314426713083028711676124039565129253127517; - uint256 constant IC3x = 14786441504972962102595252435524938360766818272311031519783302127874034635598; - uint256 constant IC3y = 7263574437900534125825733162428932803295530168406366964719997184009491498667; + uint256 constant IC3x = 21584447021606080565283967330346956849326136753802672422824192566068628153915; + uint256 constant IC3y = 1261199723364638371668072957276424859509876825026847397248117933862343237041; - uint256 constant IC4x = 19375830445311358980282436806871584323322276448079881638691559240245282530721; - uint256 constant IC4y = 17318811088837838309059961808619142218183737694662955481260362152107708083062; + uint256 constant IC4x = 3399569260784618407990621256153036638215540856855952853726597610058814968103; + uint256 constant IC4y = 687404032594938248912548718190040022614310050624013027163241581893823783758; - uint256 constant IC5x = 3908227178212770389553921608205338222911059589553208283649167492849523282345; - uint256 constant IC5y = 8243748932599724059484995795741695102111754510915071330829401474670457928650; + uint256 constant IC5x = 8817242174855800452959058327697277237932727273129982264823474259998886118899; + uint256 constant IC5y = 745547990358815220304448569984726876247117265651197850018076755252885093559; - uint256 constant IC6x = 15439278021703347151433503379992310851576978215602018333651893780355077291845; - uint256 constant IC6y = 21638430297043622123317246766715330304056281051508740200264186302710354377616; + uint256 constant IC6x = 9773950109559302870711673234338476620357989668698321824536457991633280420288; + uint256 constant IC6y = 14533302925041308054648189747824349330580676247015117243079661877558842833788; - uint256 constant IC7x = 12614103461207067723818290400900871937981485144306233479485282703564757523327; - uint256 constant IC7y = 2737120747640126912662625084039805926692259047896278598795372237156151273318; + uint256 constant IC7x = 3963682934613367021188873996000719544372782482540438980534549622426649176046; + uint256 constant IC7y = 801536238462993076122494239659972870006991910467816286361457420946271474346; - uint256 constant IC8x = 15301183870052143551620186414376410062664451990889671784420365756444494392325; - uint256 constant IC8y = 4650698488466967485773224735285319520384787418399204639031566674273247603131; + uint256 constant IC8x = 2487095520691476314470275136374330856545354854209705819692947704657070595979; + uint256 constant IC8y = 10544300486381541309288460662341732749521370446034689659769841203729475371113; - uint256 constant IC9x = 21754156616385732298740390360467956414568776103529844468119786993545110783064; - uint256 constant IC9y = 16184446846961693609726275447321514238507287886109687792410351138135250274144; + uint256 constant IC9x = 326620223728757596227554243421431251691981706620656788476938501573205907874; + uint256 constant IC9y = 6986395496068774717839463105084280693949202689850695218356233568967446929488; - uint256 constant IC10x = 244135444354636500241781120121461553791792444355025240108322368710180522317; - uint256 constant IC10y = 2502520855082041491808837191614596123009056536282647176762486196242326912440; + uint256 constant IC10x = 5880021638199091415118842867224346924424495788206679177206313172707282749019; + uint256 constant IC10y = 1166265341263191742371398321927281445397966036291598911375646997266647559564; - uint256 constant IC11x = 21775882581895783644266592948550034589672533233069670861804731728949339352238; - uint256 constant IC11y = 11881400815743694635896824745111667035477824478303686605652795964490344532799; + uint256 constant IC11x = 18129931226992069541952142077123737860996417143560686057025609598128645485754; + uint256 constant IC11y = 14131019629860420114163975580235773040024485558977397936691469038927144431536; - uint256 constant IC12x = 3312179889940052232204751898979833097517557003027876142751774737404346769486; - uint256 constant IC12y = 21374632894304888129661426640165240436413284427338075262260399838612492997131; + uint256 constant IC12x = 12755744125857143978932600574922935751426162397594985634868876782885076156171; + uint256 constant IC12y = 12418480364524499572581185629387446287279575899686303308439008205742001818196; - uint256 constant IC13x = 7528626507625376052925073583344030864021221821172063769053410245035129716312; - uint256 constant IC13y = 9166096334755065092764176720997273246795251892031153588688410906044526198171; + uint256 constant IC13x = 7705798748509510362990708861510570607770482044434080903459814039525550811045; + uint256 constant IC13y = 12294643682468101997655474763332459912297542715971809346745941183230862065886; - uint256 constant IC14x = 6369530737509876846946090390455741937023125890510750661735149513809418509605; - uint256 constant IC14y = 9280745716541780368193317986861227250950780074033868300480845563855753398269; + uint256 constant IC14x = 4365016931665154092025767970436283666697558648385371311603353072458375464856; + uint256 constant IC14y = 3378996817165894643714044072874502409910787564045196209333665714104967070968; - uint256 constant IC15x = 12558224684088018750215250798503126445875846848169703467438387530529151184093; - uint256 constant IC15y = 6438447722525942451152734025293335130203657459750071579867825017750662264543; + uint256 constant IC15x = 12942639100973261241508418471433458313396910350707280055246165565361086272416; + uint256 constant IC15y = 16883566451399483939940726048206736795207590921803163664190901956100912424203; - uint256 constant IC16x = 21760172767678989053712974210946185954416464325269741202502365558511569730969; - uint256 constant IC16y = 14328555534854937419599307487887607109383935995961943164869104475259737674952; + uint256 constant IC16x = 16900951554610909140147222189479377967149563030075650494851922945848439154938; + uint256 constant IC16y = 2831071635260980435010892774652225761318599214466436569746059908031333393104; - uint256 constant IC17x = 12721450965857647842653598818060523209655807544582142503114340239875644094169; - uint256 constant IC17y = 509291315940844110919310141621160761306967491284754194278419723289372915824; + uint256 constant IC17x = 21045086991208545832697470603723824632455411177388787997158483003944406740701; + uint256 constant IC17y = 7611150055221725378329322250543425354507632193614430819455015631593956721665; - uint256 constant IC18x = 11821091968722472223052893420629266585896381860398218548505450239066680784138; - uint256 constant IC18y = 637629613665587078024011533283160236803183532182389013399718830046110157867; + uint256 constant IC18x = 4699176174916609937440413994793237802272916900741528238144061053102509322926; + uint256 constant IC18y = 17692771579480506570623075391095404172551798163926917669587781147836847833334; - uint256 constant IC19x = 15171686905454021445617486794000410115298497039166377603938555414739376699278; - uint256 constant IC19y = 9367860372950551907843497084251870484664401058060747979299880821479072333651; + uint256 constant IC19x = 2598215866876895961342026156016883715229099363462942736784529686949852145531; + uint256 constant IC19y = 9099037230730879008428571127823686486146127341409596867149255497560502101570; - uint256 constant IC20x = 13453885302087699738578768621050293444980598938635823846236227865376091470051; - uint256 constant IC20y = 4114932099627848758644340520348411173109495028640015773993131575914340470444; + uint256 constant IC20x = 6980795279209804044295589310984050515035792816859195213306659081972236138808; + uint256 constant IC20y = 15627071611167565395787388508415046824182330376694046141037789063334945700484; - uint256 constant IC21x = 7816164550596800024128197318709984983746028547286775312210385941824772819678; - uint256 constant IC21y = 11907598145362082980231488040519763420460629270042988114575694207123419480799; + uint256 constant IC21x = 19991318329169509054324908381118908733810989706554484682986656981087898608814; + uint256 constant IC21y = 11151807388042712387799748332876052539247718759011571517468702168033854620333; - uint256 constant IC22x = 7026291121711518717885133396634431504702598004699717987639781623426372406068; - uint256 constant IC22y = 2934217034199305782699570943807041161901569272146498895183569827812876684414; + uint256 constant IC22x = 7197786955835576310230622013863595572022456978202957664139282153387449765728; + uint256 constant IC22y = 7307929232998432043303568215695279547080512060432597909299323422352066971346; - uint256 constant IC23x = 5696885153673563482639795878703782890060885577257079837208380543842190305806; - uint256 constant IC23y = 17677490074850382391167178977789148501419703191123700226733359751191884925088; + uint256 constant IC23x = 21107038666325993398111883307057715881826929611399469086054570549123822967238; + uint256 constant IC23y = 19358046509882604343296035735393686982343622871808723326223508506968704079350; - uint256 constant IC24x = 2611683639773662474624629722305165059188459747093556135898769696357331487500; - uint256 constant IC24y = 10044388249493140225865522073559488567982324265722702513571966586506538669872; + uint256 constant IC24x = 21733425743886494354074785589259540093831519447981215111447931957177658740646; + uint256 constant IC24y = 320378227520532747494170231505351389860899285148596547714153415229780896938; - uint256 constant IC25x = 5214009542610232932442041067813113650632680623992721376070046067376709227182; - uint256 constant IC25y = 10185071351439460276090510663428745483434923234173869867480387557540646341686; + uint256 constant IC25x = 10807363486279526649522279602442296273796876163746157648463927482878729634814; + uint256 constant IC25y = 1637998659150932502657930583239566566919439759060156510688537779402992343159; - uint256 constant IC26x = 4636491635078988706441689757212385869973641936706839840615699323767584705656; - uint256 constant IC26y = 5385588163483057776915996860882717516859067158972572817291591123171461874905; + uint256 constant IC26x = 15757040111324664890702778276531602253630891387857810903715246887753778016641; + uint256 constant IC26y = 6856013776266785793905331841857739093410009401943634715134261212915376925892; - uint256 constant IC27x = 18705809007834830886982817327652431135135881045537983411955656556286258722805; - uint256 constant IC27y = 15760086357718846365304413904138098736915444207916507230376426657348004828234; + uint256 constant IC27x = 18553175766346853831692305237396483021145543868232800539672120632362275693195; + uint256 constant IC27y = 14657550563005610536262461999604468583742581872657961609866691539824355348828; - uint256 constant IC28x = 19182077652075606448764076721233989088126556417897799020951367435544174328839; - uint256 constant IC28y = 9136270306453077808755194696108953703001292400385038364957275580855848746843; + uint256 constant IC28x = 11307205585890781731407066743509582696655833995661404766510137435016538965344; + uint256 constant IC28y = 2144099371502329678400131476622394151925768035082782314390950021415482758590; - uint256 constant IC29x = 18485427693577943108144538953927906684343832918965223721720202393052827398914; - uint256 constant IC29y = 18575738887044959080624252642810238700989315891377197214187365412313209252763; + uint256 constant IC29x = 19863337319551832100103833561655376220229778657285914289628589118314859029630; + uint256 constant IC29y = 19472338867331214938087160238447952612012239119574949450267961552410803459527; - uint256 constant IC30x = 4223202583040339035072354022171586822138322889663701017950037645370876520845; - uint256 constant IC30y = 11856130485182396243929365545262884496878630681794480179341681754292009988063; + uint256 constant IC30x = 8371922207290736821290597463621858573798316984929092662306394953292053762525; + uint256 constant IC30y = 14848518290051803848584558630923125749231759972312860015021014554436507470332; - uint256 constant IC31x = 19407812422219942955336266485712702970841716137575998392385328696244122346627; - uint256 constant IC31y = 6785055681044554372605737518388942189987917619986273461429790568638918699867; + uint256 constant IC31x = 13570881902287311629614928096950362138730249575904851488233466324378922833172; + uint256 constant IC31y = 18423779455926046216682826304198019248056507540857425043799964466957213586668; - uint256 constant IC32x = 14993212179101104565462829595748725448512808800293815566424165418121053284398; - uint256 constant IC32y = 4083889862604497566428910703229716185418233528250337149121364790918693829394; + uint256 constant IC32x = 4759810453846148646280588932789014108299960602482129313376187206813298258954; + uint256 constant IC32y = 12819422029154239643140464591644016635134303655591826988181005292616687182322; - uint256 constant IC33x = 19535193266806328470942118649012700164578795620538913542594738691400891335098; - uint256 constant IC33y = 12775783114117041065841750751628812939076814753172334426229780042733013690673; + uint256 constant IC33x = 8225433101022329967503231819162786588654489274877868722142176993702085762867; + uint256 constant IC33y = 5784915490119435870737229021171029732529240230987585350455092854185984360396; - uint256 constant IC34x = 3062181060286810160747070144635312664862371094982947559639250577939387406466; - uint256 constant IC34y = 4596414785886448742196272188716315360063739806767099479393366426606524993331; + uint256 constant IC34x = 9421023559488812561399383302624803731724380132279383523742628428412583446117; + uint256 constant IC34y = 20652759705519069352723256379975567044863836965792525966773816754785358072654; // Memory data diff --git a/packages/utils/src/cryptos.rs b/packages/utils/src/cryptos.rs index 92b70441..6ea61766 100644 --- a/packages/utils/src/cryptos.rs +++ b/packages/utils/src/cryptos.rs @@ -29,6 +29,26 @@ impl PaddedEmailAddr { pub fn to_email_addr_fields(&self) -> Vec { bytes2fields(&self.padded_bytes) } + + pub fn to_commitment(&self, rand: &Fr) -> Result { + let mut inputs = vec![*rand]; + inputs.append(&mut self.to_email_addr_fields()); + poseidon_fields(&inputs) + } + + pub fn to_commitment_with_signature(&self, signature: &[u8]) -> Result { + let cm_rand = extract_rand_from_signature(signature)?; + poseidon_fields(&[vec![cm_rand], self.to_email_addr_fields()].concat()) + } +} + +pub fn extract_rand_from_signature(signature: &[u8]) -> Result { + let mut signature = signature.to_vec(); + signature.reverse(); + let mut inputs = bytes_chunk_fields(&signature, 121, 2); + inputs.push(Fr::one()); + let cm_rand = poseidon_fields(&inputs)?; + Ok(cm_rand) } #[derive(Debug, Clone, Copy)] @@ -133,3 +153,48 @@ pub fn email_nullifier_node(mut cx: FunctionContext) -> JsResult { let nullifier_str = field2hex(&nullifier); Ok(cx.string(nullifier_str)) } + +pub fn email_addr_commit_node(mut cx: FunctionContext) -> JsResult { + let email_addr = cx.argument::(0)?.value(&mut cx); + let rand = cx.argument::(1)?.value(&mut cx); + let rand = hex2field_node(&mut cx, &rand)?; + let padded_email_addr = PaddedEmailAddr::from_email_addr(&email_addr); + let email_addr_commit = match padded_email_addr.to_commitment(&rand) { + Ok(fr) => fr, + Err(e) => return cx.throw_error(&format!("EmailAddrCommit failed: {}", e)), + }; + let email_addr_commit_str = field2hex(&email_addr_commit); + Ok(cx.string(email_addr_commit_str)) +} + +pub fn email_addr_commit_with_signature_node(mut cx: FunctionContext) -> JsResult { + let email_addr = cx.argument::(0)?.value(&mut cx); + let signature = cx.argument::(1)?.value(&mut cx); + let signature = match hex::decode(&signature[2..]) { + Ok(bytes) => bytes, + Err(e) => return cx.throw_error(&format!("signature is an invalid hex string: {}", e)), + }; + // signature.reverse(); + let padded_email_addr = PaddedEmailAddr::from_email_addr(&email_addr); + let email_addr_commit = match padded_email_addr.to_commitment_with_signature(&signature) { + Ok(fr) => fr, + Err(e) => return cx.throw_error(&format!("EmailAddrCommit failed: {}", e)), + }; + let email_addr_commit_str = field2hex(&email_addr_commit); + Ok(cx.string(email_addr_commit_str)) +} + +pub fn extract_rand_from_signature_node(mut cx: FunctionContext) -> JsResult { + let signature = cx.argument::(0)?.value(&mut cx); + let signature = match hex::decode(&signature[2..]) { + Ok(bytes) => bytes, + Err(e) => return cx.throw_error(&format!("signature is an invalid hex string: {}", e)), + }; + // signature.reverse(); + let rand = match extract_rand_from_signature(&signature) { + Ok(fr) => fr, + Err(e) => return cx.throw_error(&format!("extract_rand_from_signature failed: {}", e)), + }; + let rand_str = field2hex(&rand); + Ok(cx.string(rand_str)) +} diff --git a/packages/utils/src/lib.rs b/packages/utils/src/lib.rs index a0cc1c4a..13a98c74 100644 --- a/packages/utils/src/lib.rs +++ b/packages/utils/src/lib.rs @@ -38,5 +38,11 @@ fn main(mut cx: ModuleContext) -> NeonResult<()> { cx.export_function("accountSalt", account_salt_node)?; cx.export_function("publicKeyHash", public_key_hash_node)?; cx.export_function("emailNullifier", email_nullifier_node)?; + cx.export_function("emailAddrCommit", email_addr_commit_node)?; + cx.export_function( + "emailAddrCommitWithSignature", + email_addr_commit_with_signature_node, + )?; + cx.export_function("extractRandFromSignature", extract_rand_from_signature_node)?; Ok(()) } diff --git a/packages/utils/src/parse_email.rs b/packages/utils/src/parse_email.rs index 0fdf1e79..31d2d734 100644 --- a/packages/utils/src/parse_email.rs +++ b/packages/utils/src/parse_email.rs @@ -197,7 +197,7 @@ mod test { #[tokio::test] async fn test_extractions_from_email1() { - let raw_email = include_str!("../../circuits/tests/emails/email_sender_test1.eml"); + let raw_email = include_str!("../../circuits/tests/emails/email_auth_test1.eml"); let parsed_email = ParsedEmail::new_from_raw_email(raw_email).await.unwrap(); let from_addr = parsed_email.get_from_addr().unwrap(); assert_eq!(from_addr, "suegamisora@gmail.com"); @@ -215,7 +215,7 @@ mod test { #[tokio::test] async fn test_extractions_from_email2() { - let raw_email = include_str!("../../circuits/tests/emails/account_creation_test1.eml"); + let raw_email = include_str!("../../circuits/tests/emails/email_auth_test5.eml"); let parsed_email = ParsedEmail::new_from_raw_email(raw_email).await.unwrap(); let from_addr = parsed_email.get_from_addr().unwrap(); assert_eq!(from_addr, "suegamisora@gmail.com"); @@ -231,23 +231,4 @@ mod test { "01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76" ); } - - #[tokio::test] - async fn test_extractions_from_email3() { - let raw_email = include_str!("../../circuits/tests/emails/account_init_test2.eml"); - let parsed_email = ParsedEmail::new_from_raw_email(raw_email).await.unwrap(); - let from_addr = parsed_email.get_from_addr().unwrap(); - assert_eq!(from_addr, "suegamisora@gmail.com"); - let to_addr = parsed_email.get_to_addr().unwrap(); - assert_eq!(to_addr, "emailwallet.relayer@gmail.com"); - let email_domain = parsed_email.get_email_domain().unwrap(); - assert_eq!(email_domain, "gmail.com"); - let subject_all = parsed_email.get_subject_all().unwrap(); - assert_eq!( - subject_all, - "This is a test. CODE:0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76" - ); - let timestamp = parsed_email.get_timestamp().unwrap(); - assert_eq!(timestamp, 1697224006); - } } diff --git a/yarn.lock b/yarn.lock index b9a376ba..3ef0fce5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1962,10 +1962,10 @@ "@uniswap/v3-core" "^1.0.0" base64-sol "1.0.1" -"@zk-email/circuits@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@zk-email/circuits/-/circuits-3.2.3.tgz#24e16706bc1f46eab5b6e51185faf8d8afe28175" - integrity sha512-dAOaEul2iq86f69FFaXK/u3ec+Lk6B3vpbapyJ9oKGgWeINilWJQaEP1WSJyeVV52zPRVE5uDkIVhIguU7jk2g== +"@zk-email/circuits@^3.2.4": + version "3.2.4" + resolved "https://registry.yarnpkg.com/@zk-email/circuits/-/circuits-3.2.4.tgz#10fcc5f997a2f65285f51ab03625e4f8fb300f7d" + integrity sha512-MCF1TfaN02wUOUnZxO/DfKd5cqsLmoCBbGwmjEwhFtntlTbVo8ZW+QpzlosRHSR/jNE/pGbhBuyQICcujkJ3Ig== dependencies: "@zk-email/zk-regex-circom" "^1.1.1" @@ -2003,10 +2003,10 @@ commander "^11.0.0" snarkjs "^0.7.0" -"@zk-email/zk-regex-circom@^1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@zk-email/zk-regex-circom/-/zk-regex-circom-1.2.2.tgz#d1ea2731b4308e8f7c7b08ca2ff2d41934c6ce5e" - integrity sha512-IZy1xAG9EDELlPyoWNBswHVSKt2X311ZybVLv4sRTtrhaS+W3wQMEE7T+hlgtP6lJioeJrGLBS4Xp30HSazb/Q== +"@zk-email/zk-regex-circom@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@zk-email/zk-regex-circom/-/zk-regex-circom-1.3.0.tgz#8cb2b3b4977cfe42dc7072e13795e10d92efa074" + integrity sha512-faMboihzV3zyh2K3Qy4GYgxRRql4YEef26QDCISFFuURACWINfwtoZPC4OHtE0Ug60iAWRbpQtUWlPjomTCxoQ== dependencies: commander "^11.0.0" snarkjs "^0.7.0" From 32b4e98d737881f4c594afc3388bb5088b2e9f46 Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Sat, 23 Mar 2024 19:14:22 +0900 Subject: [PATCH 30/42] Add script to generate circuit inputs. --- packages/circuits/package.json | 1 - packages/circuits/scripts/gen_input.ts | 67 ++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 packages/circuits/scripts/gen_input.ts diff --git a/packages/circuits/package.json b/packages/circuits/package.json index 9029bd69..0945956f 100644 --- a/packages/circuits/package.json +++ b/packages/circuits/package.json @@ -6,7 +6,6 @@ "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", "gen-input": "NODE_OPTIONS=--max_old_space_size=8192 npx ts-node scripts/gen_input.ts", - "gen-random-proofs": "NODE_OPTIONS=--max_old_space_size=8192 npx ts-node scripts/gen_random_proofs.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" }, diff --git a/packages/circuits/scripts/gen_input.ts b/packages/circuits/scripts/gen_input.ts new file mode 100644 index 00000000..899ea05d --- /dev/null +++ b/packages/circuits/scripts/gen_input.ts @@ -0,0 +1,67 @@ +/** + * + * This script is for generating input for the main circuit. + * + */ + + +import { program } from "commander"; +import fs from "fs"; +import { promisify } from "util"; +import { genEmailAuthInput } from "../helpers/email_auth"; +import path from "path"; +const snarkjs = require("snarkjs"); + +program + .requiredOption( + "--email-file ", + "Path to an email file" + ) + .requiredOption( + "--account-code ", + "The account code for the sender's email address" + ) + .requiredOption( + "--input-file ", + "Path of a json file to write the generated input" + ) + .option("--silent", "No console logs") + .option("--prove", "Also generate proof"); + +program.parse(); +const args = program.opts(); + +function log(...message: any) { + if (!args.silent) { + console.log(...message); + } +} + +async function generate() { + if (!args.inputFile.endsWith(".json")) { + throw new Error("--input file path arg must end with .json"); + } + + log("Generating Inputs for:", args); + + const circuitInputs = await genEmailAuthInput(args.emailFile, args.accountCode); + 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); +} + +generate().catch((err) => { + console.error("Error generating inputs", err); + process.exit(1); +}); From 59d90b20c2283a773fbea1aa979d27dab1a14dfe Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Sat, 23 Mar 2024 23:43:39 +0900 Subject: [PATCH 31/42] Add prover. --- packages/prover/Dockerfile | 52 ++++++++++++++++++++++ packages/prover/circom_proofgen.sh | 66 ++++++++++++++++++++++++++++ packages/prover/core.py | 69 ++++++++++++++++++++++++++++++ packages/prover/local.py | 31 ++++++++++++++ packages/prover/local_setup.sh | 16 +++++++ packages/prover/modal_server.py | 40 +++++++++++++++++ packages/prover/requirements.txt | 6 +++ 7 files changed, 280 insertions(+) create mode 100644 packages/prover/Dockerfile create mode 100755 packages/prover/circom_proofgen.sh create mode 100644 packages/prover/core.py create mode 100644 packages/prover/local.py create mode 100755 packages/prover/local_setup.sh create mode 100644 packages/prover/modal_server.py create mode 100644 packages/prover/requirements.txt diff --git a/packages/prover/Dockerfile b/packages/prover/Dockerfile new file mode 100644 index 00000000..97de9e02 --- /dev/null +++ b/packages/prover/Dockerfile @@ -0,0 +1,52 @@ +FROM python:3.10 +# FROM aayushg0/rapidsnark:latest AS rapidsnark +# FROM rust:latest +# FROM node:18 + + +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 + +# Node install +RUN npm install -g n +RUN n 18 +RUN npm install -g yarn snarkjs + +RUN git clone https://github.com/zkemail/email-wallet.git +WORKDIR /email-wallet/packages/prover +RUN pip install -r requirements.txt +RUN cp ./circom_proofgen.sh /root +WORKDIR /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=1ky3XyabnBFwcyBoWBimhoePT9kbFyEBR" +RUN unzip params.zip +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 chmod +x circom_proofgen.sh +RUN mkdir build + +RUN git clone https://github.com/iden3/rapidsnark-old.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 +WORKDIR /root \ No newline at end of file diff --git a/packages/prover/circom_proofgen.sh b/packages/prover/circom_proofgen.sh new file mode 100755 index 00000000..738f2e2c --- /dev/null +++ b/packages/prover/circom_proofgen.sh @@ -0,0 +1,66 @@ +#!/bin/bash +set -e # Stop on error + +if [ $# -ne 5 ]; then + echo "Usage: $0 " + exit 1 +fi + +circuitName=$1 +nonce=$2 +paramsDir=$3 +buildDir=$4 +isLocal=$5 +SCRIPT_DIR=$(cd $(dirname $0); pwd) + +input_path="${buildDir}/input_${circuitName}_${nonce}.json" +witness_path="${buildDir}/witness_${circuitName}_${nonce}.wtns" +proof_path="${buildDir}/rapidsnark_proof_${circuitName}_${nonce}.json" +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 +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 + +if [ $isLocal = 1 ]; then + # DEFAULT SNARKJS PROVER (SLOW) + NODE_OPTIONS='--max-old-space-size=644000' snarkjs groth16 prove "${paramsDir}/${circuitName}.zkey" "${witness_path}" "${proof_path}" "${public_path}" + 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" + 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 + status_prover=$? + echo "✓ Finished rapid proofgen! Status: ${status_prover}" +fi + + + +# TODO: Upgrade debug -> release and edit dockerfile to use release +# echo "${HOME}/relayer/target/release/relayer chain false ${prover_output_path} ${nonce}" +# "${HOME}/relayer/target/release/relayer" chain false "${prover_output_path}" "${nonce}" 2>&1 | tee /dev/stderr +# status_chain=$? +# echo "✓ Finished send to chain! Status: ${status_chain}" + +exit 0 \ No newline at end of file diff --git a/packages/prover/core.py b/packages/prover/core.py new file mode 100644 index 00000000..f88d66b9 --- /dev/null +++ b/packages/prover/core.py @@ -0,0 +1,69 @@ +import subprocess +import os +import json + + +def gen_email_auth_proof(nonce: str, is_local: bool, input: dict) -> dict: + circuit_name = "email_auth" + store_input(circuit_name, nonce, input) + gen_proof(circuit_name, nonce, is_local) + proof = load_proof(circuit_name, nonce) + pub_signals = load_pub_signals(circuit_name, nonce) + return {"proof": proof, "pub_signals": pub_signals} + + +def store_input(circuit_name: str, nonce: str, json_data: dict): + cur_dir = get_cur_dir() + build_dir = os.path.join(cur_dir, "build") + # check if build_dir exists + if not os.path.exists(build_dir): + os.makedirs(build_dir) + + json_file_path = os.path.join( + build_dir, "input_" + circuit_name + "_" + nonce + ".json" + ) + with open(json_file_path, "w") as json_file: + json_file.write(json_data) + + +def load_proof(circuit_name: str, nonce: str) -> dict: + cur_dir = get_cur_dir() + build_dir = os.path.join(cur_dir, "build") + json_file_path = os.path.join( + build_dir, "rapidsnark_proof_" + circuit_name + "_" + nonce + ".json" + ) + with open(json_file_path, "r") as json_file: + return json.loads(json_file.read()) + + +def load_pub_signals(circuit_name: str, nonce: str) -> dict: + cur_dir = get_cur_dir() + build_dir = os.path.join(cur_dir, "build") + json_file_path = os.path.join( + build_dir, "rapidsnark_public_" + circuit_name + "_" + nonce + ".json" + ) + with open(json_file_path, "r") as json_file: + return json.loads(json_file.read()) + + +def gen_proof(circuit_name: str, nonce: str, is_local: bool): + is_local_int: int = 1 if is_local else 0 + cur_dir = get_cur_dir() + params_dir = os.path.join(cur_dir, "params") + build_dir = os.path.join(cur_dir, "build") + result = subprocess.run( + [ + os.path.join(cur_dir, "circom_proofgen.sh"), + circuit_name, + nonce, + params_dir, + build_dir, + str(is_local_int), + ] + ) + print(result.stdout) + print(result.stderr) + + +def get_cur_dir() -> str: + return os.path.dirname(os.path.abspath(__file__)) diff --git a/packages/prover/local.py b/packages/prover/local.py new file mode 100644 index 00000000..257968d4 --- /dev/null +++ b/packages/prover/local.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +# encoding: utf-8 + +from flask import Flask, request, jsonify +import random +import sys +from core import ( + gen_email_auth_proof, +) + +app = Flask(__name__) + + +@app.route("/prove/email_auth", methods=["POST"]) +def prove_email_auth(): + req = request.get_json() + input = req["input"] + print(input) + print(type(input)) + nonce = random.randint( + 0, + sys.maxsize, + ) + proof = gen_email_auth_proof(str(nonce), True, input) + return jsonify(proof) + + +if __name__ == "__main__": + from waitress import serve + + serve(app, host="0.0.0.0", port=8080) diff --git a/packages/prover/local_setup.sh b/packages/prover/local_setup.sh new file mode 100755 index 00000000..a8e073d4 --- /dev/null +++ b/packages/prover/local_setup.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e # Stop on error + +mkdir -p build + +npm install -g snarkjs@latest +pip install -r requirements.txt +mkdir build && cd build +gdown "https://drive.google.com/uc?id=1ky3XyabnBFwcyBoWBimhoePT9kbFyEBR" +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 diff --git a/packages/prover/modal_server.py b/packages/prover/modal_server.py new file mode 100644 index 00000000..8ff4bfd7 --- /dev/null +++ b/packages/prover/modal_server.py @@ -0,0 +1,40 @@ +import modal + +from core import ( + gen_email_auth_proof, +) + + +stub = modal.Stub("email-wallet-relayer-v1.1") + +image = modal.Image.from_dockerfile("Dockerfile") + + +@stub.function( + image=image, + mounts=[ + modal.Mount.from_local_python_packages("core"), + ], + cpu=14, +) +@modal.wsgi_app() +def flask_app(): + from flask import Flask, request, jsonify + import random + import sys + + app = Flask(__name__) + + @app.post("/prove/email_auth") + def prove_email_auth(): + req = request.get_json() + input = req["input"] + print(input) + print(type(input)) + nonce = random.randint( + 0, + sys.maxsize, + ) + proof = gen_email_auth_proof(str(nonce), False, input) + return jsonify(proof) + return app diff --git a/packages/prover/requirements.txt b/packages/prover/requirements.txt new file mode 100644 index 00000000..f81fe1a7 --- /dev/null +++ b/packages/prover/requirements.txt @@ -0,0 +1,6 @@ +flask +waitress +gdown +jsonify +requests +modal \ No newline at end of file From 091c3585acbd079a0b1fae1a3bab6be018784211 Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Sun, 24 Mar 2024 01:13:33 +0900 Subject: [PATCH 32/42] Add relayer. --- Cargo.toml | 2 +- packages/relayer/Cargo.toml | 57 ++++ packages/relayer/src/config.rs | 76 +++++ packages/relayer/src/database.rs | 360 ++++++++++++++++++++++ packages/relayer/src/dkim_oracle.rs | 62 ++++ packages/relayer/src/emails_pool.rs | 75 +++++ packages/relayer/src/imap_client.rs | 223 ++++++++++++++ packages/relayer/src/lib.rs | 21 ++ packages/relayer/src/logger.rs | 54 ++++ packages/relayer/src/main.rs | 1 + packages/relayer/src/selector_def.json | 20 ++ packages/relayer/src/smtp_client.rs | 146 +++++++++ packages/relayer/src/subject_templates.rs | 228 ++++++++++++++ packages/relayer/src/utils.rs | 185 +++++++++++ packages/relayer/src/web_server.rs | 190 ++++++++++++ 15 files changed, 1699 insertions(+), 1 deletion(-) create mode 100644 packages/relayer/Cargo.toml create mode 100644 packages/relayer/src/config.rs create mode 100644 packages/relayer/src/database.rs create mode 100644 packages/relayer/src/dkim_oracle.rs create mode 100644 packages/relayer/src/emails_pool.rs create mode 100644 packages/relayer/src/imap_client.rs create mode 100644 packages/relayer/src/lib.rs create mode 100644 packages/relayer/src/logger.rs create mode 100644 packages/relayer/src/main.rs create mode 100644 packages/relayer/src/selector_def.json create mode 100644 packages/relayer/src/smtp_client.rs create mode 100644 packages/relayer/src/subject_templates.rs create mode 100644 packages/relayer/src/utils.rs create mode 100644 packages/relayer/src/web_server.rs diff --git a/Cargo.toml b/Cargo.toml index 20c0ba05..63a650e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,4 @@ [workspace] -members = ["packages/utils"] +members = ["packages/utils", "packages/relayer"] exclude = ["node_modules/*"] resolver = "2" diff --git a/packages/relayer/Cargo.toml b/packages/relayer/Cargo.toml new file mode 100644 index 00000000..1a07ed1b --- /dev/null +++ b/packages/relayer/Cargo.toml @@ -0,0 +1,57 @@ +[package] +name = "relayer" +version = "1.1.0" +edition = "2021" + +[dependencies] +tower-http = { version = "0.4", git = "https://github.com/tower-rs/tower-http.git", features = [ + "cors", +], rev = "f33c3e038dc85b8d064541e915d501f9c9e6a6b4" } +tokio = { version = "1.0", features = ["full"] } +sled = "0.34.2" +anyhow = "1.0.75" +dotenv = "0.15.0" +oauth2 = "4.3.0" +async-imap = { version = "0.9.1", default-features = false, features = [ + "runtime-tokio", +] } +async-native-tls = { version = "0.5.0", default-features = false, features = [ + "runtime-tokio", +] } +serde = { version = "1.0", features = ["derive"] } +webbrowser = "0.8.11" +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"] } +ether-email-auth-utils = { path = "../utils" } +futures = "0.3.28" +sqlx = { version = "=0.7.3", features = ["postgres", "runtime-tokio"] } +regex = "1.10.2" +axum = "0.6.20" +rand = "0.8.5" +reqwest = "0.11.22" +num-bigint = { version = "0.4", features = ["rand"] } +num-traits = "0.2.16" +hex = "0.4.3" +chrono = "0.4.31" +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", + "release_max_level_warn", +] } +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" + +[build-dependencies] +ethers = "2.0.10" diff --git a/packages/relayer/src/config.rs b/packages/relayer/src/config.rs new file mode 100644 index 00000000..61a846f4 --- /dev/null +++ b/packages/relayer/src/config.rs @@ -0,0 +1,76 @@ +use crate::*; + +pub static CIRCUITS_DIR_PATH: OnceLock = OnceLock::new(); +pub static WEB_SERVER_ADDRESS: OnceLock = OnceLock::new(); +pub static RELAYER_RAND: OnceLock = OnceLock::new(); +pub static PROVER_ADDRESS: OnceLock = OnceLock::new(); +pub static PRIVATE_KEY: OnceLock = OnceLock::new(); +pub static CHAIN_ID: OnceLock = OnceLock::new(); +pub static CHAIN_RPC_PROVIDER: OnceLock = OnceLock::new(); +pub static CHAIN_RPC_EXPLORER: OnceLock = OnceLock::new(); +pub static CORE_CONTRACT_ADDRESS: OnceLock = OnceLock::new(); +pub static FEE_PER_GAS: OnceLock = OnceLock::new(); +pub static INPUT_FILES_DIR: OnceLock = OnceLock::new(); +pub static RECEIVED_EMAILS_DIR: OnceLock = OnceLock::new(); +pub static EMAIL_TEMPLATES: OnceLock = OnceLock::new(); +pub static RELAYER_EMAIL_ADDRESS: OnceLock = OnceLock::new(); +pub static CANISTER_ID: OnceLock = OnceLock::new(); +pub static IC_PEM_PATH: OnceLock = OnceLock::new(); +pub static IC_REPLICA_URL: OnceLock = OnceLock::new(); + +use std::{env, path::PathBuf}; + +use anyhow::{anyhow, Result}; +use dotenv::dotenv; + +pub fn setup_configs() -> Result<()> { + let relayer_rand = env::var("RELAYER_RAND").unwrap(); + RELAYER_RAND.set(relayer_rand); + + let web_server_address = env::var("WEB_SERVER_ADDRESS").unwrap(); + WEB_SERVER_ADDRESS.set(web_server_address); + + let prover_address = env::var("PROVER_ADDRESS").unwrap(); + PROVER_ADDRESS.set(prover_address); + + let private_key = env::var("PRIVATE_KEY").unwrap(); + PRIVATE_KEY.set(private_key); + + let chain_id = env::var("CHAIN_ID").unwrap().parse().unwrap(); + CHAIN_ID.set(chain_id); + + let chain_rpc_provider = env::var("CHAIN_RPC_PROVIDER").unwrap(); + CHAIN_RPC_PROVIDER.set(chain_rpc_provider); + + let chain_rpc_explorer = env::var("CHAIN_RPC_EXPLORER").unwrap(); + CHAIN_RPC_EXPLORER.set(chain_rpc_explorer); + + let core_contract_address = env::var("CORE_CONTRACT_ADDRESS").unwrap(); + CORE_CONTRACT_ADDRESS.set(core_contract_address); + + let fee_per_gas = env::var("FEE_PER_GAS").unwrap(); + let fee_per_gas = U256::from_dec_str(&fee_per_gas).unwrap(); + FEE_PER_GAS.set(fee_per_gas); + + let input_files_dir = env::var("INPUT_FILES_DIR").unwrap(); + INPUT_FILES_DIR.set(input_files_dir); + + let received_emails_dir = env::var("RECEIVED_EMAILS_DIR").unwrap(); + RECEIVED_EMAILS_DIR.set(received_emails_dir); + + let email_templates = env::var("EMAIL_TEMPLATES").unwrap(); + EMAIL_TEMPLATES.set(email_templates); + + let relayer_email_address = env::var("RELAYER_EMAIL_ADDRESS").unwrap(); + RELAYER_EMAIL_ADDRESS.set(relayer_email_address); + + let canister_id = env::var("CANISTER_ID").unwrap(); + CANISTER_ID.set(canister_id); + + let ic_pem_path = env::var("IC_PEM_PATH").unwrap(); + IC_PEM_PATH.set(ic_pem_path); + + let ic_replica_url = env::var("IC_REPLICA_URL").unwrap(); + IC_REPLICA_URL.set(ic_replica_url); + Ok(()) +} diff --git a/packages/relayer/src/database.rs b/packages/relayer/src/database.rs new file mode 100644 index 00000000..e4bd1f43 --- /dev/null +++ b/packages/relayer/src/database.rs @@ -0,0 +1,360 @@ +use crate::*; + +use sqlx::{postgres::PgPool, Row}; + +pub struct Database { + db: PgPool, +} + +impl Database { + pub(crate) async fn open(path: &str) -> Result { + let res = Self { + db: PgPool::connect(path) + .await + .map_err(|e| anyhow::anyhow!(e))?, + }; + + res.setup_database().await?; + + Ok(res) + } + + pub(crate) async fn setup_database(&self) -> Result<()> { + sqlx::query( + "CREATE TABLE IF NOT EXISTS users ( + email_address TEXT PRIMARY KEY, + account_key TEXT NOT NULL, + tx_hash TEXT NOT NULL, + is_onborded BOOLEAN NOT NULL DEFAULT FALSE + );", + ) + .execute(&self.db) + .await?; + + sqlx::query( + "CREATE TABLE IF NOT EXISTS claims ( + id TEXT PRIMARY KEY, + email_address TEXT NOT NULL, + random TEXT NOT NULL, + email_addr_commit TEXT NOT NULL, + expiry_time BIGINT NOT NULL, + is_fund BOOLEAN NOT NULL, + is_announced BOOLEAN NOT NULL, + is_deleted BOOLEAN NOT NULL DEFAULT FALSE, + is_seen BOOLEAN NOT NULL DEFAULT FALSE + );", + ) + .execute(&self.db) + .await?; + + Ok(()) + } + + // pub(crate) async fn get_unhandled_emails(&self) -> Result> { + // let mut vec = Vec::new(); + + // let rows = sqlx::query("SELECT email FROM emails") + // .fetch_all(&self.db) + // .await?; + + // for row in rows { + // let email: String = row.get("email"); + // vec.push(email) + // } + + // Ok(vec) + // } + + // pub(crate) async fn insert_email(&self, email_hash: &str, email: &str) -> Result<()> { + // info!("email_hash {}", email_hash); + // let row = sqlx::query( + // "INSERT INTO emails (email_hash, email) VALUES ($1 $2) REtURNING (email_hash)", + // ) + // .bind(email_hash) + // .bind(email) + // .fetch_one(&self.db) + // .await?; + // info!("inserted row: {}", row.get::("email_hash")); + // Ok(()) + // } + + // pub(crate) async fn delete_email(&self, email_hash: &str) -> Result<()> { + // let row_affected = sqlx::query("DELETE FROM emails WHERE email_hash = $1") + // .bind(email_hash) + // .execute(&self.db) + // .await? + // .rows_affected(); + // info!("deleted {} rows", row_affected); + + // Ok(()) + // } + + // // Result is bad - fix later (possible solution: to output Result + // // where, ReturnStatus is some Enum ... + // pub(crate) async fn contains_email(&self, email_hash: &str) -> Result { + // let result = sqlx::query("SELECT 1 FROM emails WHERE email_hash = $1") + // .bind(email_hash) + // .fetch_optional(&self.db) + // .await?; + + // Ok(result.is_some()) + // } + + #[named] + pub(crate) async fn insert_user( + &self, + email_address: &str, + account_key: &str, + tx_hash: &str, + is_onborded: bool, + ) -> Result<()> { + let row = sqlx::query( + "INSERT INTO users (email_address, account_key, tx_hash, is_onborded) VALUES ($1, $2, $3, $4) RETURNING *", + ) + .bind(email_address) + .bind(account_key) + .bind(tx_hash) + .bind(is_onborded) + .fetch_one(&self.db) + .await?; + info!( + LOG, + "inserted row: {}", + row.get::("email_address"); "func" => function_name!() + ); + Ok(()) + } + + #[named] + pub async fn user_onborded(&self, email_address: &str, tx_hash: &str) -> Result<()> { + info!(LOG, "email_address {}", email_address; "func" => function_name!()); + let res = sqlx::query( + "UPDATE users SET is_onborded = TRUE, tx_hash = $1 WHERE email_address = $2", + ) + .bind(tx_hash) + .bind(email_address) + .execute(&self.db) + .await?; + info!( + LOG, + "updated result: {:?}", + res; "func" => function_name!() + ); + Ok(()) + } + + pub async fn get_claims_by_id(&self, id: &U256) -> Result> { + let mut vec = Vec::new(); + + let rows = sqlx::query("SELECT * FROM claims WHERE id = $1 AND is_deleted = FALSE") + .bind(u256_to_hex(id)) + .fetch_all(&self.db) + .await?; + + for row in rows { + let commit: String = row.get("email_addr_commit"); + let email_address: String = row.get("email_address"); + let random: String = row.get("random"); + let expiry_time: i64 = row.get("expiry_time"); + let is_fund: bool = row.get("is_fund"); + let is_announced: bool = row.get("is_announced"); + let is_seen: bool = row.get("is_seen"); + vec.push(Claim { + id: *id, + email_address, + random, + commit, + expiry_time, + is_fund, + is_announced, + is_seen, + }) + } + Ok(vec) + } + + pub async fn get_claims_by_email_addr(&self, email_addr: &str) -> Result> { + let mut vec = Vec::new(); + + let rows = + sqlx::query("SELECT * FROM claims WHERE email_address = $1 AND is_deleted = FALSE") + .bind(email_addr) + .fetch_all(&self.db) + .await?; + + for row in rows { + let id: String = row.get("id"); + let commit: String = row.get("email_addr_commit"); + let email_address: String = row.get("email_address"); + let random: String = row.get("random"); + let expiry_time: i64 = row.get("expiry_time"); + let is_fund: bool = row.get("is_fund"); + let is_announced: bool = row.get("is_announced"); + let is_seen: bool = row.get("is_seen"); + vec.push(Claim { + id: hex_to_u256(&id)?, + email_address, + random, + commit, + expiry_time, + is_fund, + is_announced, + is_seen, + }) + } + Ok(vec) + } + + #[named] + pub async fn get_claims_unexpired(&self, now: i64) -> Result> { + let mut vec = Vec::new(); + info!(LOG, "now {}", now; "func" => function_name!()); + let rows = + sqlx::query("SELECT * FROM claims WHERE expiry_time > $1 AND is_deleted = FALSE") + .bind(now) + .fetch_all(&self.db) + .await?; + + for row in rows { + let id: String = row.get("id"); + let commit: String = row.get("email_addr_commit"); + let email_address: String = row.get("email_address"); + let random: String = row.get("random"); + let expiry_time: i64 = row.get("expiry_time"); + let is_fund: bool = row.get("is_fund"); + let is_announced: bool = row.get("is_announced"); + let is_seen: bool = row.get("is_seen"); + vec.push(Claim { + id: hex_to_u256(&id)?, + email_address, + random, + commit, + expiry_time, + is_fund, + is_announced, + is_seen, + }) + } + Ok(vec) + } + + #[named] + pub async fn get_claims_expired(&self, now: i64) -> Result> { + let mut vec = Vec::new(); + info!(LOG, "now {}", now; "func" => function_name!()); + let rows = + sqlx::query("SELECT * FROM claims WHERE expiry_time < $1 AND is_deleted = FALSE") + .bind(now) + .fetch_all(&self.db) + .await?; + + for row in rows { + let id: String = row.get("id"); + let commit: String = row.get("email_addr_commit"); + let email_address: String = row.get("email_address"); + let random: String = row.get("random"); + let expiry_time: i64 = row.get("expiry_time"); + let is_fund: bool = row.get("is_fund"); + let is_announced: bool = row.get("is_announced"); + let is_seen: bool = row.get("is_seen"); + vec.push(Claim { + id: hex_to_u256(&id)?, + email_address, + random, + commit, + expiry_time, + is_fund, + is_announced, + is_seen, + }) + } + Ok(vec) + } + + #[named] + pub(crate) async fn insert_claim(&self, claim: &Claim) -> Result<()> { + info!(LOG, "expiry_time {}", claim.expiry_time; "func" => function_name!()); + let row = sqlx::query( + "INSERT INTO claims (id, email_address, random, email_addr_commit, expiry_time, is_fund, is_announced, is_seen) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *", + ) + .bind(u256_to_hex(&claim.id)) + .bind(claim.email_address.clone()) + .bind(claim.random.clone()) + .bind(claim.commit.clone()) + .bind(claim.expiry_time) + .bind(claim.is_fund) + .bind(claim.is_announced) + .bind(claim.is_seen) + .fetch_one(&self.db) + .await?; + info!( + LOG, + "inserted row: {}", + row.get::("email_addr_commit"); "func" => function_name!() + ); + Ok(()) + } + + pub(crate) async fn delete_claim(&self, id: &U256, is_fund: bool) -> Result<()> { + sqlx::query("UPDATE claims SET is_deleted=TRUE WHERE id = $1 AND is_fund = $2 AND is_deleted = FALSE") + .bind(u256_to_hex(id)) + .bind(is_fund) + .execute(&self.db) + .await?; + // sqlx::query("DELETE FROM claims WHERE id = $1 AND is_fund = $2") + // .bind(u256_to_hex(id)) + // .bind(is_fund) + // .execute(&self.db) + // .await?; + Ok(()) + } + + pub async fn contains_user(&self, email_address: &str) -> Result { + let result = sqlx::query("SELECT 1 FROM users WHERE email_address = $1") + .bind(email_address) + .fetch_optional(&self.db) + .await?; + + Ok(result.is_some()) + } + + pub async fn is_user_onborded(&self, email_address: &str) -> Result { + let result = sqlx::query("SELECT is_onborded FROM users WHERE email_address = $1") + .bind(email_address) + .fetch_one(&self.db) + .await?; + Ok(result.get("is_onborded")) + } + + pub async fn get_account_key(&self, email_address: &str) -> Result> { + let row_result = sqlx::query("SELECT account_key FROM users WHERE email_address = $1") + .bind(email_address) + .fetch_one(&self.db) + .await; + + match row_result { + Ok(row) => { + let account_key: String = row.get("account_key"); + Ok(Some(account_key)) + } + Err(sqlx::error::Error::RowNotFound) => Ok(None), + Err(e) => Err(e).map_err(|e| anyhow::anyhow!(e))?, + } + } + + pub async fn get_creation_tx_hash(&self, email_address: &str) -> Result> { + let row_result = sqlx::query("SELECT tx_hash FROM users WHERE email_address = $1") + .bind(email_address) + .fetch_one(&self.db) + .await; + + match row_result { + Ok(row) => { + let tx_hash: String = row.get("tx_hash"); + Ok(Some(tx_hash)) + } + Err(sqlx::error::Error::RowNotFound) => Ok(None), + Err(e) => Err(e).map_err(|e| anyhow::anyhow!(e))?, + } + } +} diff --git a/packages/relayer/src/dkim_oracle.rs b/packages/relayer/src/dkim_oracle.rs new file mode 100644 index 00000000..d5c25253 --- /dev/null +++ b/packages/relayer/src/dkim_oracle.rs @@ -0,0 +1,62 @@ +use anyhow::anyhow; + +use candid::CandidType; +use ic_agent::agent::http_transport::ReqwestTransport; +use ic_agent::agent::*; +use ic_agent::identity::*; +use ic_utils::canister::*; + +use serde::Deserialize; + +#[derive(Debug, Clone)] +pub struct DkimOracleClient<'a> { + pub(crate) canister: Canister<'a>, +} + +#[derive(Default, CandidType, Deserialize, Debug, Clone)] +pub struct SignedDkimPublicKey { + pub selector: String, + pub domain: String, + pub signature: String, + pub public_key: String, + pub public_key_hash: String, +} + +impl<'a> DkimOracleClient<'a> { + pub fn gen_agent(pem_path: &str, replica_url: &str) -> anyhow::Result { + let identity = Secp256k1Identity::from_pem_file(pem_path)?; + let transport = ReqwestTransport::create(replica_url)?; + let agent = AgentBuilder::default() + .with_identity(identity) + .with_transport(transport) + .build()?; + Ok(agent) + } + + pub fn new(canister_id: &str, agent: &'a Agent) -> anyhow::Result { + let canister = CanisterBuilder::new() + .with_canister_id(canister_id) + .with_agent(&agent) + .build()?; + Ok(Self { canister }) + } + + 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)))?; + + // let result = Decode!(&response, String)?; + Ok(response) + } +} diff --git a/packages/relayer/src/emails_pool.rs b/packages/relayer/src/emails_pool.rs new file mode 100644 index 00000000..aadc2fec --- /dev/null +++ b/packages/relayer/src/emails_pool.rs @@ -0,0 +1,75 @@ +use crate::*; +use anyhow::Result; +use async_trait::async_trait; +use std::fs; +use std::path::PathBuf; + +#[async_trait] +pub(crate) trait EmailsPool { + async fn get_unhandled_emails(&self) -> Result>; + + async fn get_email_by_hash(&self, email_hash: &str) -> Result; + + async fn insert_email(&self, email_hash: &str, email: &str) -> Result<()>; + + async fn delete_email(&self, email_hash: &str) -> Result<()>; + + // Result is bad - fix later (possible solution: to output Result + // where, ReturnStatus is some Enum ... + async fn contains_email(&self, email_hash: &str) -> Result; +} + +pub struct FileEmailsPool { + dir_path: String, +} + +#[async_trait] +impl EmailsPool for FileEmailsPool { + async fn get_unhandled_emails(&self) -> Result> { + let dir = fs::read_dir(&self.dir_path)?; + let mut emails = Vec::new(); + for path in dir.into_iter() { + let path = path?.path(); + let email = fs::read_to_string(path)?; + emails.push((calculate_default_hash(&email), email)); + } + Ok(emails) + } + + async fn get_email_by_hash(&self, email_hash: &str) -> Result { + let file_path = self.email_hash_to_path(email_hash); + let email = fs::read_to_string(file_path)?; + Ok(email) + } + + async fn insert_email(&self, email_hash: &str, email: &str) -> Result<()> { + let file_path = self.email_hash_to_path(email_hash); + fs::write(file_path, email)?; + Ok(()) + } + + async fn delete_email(&self, email_hash: &str) -> Result<()> { + let file_path = self.email_hash_to_path(email_hash); + fs::remove_file(file_path)?; + Ok(()) + } + + async fn contains_email(&self, email_hash: &str) -> Result { + let file_path = self.email_hash_to_path(email_hash); + Ok(file_path.exists()) + } +} + +impl FileEmailsPool { + #[named] + pub fn new() -> Self { + let dir_path = RECEIVED_EMAILS_DIR.get().unwrap(); + info!(LOG, "dir_path: {}", dir_path; "func" => function_name!()); + fs::create_dir_all(&dir_path).unwrap(); + Self { dir_path } + } + + fn email_hash_to_path(&self, email_hash: &str) -> PathBuf { + PathBuf::from(&self.dir_path).join(format!("{}.eml", email_hash)) + } +} diff --git a/packages/relayer/src/imap_client.rs b/packages/relayer/src/imap_client.rs new file mode 100644 index 00000000..6a595714 --- /dev/null +++ b/packages/relayer/src/imap_client.rs @@ -0,0 +1,223 @@ +use crate::*; + +use std::time::Duration; + +use anyhow::anyhow; +use async_imap::{types::Fetch, Session}; +use async_native_tls::TlsStream; +use futures::TryStreamExt; +use oauth2::reqwest::async_http_client; +use oauth2::{ + basic::BasicClient, AuthUrl, AuthorizationCode, ClientId, ClientSecret, CsrfToken, + PkceCodeChallenge, RedirectUrl, Scope, TokenResponse, TokenUrl, +}; +use tokio::net::TcpStream; + +#[derive(Clone)] +pub(crate) enum ImapAuth { + Password { + user_id: String, + password: String, + }, + Oauth { + user_id: String, + client_id: String, + client_secret: String, + auth_url: String, + token_url: String, + redirect_url: String, + }, +} + +#[derive(Clone)] +pub(crate) struct ImapConfig { + pub(crate) domain_name: String, + pub(crate) port: u16, + pub(crate) auth: ImapAuth, + pub(crate) initially_checked: bool, +} + +struct OAuth2 { + user_id: String, + access_token: String, +} + +impl async_imap::Authenticator for &OAuth2 { + type Response = String; + + fn process(&mut self, _: &[u8]) -> Self::Response { + format!( + "user={}\x01auth=Bearer {}\x01\x01", + self.user_id, self.access_token + ) + } +} + +pub(crate) struct ImapClient { + session: Session>, + config: ImapConfig, +} + +impl ImapClient { + #[named] + pub(crate) async fn new(config: ImapConfig) -> Result { + let tcp_stream = TcpStream::connect((&*config.domain_name, config.port)).await?; + let tls = async_native_tls::TlsConnector::new(); + let tls_stream = tls.connect(&*config.domain_name, tcp_stream).await?; + let client = async_imap::Client::new(tls_stream); + + let mut session = match config.auth.clone() { + ImapAuth::Password { user_id, password } => { + client.login(user_id, password).await.map_err(|e| e.0) + } + ImapAuth::Oauth { + user_id, + client_id, + client_secret, + auth_url, + token_url, + redirect_url, + } => { + let oauth_client = BasicClient::new( + ClientId::new(client_id), + Some(ClientSecret::new(client_secret)), + AuthUrl::new(auth_url)?, + Some(TokenUrl::new(token_url)?), + ) + .set_redirect_uri(RedirectUrl::new(redirect_url)?); + + let (pkce_challenge, pkce_verifier) = PkceCodeChallenge::new_random_sha256(); + let (auth_url, _) = oauth_client + .authorize_url(CsrfToken::new_random) + .add_scope(Scope::new("https://mail.google.com/".to_string())) + .set_pkce_challenge(pkce_challenge) + .url(); + + let server = tiny_http::Server::http("127.0.0.1:8000").unwrap(); + webbrowser::open(auth_url.as_ref())?; + let request = server.recv()?; + let url = request.url().to_string(); + let auth_code = url.split("code=").collect::>()[1] + .split('&') + .next() + .unwrap_or(""); + let response = + tiny_http::Response::from_string("You can close this window now.".to_string()); + request.respond(response).unwrap(); + + trace!(LOG, "Auth Code that I captured {}", auth_code; "func" => function_name!()); + + let token_result = oauth_client + .exchange_code(AuthorizationCode::new(auth_code.to_string())) + .set_pkce_verifier(pkce_verifier) + .request_async(async_http_client) + .await?; + + let access_token = serde_json::to_string(token_result.access_token())?; + let oauthed = OAuth2 { + user_id, + access_token, + }; + + client + .authenticate("XOAUTH2", &oauthed) + .await + .map_err(|e| e.0) + } + }?; + + session.select("INBOX").await?; + + trace!(LOG, "ImapClient connected succesfully!"; "func" => function_name!()); + + Ok(Self { session, config }) + } + + #[named] + pub(crate) async fn retrieve_new_emails(&mut self) -> Result>> { + if !self.config.initially_checked { + self.config.initially_checked = true; + let result = + tokio::time::timeout(Duration::from_secs(10), self.get_unseen_emails()).await; + if let Ok(Ok(result)) = result { + return Ok(result); + } + } + + // let mut new_client = self.wait_new_email().await?; + trace!(LOG, "Reconnecting..."; "func" => function_name!()); + self.reconnect().await?; + trace!(LOG, "Reconnected!"; "func" => function_name!()); + // Ok((new_client.get_unseen_emails().await?, new_client)) + Ok(self.get_unseen_emails().await?) + } + + #[named] + async fn get_unseen_emails(&mut self) -> Result>> { + trace!(LOG, "Getting unseen emails..."; "func" => function_name!()); + loop { + match self.session.uid_search("UNSEEN").await { + Ok(uids) => { + trace!(LOG, "Got unseen emails: {:?}!", uids; "func" => function_name!()); + let mut results = vec![]; + for uid in uids { + let res = self + .session + .uid_fetch(uid.to_string(), "(BODY[] ENVELOPE)") + .await?; + let res = res.try_collect::>().await?; + results.push(res); + } + trace!(LOG, "Got unseen emails: {:?}!", results; "func" => function_name!()); + return Ok(results); + } + Err(e) => { + error!(LOG, "Connection reset, reconnecting..."; "func" => function_name!()); + self.reconnect().await?; + } + } + } + } + + // async fn wait_new_email(mut self) -> Result { + // loop { + // let mut idle = self.session.idle(); + // idle.init().await?; + // let result = idle.wait_with_timeout(Duration::from_secs(29 * 60)).0.await; + // let is_new_data = matches!(result, Ok(NewData(_))); + + // let session_result = idle.done().await; + + // self = match session_result { + // Ok(session) => Self { session, ..self }, + // Err(_) => Self::new(self.config).await.unwrap(), + // }; + + // if is_new_data { + // return Ok(self); + // } else { + // self.reconnect().await?; + // } + // } + // } + + async fn reconnect(&mut self) -> Result<()> { + const MAX_RETRIES: u32 = 5; + let mut retry_count = 0; + + while retry_count < MAX_RETRIES { + match ImapClient::new(self.config.clone()).await { + Ok(new_client) => { + self.session = new_client.session; + return Ok(()); + } + Err(_) => { + retry_count += 1; + std::thread::sleep(std::time::Duration::from_millis(1000)); + } + } + } + + Err(anyhow!("{IMAP_RECONNECT_ERROR}")) + } +} diff --git a/packages/relayer/src/lib.rs b/packages/relayer/src/lib.rs new file mode 100644 index 00000000..d425a97e --- /dev/null +++ b/packages/relayer/src/lib.rs @@ -0,0 +1,21 @@ +pub(crate) mod config; +pub(crate) mod database; +pub(crate) mod dkim_oracle; +pub(crate) mod emails_pool; +pub(crate) mod imap_client; +pub(crate) mod logger; +pub(crate) mod smtp_client; +pub(crate) mod subject_templates; +pub(crate) mod utils; +pub(crate) mod web_server; +use anyhow::{anyhow, Result}; +pub(crate) use config::*; +pub(crate) use database::*; +pub(crate) use dkim_oracle::*; +pub(crate) use emails_pool::*; +pub(crate) use imap_client::*; +pub(crate) use logger::*; +pub(crate) use smtp_client::*; +pub(crate) use subject_templates::*; +pub(crate) use utils::*; +pub(crate) use web_server::*; diff --git a/packages/relayer/src/logger.rs b/packages/relayer/src/logger.rs new file mode 100644 index 00000000..b13b4bed --- /dev/null +++ b/packages/relayer/src/logger.rs @@ -0,0 +1,54 @@ +use file_rotate::{ + compression::Compression, + suffix::{AppendTimestamp, FileLimit}, + ContentLimit, FileRotate, +}; +use lazy_static::lazy_static; +use slog::{o, Drain}; +use slog_async; +use slog_json; +use slog_term; +use std::env; + +lazy_static! { + pub static ref LOG: slog::Logger = init_logger(); +} + +fn init_logger() -> slog::Logger { + let directory = std::path::Path::new("logs"); + let log_path = directory.join("relayer.log"); + let file_rotate = FileRotate::new( + log_path.clone(), + AppendTimestamp::default(FileLimit::MaxFiles(1_000_000)), + ContentLimit::Bytes(5_000_000), + Compression::OnRotate(5), + #[cfg(unix)] + None, + ); + let log_file_drain = slog_json::Json::default(file_rotate).fuse(); + + // Check if LOGGER env var is set and true or True or TRUE, if not, set false + let terminal_json_output = match env::var("JSON_LOGGER") { + Ok(val) => val.eq_ignore_ascii_case("true"), + Err(_) => false, + }; + + let log_terminal_decorator = slog_term::TermDecorator::new().build(); + let log_terminal_drain = slog_term::FullFormat::new(log_terminal_decorator) + .build() + .fuse(); + let log_terminal_json_drain = slog_json::Json::default(std::io::stdout()).fuse(); + + if terminal_json_output { + let log_drain = + slog_async::Async::new(slog::Duplicate(log_terminal_json_drain, log_file_drain).fuse()) + .build() + .fuse(); + return slog::Logger::root(log_drain, o!("version" => env!("CARGO_PKG_VERSION"))); + } + let log_drain = + slog_async::Async::new(slog::Duplicate(log_terminal_drain, log_file_drain).fuse()) + .build() + .fuse(); + slog::Logger::root(log_drain, o!("version" => env!("CARGO_PKG_VERSION"))) +} diff --git a/packages/relayer/src/main.rs b/packages/relayer/src/main.rs new file mode 100644 index 00000000..09345041 --- /dev/null +++ b/packages/relayer/src/main.rs @@ -0,0 +1 @@ +use relayer::*; diff --git a/packages/relayer/src/selector_def.json b/packages/relayer/src/selector_def.json new file mode 100644 index 00000000..609b00e1 --- /dev/null +++ b/packages/relayer/src/selector_def.json @@ -0,0 +1,20 @@ +{ + "parts": [ + { + "is_public": false, + "regex_def": "((\r\n)|^)dkim-signature:" + }, + { + "is_public": false, + "regex_def": "((a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z)+=[^;]+; )+s=" + }, + { + "is_public": true, + "regex_def": "(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|-|_)+" + }, + { + "is_public": false, + "regex_def": ";" + } + ] +} \ No newline at end of file diff --git a/packages/relayer/src/smtp_client.rs b/packages/relayer/src/smtp_client.rs new file mode 100644 index 00000000..fee7efae --- /dev/null +++ b/packages/relayer/src/smtp_client.rs @@ -0,0 +1,146 @@ +#![allow(unused_imports)] + +use crate::*; + +use anyhow::anyhow; +use handlebars::Handlebars; +use lettre::{ + message::{ + header::{Cc, From, Header, HeaderName, InReplyTo, ReplyTo, To}, + Attachment, Mailbox, Mailboxes, MessageBuilder, MultiPart, SinglePart, + }, + transport::smtp::{ + authentication::Credentials, client::SmtpConnection, commands::*, extension::ClientId, + SMTP_PORT, + }, + Address, AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor, +}; +use serde_json::Value; +use tokio::fs::read_to_string; + +#[derive(Debug, Clone)] +pub struct EmailMessage { + pub to: String, + pub subject: String, + pub reference: Option, + pub reply_to: Option, + pub body_plain: String, + pub body_html: String, + pub body_attachments: Option>, +} + +#[derive(Debug, Clone)] +pub struct EmailAttachment { + pub inline_id: String, + pub content_type: String, + pub contents: Vec, +} + +#[derive(Clone)] +pub(crate) struct SmtpConfig { + pub(crate) domain_name: String, + pub(crate) id: String, + pub(crate) password: String, +} + +pub(crate) struct SmtpClient { + config: SmtpConfig, + transport: AsyncSmtpTransport, +} + +impl SmtpClient { + pub(crate) fn new(config: SmtpConfig) -> Result { + let creds = Credentials::new(config.id.clone(), config.password.clone()); + let transport = AsyncSmtpTransport::::relay(&config.domain_name)? + .credentials(creds) + .build(); + + Ok(Self { config, transport }) + } + + pub(crate) async fn send_new_email(&self, email: EmailMessage) -> Result<()> { + self.send_inner( + email.to, + email.subject, + email.reference, + email.reply_to, + email.body_plain, + email.body_html, + email.body_attachments, + ) + .await + } + + async fn send_inner( + &self, + to: String, + subject: String, + reference: Option, + reply_to: Option, + body_plain: String, + body_html: String, + body_attachments: Option>, + ) -> Result<()> { + let from_mbox = Mailbox::new(None, self.config.id.parse::
()?); + let to_mbox = Mailbox::new(None, to.parse::
()?); + + let mut email_builder = Message::builder() + .from(from_mbox) + .subject(subject) + .to(to_mbox); + if let Some(reference) = reference { + email_builder = email_builder.references(reference); + } + if let Some(reply_to) = reply_to { + email_builder = email_builder.in_reply_to(reply_to); + } + let mut multipart = MultiPart::related().singlepart(SinglePart::html(body_html)); + if let Some(body_attachments) = body_attachments { + for attachment in body_attachments { + multipart = multipart.singlepart( + Attachment::new_inline(attachment.inline_id) + .body(attachment.contents, attachment.content_type.parse()?), + ); + } + } + let email = email_builder.multipart( + MultiPart::alternative() + .singlepart(SinglePart::plain(body_plain)) + .multipart(multipart), + )?; + + self.transport.send(email).await?; + + Ok(()) + } + + fn reconnect(mut self) -> Result<()> { + const MAX_RETRIES: u32 = 5; + let mut retry_count = 0; + + while retry_count < MAX_RETRIES { + match SmtpClient::new(self.config.clone()) { + Ok(new_client) => { + self.transport = new_client.transport; + return Ok(()); + } + Err(_) => { + retry_count += 1; + std::thread::sleep(std::time::Duration::from_millis(1000)); + } + } + } + + Err(anyhow!("{SMTP_RECONNECT_ERROR}")) + } +} + +pub async fn render_html(template_name: &str, render_data: Value) -> Result { + let email_template_filename = PathBuf::new() + .join(EMAIL_TEMPLATES.get().unwrap()) + .join(template_name); + let email_template = read_to_string(&email_template_filename).await?; + + let reg = Handlebars::new(); + Ok(reg.render_template(&email_template, &render_data)?) +} diff --git a/packages/relayer/src/subject_templates.rs b/packages/relayer/src/subject_templates.rs new file mode 100644 index 00000000..b7a475d9 --- /dev/null +++ b/packages/relayer/src/subject_templates.rs @@ -0,0 +1,228 @@ +#![allow(clippy::upper_case_acronyms)] + +use crate::*; + +use ethers::abi::{self, Token}; +use ethers::types::{Address, Bytes, I256, U256}; +use regex::Regex; + +#[derive(Debug, Clone)] +pub enum TemplateValue { + String(String), + Uint(U256), + Int(I256), + Decimals(String), + EthAddr(Address), + Fixed(String), +} + +pub(crate) const STRING_RGEX: &str = ".+"; +pub(crate) const UINT_REGEX: &str = "[0-9]+"; +pub(crate) const INT_REGEX: &str = "-?[0-9]+"; +pub(crate) const DECIMALS_REGEX: &str = "[0-9]+(\\.[0-9]+)?"; +pub(crate) const ETH_ADDR_REGEX: &str = "0x[0-9a-fA-F]{40}"; +// pub(crate) const EMAIL_ADDR_REGEX: &str = +// "[a-zA-Z0-9!#$%&'\\*\\+-/=\\?^_`{\\|}~\\.]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9\\.-]+"; + +impl TemplateValue { + #[named] + 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), + )]))), + 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_idx( + input: &str, + templates_array: Vec>, +) -> Result<(Option, Vec)> { + for (idx, templates) in templates_array.into_iter().enumerate() { + let template_vals = extract_template_vals(input, templates); + match template_vals { + Ok(vals) => { + return Ok((Some(idx), vals)); + } + Err(_) => { + continue; + } + } + } + Ok((None, Vec::new())) +} + +pub fn extract_template_vals(input: &str, templates: Vec) -> Result> { + let input_decomposed: Vec<&str> = input.split(' ').collect(); + let mut template_vals = Vec::new(); + let mut input_idx = 0; + for template in templates.iter() { + match template.as_str() { + "{string}" => { + let string_match = Regex::new(STRING_RGEX) + .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)); + input_idx += 1; + } + "{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)); + input_idx += 1; + } + "{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_str = int_match.as_str(); + let int = I256::from_dec_str(int_match.as_str()).unwrap(); + template_vals.push(TemplateValue::Int(int)); + input_idx += 1; + } + "{decimals}" => { + let decimals_match = Regex::new(DECIMALS_REGEX) + .unwrap() + .find(input_decomposed[input_idx]) + .ok_or(anyhow!("No amount found"))?; + if decimals_match.start() != 0 + || decimals_match.end() != input_decomposed[input_idx].len() + { + return Err(anyhow!("Amount must be the whole word")); + } + let decimals = decimals_match.as_str().to_string(); + template_vals.push(TemplateValue::Decimals(decimals)); + input_idx += 1; + } + "{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::Address(address)); + input_idx += 1; + } + _ => { + input_idx += 1; + } + } + } + if input_idx != input_decomposed.len() { + return Err(anyhow!("Input is not fully consumed")); + } + 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] = amount_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.rs b/packages/relayer/src/utils.rs new file mode 100644 index 00000000..b388a04f --- /dev/null +++ b/packages/relayer/src/utils.rs @@ -0,0 +1,185 @@ +#![allow(clippy::upper_case_acronyms)] +#![allow(clippy::identity_op)] + +use crate::*; +use chrono::{DateTime, Local}; +use email_wallet_utils::*; +use ethers::abi::Token; +use ethers::types::{Bytes, U256}; + +use serde::Deserialize; + +use std::path::Path; + +use tokio::{ + fs::{read_to_string, remove_file, File}, + io::AsyncWriteExt, +}; + +use lazy_static::lazy_static; +use std::sync::Arc; +use tokio::sync::Mutex; + +lazy_static! { + pub static ref SHARED_MUTEX: Arc> = Arc::new(Mutex::new(0)); +} + +// Error strings +pub const WRONG_AUTH_METHOD: &str = "Not supported auth type"; +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 INSUFFICIENT_BALANCE: &str = "Insufficient balance"; + +// Core REGEX'es +// pub(crate) const AMOUNT_REGEX: &str = "[0-9]+(\\.[0-9]+)?"; +// pub(crate) const TOKEN_NAME_REGEX: &str = "[A-Z]+"; +// pub(crate) const STRING_RGEX: &str = ".+"; +// pub(crate) const UINT_REGEX: &str = "[0-9]+"; +// pub(crate) const INT_REGEX: &str = "-?[0-9]+"; +// pub(crate) const ETH_ADDR_REGEX: &str = "0x[0-9a-fA-F]{40}"; +// pub(crate) const EMAIL_ADDR_REGEX: &str = +// "[a-zA-Z0-9!#$%&'\\*\\+-/=\\?^_`{\\|}~\\.]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9\\.-]+"; + +pub(crate) const DOMAIN_FIELDS: usize = 9; +pub(crate) const SUBJECT_FIELDS: usize = 17; +pub(crate) 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]))) + } +} + +pub(crate) async fn generate_email_auth_input( + circuits_dir_path: &Path, + email: &str, + account_code: &str, +) -> Result { + let email_hash = calculate_default_hash(email); + let email_file_name = PathBuf::new() + .join(INPUT_FILES_DIR.get().unwrap()) + .join(email_hash.to_string() + ".email"); + let input_file_name = PathBuf::new() + .join(INPUT_FILES_DIR.get().unwrap()) + .join(email_hash.to_string() + ".json"); + + let mut email_file = File::create(&email_file_name).await?; + email_file.write_all(email.as_bytes()).await?; + + let command_str = format!( + "--cwd {} gen-input --email-file {} --account-code {} --input-file {}", + circuits_dir_path.to_str().unwrap(), + email_file_name.to_str().unwrap(), + account_code, + input_file_name.to_str().unwrap() + ); + + let mut proc = tokio::process::Command::new("yarn") + .args(command_str.split_whitespace()) + .spawn()?; + + let status = proc.wait().await?; + assert!(status.success()); + + let result = read_to_string(&input_file_name).await?; + + remove_file(email_file_name).await?; + remove_file(input_file_name).await?; + + Ok(result) +} + +#[named] +pub(crate) 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(crate) fn u256_to_bytes32(x: &U256) -> [u8; 32] { + let mut bytes = [0u8; 32]; + x.to_big_endian(&mut bytes); + bytes +} + +pub(crate) fn u256_to_hex(x: &U256) -> String { + "0x".to_string() + &hex::encode(u256_to_bytes32(x)) +} + +pub(crate) fn hex_to_u256(hex: &str) -> Result { + let bytes: Vec = hex::decode(&hex[2..])?; + let mut array = [0u8; 32]; + array.copy_from_slice(&bytes); + Ok(U256::from_big_endian(&array)) +} + +pub(crate) fn fr_to_bytes32(fr: &Fr) -> Result<[u8; 32]> { + let hex = field2hex(fr); + let bytes = hex::decode(&hex[2..])?; + let mut result = [0u8; 32]; + result.copy_from_slice(&bytes); + Ok(result) +} + +pub(crate) fn bytes32_to_fr(bytes32: &[u8; 32]) -> Result { + let hex: String = "0x".to_string() + &hex::encode(bytes32); + let field = hex2field(&hex)?; + Ok(field) +} + +pub(crate) fn now() -> i64 { + let dt: DateTime = Local::now(); + dt.timestamp() +} diff --git a/packages/relayer/src/web_server.rs b/packages/relayer/src/web_server.rs new file mode 100644 index 00000000..d13040b1 --- /dev/null +++ b/packages/relayer/src/web_server.rs @@ -0,0 +1,190 @@ +use crate::*; + +use std::sync::atomic::Ordering; + +use axum::{routing::MethodRouter, Router}; +use serde::{Deserialize, Serialize}; +use tokio::sync::mpsc::UnboundedSender; +use tower_http::cors::{AllowHeaders, AllowMethods, Any, CorsLayer}; + +#[derive(Serialize, Deserialize)] +pub struct EmailAddrCommitRequest { + pub email_address: String, + pub random: String, +} + +#[derive(Serialize, Deserialize)] +pub struct UnclaimRequest { + pub email_address: String, + pub random: String, + pub expiry_time: i64, + pub is_fund: bool, + pub tx_hash: String, +} + +#[derive(Serialize, Deserialize)] +pub struct AccountRegistrationRequest { + pub email_address: String, + pub account_key: String, +} + +#[derive(Serialize, Deserialize)] +pub struct AccountRegistrationResponse { + pub account_key: String, + pub wallet_addr: String, + pub tx_hash: String, +} + +#[derive(Serialize, Deserialize)] +pub struct StatResponse { + pub onboarding_tokens_distributed: u32, + pub onboarding_tokens_left: u32, +} + +#[named] +async fn unclaim( + payload: UnclaimRequest, + db: Arc, + chain_client: Arc, + tx_claimer: UnboundedSender, +) -> Result { + let padded_email_addr = PaddedEmailAddr::from_email_addr(&payload.email_address); + info!( + LOG, + "padded email address fields: {:?}", + padded_email_addr.to_email_addr_fields(); "func" => function_name!() + ); + let commit = padded_email_addr.to_commitment(&hex2field(&payload.random)?)?; + info!(LOG, "commit {:?}", commit; "func" => function_name!()); + let id = chain_client + .get_unclaim_id_from_tx_hash(&payload.tx_hash, payload.is_fund) + .await?; + info!(LOG, "id {:?}", id; "func" => function_name!()); + // let psi_client = PSIClient::new( + // Arc::clone(&chain_client), + // payload.email_address.clone(), + // id, + // payload.is_fund, + // ) + // .await?; + // psi_client + // .check_and_reveal(db.clone(), chain_client.clone(), &payload.email_address) + // .await?; + let claim = Claim { + id, + email_address: payload.email_address.clone(), + random: payload.random.clone(), + commit: field2hex(&commit), + expiry_time: payload.expiry_time, + is_fund: payload.is_fund, + is_announced: false, + is_seen: false, + }; + tx_claimer.send(claim)?; + trace!(LOG, "claim sent to tx_claimer"; "func" => function_name!()); + + Ok(format!( + "Unclaimed {} for {} is accepted", + if payload.is_fund { "fund" } else { "state" }, + payload.email_address + )) +} + +#[named] +pub(crate) async fn run_server( + addr: &str, + routes: Vec<(String, MethodRouter)>, + db: Arc, + chain_client: Arc, + tx_claimer: UnboundedSender, +) -> Result<()> { + let chain_client_check_clone = Arc::clone(&chain_client); + let chain_client_reveal_clone = Arc::clone(&chain_client); + let tx_claimer_reveal_clone = tx_claimer.clone(); + + let mut app = Router::new() + .route( + "/api/emailAddrCommit", + axum::routing::post(move |payload: String| async move { + info!(LOG, "/emailAddrCommit Received payload: {}", payload; "func" => function_name!()); + let json = serde_json::from_str::(&payload) + .map_err(|_| "Invalid payload json".to_string()) + .unwrap(); + let padded_email_addr = PaddedEmailAddr::from_email_addr(&json.email_address); + let commit = padded_email_addr + .to_commitment(&hex2field(&json.random).unwrap()) + .unwrap(); + info!(LOG, "commit {:?}", commit; "func" => function_name!()); + field2hex(&commit) + }), + ) + .route( + "/api/unclaim", + axum::routing::post(move |payload: String| async move { + info!(LOG, "/unclaim Received payload: {}", payload; "func" => function_name!()); + let json = serde_json::from_str::(&payload) + .map_err(|_| "Invalid payload json".to_string())?; + unclaim(json, db, chain_client, tx_claimer) + .await + .map_err(|err| { + error!(LOG, "Failed to accept unclaim: {}", err; "func" => function_name!()); + err.to_string() + }) + }), + ) + .route( + "/api/stats", + axum::routing::get(move || async move { + let stats = StatResponse { + onboarding_tokens_distributed: ONBOARDING_COUNTER.load(Ordering::SeqCst), + onboarding_tokens_left: *ONBOARDING_TOKEN_DISTRIBUTION_LIMIT.get().unwrap() + - ONBOARDING_COUNTER.load(Ordering::SeqCst), + }; + axum::Json(stats) + }), + ) + .route( + "/api/serveCheck/", + axum::routing::post(move |payload: String| async move { + info!(LOG, "/serveCheck Received payload: {}", payload; "func" => function_name!()); + let json = serde_json::from_str::(&payload) + .map_err(|_| "Invalid payload json".to_string())?; + serve_check_request(json, chain_client_check_clone) + .await + .map_err(|err| { + error!(LOG, "Failed PSI check serve: {}", err; "func" => function_name!()); + err.to_string() + }) + }), + ) + .route( + "/api/serveReveal/", + axum::routing::post(move |payload: String| async move { + info!(LOG, "/serveCheck Received payload: {}", payload; "func" => function_name!()); + let json = serde_json::from_str::(&payload) + .map_err(|_| "Invalid payload json".to_string())?; + serve_reveal_request(json, chain_client_reveal_clone, tx_claimer_reveal_clone) + .await + .map_err(|err| { + error!(LOG, "Failed PSI reveal serve: {}", err; "func" => function_name!()); + err.to_string() + }) + }), + ); + for (path, router) in routes { + app = app.route(&path, router); + } + app = app.layer( + CorsLayer::new() + .allow_methods(AllowMethods::any()) + .allow_headers(AllowHeaders::any()) + .allow_origin(Any), + ); + + trace!(LOG, "Listening API at {}", addr; "func" => function_name!()); + axum::Server::bind(&addr.parse()?) + .serve(app.into_make_service()) + .await?; + + Ok(()) +} From 7ba7f56dd0dc2849bb7b3b3ed255ec11f48ef274 Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Mon, 25 Mar 2024 03:45:07 +0900 Subject: [PATCH 33/42] Update utils and relayer. --- Cargo.lock | 5827 ++++++++++++++++++--- packages/circuits/package.json | 2 +- packages/relayer/src/config.rs | 2 + packages/relayer/src/emails_pool.rs | 4 +- packages/relayer/src/lib.rs | 4 + packages/relayer/src/smtp_client.rs | 2 + packages/relayer/src/subject_templates.rs | 6 +- packages/relayer/src/utils.rs | 18 +- packages/utils/Cargo.toml | 2 +- packages/utils/src/converters.rs | 2 +- packages/utils/src/cryptos.rs | 4 +- packages/utils/src/lib.rs | 8 +- packages/utils/src/regex.rs | 243 + yarn.lock | 8 +- 14 files changed, 5365 insertions(+), 767 deletions(-) create mode 100644 packages/utils/src/regex.rs diff --git a/Cargo.lock b/Cargo.lock index 6d0a318c..727a7ee7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,16 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + [[package]] name = "addr2line" version = "0.21.0" @@ -17,15 +27,45 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -43,9 +83,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.80" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "arrayref" @@ -53,21 +93,147 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + [[package]] name = "arrayvec" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "ascii" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" + +[[package]] +name = "ascii" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" + +[[package]] +name = "ascii-canvas" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" +dependencies = [ + "term", +] + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" +dependencies = [ + "concurrent-queue", + "event-listener 5.2.0", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-imap" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98892ebee4c05fc66757e600a7466f0d9bfcde338f645d64add323789f26cb36" +dependencies = [ + "async-channel 2.2.0", + "base64 0.21.7", + "bytes", + "chrono", + "futures", + "imap-proto", + "log", + "nom", + "once_cell", + "pin-utils", + "self_cell", + "stop-token", + "thiserror", + "tokio", +] + +[[package]] +name = "async-native-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9343dc5acf07e79ff82d0c37899f079db3534d99f189a1837c8e549c99405bec" +dependencies = [ + "native-tls", + "thiserror", + "tokio", + "url", +] + [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "async_io_stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" +dependencies = [ + "futures", + "pharos", + "rustc_version", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atomic-write-file" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8204db279bf648d64fe845bd8840f78b39c8132ed4d6a4194c3b10d4b4cfb0b" +dependencies = [ + "nix", + "rand", +] + +[[package]] +name = "auto_impl" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.55", ] [[package]] @@ -76,11 +242,71 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backoff" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" +dependencies = [ + "getrandom", + "instant", + "rand", +] + [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -91,6 +317,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.13.1" @@ -109,6 +341,35 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "binread" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16598dfc8e6578e9b597d9910ba2e73618385dc9f4b1d43dd92c349d6be6418f" +dependencies = [ + "binread_derive", + "lazy_static", + "rustversion", +] + +[[package]] +name = "binread_derive" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d9672209df1714ee804b1f4d4f68c8eb2a90b1f7a07acf472f88ce198ef1fed" +dependencies = [ + "either", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "bit-set" version = "0.5.3" @@ -130,6 +391,15 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +dependencies = [ + "serde", +] + [[package]] name = "bitvec" version = "1.0.1" @@ -149,8 +419,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" dependencies = [ "arrayref", - "arrayvec", - "constant_time_eq", + "arrayvec 0.7.4", + "constant_time_eq 0.3.0", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", ] [[package]] @@ -162,12 +441,42 @@ 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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "sha2 0.10.8", + "tinyvec", +] + [[package]] name = "bumpalo" version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + [[package]] name = "byteorder" version = "1.5.0" @@ -176,73 +485,310 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +dependencies = [ + "serde", +] [[package]] -name = "cc" -version = "1.0.90" +name = "bzip2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" - -[[package]] -name = "cfdkim" -version = "0.3.0" -source = "git+https://github.com/SoraSuegami/dkim.git#93829027f03a7442392a37b4635471d8b7f49e6b" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" dependencies = [ - "base64 0.21.7", - "chrono", - "console_error_panic_hook", - "ed25519-dalek", - "futures", - "getrandom", - "indexmap", - "js-sys", - "mailparse", - "nom", - "quick-error 2.0.1", - "regex", - "rsa", - "serde_json", - "sha-1", - "sha2", - "slog", - "trust-dns-resolver", - "wasm-bindgen", + "bzip2-sys", + "libc", ] [[package]] -name = "cfg-if" -version = "1.0.0" +name = "bzip2-sys" +version = "0.1.11+1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] [[package]] -name = "charset" -version = "0.1.3" +name = "cached" +version = "0.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e9079d1a12a2cc2bffb5db039c43661836ead4082120d5844f02555aca2d46" +checksum = "c7c8c50262271cdf5abc979a5f76515c234e764fa025d1ba4862c0f0bcda0e95" dependencies = [ - "base64 0.13.1", - "encoding_rs", + "ahash", + "hashbrown 0.14.3", + "instant", + "once_cell", + "thiserror", ] [[package]] -name = "chrono" -version = "0.4.35" +name = "camino" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "windows-targets 0.52.4", + "serde", ] [[package]] -name = "console_error_panic_hook" -version = "0.1.7" +name = "candid" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "465c1ce01d8089ee5b49ba20d3a9da15a28bba64c35cdff2aa256d37e319625d" +dependencies = [ + "anyhow", + "binread", + "byteorder", + "candid_derive", + "codespan-reporting", + "crc32fast", + "data-encoding", + "hex", + "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201ea498d901add0822653ac94cb0f8a92f9b1758a5273f4dafbb6673c9a5020" +dependencies = [ + "lazy_static", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "cargo-platform" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.22", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cc" +version = "1.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfdkim" +version = "0.3.0" +source = "git+https://github.com/SoraSuegami/dkim.git#93829027f03a7442392a37b4635471d8b7f49e6b" +dependencies = [ + "base64 0.21.7", + "chrono", + "console_error_panic_hook", + "ed25519-dalek", + "futures", + "getrandom", + "indexmap 1.9.3", + "js-sys", + "mailparse", + "nom", + "quick-error 2.0.1", + "regex", + "rsa", + "serde_json", + "sha-1", + "sha2 0.10.8", + "slog", + "trust-dns-resolver", + "wasm-bindgen", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "charset" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e9079d1a12a2cc2bffb5db039c43661836ead4082120d5844f02555aca2d46" +dependencies = [ + "base64 0.13.1", + "encoding_rs", +] + +[[package]] +name = "chrono" +version = "0.4.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.4", +] + +[[package]] +name = "chunked_transfer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b6be4a5df2098cd811f3194f64ddb96c267606bffd9689ac7b0160097b01ad3" +dependencies = [ + "bs58", + "coins-core", + "digest 0.10.7", + "hmac", + "k256", + "serde", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "coins-bip39" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8fba409ce3dc04f7d804074039eb68b960b0829161f8e06c95fea3f122528" +dependencies = [ + "bitvec", + "coins-bip32", + "hmac", + "once_cell", + "pbkdf2 0.12.2", + "rand", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "coins-core" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" +dependencies = [ + "base64 0.21.7", + "bech32", + "bs58", + "digest 0.10.7", + "generic-array", + "hex", + "ripemd", + "serde", + "serde_derive", + "sha2 0.10.8", + "sha3", + "thiserror", +] + +[[package]] +name = "combine" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" +dependencies = [ + "ascii 0.9.3", + "byteorder", + "either", + "memchr", + "unreachable", +] + +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concurrent-queue" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" dependencies = [ @@ -250,18 +796,47 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "const-hex" +version = "1.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ba00838774b4ab0233e355d26710fbfc8327a05c017f6dc4873f876d1f79f78" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "proptest", + "serde", +] + [[package]] name = "const-oid" version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + [[package]] name = "constant_time_eq" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -277,6 +852,39 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-deque" version = "0.8.5" @@ -296,12 +904,39 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -312,6 +947,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + [[package]] name = "curve25519-dalek" version = "4.1.2" @@ -321,7 +965,7 @@ dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", - "digest", + "digest 0.10.7", "fiat-crypto", "platforms", "rustc_version", @@ -337,7 +981,20 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.55", +] + +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core", + "subtle-ng", + "zeroize", ] [[package]] @@ -358,18 +1015,122 @@ dependencies = [ ] [[package]] -name = "digest" -version = "0.10.7" +name = "deranged" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", + "powerfmt", ] [[package]] -name = "ed25519" +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" @@ -378,6 +1139,21 @@ dependencies = [ "signature", ] +[[package]] +name = "ed25519-consensus" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" +dependencies = [ + "curve25519-dalek-ng", + "hex", + "rand_core", + "serde", + "sha2 0.9.9", + "thiserror", + "zeroize", +] + [[package]] name = "ed25519-dalek" version = "2.1.1" @@ -387,7 +1163,7 @@ dependencies = [ "curve25519-dalek", "ed25519", "serde", - "sha2", + "sha2 0.10.8", "subtle", "zeroize", ] @@ -397,6 +1173,54 @@ name = "either" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +dependencies = [ + "serde", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff 0.13.0", + "generic-array", + "group 0.13.0", + "pem-rfc7468", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "email-encoding" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbfb21b9878cf7a348dcb8559109aabc0ec40d69924bd706fa5149846c4fef75" +dependencies = [ + "base64 0.21.7", + "memchr", +] + +[[package]] +name = "email_address" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2153bd83ebc09db15bcbdc3e2194d901804952e3dc96967e1cd3b0c5c32d112" + +[[package]] +name = "ena" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +dependencies = [ + "log", +] [[package]] name = "encoding_rs" @@ -407,6 +1231,24 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enr" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4" +dependencies = [ + "base64 0.21.7", + "bytes", + "hex", + "k256", + "log", + "rand", + "rlp", + "serde", + "sha3", + "zeroize", +] + [[package]] name = "enum-as-inner" version = "0.5.1" @@ -419,6 +1261,87 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + +[[package]] +name = "eth-keystore" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" +dependencies = [ + "aes", + "ctr", + "digest 0.10.7", + "hex", + "hmac", + "pbkdf2 0.11.0", + "rand", + "scrypt", + "serde", + "serde_json", + "sha2 0.10.8", + "sha3", + "thiserror", + "uuid", +] + +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "tiny-keccak", +] + [[package]] name = "ether-email-auth-utils" version = "0.1.0" @@ -429,7 +1352,7 @@ dependencies = [ "fancy-regex", "halo2curves 0.4.0", "hex", - "itertools", + "itertools 0.10.5", "neon", "num-bigint", "num-traits", @@ -446,1187 +1369,4147 @@ dependencies = [ ] [[package]] -name = "fancy-regex" -version = "0.11.0" +name = "ethereum-types" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" dependencies = [ - "bit-set", - "regex", + "ethbloom", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "primitive-types", + "scale-info", + "uint", ] [[package]] -name = "ff" -version = "0.13.0" +name = "ethers" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +checksum = "816841ea989f0c69e459af1cf23a6b0033b19a55424a1ea3a30099becdb8dec0" dependencies = [ - "bitvec", - "rand_core", - "subtle", + "ethers-addressbook", + "ethers-contract", + "ethers-core", + "ethers-etherscan", + "ethers-middleware", + "ethers-providers", + "ethers-signers", + "ethers-solc", ] [[package]] -name = "fiat-crypto" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" +name = "ethers-addressbook" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "5495afd16b4faa556c3bba1f21b98b4983e53c1755022377051a975c3b021759" dependencies = [ - "percent-encoding", + "ethers-core", + "once_cell", + "serde", + "serde_json", ] [[package]] -name = "funty" -version = "2.0.0" +name = "ethers-contract" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +checksum = "6fceafa3578c836eeb874af87abacfb041f92b4da0a78a5edd042564b8ecdaaa" +dependencies = [ + "const-hex", + "ethers-contract-abigen", + "ethers-contract-derive", + "ethers-core", + "ethers-providers", + "futures-util", + "once_cell", + "pin-project", + "serde", + "serde_json", + "thiserror", +] [[package]] -name = "futures" -version = "0.3.30" +name = "ethers-contract-abigen" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "04ba01fbc2331a38c429eb95d4a570166781f14290ef9fdb144278a90b5a739b" dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", + "Inflector", + "const-hex", + "dunce", + "ethers-core", + "ethers-etherscan", + "eyre", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "reqwest", + "serde", + "serde_json", + "syn 2.0.55", + "toml", + "walkdir", ] [[package]] -name = "futures-channel" -version = "0.3.30" +name = "ethers-contract-derive" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "87689dcabc0051cde10caaade298f9e9093d65f6125c14575db3fd8c669a168f" dependencies = [ - "futures-core", - "futures-sink", + "Inflector", + "const-hex", + "ethers-contract-abigen", + "ethers-core", + "proc-macro2", + "quote", + "serde_json", + "syn 2.0.55", ] [[package]] -name = "futures-core" -version = "0.3.30" +name = "ethers-core" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" +dependencies = [ + "arrayvec 0.7.4", + "bytes", + "cargo_metadata", + "chrono", + "const-hex", + "elliptic-curve", + "ethabi", + "generic-array", + "k256", + "num_enum 0.7.2", + "once_cell", + "open-fastrlp", + "rand", + "rlp", + "serde", + "serde_json", + "strum 0.26.2", + "syn 2.0.55", + "tempfile", + "thiserror", + "tiny-keccak", + "unicode-xid", +] [[package]] -name = "futures-executor" -version = "0.3.30" +name = "ethers-etherscan" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "e79e5973c26d4baf0ce55520bd732314328cabe53193286671b47144145b9649" dependencies = [ - "futures-core", - "futures-task", - "futures-util", + "chrono", + "ethers-core", + "reqwest", + "semver 1.0.22", + "serde", + "serde_json", + "thiserror", + "tracing", ] [[package]] -name = "futures-io" -version = "0.3.30" +name = "ethers-middleware" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "48f9fdf09aec667c099909d91908d5eaf9be1bd0e2500ba4172c1d28bfaa43de" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", + "async-trait", + "auto_impl", + "ethers-contract", + "ethers-core", + "ethers-etherscan", + "ethers-providers", + "ethers-signers", + "futures-channel", + "futures-locks", + "futures-util", + "instant", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "tracing-futures", + "url", ] [[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" +name = "ethers-providers" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "6434c9a33891f1effc9c75472e12666db2fa5a0fec4b29af6221680a6fe83ab2" dependencies = [ - "futures-channel", + "async-trait", + "auto_impl", + "base64 0.21.7", + "bytes", + "const-hex", + "enr", + "ethers-core", "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", + "futures-timer", + "futures-util", + "hashers", + "http", + "instant", + "jsonwebtoken", + "once_cell", + "pin-project", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "tracing-futures", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "ws_stream_wasm", ] [[package]] -name = "generic-array" -version = "0.14.7" +name = "ethers-signers" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "228875491c782ad851773b652dd8ecac62cda8571d3bc32a5853644dd26766c2" dependencies = [ - "typenum", - "version_check", + "async-trait", + "coins-bip32", + "coins-bip39", + "const-hex", + "elliptic-curve", + "eth-keystore", + "ethers-core", + "rand", + "sha2 0.10.8", + "thiserror", + "tracing", ] [[package]] -name = "getrandom" -version = "0.2.12" +name = "ethers-solc" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "66244a771d9163282646dbeffe0e6eca4dda4146b6498644e678ac6089b11edd" dependencies = [ "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", + "const-hex", + "dirs", + "dunce", + "ethers-core", + "glob", + "home", + "md-5", + "num_cpus", + "once_cell", + "path-slash", + "rayon", + "regex", + "semver 1.0.22", + "serde", + "serde_json", + "solang-parser", + "svm-rs", + "thiserror", + "tiny-keccak", + "tokio", + "tracing", + "walkdir", + "yansi", ] [[package]] -name = "gimli" -version = "0.28.1" +name = "event-listener" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] -name = "group" -version = "0.13.0" +name = "event-listener" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +checksum = "2b5fb89194fa3cad959b833185b3063ba881dbfc7030680b314250779fb4cc91" dependencies = [ - "ff", - "rand_core", - "subtle", + "concurrent-queue", + "parking", + "pin-project-lite", ] [[package]] -name = "halo2curves" -version = "0.4.0" -source = "git+https://github.com/privacy-scaling-explorations/halo2curves.git?rev=81a078254518a7a4b7c69fab120621deaace9389#81a078254518a7a4b7c69fab120621deaace9389" +name = "event-listener-strategy" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" dependencies = [ - "blake2b_simd", - "ff", - "group", - "lazy_static", - "maybe-rayon", - "num-bigint", - "num-traits", - "pairing", - "pasta_curves", - "paste", - "rand", - "rand_core", - "static_assertions", - "subtle", + "event-listener 5.2.0", + "pin-project-lite", ] [[package]] -name = "halo2curves" -version = "0.6.1" -source = "git+https://github.com/privacy-scaling-explorations/halo2curves.git#dc57ddd69105b3d4d4132edc4959484fb62ba9e9" +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ - "blake2b_simd", - "ff", - "group", - "lazy_static", - "num-bigint", - "num-traits", - "pairing", - "pasta_curves", - "paste", - "rand", - "rand_core", - "rayon", - "static_assertions", - "subtle", - "unroll", + "indenter", + "once_cell", ] [[package]] -name = "hashbrown" -version = "0.12.3" +name = "fancy-regex" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2" +dependencies = [ + "bit-set", + "regex", +] [[package]] -name = "heck" -version = "0.4.1" +name = "fastrand" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] [[package]] -name = "hermit-abi" -version = "0.3.9" +name = "fastrand" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] -name = "hex" -version = "0.4.3" +name = "ff" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core", + "subtle", +] [[package]] -name = "hostname" -version = "0.3.1" +name = "ff" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "libc", - "match_cfg", - "winapi", + "bitvec", + "rand_core", + "subtle", ] [[package]] -name = "iana-time-zone" -version = "0.1.60" +name = "fiat-crypto" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] +checksum = "c007b1ae3abe1cb6f85a16305acd418b7ca6343b953633fee2b76d8f108b830f" [[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" +name = "file-rotate" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +checksum = "ddf221ceec4517f3cb764dae3541b2bd87666fc8832e51322fbb97250b468c71" dependencies = [ - "cc", + "chrono", + "flate2", ] [[package]] -name = "idna" -version = "0.2.3" +name = "finl_unicode" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" [[package]] -name = "idna" -version = "0.5.0" +name = "fixed-hash" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "byteorder", + "rand", + "rustc-hex", + "static_assertions", ] [[package]] -name = "indexmap" -version = "1.9.3" +name = "fixedbitset" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ - "autocfg", - "hashbrown", + "crc32fast", + "miniz_oxide", ] [[package]] -name = "ipconfig" -version = "0.3.2" +name = "flume" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" dependencies = [ - "socket2", - "widestring", - "windows-sys 0.48.0", - "winreg", + "futures-core", + "futures-sink", + "spin 0.9.8", ] [[package]] -name = "ipnet" -version = "2.9.0" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "itertools" -version = "0.10.5" +name = "foreign-types" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "either", + "foreign-types-shared", ] [[package]] -name = "itoa" -version = "1.0.10" +name = "foreign-types-shared" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] -name = "js-sys" -version = "0.3.69" +name = "form_urlencoded" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ - "wasm-bindgen", + "percent-encoding", ] [[package]] -name = "lazy_static" -version = "1.4.0" +name = "fs2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" dependencies = [ - "spin", + "libc", + "winapi", ] [[package]] -name = "libc" -version = "0.2.153" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" - -[[package]] -name = "libloading" -version = "0.6.7" +name = "function_name" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883" +checksum = "b1ab577a896d09940b5fe12ec5ae71f9d8211fff62c919c03a3750a9901e98a7" dependencies = [ - "cfg-if", - "winapi", + "function_name-proc-macro", ] [[package]] -name = "libm" -version = "0.2.8" +name = "function_name-proc-macro" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "673464e1e314dd67a0fd9544abc99e8eb28d0c7e3b69b033bcff9b2d00b87333" [[package]] -name = "linked-hash-map" -version = "0.5.6" +name = "funty" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] -name = "lock_api" -version = "0.4.11" +name = "futures" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ - "autocfg", - "scopeguard", + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] -name = "log" -version = "0.4.21" +name = "futures-channel" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] [[package]] -name = "lru-cache" -version = "0.1.2" +name = "futures-core" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ - "linked-hash-map", + "futures-core", + "futures-task", + "futures-util", ] [[package]] -name = "mailparse" -version = "0.14.1" +name = "futures-intrusive" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d096594926cab442e054e047eb8c1402f7d5b2272573b97ba68aa40629f9757" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" dependencies = [ - "charset", - "data-encoding", - "quoted_printable", + "futures-core", + "lock_api", + "parking_lot 0.12.1", ] [[package]] -name = "match_cfg" -version = "0.1.0" +name = "futures-io" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] -name = "matches" -version = "0.1.10" +name = "futures-locks" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" +checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" +dependencies = [ + "futures-channel", + "futures-task", +] [[package]] -name = "maybe-rayon" -version = "0.1.1" +name = "futures-macro" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ - "cfg-if", - "rayon", + "proc-macro2", + "quote", + "syn 2.0.55", ] [[package]] -name = "memchr" -version = "2.7.1" +name = "futures-sink" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] -name = "minimal-lexical" -version = "0.2.1" +name = "futures-task" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] -name = "miniz_oxide" -version = "0.7.2" +name = "futures-timer" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" dependencies = [ - "adler", + "gloo-timers", + "send_wrapper 0.4.0", ] [[package]] -name = "mio" -version = "0.8.11" +name = "futures-util" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", ] [[package]] -name = "neon" -version = "0.10.1" +name = "fxhash" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28e15415261d880aed48122e917a45e87bb82cf0260bb6db48bbab44b7464373" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" dependencies = [ - "neon-build", - "neon-macros", - "neon-runtime", - "semver 0.9.0", - "smallvec", + "byteorder", ] [[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" +name = "generic-array" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7288eac8b54af7913c60e0eb0e2a7683020dffa342ab3fd15e28f035ba897cf" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ - "quote", - "syn 1.0.109", - "syn-mid", + "typenum", + "version_check", + "zeroize", ] [[package]] -name = "neon-runtime" -version = "0.10.1" +name = "getrandom" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4676720fa8bb32c64c3d9f49c47a47289239ec46b4bdb66d0913cc512cb0daca" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", - "libloading", - "smallvec", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", ] [[package]] -name = "nom" -version = "7.1.3" +name = "gimli" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] -name = "num-bigint" -version = "0.4.4" +name = "glob" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] -name = "num-bigint-dig" -version = "0.8.4" +name = "gloo-timers" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" dependencies = [ - "byteorder", - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand", - "serde", - "smallvec", - "zeroize", + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "num-integer" -version = "0.1.46" +name = "graphql-introspection-query" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "7f2a4732cf5140bd6c082434494f785a19cfb566ab07d1382c3671f5812fed6d" dependencies = [ - "num-traits", + "serde", ] [[package]] -name = "num-iter" -version = "0.1.44" +name = "graphql-parser" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +checksum = "d2ebc8013b4426d5b81a4364c419a95ed0b404af2b82e2457de52d9348f0e474" dependencies = [ - "autocfg", - "num-integer", - "num-traits", + "combine 3.8.1", + "thiserror", ] [[package]] -name = "num-traits" -version = "0.2.18" +name = "graphql_client" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "09cdf7b487d864c2939b23902291a5041bc4a84418268f25fda1c8d4e15ad8fa" dependencies = [ - "autocfg", - "libm", + "graphql_query_derive", + "reqwest", + "serde", + "serde_json", ] [[package]] -name = "num_cpus" -version = "1.16.0" +name = "graphql_client_codegen" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "a40f793251171991c4eb75bd84bc640afa8b68ff6907bc89d3b712a22f700506" dependencies = [ - "hermit-abi", - "libc", + "graphql-introspection-query", + "graphql-parser", + "heck", + "lazy_static", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn 1.0.109", ] [[package]] -name = "object" -version = "0.32.2" +name = "graphql_query_derive" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "00bda454f3d313f909298f626115092d348bc231025699f557b27e248475f48c" dependencies = [ - "memchr", + "graphql_client_codegen", + "proc-macro2", + "syn 1.0.109", ] [[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "pairing" -version = "0.23.0" +name = "group" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ - "group", + "ff 0.12.1", + "rand_core", + "subtle", ] [[package]] -name = "parking_lot" -version = "0.12.1" +name = "group" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "lock_api", - "parking_lot_core", + "ff 0.13.0", + "rand_core", + "subtle", ] [[package]] -name = "parking_lot_core" -version = "0.9.9" +name = "h2" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.48.5", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", ] [[package]] -name = "pasta_curves" -version = "0.5.1" +name = "half" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" +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", - "group", + "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 = "paste" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +name = "halo2curves" +version = "0.6.1" +source = "git+https://github.com/privacy-scaling-explorations/halo2curves.git#1662f881cb1a19719f3a25edd373c15e0aff3274" +dependencies = [ + "blake2b_simd", + "ff 0.13.0", + "group 0.13.0", + "lazy_static", + "num-bigint", + "num-traits", + "pairing 0.23.0", + "pasta_curves", + "paste", + "rand", + "rand_core", + "rayon", + "static_assertions", + "subtle", + "unroll", +] [[package]] -name = "pem-rfc7468" -version = "0.7.0" +name = "handlebars" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +checksum = "faa67bab9ff362228eb3d00bd024a4965d8231bbb7921167f0cfa66c6626b225" dependencies = [ - "base64ct", + "log", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror", ] [[package]] -name = "percent-encoding" -version = "2.3.1" +name = "hashbrown" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] -name = "pin-project-lite" -version = "0.2.13" +name = "hashbrown" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] [[package]] -name = "pin-utils" -version = "0.1.0" +name = "hashers" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "b2bca93b15ea5a746f220e56587f71e73c6165eab783df9e26590069953e3c30" +dependencies = [ + "fxhash", +] [[package]] -name = "pkcs1" -version = "0.7.5" +name = "hashlink" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "der", - "pkcs8", - "spki", + "hashbrown 0.14.3", ] [[package]] -name = "pkcs8" -version = "0.10.2" +name = "heck" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" dependencies = [ - "der", - "spki", + "unicode-segmentation", ] [[package]] -name = "platforms" -version = "3.3.0" +name = "hermit-abi" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] -name = "poseidon-rs" -version = "0.0.10" -source = "git+https://github.com/SoraSuegami/poseidon-rs.git?branch=master#15aa98d045e531806e39e48ba5a0b999f5de5d8d" +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "getrandom", - "halo2curves 0.6.1", - "once_cell", - "serde", - "thiserror", + "hmac", ] [[package]] -name = "ppv-lite86" -version = "0.2.17" +name = "hmac" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] [[package]] -name = "proc-macro2" -version = "1.0.78" +name = "home" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "unicode-ident", + "windows-sys 0.52.0", ] [[package]] -name = "quick-error" -version = "1.2.3" +name = "hostname" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] [[package]] -name = "quick-error" -version = "2.0.1" +name = "http" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] [[package]] -name = "quote" -version = "1.0.35" +name = "http-body" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ - "proc-macro2", + "bytes", + "http", + "pin-project-lite", ] [[package]] -name = "quoted_printable" -version = "0.5.0" +name = "httparse" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ec282e887b434b68c18fe5c121d38e72a5cf35119b59e54ec5b992ea9c8eb0" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] -name = "radium" -version = "0.7.0" +name = "httpdate" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] -name = "rand" -version = "0.8.5" +name = "hyper" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ - "libc", - "rand_chacha", - "rand_core", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.5.6", + "tokio", + "tower-service", + "tracing", + "want", ] [[package]] -name = "rand_chacha" -version = "0.3.1" +name = "hyper-rustls" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ - "ppv-lite86", - "rand_core", + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", ] [[package]] -name = "rand_core" -version = "0.6.4" +name = "hyper-tls" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "getrandom", + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", ] [[package]] -name = "rayon" -version = "1.9.0" +name = "iana-time-zone" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ - "either", - "rayon-core", + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", ] [[package]] -name = "rayon-core" -version = "1.12.1" +name = "iana-time-zone-haiku" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "crossbeam-deque", - "crossbeam-utils", + "cc", ] [[package]] -name = "redox_syscall" -version = "0.4.1" +name = "ic-agent" +version = "0.30.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "263d5c7b295ba69eac0692e6f6b35a01ca323889d10612c0f8c8fd223b0bfec5" dependencies = [ - "bitflags", + "backoff", + "cached", + "candid", + "ed25519-consensus", + "futures-util", + "hex", + "http", + "http-body", + "ic-certification", + "ic-transport-types", + "ic-verify-bls-signature", + "k256", + "leb128", + "pem 2.0.1", + "pkcs8", + "rand", + "rangemap", + "reqwest", + "ring 0.16.20", + "rustls-webpki", + "sec1", + "serde", + "serde_bytes", + "serde_cbor", + "serde_repr", + "sha2 0.10.8", + "simple_asn1", + "thiserror", + "time", + "tokio", + "url", ] [[package]] -name = "regex" -version = "1.10.3" +name = "ic-certification" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "e8c04340437a32c8b9c80d36f09715909c1e0a755327503a2e2906dcd662ba4e" dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", + "hex", + "serde", + "serde_bytes", + "sha2 0.10.8", ] [[package]] -name = "regex-automata" -version = "0.4.6" +name = "ic-transport-types" +version = "0.30.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "7b2be3fc4f0641a8c3967fbc8ab52b08bc6d13bf65fb2460b090710374be49b1" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "candid", + "hex", + "ic-certification", + "leb128", + "serde", + "serde_bytes", + "serde_repr", + "sha2 0.10.8", + "thiserror", ] [[package]] -name = "regex-syntax" -version = "0.8.2" +name = "ic-utils" +version = "0.30.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "fbd6fac62c95df9f963c8a941431d86308c864ba1e9001da75843d79a355fb68" +dependencies = [ + "async-trait", + "candid", + "ic-agent", + "once_cell", + "semver 1.0.22", + "serde", + "serde_bytes", + "strum 0.24.1", + "strum_macros 0.24.3", + "thiserror", + "time", +] [[package]] -name = "resolv-conf" -version = "0.7.0" +name = "ic-verify-bls-signature" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +checksum = "583b1c03380cf86059160cc6c91dcbf56c7b5f141bf3a4f06bc79762d775fac4" dependencies = [ - "hostname", - "quick-error 1.2.3", + "bls12_381", + "lazy_static", + "pairing 0.22.0", + "sha2 0.9.9", ] [[package]] -name = "rsa" -version = "0.9.6" +name = "idna" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" dependencies = [ - "const-oid", - "digest", - "num-bigint-dig", - "num-integer", - "num-traits", - "pkcs1", - "pkcs8", - "rand_core", - "serde", - "sha2", - "signature", + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "imap-proto" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e70cd66882c8cb1c9802096ba75212822153c51478dc61621e1a22f6c92361" +dependencies = [ + "nom", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipconfig" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +dependencies = [ + "socket2 0.5.6", + "widestring", + "windows-sys 0.48.0", + "winreg", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine 4.6.6", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonwebtoken" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +dependencies = [ + "base64 0.21.7", + "pem 1.1.1", + "ring 0.16.20", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2 0.10.8", + "signature", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lalrpop" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" +dependencies = [ + "ascii-canvas", + "bit-set", + "ena", + "itertools 0.11.0", + "lalrpop-util", + "petgraph", + "regex", + "regex-syntax", + "string_cache", + "term", + "tiny-keccak", + "unicode-xid", + "walkdir", +] + +[[package]] +name = "lalrpop-util" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "lettre" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bd09637ae3ec7bd605b8e135e757980b3968430ff2b1a4a94fb7769e50166d" +dependencies = [ + "async-trait", + "base64 0.21.7", + "email-encoding", + "email_address", + "fastrand 1.9.0", + "futures-io", + "futures-util", + "hostname", + "httpdate", + "idna 0.3.0", + "mime", + "native-tls", + "nom", + "once_cell", + "quoted_printable 0.4.8", + "socket2 0.4.10", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libloading" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.5.0", + "libc", + "redox_syscall 0.4.1", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "mailparse" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d096594926cab442e054e047eb8c1402f7d5b2272573b97ba68aa40629f9757" +dependencies = [ + "charset", + "data-encoding", + "quoted_printable 0.5.0", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "matchit" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest 0.10.7", +] + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "ndk-context" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", + "rand", + "serde", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "serde", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "oauth2" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c38841cdd844847e3e7c8d29cef9dcfed8877f8f56f9071f77843ecf3baf937f" +dependencies = [ + "base64 0.13.1", + "chrono", + "getrandom", + "http", + "rand", + "reqwest", + "serde", + "serde_json", + "serde_path_to_error", + "sha2 0.10.8", + "thiserror", + "url", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "open-fastrlp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" +dependencies = [ + "arrayvec 0.7.4", + "auto_impl", + "bytes", + "ethereum-types", + "open-fastrlp-derive", +] + +[[package]] +name = "open-fastrlp-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" +dependencies = [ + "bytes", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "pairing" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b" +dependencies = [ + "group 0.12.1", +] + +[[package]] +name = "pairing" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" +dependencies = [ + "group 0.13.0", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +dependencies = [ + "arrayvec 0.7.4", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +dependencies = [ + "proc-macro-crate 2.0.0", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "password-hash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + +[[package]] +name = "pasta_curves" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" +dependencies = [ + "blake2b_simd", + "ff 0.13.0", + "group 0.13.0", + "lazy_static", + "rand", + "static_assertions", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "path-slash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", + "hmac", + "password-hash", + "sha2 0.10.8", +] + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", + "hmac", +] + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "pem" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b13fe415cdf3c8e44518e18a7c95a13431d9bdf6d15367d82b23c377fdd441a" +dependencies = [ + "base64 0.21.7", + "serde", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "pest_meta" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.8", +] + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.2.6", +] + +[[package]] +name = "pharos" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared 0.11.2", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "platforms" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" + +[[package]] +name = "poseidon-rs" +version = "0.0.10" +source = "git+https://github.com/SoraSuegami/poseidon-rs.git?branch=master#15aa98d045e531806e39e48ba5a0b999f5de5d8d" +dependencies = [ + "getrandom", + "halo2curves 0.6.1", + "once_cell", + "serde", + "thiserror", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "pretty" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55c4d17d994b637e2f4daf6e5dc5d660d209d5642377d675d7a1c3ab69fa579" +dependencies = [ + "arrayvec 0.5.2", + "typed-arena", + "unicode-width", +] + +[[package]] +name = "prettyplease" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +dependencies = [ + "proc-macro2", + "syn 2.0.55", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "uint", +] + +[[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 = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.7", +] + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +dependencies = [ + "bitflags 2.5.0", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax", + "unarray", +] + +[[package]] +name = "psm" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +dependencies = [ + "cc", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "quoted_printable" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3866219251662ec3b26fc217e3e05bf9c4f84325234dfb96bf0bf840889e49" + +[[package]] +name = "quoted_printable" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79ec282e887b434b68c18fe5c121d38e72a5cf35119b59e54ec5b992ea9c8eb0" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rangemap" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684" + +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[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_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "relayer" +version = "1.1.0" +dependencies = [ + "anyhow", + "async-imap", + "async-native-tls", + "async-trait", + "axum", + "candid", + "chrono", + "dotenv", + "ether-email-auth-utils", + "ethers", + "ff 0.13.0", + "file-rotate", + "function_name", + "futures", + "graphql_client", + "handlebars", + "hex", + "ic-agent", + "ic-utils", + "lazy_static", + "lettre", + "num-bigint", + "num-traits", + "oauth2", + "rand", + "regex", + "reqwest", + "serde", + "serde_json", + "sled", + "slog", + "slog-async", + "slog-json", + "slog-term", + "sqlx", + "tiny_http", + "tokio", + "tower-http", + "webbrowser", +] + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error 1.2.3", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rlp-derive", + "rustc-hex", +] + +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "serde", + "sha2 0.10.8", + "signature", "spki", "subtle", "zeroize", ] [[package]] -name = "rustc-demangle" -version = "0.1.23" +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.22", +] + +[[package]] +name = "rustix" +version = "0.38.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "log", + "ring 0.17.8", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scale-info" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ef2175c2907e7c8bc0a9c3f86aeb5ec1f3b275300ad58a44d0c3ae379a5e52e" +dependencies = [ + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b8eb8fd61c5cdd3390d9b2132300a7e7618955b98b8416f118c1b4e144f" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scrypt" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" +dependencies = [ + "hmac", + "pbkdf2 0.11.0", + "salsa20", + "sha2 0.10.8", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "self_cell" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba" + +[[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.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_bytes" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "serde_json" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +dependencies = [ + "itoa", + "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.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha-1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core", +] + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "sled" +version = "0.34.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935" +dependencies = [ + "crc32fast", + "crossbeam-epoch", + "crossbeam-utils", + "fs2", + "fxhash", + "libc", + "log", + "parking_lot 0.11.2", +] + +[[package]] +name = "slog" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" + +[[package]] +name = "slog-async" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c8038f898a2c79507940990f05386455b3a317d8f18d4caea7cbc3d5096b84" +dependencies = [ + "crossbeam-channel", + "slog", + "take_mut", + "thread_local", +] + +[[package]] +name = "slog-json" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e1e53f61af1e3c8b852eef0a9dee29008f55d6dd63794f3f12cef786cf0f219" +dependencies = [ + "serde", + "serde_json", + "slog", + "time", +] + +[[package]] +name = "slog-term" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6e022d0b998abfe5c3782c1f03551a596269450ccd677ea51c56f8b214610e8" +dependencies = [ + "is-terminal", + "slog", + "term", + "thread_local", + "time", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "solang-parser" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c425ce1c59f4b154717592f0bdf4715c3a1d55058883622d3157e1f0908a5b26" +dependencies = [ + "itertools 0.11.0", + "lalrpop", + "lalrpop-util", + "phf", + "thiserror", + "unicode-xid", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlformat" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" +dependencies = [ + "itertools 0.12.1", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" +dependencies = [ + "ahash", + "atoi", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener 2.5.3", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashlink", + "hex", + "indexmap 2.2.6", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "serde", + "serde_json", + "sha2 0.10.8", + "smallvec", + "sqlformat", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "url", +] [[package]] -name = "rustc_version" -version = "0.4.0" +name = "sqlx-macros" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" +dependencies = [ + "atomic-write-file", + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2 0.10.8", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 1.0.109", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" +dependencies = [ + "atoi", + "base64 0.21.7", + "bitflags 2.5.0", + "byteorder", + "bytes", + "crc", + "digest 0.10.7", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand", + "rsa", + "serde", + "sha1", + "sha2 0.10.8", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" +dependencies = [ + "atoi", + "base64 0.21.7", + "bitflags 2.5.0", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand", + "serde", + "serde_json", + "sha1", + "sha2 0.10.8", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "tracing", + "url", + "urlencoding", +] + +[[package]] +name = "stacker" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "winapi", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stop-token" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" +dependencies = [ + "async-channel 1.9.0", + "cfg-if", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot 0.12.1", + "phf_shared 0.10.0", + "precomputed-hash", +] + +[[package]] +name = "stringprep" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +dependencies = [ + "finl_unicode", + "unicode-bidi", + "unicode-normalization", +] + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros 0.26.2", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "strum_macros" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.55", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + +[[package]] +name = "svm-rs" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11297baafe5fa0c99d5722458eac6a5e25c01eb1b8e5cd137f54079093daa7a4" dependencies = [ + "dirs", + "fs2", + "hex", + "once_cell", + "reqwest", "semver 1.0.22", + "serde", + "serde_json", + "sha2 0.10.8", + "thiserror", + "url", + "zip", ] [[package]] -name = "ryu" -version = "1.0.17" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] -name = "scopeguard" -version = "1.2.0" +name = "syn" +version = "2.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn-mid" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea305d57546cc8cd04feb14b62ec84bf17f50e3f7b12560d7bfa9265f39d9ed" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "take_mut" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" + +[[package]] +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] -name = "semver" -version = "0.9.0" +name = "tempfile" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ - "semver-parser", + "cfg-if", + "fastrand 2.0.2", + "rustix", + "windows-sys 0.52.0", ] [[package]] -name = "semver" -version = "1.0.22" +name = "term" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] [[package]] -name = "semver-parser" -version = "0.7.0" +name = "termcolor" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] [[package]] -name = "serde" -version = "1.0.197" +name = "thiserror" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ - "serde_derive", + "thiserror-impl", ] [[package]] -name = "serde_derive" -version = "1.0.197" +name = "thiserror-impl" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.55", ] [[package]] -name = "serde_json" -version = "1.0.114" +name = "thread_local" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ - "itoa", - "ryu", - "serde", + "cfg-if", + "once_cell", ] [[package]] -name = "serde_regex" -version = "1.1.0" +name = "time" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ - "regex", + "deranged", + "itoa", + "num-conv", + "powerfmt", "serde", + "time-core", + "time-macros", ] [[package]] -name = "sha-1" -version = "0.10.1" +name = "time-core" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] -name = "sha2" -version = "0.10.8" +name = "time-macros" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "num-conv", + "time-core", ] [[package]] -name = "signature" -version = "2.2.0" +name = "tiny-keccak" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" dependencies = [ - "digest", - "rand_core", + "crunchy", ] [[package]] -name = "slab" -version = "0.4.9" +name = "tiny_http" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82" dependencies = [ - "autocfg", + "ascii 1.1.0", + "chunked_transfer", + "httpdate", + "log", ] [[package]] -name = "slog" -version = "2.7.0" +name = "tinyvec" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] [[package]] -name = "smallvec" -version = "1.13.1" +name = "tinyvec_macros" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] -name = "socket2" -version = "0.5.6" +name = "tokio" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ + "backtrace", + "bytes", "libc", - "windows-sys 0.52.0", + "mio", + "num_cpus", + "parking_lot 0.12.1", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.6", + "tokio-macros", + "windows-sys 0.48.0", ] [[package]] -name = "spin" -version = "0.5.2" +name = "tokio-macros" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] [[package]] -name = "spki" -version = "0.7.3" +name = "tokio-native-tls" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ - "base64ct", - "der", + "native-tls", + "tokio", ] [[package]] -name = "static_assertions" -version = "1.1.0" +name = "tokio-rustls" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] [[package]] -name = "subtle" -version = "2.5.0" +name = "tokio-stream" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] [[package]] -name = "syn" -version = "1.0.109" +name = "tokio-tungstenite" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "futures-util", + "log", + "rustls", + "tokio", + "tokio-rustls", + "tungstenite", + "webpki-roots", ] [[package]] -name = "syn" -version = "2.0.52" +name = "tokio-util" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", ] [[package]] -name = "syn-mid" -version = "0.5.4" +name = "toml" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea305d57546cc8cd04feb14b62ec84bf17f50e3f7b12560d7bfa9265f39d9ed" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.9", ] [[package]] -name = "tap" -version = "1.0.1" +name = "toml_datetime" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] [[package]] -name = "thiserror" -version = "1.0.57" +name = "toml_edit" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "thiserror-impl", + "indexmap 2.2.6", + "toml_datetime", + "winnow 0.5.40", ] [[package]] -name = "thiserror-impl" -version = "1.0.57" +name = "toml_edit" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", + "indexmap 2.2.6", + "toml_datetime", + "winnow 0.5.40", ] [[package]] -name = "tinyvec" -version = "1.6.0" +name = "toml_edit" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "tinyvec_macros", + "indexmap 2.2.6", + "toml_datetime", + "winnow 0.5.40", ] [[package]] -name = "tinyvec_macros" -version = "0.1.1" +name = "toml_edit" +version = "0.22.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.5", +] [[package]] -name = "tokio" -version = "1.36.0" +name = "tower" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", + "futures-core", + "futures-util", + "pin-project", "pin-project-lite", - "socket2", - "tokio-macros", - "windows-sys 0.48.0", + "tokio", + "tower-layer", + "tower-service", + "tracing", ] [[package]] -name = "tokio-macros" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +name = "tower-http" +version = "0.4.2" +source = "git+https://github.com/tower-rs/tower-http.git?rev=f33c3e038dc85b8d064541e915d501f9c9e6a6b4#f33c3e038dc85b8d064541e915d501f9c9e6a6b4" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", + "bitflags 2.5.0", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "pin-project-lite", + "tower-layer", + "tower-service", ] +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + [[package]] name = "tracing" version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1640,7 +5523,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.55", ] [[package]] @@ -1652,6 +5535,16 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + [[package]] name = "trust-dns-proto" version = "0.22.0" @@ -1678,30 +5571,86 @@ dependencies = [ ] [[package]] -name = "trust-dns-resolver" -version = "0.22.0" +name = "trust-dns-resolver" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe" +dependencies = [ + "cfg-if", + "futures-util", + "ipconfig", + "lazy_static", + "lru-cache", + "parking_lot 0.12.1", + "resolv-conf", + "smallvec", + "thiserror", + "tokio", + "tracing", + "trust-dns-proto", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand", + "rustls", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uint" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" dependencies = [ - "cfg-if", - "futures-util", - "ipconfig", - "lazy_static", - "lru-cache", - "parking_lot", - "resolv-conf", - "smallvec", - "thiserror", - "tokio", - "tracing", - "trust-dns-proto", + "byteorder", + "crunchy", + "hex", + "static_assertions", ] [[package]] -name = "typenum" -version = "1.17.0" +name = "unarray" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-bidi" @@ -1724,6 +5673,39 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] + [[package]] name = "unroll" version = "0.1.5" @@ -1734,6 +5716,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.0" @@ -1743,20 +5737,80 @@ dependencies = [ "form_urlencoded", "idna 0.5.0", "percent-encoding", + "serde", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" version = "0.2.92" @@ -1780,10 +5834,22 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.55", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.92" @@ -1802,7 +5868,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.55", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1813,6 +5879,87 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +[[package]] +name = "wasm-bindgen-test" +version = "0.3.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9bf62a58e0780af3e852044583deee40983e5886da43a271dd772379987667b" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f89739351a2e03cb94beb799d47fb2cac01759b40ec441f7de39b00cbf7ef0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "wasm-streams" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webbrowser" +version = "0.8.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1b04c569c83a9bb971dd47ec6fd48753315f4bf989b9b04a2e7ca4d7f0dc950" +dependencies = [ + "core-foundation", + "home", + "jni", + "log", + "ndk-context", + "objc", + "raw-window-handle", + "url", + "web-sys", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "whoami" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +dependencies = [ + "redox_syscall 0.4.1", + "wasite", +] + [[package]] name = "widestring" version = "1.0.2" @@ -1835,6 +5982,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -1850,6 +6006,15 @@ dependencies = [ "windows-targets 0.52.4", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -1868,6 +6033,21 @@ dependencies = [ "windows-targets 0.52.4", ] +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -1898,6 +6078,12 @@ dependencies = [ "windows_x86_64_msvc 0.52.4", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -1910,6 +6096,12 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -1922,6 +6114,12 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -1934,6 +6132,12 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -1946,6 +6150,12 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -1958,6 +6168,12 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -1970,6 +6186,12 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -1982,6 +6204,24 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" @@ -1992,6 +6232,25 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "ws_stream_wasm" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version", + "send_wrapper 0.6.0", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wyz" version = "0.5.1" @@ -2001,21 +6260,99 @@ dependencies = [ "tap", ] +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + [[package]] name = "zeroize" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "aes", + "byteorder", + "bzip2", + "constant_time_eq 0.1.5", + "crc32fast", + "crossbeam-utils", + "flate2", + "hmac", + "pbkdf2 0.11.0", + "sha1", + "time", + "zstd", +] + [[package]] name = "zk-regex-apis" -version = "1.2.0" -source = "git+https://github.com/zkemail/zk-regex.git?branch=main#9995d9b2801c7510bbb023eadc6809e650c5a5df" +version = "2.0.1" +source = "git+https://github.com/zkemail/zk-regex.git?branch=main#89ca0db11d61e8533089d01297178e45943ca8a9" dependencies = [ "fancy-regex", - "itertools", - "neon", + "itertools 0.10.5", + "js-sys", "serde", + "serde-wasm-bindgen", "serde_json", "thiserror", + "wasm-bindgen", + "wasm-bindgen-test", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.9+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +dependencies = [ + "cc", + "pkg-config", ] diff --git a/packages/circuits/package.json b/packages/circuits/package.json index 0945956f..327b52be 100644 --- a/packages/circuits/package.json +++ b/packages/circuits/package.json @@ -12,7 +12,7 @@ "dependencies": { "@zk-email/circuits": "^3.2.4", "@zk-email/helpers": "^3.1.3", - "@zk-email/zk-regex-circom": "^1.3.0", + "@zk-email/zk-regex-circom": "^2.0.1", "commander": "^11.0.0", "snarkjs": "^0.7.0" }, diff --git a/packages/relayer/src/config.rs b/packages/relayer/src/config.rs index 61a846f4..5e2c7032 100644 --- a/packages/relayer/src/config.rs +++ b/packages/relayer/src/config.rs @@ -1,4 +1,6 @@ use crate::*; +use ethers::types::U256; +use std::sync::OnceLock; pub static CIRCUITS_DIR_PATH: OnceLock = OnceLock::new(); pub static WEB_SERVER_ADDRESS: OnceLock = OnceLock::new(); diff --git a/packages/relayer/src/emails_pool.rs b/packages/relayer/src/emails_pool.rs index aadc2fec..174a03f5 100644 --- a/packages/relayer/src/emails_pool.rs +++ b/packages/relayer/src/emails_pool.rs @@ -31,7 +31,7 @@ impl EmailsPool for FileEmailsPool { for path in dir.into_iter() { let path = path?.path(); let email = fs::read_to_string(path)?; - emails.push((calculate_default_hash(&email), email)); + emails.push((calculate_email_hash(&email), email)); } Ok(emails) } @@ -63,7 +63,7 @@ impl EmailsPool for FileEmailsPool { impl FileEmailsPool { #[named] pub fn new() -> Self { - let dir_path = RECEIVED_EMAILS_DIR.get().unwrap(); + let dir_path = RECEIVED_EMAILS_DIR.get().unwrap().to_string(); info!(LOG, "dir_path: {}", dir_path; "func" => function_name!()); fs::create_dir_all(&dir_path).unwrap(); Self { dir_path } diff --git a/packages/relayer/src/lib.rs b/packages/relayer/src/lib.rs index d425a97e..15617bea 100644 --- a/packages/relayer/src/lib.rs +++ b/packages/relayer/src/lib.rs @@ -13,8 +13,12 @@ pub(crate) use config::*; pub(crate) use database::*; pub(crate) use dkim_oracle::*; pub(crate) use emails_pool::*; +pub(crate) use ether_email_auth_utils::*; +pub(crate) use ethers::types::*; +pub(crate) use function_name::named; pub(crate) use imap_client::*; pub(crate) use logger::*; +pub(crate) use slog::*; pub(crate) use smtp_client::*; pub(crate) use subject_templates::*; pub(crate) use utils::*; diff --git a/packages/relayer/src/smtp_client.rs b/packages/relayer/src/smtp_client.rs index fee7efae..1412d9f2 100644 --- a/packages/relayer/src/smtp_client.rs +++ b/packages/relayer/src/smtp_client.rs @@ -1,5 +1,7 @@ #![allow(unused_imports)] +use std::path::PathBuf; + use crate::*; use anyhow::anyhow; diff --git a/packages/relayer/src/subject_templates.rs b/packages/relayer/src/subject_templates.rs index b7a475d9..52ea66b1 100644 --- a/packages/relayer/src/subject_templates.rs +++ b/packages/relayer/src/subject_templates.rs @@ -32,7 +32,7 @@ impl TemplateValue { 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), + 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")), @@ -146,7 +146,7 @@ pub fn extract_template_vals(input: &str, templates: Vec) -> Result().unwrap(); - template_vals.push(TemplateValue::Address(address)); + template_vals.push(TemplateValue::EthAddr(address)); input_idx += 1; } _ => { @@ -215,7 +215,7 @@ pub fn uint_to_decimal_string(uint: u128, decimal: usize) -> String { } // 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] = amount_str.chars().nth(i - delta).unwrap(); + result[i] = uint_str.chars().nth(i - delta).unwrap(); actual_result_len += 1; found_non_zero_decimal = true; } diff --git a/packages/relayer/src/utils.rs b/packages/relayer/src/utils.rs index b388a04f..baeb340d 100644 --- a/packages/relayer/src/utils.rs +++ b/packages/relayer/src/utils.rs @@ -3,13 +3,13 @@ use crate::*; use chrono::{DateTime, Local}; -use email_wallet_utils::*; -use ethers::abi::Token; +use ethers::abi::{self, Token}; use ethers::types::{Bytes, U256}; - use serde::Deserialize; +use std::hash::{Hash,Hasher}; -use std::path::Path; +use std::collections::hash_map::DefaultHasher; +use std::path::{Path, PathBuf}; use tokio::{ fs::{read_to_string, remove_file, File}, @@ -89,7 +89,7 @@ pub(crate) async fn generate_email_auth_input( email: &str, account_code: &str, ) -> Result { - let email_hash = calculate_default_hash(email); + let email_hash = calculate_email_hash(email); let email_file_name = PathBuf::new() .join(INPUT_FILES_DIR.get().unwrap()) .join(email_hash.to_string() + ".email"); @@ -183,3 +183,11 @@ pub(crate) fn now() -> i64 { let dt: DateTime = Local::now(); dt.timestamp() } + +pub(crate) fn calculate_email_hash(input: &str) -> String { + let mut hasher = DefaultHasher::new(); + input.hash(&mut hasher); + let hash_code = hasher.finish(); + + hash_code.to_string() +} diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 63ca4291..cc355b25 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -16,7 +16,7 @@ itertools = "0.10.3" serde_json = "1.0.95" serde = { version = "1.0.159", features = ["derive"] } # halo2-regex = { git = "https://github.com/zkemail/halo2-regex.git", version = "0.1.0" } -zk-regex-apis = { version = "1.1.4", git = "https://github.com/zkemail/zk-regex.git", branch = "main", default-features = false } +zk-regex-apis = { version = "2.0.1", git = "https://github.com/zkemail/zk-regex.git", branch = "main", default-features = false } fancy-regex = "0.11.0" hex = "0.4.3" tokio = { version = "1.16", features = [ diff --git a/packages/utils/src/converters.rs b/packages/utils/src/converters.rs index 5a5b275c..6b2f0918 100644 --- a/packages/utils/src/converters.rs +++ b/packages/utils/src/converters.rs @@ -6,7 +6,7 @@ use itertools::Itertools; use neon::prelude::*; use poseidon_rs::*; -pub use zk_regex_apis::padding::{pad_string, pad_string_node}; +pub use zk_regex_apis::padding::pad_string; pub fn hex2field(input_hex: &str) -> anyhow::Result { if &input_hex[0..2] != "0x" { diff --git a/packages/utils/src/cryptos.rs b/packages/utils/src/cryptos.rs index 6ea61766..5d5c682b 100644 --- a/packages/utils/src/cryptos.rs +++ b/packages/utils/src/cryptos.rs @@ -4,7 +4,7 @@ use halo2curves::ff::Field; use neon::prelude::*; use poseidon_rs::*; use rand_core::{OsRng, RngCore}; -pub use zk_regex_apis::padding::{pad_string, pad_string_node}; +pub use zk_regex_apis::padding::pad_string; pub const MAX_EMAIL_ADDR_BYTES: usize = 256; @@ -19,7 +19,7 @@ impl PaddedEmailAddr { let email_addr_len = email_addr.as_bytes().len(); // let mut padded_bytes = email_addr.as_bytes().to_vec(); // padded_bytes.append(&mut vec![0; MAX_EMAIL_ADDR_BYTES - email_addr_len]); - let padded_bytes = pad_string(email_addr, MAX_EMAIL_ADDR_BYTES); + let padded_bytes = pad_string(email_addr, MAX_EMAIL_ADDR_BYTES).to_vec(); Self { padded_bytes, email_addr_len, diff --git a/packages/utils/src/lib.rs b/packages/utils/src/lib.rs index 13a98c74..509e61b9 100644 --- a/packages/utils/src/lib.rs +++ b/packages/utils/src/lib.rs @@ -2,11 +2,13 @@ use neon::prelude::*; pub mod converters; pub mod cryptos; pub mod parse_email; +mod regex; mod statics; -use converters::*; -use cryptos::*; -use parse_email::*; +pub use converters::*; +pub use cryptos::*; +pub use parse_email::*; pub use poseidon_rs::*; +use regex::*; pub use zk_regex_apis::extract_substrs::*; pub use zk_regex_apis::padding::*; diff --git a/packages/utils/src/regex.rs b/packages/utils/src/regex.rs new file mode 100644 index 00000000..b9806e3a --- /dev/null +++ b/packages/utils/src/regex.rs @@ -0,0 +1,243 @@ +use neon::prelude::*; +pub use zk_regex_apis::extract_substrs::*; +pub use zk_regex_apis::padding::*; + +pub fn pad_string_node(mut cx: FunctionContext) -> JsResult { + let string = cx.argument::(0)?.value(&mut cx); + let padded_bytes_size = cx.argument::(1)?.value(&mut cx) as usize; + let padded_bytes = pad_string(&string, padded_bytes_size); + let padded_array = JsArray::new(&mut cx, padded_bytes_size as u32); + for (idx, byte) in padded_bytes.into_iter().enumerate() { + let js_byte = cx.number(byte); + padded_array.set(&mut cx, idx as u32, js_byte)?; + } + Ok(padded_array) +} + +pub fn extract_substr_idxes_node(mut cx: FunctionContext) -> JsResult { + let input_str = cx.argument::(0)?.value(&mut cx); + let regex_config_str = cx.argument::(1)?.value(&mut cx); + let regex_config = match serde_json::from_str::(®ex_config_str) { + Ok(regex_config) => regex_config, + Err(e) => return cx.throw_error(e.to_string()), + }; + let substr_idxes = match extract_substr_idxes(&input_str, ®ex_config) { + Ok(substr_idxes) => substr_idxes, + Err(e) => return cx.throw_error(e.to_string()), + }; + let js_array = JsArray::new(&mut cx, substr_idxes.len() as u32); + for (i, (start_idx, end_idx)) in substr_idxes.iter().enumerate() { + let start_end_array = JsArray::new(&mut cx, 2u32); + let start_idx = cx.number(*start_idx as f64); + start_end_array.set(&mut cx, 0, start_idx)?; + let end_idx = cx.number(*end_idx as f64); + start_end_array.set(&mut cx, 1, end_idx)?; + js_array.set(&mut cx, i as u32, start_end_array)?; + } + Ok(js_array) +} + +pub fn extract_email_addr_idxes_node(mut cx: FunctionContext) -> JsResult { + let input_str = cx.argument::(0)?.value(&mut cx); + let substr_idxes = match extract_email_addr_idxes(&input_str) { + Ok(substr_idxes) => substr_idxes, + Err(e) => return cx.throw_error(e.to_string()), + }; + let js_array = JsArray::new(&mut cx, substr_idxes.len() as u32); + for (i, (start_idx, end_idx)) in substr_idxes.iter().enumerate() { + let start_end_array = JsArray::new(&mut cx, 2u32); + let start_idx = cx.number(*start_idx as f64); + start_end_array.set(&mut cx, 0, start_idx)?; + let end_idx = cx.number(*end_idx as f64); + start_end_array.set(&mut cx, 1, end_idx)?; + js_array.set(&mut cx, i as u32, start_end_array)?; + } + Ok(js_array) +} + +pub fn extract_email_domain_idxes_node(mut cx: FunctionContext) -> JsResult { + let input_str = cx.argument::(0)?.value(&mut cx); + let substr_idxes = match extract_email_domain_idxes(&input_str) { + Ok(substr_idxes) => substr_idxes, + Err(e) => return cx.throw_error(e.to_string()), + }; + let js_array = JsArray::new(&mut cx, substr_idxes.len() as u32); + for (i, (start_idx, end_idx)) in substr_idxes.iter().enumerate() { + let start_end_array = JsArray::new(&mut cx, 2u32); + let start_idx = cx.number(*start_idx as f64); + start_end_array.set(&mut cx, 0, start_idx)?; + let end_idx = cx.number(*end_idx as f64); + start_end_array.set(&mut cx, 1, end_idx)?; + js_array.set(&mut cx, i as u32, start_end_array)?; + } + Ok(js_array) +} + +pub fn extract_email_addr_with_name_idxes_node(mut cx: FunctionContext) -> JsResult { + let input_str = cx.argument::(0)?.value(&mut cx); + let substr_idxes = match extract_email_addr_with_name_idxes(&input_str) { + Ok(substr_idxes) => substr_idxes, + Err(e) => return cx.throw_error(e.to_string()), + }; + let js_array = JsArray::new(&mut cx, substr_idxes.len() as u32); + for (i, (start_idx, end_idx)) in substr_idxes.iter().enumerate() { + let start_end_array = JsArray::new(&mut cx, 2u32); + let start_idx = cx.number(*start_idx as f64); + start_end_array.set(&mut cx, 0, start_idx)?; + let end_idx = cx.number(*end_idx as f64); + start_end_array.set(&mut cx, 1, end_idx)?; + js_array.set(&mut cx, i as u32, start_end_array)?; + } + Ok(js_array) +} + +pub fn extract_from_all_idxes_node(mut cx: FunctionContext) -> JsResult { + let input_str = cx.argument::(0)?.value(&mut cx); + let substr_idxes = match extract_from_all_idxes(&input_str) { + Ok(substr_idxes) => substr_idxes, + Err(e) => return cx.throw_error(e.to_string()), + }; + let js_array = JsArray::new(&mut cx, substr_idxes.len() as u32); + for (i, (start_idx, end_idx)) in substr_idxes.iter().enumerate() { + let start_end_array = JsArray::new(&mut cx, 2u32); + let start_idx = cx.number(*start_idx as f64); + start_end_array.set(&mut cx, 0, start_idx)?; + let end_idx = cx.number(*end_idx as f64); + start_end_array.set(&mut cx, 1, end_idx)?; + js_array.set(&mut cx, i as u32, start_end_array)?; + } + Ok(js_array) +} + +pub fn extract_from_addr_idxes_node(mut cx: FunctionContext) -> JsResult { + let input_str = cx.argument::(0)?.value(&mut cx); + let substr_idxes = match extract_from_addr_idxes(&input_str) { + Ok(substr_idxes) => substr_idxes, + Err(e) => return cx.throw_error(e.to_string()), + }; + let js_array = JsArray::new(&mut cx, substr_idxes.len() as u32); + for (i, (start_idx, end_idx)) in substr_idxes.iter().enumerate() { + let start_end_array = JsArray::new(&mut cx, 2u32); + let start_idx = cx.number(*start_idx as f64); + start_end_array.set(&mut cx, 0, start_idx)?; + let end_idx = cx.number(*end_idx as f64); + start_end_array.set(&mut cx, 1, end_idx)?; + js_array.set(&mut cx, i as u32, start_end_array)?; + } + Ok(js_array) +} + +pub fn extract_to_all_idxes_node(mut cx: FunctionContext) -> JsResult { + let input_str = cx.argument::(0)?.value(&mut cx); + + let substr_idxes = match extract_to_all_idxes(&input_str) { + Ok(substr_idxes) => substr_idxes, + Err(e) => return cx.throw_error(e.to_string()), + }; + + let js_array = JsArray::new(&mut cx, substr_idxes.len() as u32); + + for (i, (start_idx, end_idx)) in substr_idxes.iter().enumerate() { + let start_end_array = JsArray::new(&mut cx, 2u32); + + let start_idx = cx.number(*start_idx as f64); + start_end_array.set(&mut cx, 0, start_idx)?; + + let end_idx = cx.number(*end_idx as f64); + start_end_array.set(&mut cx, 1, end_idx)?; + + js_array.set(&mut cx, i as u32, start_end_array)?; + } + + Ok(js_array) +} + +pub fn extract_to_addr_idxes_node(mut cx: FunctionContext) -> JsResult { + let input_str = cx.argument::(0)?.value(&mut cx); + let substr_idxes = match extract_to_addr_idxes(&input_str) { + Ok(substr_idxes) => substr_idxes, + Err(e) => return cx.throw_error(e.to_string()), + }; + let js_array = JsArray::new(&mut cx, substr_idxes.len() as u32); + for (i, (start_idx, end_idx)) in substr_idxes.iter().enumerate() { + let start_end_array = JsArray::new(&mut cx, 2u32); + let start_idx = cx.number(*start_idx as f64); + start_end_array.set(&mut cx, 0, start_idx)?; + let end_idx = cx.number(*end_idx as f64); + start_end_array.set(&mut cx, 1, end_idx)?; + js_array.set(&mut cx, i as u32, start_end_array)?; + } + Ok(js_array) +} + +pub fn extract_subject_all_idxes_node(mut cx: FunctionContext) -> JsResult { + let input_str = cx.argument::(0)?.value(&mut cx); + let substr_idxes = match extract_subject_all_idxes(&input_str) { + Ok(substr_idxes) => substr_idxes, + Err(e) => return cx.throw_error(e.to_string()), + }; + let js_array = JsArray::new(&mut cx, substr_idxes.len() as u32); + for (i, (start_idx, end_idx)) in substr_idxes.iter().enumerate() { + let start_end_array = JsArray::new(&mut cx, 2u32); + let start_idx = cx.number(*start_idx as f64); + start_end_array.set(&mut cx, 0, start_idx)?; + let end_idx = cx.number(*end_idx as f64); + start_end_array.set(&mut cx, 1, end_idx)?; + js_array.set(&mut cx, i as u32, start_end_array)?; + } + Ok(js_array) +} + +pub fn extract_body_hash_idxes_node(mut cx: FunctionContext) -> JsResult { + let input_str = cx.argument::(0)?.value(&mut cx); + let substr_idxes = match extract_body_hash_idxes(&input_str) { + Ok(substr_idxes) => substr_idxes, + Err(e) => return cx.throw_error(e.to_string()), + }; + let js_array = JsArray::new(&mut cx, substr_idxes.len() as u32); + for (i, (start_idx, end_idx)) in substr_idxes.iter().enumerate() { + let start_end_array = JsArray::new(&mut cx, 2u32); + let start_idx = cx.number(*start_idx as f64); + start_end_array.set(&mut cx, 0, start_idx)?; + let end_idx = cx.number(*end_idx as f64); + start_end_array.set(&mut cx, 1, end_idx)?; + js_array.set(&mut cx, i as u32, start_end_array)?; + } + Ok(js_array) +} + +pub fn extract_timestamp_idxes_node(mut cx: FunctionContext) -> JsResult { + let input_str = cx.argument::(0)?.value(&mut cx); + let substr_idxes = match extract_timestamp_idxes(&input_str) { + Ok(substr_idxes) => substr_idxes, + Err(e) => return cx.throw_error(e.to_string()), + }; + let js_array = JsArray::new(&mut cx, substr_idxes.len() as u32); + for (i, (start_idx, end_idx)) in substr_idxes.iter().enumerate() { + let start_end_array = JsArray::new(&mut cx, 2u32); + let start_idx = cx.number(*start_idx as f64); + start_end_array.set(&mut cx, 0, start_idx)?; + let end_idx = cx.number(*end_idx as f64); + start_end_array.set(&mut cx, 1, end_idx)?; + js_array.set(&mut cx, i as u32, start_end_array)?; + } + Ok(js_array) +} + +pub fn extract_message_id_idxes_node(mut cx: FunctionContext) -> JsResult { + let input_str = cx.argument::(0)?.value(&mut cx); + let substr_idxes = match extract_message_id_idxes(&input_str) { + Ok(substr_idxes) => substr_idxes, + Err(e) => return cx.throw_error(e.to_string()), + }; + let js_array = JsArray::new(&mut cx, substr_idxes.len() as u32); + for (i, (start_idx, end_idx)) in substr_idxes.iter().enumerate() { + let start_end_array = JsArray::new(&mut cx, 2u32); + let start_idx = cx.number(*start_idx as f64); + start_end_array.set(&mut cx, 0, start_idx)?; + let end_idx = cx.number(*end_idx as f64); + start_end_array.set(&mut cx, 1, end_idx)?; + js_array.set(&mut cx, i as u32, start_end_array)?; + } + Ok(js_array) +} diff --git a/yarn.lock b/yarn.lock index 3ef0fce5..c1e132f9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2003,10 +2003,10 @@ commander "^11.0.0" snarkjs "^0.7.0" -"@zk-email/zk-regex-circom@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@zk-email/zk-regex-circom/-/zk-regex-circom-1.3.0.tgz#8cb2b3b4977cfe42dc7072e13795e10d92efa074" - integrity sha512-faMboihzV3zyh2K3Qy4GYgxRRql4YEef26QDCISFFuURACWINfwtoZPC4OHtE0Ug60iAWRbpQtUWlPjomTCxoQ== +"@zk-email/zk-regex-circom@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@zk-email/zk-regex-circom/-/zk-regex-circom-2.0.1.tgz#588eaefb4b04ec099089539f39e35cafd9f2d52e" + integrity sha512-FwXpnTIh6TtFKYsF0yr1u6uwWipFYz42kH/jRE9FkLQ3QkrgZ3pdx65wuhUTOTH1i8IXS6Gs1x6l8quko9sx3w== dependencies: commander "^11.0.0" snarkjs "^0.7.0" From 9315f3c74efa19475230d644379db60335371b86 Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Mon, 25 Mar 2024 04:00:34 +0900 Subject: [PATCH 34/42] Fix database. --- packages/relayer/src/database.rs | 474 ++++++++++++++--------------- packages/relayer/src/main.rs | 1 + packages/relayer/src/web_server.rs | 342 ++++++++++----------- 3 files changed, 407 insertions(+), 410 deletions(-) diff --git a/packages/relayer/src/database.rs b/packages/relayer/src/database.rs index e4bd1f43..3936ad86 100644 --- a/packages/relayer/src/database.rs +++ b/packages/relayer/src/database.rs @@ -1,5 +1,6 @@ use crate::*; +use ic_utils::interfaces::wallet; use sqlx::{postgres::PgPool, Row}; pub struct Database { @@ -21,27 +22,30 @@ impl Database { pub(crate) async fn setup_database(&self) -> Result<()> { sqlx::query( - "CREATE TABLE IF NOT EXISTS users ( - email_address TEXT PRIMARY KEY, - account_key TEXT NOT NULL, - tx_hash TEXT NOT NULL, - is_onborded BOOLEAN NOT NULL DEFAULT FALSE + "CREATE TABLE IF NOT EXISTS codes ( + account_code TEXT PRIMARY KEY, + wallet_eth_addr TEXT NOT NULL, + guardian_email_addr TEXT NOT NULL, + is_set BOOLEAN NOT NULL DEFAULT FALSE );", ) .execute(&self.db) .await?; sqlx::query( - "CREATE TABLE IF NOT EXISTS claims ( - id TEXT PRIMARY KEY, - email_address TEXT NOT NULL, + "CREATE TABLE IF NOT EXISTS requests ( + request_id INT PRIMARY KEY, + wallet_eth_addr TEXT NOT NULL, + guardian_email_addr TEXT NOT NULL, random TEXT NOT NULL, email_addr_commit TEXT NOT NULL, - expiry_time BIGINT NOT NULL, - is_fund BOOLEAN NOT NULL, - is_announced BOOLEAN NOT NULL, - is_deleted BOOLEAN NOT NULL DEFAULT FALSE, - is_seen BOOLEAN NOT NULL DEFAULT FALSE + is_for_recovery BOOLEAN NOT NULL DEFAULT FALSE, + template_idx INT NOT NULL, + is_processed BOOLEAN NOT NULL DEFAULT FALSE, + is_success BOOLEAN, + email_nullifier TEXT, + account_salt TEXT, + is_code_exist BOOLEAN );", ) .execute(&self.db) @@ -101,40 +105,32 @@ impl Database { // } #[named] - pub(crate) async fn insert_user( + pub(crate) async fn insert_code( &self, - email_address: &str, - account_key: &str, - tx_hash: &str, - is_onborded: bool, + account_code: &str, + wallet_eth_addr: &str, + guardian_email_addr: &str, + is_set: bool, ) -> Result<()> { let row = sqlx::query( - "INSERT INTO users (email_address, account_key, tx_hash, is_onborded) VALUES ($1, $2, $3, $4) RETURNING *", + "INSERT INTO users (account_code, wallet_eth_addr, guardian_email_addr, is_set) VALUES ($1, $2, $3, $4) RETURNING *", ) - .bind(email_address) - .bind(account_key) - .bind(tx_hash) - .bind(is_onborded) + .bind(account_code) + .bind(wallet_eth_addr) + .bind(guardian_email_addr) + .bind(is_set) .fetch_one(&self.db) .await?; - info!( - LOG, - "inserted row: {}", - row.get::("email_address"); "func" => function_name!() - ); Ok(()) } #[named] - pub async fn user_onborded(&self, email_address: &str, tx_hash: &str) -> Result<()> { - info!(LOG, "email_address {}", email_address; "func" => function_name!()); - let res = sqlx::query( - "UPDATE users SET is_onborded = TRUE, tx_hash = $1 WHERE email_address = $2", - ) - .bind(tx_hash) - .bind(email_address) - .execute(&self.db) - .await?; + pub async fn set_guardian(&self, account_code: &str) -> Result<()> { + info!(LOG, "account_code {}", account_code; "func" => function_name!()); + let res = sqlx::query("UPDATE users SET is_set = TRUE WHERE account_code = $1") + .bind(account_code) + .execute(&self.db) + .await?; info!( LOG, "updated result: {:?}", @@ -143,218 +139,218 @@ impl Database { Ok(()) } - pub async fn get_claims_by_id(&self, id: &U256) -> Result> { - let mut vec = Vec::new(); + // pub async fn get_claims_by_id(&self, id: &U256) -> Result> { + // let mut vec = Vec::new(); - let rows = sqlx::query("SELECT * FROM claims WHERE id = $1 AND is_deleted = FALSE") - .bind(u256_to_hex(id)) - .fetch_all(&self.db) - .await?; + // let rows = sqlx::query("SELECT * FROM claims WHERE id = $1 AND is_deleted = FALSE") + // .bind(u256_to_hex(id)) + // .fetch_all(&self.db) + // .await?; - for row in rows { - let commit: String = row.get("email_addr_commit"); - let email_address: String = row.get("email_address"); - let random: String = row.get("random"); - let expiry_time: i64 = row.get("expiry_time"); - let is_fund: bool = row.get("is_fund"); - let is_announced: bool = row.get("is_announced"); - let is_seen: bool = row.get("is_seen"); - vec.push(Claim { - id: *id, - email_address, - random, - commit, - expiry_time, - is_fund, - is_announced, - is_seen, - }) - } - Ok(vec) - } + // for row in rows { + // let commit: String = row.get("email_addr_commit"); + // let email_address: String = row.get("email_address"); + // let random: String = row.get("random"); + // let expiry_time: i64 = row.get("expiry_time"); + // let is_fund: bool = row.get("is_fund"); + // let is_announced: bool = row.get("is_announced"); + // let is_seen: bool = row.get("is_seen"); + // vec.push(Claim { + // id: *id, + // email_address, + // random, + // commit, + // expiry_time, + // is_fund, + // is_announced, + // is_seen, + // }) + // } + // Ok(vec) + // } - pub async fn get_claims_by_email_addr(&self, email_addr: &str) -> Result> { - let mut vec = Vec::new(); - - let rows = - sqlx::query("SELECT * FROM claims WHERE email_address = $1 AND is_deleted = FALSE") - .bind(email_addr) - .fetch_all(&self.db) - .await?; - - for row in rows { - let id: String = row.get("id"); - let commit: String = row.get("email_addr_commit"); - let email_address: String = row.get("email_address"); - let random: String = row.get("random"); - let expiry_time: i64 = row.get("expiry_time"); - let is_fund: bool = row.get("is_fund"); - let is_announced: bool = row.get("is_announced"); - let is_seen: bool = row.get("is_seen"); - vec.push(Claim { - id: hex_to_u256(&id)?, - email_address, - random, - commit, - expiry_time, - is_fund, - is_announced, - is_seen, - }) - } - Ok(vec) - } + // pub async fn get_claims_by_email_addr(&self, email_addr: &str) -> Result> { + // let mut vec = Vec::new(); - #[named] - pub async fn get_claims_unexpired(&self, now: i64) -> Result> { - let mut vec = Vec::new(); - info!(LOG, "now {}", now; "func" => function_name!()); - let rows = - sqlx::query("SELECT * FROM claims WHERE expiry_time > $1 AND is_deleted = FALSE") - .bind(now) - .fetch_all(&self.db) - .await?; - - for row in rows { - let id: String = row.get("id"); - let commit: String = row.get("email_addr_commit"); - let email_address: String = row.get("email_address"); - let random: String = row.get("random"); - let expiry_time: i64 = row.get("expiry_time"); - let is_fund: bool = row.get("is_fund"); - let is_announced: bool = row.get("is_announced"); - let is_seen: bool = row.get("is_seen"); - vec.push(Claim { - id: hex_to_u256(&id)?, - email_address, - random, - commit, - expiry_time, - is_fund, - is_announced, - is_seen, - }) - } - Ok(vec) - } + // let rows = + // sqlx::query("SELECT * FROM claims WHERE email_address = $1 AND is_deleted = FALSE") + // .bind(email_addr) + // .fetch_all(&self.db) + // .await?; - #[named] - pub async fn get_claims_expired(&self, now: i64) -> Result> { - let mut vec = Vec::new(); - info!(LOG, "now {}", now; "func" => function_name!()); - let rows = - sqlx::query("SELECT * FROM claims WHERE expiry_time < $1 AND is_deleted = FALSE") - .bind(now) - .fetch_all(&self.db) - .await?; - - for row in rows { - let id: String = row.get("id"); - let commit: String = row.get("email_addr_commit"); - let email_address: String = row.get("email_address"); - let random: String = row.get("random"); - let expiry_time: i64 = row.get("expiry_time"); - let is_fund: bool = row.get("is_fund"); - let is_announced: bool = row.get("is_announced"); - let is_seen: bool = row.get("is_seen"); - vec.push(Claim { - id: hex_to_u256(&id)?, - email_address, - random, - commit, - expiry_time, - is_fund, - is_announced, - is_seen, - }) - } - Ok(vec) - } + // for row in rows { + // let id: String = row.get("id"); + // let commit: String = row.get("email_addr_commit"); + // let email_address: String = row.get("email_address"); + // let random: String = row.get("random"); + // let expiry_time: i64 = row.get("expiry_time"); + // let is_fund: bool = row.get("is_fund"); + // let is_announced: bool = row.get("is_announced"); + // let is_seen: bool = row.get("is_seen"); + // vec.push(Claim { + // id: hex_to_u256(&id)?, + // email_address, + // random, + // commit, + // expiry_time, + // is_fund, + // is_announced, + // is_seen, + // }) + // } + // Ok(vec) + // } - #[named] - pub(crate) async fn insert_claim(&self, claim: &Claim) -> Result<()> { - info!(LOG, "expiry_time {}", claim.expiry_time; "func" => function_name!()); - let row = sqlx::query( - "INSERT INTO claims (id, email_address, random, email_addr_commit, expiry_time, is_fund, is_announced, is_seen) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *", - ) - .bind(u256_to_hex(&claim.id)) - .bind(claim.email_address.clone()) - .bind(claim.random.clone()) - .bind(claim.commit.clone()) - .bind(claim.expiry_time) - .bind(claim.is_fund) - .bind(claim.is_announced) - .bind(claim.is_seen) - .fetch_one(&self.db) - .await?; - info!( - LOG, - "inserted row: {}", - row.get::("email_addr_commit"); "func" => function_name!() - ); - Ok(()) - } + // #[named] + // pub async fn get_claims_unexpired(&self, now: i64) -> Result> { + // let mut vec = Vec::new(); + // info!(LOG, "now {}", now; "func" => function_name!()); + // let rows = + // sqlx::query("SELECT * FROM claims WHERE expiry_time > $1 AND is_deleted = FALSE") + // .bind(now) + // .fetch_all(&self.db) + // .await?; - pub(crate) async fn delete_claim(&self, id: &U256, is_fund: bool) -> Result<()> { - sqlx::query("UPDATE claims SET is_deleted=TRUE WHERE id = $1 AND is_fund = $2 AND is_deleted = FALSE") - .bind(u256_to_hex(id)) - .bind(is_fund) - .execute(&self.db) - .await?; - // sqlx::query("DELETE FROM claims WHERE id = $1 AND is_fund = $2") - // .bind(u256_to_hex(id)) - // .bind(is_fund) - // .execute(&self.db) - // .await?; - Ok(()) - } + // for row in rows { + // let id: String = row.get("id"); + // let commit: String = row.get("email_addr_commit"); + // let email_address: String = row.get("email_address"); + // let random: String = row.get("random"); + // let expiry_time: i64 = row.get("expiry_time"); + // let is_fund: bool = row.get("is_fund"); + // let is_announced: bool = row.get("is_announced"); + // let is_seen: bool = row.get("is_seen"); + // vec.push(Claim { + // id: hex_to_u256(&id)?, + // email_address, + // random, + // commit, + // expiry_time, + // is_fund, + // is_announced, + // is_seen, + // }) + // } + // Ok(vec) + // } - pub async fn contains_user(&self, email_address: &str) -> Result { - let result = sqlx::query("SELECT 1 FROM users WHERE email_address = $1") - .bind(email_address) - .fetch_optional(&self.db) - .await?; + // #[named] + // pub async fn get_claims_expired(&self, now: i64) -> Result> { + // let mut vec = Vec::new(); + // info!(LOG, "now {}", now; "func" => function_name!()); + // let rows = + // sqlx::query("SELECT * FROM claims WHERE expiry_time < $1 AND is_deleted = FALSE") + // .bind(now) + // .fetch_all(&self.db) + // .await?; - Ok(result.is_some()) - } + // for row in rows { + // let id: String = row.get("id"); + // let commit: String = row.get("email_addr_commit"); + // let email_address: String = row.get("email_address"); + // let random: String = row.get("random"); + // let expiry_time: i64 = row.get("expiry_time"); + // let is_fund: bool = row.get("is_fund"); + // let is_announced: bool = row.get("is_announced"); + // let is_seen: bool = row.get("is_seen"); + // vec.push(Claim { + // id: hex_to_u256(&id)?, + // email_address, + // random, + // commit, + // expiry_time, + // is_fund, + // is_announced, + // is_seen, + // }) + // } + // Ok(vec) + // } - pub async fn is_user_onborded(&self, email_address: &str) -> Result { - let result = sqlx::query("SELECT is_onborded FROM users WHERE email_address = $1") - .bind(email_address) - .fetch_one(&self.db) - .await?; - Ok(result.get("is_onborded")) - } + // #[named] + // pub(crate) async fn insert_claim(&self, claim: &Claim) -> Result<()> { + // info!(LOG, "expiry_time {}", claim.expiry_time; "func" => function_name!()); + // let row = sqlx::query( + // "INSERT INTO claims (id, email_address, random, email_addr_commit, expiry_time, is_fund, is_announced, is_seen) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *", + // ) + // .bind(u256_to_hex(&claim.id)) + // .bind(claim.email_address.clone()) + // .bind(claim.random.clone()) + // .bind(claim.commit.clone()) + // .bind(claim.expiry_time) + // .bind(claim.is_fund) + // .bind(claim.is_announced) + // .bind(claim.is_seen) + // .fetch_one(&self.db) + // .await?; + // info!( + // LOG, + // "inserted row: {}", + // row.get::("email_addr_commit"); "func" => function_name!() + // ); + // Ok(()) + // } - pub async fn get_account_key(&self, email_address: &str) -> Result> { - let row_result = sqlx::query("SELECT account_key FROM users WHERE email_address = $1") - .bind(email_address) - .fetch_one(&self.db) - .await; - - match row_result { - Ok(row) => { - let account_key: String = row.get("account_key"); - Ok(Some(account_key)) - } - Err(sqlx::error::Error::RowNotFound) => Ok(None), - Err(e) => Err(e).map_err(|e| anyhow::anyhow!(e))?, - } - } + // pub(crate) async fn delete_claim(&self, id: &U256, is_fund: bool) -> Result<()> { + // sqlx::query("UPDATE claims SET is_deleted=TRUE WHERE id = $1 AND is_fund = $2 AND is_deleted = FALSE") + // .bind(u256_to_hex(id)) + // .bind(is_fund) + // .execute(&self.db) + // .await?; + // // sqlx::query("DELETE FROM claims WHERE id = $1 AND is_fund = $2") + // // .bind(u256_to_hex(id)) + // // .bind(is_fund) + // // .execute(&self.db) + // // .await?; + // Ok(()) + // } - pub async fn get_creation_tx_hash(&self, email_address: &str) -> Result> { - let row_result = sqlx::query("SELECT tx_hash FROM users WHERE email_address = $1") - .bind(email_address) - .fetch_one(&self.db) - .await; - - match row_result { - Ok(row) => { - let tx_hash: String = row.get("tx_hash"); - Ok(Some(tx_hash)) - } - Err(sqlx::error::Error::RowNotFound) => Ok(None), - Err(e) => Err(e).map_err(|e| anyhow::anyhow!(e))?, - } - } + // pub async fn contains_user(&self, email_address: &str) -> Result { + // let result = sqlx::query("SELECT 1 FROM users WHERE email_address = $1") + // .bind(email_address) + // .fetch_optional(&self.db) + // .await?; + + // Ok(result.is_some()) + // } + + // pub async fn is_user_onborded(&self, email_address: &str) -> Result { + // let result = sqlx::query("SELECT is_onborded FROM users WHERE email_address = $1") + // .bind(email_address) + // .fetch_one(&self.db) + // .await?; + // Ok(result.get("is_onborded")) + // } + + // pub async fn get_account_key(&self, email_address: &str) -> Result> { + // let row_result = sqlx::query("SELECT account_key FROM users WHERE email_address = $1") + // .bind(email_address) + // .fetch_one(&self.db) + // .await; + + // match row_result { + // Ok(row) => { + // let account_key: String = row.get("account_key"); + // Ok(Some(account_key)) + // } + // Err(sqlx::error::Error::RowNotFound) => Ok(None), + // Err(e) => Err(e).map_err(|e| anyhow::anyhow!(e))?, + // } + // } + + // pub async fn get_creation_tx_hash(&self, email_address: &str) -> Result> { + // let row_result = sqlx::query("SELECT tx_hash FROM users WHERE email_address = $1") + // .bind(email_address) + // .fetch_one(&self.db) + // .await; + + // match row_result { + // Ok(row) => { + // let tx_hash: String = row.get("tx_hash"); + // Ok(Some(tx_hash)) + // } + // Err(sqlx::error::Error::RowNotFound) => Ok(None), + // Err(e) => Err(e).map_err(|e| anyhow::anyhow!(e))?, + // } + // } } diff --git a/packages/relayer/src/main.rs b/packages/relayer/src/main.rs index 09345041..6c960355 100644 --- a/packages/relayer/src/main.rs +++ b/packages/relayer/src/main.rs @@ -1 +1,2 @@ use relayer::*; +fn main() {} diff --git a/packages/relayer/src/web_server.rs b/packages/relayer/src/web_server.rs index d13040b1..b18610cd 100644 --- a/packages/relayer/src/web_server.rs +++ b/packages/relayer/src/web_server.rs @@ -7,184 +7,184 @@ use serde::{Deserialize, Serialize}; use tokio::sync::mpsc::UnboundedSender; use tower_http::cors::{AllowHeaders, AllowMethods, Any, CorsLayer}; -#[derive(Serialize, Deserialize)] -pub struct EmailAddrCommitRequest { - pub email_address: String, - pub random: String, -} +// #[derive(Serialize, Deserialize)] +// pub struct EmailAddrCommitRequest { +// pub email_address: String, +// pub random: String, +// } -#[derive(Serialize, Deserialize)] -pub struct UnclaimRequest { - pub email_address: String, - pub random: String, - pub expiry_time: i64, - pub is_fund: bool, - pub tx_hash: String, -} +// #[derive(Serialize, Deserialize)] +// pub struct UnclaimRequest { +// pub email_address: String, +// pub random: String, +// pub expiry_time: i64, +// pub is_fund: bool, +// pub tx_hash: String, +// } -#[derive(Serialize, Deserialize)] -pub struct AccountRegistrationRequest { - pub email_address: String, - pub account_key: String, -} +// #[derive(Serialize, Deserialize)] +// pub struct AccountRegistrationRequest { +// pub email_address: String, +// pub account_key: String, +// } -#[derive(Serialize, Deserialize)] -pub struct AccountRegistrationResponse { - pub account_key: String, - pub wallet_addr: String, - pub tx_hash: String, -} +// #[derive(Serialize, Deserialize)] +// pub struct AccountRegistrationResponse { +// pub account_key: String, +// pub wallet_addr: String, +// pub tx_hash: String, +// } -#[derive(Serialize, Deserialize)] -pub struct StatResponse { - pub onboarding_tokens_distributed: u32, - pub onboarding_tokens_left: u32, -} +// #[derive(Serialize, Deserialize)] +// pub struct StatResponse { +// pub onboarding_tokens_distributed: u32, +// pub onboarding_tokens_left: u32, +// } -#[named] -async fn unclaim( - payload: UnclaimRequest, - db: Arc, - chain_client: Arc, - tx_claimer: UnboundedSender, -) -> Result { - let padded_email_addr = PaddedEmailAddr::from_email_addr(&payload.email_address); - info!( - LOG, - "padded email address fields: {:?}", - padded_email_addr.to_email_addr_fields(); "func" => function_name!() - ); - let commit = padded_email_addr.to_commitment(&hex2field(&payload.random)?)?; - info!(LOG, "commit {:?}", commit; "func" => function_name!()); - let id = chain_client - .get_unclaim_id_from_tx_hash(&payload.tx_hash, payload.is_fund) - .await?; - info!(LOG, "id {:?}", id; "func" => function_name!()); - // let psi_client = PSIClient::new( - // Arc::clone(&chain_client), - // payload.email_address.clone(), - // id, - // payload.is_fund, - // ) - // .await?; - // psi_client - // .check_and_reveal(db.clone(), chain_client.clone(), &payload.email_address) - // .await?; - let claim = Claim { - id, - email_address: payload.email_address.clone(), - random: payload.random.clone(), - commit: field2hex(&commit), - expiry_time: payload.expiry_time, - is_fund: payload.is_fund, - is_announced: false, - is_seen: false, - }; - tx_claimer.send(claim)?; - trace!(LOG, "claim sent to tx_claimer"; "func" => function_name!()); +// #[named] +// async fn unclaim( +// payload: UnclaimRequest, +// db: Arc, +// chain_client: Arc, +// tx_claimer: UnboundedSender, +// ) -> Result { +// let padded_email_addr = PaddedEmailAddr::from_email_addr(&payload.email_address); +// info!( +// LOG, +// "padded email address fields: {:?}", +// padded_email_addr.to_email_addr_fields(); "func" => function_name!() +// ); +// let commit = padded_email_addr.to_commitment(&hex2field(&payload.random)?)?; +// info!(LOG, "commit {:?}", commit; "func" => function_name!()); +// let id = chain_client +// .get_unclaim_id_from_tx_hash(&payload.tx_hash, payload.is_fund) +// .await?; +// info!(LOG, "id {:?}", id; "func" => function_name!()); +// // let psi_client = PSIClient::new( +// // Arc::clone(&chain_client), +// // payload.email_address.clone(), +// // id, +// // payload.is_fund, +// // ) +// // .await?; +// // psi_client +// // .check_and_reveal(db.clone(), chain_client.clone(), &payload.email_address) +// // .await?; +// let claim = Claim { +// id, +// email_address: payload.email_address.clone(), +// random: payload.random.clone(), +// commit: field2hex(&commit), +// expiry_time: payload.expiry_time, +// is_fund: payload.is_fund, +// is_announced: false, +// is_seen: false, +// }; +// tx_claimer.send(claim)?; +// trace!(LOG, "claim sent to tx_claimer"; "func" => function_name!()); - Ok(format!( - "Unclaimed {} for {} is accepted", - if payload.is_fund { "fund" } else { "state" }, - payload.email_address - )) -} +// Ok(format!( +// "Unclaimed {} for {} is accepted", +// if payload.is_fund { "fund" } else { "state" }, +// payload.email_address +// )) +// } -#[named] -pub(crate) async fn run_server( - addr: &str, - routes: Vec<(String, MethodRouter)>, - db: Arc, - chain_client: Arc, - tx_claimer: UnboundedSender, -) -> Result<()> { - let chain_client_check_clone = Arc::clone(&chain_client); - let chain_client_reveal_clone = Arc::clone(&chain_client); - let tx_claimer_reveal_clone = tx_claimer.clone(); +// #[named] +// pub(crate) async fn run_server( +// addr: &str, +// routes: Vec<(String, MethodRouter)>, +// db: Arc, +// chain_client: Arc, +// tx_claimer: UnboundedSender, +// ) -> Result<()> { +// let chain_client_check_clone = Arc::clone(&chain_client); +// let chain_client_reveal_clone = Arc::clone(&chain_client); +// let tx_claimer_reveal_clone = tx_claimer.clone(); - let mut app = Router::new() - .route( - "/api/emailAddrCommit", - axum::routing::post(move |payload: String| async move { - info!(LOG, "/emailAddrCommit Received payload: {}", payload; "func" => function_name!()); - let json = serde_json::from_str::(&payload) - .map_err(|_| "Invalid payload json".to_string()) - .unwrap(); - let padded_email_addr = PaddedEmailAddr::from_email_addr(&json.email_address); - let commit = padded_email_addr - .to_commitment(&hex2field(&json.random).unwrap()) - .unwrap(); - info!(LOG, "commit {:?}", commit; "func" => function_name!()); - field2hex(&commit) - }), - ) - .route( - "/api/unclaim", - axum::routing::post(move |payload: String| async move { - info!(LOG, "/unclaim Received payload: {}", payload; "func" => function_name!()); - let json = serde_json::from_str::(&payload) - .map_err(|_| "Invalid payload json".to_string())?; - unclaim(json, db, chain_client, tx_claimer) - .await - .map_err(|err| { - error!(LOG, "Failed to accept unclaim: {}", err; "func" => function_name!()); - err.to_string() - }) - }), - ) - .route( - "/api/stats", - axum::routing::get(move || async move { - let stats = StatResponse { - onboarding_tokens_distributed: ONBOARDING_COUNTER.load(Ordering::SeqCst), - onboarding_tokens_left: *ONBOARDING_TOKEN_DISTRIBUTION_LIMIT.get().unwrap() - - ONBOARDING_COUNTER.load(Ordering::SeqCst), - }; - axum::Json(stats) - }), - ) - .route( - "/api/serveCheck/", - axum::routing::post(move |payload: String| async move { - info!(LOG, "/serveCheck Received payload: {}", payload; "func" => function_name!()); - let json = serde_json::from_str::(&payload) - .map_err(|_| "Invalid payload json".to_string())?; - serve_check_request(json, chain_client_check_clone) - .await - .map_err(|err| { - error!(LOG, "Failed PSI check serve: {}", err; "func" => function_name!()); - err.to_string() - }) - }), - ) - .route( - "/api/serveReveal/", - axum::routing::post(move |payload: String| async move { - info!(LOG, "/serveCheck Received payload: {}", payload; "func" => function_name!()); - let json = serde_json::from_str::(&payload) - .map_err(|_| "Invalid payload json".to_string())?; - serve_reveal_request(json, chain_client_reveal_clone, tx_claimer_reveal_clone) - .await - .map_err(|err| { - error!(LOG, "Failed PSI reveal serve: {}", err; "func" => function_name!()); - err.to_string() - }) - }), - ); - for (path, router) in routes { - app = app.route(&path, router); - } - app = app.layer( - CorsLayer::new() - .allow_methods(AllowMethods::any()) - .allow_headers(AllowHeaders::any()) - .allow_origin(Any), - ); +// let mut app = Router::new() +// .route( +// "/api/emailAddrCommit", +// axum::routing::post(move |payload: String| async move { +// info!(LOG, "/emailAddrCommit Received payload: {}", payload; "func" => function_name!()); +// let json = serde_json::from_str::(&payload) +// .map_err(|_| "Invalid payload json".to_string()) +// .unwrap(); +// let padded_email_addr = PaddedEmailAddr::from_email_addr(&json.email_address); +// let commit = padded_email_addr +// .to_commitment(&hex2field(&json.random).unwrap()) +// .unwrap(); +// info!(LOG, "commit {:?}", commit; "func" => function_name!()); +// field2hex(&commit) +// }), +// ) +// .route( +// "/api/unclaim", +// axum::routing::post(move |payload: String| async move { +// info!(LOG, "/unclaim Received payload: {}", payload; "func" => function_name!()); +// let json = serde_json::from_str::(&payload) +// .map_err(|_| "Invalid payload json".to_string())?; +// unclaim(json, db, chain_client, tx_claimer) +// .await +// .map_err(|err| { +// error!(LOG, "Failed to accept unclaim: {}", err; "func" => function_name!()); +// err.to_string() +// }) +// }), +// ) +// .route( +// "/api/stats", +// axum::routing::get(move || async move { +// let stats = StatResponse { +// onboarding_tokens_distributed: ONBOARDING_COUNTER.load(Ordering::SeqCst), +// onboarding_tokens_left: *ONBOARDING_TOKEN_DISTRIBUTION_LIMIT.get().unwrap() +// - ONBOARDING_COUNTER.load(Ordering::SeqCst), +// }; +// axum::Json(stats) +// }), +// ) +// .route( +// "/api/serveCheck/", +// axum::routing::post(move |payload: String| async move { +// info!(LOG, "/serveCheck Received payload: {}", payload; "func" => function_name!()); +// let json = serde_json::from_str::(&payload) +// .map_err(|_| "Invalid payload json".to_string())?; +// serve_check_request(json, chain_client_check_clone) +// .await +// .map_err(|err| { +// error!(LOG, "Failed PSI check serve: {}", err; "func" => function_name!()); +// err.to_string() +// }) +// }), +// ) +// .route( +// "/api/serveReveal/", +// axum::routing::post(move |payload: String| async move { +// info!(LOG, "/serveCheck Received payload: {}", payload; "func" => function_name!()); +// let json = serde_json::from_str::(&payload) +// .map_err(|_| "Invalid payload json".to_string())?; +// serve_reveal_request(json, chain_client_reveal_clone, tx_claimer_reveal_clone) +// .await +// .map_err(|err| { +// error!(LOG, "Failed PSI reveal serve: {}", err; "func" => function_name!()); +// err.to_string() +// }) +// }), +// ); +// for (path, router) in routes { +// app = app.route(&path, router); +// } +// app = app.layer( +// CorsLayer::new() +// .allow_methods(AllowMethods::any()) +// .allow_headers(AllowHeaders::any()) +// .allow_origin(Any), +// ); - trace!(LOG, "Listening API at {}", addr; "func" => function_name!()); - axum::Server::bind(&addr.parse()?) - .serve(app.into_make_service()) - .await?; +// trace!(LOG, "Listening API at {}", addr; "func" => function_name!()); +// axum::Server::bind(&addr.parse()?) +// .serve(app.into_make_service()) +// .await?; - Ok(()) -} +// Ok(()) +// } From c53d555f981bccc9aba8cb5ebd15dbe0506ae540 Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Mon, 25 Mar 2024 04:09:24 +0900 Subject: [PATCH 35/42] Remove unused code. --- packages/relayer/src/subject_templates.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/relayer/src/subject_templates.rs b/packages/relayer/src/subject_templates.rs index 52ea66b1..9b64cb6e 100644 --- a/packages/relayer/src/subject_templates.rs +++ b/packages/relayer/src/subject_templates.rs @@ -116,7 +116,6 @@ pub fn extract_template_vals(input: &str, templates: Vec) -> Result Date: Mon, 25 Mar 2024 22:34:37 +0900 Subject: [PATCH 36/42] Update database and web_server --- packages/relayer/src/database.rs | 177 +++++++++++++++++++++++++++-- packages/relayer/src/lib.rs | 1 + packages/relayer/src/web_server.rs | 126 +++++++++++++++----- 3 files changed, 263 insertions(+), 41 deletions(-) diff --git a/packages/relayer/src/database.rs b/packages/relayer/src/database.rs index 3936ad86..7a7b9f14 100644 --- a/packages/relayer/src/database.rs +++ b/packages/relayer/src/database.rs @@ -3,6 +3,28 @@ use crate::*; use ic_utils::interfaces::wallet; use sqlx::{postgres::PgPool, Row}; +#[derive(Debug, Clone)] +pub struct CodesRow { + pub account_code: String, + pub wallet_eth_addr: String, + pub guardian_email_addr: String, + pub is_set: bool, +} + +#[derive(Debug, Clone)] +pub struct RequestsRow { + pub request_id: i64, + pub wallet_eth_addr: String, + pub guardian_email_addr: String, + pub is_for_recovery: bool, + pub template_idx: u64, + pub is_processed: bool, + pub is_success: Option, + pub email_nullifier: Option, + pub account_salt: Option, + pub is_code_exist: Option, +} + pub struct Database { db: PgPool, } @@ -105,27 +127,53 @@ impl Database { // } #[named] - pub(crate) async fn insert_code( - &self, - account_code: &str, - wallet_eth_addr: &str, - guardian_email_addr: &str, - is_set: bool, - ) -> Result<()> { + pub(crate) async fn get_codes_row(&self, account_code: &str) -> Result> { + let row = sqlx::query("SELECT * FROM codes WHERE account_code = $1") + .bind(account_code) + .fetch_optional(&self.db) + .await?; + + match row { + Some(row) => { + let account_code: String = row.get("account_code"); + let wallet_eth_addr: String = row.get("wallet_eth_addr"); + let guardian_email_addr: String = row.get("guardian_email_addr"); + let is_set: bool = row.get("is_set"); + let codes_row = CodesRow { + account_code, + wallet_eth_addr, + guardian_email_addr, + is_set, + }; + info!(LOG, "row {:?}", codes_row; "func" => function_name!()); + Ok(Some(codes_row)) + } + None => Ok(None), + } + } + + #[named] + pub(crate) async fn insert_codes_row(&self, row: &CodesRow) -> Result<()> { + info!(LOG, "insert row {:?}", row; "func" => function_name!()); let row = sqlx::query( "INSERT INTO users (account_code, wallet_eth_addr, guardian_email_addr, is_set) VALUES ($1, $2, $3, $4) RETURNING *", ) - .bind(account_code) - .bind(wallet_eth_addr) - .bind(guardian_email_addr) - .bind(is_set) + .bind(&row.account_code) + .bind(&row.wallet_eth_addr) + .bind(&row.guardian_email_addr) + .bind(row.is_set) .fetch_one(&self.db) .await?; + info!( + LOG, + "{} row inserted", + row.len(); "func" => function_name!() + ); Ok(()) } #[named] - pub async fn set_guardian(&self, account_code: &str) -> Result<()> { + pub async fn set_guardian_in_codes(&self, account_code: &str) -> Result<()> { info!(LOG, "account_code {}", account_code; "func" => function_name!()); let res = sqlx::query("UPDATE users SET is_set = TRUE WHERE account_code = $1") .bind(account_code) @@ -139,6 +187,111 @@ impl Database { Ok(()) } + #[named] + pub(crate) async fn get_requests_row(&self, request_id: i64) -> Result> { + let row = sqlx::query("SELECT * FROM requests WHERE request_id = $1") + .bind(request_id) + .fetch_optional(&self.db) + .await?; + + match row { + Some(row) => { + let request_id: i64 = row.get("request_id"); + let wallet_eth_addr: String = row.get("wallet_eth_addr"); + let guardian_email_addr: String = row.get("guardian_email_addr"); + let is_for_recovery: bool = row.get("is_for_recovery"); + let template_idx: u64 = row.get::("template_idx") as u64; + let is_processed: bool = row.get("is_processed"); + let is_success: Option = row.get("is_success"); + let email_nullifier: Option = row.get("email_nullifier"); + let account_salt: Option = row.get("account_salt"); + let is_code_exist: Option = row.get("is_code_exist"); + let requests_row = RequestsRow { + request_id, + wallet_eth_addr, + guardian_email_addr, + is_for_recovery, + template_idx, + is_processed, + is_success, + email_nullifier, + account_salt, + is_code_exist, + }; + info!(LOG, "row {:?}", requests_row; "func" => function_name!()); + Ok(Some(requests_row)) + } + None => Ok(None), + } + } + + #[named] + pub(crate) async fn insert_requests_row(&self, row: &RequestsRow) -> Result<()> { + info!(LOG, "insert row {:?}", row; "func" => function_name!()); + let row = sqlx::query( + "INSERT INTO requests (request_id, wallet_eth_addr, guardian_email_addr, is_for_recovery, template_idx, is_processed, is_success, email_nullifier, account_salt, is_code_exist) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING *", + ) + .bind(&row.request_id) + .bind(&row.wallet_eth_addr) + .bind(&row.guardian_email_addr) + .bind(row.is_for_recovery) + .bind(row.template_idx as i64) + .bind(row.is_processed) + .bind(row.is_success) + .bind(&row.email_nullifier) + .bind(&row.account_salt) + .bind(row.is_code_exist) + .fetch_one(&self.db) + .await?; + info!( + LOG, + "{} row inserted", + row.len(); "func" => function_name!() + ); + Ok(()) + } + + #[named] + pub(crate) async fn request_successed( + &self, + request_id: i64, + email_nullifier: &str, + account_salt: &str, + is_code_exist: bool, + ) -> Result<()> { + info!(LOG, "request_id {}", request_id; "func" => function_name!()); + let res = sqlx::query("UPDATE requests SET is_processed = TRUE, is_success = TRUE, email_nullifier = $1, account_salt = $2, is_code_exist = $3, WHERE request_id = $4") + .bind(email_nullifier) + .bind(account_salt) + .bind(is_code_exist) + .bind(request_id) + .execute(&self.db) + .await?; + info!( + LOG, + "updated result: {:?}", + res; "func" => function_name!() + ); + Ok(()) + } + + #[named] + pub(crate) async fn request_failed(&self, request_id: i64) -> Result<()> { + info!(LOG, "request_id {}", request_id; "func" => function_name!()); + let res = sqlx::query( + "UPDATE requests SET is_processed = TRUE, is_success = FALSE WHERE request_id = $1", + ) + .bind(request_id) + .execute(&self.db) + .await?; + info!( + LOG, + "updated result: {:?}", + res; "func" => function_name!() + ); + Ok(()) + } + // pub async fn get_claims_by_id(&self, id: &U256) -> Result> { // let mut vec = Vec::new(); diff --git a/packages/relayer/src/lib.rs b/packages/relayer/src/lib.rs index 15617bea..552d8151 100644 --- a/packages/relayer/src/lib.rs +++ b/packages/relayer/src/lib.rs @@ -20,6 +20,7 @@ pub(crate) use imap_client::*; pub(crate) use logger::*; pub(crate) use slog::*; pub(crate) use smtp_client::*; +pub(crate) use std::sync::{Arc, OnceLock}; pub(crate) use subject_templates::*; pub(crate) use utils::*; pub(crate) use web_server::*; diff --git a/packages/relayer/src/web_server.rs b/packages/relayer/src/web_server.rs index b18610cd..0c73e475 100644 --- a/packages/relayer/src/web_server.rs +++ b/packages/relayer/src/web_server.rs @@ -7,40 +7,108 @@ use serde::{Deserialize, Serialize}; use tokio::sync::mpsc::UnboundedSender; use tower_http::cors::{AllowHeaders, AllowMethods, Any, CorsLayer}; -// #[derive(Serialize, Deserialize)] -// pub struct EmailAddrCommitRequest { -// pub email_address: String, -// pub random: String, -// } +#[derive(Serialize, Deserialize)] +pub struct RequestStatusRequest { + pub request_id: i64, +} -// #[derive(Serialize, Deserialize)] -// pub struct UnclaimRequest { -// pub email_address: String, -// pub random: String, -// pub expiry_time: i64, -// pub is_fund: bool, -// pub tx_hash: String, -// } +#[derive(Serialize, Deserialize)] +pub enum RequestStatus { + NotExist = 0, + Pending = 1, + Processed = 2, +} -// #[derive(Serialize, Deserialize)] -// pub struct AccountRegistrationRequest { -// pub email_address: String, -// pub account_key: String, -// } +#[derive(Serialize, Deserialize)] +pub struct RequestStatusResponse { + pub request_id: i64, + pub status: RequestStatus, + pub is_success: bool, + pub email_nullifier: Option, + pub account_salt: Option, + pub is_code_exist: Option, +} -// #[derive(Serialize, Deserialize)] -// pub struct AccountRegistrationResponse { -// pub account_key: String, -// pub wallet_addr: String, -// pub tx_hash: String, -// } +#[derive(Serialize, Deserialize)] +pub struct AcceptanceRequest { + pub wallet_eth_addr: String, + pub guardian_email_addr: String, + pub account_code: String, + pub template_idx: u64, + pub subject: String, +} -// #[derive(Serialize, Deserialize)] -// pub struct StatResponse { -// pub onboarding_tokens_distributed: u32, -// pub onboarding_tokens_left: u32, -// } +#[derive(Serialize, Deserialize)] +pub struct AcceptanceResponse { + pub request_id: i64, + pub subject_params: Vec, +} + +#[derive(Serialize, Deserialize)] +pub struct RecoveryRequest { + pub wallet_eth_addr: String, + pub guardian_email_addr: String, + pub template_idx: u64, + pub subject: String, +} +#[derive(Serialize, Deserialize)] +pub struct RecoveryResponse { + pub request_id: i64, + pub subject_params: Vec, +} + +#[named] +async fn requestStatus(payload: String, db: Arc) -> Result { + let req = serde_json::from_str::(&payload) + .map_err(|_| anyhow!("Invalid payload json".to_string()))?; + let request_id = req.request_id; + let row = db.get_requests_row(request_id).await?; + match row { + None => Ok(RequestStatusResponse { + request_id, + status: RequestStatus::NotExist, + is_success: false, + email_nullifier: None, + account_salt: None, + is_code_exist: None, + }), + Some(row) => { + let status = if row.is_processed { + RequestStatus::Processed + } else { + RequestStatus::Pending + }; + Ok(RequestStatusResponse { + request_id, + status, + is_success: row.is_success.unwrap_or(false), + email_nullifier: if row.is_processed { + row.email_nullifier + } else { + None + }, + account_salt: if row.is_processed { + row.account_salt + } else { + None + }, + is_code_exist: if row.is_processed { + row.is_code_exist + } else { + None + }, + }) + } + } +} + +// #[named] +// async fn acceptanceRequest(payload: String, db: Arc) -> Result { +// let req = serde_json::from_str::(&payload) +// .map_err(|_| anyhow!("Invalid payload json".to_string()))?; + +// } // #[named] // async fn unclaim( // payload: UnclaimRequest, From 75607805e8982a4851970c724c43fd6515e974eb Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Tue, 26 Mar 2024 03:53:28 +0900 Subject: [PATCH 37/42] Fix config.rs --- packages/relayer/src/config.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/relayer/src/config.rs b/packages/relayer/src/config.rs index 5e2c7032..0f830456 100644 --- a/packages/relayer/src/config.rs +++ b/packages/relayer/src/config.rs @@ -27,52 +27,52 @@ use dotenv::dotenv; pub fn setup_configs() -> Result<()> { let relayer_rand = env::var("RELAYER_RAND").unwrap(); - RELAYER_RAND.set(relayer_rand); + RELAYER_RAND.set(relayer_rand).unwrap(); let web_server_address = env::var("WEB_SERVER_ADDRESS").unwrap(); - WEB_SERVER_ADDRESS.set(web_server_address); + WEB_SERVER_ADDRESS.set(web_server_address).unwrap(); let prover_address = env::var("PROVER_ADDRESS").unwrap(); - PROVER_ADDRESS.set(prover_address); + PROVER_ADDRESS.set(prover_address).unwrap(); let private_key = env::var("PRIVATE_KEY").unwrap(); - PRIVATE_KEY.set(private_key); + PRIVATE_KEY.set(private_key).unwrap(); let chain_id = env::var("CHAIN_ID").unwrap().parse().unwrap(); - CHAIN_ID.set(chain_id); + CHAIN_ID.set(chain_id).unwrap(); let chain_rpc_provider = env::var("CHAIN_RPC_PROVIDER").unwrap(); - CHAIN_RPC_PROVIDER.set(chain_rpc_provider); + CHAIN_RPC_PROVIDER.set(chain_rpc_provider).unwrap(); let chain_rpc_explorer = env::var("CHAIN_RPC_EXPLORER").unwrap(); - CHAIN_RPC_EXPLORER.set(chain_rpc_explorer); + CHAIN_RPC_EXPLORER.set(chain_rpc_explorer).unwrap(); let core_contract_address = env::var("CORE_CONTRACT_ADDRESS").unwrap(); - CORE_CONTRACT_ADDRESS.set(core_contract_address); + CORE_CONTRACT_ADDRESS.set(core_contract_address).unwrap(); let fee_per_gas = env::var("FEE_PER_GAS").unwrap(); let fee_per_gas = U256::from_dec_str(&fee_per_gas).unwrap(); - FEE_PER_GAS.set(fee_per_gas); + FEE_PER_GAS.set(fee_per_gas).unwrap(); let input_files_dir = env::var("INPUT_FILES_DIR").unwrap(); - INPUT_FILES_DIR.set(input_files_dir); + INPUT_FILES_DIR.set(input_files_dir).unwrap(); let received_emails_dir = env::var("RECEIVED_EMAILS_DIR").unwrap(); - RECEIVED_EMAILS_DIR.set(received_emails_dir); + RECEIVED_EMAILS_DIR.set(received_emails_dir).unwrap(); let email_templates = env::var("EMAIL_TEMPLATES").unwrap(); - EMAIL_TEMPLATES.set(email_templates); + EMAIL_TEMPLATES.set(email_templates).unwrap(); let relayer_email_address = env::var("RELAYER_EMAIL_ADDRESS").unwrap(); - RELAYER_EMAIL_ADDRESS.set(relayer_email_address); + RELAYER_EMAIL_ADDRESS.set(relayer_email_address).unwrap(); let canister_id = env::var("CANISTER_ID").unwrap(); - CANISTER_ID.set(canister_id); + CANISTER_ID.set(canister_id).unwrap(); let ic_pem_path = env::var("IC_PEM_PATH").unwrap(); - IC_PEM_PATH.set(ic_pem_path); + IC_PEM_PATH.set(ic_pem_path).unwrap(); let ic_replica_url = env::var("IC_REPLICA_URL").unwrap(); - IC_REPLICA_URL.set(ic_replica_url); + IC_REPLICA_URL.set(ic_replica_url).unwrap(); Ok(()) } From 87c5467b9b37b7f96e337e4ce14ca7fb0a2e71ae Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Mon, 1 Apr 2024 09:20:46 +0900 Subject: [PATCH 38/42] Fix modal server name. --- packages/prover/modal_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/prover/modal_server.py b/packages/prover/modal_server.py index 8ff4bfd7..440850e1 100644 --- a/packages/prover/modal_server.py +++ b/packages/prover/modal_server.py @@ -5,7 +5,7 @@ ) -stub = modal.Stub("email-wallet-relayer-v1.1") +stub = modal.Stub("email-auth-prover-v1") image = modal.Image.from_dockerfile("Dockerfile") From b079343eae171c8880534559865798cf5054c917 Mon Sep 17 00:00:00 2001 From: wshino Date: Mon, 1 Apr 2024 15:40:57 +0900 Subject: [PATCH 39/42] Fix typo of EmailAccountRecoery.t.sol. --- .../{EmailAccountRecoery.t.sol => EmailAccountRecovery.t.sol} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/contracts/test/{EmailAccountRecoery.t.sol => EmailAccountRecovery.t.sol} (100%) diff --git a/packages/contracts/test/EmailAccountRecoery.t.sol b/packages/contracts/test/EmailAccountRecovery.t.sol similarity index 100% rename from packages/contracts/test/EmailAccountRecoery.t.sol rename to packages/contracts/test/EmailAccountRecovery.t.sol From a643650187140d3a8c6dd82b5d0c58deb5c7a17a Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Wed, 3 Apr 2024 02:08:39 +0900 Subject: [PATCH 40/42] Fix Dockerfile in prover. --- packages/prover/Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/prover/Dockerfile b/packages/prover/Dockerfile index 97de9e02..6a5b5a3a 100644 --- a/packages/prover/Dockerfile +++ b/packages/prover/Dockerfile @@ -14,11 +14,12 @@ RUN npm install -g n RUN n 18 RUN npm install -g yarn snarkjs -RUN git clone https://github.com/zkemail/email-wallet.git -WORKDIR /email-wallet/packages/prover +RUN git clone 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 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 @@ -29,6 +30,7 @@ RUN mkdir params WORKDIR /root/params RUN gdown "https://drive.google.com/uc?id=1ky3XyabnBFwcyBoWBimhoePT9kbFyEBR" RUN unzip params.zip +RUN mv params/* /root/params WORKDIR /root RUN ls params # RUN mv build params From 94e6a67e43bbfc2417139eb2da42aa4ec6952540 Mon Sep 17 00:00:00 2001 From: SoraSuegami Date: Thu, 4 Apr 2024 03:18:17 +0900 Subject: [PATCH 41/42] Update utils package. --- Cargo.lock | 210 +++++++------- packages/circuits/helpers/email_auth.ts | 40 +-- packages/circuits/helpers/recipient.ts | 10 +- packages/circuits/tests/email_auth.test.ts | 107 ++++---- .../tests/invitation_code_regex.test.ts | 26 +- .../circuits/tests/recipient_enabled.test.ts | 80 +++--- packages/relayer/Cargo.toml | 2 +- packages/relayer/src/core.rs | 28 +- packages/relayer/src/dkim_oracle.rs | 62 ----- packages/relayer/src/emails_pool.rs | 75 ----- packages/relayer/src/imap_client.rs | 223 --------------- packages/relayer/src/logger.rs | 54 ---- packages/relayer/src/selector_def.json | 20 -- packages/relayer/src/smtp_client.rs | 148 ---------- packages/relayer/src/subject_templates.rs | 227 --------------- packages/relayer/src/utils.rs | 193 ------------- packages/relayer/src/utils/utils.rs | 104 +++---- packages/relayer/src/web_server.rs | 258 ------------------ packages/utils/Cargo.toml | 7 +- packages/utils/src/circuit.rs | 5 +- packages/utils/src/converters.rs | 28 ++ packages/utils/src/cryptos.rs | 210 +++++++------- packages/utils/src/email_auth.rs | 85 ++++++ packages/utils/src/lib.rs | 14 +- packages/utils/src/parse_email.rs | 4 +- packages/utils/src/regex.rs | 1 + packages/utils/src/statics.rs | 9 + 27 files changed, 563 insertions(+), 1667 deletions(-) delete mode 100644 packages/relayer/src/dkim_oracle.rs delete mode 100644 packages/relayer/src/emails_pool.rs delete mode 100644 packages/relayer/src/imap_client.rs delete mode 100644 packages/relayer/src/logger.rs delete mode 100644 packages/relayer/src/selector_def.json delete mode 100644 packages/relayer/src/smtp_client.rs delete mode 100644 packages/relayer/src/subject_templates.rs delete mode 100644 packages/relayer/src/utils.rs delete mode 100644 packages/relayer/src/web_server.rs create mode 100644 packages/utils/src/email_auth.rs create mode 100644 packages/utils/src/statics.rs diff --git a/Cargo.lock b/Cargo.lock index 187d7099..c019e904 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -192,7 +192,7 @@ checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -233,7 +233,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -577,7 +577,7 @@ dependencies = [ "lazy_static", "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -597,7 +597,7 @@ checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", - "semver", + "semver 1.0.22", "serde", "serde_json", "thiserror", @@ -987,7 +987,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -1430,7 +1430,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "syn 2.0.57", + "syn 2.0.58", "toml", "walkdir", ] @@ -1448,7 +1448,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -1474,7 +1474,7 @@ dependencies = [ "serde", "serde_json", "strum 0.26.2", - "syn 2.0.57", + "syn 2.0.58", "tempfile", "thiserror", "tiny-keccak", @@ -1490,7 +1490,7 @@ dependencies = [ "chrono", "ethers-core", "reqwest", - "semver", + "semver 1.0.22", "serde", "serde_json", "thiserror", @@ -1599,7 +1599,7 @@ dependencies = [ "path-slash", "rayon", "regex", - "semver", + "semver 1.0.22", "serde", "serde_json", "solang-parser", @@ -1894,7 +1894,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -2447,7 +2447,7 @@ dependencies = [ "candid", "ic-agent", "once_cell", - "semver", + "semver 1.0.22", "serde", "serde_bytes", "strum 0.24.1", @@ -2806,6 +2806,16 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libloading" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883" +dependencies = [ + "cfg-if", + "winapi", +] + [[package]] name = "libm" version = "0.2.8" @@ -2990,6 +3000,47 @@ 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" @@ -3122,7 +3173,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -3134,7 +3185,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -3235,7 +3286,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -3485,7 +3536,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -3549,7 +3600,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -3587,7 +3638,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -3683,7 +3734,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7" dependencies = [ "proc-macro2", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -3990,6 +4041,7 @@ dependencies = [ "halo2curves 0.4.0", "hex", "itertools 0.10.5", + "neon", "num-bigint", "num-traits", "once_cell", @@ -4172,7 +4224,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver", + "semver 1.0.22", ] [[package]] @@ -4359,6 +4411,15 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba" +[[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.22" @@ -4368,6 +4429,12 @@ 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" @@ -4427,7 +4494,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -4469,7 +4536,7 @@ checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -5020,7 +5087,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -5046,7 +5113,7 @@ dependencies = [ "hex", "once_cell", "reqwest", - "semver", + "semver 1.0.22", "serde", "serde_json", "sha2 0.10.8", @@ -5068,15 +5135,26 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.57" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a6ae1e52eb25aab8f3fb9fca13be982a373b8f1157ca14b897a825ba4a2d35" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "syn-mid" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea305d57546cc8cd04feb14b62ec84bf17f50e3f7b12560d7bfa9265f39d9ed" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "sync_wrapper" version = "0.1.2" @@ -5165,7 +5243,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -5272,7 +5350,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -5466,7 +5544,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -5539,70 +5617,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "tungstenite" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http", - "httparse", - "log", - "rand", - "rustls", - "sha1", - "thiserror", - "url", - "utf-8", -] - -[[package]] -name = "typed-arena" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "cfg-if", - "futures-util", - "ipconfig", - "lazy_static", - "lru-cache", - "parking_lot 0.12.1", - "resolv-conf", - "smallvec", - "thiserror", - "tokio", - "tracing", - "trust-dns-proto", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - [[package]] name = "tungstenite" version = "0.20.1" @@ -5633,7 +5647,7 @@ checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" @@ -5847,7 +5861,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", "wasm-bindgen-shared", ] @@ -5881,7 +5895,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5914,7 +5928,7 @@ checksum = "b7f89739351a2e03cb94beb799d47fb2cac01759b40ec441f7de39b00cbf7ef0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -6296,7 +6310,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] diff --git a/packages/circuits/helpers/email_auth.ts b/packages/circuits/helpers/email_auth.ts index 136ac94c..aeeed0ae 100644 --- a/packages/circuits/helpers/email_auth.ts +++ b/packages/circuits/helpers/email_auth.ts @@ -1,7 +1,7 @@ import fs from "fs"; import { promisify } from "util"; -import { generateCircuitInputs } from "@zk-email/helpers/dist/input-helpers"; -const emailWalletUtils = require("../../utils"); +// import { generateCircuitInputs } from "@zk-email/helpers/dist/input-helpers"; +const relayerUtils = require("../../utils"); export async function genEmailAuthInput(emailFilePath: string, accountCode: string): @@ -18,38 +18,6 @@ export async function genEmailAuthInput(emailFilePath: string, accountCode: stri code_idx: number }> { const emailRaw = await promisify(fs.readFile)(emailFilePath, "utf8"); - const parsedEmail = await emailWalletUtils.parseEmail(emailRaw); - const emailCircuitInputs = generateCircuitInputs({ - body: Buffer.from(""), - message: Buffer.from(parsedEmail.canonicalizedHeader), - bodyHash: "", - rsaSignature: BigInt(parsedEmail.signature), - rsaPublicKey: BigInt(parsedEmail.publicKey), - maxMessageLength: 1024, - maxBodyLength: 64, - ignoreBodyHashCheck: true - }); - const from_addr_idxes = emailWalletUtils.extractFromAddrIdxes(parsedEmail.canonicalizedHeader)[0]; - const fromEmailAddrPart = parsedEmail.canonicalizedHeader.slice(from_addr_idxes[0], from_addr_idxes[1]); - const subject_idx = emailWalletUtils.extractSubjectAllIdxes(parsedEmail.canonicalizedHeader)[0][0]; - const domainIdx = emailWalletUtils.extractEmailDomainIdxes(fromEmailAddrPart)[0][0]; - const timestampIdx = emailWalletUtils.extractTimestampIdxes(parsedEmail.canonicalizedHeader)[0][0]; - let codeIdx = 0; - try { - codeIdx = emailWalletUtils.extractInvitationCodeIdxes(parsedEmail.canonicalizedHeader)[0][0]; - } catch (e) { - console.log("No invitation code in header"); - } - return { - padded_header: emailCircuitInputs.in_padded, - public_key: emailCircuitInputs.pubkey, - signature: emailCircuitInputs.signature, - padded_header_len: emailCircuitInputs.in_len_padded_bytes, - account_code: accountCode, - from_addr_idx: from_addr_idxes[0], - subject_idx: subject_idx, - domain_idx: domainIdx, - timestamp_idx: timestampIdx, - code_idx: codeIdx, - }; + const jsonStr = await relayerUtils.genEmailAuthInput(emailRaw, accountCode); + return JSON.parse(jsonStr); } diff --git a/packages/circuits/helpers/recipient.ts b/packages/circuits/helpers/recipient.ts index b727ab0f..5604e55d 100644 --- a/packages/circuits/helpers/recipient.ts +++ b/packages/circuits/helpers/recipient.ts @@ -1,7 +1,7 @@ import fs from "fs"; import { promisify } from "util"; import { generateCircuitInputs } from "@zk-email/helpers/dist/input-helpers"; -const emailWalletUtils = require("../../utils"); +const relayerUtils = require("../../utils"); export async function genRecipientInput(emailFilePath: string): @@ -10,17 +10,17 @@ export async function genRecipientInput(emailFilePath: string): rand: string }> { const emailRaw = await promisify(fs.readFile)(emailFilePath, "utf8"); - const parsedEmail = await emailWalletUtils.parseEmail(emailRaw); - const subjectEmailIdxes = emailWalletUtils.extractSubjectAllIdxes(parsedEmail.canonicalizedHeader)[0]; + const parsedEmail = await relayerUtils.parseEmail(emailRaw); + const subjectEmailIdxes = relayerUtils.extractSubjectAllIdxes(parsedEmail.canonicalizedHeader)[0]; const subject = parsedEmail.canonicalizedHeader.slice(subjectEmailIdxes[0], subjectEmailIdxes[1]); let subjectEmailAddrIdx = 0; try { - subjectEmailAddrIdx = emailWalletUtils.extractEmailAddrIdxes(subject)[0][0]; + subjectEmailAddrIdx = relayerUtils.extractEmailAddrIdxes(subject)[0][0]; } catch (e) { console.log("No email address in subject"); subjectEmailAddrIdx = 0; } - const rand = emailWalletUtils.extractRandFromSignature(parsedEmail.signature); + const rand = relayerUtils.extractRandFromSignature(parsedEmail.signature); return { subject_email_addr_idx: subjectEmailAddrIdx, rand: rand diff --git a/packages/circuits/tests/email_auth.test.ts b/packages/circuits/tests/email_auth.test.ts index ff9850b7..cea7d8fe 100644 --- a/packages/circuits/tests/email_auth.test.ts +++ b/packages/circuits/tests/email_auth.test.ts @@ -6,7 +6,7 @@ const wasm_tester = circom_tester.wasm; import * as path from "path"; const p = "21888242871839275222246405745257275088548364400416034343698204186575808495617"; const field = new ff.F1Field(p); -const emailWalletUtils = require("../../utils"); +const relayerUtils = require("../../utils"); const option = { include: path.join(__dirname, "../../../node_modules") }; @@ -18,33 +18,34 @@ describe("Email Auth", () => { 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 emailWalletUtils.parseEmail(emailRaw); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); console.log(parsedEmail.canonicalizedHeader); - const accountCode = await emailWalletUtils.genAccountCode(); + const accountCode = await relayerUtils.genAccountCode(); const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); + console.log(circuitInputs); const circuit = await wasm_tester(path.join(__dirname, "../src/email_auth.circom"), option); const witness = await circuit.calculateWitness(circuitInputs); await circuit.checkConstraints(witness); const domainName = "gmail.com"; - const paddedDomain = emailWalletUtils.padString(domainName, 255); - const domainFields = emailWalletUtils.bytes2Fields(paddedDomain); + 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 = emailWalletUtils.publicKeyHash(parsedEmail.publicKey); + const expectedPubKeyHash = relayerUtils.publicKeyHash(parsedEmail.publicKey); expect(BigInt(expectedPubKeyHash)).toEqual(witness[1 + domainFields.length]); - const expectedEmailNullifier = emailWalletUtils.emailNullifier(parsedEmail.signature); + 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 = emailWalletUtils.padString(maskedSubject, 605); - const maskedSubjectFields = emailWalletUtils.bytes2Fields(paddedMaskedSubject); + 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 = emailWalletUtils.accountSalt(fromAddr, accountCode); + 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]); }); @@ -52,33 +53,33 @@ describe("Email Auth", () => { 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 emailWalletUtils.parseEmail(emailRaw); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); console.log(parsedEmail.canonicalizedHeader); - const accountCode = await emailWalletUtils.genAccountCode(); + const accountCode = await relayerUtils.genAccountCode(); const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); const circuit = await wasm_tester(path.join(__dirname, "../src/email_auth.circom"), option); const witness = await circuit.calculateWitness(circuitInputs); await circuit.checkConstraints(witness); const domainName = "gmail.com"; - const paddedDomain = emailWalletUtils.padString(domainName, 255); - const domainFields = emailWalletUtils.bytes2Fields(paddedDomain); + 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 = emailWalletUtils.publicKeyHash(parsedEmail.publicKey); + const expectedPubKeyHash = relayerUtils.publicKeyHash(parsedEmail.publicKey); expect(BigInt(expectedPubKeyHash)).toEqual(witness[1 + domainFields.length]); - const expectedEmailNullifier = emailWalletUtils.emailNullifier(parsedEmail.signature); + 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 = emailWalletUtils.padString(maskedSubject, 605); - const maskedSubjectFields = emailWalletUtils.bytes2Fields(paddedMaskedSubject); + 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 = emailWalletUtils.accountSalt(fromAddr, accountCode); + 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]); }); @@ -86,33 +87,33 @@ describe("Email Auth", () => { 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 emailWalletUtils.parseEmail(emailRaw); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); console.log(parsedEmail.canonicalizedHeader); - const accountCode = await emailWalletUtils.genAccountCode(); + const accountCode = await relayerUtils.genAccountCode(); const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); const circuit = await wasm_tester(path.join(__dirname, "../src/email_auth.circom"), option); const witness = await circuit.calculateWitness(circuitInputs); await circuit.checkConstraints(witness); const domainName = "gmail.com"; - const paddedDomain = emailWalletUtils.padString(domainName, 255); - const domainFields = emailWalletUtils.bytes2Fields(paddedDomain); + 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 = emailWalletUtils.publicKeyHash(parsedEmail.publicKey); + const expectedPubKeyHash = relayerUtils.publicKeyHash(parsedEmail.publicKey); expect(BigInt(expectedPubKeyHash)).toEqual(witness[1 + domainFields.length]); - const expectedEmailNullifier = emailWalletUtils.emailNullifier(parsedEmail.signature); + 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 = emailWalletUtils.padString(maskedSubject, 605); - const maskedSubjectFields = emailWalletUtils.bytes2Fields(paddedMaskedSubject); + 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 = emailWalletUtils.accountSalt(fromAddr, accountCode); + 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]); }); @@ -120,33 +121,33 @@ describe("Email Auth", () => { 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 emailWalletUtils.parseEmail(emailRaw); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); console.log(parsedEmail.canonicalizedHeader); - const accountCode = await emailWalletUtils.genAccountCode(); + const accountCode = await relayerUtils.genAccountCode(); const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); const circuit = await wasm_tester(path.join(__dirname, "../src/email_auth.circom"), option); const witness = await circuit.calculateWitness(circuitInputs); await circuit.checkConstraints(witness); const domainName = "gmail.com"; - const paddedDomain = emailWalletUtils.padString(domainName, 255); - const domainFields = emailWalletUtils.bytes2Fields(paddedDomain); + 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 = emailWalletUtils.publicKeyHash(parsedEmail.publicKey); + const expectedPubKeyHash = relayerUtils.publicKeyHash(parsedEmail.publicKey); expect(BigInt(expectedPubKeyHash)).toEqual(witness[1 + domainFields.length]); - const expectedEmailNullifier = emailWalletUtils.emailNullifier(parsedEmail.signature); + 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 = emailWalletUtils.padString(maskedSubject, 605); - const maskedSubjectFields = emailWalletUtils.bytes2Fields(paddedMaskedSubject); + 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 = emailWalletUtils.accountSalt(fromAddr, accountCode); + 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]); }); @@ -154,7 +155,7 @@ describe("Email Auth", () => { 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 emailWalletUtils.parseEmail(emailRaw); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); console.log(parsedEmail.canonicalizedHeader); const accountCode = "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); @@ -162,25 +163,25 @@ describe("Email Auth", () => { const witness = await circuit.calculateWitness(circuitInputs); await circuit.checkConstraints(witness); const domainName = "gmail.com"; - const paddedDomain = emailWalletUtils.padString(domainName, 255); - const domainFields = emailWalletUtils.bytes2Fields(paddedDomain); + 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 = emailWalletUtils.publicKeyHash(parsedEmail.publicKey); + const expectedPubKeyHash = relayerUtils.publicKeyHash(parsedEmail.publicKey); expect(BigInt(expectedPubKeyHash)).toEqual(witness[1 + domainFields.length]); - const expectedEmailNullifier = emailWalletUtils.emailNullifier(parsedEmail.signature); + 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 = emailWalletUtils.padString(maskedSubject, 605); - const maskedSubjectFields = emailWalletUtils.bytes2Fields(paddedMaskedSubject); + 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 = emailWalletUtils.accountSalt(fromAddr, accountCode); + 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]); }); @@ -188,32 +189,32 @@ describe("Email Auth", () => { 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 emailWalletUtils.parseEmail(emailRaw); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); const accountCode = "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; const circuitInputs = await genEmailAuthInput(emailFilePath, accountCode); const circuit = await wasm_tester(path.join(__dirname, "../src/email_auth.circom"), option); const witness = await circuit.calculateWitness(circuitInputs); await circuit.checkConstraints(witness); const domainName = "gmail.com"; - const paddedDomain = emailWalletUtils.padString(domainName, 255); - const domainFields = emailWalletUtils.bytes2Fields(paddedDomain); + 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 = emailWalletUtils.publicKeyHash(parsedEmail.publicKey); + const expectedPubKeyHash = relayerUtils.publicKeyHash(parsedEmail.publicKey); expect(BigInt(expectedPubKeyHash)).toEqual(witness[1 + domainFields.length]); - const expectedEmailNullifier = emailWalletUtils.emailNullifier(parsedEmail.signature); + 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 = emailWalletUtils.padString(maskedSubject, 605); - const maskedSubjectFields = emailWalletUtils.bytes2Fields(paddedMaskedSubject); + 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 = emailWalletUtils.accountSalt(fromAddr, accountCode); + 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]); }); diff --git a/packages/circuits/tests/invitation_code_regex.test.ts b/packages/circuits/tests/invitation_code_regex.test.ts index de0f6673..69d0387b 100644 --- a/packages/circuits/tests/invitation_code_regex.test.ts +++ b/packages/circuits/tests/invitation_code_regex.test.ts @@ -1,7 +1,7 @@ const circom_tester = require("circom_tester"); const wasm_tester = circom_tester.wasm; import * as path from "path"; -const emailWalletUtils = require("../../utils"); +const relayerUtils = require("../../utils"); const option = { include: path.join(__dirname, "../../../node_modules") }; @@ -14,7 +14,7 @@ describe("Invitation Code Regex", () => { const codeStr = "Code 123abc"; // const prefixLen = "ACCOUNTKEY.0x".length; // const revealed = "123abc"; - const paddedStr = emailWalletUtils.padString(codeStr, 256); + const paddedStr = relayerUtils.padString(codeStr, 256); const circuitInputs = { msg: paddedStr, }; @@ -23,7 +23,7 @@ describe("Invitation Code Regex", () => { await circuit.checkConstraints(witness); // console.log(witness); expect(1n).toEqual(witness[1]); - const prefixIdxes = emailWalletUtils.extractInvitationCodeIdxes(codeStr)[0]; + 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]); @@ -37,7 +37,7 @@ describe("Invitation Code Regex", () => { const codeStr = "Swap 0.1 ETH to DAI code 123abc"; // const prefixLen = "sepolia+ACCOUNTKEY.0x".length; // const revealed = "123abc"; - const paddedStr = emailWalletUtils.padString(codeStr, 256); + const paddedStr = relayerUtils.padString(codeStr, 256); const circuitInputs = { msg: paddedStr, }; @@ -46,7 +46,7 @@ describe("Invitation Code Regex", () => { await circuit.checkConstraints(witness); // console.log(witness); expect(1n).toEqual(witness[1]); - const prefixIdxes = emailWalletUtils.extractInvitationCodeIdxes(codeStr)[0]; + 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) { @@ -62,7 +62,7 @@ describe("Invitation Code Regex", () => { const codeStr = "Send 0.1 ETH to alice@gmail.com code 123abc"; // const prefixLen = "sepolia+ACCOUNTKEY.0x".length; // const revealed = "123abc"; - const paddedStr = emailWalletUtils.padString(codeStr, 256); + const paddedStr = relayerUtils.padString(codeStr, 256); const circuitInputs = { msg: paddedStr, }; @@ -71,7 +71,7 @@ describe("Invitation Code Regex", () => { await circuit.checkConstraints(witness); // console.log(witness); expect(1n).toEqual(witness[1]); - const prefixIdxes = emailWalletUtils.extractInvitationCodeIdxes(codeStr)[0]; + 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) { @@ -87,7 +87,7 @@ describe("Invitation Code Regex", () => { const codeStr = "sepolia+code123456@sendeth.org"; // const prefixLen = "sepolia+ACCOUNTKEY.0x".length; // const revealed = "123abc"; - const paddedStr = emailWalletUtils.padString(codeStr, 256); + const paddedStr = relayerUtils.padString(codeStr, 256); const circuitInputs = { msg: paddedStr, }; @@ -96,7 +96,7 @@ describe("Invitation Code Regex", () => { await circuit.checkConstraints(witness); // console.log(witness); expect(1n).toEqual(witness[1]); - const prefixIdxes = emailWalletUtils.extractInvitationCodeIdxes(codeStr)[0]; + 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) { @@ -112,7 +112,7 @@ describe("Invitation Code Regex", () => { const codeStr = "Swap 0.1 ETH to DAI code 123abc"; // const prefixLen = "sepolia+ACCOUNTKEY.0x".length; // const revealed = "123abc"; - const paddedStr = emailWalletUtils.padString(codeStr, 256); + const paddedStr = relayerUtils.padString(codeStr, 256); const circuitInputs = { msg: paddedStr, }; @@ -121,7 +121,7 @@ describe("Invitation Code Regex", () => { await circuit.checkConstraints(witness); // console.log(witness); expect(1n).toEqual(witness[1]); - const prefixIdxes = emailWalletUtils.extractInvitationCodeWithPrefixIdxes(codeStr)[0]; + 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) { @@ -137,7 +137,7 @@ describe("Invitation Code Regex", () => { const codeStr = "Re: Accept guardian request for 0x04884491560f38342C56E26BDD0fEAbb68E2d2FC Code 01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; // const prefixLen = "sepolia+ACCOUNTKEY.0x".length; // const revealed = "123abc"; - const paddedStr = emailWalletUtils.padString(codeStr, 256); + const paddedStr = relayerUtils.padString(codeStr, 256); const circuitInputs = { msg: paddedStr, }; @@ -146,7 +146,7 @@ describe("Invitation Code Regex", () => { await circuit.checkConstraints(witness); // console.log(witness); expect(1n).toEqual(witness[1]); - const prefixIdxes = emailWalletUtils.extractInvitationCodeWithPrefixIdxes(codeStr)[0]; + 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) { diff --git a/packages/circuits/tests/recipient_enabled.test.ts b/packages/circuits/tests/recipient_enabled.test.ts index 70c3a7a3..8329f07c 100644 --- a/packages/circuits/tests/recipient_enabled.test.ts +++ b/packages/circuits/tests/recipient_enabled.test.ts @@ -6,7 +6,7 @@ const wasm_tester = circom_tester.wasm; import * as path from "path"; const p = "21888242871839275222246405745257275088548364400416034343698204186575808495617"; const field = new ff.F1Field(p); -const emailWalletUtils = require("../../utils"); +const relayerUtils = require("../../utils"); const option = { include: path.join(__dirname, "../../../node_modules") }; @@ -19,9 +19,9 @@ describe("Email Auth", () => { 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 emailWalletUtils.parseEmail(emailRaw); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); console.log(parsedEmail.canonicalizedHeader); - const accountCode = await emailWalletUtils.genAccountCode(); + const accountCode = await relayerUtils.genAccountCode(); const emailAuthInput = await genEmailAuthInput(emailFilePath, accountCode); const recipientInput = await genRecipientInput(emailFilePath); const circuitInputs = { @@ -32,30 +32,30 @@ describe("Email Auth", () => { const witness = await circuit.calculateWitness(circuitInputs); await circuit.checkConstraints(witness); const domainName = "gmail.com"; - const paddedDomain = emailWalletUtils.padString(domainName, 255); - const domainFields = emailWalletUtils.bytes2Fields(paddedDomain); + 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 = emailWalletUtils.publicKeyHash(parsedEmail.publicKey); + const expectedPubKeyHash = relayerUtils.publicKeyHash(parsedEmail.publicKey); expect(BigInt(expectedPubKeyHash)).toEqual(witness[1 + domainFields.length]); - const expectedEmailNullifier = emailWalletUtils.emailNullifier(parsedEmail.signature); + 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 = emailWalletUtils.padString(maskedSubject, 605); - const maskedSubjectFields = emailWalletUtils.bytes2Fields(paddedMaskedSubject); + 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 = emailWalletUtils.accountSalt(fromAddr, accountCode); + 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 = emailWalletUtils.emailAddrCommitWithSignature(recipientEmailAddr, parsedEmail.signature); + const emailAddrCommit = relayerUtils.emailAddrCommitWithSignature(recipientEmailAddr, parsedEmail.signature); expect(BigInt(emailAddrCommit)).toEqual(witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 3]); }); @@ -63,9 +63,9 @@ describe("Email Auth", () => { 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 emailWalletUtils.parseEmail(emailRaw); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); console.log(parsedEmail.canonicalizedHeader); - const accountCode = await emailWalletUtils.genAccountCode(); + const accountCode = await relayerUtils.genAccountCode(); const emailAuthInput = await genEmailAuthInput(emailFilePath, accountCode); const recipientInput = await genRecipientInput(emailFilePath); const circuitInputs = { @@ -76,39 +76,39 @@ describe("Email Auth", () => { const witness = await circuit.calculateWitness(circuitInputs); await circuit.checkConstraints(witness); const domainName = "gmail.com"; - const paddedDomain = emailWalletUtils.padString(domainName, 255); - const domainFields = emailWalletUtils.bytes2Fields(paddedDomain); + 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 = emailWalletUtils.publicKeyHash(parsedEmail.publicKey); + const expectedPubKeyHash = relayerUtils.publicKeyHash(parsedEmail.publicKey); expect(BigInt(expectedPubKeyHash)).toEqual(witness[1 + domainFields.length]); - const expectedEmailNullifier = emailWalletUtils.emailNullifier(parsedEmail.signature); + 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 = emailWalletUtils.padString(maskedSubject, 605); - const maskedSubjectFields = emailWalletUtils.bytes2Fields(paddedMaskedSubject); + 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 = emailWalletUtils.accountSalt(fromAddr, accountCode); + 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 = emailWalletUtils.emailAddrCommitWithSignature(recipientEmailAddr, parsedEmail.signature); + 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 emailWalletUtils.parseEmail(emailRaw); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); console.log(parsedEmail.canonicalizedHeader); - const accountCode = await emailWalletUtils.genAccountCode(); + const accountCode = await relayerUtils.genAccountCode(); const emailAuthInput = await genEmailAuthInput(emailFilePath, accountCode); const recipientInput = await genRecipientInput(emailFilePath); const circuitInputs = { @@ -119,37 +119,37 @@ describe("Email Auth", () => { const witness = await circuit.calculateWitness(circuitInputs); await circuit.checkConstraints(witness); const domainName = "gmail.com"; - const paddedDomain = emailWalletUtils.padString(domainName, 255); - const domainFields = emailWalletUtils.bytes2Fields(paddedDomain); + 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 = emailWalletUtils.publicKeyHash(parsedEmail.publicKey); + const expectedPubKeyHash = relayerUtils.publicKeyHash(parsedEmail.publicKey); expect(BigInt(expectedPubKeyHash)).toEqual(witness[1 + domainFields.length]); - const expectedEmailNullifier = emailWalletUtils.emailNullifier(parsedEmail.signature); + 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 = emailWalletUtils.padString(maskedSubject, 605); - const maskedSubjectFields = emailWalletUtils.bytes2Fields(paddedMaskedSubject); + 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 = emailWalletUtils.accountSalt(fromAddr, accountCode); + 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 = emailWalletUtils.emailAddrCommitWithSignature(recipientEmailAddr, parsedEmail.signature); + 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 emailWalletUtils.parseEmail(emailRaw); + const parsedEmail = await relayerUtils.parseEmail(emailRaw); console.log(parsedEmail.canonicalizedHeader); const accountCode = "0x01eb9b204cc24c3baee11accc37d253a9c53e92b1a2cc07763475c135d575b76"; const emailAuthInput = await genEmailAuthInput(emailFilePath, accountCode); @@ -162,30 +162,30 @@ describe("Email Auth", () => { const witness = await circuit.calculateWitness(circuitInputs); await circuit.checkConstraints(witness); const domainName = "gmail.com"; - const paddedDomain = emailWalletUtils.padString(domainName, 255); - const domainFields = emailWalletUtils.bytes2Fields(paddedDomain); + 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 = emailWalletUtils.publicKeyHash(parsedEmail.publicKey); + const expectedPubKeyHash = relayerUtils.publicKeyHash(parsedEmail.publicKey); expect(BigInt(expectedPubKeyHash)).toEqual(witness[1 + domainFields.length]); - const expectedEmailNullifier = emailWalletUtils.emailNullifier(parsedEmail.signature); + 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 = emailWalletUtils.padString(maskedSubject, 605); - const maskedSubjectFields = emailWalletUtils.bytes2Fields(paddedMaskedSubject); + 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 = emailWalletUtils.accountSalt(fromAddr, accountCode); + 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 = emailWalletUtils.emailAddrCommitWithSignature(recipientEmailAddr, parsedEmail.signature); + const emailAddrCommit = relayerUtils.emailAddrCommitWithSignature(recipientEmailAddr, parsedEmail.signature); expect(BigInt(emailAddrCommit)).toEqual(witness[1 + domainFields.length + 3 + maskedSubjectFields.length + 3]); }); }); \ No newline at end of file diff --git a/packages/relayer/Cargo.toml b/packages/relayer/Cargo.toml index 8a1322a8..b7f7935b 100644 --- a/packages/relayer/Cargo.toml +++ b/packages/relayer/Cargo.toml @@ -26,7 +26,7 @@ lettre = { version = "0.10.4", features = ["tokio1", "tokio1-native-tls"] } ethers = { version = "2.0.10", features = ["abigen"] } relayer-utils = { path = "../utils" } futures = "0.3.28" -sqlx = { version = "0.7", features = ["postgres", "runtime-tokio"] } +sqlx = { version = "=0.7.3", features = ["postgres", "runtime-tokio"] } regex = "1.10.2" axum = "0.6.20" rand = "0.8.5" diff --git a/packages/relayer/src/core.rs b/packages/relayer/src/core.rs index 5bbc0371..adeaab40 100644 --- a/packages/relayer/src/core.rs +++ b/packages/relayer/src/core.rs @@ -8,7 +8,7 @@ use ethers::{ abi::{encode, Token}, utils::keccak256, }; -use relayer_utils::extract_substr_idxes; +use relayer_utils::{extract_substr_idxes, generate_email_auth_input}; const DOMAIN_FIELDS: usize = 9; const SUBJECT_FIELDS: usize = 20; @@ -28,7 +28,7 @@ pub async fn handle_email( trace!(LOG, "From address: {}", guardian_email_addr; "func" => function_name!()); let subject = parsed_email.get_subject_all()?; - let account_key_str = db + let account_code_str = db .get_invitation_code_from_email_addr(&guardian_email_addr) .await? .ok_or(anyhow!( @@ -66,10 +66,10 @@ pub async fn handle_email( if let Ok(invitation_code) = parsed_email.get_invitation_code() { trace!(LOG, "Email with account code"; "func" => function_name!()); - if account_key_str != invitation_code { + if account_code_str != invitation_code { return Err(anyhow!( - "Stored account key is not equal to one in the email. Stored: {}, Email: {}", - account_key_str, + "Stored account code is not equal to one in the email. Stored: {}, Email: {}", + account_code_str, invitation_code )); } @@ -105,7 +105,11 @@ pub async fn handle_email( let template_id = keccak256(encode(&tokens)); - let circuit_input = generate_email_auth_input(&email, &invitation_code).await?; + let circuit_input = generate_email_auth_input( + &email, + &AccountCode::from(hex2field(&account_code_str)?), + ) + .await?; let (proof, public_signals) = generate_proof(&circuit_input, "email_auth", PROVER_ADDRESS.get().unwrap()).await?; @@ -230,7 +234,11 @@ pub async fn handle_email( let template_id = keccak256(encode(&tokens)); - let circuit_input = generate_email_auth_input(&email, &account_key_str).await?; + let circuit_input = generate_email_auth_input( + &email, + &AccountCode::from(hex2field(&account_code_str)?), + ) + .await?; let (proof, public_signals) = generate_proof(&circuit_input, "email_auth", PROVER_ADDRESS.get().unwrap()).await?; @@ -348,7 +356,11 @@ pub async fn handle_email( let template_id = keccak256(encode(&tokens)); - let circuit_input = generate_email_auth_input(&email, &account_key_str).await?; + let circuit_input = generate_email_auth_input( + &email, + &AccountCode::from(hex2field(&account_code_str)?), + ) + .await?; let (proof, public_signals) = generate_proof(&circuit_input, "email_auth", PROVER_ADDRESS.get().unwrap()).await?; diff --git a/packages/relayer/src/dkim_oracle.rs b/packages/relayer/src/dkim_oracle.rs deleted file mode 100644 index d5c25253..00000000 --- a/packages/relayer/src/dkim_oracle.rs +++ /dev/null @@ -1,62 +0,0 @@ -use anyhow::anyhow; - -use candid::CandidType; -use ic_agent::agent::http_transport::ReqwestTransport; -use ic_agent::agent::*; -use ic_agent::identity::*; -use ic_utils::canister::*; - -use serde::Deserialize; - -#[derive(Debug, Clone)] -pub struct DkimOracleClient<'a> { - pub(crate) canister: Canister<'a>, -} - -#[derive(Default, CandidType, Deserialize, Debug, Clone)] -pub struct SignedDkimPublicKey { - pub selector: String, - pub domain: String, - pub signature: String, - pub public_key: String, - pub public_key_hash: String, -} - -impl<'a> DkimOracleClient<'a> { - pub fn gen_agent(pem_path: &str, replica_url: &str) -> anyhow::Result { - let identity = Secp256k1Identity::from_pem_file(pem_path)?; - let transport = ReqwestTransport::create(replica_url)?; - let agent = AgentBuilder::default() - .with_identity(identity) - .with_transport(transport) - .build()?; - Ok(agent) - } - - pub fn new(canister_id: &str, agent: &'a Agent) -> anyhow::Result { - let canister = CanisterBuilder::new() - .with_canister_id(canister_id) - .with_agent(&agent) - .build()?; - Ok(Self { canister }) - } - - 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)))?; - - // let result = Decode!(&response, String)?; - Ok(response) - } -} diff --git a/packages/relayer/src/emails_pool.rs b/packages/relayer/src/emails_pool.rs deleted file mode 100644 index 174a03f5..00000000 --- a/packages/relayer/src/emails_pool.rs +++ /dev/null @@ -1,75 +0,0 @@ -use crate::*; -use anyhow::Result; -use async_trait::async_trait; -use std::fs; -use std::path::PathBuf; - -#[async_trait] -pub(crate) trait EmailsPool { - async fn get_unhandled_emails(&self) -> Result>; - - async fn get_email_by_hash(&self, email_hash: &str) -> Result; - - async fn insert_email(&self, email_hash: &str, email: &str) -> Result<()>; - - async fn delete_email(&self, email_hash: &str) -> Result<()>; - - // Result is bad - fix later (possible solution: to output Result - // where, ReturnStatus is some Enum ... - async fn contains_email(&self, email_hash: &str) -> Result; -} - -pub struct FileEmailsPool { - dir_path: String, -} - -#[async_trait] -impl EmailsPool for FileEmailsPool { - async fn get_unhandled_emails(&self) -> Result> { - let dir = fs::read_dir(&self.dir_path)?; - let mut emails = Vec::new(); - for path in dir.into_iter() { - let path = path?.path(); - let email = fs::read_to_string(path)?; - emails.push((calculate_email_hash(&email), email)); - } - Ok(emails) - } - - async fn get_email_by_hash(&self, email_hash: &str) -> Result { - let file_path = self.email_hash_to_path(email_hash); - let email = fs::read_to_string(file_path)?; - Ok(email) - } - - async fn insert_email(&self, email_hash: &str, email: &str) -> Result<()> { - let file_path = self.email_hash_to_path(email_hash); - fs::write(file_path, email)?; - Ok(()) - } - - async fn delete_email(&self, email_hash: &str) -> Result<()> { - let file_path = self.email_hash_to_path(email_hash); - fs::remove_file(file_path)?; - Ok(()) - } - - async fn contains_email(&self, email_hash: &str) -> Result { - let file_path = self.email_hash_to_path(email_hash); - Ok(file_path.exists()) - } -} - -impl FileEmailsPool { - #[named] - pub fn new() -> Self { - let dir_path = RECEIVED_EMAILS_DIR.get().unwrap().to_string(); - info!(LOG, "dir_path: {}", dir_path; "func" => function_name!()); - fs::create_dir_all(&dir_path).unwrap(); - Self { dir_path } - } - - fn email_hash_to_path(&self, email_hash: &str) -> PathBuf { - PathBuf::from(&self.dir_path).join(format!("{}.eml", email_hash)) - } -} diff --git a/packages/relayer/src/imap_client.rs b/packages/relayer/src/imap_client.rs deleted file mode 100644 index 6a595714..00000000 --- a/packages/relayer/src/imap_client.rs +++ /dev/null @@ -1,223 +0,0 @@ -use crate::*; - -use std::time::Duration; - -use anyhow::anyhow; -use async_imap::{types::Fetch, Session}; -use async_native_tls::TlsStream; -use futures::TryStreamExt; -use oauth2::reqwest::async_http_client; -use oauth2::{ - basic::BasicClient, AuthUrl, AuthorizationCode, ClientId, ClientSecret, CsrfToken, - PkceCodeChallenge, RedirectUrl, Scope, TokenResponse, TokenUrl, -}; -use tokio::net::TcpStream; - -#[derive(Clone)] -pub(crate) enum ImapAuth { - Password { - user_id: String, - password: String, - }, - Oauth { - user_id: String, - client_id: String, - client_secret: String, - auth_url: String, - token_url: String, - redirect_url: String, - }, -} - -#[derive(Clone)] -pub(crate) struct ImapConfig { - pub(crate) domain_name: String, - pub(crate) port: u16, - pub(crate) auth: ImapAuth, - pub(crate) initially_checked: bool, -} - -struct OAuth2 { - user_id: String, - access_token: String, -} - -impl async_imap::Authenticator for &OAuth2 { - type Response = String; - - fn process(&mut self, _: &[u8]) -> Self::Response { - format!( - "user={}\x01auth=Bearer {}\x01\x01", - self.user_id, self.access_token - ) - } -} - -pub(crate) struct ImapClient { - session: Session>, - config: ImapConfig, -} - -impl ImapClient { - #[named] - pub(crate) async fn new(config: ImapConfig) -> Result { - let tcp_stream = TcpStream::connect((&*config.domain_name, config.port)).await?; - let tls = async_native_tls::TlsConnector::new(); - let tls_stream = tls.connect(&*config.domain_name, tcp_stream).await?; - let client = async_imap::Client::new(tls_stream); - - let mut session = match config.auth.clone() { - ImapAuth::Password { user_id, password } => { - client.login(user_id, password).await.map_err(|e| e.0) - } - ImapAuth::Oauth { - user_id, - client_id, - client_secret, - auth_url, - token_url, - redirect_url, - } => { - let oauth_client = BasicClient::new( - ClientId::new(client_id), - Some(ClientSecret::new(client_secret)), - AuthUrl::new(auth_url)?, - Some(TokenUrl::new(token_url)?), - ) - .set_redirect_uri(RedirectUrl::new(redirect_url)?); - - let (pkce_challenge, pkce_verifier) = PkceCodeChallenge::new_random_sha256(); - let (auth_url, _) = oauth_client - .authorize_url(CsrfToken::new_random) - .add_scope(Scope::new("https://mail.google.com/".to_string())) - .set_pkce_challenge(pkce_challenge) - .url(); - - let server = tiny_http::Server::http("127.0.0.1:8000").unwrap(); - webbrowser::open(auth_url.as_ref())?; - let request = server.recv()?; - let url = request.url().to_string(); - let auth_code = url.split("code=").collect::>()[1] - .split('&') - .next() - .unwrap_or(""); - let response = - tiny_http::Response::from_string("You can close this window now.".to_string()); - request.respond(response).unwrap(); - - trace!(LOG, "Auth Code that I captured {}", auth_code; "func" => function_name!()); - - let token_result = oauth_client - .exchange_code(AuthorizationCode::new(auth_code.to_string())) - .set_pkce_verifier(pkce_verifier) - .request_async(async_http_client) - .await?; - - let access_token = serde_json::to_string(token_result.access_token())?; - let oauthed = OAuth2 { - user_id, - access_token, - }; - - client - .authenticate("XOAUTH2", &oauthed) - .await - .map_err(|e| e.0) - } - }?; - - session.select("INBOX").await?; - - trace!(LOG, "ImapClient connected succesfully!"; "func" => function_name!()); - - Ok(Self { session, config }) - } - - #[named] - pub(crate) async fn retrieve_new_emails(&mut self) -> Result>> { - if !self.config.initially_checked { - self.config.initially_checked = true; - let result = - tokio::time::timeout(Duration::from_secs(10), self.get_unseen_emails()).await; - if let Ok(Ok(result)) = result { - return Ok(result); - } - } - - // let mut new_client = self.wait_new_email().await?; - trace!(LOG, "Reconnecting..."; "func" => function_name!()); - self.reconnect().await?; - trace!(LOG, "Reconnected!"; "func" => function_name!()); - // Ok((new_client.get_unseen_emails().await?, new_client)) - Ok(self.get_unseen_emails().await?) - } - - #[named] - async fn get_unseen_emails(&mut self) -> Result>> { - trace!(LOG, "Getting unseen emails..."; "func" => function_name!()); - loop { - match self.session.uid_search("UNSEEN").await { - Ok(uids) => { - trace!(LOG, "Got unseen emails: {:?}!", uids; "func" => function_name!()); - let mut results = vec![]; - for uid in uids { - let res = self - .session - .uid_fetch(uid.to_string(), "(BODY[] ENVELOPE)") - .await?; - let res = res.try_collect::>().await?; - results.push(res); - } - trace!(LOG, "Got unseen emails: {:?}!", results; "func" => function_name!()); - return Ok(results); - } - Err(e) => { - error!(LOG, "Connection reset, reconnecting..."; "func" => function_name!()); - self.reconnect().await?; - } - } - } - } - - // async fn wait_new_email(mut self) -> Result { - // loop { - // let mut idle = self.session.idle(); - // idle.init().await?; - // let result = idle.wait_with_timeout(Duration::from_secs(29 * 60)).0.await; - // let is_new_data = matches!(result, Ok(NewData(_))); - - // let session_result = idle.done().await; - - // self = match session_result { - // Ok(session) => Self { session, ..self }, - // Err(_) => Self::new(self.config).await.unwrap(), - // }; - - // if is_new_data { - // return Ok(self); - // } else { - // self.reconnect().await?; - // } - // } - // } - - async fn reconnect(&mut self) -> Result<()> { - const MAX_RETRIES: u32 = 5; - let mut retry_count = 0; - - while retry_count < MAX_RETRIES { - match ImapClient::new(self.config.clone()).await { - Ok(new_client) => { - self.session = new_client.session; - return Ok(()); - } - Err(_) => { - retry_count += 1; - std::thread::sleep(std::time::Duration::from_millis(1000)); - } - } - } - - Err(anyhow!("{IMAP_RECONNECT_ERROR}")) - } -} diff --git a/packages/relayer/src/logger.rs b/packages/relayer/src/logger.rs deleted file mode 100644 index b13b4bed..00000000 --- a/packages/relayer/src/logger.rs +++ /dev/null @@ -1,54 +0,0 @@ -use file_rotate::{ - compression::Compression, - suffix::{AppendTimestamp, FileLimit}, - ContentLimit, FileRotate, -}; -use lazy_static::lazy_static; -use slog::{o, Drain}; -use slog_async; -use slog_json; -use slog_term; -use std::env; - -lazy_static! { - pub static ref LOG: slog::Logger = init_logger(); -} - -fn init_logger() -> slog::Logger { - let directory = std::path::Path::new("logs"); - let log_path = directory.join("relayer.log"); - let file_rotate = FileRotate::new( - log_path.clone(), - AppendTimestamp::default(FileLimit::MaxFiles(1_000_000)), - ContentLimit::Bytes(5_000_000), - Compression::OnRotate(5), - #[cfg(unix)] - None, - ); - let log_file_drain = slog_json::Json::default(file_rotate).fuse(); - - // Check if LOGGER env var is set and true or True or TRUE, if not, set false - let terminal_json_output = match env::var("JSON_LOGGER") { - Ok(val) => val.eq_ignore_ascii_case("true"), - Err(_) => false, - }; - - let log_terminal_decorator = slog_term::TermDecorator::new().build(); - let log_terminal_drain = slog_term::FullFormat::new(log_terminal_decorator) - .build() - .fuse(); - let log_terminal_json_drain = slog_json::Json::default(std::io::stdout()).fuse(); - - if terminal_json_output { - let log_drain = - slog_async::Async::new(slog::Duplicate(log_terminal_json_drain, log_file_drain).fuse()) - .build() - .fuse(); - return slog::Logger::root(log_drain, o!("version" => env!("CARGO_PKG_VERSION"))); - } - let log_drain = - slog_async::Async::new(slog::Duplicate(log_terminal_drain, log_file_drain).fuse()) - .build() - .fuse(); - slog::Logger::root(log_drain, o!("version" => env!("CARGO_PKG_VERSION"))) -} diff --git a/packages/relayer/src/selector_def.json b/packages/relayer/src/selector_def.json deleted file mode 100644 index 609b00e1..00000000 --- a/packages/relayer/src/selector_def.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "parts": [ - { - "is_public": false, - "regex_def": "((\r\n)|^)dkim-signature:" - }, - { - "is_public": false, - "regex_def": "((a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z)+=[^;]+; )+s=" - }, - { - "is_public": true, - "regex_def": "(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|-|_)+" - }, - { - "is_public": false, - "regex_def": ";" - } - ] -} \ No newline at end of file diff --git a/packages/relayer/src/smtp_client.rs b/packages/relayer/src/smtp_client.rs deleted file mode 100644 index 1412d9f2..00000000 --- a/packages/relayer/src/smtp_client.rs +++ /dev/null @@ -1,148 +0,0 @@ -#![allow(unused_imports)] - -use std::path::PathBuf; - -use crate::*; - -use anyhow::anyhow; -use handlebars::Handlebars; -use lettre::{ - message::{ - header::{Cc, From, Header, HeaderName, InReplyTo, ReplyTo, To}, - Attachment, Mailbox, Mailboxes, MessageBuilder, MultiPart, SinglePart, - }, - transport::smtp::{ - authentication::Credentials, client::SmtpConnection, commands::*, extension::ClientId, - SMTP_PORT, - }, - Address, AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor, -}; -use serde_json::Value; -use tokio::fs::read_to_string; - -#[derive(Debug, Clone)] -pub struct EmailMessage { - pub to: String, - pub subject: String, - pub reference: Option, - pub reply_to: Option, - pub body_plain: String, - pub body_html: String, - pub body_attachments: Option>, -} - -#[derive(Debug, Clone)] -pub struct EmailAttachment { - pub inline_id: String, - pub content_type: String, - pub contents: Vec, -} - -#[derive(Clone)] -pub(crate) struct SmtpConfig { - pub(crate) domain_name: String, - pub(crate) id: String, - pub(crate) password: String, -} - -pub(crate) struct SmtpClient { - config: SmtpConfig, - transport: AsyncSmtpTransport, -} - -impl SmtpClient { - pub(crate) fn new(config: SmtpConfig) -> Result { - let creds = Credentials::new(config.id.clone(), config.password.clone()); - let transport = AsyncSmtpTransport::::relay(&config.domain_name)? - .credentials(creds) - .build(); - - Ok(Self { config, transport }) - } - - pub(crate) async fn send_new_email(&self, email: EmailMessage) -> Result<()> { - self.send_inner( - email.to, - email.subject, - email.reference, - email.reply_to, - email.body_plain, - email.body_html, - email.body_attachments, - ) - .await - } - - async fn send_inner( - &self, - to: String, - subject: String, - reference: Option, - reply_to: Option, - body_plain: String, - body_html: String, - body_attachments: Option>, - ) -> Result<()> { - let from_mbox = Mailbox::new(None, self.config.id.parse::
()?); - let to_mbox = Mailbox::new(None, to.parse::
()?); - - let mut email_builder = Message::builder() - .from(from_mbox) - .subject(subject) - .to(to_mbox); - if let Some(reference) = reference { - email_builder = email_builder.references(reference); - } - if let Some(reply_to) = reply_to { - email_builder = email_builder.in_reply_to(reply_to); - } - let mut multipart = MultiPart::related().singlepart(SinglePart::html(body_html)); - if let Some(body_attachments) = body_attachments { - for attachment in body_attachments { - multipart = multipart.singlepart( - Attachment::new_inline(attachment.inline_id) - .body(attachment.contents, attachment.content_type.parse()?), - ); - } - } - let email = email_builder.multipart( - MultiPart::alternative() - .singlepart(SinglePart::plain(body_plain)) - .multipart(multipart), - )?; - - self.transport.send(email).await?; - - Ok(()) - } - - fn reconnect(mut self) -> Result<()> { - const MAX_RETRIES: u32 = 5; - let mut retry_count = 0; - - while retry_count < MAX_RETRIES { - match SmtpClient::new(self.config.clone()) { - Ok(new_client) => { - self.transport = new_client.transport; - return Ok(()); - } - Err(_) => { - retry_count += 1; - std::thread::sleep(std::time::Duration::from_millis(1000)); - } - } - } - - Err(anyhow!("{SMTP_RECONNECT_ERROR}")) - } -} - -pub async fn render_html(template_name: &str, render_data: Value) -> Result { - let email_template_filename = PathBuf::new() - .join(EMAIL_TEMPLATES.get().unwrap()) - .join(template_name); - let email_template = read_to_string(&email_template_filename).await?; - - let reg = Handlebars::new(); - Ok(reg.render_template(&email_template, &render_data)?) -} diff --git a/packages/relayer/src/subject_templates.rs b/packages/relayer/src/subject_templates.rs deleted file mode 100644 index 9b64cb6e..00000000 --- a/packages/relayer/src/subject_templates.rs +++ /dev/null @@ -1,227 +0,0 @@ -#![allow(clippy::upper_case_acronyms)] - -use crate::*; - -use ethers::abi::{self, Token}; -use ethers::types::{Address, Bytes, I256, U256}; -use regex::Regex; - -#[derive(Debug, Clone)] -pub enum TemplateValue { - String(String), - Uint(U256), - Int(I256), - Decimals(String), - EthAddr(Address), - Fixed(String), -} - -pub(crate) const STRING_RGEX: &str = ".+"; -pub(crate) const UINT_REGEX: &str = "[0-9]+"; -pub(crate) const INT_REGEX: &str = "-?[0-9]+"; -pub(crate) const DECIMALS_REGEX: &str = "[0-9]+(\\.[0-9]+)?"; -pub(crate) const ETH_ADDR_REGEX: &str = "0x[0-9a-fA-F]{40}"; -// pub(crate) const EMAIL_ADDR_REGEX: &str = -// "[a-zA-Z0-9!#$%&'\\*\\+-/=\\?^_`{\\|}~\\.]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9\\.-]+"; - -impl TemplateValue { - #[named] - 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_idx( - input: &str, - templates_array: Vec>, -) -> Result<(Option, Vec)> { - for (idx, templates) in templates_array.into_iter().enumerate() { - let template_vals = extract_template_vals(input, templates); - match template_vals { - Ok(vals) => { - return Ok((Some(idx), vals)); - } - Err(_) => { - continue; - } - } - } - Ok((None, Vec::new())) -} - -pub fn extract_template_vals(input: &str, templates: Vec) -> Result> { - let input_decomposed: Vec<&str> = input.split(' ').collect(); - let mut template_vals = Vec::new(); - let mut input_idx = 0; - for template in templates.iter() { - match template.as_str() { - "{string}" => { - let string_match = Regex::new(STRING_RGEX) - .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)); - input_idx += 1; - } - "{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)); - input_idx += 1; - } - "{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)); - input_idx += 1; - } - "{decimals}" => { - let decimals_match = Regex::new(DECIMALS_REGEX) - .unwrap() - .find(input_decomposed[input_idx]) - .ok_or(anyhow!("No amount found"))?; - if decimals_match.start() != 0 - || decimals_match.end() != input_decomposed[input_idx].len() - { - return Err(anyhow!("Amount must be the whole word")); - } - let decimals = decimals_match.as_str().to_string(); - template_vals.push(TemplateValue::Decimals(decimals)); - input_idx += 1; - } - "{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)); - input_idx += 1; - } - _ => { - input_idx += 1; - } - } - } - if input_idx != input_decomposed.len() { - return Err(anyhow!("Input is not fully consumed")); - } - 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.rs b/packages/relayer/src/utils.rs deleted file mode 100644 index baeb340d..00000000 --- a/packages/relayer/src/utils.rs +++ /dev/null @@ -1,193 +0,0 @@ -#![allow(clippy::upper_case_acronyms)] -#![allow(clippy::identity_op)] - -use crate::*; -use chrono::{DateTime, Local}; -use ethers::abi::{self, Token}; -use ethers::types::{Bytes, U256}; -use serde::Deserialize; -use std::hash::{Hash,Hasher}; - -use std::collections::hash_map::DefaultHasher; -use std::path::{Path, PathBuf}; - -use tokio::{ - fs::{read_to_string, remove_file, File}, - io::AsyncWriteExt, -}; - -use lazy_static::lazy_static; -use std::sync::Arc; -use tokio::sync::Mutex; - -lazy_static! { - pub static ref SHARED_MUTEX: Arc> = Arc::new(Mutex::new(0)); -} - -// Error strings -pub const WRONG_AUTH_METHOD: &str = "Not supported auth type"; -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 INSUFFICIENT_BALANCE: &str = "Insufficient balance"; - -// Core REGEX'es -// pub(crate) const AMOUNT_REGEX: &str = "[0-9]+(\\.[0-9]+)?"; -// pub(crate) const TOKEN_NAME_REGEX: &str = "[A-Z]+"; -// pub(crate) const STRING_RGEX: &str = ".+"; -// pub(crate) const UINT_REGEX: &str = "[0-9]+"; -// pub(crate) const INT_REGEX: &str = "-?[0-9]+"; -// pub(crate) const ETH_ADDR_REGEX: &str = "0x[0-9a-fA-F]{40}"; -// pub(crate) const EMAIL_ADDR_REGEX: &str = -// "[a-zA-Z0-9!#$%&'\\*\\+-/=\\?^_`{\\|}~\\.]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9\\.-]+"; - -pub(crate) const DOMAIN_FIELDS: usize = 9; -pub(crate) const SUBJECT_FIELDS: usize = 17; -pub(crate) 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]))) - } -} - -pub(crate) async fn generate_email_auth_input( - circuits_dir_path: &Path, - email: &str, - account_code: &str, -) -> Result { - let email_hash = calculate_email_hash(email); - let email_file_name = PathBuf::new() - .join(INPUT_FILES_DIR.get().unwrap()) - .join(email_hash.to_string() + ".email"); - let input_file_name = PathBuf::new() - .join(INPUT_FILES_DIR.get().unwrap()) - .join(email_hash.to_string() + ".json"); - - let mut email_file = File::create(&email_file_name).await?; - email_file.write_all(email.as_bytes()).await?; - - let command_str = format!( - "--cwd {} gen-input --email-file {} --account-code {} --input-file {}", - circuits_dir_path.to_str().unwrap(), - email_file_name.to_str().unwrap(), - account_code, - input_file_name.to_str().unwrap() - ); - - let mut proc = tokio::process::Command::new("yarn") - .args(command_str.split_whitespace()) - .spawn()?; - - let status = proc.wait().await?; - assert!(status.success()); - - let result = read_to_string(&input_file_name).await?; - - remove_file(email_file_name).await?; - remove_file(input_file_name).await?; - - Ok(result) -} - -#[named] -pub(crate) 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(crate) fn u256_to_bytes32(x: &U256) -> [u8; 32] { - let mut bytes = [0u8; 32]; - x.to_big_endian(&mut bytes); - bytes -} - -pub(crate) fn u256_to_hex(x: &U256) -> String { - "0x".to_string() + &hex::encode(u256_to_bytes32(x)) -} - -pub(crate) fn hex_to_u256(hex: &str) -> Result { - let bytes: Vec = hex::decode(&hex[2..])?; - let mut array = [0u8; 32]; - array.copy_from_slice(&bytes); - Ok(U256::from_big_endian(&array)) -} - -pub(crate) fn fr_to_bytes32(fr: &Fr) -> Result<[u8; 32]> { - let hex = field2hex(fr); - let bytes = hex::decode(&hex[2..])?; - let mut result = [0u8; 32]; - result.copy_from_slice(&bytes); - Ok(result) -} - -pub(crate) fn bytes32_to_fr(bytes32: &[u8; 32]) -> Result { - let hex: String = "0x".to_string() + &hex::encode(bytes32); - let field = hex2field(&hex)?; - Ok(field) -} - -pub(crate) fn now() -> i64 { - let dt: DateTime = Local::now(); - dt.timestamp() -} - -pub(crate) fn calculate_email_hash(input: &str) -> String { - let mut hasher = DefaultHasher::new(); - input.hash(&mut hasher); - let hash_code = hasher.finish(); - - hash_code.to_string() -} diff --git a/packages/relayer/src/utils/utils.rs b/packages/relayer/src/utils/utils.rs index c3042813..bea5bae7 100644 --- a/packages/relayer/src/utils/utils.rs +++ b/packages/relayer/src/utils/utils.rs @@ -28,19 +28,19 @@ pub struct ProofJson { pi_c: Vec, } -#[derive(Serialize, Deserialize)] -struct EmailAuthInput { - padded_header: Vec, - public_key: Vec, - signature: Vec, - padded_header_len: String, - account_code: String, - from_addr_idx: usize, - subject_idx: usize, - domain_idx: usize, - timestamp_idx: usize, - code_idx: usize, -} +// #[derive(Serialize, Deserialize)] +// struct EmailAuthInput { +// padded_header: Vec, +// public_key: Vec, +// signature: Vec, +// padded_header_len: String, +// account_code: String, +// from_addr_idx: usize, +// subject_idx: usize, +// domain_idx: usize, +// timestamp_idx: usize, +// code_idx: usize, +// } impl ProofJson { pub fn to_eth_bytes(&self) -> Result { @@ -66,48 +66,48 @@ impl ProofJson { } } -pub async fn generate_email_auth_input(email: &str, account_key: &str) -> Result { - let parsed_email = ParsedEmail::new_from_raw_email(&email).await?; - let circuit_input_params = circuit::CircuitInputParams::new( - vec![], - parsed_email.canonicalized_header.as_bytes().to_vec(), - "".to_string(), - vec_u8_to_bigint(parsed_email.clone().signature), - vec_u8_to_bigint(parsed_email.clone().public_key), - None, - Some(1024), - Some(64), - Some(true), - ); - let email_circuit_inputs = circuit::generate_circuit_inputs(circuit_input_params); +// pub async fn generate_email_auth_input(email: &str, account_key: &str) -> Result { +// let parsed_email = ParsedEmail::new_from_raw_email(&email).await?; +// let circuit_input_params = circuit::CircuitInputParams::new( +// vec![], +// parsed_email.canonicalized_header.as_bytes().to_vec(), +// "".to_string(), +// vec_u8_to_bigint(parsed_email.clone().signature), +// vec_u8_to_bigint(parsed_email.clone().public_key), +// None, +// Some(1024), +// Some(64), +// Some(true), +// ); +// let email_circuit_inputs = circuit::generate_circuit_inputs(circuit_input_params); - let from_addr_idx = parsed_email.get_from_addr_idxes().unwrap(); - let domain_idx = parsed_email.get_email_domain_idxes().unwrap(); - let subject_idx = parsed_email.get_subject_all_idxes().unwrap(); - let code_idx = match parsed_email.get_invitation_code_idxes() { - Ok(indexes) => indexes.0, - Err(_) => { - info!(LOG, "No invitation code in header"); - 0 - } - }; - let timestamp_idx = parsed_email.get_timestamp_idxes().unwrap(); +// let from_addr_idx = parsed_email.get_from_addr_idxes().unwrap(); +// let domain_idx = parsed_email.get_email_domain_idxes().unwrap(); +// let subject_idx = parsed_email.get_subject_all_idxes().unwrap(); +// let code_idx = match parsed_email.get_invitation_code_idxes() { +// Ok(indexes) => indexes.0, +// Err(_) => { +// info!(LOG, "No invitation code in header"); +// 0 +// } +// }; +// let timestamp_idx = parsed_email.get_timestamp_idxes().unwrap(); - let email_auth_input = EmailAuthInput { - padded_header: email_circuit_inputs.in_padded, - public_key: email_circuit_inputs.pubkey, - signature: email_circuit_inputs.signature, - padded_header_len: email_circuit_inputs.in_len_padded_bytes, - account_code: format!("0x{}", account_key.to_string()), - from_addr_idx: from_addr_idx.0, - subject_idx: subject_idx.0, - domain_idx: domain_idx.0, - timestamp_idx: timestamp_idx.0, - code_idx, - }; +// let email_auth_input = EmailAuthInput { +// padded_header: email_circuit_inputs.in_padded, +// public_key: email_circuit_inputs.pubkey, +// signature: email_circuit_inputs.signature, +// padded_header_len: email_circuit_inputs.in_len_padded_bytes, +// account_code: format!("0x{}", account_key.to_string()), +// from_addr_idx: from_addr_idx.0, +// subject_idx: subject_idx.0, +// domain_idx: domain_idx.0, +// timestamp_idx: timestamp_idx.0, +// code_idx, +// }; - Ok(serde_json::to_string(&email_auth_input)?) -} +// Ok(serde_json::to_string(&email_auth_input)?) +// } #[named] pub async fn generate_proof( diff --git a/packages/relayer/src/web_server.rs b/packages/relayer/src/web_server.rs deleted file mode 100644 index 0c73e475..00000000 --- a/packages/relayer/src/web_server.rs +++ /dev/null @@ -1,258 +0,0 @@ -use crate::*; - -use std::sync::atomic::Ordering; - -use axum::{routing::MethodRouter, Router}; -use serde::{Deserialize, Serialize}; -use tokio::sync::mpsc::UnboundedSender; -use tower_http::cors::{AllowHeaders, AllowMethods, Any, CorsLayer}; - -#[derive(Serialize, Deserialize)] -pub struct RequestStatusRequest { - pub request_id: i64, -} - -#[derive(Serialize, Deserialize)] -pub enum RequestStatus { - NotExist = 0, - Pending = 1, - Processed = 2, -} - -#[derive(Serialize, Deserialize)] -pub struct RequestStatusResponse { - pub request_id: i64, - pub status: RequestStatus, - pub is_success: bool, - pub email_nullifier: Option, - pub account_salt: Option, - pub is_code_exist: Option, -} - -#[derive(Serialize, Deserialize)] -pub struct AcceptanceRequest { - pub wallet_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: i64, - pub subject_params: Vec, -} - -#[derive(Serialize, Deserialize)] -pub struct RecoveryRequest { - pub wallet_eth_addr: String, - pub guardian_email_addr: String, - pub template_idx: u64, - pub subject: String, -} - -#[derive(Serialize, Deserialize)] -pub struct RecoveryResponse { - pub request_id: i64, - pub subject_params: Vec, -} - -#[named] -async fn requestStatus(payload: String, db: Arc) -> Result { - let req = serde_json::from_str::(&payload) - .map_err(|_| anyhow!("Invalid payload json".to_string()))?; - let request_id = req.request_id; - let row = db.get_requests_row(request_id).await?; - match row { - None => Ok(RequestStatusResponse { - request_id, - status: RequestStatus::NotExist, - is_success: false, - email_nullifier: None, - account_salt: None, - is_code_exist: None, - }), - Some(row) => { - let status = if row.is_processed { - RequestStatus::Processed - } else { - RequestStatus::Pending - }; - Ok(RequestStatusResponse { - request_id, - status, - is_success: row.is_success.unwrap_or(false), - email_nullifier: if row.is_processed { - row.email_nullifier - } else { - None - }, - account_salt: if row.is_processed { - row.account_salt - } else { - None - }, - is_code_exist: if row.is_processed { - row.is_code_exist - } else { - None - }, - }) - } - } -} - -// #[named] -// async fn acceptanceRequest(payload: String, db: Arc) -> Result { -// let req = serde_json::from_str::(&payload) -// .map_err(|_| anyhow!("Invalid payload json".to_string()))?; - -// } -// #[named] -// async fn unclaim( -// payload: UnclaimRequest, -// db: Arc, -// chain_client: Arc, -// tx_claimer: UnboundedSender, -// ) -> Result { -// let padded_email_addr = PaddedEmailAddr::from_email_addr(&payload.email_address); -// info!( -// LOG, -// "padded email address fields: {:?}", -// padded_email_addr.to_email_addr_fields(); "func" => function_name!() -// ); -// let commit = padded_email_addr.to_commitment(&hex2field(&payload.random)?)?; -// info!(LOG, "commit {:?}", commit; "func" => function_name!()); -// let id = chain_client -// .get_unclaim_id_from_tx_hash(&payload.tx_hash, payload.is_fund) -// .await?; -// info!(LOG, "id {:?}", id; "func" => function_name!()); -// // let psi_client = PSIClient::new( -// // Arc::clone(&chain_client), -// // payload.email_address.clone(), -// // id, -// // payload.is_fund, -// // ) -// // .await?; -// // psi_client -// // .check_and_reveal(db.clone(), chain_client.clone(), &payload.email_address) -// // .await?; -// let claim = Claim { -// id, -// email_address: payload.email_address.clone(), -// random: payload.random.clone(), -// commit: field2hex(&commit), -// expiry_time: payload.expiry_time, -// is_fund: payload.is_fund, -// is_announced: false, -// is_seen: false, -// }; -// tx_claimer.send(claim)?; -// trace!(LOG, "claim sent to tx_claimer"; "func" => function_name!()); - -// Ok(format!( -// "Unclaimed {} for {} is accepted", -// if payload.is_fund { "fund" } else { "state" }, -// payload.email_address -// )) -// } - -// #[named] -// pub(crate) async fn run_server( -// addr: &str, -// routes: Vec<(String, MethodRouter)>, -// db: Arc, -// chain_client: Arc, -// tx_claimer: UnboundedSender, -// ) -> Result<()> { -// let chain_client_check_clone = Arc::clone(&chain_client); -// let chain_client_reveal_clone = Arc::clone(&chain_client); -// let tx_claimer_reveal_clone = tx_claimer.clone(); - -// let mut app = Router::new() -// .route( -// "/api/emailAddrCommit", -// axum::routing::post(move |payload: String| async move { -// info!(LOG, "/emailAddrCommit Received payload: {}", payload; "func" => function_name!()); -// let json = serde_json::from_str::(&payload) -// .map_err(|_| "Invalid payload json".to_string()) -// .unwrap(); -// let padded_email_addr = PaddedEmailAddr::from_email_addr(&json.email_address); -// let commit = padded_email_addr -// .to_commitment(&hex2field(&json.random).unwrap()) -// .unwrap(); -// info!(LOG, "commit {:?}", commit; "func" => function_name!()); -// field2hex(&commit) -// }), -// ) -// .route( -// "/api/unclaim", -// axum::routing::post(move |payload: String| async move { -// info!(LOG, "/unclaim Received payload: {}", payload; "func" => function_name!()); -// let json = serde_json::from_str::(&payload) -// .map_err(|_| "Invalid payload json".to_string())?; -// unclaim(json, db, chain_client, tx_claimer) -// .await -// .map_err(|err| { -// error!(LOG, "Failed to accept unclaim: {}", err; "func" => function_name!()); -// err.to_string() -// }) -// }), -// ) -// .route( -// "/api/stats", -// axum::routing::get(move || async move { -// let stats = StatResponse { -// onboarding_tokens_distributed: ONBOARDING_COUNTER.load(Ordering::SeqCst), -// onboarding_tokens_left: *ONBOARDING_TOKEN_DISTRIBUTION_LIMIT.get().unwrap() -// - ONBOARDING_COUNTER.load(Ordering::SeqCst), -// }; -// axum::Json(stats) -// }), -// ) -// .route( -// "/api/serveCheck/", -// axum::routing::post(move |payload: String| async move { -// info!(LOG, "/serveCheck Received payload: {}", payload; "func" => function_name!()); -// let json = serde_json::from_str::(&payload) -// .map_err(|_| "Invalid payload json".to_string())?; -// serve_check_request(json, chain_client_check_clone) -// .await -// .map_err(|err| { -// error!(LOG, "Failed PSI check serve: {}", err; "func" => function_name!()); -// err.to_string() -// }) -// }), -// ) -// .route( -// "/api/serveReveal/", -// axum::routing::post(move |payload: String| async move { -// info!(LOG, "/serveCheck Received payload: {}", payload; "func" => function_name!()); -// let json = serde_json::from_str::(&payload) -// .map_err(|_| "Invalid payload json".to_string())?; -// serve_reveal_request(json, chain_client_reveal_clone, tx_claimer_reveal_clone) -// .await -// .map_err(|err| { -// error!(LOG, "Failed PSI reveal serve: {}", err; "func" => function_name!()); -// err.to_string() -// }) -// }), -// ); -// for (path, router) in routes { -// app = app.route(&path, router); -// } -// app = app.layer( -// CorsLayer::new() -// .allow_methods(AllowMethods::any()) -// .allow_headers(AllowHeaders::any()) -// .allow_origin(Any), -// ); - -// trace!(LOG, "Listening API at {}", addr; "func" => function_name!()); -// axum::Server::bind(&addr.parse()?) -// .serve(app.into_make_service()) -// .await?; - -// Ok(()) -// } diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index a18523ec..3c5a7055 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "relayer-utils" version = "0.1.0" -authors = ["Sora Suegami"] +authors = ["Sora Suegami", "Aditya Bisht"] license = "MIT" edition = "2018" exclude = ["index.node"] @@ -43,3 +43,8 @@ slog = "2.7.0" sha2 = "0.10.8" ethers = "2.0.14" # wasm-bindgen = { version = "0.2.90", default-features = false } + +[dependencies.neon] +version = "0.10" +default-features = false +features = ["napi-6", "channel-api", "promise-api"] diff --git a/packages/utils/src/circuit.rs b/packages/utils/src/circuit.rs index 584bc6cb..342136ee 100644 --- a/packages/utils/src/circuit.rs +++ b/packages/utils/src/circuit.rs @@ -1,8 +1,9 @@ use std::cmp; +use crate::*; +use anyhow::Result; use num_bigint::BigInt; - -use crate::{generate_partial_sha, sha256_pad, to_circom_bigint_bytes, uint8_array_to_char_array}; +use serde::{Deserialize, Serialize}; pub const MAX_HEADER_PADDED_BYTES: usize = 1024; pub const MAX_BODY_PADDED_BYTES: usize = 1536; diff --git a/packages/utils/src/converters.rs b/packages/utils/src/converters.rs index 194833e2..ca25eb59 100644 --- a/packages/utils/src/converters.rs +++ b/packages/utils/src/converters.rs @@ -4,6 +4,7 @@ use anyhow; use ethers::types::U256; use halo2curves::ff::PrimeField; use itertools::Itertools; +use neon::prelude::*; use num_bigint::BigInt; use poseidon_rs::*; @@ -191,3 +192,30 @@ pub fn hex_to_u256(hex: &str) -> Result { array.copy_from_slice(&bytes); Ok(U256::from_big_endian(&array)) } + +pub fn hex2field_node(cx: &mut FunctionContext, input_strs: &str) -> NeonResult { + match hex2field(input_strs) { + Ok(field) => Ok(field), + Err(e) => cx.throw_error(e.to_string()), + } +} + +pub fn bytes2fields_node(mut cx: FunctionContext) -> JsResult { + let input_str = cx.argument::(0)?; + let input_vec = input_str.to_vec(&mut cx)?; + let mut input_bytes = vec![]; + for val in input_vec.into_iter() { + let val = match val.downcast::(&mut cx) { + Ok(v) => v.value(&mut cx), + Err(e) => return cx.throw_error(e.to_string()), + }; + input_bytes.push(val as u8); + } + let fields = bytes2fields(&input_bytes); + let js_array = JsArray::new(&mut cx, fields.len() as u32); + for (i, field) in fields.into_iter().enumerate() { + let field = cx.string(&field2hex(&field)); + js_array.set(&mut cx, i as u32, field)?; + } + Ok(js_array) +} diff --git a/packages/utils/src/cryptos.rs b/packages/utils/src/cryptos.rs index f74aa0a9..e4bcdb41 100644 --- a/packages/utils/src/cryptos.rs +++ b/packages/utils/src/cryptos.rs @@ -3,27 +3,14 @@ use std::error::Error; use crate::converters::*; use halo2curves::ff::Field; +use neon::prelude::*; use poseidon_rs::*; -use rand_core::RngCore; +use rand_core::{OsRng, RngCore}; use rsa::sha2::{Digest, Sha256}; pub use zk_regex_apis::padding::pad_string; pub const MAX_EMAIL_ADDR_BYTES: usize = 256; -#[derive(Debug, Clone, Copy)] -pub struct RelayerRand(pub Fr); - -impl RelayerRand { - pub fn new(mut r: R) -> Self { - Self(Fr::random(&mut r)) - } - - pub fn new_from_seed(seed: &[u8]) -> Result { - let value = poseidon_bytes(seed)?; - Ok(Self(value)) - } -} - #[derive(Debug, Clone)] pub struct PaddedEmailAddr { pub padded_bytes: Vec, @@ -33,8 +20,6 @@ pub struct PaddedEmailAddr { impl PaddedEmailAddr { pub fn from_email_addr(email_addr: &str) -> Self { let email_addr_len = email_addr.as_bytes().len(); - // let mut padded_bytes = email_addr.as_bytes().to_vec(); - // padded_bytes.append(&mut vec![0; MAX_EMAIL_ADDR_BYTES - email_addr_len]); let padded_bytes = pad_string(email_addr, MAX_EMAIL_ADDR_BYTES).to_vec(); Self { padded_bytes, @@ -46,10 +31,6 @@ impl PaddedEmailAddr { bytes2fields(&self.padded_bytes) } - // pub fn to_pointer(&self, relayer_rand: &RelayerRand) -> Result { - // self.to_commitment(&relayer_rand.0) - // } - pub fn to_commitment(&self, rand: &Fr) -> Result { let mut inputs = vec![*rand]; inputs.append(&mut self.to_email_addr_fields()); @@ -72,9 +53,9 @@ pub fn extract_rand_from_signature(signature: &[u8]) -> Result(rng: R) -> Self { Self(Fr::random(rng)) } @@ -82,41 +63,20 @@ impl AccountKey { pub fn from(elem: Fr) -> Self { Self(elem) } - - // pub fn to_commitment( - // &self, - // email_addr: &PaddedEmailAddr, - // relayer_rand_hash: &Fr, - // ) -> Result { - // let mut inputs = vec![self.0]; - // inputs.append(&mut email_addr.to_email_addr_fields()); - // inputs.push(*relayer_rand_hash); - // poseidon_fields(&inputs) - // } - - // pub fn to_wallet_salt(&self, account_key: AccountKey) -> Result { - // let field = poseidon_fields(&[self.0, Fr::zero()])?; - // Ok(WalletSalt(field)) - // } - - // pub fn to_ext_account_salt(&self) -> Result { - // let field = poseidon_fields(&[self.0.clone(), Fr::one()])?; - // Ok(ExtAccountSalt(field)) - // } } #[derive(Debug, Clone, Copy)] -pub struct WalletSalt(pub Fr); +pub struct AccountSalt(pub Fr); -impl WalletSalt { +impl AccountSalt { pub fn new( email_addr: &PaddedEmailAddr, - account_key: AccountKey, + account_code: AccountCode, ) -> Result { let mut inputs = email_addr.to_email_addr_fields(); - inputs.push(account_key.0); + inputs.push(account_code.0); inputs.push(Fr::zero()); - Ok(WalletSalt(poseidon_fields(&inputs)?)) + Ok(Self(poseidon_fields(&inputs)?)) } } @@ -133,6 +93,113 @@ pub fn email_nullifier(signature: &[u8]) -> Result { poseidon_fields(&[sign_rand]) } +pub fn pad_email_addr_node(mut cx: FunctionContext) -> JsResult { + let email_addr = cx.argument::(0)?.value(&mut cx); + let padded_email_addr = PaddedEmailAddr::from_email_addr(&email_addr); + let padded_email_addr_bytes = + JsArray::new(&mut cx, padded_email_addr.padded_bytes.len() as u32); + for (idx, byte) in padded_email_addr.padded_bytes.into_iter().enumerate() { + let js_byte = cx.number(byte); + padded_email_addr_bytes.set(&mut cx, idx as u32, js_byte)?; + } + Ok(padded_email_addr_bytes) +} + +pub fn gen_account_code_node(mut cx: FunctionContext) -> JsResult { + let mut rng = OsRng; + let account_code = AccountCode::new(&mut rng); + let account_code_str = field2hex(&account_code.0); + Ok(cx.string(account_code_str)) +} + +pub fn account_salt_node(mut cx: FunctionContext) -> JsResult { + let email_addr = cx.argument::(0)?.value(&mut cx); + let padded_email_addr = PaddedEmailAddr::from_email_addr(&email_addr); + let account_code_str = cx.argument::(1)?.value(&mut cx); + let account_code = hex2field_node(&mut cx, &account_code_str)?; + let account_salt = match AccountSalt::new(&padded_email_addr, AccountCode(account_code)) { + Ok(account_salt) => account_salt, + Err(e) => return cx.throw_error(&format!("WalletSalt failed: {}", e)), + }; + let account_salt_str = field2hex(&account_salt.0); + Ok(cx.string(account_salt_str)) +} + +pub fn public_key_hash_node(mut cx: FunctionContext) -> JsResult { + let public_key_n = cx.argument::(0)?.value(&mut cx); + let mut public_key_n = match hex::decode(&public_key_n[2..]) { + Ok(bytes) => bytes, + Err(e) => return cx.throw_error(&format!("public_key_n is an invalid hex string: {}", e)), + }; + public_key_n.reverse(); + let hash_field = match public_key_hash(&public_key_n) { + Ok(hash_field) => hash_field, + Err(e) => return cx.throw_error(&format!("public_key_hash failed: {}", e)), + }; + let hash_str = field2hex(&hash_field); + Ok(cx.string(hash_str)) +} + +pub fn email_nullifier_node(mut cx: FunctionContext) -> JsResult { + let signature = cx.argument::(0)?.value(&mut cx); + let mut signature = match hex::decode(&signature[2..]) { + Ok(bytes) => bytes, + Err(e) => return cx.throw_error(&format!("signature is an invalid hex string: {}", e)), + }; + signature.reverse(); + let nullifier = match email_nullifier(&signature) { + Ok(nullifier) => nullifier, + Err(e) => return cx.throw_error(&format!("email_nullifier failed: {}", e)), + }; + let nullifier_str = field2hex(&nullifier); + Ok(cx.string(nullifier_str)) +} + +pub fn email_addr_commit_node(mut cx: FunctionContext) -> JsResult { + let email_addr = cx.argument::(0)?.value(&mut cx); + let rand = cx.argument::(1)?.value(&mut cx); + let rand = hex2field_node(&mut cx, &rand)?; + let padded_email_addr = PaddedEmailAddr::from_email_addr(&email_addr); + let email_addr_commit = match padded_email_addr.to_commitment(&rand) { + Ok(fr) => fr, + Err(e) => return cx.throw_error(&format!("EmailAddrCommit failed: {}", e)), + }; + let email_addr_commit_str = field2hex(&email_addr_commit); + Ok(cx.string(email_addr_commit_str)) +} + +pub fn email_addr_commit_with_signature_node(mut cx: FunctionContext) -> JsResult { + let email_addr = cx.argument::(0)?.value(&mut cx); + let signature = cx.argument::(1)?.value(&mut cx); + let signature = match hex::decode(&signature[2..]) { + Ok(bytes) => bytes, + Err(e) => return cx.throw_error(&format!("signature is an invalid hex string: {}", e)), + }; + // signature.reverse(); + let padded_email_addr = PaddedEmailAddr::from_email_addr(&email_addr); + let email_addr_commit = match padded_email_addr.to_commitment_with_signature(&signature) { + Ok(fr) => fr, + Err(e) => return cx.throw_error(&format!("EmailAddrCommit failed: {}", e)), + }; + let email_addr_commit_str = field2hex(&email_addr_commit); + Ok(cx.string(email_addr_commit_str)) +} + +pub fn extract_rand_from_signature_node(mut cx: FunctionContext) -> JsResult { + let signature = cx.argument::(0)?.value(&mut cx); + let signature = match hex::decode(&signature[2..]) { + Ok(bytes) => bytes, + Err(e) => return cx.throw_error(&format!("signature is an invalid hex string: {}", e)), + }; + // signature.reverse(); + let rand = match extract_rand_from_signature(&signature) { + Ok(fr) => fr, + Err(e) => return cx.throw_error(&format!("extract_rand_from_signature failed: {}", e)), + }; + let rand_str = field2hex(&rand); + Ok(cx.string(rand_str)) +} + pub fn sha256_pad(mut data: Vec, max_sha_bytes: usize) -> (Vec, usize) { let length_bits = data.len() * 8; // Convert length from bytes to bits let length_in_bytes = int64_to_bytes(length_bits as u64); @@ -229,48 +296,3 @@ pub fn generate_partial_sha( let precomputed_sha = partial_sha(precompute_text, sha_cutoff_index); Ok((precomputed_sha, body_remaining, body_remaining_length)) } - -pub fn email_addr_commit_node(mut cx: FunctionContext) -> JsResult { - let email_addr = cx.argument::(0)?.value(&mut cx); - let rand = cx.argument::(1)?.value(&mut cx); - let rand = hex2field_node(&mut cx, &rand)?; - let padded_email_addr = PaddedEmailAddr::from_email_addr(&email_addr); - let email_addr_commit = match padded_email_addr.to_commitment(&rand) { - Ok(fr) => fr, - Err(e) => return cx.throw_error(&format!("EmailAddrCommit failed: {}", e)), - }; - let email_addr_commit_str = field2hex(&email_addr_commit); - Ok(cx.string(email_addr_commit_str)) -} - -pub fn email_addr_commit_with_signature_node(mut cx: FunctionContext) -> JsResult { - let email_addr = cx.argument::(0)?.value(&mut cx); - let signature = cx.argument::(1)?.value(&mut cx); - let signature = match hex::decode(&signature[2..]) { - Ok(bytes) => bytes, - Err(e) => return cx.throw_error(&format!("signature is an invalid hex string: {}", e)), - }; - // signature.reverse(); - let padded_email_addr = PaddedEmailAddr::from_email_addr(&email_addr); - let email_addr_commit = match padded_email_addr.to_commitment_with_signature(&signature) { - Ok(fr) => fr, - Err(e) => return cx.throw_error(&format!("EmailAddrCommit failed: {}", e)), - }; - let email_addr_commit_str = field2hex(&email_addr_commit); - Ok(cx.string(email_addr_commit_str)) -} - -pub fn extract_rand_from_signature_node(mut cx: FunctionContext) -> JsResult { - let signature = cx.argument::(0)?.value(&mut cx); - let signature = match hex::decode(&signature[2..]) { - Ok(bytes) => bytes, - Err(e) => return cx.throw_error(&format!("signature is an invalid hex string: {}", e)), - }; - // signature.reverse(); - let rand = match extract_rand_from_signature(&signature) { - Ok(fr) => fr, - Err(e) => return cx.throw_error(&format!("extract_rand_from_signature failed: {}", e)), - }; - let rand_str = field2hex(&rand); - Ok(cx.string(rand_str)) -} diff --git a/packages/utils/src/email_auth.rs b/packages/utils/src/email_auth.rs new file mode 100644 index 00000000..dd6a1812 --- /dev/null +++ b/packages/utils/src/email_auth.rs @@ -0,0 +1,85 @@ +use std::cmp; + +use crate::*; +use anyhow::Result; +use num_bigint::BigInt; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +pub struct EmailAuthInput { + padded_header: Vec, + public_key: Vec, + signature: Vec, + padded_header_len: String, + account_code: String, + from_addr_idx: usize, + subject_idx: usize, + domain_idx: usize, + timestamp_idx: usize, + code_idx: usize, +} + +pub async fn generate_email_auth_input(email: &str, account_code: &AccountCode) -> Result { + let parsed_email = ParsedEmail::new_from_raw_email(&email).await?; + let circuit_input_params = circuit::CircuitInputParams::new( + vec![], + parsed_email.canonicalized_header.as_bytes().to_vec(), + "".to_string(), + vec_u8_to_bigint(parsed_email.clone().signature), + vec_u8_to_bigint(parsed_email.clone().public_key), + None, + Some(1024), + Some(64), + Some(true), + ); + let email_circuit_inputs = circuit::generate_circuit_inputs(circuit_input_params); + + let from_addr_idx = parsed_email.get_from_addr_idxes().unwrap().0; + let domain_idx = parsed_email.get_email_domain_idxes().unwrap().0; + let subject_idx = parsed_email.get_subject_all_idxes().unwrap().0; + let code_idx = match parsed_email.get_invitation_code_idxes() { + Ok(indexes) => indexes.0, + Err(_) => { + // info!(LOG, "No invitation code in header"); + 0 + } + }; + let timestamp_idx = parsed_email.get_timestamp_idxes().unwrap().0; + + let email_auth_input = EmailAuthInput { + padded_header: email_circuit_inputs.in_padded, + public_key: email_circuit_inputs.pubkey, + signature: email_circuit_inputs.signature, + padded_header_len: email_circuit_inputs.in_len_padded_bytes, + account_code: field2hex(&account_code.0), + from_addr_idx: from_addr_idx, + subject_idx: subject_idx, + domain_idx: domain_idx, + timestamp_idx: timestamp_idx, + code_idx, + }; + + Ok(serde_json::to_string(&email_auth_input)?) +} + +pub fn generate_email_auth_input_node(mut cx: FunctionContext) -> JsResult { + let email = cx.argument::(0)?.value(&mut cx); + let account_code = cx.argument::(1)?.value(&mut cx); + let account_code = AccountCode::from(hex2field_node(&mut cx, &account_code)?); + let channel = cx.channel(); + let (deferred, promise) = cx.promise(); + let rt = runtime(&mut cx)?; + + rt.spawn(async move { + let email_auth_input = generate_email_auth_input(&email, &account_code).await; + deferred.settle_with(&channel, move |mut cx| match email_auth_input { + Ok(email_auth_input) => { + let email_auth_input = cx.string(email_auth_input); + Ok(email_auth_input) + } + Err(err) => cx.throw_error(format!("Could not generate email auth input: {}", err)), + }); + }); + + Ok(promise) +} diff --git a/packages/utils/src/lib.rs b/packages/utils/src/lib.rs index a2bf9abc..a24f353a 100644 --- a/packages/utils/src/lib.rs +++ b/packages/utils/src/lib.rs @@ -1,16 +1,24 @@ pub mod circuit; pub mod converters; pub mod cryptos; +pub mod email_auth; pub mod parse_email; -use converters::*; -use cryptos::*; +pub mod regex; +pub mod statics; +pub(crate) use converters::*; +pub(crate) use cryptos::*; +pub use email_auth::*; +pub(crate) use neon::prelude::*; +pub(crate) use parse_email::*; pub use poseidon_rs::*; -use regex::*; +pub(crate) use regex::*; +pub(crate) use statics::*; pub use zk_regex_apis::extract_substrs::*; pub use zk_regex_apis::padding::*; #[neon::main] fn main(mut cx: ModuleContext) -> NeonResult<()> { + cx.export_function("genEmailAuthInput", generate_email_auth_input_node)?; cx.export_function("parseEmail", parse_email_node)?; cx.export_function("padString", pad_string_node)?; cx.export_function("bytes2Fields", bytes2fields_node)?; diff --git a/packages/utils/src/parse_email.rs b/packages/utils/src/parse_email.rs index be7de04b..09868031 100644 --- a/packages/utils/src/parse_email.rs +++ b/packages/utils/src/parse_email.rs @@ -4,10 +4,12 @@ use anyhow::Result; use hex; use cfdkim::{canonicalize_signed_email, resolve_public_key}; +use neon::prelude::*; use rsa::traits::PublicKeyParts; - use serde::{Deserialize, Serialize}; use zk_regex_apis::extract_substrs::*; + +use crate::runtime; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ParsedEmail { pub canonicalized_header: String, diff --git a/packages/utils/src/regex.rs b/packages/utils/src/regex.rs index b9806e3a..6688f8c7 100644 --- a/packages/utils/src/regex.rs +++ b/packages/utils/src/regex.rs @@ -1,4 +1,5 @@ use neon::prelude::*; +use neon::prelude::*; pub use zk_regex_apis::extract_substrs::*; pub use zk_regex_apis::padding::*; diff --git a/packages/utils/src/statics.rs b/packages/utils/src/statics.rs new file mode 100644 index 00000000..fe6c6a02 --- /dev/null +++ b/packages/utils/src/statics.rs @@ -0,0 +1,9 @@ +use neon::prelude::*; +use once_cell::sync::OnceCell; +use tokio::runtime::Runtime; + +pub fn runtime<'a, C: Context<'a>>(cx: &mut C) -> NeonResult<&'static Runtime> { + static RUNTIME: OnceCell = OnceCell::new(); + + RUNTIME.get_or_try_init(|| Runtime::new().or_else(|err| cx.throw_error(err.to_string()))) +} From dce9d198d038a6e68087dc76d7ab3bff4dcb0bd1 Mon Sep 17 00:00:00 2001 From: Aditya Bisht Date: Thu, 4 Apr 2024 05:58:15 +0530 Subject: [PATCH 42/42] feat: fixes --- .../eml_templates/acceptance_request.html | 2 +- .../eml_templates/acceptance_success.html | 2 +- .../assets/img/logoEmailWallet.png | Bin 102737 -> 0 bytes .../eml_templates/credential_not_present.html | 2 +- packages/relayer/eml_templates/error.html | 2 +- .../guardian_already_exists.html | 2 +- .../eml_templates/guardian_not_set.html | 2 +- .../eml_templates/recovery_request.html | 2 +- .../eml_templates/recovery_success.html | 2 +- packages/relayer/src/core.rs | 6 +- packages/relayer/src/database.rs | 14 +-- packages/relayer/src/utils/utils.rs | 60 +------------ packages/utils/src/circuit.rs | 76 ++++++++++++++++ packages/utils/src/email_auth.rs | 85 ------------------ packages/utils/src/lib.rs | 3 +- packages/utils/src/parse_email.rs | 8 +- packages/utils/src/regex.rs | 1 - 17 files changed, 98 insertions(+), 171 deletions(-) delete mode 100644 packages/relayer/eml_templates/assets/img/logoEmailWallet.png delete mode 100644 packages/utils/src/email_auth.rs diff --git a/packages/relayer/eml_templates/acceptance_request.html b/packages/relayer/eml_templates/acceptance_request.html index 2d75a1db..f350817a 100644 --- a/packages/relayer/eml_templates/acceptance_request.html +++ b/packages/relayer/eml_templates/acceptance_request.html @@ -104,7 +104,7 @@ " > Email Wallet Email Wallet Email Wallet Email Wallet Email Wallet Email Wallet Email Wallet Email Wallet( let circuit_input = generate_email_auth_input( &email, - &AccountCode::from(hex2field(&account_code_str)?), + &AccountCode::from(hex2field(&format!("0x{}", &account_code_str))?), ) .await?; @@ -358,7 +358,7 @@ pub async fn handle_email( let circuit_input = generate_email_auth_input( &email, - &AccountCode::from(hex2field(&account_code_str)?), + &AccountCode::from(hex2field(&format!("0x{}", &account_code_str))?), ) .await?; diff --git a/packages/relayer/src/database.rs b/packages/relayer/src/database.rs index 4faa6103..d1663312 100644 --- a/packages/relayer/src/database.rs +++ b/packages/relayer/src/database.rs @@ -42,7 +42,7 @@ impl Database { pub async fn setup_database(&self) -> Result<()> { sqlx::query( - "CREATE TABLE IF NOT EXISTS codes ( + "CREATE TABLE IF NOT EXISTS credentials ( account_code TEXT PRIMARY KEY, wallet_eth_addr TEXT NOT NULL, guardian_email_addr TEXT NOT NULL, @@ -72,7 +72,7 @@ impl Database { #[named] pub(crate) async fn get_credentials(&self, account_code: &str) -> Result> { - let row = sqlx::query("SELECT * FROM codes WHERE account_code = $1") + let row = sqlx::query("SELECT * FROM credentials WHERE account_code = $1") .bind(account_code) .fetch_optional(&self.db) .await?; @@ -97,7 +97,7 @@ impl Database { } pub(crate) async fn is_email_registered(&self, email_addr: &str) -> bool { - let row = sqlx::query("SELECT * FROM codes WHERE guardian_email_addr = $1") + let row = sqlx::query("SELECT * FROM credentials WHERE guardian_email_addr = $1") .bind(email_addr) .fetch_optional(&self.db) .await @@ -110,7 +110,7 @@ impl Database { } pub(crate) async fn update_credentials(&self, row: &Credentials) -> Result<()> { - let res = sqlx::query("UPDATE codes SET wallet_eth_addr = $1, guardian_email_addr = $2, is_set = $3 WHERE account_code = $4") + let res = sqlx::query("UPDATE credentials SET wallet_eth_addr = $1, guardian_email_addr = $2, is_set = $3 WHERE account_code = $4") .bind(&row.wallet_eth_addr) .bind(&row.guardian_email_addr) .bind(row.is_set) @@ -124,7 +124,7 @@ impl Database { pub(crate) async fn insert_credentials(&self, row: &Credentials) -> Result<()> { info!(LOG, "insert row {:?}", row; "func" => function_name!()); let row = sqlx::query( - "INSERT INTO codes (account_code, wallet_eth_addr, guardian_email_addr, is_set) VALUES ($1, $2, $3, $4) RETURNING *", + "INSERT INTO credentials (account_code, wallet_eth_addr, guardian_email_addr, is_set) VALUES ($1, $2, $3, $4) RETURNING *", ) .bind(&row.account_code) .bind(&row.wallet_eth_addr) @@ -141,7 +141,7 @@ impl Database { } pub async fn is_guardian_set(&self, wallet_eth_addr: &str, guardian_email_addr: &str) -> bool { - let row = sqlx::query("SELECT * FROM codes WHERE wallet_eth_addr = $1 AND guardian_email_addr = $2 AND is_set = TRUE") + let row = sqlx::query("SELECT * FROM credentials WHERE wallet_eth_addr = $1 AND guardian_email_addr = $2 AND is_set = TRUE") .bind(wallet_eth_addr) .bind(guardian_email_addr) .fetch_optional(&self.db) @@ -210,7 +210,7 @@ impl Database { &self, email_addr: &str, ) -> Result> { - let row = sqlx::query("SELECT * FROM codes WHERE guardian_email_addr = $1") + let row = sqlx::query("SELECT * FROM credentials WHERE guardian_email_addr = $1") .bind(email_addr) .fetch_optional(&self.db) .await?; diff --git a/packages/relayer/src/utils/utils.rs b/packages/relayer/src/utils/utils.rs index bea5bae7..efacb698 100644 --- a/packages/relayer/src/utils/utils.rs +++ b/packages/relayer/src/utils/utils.rs @@ -4,9 +4,8 @@ use crate::*; use ethers::abi::Token; use ethers::types::{Bytes, U256}; -use relayer_utils::*; -use ::serde::{Deserialize, Serialize}; +use ::serde::Deserialize; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; @@ -28,20 +27,6 @@ pub struct ProofJson { pi_c: Vec, } -// #[derive(Serialize, Deserialize)] -// struct EmailAuthInput { -// padded_header: Vec, -// public_key: Vec, -// signature: Vec, -// padded_header_len: String, -// account_code: String, -// from_addr_idx: usize, -// subject_idx: usize, -// domain_idx: usize, -// timestamp_idx: usize, -// code_idx: usize, -// } - impl ProofJson { pub fn to_eth_bytes(&self) -> Result { let pi_a = Token::FixedArray(vec![ @@ -66,49 +51,6 @@ impl ProofJson { } } -// pub async fn generate_email_auth_input(email: &str, account_key: &str) -> Result { -// let parsed_email = ParsedEmail::new_from_raw_email(&email).await?; -// let circuit_input_params = circuit::CircuitInputParams::new( -// vec![], -// parsed_email.canonicalized_header.as_bytes().to_vec(), -// "".to_string(), -// vec_u8_to_bigint(parsed_email.clone().signature), -// vec_u8_to_bigint(parsed_email.clone().public_key), -// None, -// Some(1024), -// Some(64), -// Some(true), -// ); -// let email_circuit_inputs = circuit::generate_circuit_inputs(circuit_input_params); - -// let from_addr_idx = parsed_email.get_from_addr_idxes().unwrap(); -// let domain_idx = parsed_email.get_email_domain_idxes().unwrap(); -// let subject_idx = parsed_email.get_subject_all_idxes().unwrap(); -// let code_idx = match parsed_email.get_invitation_code_idxes() { -// Ok(indexes) => indexes.0, -// Err(_) => { -// info!(LOG, "No invitation code in header"); -// 0 -// } -// }; -// let timestamp_idx = parsed_email.get_timestamp_idxes().unwrap(); - -// let email_auth_input = EmailAuthInput { -// padded_header: email_circuit_inputs.in_padded, -// public_key: email_circuit_inputs.pubkey, -// signature: email_circuit_inputs.signature, -// padded_header_len: email_circuit_inputs.in_len_padded_bytes, -// account_code: format!("0x{}", account_key.to_string()), -// from_addr_idx: from_addr_idx.0, -// subject_idx: subject_idx.0, -// domain_idx: domain_idx.0, -// timestamp_idx: timestamp_idx.0, -// code_idx, -// }; - -// Ok(serde_json::to_string(&email_auth_input)?) -// } - #[named] pub async fn generate_proof( input: &str, diff --git a/packages/utils/src/circuit.rs b/packages/utils/src/circuit.rs index 342136ee..b57a83d7 100644 --- a/packages/utils/src/circuit.rs +++ b/packages/utils/src/circuit.rs @@ -10,6 +10,20 @@ pub const MAX_BODY_PADDED_BYTES: usize = 1536; pub const CIRCOM_BIGINT_N: usize = 121; pub const CIRCOM_BIGINT_K: usize = 17; +#[derive(Serialize, Deserialize)] +pub struct EmailAuthInput { + padded_header: Vec, + public_key: Vec, + signature: Vec, + padded_header_len: String, + account_code: String, + from_addr_idx: usize, + subject_idx: usize, + domain_idx: usize, + timestamp_idx: usize, + code_idx: usize, +} + pub struct CircuitInput { pub in_padded: Vec, pub pubkey: Vec, @@ -105,3 +119,65 @@ pub fn generate_circuit_inputs(params: CircuitInputParams) -> CircuitInput { } circuit_input } + +pub async fn generate_email_auth_input(email: &str, account_code: &AccountCode) -> Result { + let parsed_email = ParsedEmail::new_from_raw_email(&email).await?; + let circuit_input_params = circuit::CircuitInputParams::new( + vec![], + parsed_email.canonicalized_header.as_bytes().to_vec(), + "".to_string(), + vec_u8_to_bigint(parsed_email.clone().signature), + vec_u8_to_bigint(parsed_email.clone().public_key), + None, + Some(1024), + Some(64), + Some(true), + ); + let email_circuit_inputs = circuit::generate_circuit_inputs(circuit_input_params); + + let from_addr_idx = parsed_email.get_from_addr_idxes().unwrap().0; + let domain_idx = parsed_email.get_email_domain_idxes().unwrap().0; + let subject_idx = parsed_email.get_subject_all_idxes().unwrap().0; + let code_idx = match parsed_email.get_invitation_code_idxes() { + Ok(indexes) => indexes.0, + Err(_) => 0, + }; + let timestamp_idx = parsed_email.get_timestamp_idxes().unwrap().0; + + let email_auth_input = EmailAuthInput { + padded_header: email_circuit_inputs.in_padded, + public_key: email_circuit_inputs.pubkey, + signature: email_circuit_inputs.signature, + padded_header_len: email_circuit_inputs.in_len_padded_bytes, + account_code: field2hex(&account_code.0), + from_addr_idx: from_addr_idx, + subject_idx: subject_idx, + domain_idx: domain_idx, + timestamp_idx: timestamp_idx, + code_idx, + }; + + Ok(serde_json::to_string(&email_auth_input)?) +} + +pub fn generate_email_auth_input_node(mut cx: FunctionContext) -> JsResult { + let email = cx.argument::(0)?.value(&mut cx); + let account_code = cx.argument::(1)?.value(&mut cx); + let account_code = AccountCode::from(hex2field_node(&mut cx, &account_code)?); + let channel = cx.channel(); + let (deferred, promise) = cx.promise(); + let rt = runtime(&mut cx)?; + + rt.spawn(async move { + let email_auth_input = generate_email_auth_input(&email, &account_code).await; + deferred.settle_with(&channel, move |mut cx| match email_auth_input { + Ok(email_auth_input) => { + let email_auth_input = cx.string(email_auth_input); + Ok(email_auth_input) + } + Err(err) => cx.throw_error(format!("Could not generate email auth input: {}", err)), + }); + }); + + Ok(promise) +} diff --git a/packages/utils/src/email_auth.rs b/packages/utils/src/email_auth.rs deleted file mode 100644 index dd6a1812..00000000 --- a/packages/utils/src/email_auth.rs +++ /dev/null @@ -1,85 +0,0 @@ -use std::cmp; - -use crate::*; -use anyhow::Result; -use num_bigint::BigInt; -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize)] -pub struct EmailAuthInput { - padded_header: Vec, - public_key: Vec, - signature: Vec, - padded_header_len: String, - account_code: String, - from_addr_idx: usize, - subject_idx: usize, - domain_idx: usize, - timestamp_idx: usize, - code_idx: usize, -} - -pub async fn generate_email_auth_input(email: &str, account_code: &AccountCode) -> Result { - let parsed_email = ParsedEmail::new_from_raw_email(&email).await?; - let circuit_input_params = circuit::CircuitInputParams::new( - vec![], - parsed_email.canonicalized_header.as_bytes().to_vec(), - "".to_string(), - vec_u8_to_bigint(parsed_email.clone().signature), - vec_u8_to_bigint(parsed_email.clone().public_key), - None, - Some(1024), - Some(64), - Some(true), - ); - let email_circuit_inputs = circuit::generate_circuit_inputs(circuit_input_params); - - let from_addr_idx = parsed_email.get_from_addr_idxes().unwrap().0; - let domain_idx = parsed_email.get_email_domain_idxes().unwrap().0; - let subject_idx = parsed_email.get_subject_all_idxes().unwrap().0; - let code_idx = match parsed_email.get_invitation_code_idxes() { - Ok(indexes) => indexes.0, - Err(_) => { - // info!(LOG, "No invitation code in header"); - 0 - } - }; - let timestamp_idx = parsed_email.get_timestamp_idxes().unwrap().0; - - let email_auth_input = EmailAuthInput { - padded_header: email_circuit_inputs.in_padded, - public_key: email_circuit_inputs.pubkey, - signature: email_circuit_inputs.signature, - padded_header_len: email_circuit_inputs.in_len_padded_bytes, - account_code: field2hex(&account_code.0), - from_addr_idx: from_addr_idx, - subject_idx: subject_idx, - domain_idx: domain_idx, - timestamp_idx: timestamp_idx, - code_idx, - }; - - Ok(serde_json::to_string(&email_auth_input)?) -} - -pub fn generate_email_auth_input_node(mut cx: FunctionContext) -> JsResult { - let email = cx.argument::(0)?.value(&mut cx); - let account_code = cx.argument::(1)?.value(&mut cx); - let account_code = AccountCode::from(hex2field_node(&mut cx, &account_code)?); - let channel = cx.channel(); - let (deferred, promise) = cx.promise(); - let rt = runtime(&mut cx)?; - - rt.spawn(async move { - let email_auth_input = generate_email_auth_input(&email, &account_code).await; - deferred.settle_with(&channel, move |mut cx| match email_auth_input { - Ok(email_auth_input) => { - let email_auth_input = cx.string(email_auth_input); - Ok(email_auth_input) - } - Err(err) => cx.throw_error(format!("Could not generate email auth input: {}", err)), - }); - }); - - Ok(promise) -} diff --git a/packages/utils/src/lib.rs b/packages/utils/src/lib.rs index a24f353a..fc9bd13f 100644 --- a/packages/utils/src/lib.rs +++ b/packages/utils/src/lib.rs @@ -1,13 +1,12 @@ pub mod circuit; pub mod converters; pub mod cryptos; -pub mod email_auth; pub mod parse_email; pub mod regex; pub mod statics; +pub use circuit::*; pub(crate) use converters::*; pub(crate) use cryptos::*; -pub use email_auth::*; pub(crate) use neon::prelude::*; pub(crate) use parse_email::*; pub use poseidon_rs::*; diff --git a/packages/utils/src/parse_email.rs b/packages/utils/src/parse_email.rs index 09868031..ef06dc48 100644 --- a/packages/utils/src/parse_email.rs +++ b/packages/utils/src/parse_email.rs @@ -159,17 +159,13 @@ pub fn parse_email_node(mut cx: FunctionContext) -> JsResult { let obj = cx.empty_object(); let canonicalized_header = cx.string(parsed_email.canonicalized_header); obj.set(&mut cx, "canonicalizedHeader", canonicalized_header)?; - // let signed_header = cx.string( - // "0x".to_string() + hex::encode(parsed_email.signed_header).as_str(), - // ); - // obj.set(&mut cx, "signedHeader", signed_header)?; + let signature = cx.string(&signature_str); obj.set(&mut cx, "signature", signature)?; let public_key = cx.string(&public_key_str); obj.set(&mut cx, "publicKey", public_key)?; - // let dkim_domain = cx.string(&parsed_email.dkim_domain); - // obj.set(&mut cx, "dkimDomain", dkim_domain)?; + Ok(obj) } diff --git a/packages/utils/src/regex.rs b/packages/utils/src/regex.rs index 6688f8c7..b9806e3a 100644 --- a/packages/utils/src/regex.rs +++ b/packages/utils/src/regex.rs @@ -1,5 +1,4 @@ use neon::prelude::*; -use neon::prelude::*; pub use zk_regex_apis::extract_substrs::*; pub use zk_regex_apis::padding::*;