Implement ThirdWeb Smart Wallet and Embedded Wallet in Next.js
Tags: nextjs, thirdweb, web3
Published: 2023-10-05 12:44:23

## Introduction

ThirdWeb's Wallet feature is extensive and convenient. In this case, I tried the Smart Wallet and Embedded Wallet.

## Prerequisites
- Experience with Next.js development
- Experience with Thirdweb dashboard

---------

## Preparation (from Thirdweb dashboard)

Thirdweb
https://thirdweb.com/

**Step (chain uses Mumbai)**
1. Create API Keys from Settings
2. Create a Smart wallet Account Factory from Explore in Contracts
3. Setup Wallet and generate code from Connect in Wallets

**1. Create API Keys from Settings**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o27ou6naqfshevrjicgc.png)

**2. Create a Smart wallet Account Factory from Explore in Contracts**
Selecting and creating an Account Factory
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3sh99epn1k7deolp8pkz.png)

Check what has been created.
This contract address is required as factoryAddress when implementing the page.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ybhyte7wegubzcg03abe.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lgcfj8368320n08f9aov.png)

**3. Setup Wallet and generate code from Connect in Wallets**
In this case, I chose MetaMask, Embedded Wallets and Smart Wallet.
(To use Smart Wallet, select at least one Wallet)
The code generated here will be used as a reference for implementation.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c58lqjxqb7pamm5icdbm.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c37u0lqps33smfbk8dk6.png)

Generated Code
```
import {
  ThirdwebProvider,
  ConnectWallet,
  metamaskWallet,
  embeddedWallet,
} from "@thirdweb-dev/react";

const smartWalletOptions = {
  factoryAddress: "YOUR_FACTORY_ADDRESS",
  gasless: true,
};

export default function App() {
  return (
    <ThirdwebProvider
      activeChain="mumbai"
      clientId="YOUR_CLIENT_ID"
      supportedWallets={[
        smartWallet(
          metamaskWallet({ recommended: true }),
          smartWalletOptions,
        ),
        smartWallet(
          embeddedWallet(),
          smartWalletOptions,
        ),
      ]}
    >
      <ConnectWallet
        theme={"dark"}
        modalSize={"compact"}
      />
    </ThirdwebProvider>
  );
}
```

---------

## Sample code

Use the generated code as an implementation reference.


**Steps**

- Create a project with Next.js + Typescript
- Install SDK
  `yarn add @thirdweb-dev/react @thirdweb-dev/sdk ethers@^5`
- Write the API Key and Account Factory address you created in env.local
- Edit _app.tsx
- Edit index.tx

**Thirdweb Version**
`"@thirdweb-dev/react": "^3.16.2"`
`"@thirdweb-dev/sdk": "^3.10.64"`


**_app.tsx**
```
import "@/styles/globals.css";
import type { AppProps } from "next/app";
import {
  ThirdwebProvider,
  smartWallet,
  metamaskWallet,
  embeddedWallet,
} from "@thirdweb-dev/react";

const activeChain = "mumbai";
const smartWalletOptions = {
  factoryAddress: process.env.NEXT_PUBLIC_FACTORY_ADDRESS || "",
  gasless: true,
};

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ThirdwebProvider
      activeChain={activeChain}
      clientId={process.env.NEXT_PUBLIC_TW_CLIENT_ID}
      supportedWallets={[
        smartWallet(metamaskWallet({ recommended: true }), smartWalletOptions),
        smartWallet(embeddedWallet(), smartWalletOptions),
      ]}
    >
      <Component {...pageProps} />
    </ThirdwebProvider>
  );
}

export default MyApp;
```
**index.tsx**
```
import { ConnectWallet } from "@thirdweb-dev/react";
import type { NextPage } from "next";

const Home: NextPage = () => {
  return (
    <main className="flex flex-col items-center justify-center p-10">
      <div className="">
        <ConnectWallet
          theme={"dark"}
          modalSize={"compact"}
          btnTitle={"Connect Wallet"}
          modalTitleIconUrl={""}
        />
      </div>
    </main>
  );
};

export default Home;
```

---------

## Operation check

Start with `yarn dev`
Confirm the activated URL (e.g., localhost:3000) with a PC browser.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a1fbu68p985jvesyipgx.png)

Try to authenticate with your Gmail login.
If you enter your email address, an authentication code will be sent to you.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kble6t4m8z0f9ew323s.png)

Address generated.
The smart wallet address will appear first.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/11ibmx5d177aufhuqzzj.png)

In this case, two addresses are generated: Smart Wallet and Personal Wallet (Embedded Wallet).

**Smart Wallet address**
This time, the smart wallet address is gasless.
When you click on Connectted to Smart Wallet, you will see your Account details on the Thirdweb page. You can also check the NFTs you hold.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f972jzehsvbrn6fmtzw0.png)

**Personal Wallet (Embedded Wallet) Address**
Wallet Users can be found on the Thirdweb dashboard under Embedded Wallets in the Wallets section.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hc5g2swf9rstpiv56pkb.png)

---------

## Conclusion

I experimented with everything from setup to implementation and got the impression that it was very easy.
Thirdweb has an easy to use dashboard and is evolving more and more!

I did not put it here, but I tested a MATIC full amount transfer with a Smart Wallet address, and it worked without insufficient funds; with a Personal Wallet (Embedded Wallet) address, I got an insufficient funds error.

I also attempted a Claim at NFT (free price) on EditionDrop with a smart wallet address with zero balance, but it was successfully processed as gasless.
(I did not, however, see where they were processing the gasless.)

They also accept credit card payments, so I will try that next time I have the opportunity.