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

# Installation

WalletConnect App SDK is chain agnostic and provides seamless integration with several blockchain ecosystems. WalletConnect App SDK when combined with Universal Provider library enables compatibility across any blockchain protocol.

## Pre-requisites

This section is to inform you about the pre-requisites for integrating WalletConnect as an App with React.

### Cloud Configuration

Create a new project on WalletConnect Dashboard at [https://dashboard.walletconnect.com](https://dashboard.walletconnect.com) and obtain a new project ID. You will need this project ID to initialize WalletConnect in your project (app).

> [!NOTE]
>
> **Don't have a project ID?**
>
> Head over to WalletConnect Dashboard and create a new project now!
>
> > [card] [Get started](https://dashboard.walletconnect.com/?utm_source=cloud_banner\&utm_medium=docs\&utm_campaign=backlinks)

### Allowlist

To help prevent malicious use of your project ID, you are strongly encouraged to set an allowlist of [origins](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin) where your project ID is used. You can manage your allowlist in the [WalletConnect Dashboard](https://dashboard.walletconnect.com) under the project settings.

The allowlist supports a list of origins in the format `[scheme://]<hostname[:port]>`. Using `localhost` (or `127.0.0.1`) is always permitted, and if the allowlist is empty, all origins are allowed. Updates take 15 minutes to apply.

Examples of possible origins in the allowlist:

* `example.com` - allows `https://example.com` or `http://example.com` but not `https://www.example.com`
* `https://example.com` - allows `https://example.com` but not `http://example.com`
* `https://*.example.com` - allows `https://www.example.com` but not `https://example.com`

> [!WARNING]
>
> Requests from origins not in the allowlist will be denied. Make sure to add all domains where your app will be deployed.

## Installation

> [!WARNING]
>
> If you are setting up your React app, please **do not use** `npx create-react-app`, as it has been deprecated. Using it may cause dependency
> issues. Instead, please use [Vite](https://vitejs.dev/guide/#scaffolding-your-first-vite-project) to
> create your React app. You can set it up by running `npm create vite@latest`.

```bash npm theme={null}
npm install @reown/appkit @reown/appkit-universal-connector @reown/appkit-common ethers
```

```bash Yarn theme={null}
yarn add @reown/appkit @reown/appkit-universal-connector @reown/appkit-common ethers
```

```bash Bun theme={null}
bun add @reown/appkit @reown/appkit-universal-connector @reown/appkit-common ethers
```

```bash pnpm theme={null}
pnpm add @reown/appkit @reown/appkit-universal-connector @reown/appkit-common ethers
```

## Implementation

Here is a sample implementation of WalletConnect App SDK with React. You can also check the example repository below.

> [card] [WalletConnect App SDK Example](https://github.com/reown-com/appkit-web-examples/tree/main/react/react-core-universal-connector)
>
> Check the WalletConnect App SDK React example

For a quick integration of WalletConnect App SDK you can use the `UniversalConnector` class. Which simplifies the integration of WalletConnect App SDK by providing a single interface for all the blockchain protocols.

You can configure the Universal Connector with the networks you want to support.
For more information, please visit [RPC Reference](https://docs.reown.com/advanced/multichain/rpc-reference/cosmos-rpc) section from our docs.

We recommend creating a config file to establish a singleton instance for the Universal Connector:

```tsx Generic Example theme={null}
import type { AppKitNetwork } from '@reown/appkit/networks'
import type { CustomCaipNetwork } from '@reown/appkit-common'
import { UniversalConnector } from '@reown/appkit-universal-connector'

// Get projectId from https://dashboard.walletconnect.com
export const projectId = import.meta.env.VITE_PROJECT_ID || "b56e18d47c72ab683b10814fe9495694" // this is a public projectId only to use on localhost

if (!projectId) {
  throw new Error('Project ID is not defined')
}

// you can configure your own network
const suiMainnet: CustomCaipNetwork<'sui'> = {
  id: 784,
  chainNamespace: 'sui' as const,
  caipNetworkId: 'sui:mainnet',
  name: 'Sui',
  nativeCurrency: { name: 'SUI', symbol: 'SUI', decimals: 9 },
  rpcUrls: { default: { http: ['https://fullnode.mainnet.sui.io:443'] } }
}

export const networks = [suiMainnet] as [AppKitNetwork, ...AppKitNetwork[]]

export async function getUniversalConnector() {
  const universalConnector = await UniversalConnector.init({
    projectId,
    metadata: {
      name: 'Universal Connector',
      description: 'Universal Connector',
      url: 'https://www.walletconnect.com',
      icons: ['https://www.walletconnect.com/icon.png']
    },
    networks: [
      {
        methods: ['sui_signPersonalMessage'],
        chains: [suiMainnet as CustomCaipNetwork],
        events: [],
        namespace: 'sui'
      }
    ]
  })

  return universalConnector
}
```

```tsx Stacks Example theme={null}
import type { AppKitNetwork } from '@reown/appkit/networks'
import type { InferredCaipNetwork } from '@reown/appkit-common'
import { UniversalConnector } from '@reown/appkit-universal-connector'

// Get projectId from https://dashboard.walletconnect.com
export const projectId = import.meta.env.VITE_PROJECT_ID || "YOUR_PROJECT_ID_HERE" // Replace with your actual project ID

if (!projectId || projectId === "YOUR_PROJECT_ID_HERE") {
  throw new Error('Project ID is not defined. Please set your project ID from the WalletConnect Dashboard.')
}

// you can configure your own network
const stacksMainnet: InferredCaipNetwork = {
  id: 'stacks-mainnet',
  chainNamespace: 'stacks' as const,
  caipNetworkId: 'stacks:1',
  name: 'Stacks Mainnet',
  nativeCurrency: { name: 'STX', symbol: 'STX', decimals: 6 },
  rpcUrls: { default: { http: ['https://stacks-node-api.mainnet.stacks.co'] } } // Example Stacks Mainnet RPC URL
}

export const networks = [stacksMainnet] as [AppKitNetwork, ...AppKitNetwork[]]

export async function getUniversalConnector() {
  const universalConnector = await UniversalConnector.init({
    projectId,
    metadata: {
      name: 'Universal Connector',
      description: 'Universal Connector',
      url: 'https://www.walletconnect.com',
      icons: ['https://www.walletconnect.com/icon.png']
    },
    networks: [
      {
        methods: ['stx_signMessage', 'stx_signTransaction', 'stx_getAccounts', 'stx_getAddresses', 'stx_callContract', 'stx_deployContract', 'sendTransfer', 'getAddresses'],
        chains: [stacksMainnet as InferredCaipNetwork],
        events: ['stx_chainChanged', 'stx_accountsChanged'],
        namespace: 'stacks'
      }
    ]
  })

  return universalConnector
}
```

```tsx TON Example theme={null}
import type { AppKitNetwork } from '@reown/appkit/networks'
import type { CustomCaipNetwork } from '@reown/appkit-common'
import { UniversalConnector } from '@reown/appkit-universal-connector'

// Get projectId from https://dashboard.walletconnect.com
export const projectId = import.meta.env.VITE_PROJECT_ID || "YOUR_PROJECT_ID_HERE" // Replace with your actual project ID

if (!projectId || projectId === "YOUR_PROJECT_ID_HERE") {
  throw new Error('Project ID is not defined. Please set your project ID from the WalletConnect Dashboard.')
}

const tonMainnet: CustomCaipNetwork<'ton'> = {
  id: -239,
  chainNamespace: 'ton' as const,
  caipNetworkId: 'ton:-239',
  name: 'TON',
  nativeCurrency: { name: 'TON', symbol: 'TON', decimals: 9 },
  rpcUrls: { default: { http: ['https://toncenter.com/api/v2/jsonRPC'] } }
}

export const networks = [tonMainnet] as [AppKitNetwork, ...AppKitNetwork[]]

export async function getUniversalConnector() {
  const universalConnector = await UniversalConnector.init({
    projectId,
    metadata: {
      name: 'Universal Connector',
      description: 'Universal Connector',
      url: 'https://www.walletconnect.com',
      icons: ['https://www.walletconnect.com/icon.png']
    },
    networks: [
      {
        methods: ['ton_signData'],
        chains: [tonMainnet as CustomCaipNetwork],
        events: [],
        namespace: 'ton'
      }
    ]
  })

  return universalConnector
}
```

```tsx TRON Example theme={null}
import type { AppKitNetwork } from '@reown/appkit/networks'
import type { CustomCaipNetwork } from '@reown/appkit-common'
import { UniversalConnector } from '@reown/appkit-universal-connector'

// Get projectId from https://dashboard.walletconnect.com
export const projectId = import.meta.env.VITE_PROJECT_ID || "YOUR_PROJECT_ID_HERE" // Replace with your actual project ID

if (!projectId || projectId === "YOUR_PROJECT_ID_HERE") {
  throw new Error('Project ID is not defined. Please set your project ID from the WalletConnect Dashboard.')
}

const tronMainnet: CustomCaipNetwork<'tron'> = {
  id: '0x2b6653dc',
  chainNamespace: 'tron' as const,
  caipNetworkId: 'tron:0x2b6653dc',
  name: 'Tron Mainnet',
  nativeCurrency: { name: 'TRX', symbol: 'TRX', decimals: 6 },
  rpcUrls: { default: { http: ['https://api.trongrid.io'] } }
}

export const networks = [tronMainnet] as [AppKitNetwork, ...AppKitNetwork[]]

export async function getUniversalConnector() {
  const universalConnector = await UniversalConnector.init({
    projectId,
    metadata: {
      name: 'Universal Connector',
      description: 'Universal Connector',
      url: 'https://www.walletconnect.com',
      icons: ['https://www.walletconnect.com/icon.png']
    },
    networks: [
      {
        methods: ['tron_signTransaction', 'tron_signMessage'],
        chains: [tronMainnet as CustomCaipNetwork],
        events: [],
        namespace: 'tron'
      }
    ]
  })

  return universalConnector
}
```

In the App.tsx file you can add :

```tsx theme={null}
import { useState, useEffect } from 'react'
import { getUniversalConnector } from './config' // previous config file
import { UniversalConnector } from '@reown/appkit-universal-connector'

export function App() {
  const [universalConnector, setUniversalConnector] = useState<UniversalConnector>()
  const [session, setSession] = useState<any>()

  
  // Initialize the Universal Connector on component mount
  useEffect(() => {
    getUniversalConnector().then(setUniversalConnector)
  }, [])

  // Set the session state in case it changes
  useEffect(() => {
    setSession(universalConnector?.provider.session)
  }, [universalConnector?.provider.session])
```

## Trigger the modal

To open the WalletConnect modal you need to call the `connect` function from the Universal Connector.

```tsx theme={null}
    // get the session from the universal connector
    const handleConnect = async () => {
      if (!universalConnector) {
        return
      }
  
      const { session: providerSession } = await universalConnector.connect()
      setSession(providerSession)
    };

    // disconnect the universal connector
    const handleDisconnect = async () => {
      if (!universalConnector) {
        return
      }
      await universalConnector.disconnect()
      setSession(null)
    };

    ...

    return (
    (
    <div>      
        <button onClick={handleConnect}>Open WalletConnect modal</button>
        <button onClick={handleDisconnect}>Disconnect</button>
    </div>
    )
```

## Smart Contract Interaction

> [tab] Wagmi
>
> [Wagmi hooks](https://wagmi.sh/react/api/hooks/useReadContract) can help us interact with wallets and smart contracts:
>
> ```tsx theme={null}
> import { useReadContract } from "wagmi";
> import { USDTAbi } from "../abi/USDTAbi";
>
> const USDTAddress = "0x...";
>
> function App() {
>   const result = useReadContract({
>     abi: USDTAbi,
>     address: USDTAddress,
>     functionName: "totalSupply",
>   });
> }
> ```
>
> Read more about Wagmi hooks for smart contract interaction [here](https://wagmi.sh/react/hooks/useReadContract).

> [tab] Ethers
>
> [Ethers](https://docs.ethers.org/v6/) can help us interact with wallets and smart contracts:
>
> ```tsx theme={null}
> import { useAppKitProvider, useAppKitAccount } from "@reown/appkit/react";
> import { BrowserProvider, Contract, formatUnits } from "ethers";
>
> const USDTAddress = "0x617f3112bf5397D0467D315cC709EF968D9ba546";
>
> // The ERC-20 Contract ABI, which is a common contract interface
> // for tokens (this is the Human-Readable ABI format)
> const USDTAbi = [
>   "function name() view returns (string)",
>   "function symbol() view returns (string)",
>   "function balanceOf(address) view returns (uint)",
>   "function transfer(address to, uint amount)",
>   "event Transfer(address indexed from, address indexed to, uint amount)",
> ];
>
> function Components() {
>   const { address, isConnected } = useAppKitAccount();
>   const { walletProvider } = useAppKitProvider("eip155");
>
>   async function getBalance() {
>     if (!isConnected) throw Error("User disconnected");
>
>     const ethersProvider = new BrowserProvider(walletProvider);
>     const signer = await ethersProvider.getSigner();
>     // The Contract object
>     const USDTContract = new Contract(USDTAddress, USDTAbi, signer);
>     const USDTBalance = await USDTContract.balanceOf(address);
>
>     console.log(formatUnits(USDTBalance, 18));
>   }
>
>   return <button onClick={getBalance}>Get User Balance</button>;
> }
> ```

> [tab] Solana
>
> [@Solana/web3.js](https://solana.com/docs/clients/javascript) library allows for seamless interaction with wallets and smart contracts on the Solana blockchain.
>
> For a practical example of how it works, you can refer to our [lab dApp](https://lab.reown.com/appkit/?name=solana).
>
> ```tsx theme={null}
> import {
>   SystemProgram,
>   PublicKey,
>   Keypair,
>   Transaction,
>   TransactionInstruction,
>   LAMPORTS_PER_SOL
> } from '@solana/web3.js'
> import { useAppKitAccount, useAppKitProvider } from '@reown/appkit/react'
> import { useAppKitConnection, type Provider } from '@reown/appkit-adapter-solana/react'
>
> function deserializeCounterAccount(data?: Buffer): { count: number } {
>   if (data?.byteLength !== 8) {
>     throw Error('Need exactly 8 bytes to deserialize counter')
>   }
>
>   return {
>     count: Number(data[0])
>   }
> }
>
> const { address } = useAppKitAccount()
> const { connection } = useAppKitConnection()
> const { walletProvider } = useAppKitProvider<Provider>('solana')
>
> async function onIncrementCounter() {
>   const PROGRAM_ID = new PublicKey('Cb5aXEgXptKqHHWLifvXu5BeAuVLjojQ5ypq6CfQj1hy')
>
>   const counterKeypair = Keypair.generate()
>   const counter = counterKeypair.publicKey
>
>   const balance = await connection.getBalance(walletProvider.publicKey)
>   if (balance < LAMPORTS_PER_SOL / 100) {
>     throw Error('Not enough SOL in wallet')
>   }
>
>   const COUNTER_ACCOUNT_SIZE = 8
>   const allocIx: TransactionInstruction = SystemProgram.createAccount({
>     fromPubkey: walletProvider.publicKey,
>     newAccountPubkey: counter,
>     lamports: await connection.getMinimumBalanceForRentExemption(COUNTER_ACCOUNT_SIZE),
>     space: COUNTER_ACCOUNT_SIZE,
>     programId: PROGRAM_ID
>   })
>
>   const incrementIx: TransactionInstruction = new TransactionInstruction({
>     programId: PROGRAM_ID,
>     keys: [
>       {
>         pubkey: counter,
>         isSigner: false,
>         isWritable: true
>       }
>     ],
>     data: Buffer.from([0x0])
>   })
>
>   const tx = new Transaction().add(allocIx).add(incrementIx)
>
>   tx.feePayer = walletProvider.publicKey
>   tx.recentBlockhash = (await connection.getLatestBlockhash('confirmed')).blockhash
>
>   await walletProvider.signAndSendTransaction(tx, [counterKeypair])
>
>   const counterAccountInfo = await connection.getAccountInfo(counter, {
>     commitment: 'confirmed'
>   })
>
>   if (!counterAccountInfo) {
>     throw new Error('Expected counter account to have been created')
>   }
>
>   const counterAccount = deserializeCounterAccount(counterAccountInfo?.data)
>
>   if (counterAccount.count !== 1) {
>     throw new Error('Expected count to have been 1')
>   }
>
>   console.log(`[alloc+increment] count is: ${counterAccount.count}`);
> }
> ```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.