Building a Wallet Connector
The @thirdweb-dev/wallets
package provides a set of pre-built components and functionality for creating and managing cryptocurrency wallets.
The following will guide you through how you can create your own wallet connector in a few simple steps:
- Implement your own
Connector
class - Implement your own
AbstractClientWallet
class - Integrate with Connect Wallet button in React/React Native
At the end of this guide, you should have a fully functional wallet that can be used with the thirdweb TS, React and React Native SDKs.
1. Extending the Connector
class
The Connector
abstract class is the
interface between your wallet core functionality and the actual wallet class you'll use in your application.
This is the biggest part of the wallet implementation and allows to bridge any wallet provider to a standardized interface.
Interface
export class MyConnector extends Connector {
connect(args?: ConnectParams<TConnectParams>): Promise<string>
disconnect(): Promise<void>
getAddress(): Promise<string>
getSigner(): Promise<Signer>
getProvider(): Promise<providers.Provider>
switchChain(chainId: number): Promise<void>
isConnected(): Promise<boolean>
setupListeners(): Promise<void>
updateChains(chains: Chain[]): void
}
You can choose to implement all or part of the connector functionality.
Required methods
connect
This method should trigger the connection flow of your wallet with the user's app.
Configuration
getSigner
Returns a Promise<Signer>
with the ethers signer associated with your wallet.
getProvider
Returns a Promise<providers.Provider>
with the ethers provider associated with your wallet.
disconnect
Disconnect the currently connected wallet from your app.
isConnected
Returns a Promise<boolean>
indicating whether the wallet is connected or not.
getAddress
Returns a Promise<string>
with the currently connected wallet address.
Optional methods
You can throw an exception or leave the implementation empty if you don't want to implement these methods.
switchChain
Switch the chain the wallet is connected to.
setupListeners
This method should set all listeners needed for the wallet to work. It will be used by the AbstractClientWallet
class to set up the listeners
when the wallet is connected.
updateChains
Update the chains the wallet can connect to.
Configuration
2. Extending the AbstractClientWallet
class
Now that the hard part is done, the rest is easy, we just need to wrap our connector in a AbstractClientWallet
class.
The AbstractClientWallet
class is the base
class that provides an interface for interacting with your connector on one side and with applications on the other.
The main method that needs to be overridden is the getConnector
method. This method should return a Promise
that resolves to the Connector
class that you implemented.
export class MyWallet extends AbstractClientWallet {
async getConnector(): Promise<Connector> {
return new MyConnector();
}
}
You can expose any custom logic here as the public API for your wallet.
Required Methods
getConnector
Returns a Promise<Connector>
with the connector class that you implemented.
Using your new wallet
At this point, you should be able to instantiate your new wallet and call connect
on it.
const wallet = new MyWallet();
wallet.connect();
Examples
You can look at how the built-in wallets in @thirdweb-dev/wallets
package are created for reference
3. Integrate with Connect Wallet button
Create a wallet configurator function
The last step is to integrate it with the ConnectWallet by creating a wallet configurator - a function that returns a WalletConfig
object and adding it in ThirdwebProvider's supportedWallets
import { WalletConfig } from '@thirdweb-dev/react'
function myWallet (options?: MyWalletConfig): WalletConfig<MyWallet> {
return {
id: 'my-wallet',
meta: {
name: "My Wallet",
iconURL: "https://...", // or ipfs://...
// optional
urls: {
chrome: "https://...",
firefox: "https://...",
android: "https://...",
ios: "https://...",
},
},
// create and return wallet instance
create(walletOptions) {
return new MyWallet({ ...walletOptions, ...options })
}
// optional - render a UI for connecting your wallet
connectUI(props) {
return <MyWalletConnectionUI {...props} />;
},
// optional - override the default UI for selecting your wallet in the wallet selector screen
selectUI(props) {
return <MyWalletSelectionUI {...props} />
}
// optional
isInstalled() {
// detect if your wallet extension is installed on the user's browser/device
return true; // or false
},
// optional - show a "recommended" badge below your wallet's name in the wallet selector screen
recommended: true,
};
};
Required
id
meta
create
Optional
connectUI
selectUI
isInstalled
recommended
Creating wallet connection UI
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} />;
}
}
Connecting your wallet in wallet connection UI
There are two ways to connect your wallet in connectUI
Using useConnect
hook - Recommended
Manually creating wallet instance and connecting
Rendering a custom UI for selecting your wallet
Instead of the default icon + name in the wallet selector screen, you can render a custom UI for your wallet.
Take Embedded 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 embeddedWallet wallet has a custom selectUI
but because the embeddedWallet 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 address
function 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)} />
<button
onClick={() => {
props.onSelect(email);
}}
>
submit
</button>
{usesMoreWallets && <p> --- OR --- </p>}
</div>
);
}
function MyWalletConnectionUI(props: SelectUIProps<MyWallet>) {
// Get the email address entered by the user in MyWalletSelectionUI
const 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
.
<ThirdwebProvider supportedWallets={[myWallet()]} clientId="your-client-id">
<App />
</ThirdwebProvider>
Examples
You can look at how thirdweb-dev/react
package's built-in wallets are implemented for reference:
Contributing to the Wallets package
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.