Welcome to Hedwig. Hedwig allows you to generate client-side zero-knowledge proofs proving you have received some email and mask out any private data, without trusting a server to maintain a zk-oracle onchain.
Maintain BTC price feed using newsletter email from provider like Mail Brew.
This is build on top of ZK Email.
You can use an email from Mail brew BTC price XXK
to generate a ZK proof that the data is from a valid source along with that price data.
This ZK proof is then checked in contract and once verified, the price data will be updated.
yarn
yarn start
This will start the UI at http://localhost:3000/
where you can paste the email, generate proof and update BTC price.
The UI works against the generated zkeys downloaded from local or AWS you specified and the deployed contract on Sepolia.
If you want to generate the proof locally outside browser, follow the instructions below.
Circom circuits are located in packages/circuits
, the main circuit being oracle.circom. OracleVerifier circuit use EmailVerifier circuit from @zk-email/circuits
.
The regex circuit required to parse/extract BTC price can be generated using https://github.com/zkemail/zk-regex package.
# CWD = packages/circuits
yarn generate-regex
This will generate components/oracle-regex.circom
using the config in components/oracle-regex.json
. This oracle-regex.circom
is imported in oracle.circom
.
Note that oracle-regex.circom
is already in repo, so this step is optional.
# CWD = packages/circuits
yarn build
This will create oracle.wasm
and other files in packages/circuits/build
directory.
You can test the circuit using
# CWD = packages/circuits
yarn test
You can generate proving and verification keys using
# CWD = packages/circuits/scripts
ZKEY_ENTROPY=<random-number> ZKEY_BEACON=<random-hex> ts-node dev-setup.ts
This will generate zkey
files, vkey.json
in build
directory, and Solidity verifier in packages/contracts/src/Verifier.sol
.
Note: We are using a custom fork of
snarkjs
which generated chunked zkeys. Chunked zkeys make it easier to use in browser, especially since we have large circuit. You can switch to regularsnarkjs
inpackage.json
if you don't want to use chunked zkeys.
For browser use, the script also compresses the chunked zkeys.
**The compressed zkeys, vkey, wasm are copied to /build/artifacts` directory. This directory can be served using a local server or uploaded to S3 for use in the browser.
To upload to S3, the below script can be used.
python3 upload_to_s3.py --build-dir <project-path>/hedwig/packages/circuits/build --circuit-name oracle
There are helper functions in @zk-email/helpers
package to download and decompress the zkeys in the browser.
# CWD = packages/circuits/scripts
ts-node generate-proof.ts --email-file ../tests/emls/test_oracle.eml --ethereum-address <your-eth-address>
This will generate input + witness using the given email file and Ethereum address, and prove using the generated zkey.
The script will save inputs.json
, input.wtns
, proof.json
, and public.json
in proof
directory.
The script also verify the generated proof are correct. You can use the proof and public inputs to verify in the Solidity verifier as well.
The solidity contracts can be found in packages/contracts
. The main contract is SimpleOracle.sol.
# CWD = packages/contracts
yarn build # Assume you have foundry installed
# CWD = packages/contracts
PRIVATE_KEY=<pk-hex> forge script script/DeployOracle.s.sol:Deploy -vvvv --rpc-url https://rpc2.sepolia.org --broadcast
Currently deployed contracts on Sepolia:
Deployed SimpleOracle at address:
0x4370da73a076563448CAd69bD11437fa0814713a # Etherum Sepolia
0xB74C6Eaf47ed115Ac175872a35140c5590737D95 # Avalanche
0xB74C6Eaf47ed115Ac175872a35140c5590737D95 # Flare Coston2
0xB74C6Eaf47ed115Ac175872a35140c5590737D95 # Solana neon evm devnet
If you want to update the UI based on your own zkeys and contracts, please make the below changes:
- Set the
VITE_CONTRACT_ADDRESS
inpackages/app/.env
. This is the address of theSimpleOracle
contract. - Set
VITE_CIRCUIT_ARTIFACTS_URL
inpackages/app/.env
to the URL of the directory containing circuit artifacts (compressed partial zkeys, wasm, verifier, etc). You can run a local server incircuits/build/artifacts
directory and use that URL or upload to S3 (or similar) and use that public URL/