Quickstart
In this section, we will show you how to create a simple project using the Email Transaction Builder and the EmitEmailCommand.sol
contract. You will learn how to set up the project, deploy the contracts, calling the Generic Relayer API and broadcasting the transaction to the network to execute commands via email.
Create a Project
We have provided a GitHub template that includes all necessary components, including the EmitEmailCommand.sol
contract, deployment scripts and a .env.example
file. This template allows you to get started using the Generic Relayer quickly without deploying contracts yourself.
You can either fork the template repository or clone it:
git clone https://github.com/zkemail/email-tx-builder-template.git
cd email-tx-builder-template
Project Overview
Your new project will include the following structure:
.
├── contracts
└── ts
- contracts: Contains a foundry project for the
EmitEmailCommand.sol
contract, including a deployment script. - ts: Contains a TypeScript CLI to interact with the Generic Relayer API.
The EmitEmailCommand
contract implements five command templates, each corresponding to a different type matcher. These templates are used to emit events based on commands received via email. Here's a breakdown of how it works:
The contract defines five command templates, each associated with a specific type matcher:
- String Matcher: Emits a
StringCommand
event. - Uint Matcher: Emits a
UintCommand
event. - Int Matcher: Emits an
IntCommand
event. - Decimals Matcher: Emits a
DecimalsCommand
event. - EthAddr Matcher: Emits an
EthAddrCommand
event.
Each template is represented as an array of strings, specifying the command format. You can learn more about the command format in the Command Templates section.
Build and Deploy
The Email Transaction Builder requires several smart contracts working together to enable secure email-based transactions:
EmitEmailCommand.sol
: Our main example contract that processes email commands and emits eventsEmailAuth.sol
: Handles the core authentication flow, verifying that emails came from authorized usersUserOverrideableDKIMRegistry.sol
: Maintains a registry of email domain public keys (DKIM keys) used to verify email authenticity.Verifier.sol
andGroth16Verifier.sol
: Zero-knowledge proof verifiers that cryptographically prove an email is authentic without revealing its contents.
In this guide we will deploy the EmitEmailCommand.sol
contract using the script provided in the template, but you can use a update this script to deploy your own contract.
Set Up Environment Variables
The first step is to navigate to the contracts folder and copy the example environment file:
cd contracts
cp .env.example .env
source .env
You have to edit the .env
file and set the following variables:
- PRIVATE_KEY: Your private key for deployment (include the
0x
prefix). - CHAIN_ID: Chain ID of the target network.
- RPC_URL: RPC URL for the target network.
- SIGNER: Signer for the DKIM Oracle that can update the DKIM registry.
- ETHERSCAN_API_KEY: (Optional) Etherscan API key for contract verification.
Deploy the Contracts
After you finish setting up the environment variables, you need to install the dependencies:
yarn
If you find any issues with the dependencies, you can clear your yarn cache and try again:
yarn cache clean
Then, you can deploy the contracts:
forge script script/DeployEmitEmailCommand.s.sol:Deploy --fork-url $RPC_URL --broadcast -vvvv --legacy
Calling the Generic Relayer API
To call the Generic Relayer we are going to use the TypeScript CLI, if you want to learn more about the Generic Relayer you can check the Generic Relayer section. After deploying the contracts, you can use the TypeScript CLI to test different command templates.
First, navigate to the ts
directory and install dependencies:
cd ts
yarn install
Copy the .env.example
file to .env
and set the required variables:
cp .env.example .env
- PRIVATE_KEY: Your private key for deployment (include the
0x
prefix). - RELAYER_URL: URL of the Generic Relayer API (
https://relayer.zkemail.xyz/api
).
Then you can use the following examples to test each command template. After you call the CLI, you will receive an email that you need to reply to confirm the command and after the relayer verifies the email, it will return the EmailAuthMsg
used to broadcast the transaction.
Example Commands
Before running any of the example commands below, make sure to replace the following fields with your own values:
- YOUR_CONTRACT_ADDRESS: An Ethereum address of the
EmitEmailCommand
command. - YOUR_ACCOUNT_CODE: Your account code (a random hex number in the BN254 elliptic curve used to derive your account salt)
- YOUR_EMAIL: The email address you want to use to send commands
- YOUR_WALLET_ADDRESS: Ethereum address of the owner EOA/contract of your
EmailAuth
contract.
Example
This EmitEmailCommand contract is deployed on Base Sepolia:
- YOUR_CONTRACT_ADDRESS: 0xa49600b17f2978AEaE9477836Ade18CAfD95A3de
- YOUR_ACCOUNT_CODE: 0x22a2d51a892f866cf3c6cc4e138ba87a8a5059a1d80dea5b8ee8232034a105b7
- YOUR_EMAIL: youremail@example.com
- YOUR_WALLET_ADDRESS: 0x6e8CdBE9CB9A90F75Fe4D5B2F08B9181b04f4Ea9
String Type Matcher
This command will emit a StringCommand
event.
npx ts-node src/cli.ts \
--emit-email-command-addr YOUR_CONTRACT_ADDRESS \
--account-code YOUR_ACCOUNT_CODE \
--email-addr YOUR_EMAIL \
--owner-addr YOUR_WALLET_ADDRESS \
--template-idx 0 \
--command-value "hello" \
--subject "Emit a string" \
--body "Emit a string"
Uint Type Matcher
This command will emit a UintCommand
event.
npx ts-node src/cli.ts \
--emit-email-command-addr YOUR_CONTRACT_ADDRESS \
--account-code YOUR_ACCOUNT_CODE \
--email-addr YOUR_EMAIL \
--owner-addr YOUR_WALLET_ADDRESS \
--template-idx 1 \
--command-value "123" \
--subject "Emit a uint" \
--body "Emit a uint"
Int Type Matcher
This command will emit an IntCommand
event.
npx ts-node src/cli.ts \
--emit-email-command-addr YOUR_CONTRACT_ADDRESS \
--account-code YOUR_ACCOUNT_CODE \
--email-addr YOUR_EMAIL \
--owner-addr YOUR_WALLET_ADDRESS \
--template-idx 2 \
--command-value "-123" \
--subject "Emit an int" \
--body "Emit an int"
Decimals Type Matcher
This command will emit a DecimalsCommand
event.
npx ts-node src/cli.ts \
--emit-email-command-addr YOUR_CONTRACT_ADDRESS \
--account-code YOUR_ACCOUNT_CODE \
--email-addr YOUR_EMAIL \
--owner-addr YOUR_WALLET_ADDRESS \
--template-idx 3 \
--command-value "1.23" \
--subject "Emit a decimal" \
--body "Emit a decimal"
EthAddr Type Matcher
This command will emit an EthAddrCommand
event.
npx ts-node src/cli.ts \
--emit-email-command-addr YOUR_CONTRACT_ADDRESS \
--account-code YOUR_ACCOUNT_CODE \
--email-addr YOUR_EMAIL \
--owner-addr YOUR_WALLET_ADDRESS \
--template-idx 4 \
--command-value "0x6956856464EaA434f22B42642e9089fF8e5C9cE9" \
--subject "Emit an address" \
--body "Emit an address"