Skip to main content

Wallets

We have added support for several wallets from the @thirdweb-dev/wallets package.

Below we'll show how to use them with our ThirdwebProvider.

Adding the wallets to the ThirdwebProvider

App.tsx
import {
metamaskWallet,
trustWallet,
localWallet,
walletConnect,
} from "@thirdweb-dev/react-native";

const App = () => {
return (
<ThirdwebProvider
clientId="your-client-id"
activeChain="mumbai"
dAppMeta={{
name: "Example App",
description: "This is an example app",
logoUrl: "https://example.com/logo.png",
url: "https://example.com",
}}
supportedWallets={[
metamaskWallet({
projectId: "your-wallet-connect-project-id", // optional but recommended for production
}),
trustWallet({
projectId: "your-wallet-connect-project-id", // optional but recommended for production
}),
localWallet(),
walletConnect({
projectId: "your-wallet-connect-project-id", // optional but recommended for production
}),
]}
>
<AppInner />
</ThirdwebProvider>
);
};

By default, supportedWallets will have rainbowWallet and metamaskWallet since these two are the easiest to configure.

Configuring wallets

WalletConnect

Implementation of the WalletConnect protocol. The dAppMeta prop passed in the ThirdwebProvider above will be used when connecting to the wallets to show your app's information.

import { walletConnect, ThirdwebProvider } from "@thirdweb-dev/react-native";
import { Ethereum } from "@thirdweb-dev/chains";

const App = () => {
const activeChain = Ethereum;
return (
<ThirdwebProvider
clientId="your-client-id"
activeChain={activeChain}
supportedChains={[activeChain]}
supportedWallets={[
walletConnect({
projectId: "your-wallet-connect-project-id", // optional but we recommend you get your own for production
}),
]}
>
<AppInner />
</ThirdwebProvider>
);
};

MetaMask, Rainbow and Trust wallets

These wallets are just wrappers around WalletConnect. The dAppMeta prop passed in the ThirdwebProvider above will be used when connecting to the wallets to show your app's information.

import {
metamaskWallet,
rainbowWallet,
trustWallet,
ThirdwebProvider,
} from "@thirdweb-dev/react-native";
import { Ethereum } from "@thirdweb-dev/chains";

const App = () => {
const activeChain = Ethereum;
return (
<ThirdwebProvider
clientId="your-client-id"
activeChain={activeChain}
supportedChains={[activeChain]}
supportedWallets={[
metamaskWallet({
projectId: "your-wallet-connect-project-id", // optional but we recommend you get your own for production
}),
rainbowWallet({
projectId: "your-wallet-connect-project-id", // optional but we recommend you get your own for production
}),
metamaskWallet({
trustWallet: "your-wallet-connect-project-id", // optional but we recommend you get your own for production
}),
]}
>
<AppInner />
</ThirdwebProvider>
);
};

Coinbase Wallet

To configure the Coinbase Wallet you need to follow the steps outlined in their Setup Guide. A few caveats before going through the guide:

  1. For Android, you only need to declare the <queries> tag in the AndroidManifest.xml if your app targets Android 11 (API level 30)
  2. For iOS, you need to setup UniversalLinks to allow the wallet to communicate back to your app, otherwise the wallet will not redirect you back to the app. You can pass your app's UniversalLink when you create the Coinbase Wallet:
App.tsx
import { coinbaseWallet } from "@thirdweb-dev/react-native";

const App = () => {
return (
<ThirdwebProvider
clientId="your-client-id"
supportedWallets={[
coinbaseWallet({
callbackURL: new URL("https://youruniversal.link"),
}),
]}
>
<AppInner />
</ThirdwebProvider>
);
};

Local Wallet

The local wallet works mostly the same as the web version, below we outline the key differences:

Configuration

storage (optional)

This is the storage used for storing the private key, mnemonic or encrypted JSON. On React Native we need this storage to be encrypted since we store the private key to be able to recover your wallet for reconnections.

You can use any implementation of encrypted storage you want, as long as it conforms to the AsyncStorage interface:

export interface AsyncStorage {
getItem(key: string): Promise<string | null>;
setItem(key: string, value: string): Promise<void>;
removeItem(key: string): Promise<void>;
}

If omitted, it defaults to Expo Secure Store, which stores the private key in your device in encrypted storage. We expose the createSecureStorage(name: string) utility function which creates a SecureStore instance that conforms to our AsyncStorage interface (see it in our GitHub)

Example:

import { createSecureStorage, LocalWallet } from "@thirdweb-dev/react-native";

const walletWithOptions = new LocalWallet(
{
storage: createSecureStorage("my-wallet"),
},
);

Smart Wallet

See our Smart Wallet documentation for a more comprehensive description of the mandatory fields of this wallet. Here we'll just describe what's needed to connect your wallet to any dApp.

Connect to a dApp

We have added extra configuration parameters to be able to connect to any dApp. Before you can use this feature of Smart Wallet you need to configure your app to support the camera usage to be able to scan WalletConnect QR codes:

yarn add react-native-camera && cd ios && pod install

Add the following code to your android/app/build.gradle file:

missingDimensionStrategy 'react-native-camera', 'general'
defaultConfig {
applicationId "app.id"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
missingDimensionStrategy 'react-native-camera', 'general'
}

