> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tenderly.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Reown AppKit

> 了解如何在构建、暂存和演示 dapp 时将 ConnectKit 连接到 Virtual Environments。

借助 [Reown AppKit](https://reown.com/reown-sdk)，您可以提供无缝的钱包连接，包括邮件和社交登录、法币入金功能、智能账户、一键身份验证和钱包通知，所有这些都旨在提供卓越的用户体验。

您可以将 Virtual Environment 用作 UI 开发、测试和 dapp 演示模式的链。

<Steps>
  ### 创建 Virtual Environment

  在 Tenderly Dashboard 中创建一个新的 Virtual Environment：

  * 选择 Mainnet 作为基础网络
  * 命名为 `Reown AppKit Virtual Environment`
  * 选择唯一的链 ID **`73571`**
  * 打开 **Public Explorer**
  * 复制 **Virtual Environment RPC**

  ### 创建链配置

  创建一个文件 `app/tenderly.config.ts` 并替换以下内容：

  1. 将链 ID 粘贴到 `id` 属性
  2. 更改名称和货币
  3. 将 [**Public RPC**](/virtual-environments/overview#public-rpc) 粘贴到 **`rpcUrls.default.http`**
  4. 将 **Block Explorer URL** 粘贴到 **`blockExplorers.default.url`**

  ```typescript showLineNumbers title="app/tenderly.config.ts" lines={4-5,8, 12-13} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}

  export const vSepolia = 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
      }
    }
  })

  ```

  ### 创建 Wagmi 配置

  在 `config/index.tsx` 处创建一个 Wagmi 配置，它将：

  * 包含我们在上一步中定义的 `vMainnet` 链
  * 在 `vMainnet.id` 下的 **`transport`** 中指定 [Public RPC](/virtual-environments/overview#public-rpc)

  ```typescript showLineNumbers title="config/wagmi.config.ts" lines={13, 19-20} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}

  // 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, vSepolia]

  //Set up the Wagmi Adapter (Config)
  export const wagmiAdapter = new WagmiAdapter({
    storage: createStorage({
      storage: cookieStorage
    }),
    ssr: true,
    transports: {
      [vSepolia.id]: http(process.env.TENDERLY_VIRTUAL_TESTNET_RPC!)
    },
    networks,
    projectId
  })

  export const config = wagmiAdapter.wagmiConfig
  ```

  ### 创建 ContextProvider

  现在，在您的 `context/index.tsx` 文件中，您还需要导入 `vSepolia`，并将其作为受支持的网络之一传入 `createAppKit` 函数，如下所示。

  为了仅在构建 UI、测试和演示 dapp 时使用 Virtual Environment，我们添加了一个 `NEXT_PUBLIC_TENDERLY_VNETS_ENABLED` 环境变量。
  在应用以 `NEXT_PUBLIC_TENDERLY_VNETS_ENABLED` 运行时，对 `createWeb3Modal` 的调用使用 `vMainnet` 作为默认链。

  ```tsx showLineNumbers title='context/index.tsx' lines={21, 31} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  '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, vSepolia],
    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
  ```

  ### 使用 ContextProvider

  将您的 dapp `body`（`app/layout.tsx`）包装在我们上一步创建的 `ContextProvider` 中。

  ```tsx showLineNumbers title="src/app/layout.ts" lines={15, 28} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}

  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>
    );
  }
  ```

  ### 运行 dapp

  ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  ## Get projectId at https://cloud.reown.com
  NEXT_PUBLIC_PROJECT_ID=???? \
  NEXT_PUBLIC_TENDERLY_VNETS_ENABLED=true \
  pnpm run dev
  ```
</Steps>
