Hire the author: Adetayo L
Introduction
Since the public availability of Web3, developers actively create software to facilitate transactions and identification in various scenarios. Wallets, like the Cardano Mesh connect wallet button, enable users to connect to decentralized applications (dApps).
Furthermore, Cardano, a blockchain technology, is gaining popularity due to its versatility and numerous use cases. Mesh, an open-source library that provides tools for building dApps on the Cardano blockchain, is one such tool. Additionally, it includes a ‘Cardano wallet’ button that allows seamless connection to users’ Cardano wallets. However, this issue can be frustrating for users who need to reconnect each time the page reloads.
To address this issue, developers seeking to integrate Cardano wallet functionality into their React app can create a persistent wallet button that remains connected across all pages and after users reload. This tutorial demonstrates the process using React.
Prerequisite
It is mandatory to have a Cardano wallet before continuing, To create a wallet you can follow these steps here.
Glossary
React: According to Wikipedia, “React is a free and open-source front-end JavaScript library for building user interfaces based on reusable UI components. It’s used for handling the view layer for web and mobile apps. The main purpose of React is to be fast, scalable, and simple.”
Mesh: Mesh is an open-source library providing numerous tools to easily build powerful dApps on the Cardano blockchain.
Cardano: According to Wikipedia, “Cardano is a public blockchain platform. It is open-source and decentralized, with consensus achieved using proof of stake. It can facilitate peer-to-peer transactions with its internal cryptocurrency, ADA”.
Step-by-step Procedure
Step 1: Setting up the project
To begin, we first need to set up the project. We’re going to be using Next.js to do this. To create a Next.js project, run:
npx create-next-app persistent-cardano-button
After creating the project, navigate to the project folder and run:
cd persistent-cardano-button
// to run the project
npm run dev
When you run the project you should come to the page below:

Let’s remove the placeholder content provided by Next.js since we won’t be doing much styling. This will leave us with a blank page. Now, it’s time to add a simple background colour to our body.
body {
background: rgb(86, 154, 255);
}
Step 2: Setting up Mesh
To utilize the Mesh library, let’s install it into our project by running the following commands in our console.
npm install @meshsdk/core @meshsdk/react
After the installation is complete, let’s configure our project by adding webpack to the next.config.js file. Now, open the next.config.js file and ensure that it reflects the following configuration:
/** @type {import('next').NextConfig} */ | |
const nextConfig = { | |
reactStrictMode: true, | |
webpack: function (config, options) { | |
config.experiments = { | |
asyncWebAssembly: true, | |
layers: true, | |
}; | |
return config; | |
}, | |
}; | |
module.exports = nextConfig; |
next.config.js
Next, add the MeshProvider to the _app.js file to ensure that the wallet is available to all pages in the project:
import "../styles/globals.css"; | |
import { MeshProvider } from "@meshsdk/react"; | |
function MyApp({ Component, pageProps }: AppProps) { | |
return ( | |
<MeshProvider> | |
<Component {...pageProps} /> | |
</MeshProvider> | |
); | |
} | |
export default MyApp; |
./pages/_app.js
Now, we are good to go.
Step 3: Testing Cardano Component
Import the Cardano wallet button provided by Mesh and observe its functionality as the first step. In the index.js file, add the button by following these instructions:
import { CardanoWallet } from '@meshsdk/react' | |
export default function Home() { | |
return ( | |
<> | |
<Head> | |
<title>Persistent Cardano Button</title> | |
<meta name='description' content='Generated by create next app' /> | |
<meta name='viewport' content='width=device-width, initial-scale=1' /> | |
<link rel='icon' href='/favicon.ico' /> | |
</Head> | |
<main className={`${styles.main} ${inter.className}`}> | |
<CardanoWallet /> | |
</main> | |
</> | |
) | |
} |
./pages/index.js
Our result will be:




