Completing the Frontend
Hooks
Next, create a src/hooks
folder and add the hooks below to manage the created smart account.
mkdir src/hooks
We will create two hooks: useAccount
and useWallet
.
useAccount
Create a new file in the hooks
folder called useAccount.tsx
.
touch src/hooks/useAccount.tsx
The useAccount
hook saves and retrieves the public account address of the user's smart account using local storage.
This allows the app to "remember" the created account after the user has closed the app.
useWallet
Create another file in the hooks
folder called useWallet.tsx
.
touch src/hooks/useWallet.tsx
The useWallet
hook temporarily saves the full wallet owner of the deployed smart contract account to use for registering a passkey.
This is used after the registration ceremony when the user wants to register their passkey as the r1Owner
of the account,
which requires the private key of the initial wallet that made the smart account.
In a real-world app, this exact implementation isn't ideal. Note that the wallet isn't stored permanently, so once the user closes and returns to the app, they cannot register a new passkey to the smart account without inputing their private key. However, the user could still transfer ETH and mint the NFT as the passkey and public account address are still available.
Adding the Hooks to _app.tsx
Import the hooks into your src/pages/_app.tsx
file and wrap your app in the hook providers.
This file also creates a new Provider
connected to our local era_test_node
running on port 8011
and passes it into every page.
Pages
Finally, let's create the pages and put everything together.
Inside the frontend/src/pages
folder we will create four new pages: create-account.tsx
, register.tsx
, mint.tsx
, and transfer.tsx
.
Create Account
Create a new file in the src/pages
folder called create-account.tsx
.
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 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.
Register Passkey
Create a new file in the src/pages
folder called register.tsx
.
touch src/pages/register.tsx
The register page is where users can go through the WebAuthn registration process to create a new passkey,
and then register that passkey as the r1Owner
in their smart contract account.
Users can input a string as the name of the new passkey they want to register, and then click the "Register New Passkey" button.
The first step in the registerNewPasskey
function is to use the platformAuthenticatorIsAvailable
method to check if the user's device supports WebAuthn.
Next, the get-registration-options
endpoint we created earlier is called to get the registration options
and pass them into the startRegistration
method provided by @simplewebauthn
.
The name input from the user is passed along with localhost
as relying party's (rp
) name and ID.
Once the passkey is registered to the browser, the public key is extraced from the response and registered as the r1Owner
in the user's account.
Transfer ETH
Create a new file in the src/pages
folder called transfer.tsx
.
touch src/pages/transfer.tsx
The transfer page is where users can transfer any amount of ETH to a given address using their WebAuthn passkey to sign the transaction.
The sendTransfer
function uses the getTransaction
and getDataToSign
functions from the utils
to create the transaction challenge to be signed.
Then, it calls the authenticate
function from the utils
to get the WebAuthn authentication response,
which finally gets passed to the signAndSend
function.
Mint NFT
Create a new file in the src/pages
folder called mint.tsx
.
touch src/pages/mint.tsx
The last page is to mint an NFT using WebAuthn.
The mint
function works very similar to the sendTransfer
function on the transfer page,
but has a couple of extra steps.
Instead of sending empty data in the transaction, it prepares the function call data by encoding it.
Once the transaction is complete, it looks through the logs to find the token ID and fetch the NFT artwork to display.
Running the App
Start the frontend app by running the command below in the frontend
folder:
npm run dev
You can now try out the app!
It should be running at http://localhost:3000
.
Follow the order of the buttons on the home page:
- Start by creating a new account.
- Next, register a new passkey.
- Finally, you can use the registered passkey to transfer ETH and mint an NFT.
chrome://settings/passkeys
.Note that after following the steps above and reloading the app, the private key of the newly created account will be forgotten, and just the passkey and the public address of the account is stored. However, the user can still use the account by signing with the passkey.
This means that the user can lose their private key, or never store it in the first place, and still be able to use their account and recover their funds!