Integrate with ConnectWallet
If you also want to integrate this wallet with ConnectWallet
component in React SDK or React Native SDK, You have to create a Wallet Configurator function which can be passed to ThirdwebProvider
component
import { WalletConfig } from '@thirdweb-dev/react'function myWallet (options?: MyWalletConfig): WalletConfig<MyWallet> {return {id: 'my-wallet',meta: {name: "My Wallet",iconURL: "https://...", // or ipfs://...// optionalurls: {chrome: "https://...",firefox: "https://...",android: "https://...",ios: "https://...",},},// create and return wallet instancecreate(walletOptions) {return new MyWallet({ ...walletOptions, ...options })}// optional - render a UI for connecting your walletconnectUI(props) {return <MyWalletConnectionUI {...props} />;},// optional - override the default UI for selecting your wallet in the wallet selector screenselectUI(props) {return <MyWalletSelectionUI {...props} />}// optionalisInstalled() {// detect if your wallet extension is installed on the user's browser/devicereturn true; // or false},// optional - show a "recommended" badge below your wallet's name in the wallet selector screenrecommended: true,};};
A unique ID for your wallet. It is used to identify your wallet among other wallets in the app.
It can be anything, but using the name of your wallet as id
is recommended because it
is not likely to be used by other wallets.
metadata of your wallet.
name
and iconURL
are required. They are used to display your wallet in the list of supported wallets in Connect Wallet Modal's Wallet Selector screen.
urls
object is optional and all of its properties are optional as well.
{chrome?: string;android?: string;ios?: string;}
A function that creates and returns the wallet instance.
import type { WalletOptions } from "@thirdweb-dev/wallets";import type { WalletInstance } from "@thirdweb-dev/react";type Create = (walletOptions: WalletOptions) => WalletInstance;
You can create an instance of your wallet using the walletOptions
provided by the create
function and optionally add the options
provided by the myWallet
function.
create(walletOptions) {return new MyWallet({...walletOptions,...options,});}
since the create
method only provides options
of type WalletOptions
- the rest of the wallet-specific configuration (if any) can be exposed as options
of the myWallet
function.
connect(connectUIProps: ConnectUIProps) => React.ReactNode;
A function that returns a React component that renders the UI for connecting your wallet.
This UI will be rendered inside the ConnectWallet Modal when the user clicks on your wallet in the wallet-selector screen.
The connectUI
function provides the props of type ConnectUIProps
which you can use in your UI to trigger various actions - like closing the modal, opening the modal, connecting the wallet, going back to the list of supported wallets etc.
type ConnectUIProps = {walletConfig: WalletConfig;supportedWallets: WalletConfig[];open: () => void;close: (reset?: boolean) => void;isOpen: boolean;goBack: () => void;theme: "dark" | "light";selectionData: any;setSelectionData: (selectiondata: any) => void;};
walletConfig: WalletConfig;
WalletConfig
object of your wallet. You can use it for connecting your wallet and getting metadata
supportedWallets: WalletConfig[];
List of all supported wallets including your wallet.
You can use this to conditionally render UI based on how many wallets are supported.
If only one wallet (your wallet) is supported, ConnectWallet Modal will skip showing the wallet selection screen and directly render the connectUI
of your wallet.
You can detect this by checking if supportedWallets.length === 1
and adjusting your UI accordingly - for example: not rendering a "back" button
open: () => void;
Open the ConnectWallet modal
close: (reset?: boolean) => void;
close the ConnectWallet modal.
If close
is called with true
( reset = true ), the ConnectWallet modal will be reset to its initial state - so that if it's opened again, it will start from the wallet-selection screen. By default reset is true
isOpen: boolean;
Indicates whether the ConnectWallet modal is open or not
goBack: () => void;
Go back to the wallet selector screen in ConnectWallet modal
The theme of the ConnectWallet modal. You can use this to render your connect UI to match the theme of the modal
selectionData: any;
selectionData passed from selectUI
's onSelect
function.
This is only relevant if you are using selectUI
to render a custom UI for selecting your wallet
setSelectionData: (selectiondata: any) => void;
set selectionData
.
This is only relevant if you are creating a connectUI
which involves rendering other wallets and you need to render the selectUI
of those wallets and need to pass down the onSelect
prop.
If no connectUI
is given, the wallet is assumed to be in "headless" mode - meaning that it does not require any UI to be rendered inside the ConnectWallet Modal to connect the wallet - This can be the case if either the wallet has its own UI that is appended to DOM (Example: walletConnect on web) or it does not require any UI at all.
In this case, when the user clicks on your wallet in the wallet selector screen, your wallet is connected using the useConnect
hook and the ConnectWallet Modal is closed.
selectUI(selectUIProps: SelectUIProps) => React.ReactNode;
A function that returns a React component that renders the UI for selecting your wallet.
Instead of the default icon + name in wallet selector screen, you can render a custom UI for your wallet.
Take in-app wallet for example, It renders an Social Icons + Email Input.
In this example, rest of the wallets are put behind a "Connect a wallet" button - that is NOT because the inAppWallet wallet has a custom selectUI
but because the inAppWallet is a social login.
If you add a custom selectUI
to your wallet, This will not be the case and rest of the wallets will be rendered in the same screen below your wallet's selectUI
Wallets with selectUI
are rendered at the top of the list in ConnectWallet Modal's wallet selector screen.
The selectUI
function provides the props of type SelectUIProps
which you can use in your UI to trigger wallet selection and move to the next screen in ConnectWallet Modal using onSelect
and also optionally save user's input using onSelect(data)
which will be passed to connectUI
's selectionData
prop.
type SelectUIProps = {onSelect: (selectionData: any) => void;walletConfig: WalletConfig;supportedWallets: WalletConfig[];};
onSelect: (selectionData: any) => void;
Call this function to "select" your wallet and render the screen for connecting the wallet. You can optionally pass selectionData
to be passed to connectUI
's selectionData
prop
theme: "dark" | "light";
The theme of the ConnectWallet modal. You can use this to render your select UI to match the theme of the ConnectWallet modal
walletConfig: WalletConfig;
WalletConfig
object of your wallet. You can use this to get metadata of your wallet by doing walletConfig.meta
supportedWallets: WalletConfig[];
List of all supported wallets including your wallet.
You can use this to conditionally render UI based on how many wallets are supported.
For example, You can render an "OR" at the bottom of your UI if more than one wallet is supported
A function that returns a boolean indicating whether your wallet is installed on the user's browser/device or not.
It is used to show an "installed" badge below the wallet's name in ConnectWallet Modal if this function is defined and returns true
.
See Coinbase wallet in below screenshot for example:
Set it to true
if the wallet should have the "recommended" badge shown below its name in ConnectWallet Modal.
See MetaMask wallet in below screenshot for example:
import { ConnectUIProps } from '@thirdweb-dev/react';function MyWalletConnectionUI(props: ConnectUIProps<MyWallet>) {return <div> ... </div>}function myWallet (options?: MyWalletConfig): WalletConfig<MyWallet> {// ...connectUI(props) {return <MyWalletConnectionUI {...props} />;}}
There are two ways to connect your wallet in connectUI
The recommended way to connect your wallet is to use the useConnect hook.
import { ConnectUIProps } from "@thirdweb-dev/react";function MyWalletConnectionUI(props: ConnectUIProps<MyWallet>) {const connect = useConnect();// call this function to connect your walletconst handleConnect = async () => {try {await connect(props.walletConfig,connectOptions, // if your MyWallet.connect method accepts any options, specify it here);// close the modal after connecting your walletprops.close();} catch (e) {console.error("failed to connect", e);// show error UI or close modal using props.close();}};return <div> ... </div>;}
You should only use this method if you need access to the wallet instance before connecting your wallet. Otherwise, use the useConnect hook.
There are 3 steps to connect your wallet manually:
- create an instance of your wallet using useCreateWalletInstance
- connect your wallet using the
connect
method of your wallet - once the wallet is connected, set the wallet instance as connected using useSetConnectedWallet
Make sure to update the connectionStatus
using useSetConnectionStatus to "connecting"
before connecting your wallet and "disconnected"
if the connection fails.
import {ConnectUIProps,useCreateWalletInstance,useSetConnectionStatus,useSetConnectedWallet,} from "@thirdweb-dev/react";function MyWalletConnectionUI(props: ConnectUIProps<MyWallet>) {const createWalletInstance = useCreateWalletInstance();const setConnectionStatus = useSetConnectionStatus();const setConnectedWallet = useSetConnectedWallet();// Call this function to connect your walletconst handleConnect = async () => {// 1. create instanceconst walletInstance = createWalletInstance(props.walletConfig);setConnectionStatus("connecting");try {// 2. Call `connect` method of your walletawait walletInstance.connect(connectOptions, // if your MyWallet.connect method accepts any options, specify it here);// 3. Set connected walletsetConnectedWallet(walletInstance);props.close();} catch (e) {setConnectionStatus("disconnected");console.error("failed to connect", e);// show error UI or close modal using props.close()}};return <div> ... </div>;}
Instead of the default icon + name in the wallet selector screen, you can render a custom UI for your wallet.
Take in-app wallet for example, It renders Social Icons + Email Input.
In this example, rest of the wallets are put behind a "Connect a wallet" button - that is NOT because the inAppWallet wallet has a custom selectUI
but because the inAppWallet is a social login.
If you add a custom selectUI
to your wallet, This will not be the case and rest of the wallets will be rendered in the same screen below your wallet's selectUI
This can be done by specifying a React component in the selectUI
property of your wallet config.
import { SelectUIProps, ConnectionUIProps, WalletConfig } from '@thirdweb-dev/react';// example: render an input field where the user can enter their email addressfunction MyWalletSelectionUI(props: SelectUIProps<MyWallet>) {const [email, setEmail] = useState('');const usesMoreWallets = props.supportedWallets.length > 1;return (<div><input value={email} onChange={e => setEmail(e.target.value)} /><buttononClick={() => {props.onSelect(email);}}>submit</button>{usesMoreWallets && <p> --- OR --- </p>}</div>);}function MyWalletConnectionUI(props: SelectUIProps<MyWallet>) {// Get the email address entered by the user in MyWalletSelectionUIconst email = props.selectionData as string;return <div> ... </div>;}function myWallet (options?: MyWalletConfig): WalletConfig<MyWallet> {// ...selectUI(props) {return <MyWalletSelectionUI {...props} />;},connectUI(props) {return <MyWalletConnectionUI {...props} />}}
Add your wallet to ThirdwebProvider
You can now use your wallet with the Connect Wallet button! Simply add it to the supportedWallets
prop of the ThirdwebProvider
.
<ThirdwebProvidersupportedWallets={[myWallet()]}clientId="your-client-id"><App /></ThirdwebProvider>;
You can look at how thirdweb-dev/react
package's built-in wallets are implemented for reference:
If you think your wallet implementation would be useful to others, please consider sharing it by opening a PR to the @thirdweb-dev/wallets
package.