Estimated time: 5 minutes read
What is the user wallet connection?
Any operation triggered from a decentralized application that changes the blockchain state, whether a write operation or a transaction, requires setting up the user wallet connection.
The user wallet stores the cryptographic keys necessary to transact with the blockchain and access the registered digital assets.
The two main components of a user wallet are the public key, which derives the address identifying the wallet owner, and the private key, which allows signing transactions and proving ownership of the assets stored under the public address.
The following sections will outline the main components for managing the user wallet connection in a React-based DApp.
Connection Modal
Possibly the most common way to allow users to select their preferred wallet to interact with the DApp is by integrating a framework that provides a connection modal. This modal can be parameterized with various aspects, such as the list of compatible wallets, supported networks, and how the modal is visually presented in the user interface.
Some of the most popular libraries in this area include Reown’s AppKit (formerly known as Web3Modal), RainbowKit, and Blocknative’s Web3 Onboard.
In this case, AppKit was chosen due to its easy integration with the Wagmi library and its full compatibility with the WalletConnect connection option, which will be discussed later.
Wagmi is a reactive library that simplifies interactions between DApps and the blockchain in many aspects, such as connecting wallets, switching networks, signing messages, and sending transactions.
The following code snippets outline the integration of these components.
First, the compatible networks and RPC endpoints for accessing the chosen node provider to interact with the blockchain are configured. These are defined using constants declared in another file:
import { sepolia, baseSepolia } from '@wagmi/core/chains'
const chains = [baseSepolia, sepolia];
const transports = {};
chains.forEach(chain => {
if (chain.id === SEPOLIA.chainId) {
transports[chain.id] = http(SEPOLIA.rpcUrl, { timeout: 5_000, });
}
else if (chain.id === BASE_SEPOLIA.chainId) {
transports[chain.id] = http(BASE_SEPOLIA.rpcUrl, { timeout: 5_000, });
}
else return;
})
The next step is to define the connectors for the Wagmi library to support user wallets. For now, only “injected” wallets are configured—those typically installed as a browser extension using the protocol defined in EIP-1193. The most common example of this type of wallet is MetaMask.
// Connectors for Wagmi config
const connectors = [
injected({
shimDisconnect: true,
}),
]
The following snippet configures the Wagmi library with all the previously mentioned elements. While it’s common to use Wagmi’s “createConfig” function, in this example, the WagmiAdapter wrapper provided by the AppKit library is used to directly integrate Wagmi with the connection modal. Note that a projectId created through the Reown dashboard is required.
export const wagmiAdapter = new WagmiAdapter({
projectId: WALLET_CONNECT_PROJECT_ID,
networks: chains,
transports,
connectors,
});
Next, the connection modal is created. The configuration options are documented on the component’s page:
const web3Modal = createAppKit({
themeMode: 'light',
adapters: [wagmiAdapter],
defaultNetwork: baseSepolia,
networks: chains,
projectId: WALLET_CONNECT_PROJECT_ID,
enableWalletConnect: true,
debug: true,
features: {
email: false,
socials: false,
analytics: false,
swaps: false,
onramp: false,
legalCheckbox: false
},
allWallets: 'SHOW',
});
The direct integration with WalletConnect can be observed. This is an open protocol that enables connecting a wallet with a decentralized application by establishing a secure, end-to-end encrypted connection between the two. For example, this allows signing blockchain transactions in a desktop DApp using a wallet installed on a mobile device. The only requirement is that the wallet supports the WalletConnect protocol.
Additionally, the configuration of the “allWallets” element is visible, which displays the full list of wallets compatible with the connection modal. This achieves broad compatibility without the need to explicitly integrate specific connectors into the Wagmi library.
Finally, the components in the React application would need to be defined:
// Main react app wrapper component
export function WalletConnectors() {
return (
<WagmiProvider config={wagmiAdapter.wagmiConfig}>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</WagmiProvider>
);
}
To invoke the connection modal from our DApp, the <appkit-button /> element provided by AppKit can be used directly. This is a global HTML element that does not require importing to be used.
Its inclusion will display the classic “Connect Wallet” button. After establishing the connection, it will automatically be replaced by a button that shows the public address and allows opening the wallet.
Below are several images illustrating the process, with the connection modal at the center:
Social Login
One of the main barriers to the adoption of web3 applications is the inherent complexity of managing a self-custodial user wallet, where security is the sole responsibility of its owner.
The advantage of self-custodial wallets compared to custodial ones is that the control of digital assets is also exclusively in the hands of the owner.
Since the inception of early web3 applications, the most common method for creating self-custodial user wallets has been to generate them from a seed phrase—a series of 12, 18, or 24 words that can generate and recover the cryptographic keys associated with deterministic wallets, following the BIP-39 standard.
The process of creating such wallets differs significantly from traditional account creation mechanisms in the web2 world, creating substantial friction for new users. Additionally, the key to recovering and migrating the wallet to another device is the seed phrase. Losing it or exposing it to theft can result in the loss of ownership of all digital assets associated with the wallet.
To address these challenges, recent initiatives have emerged that allow the creation of self-custodial wallets through more familiar processes, such as using an email address or a passkey stored securely.
This article explores Particle’s user wallet, a Wallet-as-a-Service solution that enables the creation of wallet cryptographic keys using an email address or a social media account. The private keys are securely stored, split between the user’s device and the provider’s network, allowing account recovery through the same method used during creation (e.g., email).
To integrate Particle’s wallet with the connection modal, you can follow this integration guide, along with the page detailing the configuration options.
The result can be seen in the following code snippets:
const particleConfig = {
projectId: PARTICLE_PROJECT_ID,
clientKey: PARTICLE_CLIENT_KEY,
appId: PARTICLE_APP_ID,
web3Modal,
authTypes: [AuthType.email],
fiatCoin: "EUR",
themeType: "light",
promptSettingConfig: {
promptPaymentPasswordSettingWhenSign: 0,
promptMasterPasswordSettingWhenLogin: 0,
},
wallet: {
visible: false,
customStyle: {
supportAddToken: true,
supportChains: [BaseSepolia, EthereumSepolia],
}
},
}
// Main react app wrapper component
export function WalletConnectors() {
return (
<AuthCoreContextProvider options={particleConfig}>
<WagmiProvider config={wagmiAdapter.wagmiConfig}>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</WagmiProvider>
</AuthCoreContextProvider>
);
}
Login with the Particle wallet would look like this:
Conclusion: Making Web3 Adoption Easier for New Users
The first step to interacting with any decentralized application is connecting a user wallet, which identifies the signer of transactions on the blockchain.
This article introduced several libraries and services that help integrate components into applications to simplify the user wallet connection:
- Particle Wallet to create a blockchain address using an email.
- AppKit’s connection modal to achieve maximum wallet compatibility.
- Wagmi library to manage the connection and interaction with the blockchain in a React application.
The next area to explore will be managing blockchain transactions—another critical aspect that often creates friction for web3 application users.
What libraries do you use to connect the user wallet in your DApps? Did you find the suggestions in this article interesting?
If you want to make it easier for your users to adopt your web3 applications and services, I can help you choose the best options. Feel free to contact me, and let’s talk!