# RSA GitHub Wallets POC - Milestone 1
## Background Research
The background research is done for 3 items
1. Email wallet project: overall architecture
1. GitHub commit: how to obtain the commit message + signature and pass to Relayer
1. Account Abstraction: overall setup and communication interface
### Email-wallet project
- https://github.com/zkemail/email-wallet
- Architecture - this project will apply a similar architecture of email-wallet. with the following modifications
![image](https://hackmd.io/_uploads/BJMWGK-xA.png)
- SMTP Server: This component will be replaced with Github Actions to send the commit information to relayer
- Contracts: This component will be replaced with account abstraction interface.
- In the smart contract account, the `_validateSignature`([ref](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/core/BaseAccount.sol#L56-L73)) needs to be implemented to verify the zk-poof.
- Relayer will construct the `PackedUserOperation`([ref](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/interfaces/PackedUserOperation.sol)) struct consumed by the account, and call the bundler RPC endpoint.
- Prover and Relayer:
- For the circuits will explore for both using circom or halo2
- circom
- Will apply the similar architecture of zk-email-wallet with separate relayer, prover.
- Need to modify the circom circuits from proving email signature to commit signature
- halo2
- Can explore the possiblity of using halo2 to build the circuit. Modify from the exiting work of [halo2-zk-email](https://github.com/zkemail/halo2-zk-email/tree/main)
- Explore the possibility to run the proof generation inside the Github Actions, or find a way to involve browser in the process of making commits and generate proof from there, or build some git hook to generate proof in local terminal when commits are made.
- Relayer: Process the commit information and communicate with the Prover to get the proof, and then call bundler RPC endpoint to execute the transaction.
- Database: Same as email-wallet, storing the account information
### Github commit signature
- Requirements: Relayer needs to receive the following info for verification and trigger the action
- commit message
- commit signature
- public key
- GPG key
- GPG key essentially is an open standard that wraps around the core cryptographic key pair with other metadata such as expiry time, identity verification, etc, to guard the usage of the core key pair.
- For this project, the circuit will be focusing on verifying the signature of the core key pair with RSA.
- Following research describe the tools to use
- GitHub user can setup GPG keys to sign on commits. ([ref](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification#about-commit-signature-verification))
- GitHub Actions can be configured to be triggered on "push" event for speficied branch: ([ref](https://docs.github.com/en/webhooks/webhook-events-and-payloads#push))
- Unfortunately in the `context` object that GitHub Actions can access, it doesn't contain the information of commit message and signature ([ref](https://docs.github.com/en/actions/learn-github-actions/contexts#github-context))
- Alternatively, it can call REST API to fetch the commit message and signature. User will need to configure the API key in the GitHub Action secret env variables. ([ref]( https://docs.github.com/en/rest/commits/commits?apiVersion=2022-11-28#get-a-commit))
- Another REST API to get public key of corresponding GPG key. This is only needed for the first time when the account is created. The public key should be stored and retrieved from the Relayer. ([ref](https://docs.github.com/en/rest/users/gpg-keys?apiVersion=2022-11-28))
- Github commit signature structure
- The commit object being signed contains info of tree, author, commiter, and message. ([ref](https://github.com/git/git/blob/ae3196a5ea84a9e88991d576020cf66512487088/commit.c#L1647-L1688)). When the circuit process the signature, it needs to identify the location of the commit message in the encoding.
### Account Abstraction with Stackup:
- Follow [the steps](https://docs.stackup.sh/docs/get-started-with-stackup) in their docs to configure the AA setup, with modifications below
- The the tutorial [example](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol#L104-L111) it uses simple ECDSA recover to validat the user operation. In this project, it will change it to zero-knowledge proof verification.
- The calldata and ZKP will be constructed in Relayer. Might need to modify [Stackup SDK](https://docs.stackup.sh/docs/get-started-with-stackup#%E2%91%A6-build-and-send-the-user-operation) for sending the userOp.
## System Design and Specification
- Features
- For simplicity, the project start with supporting only the operaiton of sending ETH.
- User can make the following GitHub commit to send ETH to an Githubu wallet user or Ethereum addresses.
```
Send 1 ETH to some_github_username
Send 2.5 ETH to 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
```
### Workflow overview
![Github wallet POC architecture](https://hackmd.io/_uploads/rJo7BC7gR.jpg)
This version of design is based on the circom version. At later stage during the exploration of halo2, I will seek for possiblity to remove the component of Prover and generate the proof in GitHub repo (GitHub Actions, local command line as git hook, or involve browser in the commit process)
- Initial setup
1. Prepare the repository and set up the GitHub Actions pipeline. Put the secrets of API key with "read" access to the repo.
1. The pipeline should be configured that it is triggered when there's a commit. It use the API key to fetch the commit info and send it to Relayer with a http call.
- Create account
1. User make a commit with message `Create Account with CODE:0xababab11 GPG_KEY_ID:3262EFF25BA0D270`. The GitHub Actions will send the GitHub username, signature and the message to the Relayer
- The part after `CODE:` is the Account Key. The Account Key would serve as the salt for account creation to for deterministic account address.
- The part after `GPG_KEY_ID:` is for fetching the public key associated with the commit sign key.
1. Relayer registers and maintains the mapping between github username and account key.
1. Relayer sends the request to account abstraction endpoint for account creation with the [salt](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccountFactory.sol#L28).
1. Relayer registers a new account for a user with a commitment like `hash(githubUsername, accountKey)`. Relayer uses this commitment to prove that the commit came from the same user later, when the user sends an commit with an operation. i.e. this commitment is an output of the circuit that generates proof of commit from the user for an operation. See `AccountKeyCommitment` in Account nullifier below.
- Execute transaction
1. User makes a commit with message `Send 1 ETH to some_github_username`. GitHub Actions will send the GitHub username, signature and the message to the Relayer.
1. Relayer parses the commit message and call Prover to generate proof of the commmit.
1. Relayer sends request to Account Abstraction endpoint to execute the operation.
### Specification/success criteria for each module
- GitHub Actions
- detect the commit activity, fetch the commit information and call an external http about about the commit data.
- Needed commit information: commit message, commit signature, GPG public key of the commit sign key (only needed during account creation).
- Relayer
- Handle account creation request from GitHub Actions.
- Create a record in the database
- Get the proof for commit message from Prover
- Call the RPC endpoint for correct account creation with correct payload
- Reject if the account has already been created
- Handle transaction execution
- Verify that account has been created
- Get the proof for commit message from Prover
- Call the RPC endpoint for correct account creation with correct payload
- Prover
- The circuits would be similar to the email-wallet circuits with the changes that it would be verifying the commit message instead of email.
- account creation circuit (ref: [account_creation.circom](https://github.com/zkemail/email-wallet/blob/main/packages/circuits/README.md#account_creationcircom))
- account init circuit (ref: [account_init.circom](https://github.com/zkemail/email-wallet/blob/main/packages/circuits/README.md#account_initcircom))
- account operation circuit (ref: [email_sender.circom](https://github.com/zkemail/email-wallet/blob/main/packages/circuits/README.md#email_sendercircom))
-
- Account Abstraction
- Handle the request from Relayer and execute the transaction on-chain
- The smart contracts should verify the proof generated by Prover
- employ the similar account nullifier mechanism (ref: [Saleel's blog](https://saleel.xyz/blog/email-wallet/))