We can see the four different states for users where they:
- Initial state: Users who have yet to connect will find the button present but inactive.
- Hover state: When users hover over the button, it responds with a visual change or effect, indicating its interactive nature.
- Connected state: Once users successfully establish a connection, the button reflects this status, confirming their active connection.
- Disconnect option: Hovering over the connected button presents users with the choice to disconnect, offering a convenient way to terminate their connection.
Step 4: Creating the new ConnectWallet Button
After reloading the page, we notice that the button automatically disconnects. Now, let’s take the initiative and create our custom button. To do this, we’ll create a ConnectWallet component and copy the provided code.
import { useState, useEffect } from 'react' | |
import { useWallet, useWalletList } from '@meshsdk/react' | |
import Image from 'next/image' | |
const ConnectWallet = () => { | |
const [selectedWallet, setSelectedWallet] = useState(null) | |
const { connect, disconnect, connecting } = useWallet() | |
const wallets = useWalletList() | |
useEffect(() => { | |
const storedWallet = localStorage.getItem('selectedWallet') | |
if (storedWallet) { | |
setSelectedWallet(JSON.parse(storedWallet)) | |
connect(JSON.parse(storedWallet).name) | |
} | |
}, []) | |
const handleWalletSelection = (wallet) => { | |
localStorage.setItem('selectedWallet', JSON.stringify(wallet)) | |
setSelectedWallet(wallet) | |
connect(wallet.name) | |
} | |
const handleDisconnect = () => { | |
localStorage.removeItem('selectedWallet') | |
disconnect() | |
setSelectedWallet(null) | |
} | |
return ( | |
<> | |
<div> | |
{selectedWallet ? ( | |
<div> | |
<span>{selectedWallet.name}</span> | |
<Image | |
src={selectedWallet.icon} | |
alt={selectedWallet.name} | |
width='30' | |
height='30' | |
/> | |
</div> | |
) : ( | |
<div>connect wallet</div> | |
)} | |
</div> | |
<div> | |
{!selectedWallet && !connecting && ( | |
<ul> | |
{wallets.map((wallet) => ( | |
<li | |
key={wallet.name} | |
onClick={() => handleWalletSelection(wallet)} | |
> | |
<span>{wallet.name}</span> | |
<Image | |
src={wallet.icon} | |
alt={wallet.name} | |
width='30' | |
height='30' | |
/> | |
</li> | |
))} | |
</ul> | |
)} | |
</div> | |
<div> | |
{selectedWallet && | |
<div> | |
disconnect | |
</div> | |
} | |
</div> | |
</> | |
) | |
} | |
export default ConnectWallet |
./components/ConnectWallet/ConnectWallet.js
Here’s a breakdown of what is happening
- The
useState
hook is used to declare theselectedWallet
state variable, which keeps track of the currently selected wallet with an initial value of null. - To connect to a wallet and retrieve a list of available wallets, we utilize the
useWallet
anduseWalletList
hooks from the Mesh SDK React library. - By using the
useEffect
hook, we can check if a selected wallet is stored in local storage. If so, the stored wallet is automatically selected and connected when the component mounts. - Whenever a user clicks on a wallet from the list, the
handleWalletSelection
function is triggered. It stores the selected wallet in local storage, sets theselectedWallet
state accordingly, and establishes a connection to the selected wallet. - The
handleDisconnect
function is called when a user clicks on the “disconnect” button. It removes the selected wallet from local storage, disconnects from the selected wallet, and sets theselectedWallet
state to null. - The component renders three main parts:
- If a wallet is connected, it will display the wallet name, icon, and a “disconnect” button.
- In the absence of a connected wallet and when the
connecting
variable is false, a list of available wallets is shown. - If
connecting
is true, it does not display anything. - To showcase wallet icons, we utilize the
Image
component from thenext/image
library.
Step 5: Styling the component
With these steps, we have everything required to obtain a functional ConnectWallet Button. Now, let’s take an active role and style our component to achieve a similar appearance to the button component provided by Mesh. Feel free to style it according to your design system.
/* Set the position of the dropdown container to relative */ | |
.dropdown { | |
position: relative; | |
} | |
/* Style the button that will show the dropdown on hover */ | |
.dropdown-btn { | |
background-color: #f1f1f1; | |
color: #333; | |
padding: 10px 20px; | |
border: none; | |
cursor: pointer; | |
} | |
/* Style the dropdown content */ | |
.dropdown-content { | |
position: absolute; | |
display: none; | |
background-color: #f1f1f1; | |
padding: 10px 0; | |
margin: 0; /* Remove any margin to make the dropdown appear directly below the button */ | |
border: none; | |
z-index: 1; | |
} | |
/* Show the dropdown content when the button is hovered */ | |
.dropdown:hover .dropdown-content { | |
display: block; | |
} | |
/* Style the links in the dropdown content */ | |
.dropdown-content li { | |
display: block; | |
color: #333; | |
padding: 10px 20px; | |
text-decoration: none; | |
list-style: none; | |
cursor: pointer; | |
} | |
/* Change the background color of links on hover */ | |
.dropdown-content li:hover { | |
background-color: #ddd; | |
} |
styles/global.css
Now, let’s import the connect wallet button to the home page and test it out.
Learning Tools
Some resources that helped me with the project:
Learning Strategy
By actively engaging with the Cardano community, including Gimbalabs, and seeking their valuable insights and suggestions, I devised a thoughtful solution. Additionally, I believe in the importance of asking questions, as diverse perspectives and ideas from various sources can lead to innovative and effective solutions.
Reflective Analysis
If you’re looking to enhance the security of your wallet button and safeguard your users’ valuable data, one possible solution is to explore the use of session storage to store sensitive information securely. Moreover, this approach can provide an additional layer of protection for your users. Additionally, it can be easily implemented through a variety of state management tools and techniques.
By utilizing session storage, you can ensure the safety and security of your users’ data while delivering a streamlined user experience. If you aim to strengthen the security of your wallet button and safeguard your users’ valuable data, implementing session storage is an excellent option to consider.
Conclusions and Future Directions
Despite the lack of tutorials or articles as a reference, I chose this topic out of a desire to solve a pressing problem. Through insightful discussions with friends and fellow developers and a series of experiments, I arrived at this solution.
For future reference, it is crucial for developers to prioritize security measures when implementing this solution, in order to safeguard users’ information. I appreciate you taking the time to read this blog post. It is my sincere hope that the information provided here has been truly beneficial and informative to you in your specific use case.
It is always a great pleasure to be able to assist others in their pursuit of knowledge and understanding, and I am truly grateful for the opportunity to do so. If you have any other questions or concerns, please feel free to contact me for assistance.
Check out the GitHub repository for this project.
Additionally, you can explore some of our other React articles here.
Nice article Adetayol. It is very rare to find information on how to connect to networks that are not EVM-compatible. Your article will be a great resource for developers who would want to build dApps on the Cardano blockchain.
Thanks, one of my motivation for writing is was having similar problems and having trouble finding solutions