Add the NSCameraUsageDescription in your Info.plist file to explain why your app needs to use the Camera. Example:

<key>NSCameraUsageDescription</key>
<string>The app uses the camera to scan QR codes</string>

After adding the camera package, you are ready to use the feature!

Configuration

The following configuration enables Connect to App behavior in React Native:

enableConnectApp

Adds a UI component to the SmartWallet connected dialog to be able to scan a WalletConnect QR code or input a WalletConnect (wc://) uri.

Defaults to false.

import { Mumbai } from '@thirdweb-dev/chains';
import { ThirdwebProvider, metamaskWallet, smartWallet } from '@thirdweb-dev/react-native';

...

<ThirdwebProvider
clientId="your-client-id"
activeChain={Mumbai}
supportedWallets={[
smartWallet({
factoryAddress: "..."
gasless: true,
personalWallets: [localWallet()],
enableConnectApp: true,
}),
metamaskWallet(),
]}>
wcVersion

You can choose the WalletConnect version to support. Either 'v1' or 'v2'.

Defaults to 'v2'.

Note that WalletConnect v1 is no longer maintained and will be shutdown on June 28th, 2023

walletConnectV2ProjectId

The WalletConnect projectId. You can get one in the WalletConnect docs.

Defaults to a common projectId set by thirdweb. This should be ok for testing but note that if you want to deploy your mobile app it may make sense to create your own as WalletConnect may throttle traffic coming from the same projectId.

walletConnectV2RelayUrl

Define a custom Relay Server URL. Defaults to "wss://relay.walletconnect.com"

walletConnectWalletMetadata

Metadata that will be displayed in the dApp once your SmartWallet is connected to it.

{
name: string; // defaults to: "Thirdweb Smart Wallet",
description: string; // defaults to: "Thirdweb Smart Wallet",
url: string: // defaults to: "https://thirdweb.com",
icons: string[]; // defaults to: ["https://thirdweb.com/favicon.ico"],
};
wcStorage

Synchronous storage needed by WalletConnect V2.

Defaults to synchronous storage implemented with MMKV.

Email/Phone Number Wallet

We implemented this feature using the Magic SDK.

Add Magic's dependencies

The @magic-sdk has a few dependencies you need to add to your app before using the SDK in React Native. For convenience you can run:

yarn add react-native-safe-area-context@4.5.3 react-native-webview react-native-device-info && cd ios && pod install

which will install the following dependencies:

You also need a Magic api-key to pass it as part of the wallet config.

Using the new wallet

NOTE: magicWallet has been deprecated starting in version @thirdweb-dev/react-native@0.2.49 in favor of magicLink for consistency with our React SDK.

We suggest you add magicLink as the first wallet in your supportedWallets list since the UI for it is a TextInput field:

import { Goerli } from '@thirdweb-dev/chains';
import { ThirdwebProvider, magicLink, metamaskWallet } from '@thirdweb-dev/react-native';

<ThirdwebProvider
clientId="your-client-id"
activeChain={Goerli}
supportedWallets={[
magicLink({
apiKey: 'magic_api_key',
}),
metamaskWallet(),
]}>

Building your own wallet

With our @thirdweb-dev/wallets sdk you can build your own wallets and integrate it into our ConnectWallet button. You can see how to build one in the Building a Wallet section of our wallets documentation.

Integrating wallets that support the WalletConnect protocol

We have made it super easy to integrate wallets that support the WalletConnect protocol. We have the abstract class, WalletConnectBase that do all the work for you, you only need to set the wallet metadata and you are set to pass the new wallet in our ThirdwebProvider's supportedWallets prop.

The following example shows you how to create a MyWallet wallet that implements the WalletConnectBase protocol:

import {
WCMeta,
WalletConnectBase,
WalletOptions,
WalletConfig,
} from '@thirdweb-dev/react-native';

export class MyWallet extends WalletConnectBase {
static id = 'mywallet' as const; // ID needed to identify your wallet in the SDK.
static meta = {
name: 'My Wallet', // Name that will show up in our Connect Modal.
iconURL:
'my-wallet-icon-url-ipfs-or-png', // Icon that will show up in our Connect Modal.
links: { // The WalletConnect mobile links.
native: 'mywallet://',
universal: 'https://mywallet.com',
},
};

getMeta(): WCMeta {
return MyWallet.meta;
}
}

/**
* The WalletConnect projectId.
*
* We provide a default projectId but recommend you get your own
* when launching your app in production.
*/
type MyWalletConfig = { projectId?: string };

export const myWallet = (config?: MyWalletConfig): WalletConfig<WalletConnectBase> => {
return {
id: MyWallet.id,
meta: MyWallet.meta,
create: (options: WalletOptions) =>
new MyWallet({
...options,
projectId: config?.projectId,
walletId: MyWallet.id,
}),
};
};

You can then use your new wallet in the ThirdwebProvider's supportedWallets prop:

import { ThirdwebProvider } from "@thirdweb-dev/react-native";

<ThirdwebProvider clientId="your-client-id" supportedWallets={[myWallet()]}>
<App />
</ThirdwebProvider>;

Built-in wallets

You can look at how the built-in wallets in the @thirdweb-dev/react-native package are implemented for reference: