How to Build a React Native Dapp with WalletConnect

Tom Terado
WalletConnect
Published in
6 min readJul 21, 2023

Ever wondered what it is like to create a web3 mobile dapp like Showtime or OpenSea? Being a mobile dapp developer unlocks superpowers to understand how the provider works, how dapp and wallet connections work and how to interact with smart contracts/Blockchain RPC.

In this tutorial, we will build a simple web3 dapp with the WalletConnect Modal via React Native Expo, which empowers you with the foundations to be a web3 dapp developer.

** As of December 2023, we have created an updated tutorial on React Native and the usage of the one in package (Web3Modal) — we strongly recommend watching this tutorial instead ***

What we will be building in this tutorial?

In this simple tutorial, we will be creating a simple dapp that signs a message after it has connected to the Ethereum Blockchain after the wallet is approved.

Highly recommend going through the documentation before starting.

The tutorial process is broken down into:

  • Prerequisites
  • Installation
  • Project Setup

Let’s get started 🫡

I’ve also created a Youtube Tutorial of this so feel free to follow along here!

Prerequisites

Have a mobile device (iOS or Android) with Expo Go installed. Register for an account at expo.dev for an easier flow.

Also install a mobile wallet. Recommend Alpha Wallet, Trust or Zerion. This will facilitates the dapp <> wallet connection.

Installation

Let’s get started by starting a barebones Expo project!

npx create-expo-app -t expo-template-blank-typescript
// When prompted with "What is your app named"
// Type: reactnative_dapp_tutorial
cd reactnative_dapp_tutorial
npx expo start

As per the Expo Docs.

Install the Expo Go app on your iOS or Android phone and connect to the same wireless network as your computer. On Android, use the Expo Go app to scan the QR code from your terminal to open your project. On iOS, use the built-in QR code scanner of the default iOS Camera app

Follow the Expo instructions here for further setup.

Scan your QR Code with your device to run Expo in parallel with your code flow.

An example of what the QR code should look like after npx expo start is as below + what it should look like on your mobile device when Expo is running.

Now let’s get started with the WalletConnect modules.

As per the WalletConnect Docs, let’s install the following.

npx expo install @walletconnect/modal-react-native
npx expo install @react-native-async-storage/async-storage react-native-get-random-values react-native-modal react-native-svg

Initializing WalletConnect Modal

Get a projectID from WalletConnect Cloud Platform

With this tutorial, we will be using the projectID which is shown after you create a Project. Usually we would take a .env approach but this is complicated in React Native so we will go ahead with just copy and pasting the projectID for development/tutorial purposes.

  • Installation
  • Screen

Project Setup

Hopefully you have read the documentation for WalletConnect Modal.

⚠️⚠️NOTE: For those on Expo 48, please refer to here for extra steps.⚠️⚠️

^ Some expo / polyfill issues are addressed in the extra above steps.

The core functions we have to understand related to the package are:

  • WalletConnectModal
  • useWalletConnectModal Hook

WalletConnectModal

<WalletConnectModal projectId={projectId} providerMetadata={providerMetadata} />

You can think of this being the Provider that wraps the whole Modal connection. You pass in your projectID to use WalletConnect and provide extra metadata to help the wallet side undestand what this dapp is with regards to its name, description, url, icons and redirect links.

For more insight into what dependencies the packages uses:

"dependencies": {
"@ethersproject/shims": "5.7.0",
"@walletconnect/core": "2.9.0",
"@walletconnect/react-native-compat": "2.9.0",
"@walletconnect/universal-provider": "2.9.0",
"qrcode": "1.5.3",
"valtio": "1.10.5"
}

The most important dependencies is the @walletconnect/universal-provider which uses our Sign API which allows users to perform blockchain actions. More information can be found here. [Insert Link]

useWalletConnectModal Hook

import { useWalletConnectModal } from "@walletconnect/modal-react-native";
const { isOpen, open, close, provider, isConnected, address } = useWalletConnectModal();

