Contract Architecture
Core
EmailWalletCore.sol
- The main contract that implements functions likehandleEmailOp
. To keep the contract simple, we have split other functionalities to many "handlers".handlers/RelayerHandler.sol
- Handles operations to register and update Relayer config.handlers/AccountHandler.sol
- Handles account related operations likecreateAccount
,initAccount
,transpotAccount
, and wallet related functions.handlers/UnclaimsHandler.sol
- Handles operations related to Unclaimed Funds and Unclaimed States.handlers/ExtensionHandler.sol
- Handles operations related to publishing and installing Extensions.
Wallet
Wallet.sol
- Wallet contract deployed for each user (account). The owner of the wallet contract can execute any call data on a target. By default Core contract is the owner of the wallet contract.
Interfaces
interfaces/Types.sol
- Contains all the structs used in the contract including EmailOp.interfaces/Commands.sol
- Defines the commands used for EmailOps.interfaces/Events.sol
- Defines all events emitted by the contract.interfaces/IVerifier.sol
- Defines the interface for the ZK proof verifier contract.interfaces/IPriceOracle.sol
- Defines the interface for price oracle used for fee calculation.interfaces/Extension.sol
- Defines the interface for an Extension contract.
Libraries
libraries/SubjectUtils.sol
- Contains helper functions to compute the subject line from an EmailOp.libraries/DecimalUtils.sol
- Contains helper functions to convert uint to decimal string.
Util contracts
utils/TokenRegistry.sol
- TokenRegistry contract that stores the address of ERC20 tokens by their names (and reverse) across multiple chains.utils/UniswapTWAPOracle.sol
- UniswapTWAPOracle contract that provides the TWAP price of a token in ETH.utils/ECDSAOwnedDKIMRegistry.sol
- A custom DKIM registry that allows a ECDSA signer to set the DKIM public key for a domain.
Default extensions
extensions/NFTExtension.sol
- NFT wallet extensions to send NFTs.extensions/UniswapExtension.sol
- Uniswap wallet extension to swap tokens on Uniswap.
Circuit verifiers
verifier/Verifier.sol
- All verifiersverifier/AccountCreationVerifier.sol
- Verifier forAccountCreation
circuit.verifier/AccountInitVerifier.sol
- Verifier forAccountInit
circuit.verifier/EmailSenderVerifier.sol
- Verifier forEmailSender
circuit.verifier/ClaimVerifier.sol
- Verifier forClaim
circuit.verifier/AccountTransportVerifier.sol
- Verifier forAccountTransport
circuit.verifier/AnnouncementVerifier.sol
- Verifier forAnnouncement
circuit.
Tests
tests/*.t.sol
- Contains unit tests for all contracts/functionalities.tests/Integration.t.sol
- Contains all integration tests. Integration tests generate the proof using the circuit and verify it using contracts. Before running those tests, you need to make apackages/contracts/test/build_integration
directory, download the zip file from the following link, and place its unziped files under that directory. https://drive.google.com/file/d/1pe07fwKbtjMLHoQSY8Bcr4rg9aN06mFP/view?usp=sharing
Build and Test
Make sure you have Foundry installed
Build the contracts using the below command.
forge build
Run unit tests
forge test --no-match-test "testIntegration"
Run integration tests Run each integration tests one by one as each test will consume lot of memory.
Eg: forge test --match-test 'testIntegration_Swap_Tokens' -vvv --ffi
Deploy Contracts
You can either deploy all contracts at once or deploy each contract separately.
Deploy all contracts at once
Create .env
cp .env.sample .env
Run
source .env
forge script script/DefaultSetupScript.s.sol:Deploy \
--rpc-url $RPC_URL \
--chain-id $CHAIN_ID \
--broadcast \
-vvvv
Deploy each contract separately
Run the below commands to deploy each contracts. Ensure address of WETH and Uniswap Price oracle on the target chain.
Deploy Token Registry
PRIVATE_KEY="" \
forge script script/01_DeployTokenRegistry.s.sol:Deploy \
-vvvv \
--rpc-url https://ethereum-sepolia.publicnode.com \
--chain-id 11155111 \
--broadcast \
--etherscan-api-key "" \
--verify
Copy the address from log TokenRegistry implementation deployed at: 0x9f44be9F69aF1e049dCeCDb2d9296f36C49Ceafb
Deploy All Verifiers
PRIVATE_KEY="" \
forge script script/02_DeployAllVerifiers.s.sol:Deploy \
-vvvv \
--rpc-url https://ethereum-sepolia.publicnode.com \
--chain-id 11155111 \
--broadcast \
--etherscan-api-key "" \
--verify
Copy the address from log AllVerifiers implementation deployed at: 0x9f44be9F69aF1e049dCeCDb2d9296f36C49Ceafb
Deploy DKIM Registry
PRIVATE_KEY="" \
forge script script/03_DeployDKIMRegistry.s.sol:Deploy \
-vvvv \
--rpc-url https://ethereum-sepolia.publicnode.com \
--chain-id 11155111 \
--broadcast \
--etherscan-api-key "" \
--verify
Copy the address from log DKIMRegistry implementation deployed at: 0xbE66454b0Fa9E6b3D53DC1b0f9D21978bb864531
Deploy Uniswap TWAP Oracle
PRIVATE_KEY="" \
WETH=0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9 \
UNISWAP_FACTORY=0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f \
forge script script/DeployUniswapTWAPOracle.s.sol:Deploy \
-vvvv \
--rpc-url https://ethereum-sepolia.publicnode.com \
--chain-id 11155111 \
--broadcast \
--etherscan-api-key "" \
--verify
Copy the address from log UniswapTWAPOracle deployed at: 0x0000000000000000000000000000000000000000
Deploy Wallet
PRIVATE_KEY="" \
WETH=0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9 \
forge script script/04_DeployWallet.s.sol:Deploy \
-vvvv \
--rpc-url https://ethereum-sepolia.publicnode.com \
--chain-id 11155111 \
--broadcast \
--etherscan-api-key "" \
--verify
Copy the address from log Wallet proxy deployed at: 0x0000000000000000000000000000000000000000
Deploy Handlers
PRIVATE_KEY="" \
WETH=0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9 \
forge script script/05_DeployHandlers.s.sol:Deploy \
-vvvv \
--rpc-url https://ethereum-sepolia.publicnode.com \
--chain-id 11155111 \
--broadcast \
--etherscan-api-key "" \
--verify
Copy the addresses from log
RelayerHandler proxy deployed at: 0x0000000000000000000000000000000000000000
ExtensionHandler proxy deployed at: 0x0000000000000000000000000000000000000000
AccountHandler proxy deployed at: 0x0000000000000000000000000000000000000000
UnclaimsHandler proxy deployed at: 0x0000000000000000000000000000000000000000
Deploy Email Wallet Core
PRIVATE_KEY="" \
WETH=0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9 \
TOKEN_REGISTRY=0x9f44be9F69aF1e049dCeCDb2d9296f36C49Ceafb \
DKIM_REGISTRY=0xbE66454b0Fa9E6b3D53DC1b0f9D21978bb864531 \
PRICE_ORACLE=0xF5f40B12aa15286F0DE5610C4e29d87a97997ee7 \
forge script script/06_DeployEmailWalletCore.s.sol:Deploy \
-vvvv \
--rpc-url https://ethereum-sepolia.publicnode.com \
--chain-id 11155111 \
--broadcast \
--etherscan-api-key "" \
--verify
Copy the addresses from log:
EmailWalletCore proxy deployed at: 0x0000000000000000000000000000000000000000
Deploy Extensions
PRIVATE_KEY="" \
WETH=0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9 \
TOKEN_REGISTRY=0x9f44be9F69aF1e049dCeCDb2d9296f36C49Ceafb \
DKIM_REGISTRY=0xbE66454b0Fa9E6b3D53DC1b0f9D21978bb864531 \
PRICE_ORACLE=0xF5f40B12aa15286F0DE5610C4e29d87a97997ee7 \
forge script script/07_SetDefaultExtensions.s.sol:Deploy \
-vvvv \
--rpc-url https://ethereum-sepolia.publicnode.com \
--chain-id 11155111 \
--broadcast \
--etherscan-api-key "" \
--verify
Copy the addresses from log:
NFTExtension proxy deployed at: 0x0000000000000000000000000000000000000000
UniswapExtension proxy deployed at: 0x0000000000000000000000000000000000000000
Deploy ECDSAOwnedDKIMRegistry
Set the SIGNER
to the address of the Ethereum wallet who will be setting the DKIM public key for a domain.
PRIVATE_KEY="" \
SIGNER=0x2f6e79a6e1a982a49ca248b70b02f76e921af400 \
forge script script/DeployECDSAOwnedDKIMRegistry.s.sol:Deploy \
-vvvv \
--rpc-url https://ethereum-sepolia.publicnode.com \
--chain-id 11155111 \
--broadcast \
--etherscan-api-key "S7RWR1ENYB73HZY7WTV3EER7U8CQNBBTAJ" \
--verify
Copy the address from log ECDSAOwnedDKIMRegistry deployed at: 0xB50a02E2Da524feC1209542985b2ae2917aF7265
Upgrade Contracts
Upgrade Token Registry
Run
TOKEN_REGISTRY=0xF1d24E5f7f0Ca617F0c1f3AA34A77EcFfaFedE8f \
PRIVATE_KEY=0x00 \
forge script script/XX_UpgradeTokenRegistry.s.sol:Deploy \
--rpc-url https://ethereum-sepolia.publicnode.com \
--chain-id 11155111 \
--broadcast \
-vvvv