From a0ccac332a37e3e83dda28c7c75755f760970f3b Mon Sep 17 00:00:00 2001 From: Sarah Schwartz <58856580+sarahschwartz@users.noreply.github.com> Date: Fri, 13 Sep 2024 12:33:16 -0600 Subject: [PATCH] docs: cleanup webauthn tutorial --- .../10.index.md | 10 +++- .../20.building-the-contracts.md | 56 +++++++++++-------- .../30.building-the-frontend.md | 8 ++- .../40.completing-the-frontend.md | 4 +- 4 files changed, 48 insertions(+), 30 deletions(-) diff --git a/content/tutorials/signing-transactions-with-webauthn/10.index.md b/content/tutorials/signing-transactions-with-webauthn/10.index.md index fb248b23..78f4aadd 100644 --- a/content/tutorials/signing-transactions-with-webauthn/10.index.md +++ b/content/tutorials/signing-transactions-with-webauthn/10.index.md @@ -33,6 +33,10 @@ To break this down, the app will allow users to: You can find the completed code inside the [Community Code repo](https://github.com/zkSync-Community-Hub/community-code/code/webauthn). +::callout{icon="i-heroicons-heart"} +Special thanks to the [Clave](https://github.com/getclave) team for helping with this example. +:: + ## Introduction to WebAuthn WebAuthn, short for Web Authentication API, is an API built-in to your browser that allows your app to register and authenticate users. @@ -44,9 +48,9 @@ including using biometric data (such as Apple's TouchID) or portable hardware de There are two steps, or "ceremonies", for using WebAuthn: registration and authentication. 1. The first step, registration, is when the user creates a new key pair specific to the application they are using. -2. The second step, authentication, is used to send a challenge for WebAuthn to sign, and receive a signature in return. +2. The second step, authentication, is used to send a challenge to WebAuthn to sign using that key pair, and receive a signature in return. -In the frontend section, you will see in detail what these ceremonies look like. +In the frontend section, you will see in more detail what these ceremonies look like. ### Signatures @@ -56,4 +60,4 @@ WebAuthn uses the secp256r1 elliptic curve for signing, while standard accounts Without a helper function to handle verifying secp256r1 signatures, it can be really difficult to integrate a smart account with WebAuthn. Luckily, we can utilize the `P256Verify` precompile to verify that a given WebAuthn signature matches a known public key. -In the next section, we will create the contracts for the demo app. +In the next section, we will create the contracts for the app. diff --git a/content/tutorials/signing-transactions-with-webauthn/20.building-the-contracts.md b/content/tutorials/signing-transactions-with-webauthn/20.building-the-contracts.md index c463ef5b..63f0c24a 100644 --- a/content/tutorials/signing-transactions-with-webauthn/20.building-the-contracts.md +++ b/content/tutorials/signing-transactions-with-webauthn/20.building-the-contracts.md @@ -19,17 +19,25 @@ We can start by creating the contracts for the smart account, paymaster, and NFT zksync-cli create contracts --template hardhat_solidity --project contracts ``` -Enter the private key for a pre-configured rich wallet: +The CLI will prompt you to enter a private key for deploying. +Enter the private key below for a pre-configured rich wallet: ```shell ? Private key of the wallet responsible for deploying contracts (optional) 0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110 ``` -Once that is done, move into the `contracts` folders and delete the template contracts, scripts, and tests: +Once that is done, move into the `contracts` folders and +install the dependency below: ```shell cd contracts +npm install -D @matterlabs/hardhat-zksync-deploy@1.3.0 +``` + +Then, delete the template contracts, scripts, and tests: + +```shell rm -rf ./contracts/* rm -rf ./deploy/* rm -rf ./test/* @@ -68,7 +76,7 @@ This is a basic paymaster contract that allows us to sponsor transactions for us ### NFT Contract -Create a file in the `contracts/contracts` folder called `MyNFT.sol`. +Create another file in the `contracts/contracts` folder called `MyNFT.sol`. ```shell touch contracts/MyNFT.sol @@ -129,9 +137,7 @@ The smart account contract is where we perform the WebAuthn signature validation ### Understanding WebAuthn Signature Validation -The smart contract account implements a way to validate signatures created with WebAuthn. - -The `_validateTransaction` function first checks to see if there is a valid secp256k1 signature from the account owner, +In the `Account.sol` contract, the `_validateTransaction` function checks to see if there is a valid secp256k1 signature from the account owner, just like the example in the [Native AA Multisig](https://code.zksync.io/tutorials/native-aa-multisig) tutorial. If the transaction is not signed by the standard account owner, the next check is to see if the transaction contains a valid WebAuthn signature. @@ -139,7 +145,7 @@ If the transaction is not signed by the standard account owner, the next check i :code-import{filePath="webauthn/contracts/contracts/Account.sol:_validateTransaction"} ``` -The contract contains a state variable `r1Owner` to store the public key of the WebAuthn account that the owner wants to use. +The contract contains a state variable `r1Owner` to store the public key of the WebAuthn account that the owner wants to authorize. The `updateR1Owner` function can update the value of the `r1Owner`. ```solidity [contracts/Account.sol] @@ -150,14 +156,16 @@ The `updateR1Owner` function can update the value of the `r1Owner`. :code-import{filePath="webauthn/contracts/contracts/Account.sol:updateR1Owner"} ``` -To validate the signature, the `_validateWebAuthnSignature` first extracts the `authenticatorData`, `clientData`, and `rs` values from the decoded signature. +To validate the signature, the `_validateWebAuthnSignature` function +first extracts the `authenticatorData`, `clientData`, and `rs` values from the decoded signature. It's important to note that the WebAuthn authentication process doesn't just sign the transaction data we send as a challenge. The WebAuthn authentication process returns three pieces of information that we need for the validation process: the WebAuthn signature, the `authenticatorData`, and the `clientData`. -The `extractChallengeFromClientData` extracts the WebAuthn challenge from the `clientData`, and checks to see if it matches the transaction hash. -This means that the exact transaction data that is submitted to the contract matches the transaction data signed by the WebAuthn account. +The `extractChallengeFromClientData` function extracts the WebAuthn challenge from the `clientData`, and checks to see if it matches the transaction hash. +If the values are equal, +this means that the exact transaction data that is submitted to the contract matches the transaction data signed by the WebAuthn account. Next, the `_validateWebAuthnSignature` function checks for the malleability of the signature, and checks to see if the WebAuthn user flags are set. @@ -189,18 +197,18 @@ Open a new terminal and start a local in-memory node with `era_test_node`: era_test_node run ``` -Next, modify the `defaultNetwork` in the `hardhat.config.ts` file to deploy to the local in-memory node, and change the version of Solidity to `0.8.20`: +Next, replace your `hardhat.config.ts` file with the file below: -```ts - defaultNetwork: "inMemoryNode", -``` +::drop-panel +::panel{label="hardhat.config.ts"} -```ts - solidity: { - version: "0.8.20", - }, +```solidity [hardhat.config.ts] +:code-import{filePath="webauthn/contracts/hardhat.config.ts"} ``` +:: +:: + ### Adding the Deploy Script Create a new file inside the `deploy` folder called `deploy.ts`: @@ -209,11 +217,7 @@ Create a new file inside the `deploy` folder called `deploy.ts`: touch deploy/deploy.ts ``` -Copy and paste the code below. This script will: - -- deploy the `AAFactory` contract -- deploy the NFT contract and mint an NFT -- deploy the paymaster contract and send funds to it from the preconfigured rich account. +Copy and paste the code below. ::drop-panel ::panel{label="deploy.ts"} @@ -225,6 +229,12 @@ Copy and paste the code below. This script will: :: :: +This script will: + +- deploy the `AAFactory` contract +- deploy the NFT contract and mint an NFT +- deploy the paymaster contract and send funds to it from the pre-configured rich account. + ### Running the Deploy Script Finally, compile and deploy the contracts with: diff --git a/content/tutorials/signing-transactions-with-webauthn/30.building-the-frontend.md b/content/tutorials/signing-transactions-with-webauthn/30.building-the-frontend.md index 1f51bf7e..cfacff9a 100644 --- a/content/tutorials/signing-transactions-with-webauthn/30.building-the-frontend.md +++ b/content/tutorials/signing-transactions-with-webauthn/30.building-the-frontend.md @@ -8,7 +8,7 @@ description: Build the frontend for the WebAuthn app. We will use Next.js to build the frontend. -Move out of your `contract` folder and into the `zksync-webauthn` folder. +Move out of your `contract` folder and back into the `zksync-webauthn` folder. Make a new Next.js project for the frontend using the configuration below: ```shell @@ -75,7 +75,7 @@ Copy the `Layout` component below to your file: ### Styles -Let's also update the styles in `globals.css`. +Let's also update the styles in `src/styles/globals.css`. ::drop-panel ::panel{label="globals.css"} @@ -191,6 +191,10 @@ touch utils/tx.ts :: :: +::callout{icon="i-heroicons-exclamation-circle"} +Note: you may need to update the import at the top from `zksync-ethers/build/utils` to `zksync-ethers/build/src/utils`. +:: + This file contains helper functions to get data for a transaction and register a new passkey in a smart account. diff --git a/content/tutorials/signing-transactions-with-webauthn/40.completing-the-frontend.md b/content/tutorials/signing-transactions-with-webauthn/40.completing-the-frontend.md index 43b844b5..ff325a20 100644 --- a/content/tutorials/signing-transactions-with-webauthn/40.completing-the-frontend.md +++ b/content/tutorials/signing-transactions-with-webauthn/40.completing-the-frontend.md @@ -108,7 +108,7 @@ touch src/pages/create-account.tsx :: This page is where users can deploy a new instance of a smart account using the `AAFactory` contract. -The wallet used to create the acccount is saved temporaily saved in the application using the `useSetWallet` hook, +The wallet used to create the acccount is temporaily saved in the application using the `useSetWallet` hook, and the deployed smart contract account address is saved to the browser's local storage with the `useSetAccount` hook. For testing purposes, when a new account is created, some test funds are sent to the account from a pre-configured rich wallet. @@ -206,6 +206,6 @@ Follow the order of the buttons on the home page: 1. Start by creating a new account. 1. Next, register a new passkey. -1. Finally, you can use the registered passkey to transfer ETH and mint an NFT! +1. Finally, you can use the registered passkey to transfer ETH and mint an NFT. Note: You can edit or remove your browser passkeys by going to `chrome://settings/passkeys`.