Reown AppKit and Virtual TestNets
With Reown AppKit, you can provide seamless wallet connections, including email and social logins, on-ramp functionality, smart accounts, one-click authentication, and wallet notifications, all designed to deliver an exceptional user experience.
You can use a Virtual Testnet as a chain for UI development, testing, and dapp demo mode.
Create a Virtual TestNet
In Tenderly Dashboard, create a new Virtual TestNet:
- Select Mainnet as the base network
- Name it
Reown AppKit TestNet - Choose a unique chain ID
73571 - Turn on the Public Explorer
- Copy the Testnet RPC
Create a Chain Config
Create a file app/tenderly.config.ts and replace the following:
- Paste the chain ID to the
idproperty - Change the name and currency
- Paste the Public RPC to
rpcUrls.default.http - Paste the Block Explorer URL to
blockExplorers.default.url
import { defineChain } from '@reown/appkit/networks'
export const vTestnet = defineChain({
id: 73571, // Add this to match the chain Id you set for your Virtual TestNet
caipNetworkId: 'eip155:73571',
chainNamespace: 'eip155',
name: 'Virtual Sepolia',
nativeCurrency: { name: 'vSepolia', symbol: 'vETH', decimals: 18 },
rpcUrls: {
default:{
http: [process.env.TENDERLY_VIRTUAL_TESTNET_RPC!],
}
},
blockExplorers: {
default:{
name:'Tenderly Explorer',
url: 'https://dashboard.tenderly.co/explorer/vnet/6a6910ba-5831-4758-9d89-1f8e3169433f', // replace this with your Virtual TestNet's explorer URL
}
},
contracts: {
ensRegistry: {
address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'
},
ensUniversalResolver: {
address: '0xE4Acdd618deED4e6d2f03b9bf62dc6118FC9A4da',
blockCreated: 16773775
},
multicall3: {
address: '0xca11bde05977b3631167028862be2a173976ca11',
blockCreated: 14353601
}
}
})
Create a Wagmi Config
Create a Wagmi config at config/index.tsx that will:
- include the
vMainnetchain we defined in the previous step - Specify the Public RPC in
transportundervMainnet.id
import { cookieStorage, createStorage, http } from '@wagmi/core'
import { WagmiAdapter } from '@reown/appkit-adapter-wagmi'
import { mainnet, arbitrum } from '@reown/appkit/networks'
import { vTestnet } from '@/app/tenderly.config'
// Get projectId from https://cloud.reown.com
export const projectId = process.env.NEXT_PUBLIC_PROJECT_ID
if (!projectId) {
throw new Error('Project ID is not defined')
}
export const networks = [mainnet, arbitrum, vTestnet]
//Set up the Wagmi Adapter (Config)
export const wagmiAdapter = new WagmiAdapter({
storage: createStorage({
storage: cookieStorage
}),
ssr: true,
transports: {
[vTestnet.id]: http(process.env.TENDERLY_VIRTUAL_TESTNET_RPC!)
},
networks,
projectId
})
export const config = wagmiAdapter.wagmiConfigCreate a ContextProvider
Now, inside your context/index.tsx file, you also need to import vTestnet and pass it as one of the supported networks within the createAppKit function, as shown below.
To use the Virtual Testnet only while building UI, testing, and demoing the dapp, we added a NEXT_PUBLIC_TENDERLY_VNETS_ENABLED environment variable.
The call to createWeb3Modal uses vMainnet as the default chain, when app runs with NEXT_PUBLIC_TENDERLY_VNETS_ENABLED.
'use client'
import { wagmiAdapter, projectId } from '@/config'
import { createAppKit } from '@reown/appkit/react'
import { mainnet, arbitrum } from '@reown/appkit/networks'
import { vTestnet } from '@/app/tenderly.config'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import React, { type ReactNode } from 'react'
import { cookieToInitialState, WagmiProvider, type Config } from 'wagmi'
// Set up queryClient
const queryClient = new QueryClient()
if (!projectId) {
throw new Error('Project ID is not defined')
}
// Set up metadata
const metadata = { //this is optional
name: "appkit-example",
description: "AppKit Example - EVM",
url: "https://exampleapp.com", // origin must match your domain & subdomain
icons: ["https://avatars.githubusercontent.com/u/37784886"]
}
// Create the modal
const modal = createAppKit({
adapters: [wagmiAdapter],
projectId,
networks: [mainnet, arbitrum, vTestnet],
metadata: metadata,
features: {
analytics: true, // Optional - defaults to your Cloud configuration
}
})
function ContextProvider({ children, cookies }: { children: ReactNode; cookies: string | null }) {
const initialState = cookieToInitialState(wagmiAdapter.wagmiConfig as Config, cookies)
return (
<WagmiProvider config={wagmiAdapter.wagmiConfig as Config} initialState={initialState}>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</WagmiProvider>
)
}
export default ContextProviderUse the ContextProvider
Wrap your dapp body (app/layout.tsx) in a ContextProvider we created in the last step.
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import './globals.css';
import ContextProvider from '@/context';
const inter = Inter({ subsets: ['latin'] });
export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
};
export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) {
return (
<html lang="en">
<body className={inter.className}>
<ContextProvider>
{children}
</ContextProvider>
</body>
</html>
);
}Run the dapp
## Get projectId at https://cloud.reown.com
NEXT_PUBLIC_PROJECT_ID=???? \
NEXT_PUBLIC_TENDERLY_VNETS_ENABLED=true \
pnpm run dev