Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
luckyyang committed Mar 10, 2024
0 parents commit 9927360
Show file tree
Hide file tree
Showing 75 changed files with 32,068 additions and 0 deletions.
93 changes: 93 additions & 0 deletions .github/workflows/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: Proof of Twitter tests
on: [push]
env:
VITE_CONTRACT_ADDRESS: ${{ vars.VITE_CONTRACT_ADDRESS }}
VITE_CIRCUIT_ARTIFACTS_URL: ${{ vars.VITE_CIRCUIT_ARTIFACTS_URL }}
jobs:
run_circuit_tests:
runs-on: ubuntu-latest
environment: development
steps:
- uses: actions/checkout@v3

# Circom installation from https://github.com/erhant/circomkit/blob/main/.github/workflows/tests.yml
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install --yes \
build-essential \
libgmp-dev \
libsodium-dev \
nasm \
nlohmann-json3-dev
- name: Set Node.js 18.x
uses: actions/setup-node@v3
with:
node-version: 18

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable

- name: Download Circom Binary v2.1.5
run: |
wget -qO /home/runner/work/circom https://github.com/iden3/circom/releases/download/v2.1.5/circom-linux-amd64
chmod +x /home/runner/work/circom
sudo mv /home/runner/work/circom /bin/circom
- name: Print Circom version
run: circom --version

- name: Install Yarn dependencies
working-directory: ./packages/circuits
run: yarn install --immutable

- name: Run Tests
working-directory: ./packages/circuits
run: yarn test

run_contract_tests:
runs-on: ubuntu-latest
environment: development
steps:
- uses: actions/checkout@v3
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 16
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
- name: Install Yarn dependencies
working-directory: ./packages/contracts
run: yarn install --immutable
- name: Run Tests
run: forge test --root ./packages/contracts --fork-url https://eth-goerli.g.alchemy.com/v2/${{secrets.ALCHEMY_API_KEY}}

run_app_unit_and_e2e_tests:
runs-on: ubuntu-latest
environment: development
steps:
- uses: actions/checkout@v3
- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 16
cache: 'yarn'
env:
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 'true'
- name: Install Yarn dependencies
working-directory: ./packages/app
run: yarn install
- name: Run test
working-directory: ./packages/app
run: yarn test
- name: Run build
working-directory: ./packages/app
run: yarn build
- name: E2E Test Code
uses: mujo-code/[email protected]
env:
CI: "true"
with:
args: yarn workspace @zk-email/twitter-verifier-app test:full-e2e

74 changes: 74 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
#
#

dist

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage
junit.xml

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

*.r1cs
*.sym
*.ptau
*.zkey

.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

packages/circuits/proofs/
out/
circuits/circuit*zkey*
circuits/email/
cache/
test.log
packages/contracts/out/
packages/contracts/lib/
packages/contracts/broadcast
.next
node_modules.nosync
*Wallet*
*wallet*
circuits/regexes/subject_regex*

*_email.txt
*email_cache.json
*input.json
*email_proof.json
*.debug
*.env
.vscode

.vite
**/.vite

tsbuildinfo

**/node_modules
**/build
**/dist
tsconfig.tsbuildinfo
783 changes: 783 additions & 0 deletions .yarn/releases/yarn-3.2.3.cjs

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-3.2.3.cjs
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 zk-email

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
156 changes: 156 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Proof of Twitter

Prove ownership of a X (Twitter) account using an email from Twitter, and mint an NFT with your Twitter username.

This project is a demonstration of ZK Email. You can fork it to build other projects using ZK Email.

Try it here: https://twitter.prove.email/

## How it works

You can use an email from Twitter that contains `email was meant for @username` to generate a ZK proof that you own the Twitter account `@username`.

This ZK proof can be used to mint an NFT corresponding to your username in the `ProofOfTwitter` contract.

## Running locally

#### Install dependencies

```bash
yarn
```

#### Start the web app. In `packages/app` directory, run

```bash
yarn start
```

This will start the UI at `http://localhost:3000/` where you can paste the email, generate proof and mint the NFT.

The UI works against the generated zkeys downloaded from AWS and the deployed contract on Sepolia.

## Manual Proof Generation

If you want to generate the proof locally outside browser, follow the instructions below.

