Skip to content

Commit

Permalink
feat: code imports and webauthn demo app
Browse files Browse the repository at this point in the history
  • Loading branch information
sarahschwartz committed Sep 5, 2024
1 parent 0e19659 commit d050160
Show file tree
Hide file tree
Showing 42 changed files with 13,790 additions and 1 deletion.
96 changes: 96 additions & 0 deletions code/webauthn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Sign Transactions With Webauthn Example

Note: this code is not secure. It is just intended as a proof of concept to demonstrate how signing transactions using secp256r1 signatures is possible.

This demo requires Google Chrome and a device that supports webauthn.

## Running Locally

### Install Dependencies

Run `npm install` in both the `frontend` and `contracts` folders.
Node version 20 is required.

### Start a local node

Run a local in-memory node with `era_test_node`:

```shell
era_test_node run
```

### Deploying a New Smart Account

Create a `.env` file and add a testing private key for deployment and a testing wallet to receive funds from the smart account.
The private key and receiver account in the example below are both listed in the rich wallets list: https://docs.zksync.io/build/test-and-debug/in-memory-node#pre-configured-rich-wallets

```env
WALLET_PRIVATE_KEY=0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110
RECEIVER_ACCOUNT=0xa61464658AfeAf65CccaaFD3a512b69A83B77618
```

Compile and deploy a new smart account using the `compile` and `transfer` scripts:

```shell
cd contracts
npm run compile
npm run transfer
```

From the logged output of the `transfer` script, copy the account address after "SC Account deployed on address" and save it to your `.env` file:

```env
ACCOUNT_ADDRESS=0x...
```

You'll come back to this later.

### Registering a Webauthn Key

Go to the frontend folder and start a development server:

```shell
npm run dev
```

Open the app at `http://localhost:3000` and click the 'Register Account' button to navigate to the `/register` page.
Enter a name for your passkey, and click the `Register New Passkey` button.

Note: it's important that you don't use another port. This step depends on the app running at port `3000`.

Once you see the message `Registered public key! Click me to copy.`, click it and add the private key to the `.env` in the `contracts` folder.

```env
NEW_R1_OWNER_PUBLIC_KEY=0x...
```

Your final `.env` file should look like this:

```env
WALLET_PRIVATE_KEY=0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110
RECEIVER_ACCOUNT=0xa61464658AfeAf65CccaaFD3a512b69A83B77618
ACCOUNT_ADDRESS=0x<YOUR_ACCOUNT_ADDRESS_HERE>
NEW_R1_OWNER_PUBLIC_KEY=0x<YOUR_PUB_KEY_HERE>
```

### Adding the Registered Key to Your Smart Contract Account

Back in the `contracts` folder, run the `register` script to register the public key as a signer.

```shell
npm run register
```

The output should say `R1 Owner updated successfully`.

### Sending a Txn with Webauthn

In the `frontend` folder inside `src/pages/transfer.tsx`, update the `ACCOUNT_ADDRESS` variable with your deployed account address
(same as the `ACCOUNT_ADDRESS` variable in the `contracts/.env` file).

Go back to the home page of the frontend app running at `http://localhost:3000/` and click the `Transfer Funds` link.
Enter any amount into the input and try transfering the ETH.

### Managing Registered Passkeys

You can delete and edit your registered keys in Google Chrome by going to `chrome://settings/passkeys`.
4 changes: 4 additions & 0 deletions code/webauthn/contracts/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
WALLET_PRIVATE_KEY=
RECEIVER_ACCOUNT=
ACCOUNT_ADDRESS=
NEW_R1_OWNER_PUBLIC_KEY=
117 changes: 117 additions & 0 deletions code/webauthn/contracts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.vscode

# hardhat artifacts
artifacts
cache

# zksync artifacts
artifacts-zk
cache-zk

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# Next.js build output
.next

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# other
deploy-outputs.txt
deployments-zk
1 change: 1 addition & 0 deletions code/webauthn/contracts/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
legacy-peer-deps=true
21 changes: 21 additions & 0 deletions code/webauthn/contracts/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 Matter Labs

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.
39 changes: 39 additions & 0 deletions code/webauthn/contracts/contracts/AAFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import "@matterlabs/zksync-contracts/l2/system-contracts/Constants.sol";
import "@matterlabs/zksync-contracts/l2/system-contracts/libraries/SystemContractsCaller.sol";

contract AAFactory {
bytes32 public aaBytecodeHash;

constructor(bytes32 _aaBytecodeHash) {
aaBytecodeHash = _aaBytecodeHash;
}

function deployAccount(
bytes32 salt,
address owner
) external returns (address accountAddress) {
(bool success, bytes memory returnData) = SystemContractsCaller
.systemCallWithReturndata(
uint32(gasleft()),
address(DEPLOYER_SYSTEM_CONTRACT),
uint128(0),
abi.encodeCall(
DEPLOYER_SYSTEM_CONTRACT.create2Account,
(
salt,
aaBytecodeHash,
abi.encode(owner),
IContractDeployer.AccountAbstractionVersion.Version1
)
)
);
require(success, "Deployment failed");

(accountAddress) = abi.decode(returnData, (address));
}
}


Loading

0 comments on commit d050160

Please sign in to comment.