Solana Wallet Adapter To a Next.Js application
Last updated
Last updated
Next.js is a React framework for building full-stack web applications. You use React components to build user interfaces and Next.js for additional features and optimizations.
You will need to in order to create a Next.js app. We can execute this command, which will create a basic scaffold for us:
It will ask you questions about the project name, Typescript, ESlint, tailwind CSS, src directory, using App router or not, and customizing the default import alias. For this guide, we will use all the default and recommended options for now, including using App router.
This is how the directory structure will look like after creating the scaffold:
In order to allow our applications users connect their favorite Solana wallet, we will need to install and use the various Solana wallet adapter packages. These packages contain essential functions, hooks, and React components required to integrate Solana wallets into our NextJS app.
To allow for better composability and smaller production builds, the "standard wallet adapter" functionality is split into a few different packages:
@solana/wallet-adapter-base
includes functions that detect wallets the user has installed and sign/send transactions from a wallet
@solana/wallet-adapter-react
includes the functionality to help manage the user's wallet state within your React based application, including giving access to hooks like useConnection
and useWallet
@solana/wallet-adapter-react-ui
provides several base UI components related to wallet operations, including a wallet connect/disconnect button and wallet selection modal contexts and providers
Install these packages to your Next.js project using your preferred node package manager:
3. Setting up Wallet Adapter in your Next.js app
This section will help you set up the Next.js app so that we can use all the Solana wallet features inside all the future pages you create.
Your folder structure should look like this:
INFO
This AppWalletProvider.tsx
file we are creating will be rendered on the client side, NOT the server side. So we will need to add the "use client"
directive to the top of the file to make sure NextJS renders our context and children on the client side.
First, we will need to import all the dependencies into the file, including the standard context providers from the wallet adapter packages like connectionProvider
and WalletProvider
.
WalletAdapterNetwork
is an enum that defines default network values like mainnet-beta
, testnet
, and devnet
.
the WalletModalProvider
from @solana/wallet-adapter-base
has the context of a "connect wallet" button. This button helps you toggle the connect wallet modal component's visibility, allowing your users to select their Solana wallet to connect to your application.
UnsafeBurnerWalletAdapter
is a react component shipped by the wallet adapter maintainers for testing wallets. This Burner Wallet is the default wallet adapter used in the starter packs. This adapter implements the Wallet Adapter interface but uses an unsafe local keypair to sign messages.
Since we are using the standard wallet adapter UI components, we also must import the provided standard CSS styles required for these react components to be displayed properly in our application. Each of these styles can be easily overridden to customize the look.
Let’s import these dependencies and use them further in the context/provider component we are building:
AppWalletProvider.tsx
There are two ways to support the various Solana wallets your user's will want to use within your application:
Our AppWalletProvider
component will be used to facilitate the connection to the desired Solana network cluster (i.e. devnet
, mainnet-beta
, etc) via our desired RPC endpoint. This RPC endpoint will be where our application sends the transactions. In our guide here, we are hardcoded here to use the devnet
network cluster.
In this example, we are also defining an array called wallets
. This array contains any of the legacy wallet adapter wallets you desire to import and support within your application. Again though, you will likely not need to have any entries in this array.
AppWalletProvider.tsx
We pass the endpoint
and wallets
variables into the ConnectionProvider
and WalletProvider
as props to those providers given to us by the wallet adapter packages. The autoConnect
prop is the setting that declares whether your application should attempt to auto connect to a user's previously connected wallet when your application loads.
WalletModalProvider
has a component called WalletModal
which helps your users select a wallet from a list of available and installed wallets in the environment (i.e. their web browser). This provider will help that modal toggle visibility in the children components.
With our AppWalletAdapter
context setup and ready-to-go, we need to wrap our NextJS application with this context to make its APIs, hooks, and state accessible within the rest of our application and child pages.
Inside your root layout.tsx
, import your AppWalletAdapter
provider and pass in the application's children
as the children of the AppWalletAdapter
component:
src/app/layout.tsx
With after the steps above completed and AppWalletAdapter
setup properly, your NextJS application is ready to start interacting with user wallets.
The "connect wallet" button is a common component that will allow your users to open the "select wallet modal" and chose their desired Solana wallet to connect to your application.
Normally, developers add this connect wallet button component to their primary header component so that the connect button is viewable and accessible to on all other pages. Enabling users to easily connect their wallet wherever they are within your application. However, for the simplicity of this guide, we are adding the wallet connect to the home page:
In your page.tsx
at the root of your app
folder, import the WalletMultiButton
from @solana/wallet-adapter-react-ui
. Then, you can return that button component from your home page component.
src/app/page.tsx
Now start your dev server and see the website served in your browser:
Here's a demo of how output should look in your browser with the default styles provided from the wallet adapter packages:
The most common ways your application will interact with your user's Solana wallet is using the useWallet
and useConnection
hooks provided by the wallet adapter packages and accessible to all child components of your AppWalletAdapter
context.
From the @solana/wallet-adapter-react
package, you can import the two hooks named useWallet
and useConnection
that can be used anywhere on the client side of your app that is a child of your AppWalletAdapter
context. In this example guide, it will be your entire application.
the useWallet
hook has details like publicKey
and state of the wallet, whether it’s connecting
or it’s connected
.
the useConnection
hook will facilitate your application's connection to the Solana blockchain, via your RPC endpoint
INFO
Here’s an example of getting the SOL balance of the wallet connected using the useConnection
and useWallet
hooks.
With functions like these and the ones provided within the wallet adapter packages, you can detect whether the user's wallet is connected or not, create a button to get an airdrop of devnet or sol in the network defined, and more.
Let’s make another page now to demonstrate how we can use each of these hooks to access actually access the connection
object and your user's wallet state to send or sign transactions, read the wallet balance, and test functionality.
Create a new folder inside the app
folder and name it address
. Create a file page.tsx
inside that folder. In this example, our new page will be located at src/app/address/page.tsx
:
In side of your new page, we can create use utilize the hooks and custom function we discussed above to allow the user to actually perform these interactions with their Solana wallet of choice:
src/app/address/page.tsx
Here's what your address page will look like when the wallet is connected on the home page.
You can use the useWallet
hook to trigger a user's connected Solana wallet to ask then to sign a transaction or a plain message that your application provides to the wallet
If you are creating a brand new application or project, you can also use the create-solana-dapp
CLI took to generate a scaffold with the built-in Solana wallet adapter. To scaffold a new application, run the CLI tool in your terminal:
It will prompt you for common information (like your project name and desired frontend framework) and will generate a customized project, fully configured with Solana wallet adapter configured and ready for your users
Create a components
folder and add a file named AppWalletProvider.tsx
. We will export the contents of this file to be used inside .
The goal of this file will be to export a as a react component that will help us “teleport” data and to use (or change) within all of the context's children components. Effectively allowing all this context's children to easily access all the Solana wallet adapter functionality and facilitate user wallet interactions within your application.
Wallets with implementation. These wallets will be automatically detected with @solana/wallet-adapter-base
and do not require you to add any extra code into your application for users to use them.
Wallets with are bundled in an npm package. To support these wallets within your application, you must install and import each of these wallet's legacy adapters into your application.
The most popular Solana wallets already conform to and implement wallet-standard
. So for your user's to use these popular Solana wallets, you do not need to do anything special within your application. They will work automatically and be shown to your users (including ). If there is a specific, non-standard wallet that your users want your application to support, that is when we recommend manually adding it's legacy adapter.
Select and Connect Solana Wallets using Wallet Adapter
Solana uses the which is transport agnostic and can be implemented over HTTP, HTTPS, WebSocket, TCP, and other transports. This means you can use the connection
object returned from the useConnection
hook to get or .
Here's an example of getting a using the connection
and publicKey
from useConnection
and useWallet
hooks.
This getAirdropOnClick
function gets the latest using the RPC method. It also gets the transaction signature from the function from the connection
. We can also verify whether the transaction was and added to the block, ensuring the airdrop was successful and the SOL is available for use.
is an RPC HTTP method you can call from the connection
object to get the SOL balance of any Solana account (like a user's wallet). Calling this function with setTimeout
is good for checking the balance continuously every 10 seconds:
Example "address" page that uses the Solana wallet adapter hooks
You can call from the connection
object (via the useConnection
hook)
You can also checkout the from the creators of . It is an open-sourced wallet adapter alternative that adds some extra functionality, striving for the best Solana wallet integration experience for developers and the best wallet experience for your users.