### Circuits

Circom circuits are located in `packages/circuits`, the main circuit being [twitter.circom](packages/circuits/twitter.circom). TwitterVerifier circuit use [EmailVerifier](https://github.com/zkemail/zk-email-verify/blob/main/packages/circuits/email-verifier.circom) circuit from `@zk-email/circuits`.

The regex circuit required to parse/extract Twitter username can be generated using [https://github.com/zkemail/zk-regex](zk-regex) package.

#### » Generate Twitter Regex Circuit

```bash
# CWD = packages/circuits
yarn generate-regex
```

This will generate `components/twitter_reset.circom` using the config in `components/twitter_reset.json`. This `twitter_reset.circom` is imported in `twitter.circom`.

Note that `twitter_reset.circom` is already in repo, so this step is optional.

#### » Build the circuit

```bash
# CWD = packages/circuits
yarn build
```

This will create `twitter.wasm` and other files in `packages/circuits/build` directory.

You can test the circuit using

```bash
# CWD = packages/circuits
yarn test
```

#### » Generating Zkey

You can generate proving and verification keys using

```bash
# 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 regular `snarkjs` in `package.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.
```bash
python3 upload_to_s3.py --build-dir <project-path>/proof-of-twitter/packages/circuits/build --circuit-name twitter
```

There are helper functions in `@zk-email/helpers` package to download and decompress the zkeys in the browser.


#### » Generate Input and Proof

```bash
# CWD = packages/circuits/scripts
ts-node generate-proof.ts --email-file ../tests/emls/test_twitter.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.

### Contracts

The solidity contracts can be found in `packages/contracts`. The main contract is [ProofOfTwitter.sol](packages/contracts/src/ProofOfTwitter.sol).

#### You can build the contracts using

```bash
# CWD = packages/contracts
yarn build # Assume you have foundry installed
```

#### Run tests

```bash
# CWD = packages/contracts
yarn test
```

Note that the tests will not pass if you have generated your own zkeys and `Verifier.sol` as you would have used a different Entropy.

To fix, update the `publicSignals` and `proof` in `test/TestTwitter.t.sol` with the values from `input.json` and `public.json` generated from the above steps. (Remember that you need to flip items in the nested array of `pi_b`).

#### Deploy contracts

```bash
# CWD = packages/contracts
PRIVATE_KEY=<pk-hex> forge script script/DeployTwitter.s.sol:Deploy -vvvv --rpc-url https://rpc2.sepolia.org --broadcast
```

Currently deployed contracts on Sepolia:

```
Deployed Verifier at address: 0x6096601EB33d636b0e21593469920d06647FA955
Deployed DKIMRegistry at address: 0x993873c1b46c756b60089cBbE3baEEC9Fa292e9f
Deployed ProofOfTwitter at address: 0x86D390fDed54447fD244eD0718dbFCFCcbbA7edc
```

### UI

If you want to update the UI based on your own zkeys and contracts, please make the below changes:

- Set the `VITE_CONTRACT_ADDRESS` in `packages/app/.env`. This is the address of the `ProofOfTwitter` contract.
- Set `VITE_CIRCUIT_ARTIFACTS_URL` in `packages/app/.env` to the URL of the directory containing circuit artifacts (compressed partial zkeys, wasm, verifier, etc). You can run a local server in `circuits/build/artifacts` directory and use that URL or upload to S3 (or similar) and use that public URL/


## History

This repo was originally part of the [zk-email-verify](https://github.com/zkemail/zk-email-verify). Please refer there for the commit history and original contributors.
13 changes: 13 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "@zk-email/proof-of-twitter",
"version": "1.0.0",
"description": "Proof of twitter username using ZK Email",
"private": true,
"workspaces": [
"packages/*"
],
"keywords": [],
"author": "",
"license": "MIT",
"packageManager": "[email protected]"
}
19 changes: 19 additions & 0 deletions packages/app/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module.exports = {
plugins: [
function () {
return {
visitor: {
MetaProperty(path) {
path.replaceWithSourceString('process')
},
},
}
},
],
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-typescript',
['@babel/preset-react', { "runtime": "automatic" }],
['jest'],
],
};
Loading

0 comments on commit 9927360

Please sign in to comment.