This hook provides access to opening/closing the WalletConnect modal and checks if it is connected and exposes the provider with Blockchain actions.

So let’s add this to our code / App.tsx

import { WalletConnectModal } from '@walletconnect/modal-react-native';

const projectId = 'YOUR_PROJECT_ID';

const providerMetadata = {
name: 'YOUR_PROJECT_NAME',
description: 'YOUR_PROJECT_DESCRIPTION',
url: 'https://your-project-website.com/',
icons: ['https://your-project-logo.com/'],
redirect: {
native: 'YOUR_APP_SCHEME://',
universal: 'YOUR_APP_UNIVERSAL_LINK.com'
}
};

function App() {
return (
<>
<WalletConnectModal projectId={projectId} providerMetadata={providerMetadata} />
</>
)
}

Here we initialise the WalletConnectModal with the properties

  • ProjectID
  • ProviderMetaData

Add in your ProjectID from the Cloud and add in your own metadata.

Next we want to add in useWalletConnectModal and use the useWalletConnectModal hook.

import { StyleSheet, Text, View, Pressable } from "react-native";

import {
WalletConnectModal,
useWalletConnectModal,
} from "@walletconnect/modal-react-native";
// Add in the useWalletConnectModal hook

const projectId = "...";

const providerMetadata = {
name: "YOUR_PROJECT_NAME",
description: "YOUR_PROJECT_DESCRIPTION",
url: "https://your-project-website.com/",
icons: ["https://your-project-logo.com/"],
redirect: {
native: "YOUR_APP_SCHEME://",
universal: "YOUR_APP_UNIVERSAL_LINK.com",
},
};

export default function App() {
// Add in the useWalletConnectModal hook + props
const { open, isConnected, address, provider } = useWalletConnectModal();

// Function to handle the
const handleButtonPress = async () => {
if (isConnected) {
return provider?.disconnect();
}
return open();
};

// Main UI Render
return (
<View style={styles.container}>
<Text style={styles.heading}>WalletConnect Modal RN Tutorial</Text>
<Text>{isConnected ? address : "No Connected"}</Text>
<Pressable onPress={handleButtonPress} style={styles.pressableMargin}>
<Text>{isConnected ? "Disconnect" : "Connect"}</Text>
</Pressable>

<WalletConnectModal
projectId={projectId}
providerMetadata={providerMetadata}
/>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
heading: {
fontSize: 18,
fontWeight: "bold",
marginBottom: 16,
},
pressableMargin: {
marginTop: 16,
},
});

Your UI should look like this:

  • It allows you to Connect to the Wallet (Used Trust Wallet)
  • Then your Wallet should ask for a connection request
  • Then you will be redirected to the React Native dapp. ***
  • You are now connected!
  • You have the option to disconnect.
  • ** Note: That not all mobile Wallets handles redirections well. This is dependant on the wallet of your choice.

Let’s dive into the code changes here:

  1. We imported the useWalletConnectModal
  2. We access the props and functions of it with: open, isConnected, address and provider
  3. We created a handleButtonPress function to allow for .open() which allows for connection and if it is not connected, we have access to the provider and disconnect with provider.disconnect(). For more information on providers, read here.
  4. The rest of the UI in the return function + stylesheet are self-explanatory on handling the React Native UI.

You know have the fundamental legos and building blocks on how to get started and create your first React Native Mobile dapp 👐

In order to further expand on what you can do on the dapp side, you can start to explore

  • ethers.js
  • wagmi/ viem

Then you can start to learn how to interact with the Blockchain RPC and Smart Contracts

  • Sign / Send Messages / Transactions
  • Interact with Smart Contracts (Read or Write)

I will cover this in another blog post / tutorial 🤝

For those with any questions regarding this tutorial, please reach out to me via Twitter or open an issue here on our React Native Repo/Issues

--

--