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.
Create a new project on WalletConnect Dashboard at https://dashboard.walletconnect.com and obtain a new project ID. You will need this project ID to initialize WalletConnect in your project (app).
Don’t have a project ID?Head over to WalletConnect Dashboard and create a new project now!
To help prevent malicious use of your project ID, you are strongly encouraged to set an allowlist of origins where your project ID is used. You can manage your allowlist in the WalletConnect Dashboard 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
Requests from origins not in the allowlist will be denied. Make sure to add all domains where your app will be deployed.
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 section from our docs.We recommend creating a config file to establish a singleton instance for the Universal Connector:
Copy
Ask AI
import { UniversalConnector } from '@reown/appkit-universal-connector'export const projectId = import.meta.env.VITE_PROJECT_ID || "YOUR_PROJECT_ID_HERE" // Replace with your actual project IDif (!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 networkconst suiMainnet = { id: 784, chainNamespace: 'sui', 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]export let universalConnectorexport async function getUniversalConnector() { if (!universalConnector) { 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], events: [], namespace: 'sui' } ] }) } return universalConnector}
In the main.js file you can add:
Copy
Ask AI
import { getUniversalConnector } from './config/appKit.js'async function setup() { const universalConnector = await getUniversalConnector() // check if session is already connected if (universalConnector?.provider.session) { session = universalConnector?.provider.session }}setup()
To open the WalletConnect modal you need to call the connect function from the Universal Connector.
For more information, please visit RPC Reference section from our docs.
Copy
Ask AI
<script> let address = null let addressStacks = null let session = null async function handleConnect() { // universalConnector is the universal connector instance from the implementation section if (!universalConnector) { return } const { session: providerSession } = await universalConnector.connect() // get the address from the session if (providerSession?.namespaces?.sui?.accounts?.[0]?.split(':')[2]) { address = providerSession?.namespaces?.sui?.accounts?.[0]?.split(':')[2] } else if (providerSession?.namespaces?.stacks?.accounts?.[0]?.split(':')[2]) { addressStacks = providerSession?.namespaces?.stacks?.accounts?.[0]?.split(':')[2] } // update the session session = providerSession; } document.getElementById('open-connect-modal').addEventListener('click', handleConnect);</script>.... <div> <button id="open-connect-modal">Open WalletConnect modal</button></div>
Wagmi hooks can help us interact with wallets and smart contracts:
Copy
Ask AI
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.
Ethers can help us interact with wallets and smart contracts:
Copy
Ask AI
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>;}
@Solana/web3.js 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.
Copy
Ask AI
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}`);}