Skip to main content
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 Environment as a chain for UI development, testing, and dapp demo mode.
1
Create a Virtual Environment
2
In Tenderly Dashboard, create a new Virtual Environment:
3
  • Select Mainnet as the base network
  • Name it Reown AppKit Virtual Environment
  • Choose a unique chain ID 73571
  • Turn on the Public Explorer
  • Copy the Virtual Environment RPC
  • 4
    Create a Chain Config
    5
    Create a file app/tenderly.config.ts and replace the following:
    6
  • Paste the chain ID to the id property
  • Change the name and currency
  • Paste the Public RPC to rpcUrls.default.http
  • Paste the Block Explorer URL to blockExplorers.default.url
  • 7
    
    export const vTestnet = defineChain({
      id: 73571,  // Add this to match the chain Id you set for your Virtual Environment
      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 Environment's explorer URL
        }
      },
      contracts: {
        ensRegistry: {
          address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'
        },
        ensUniversalResolver: {
          address: '0xE4Acdd618deED4e6d2f03b9bf62dc6118FC9A4da',
          blockCreated: 16773775
        },
        multicall3: {
          address: '0xca11bde05977b3631167028862be2a173976ca11',
          blockCreated: 14353601
        }
      }
    })
    
    
    8
    Create a Wagmi Config
    9
    Create a Wagmi config at config/index.tsx that will:
    10
  • include the vMainnet chain we defined in the previous step
  • Specify the Public RPC in transport under vMainnet.id
  • 11
    
    // 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.wagmiConfig
    
    12
    Create a ContextProvider
    13
    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.
    14
    To use the Virtual Environment 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.
    15
    'use client'
    
    
    
    // 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 ContextProvider
    
    16
    Use the ContextProvider
    17
    Wrap your dapp body (app/layout.tsx) in a ContextProvider we created in the last step.
    18
    
    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>
      );
    }
    
    19
    Run the dapp
    20
    ## Get projectId at https://cloud.reown.com
    NEXT_PUBLIC_PROJECT_ID=???? \
    NEXT_PUBLIC_TENDERLY_VNETS_ENABLED=true \
    pnpm run dev