Connect Your NextJS/React Dapp to the Algorand Blockchain Using AlgoSDK ⚡

Easy-guide to start your first interaction with the Algorand Blockchain.

Connect Your NextJS/React Dapp to the Algorand Blockchain Using AlgoSDK ⚡

Introduction

Blockchain technology is revolutionizing how we think about digital interactions, and Algorand stands at the forefront of this transformation. As a high-performance, decentralized blockchain, Algorand offers developers a robust platform for building next-generation decentralized applications (Dapps).

This guide is designed for developers of all levels who want to understand how to connect a NextJS/React application to the Algorand blockchain. Whether you're a blockchain novice or an experienced developer, this tutorial will walk you through the process step-by-step.

Prerequisites

Before diving into the implementation, ensure you have the following:

  • Basic understanding of React and NextJS

  • Node.js (version 16 or higher)

  • npm or pnpm package manager

  • Familiarity with TypeScript

  • A code editor (VS Code recommended)

Required Tools

  • Algorand Wallet (Pera, Defly, etc.)

  • AlgoSDK

  • @txnlab/use-wallet-react library

Understanding the Blockchain Connection

Connecting a web application to a blockchain involves several key concepts:

Wallet Connection

A wallet connection allows users to interact with blockchain networks by:

  • Authenticating their identity

  • Signing transactions

  • Managing account balances

Key Libraries

  1. AlgoSDK: Official Algorand JavaScript SDK for transaction creation and blockchain interactions

  2. @txnlab/use-wallet-react: Simplified wallet connection library for React applications

  3. NextJS Providers: For managing application-wide state and configurations

Project Setup

Step 1: Create a New NextJS Project or React

npx create-next-app@latest algorand-dapp
cd algorand-dapp

Step 2: Install Dependencies

  1. Install AlgoSDK ( Used for interacting with the Algorand blockchain through the Javascript/Typescript environment. ) Refer to this link

    *Note: Please install the same version, the latest version might not support the function calls

 npm install algosdk@2.9.0
  1. Install Txn-Lab Use-wallet Library ( This article uses all the function calls from use-wallet library provided by Txn-Lab , also article is inspired by the same docs )

    It’s super-helpful to integrate and interact with Algorand Blockchain using this library, you can read more about it here -
    Article Reference :
    https://txnlab.gitbook.io/use-wallet

npm install @txnlab/use-wallet-react algosdk
  1. You are almost ready to go; you just need to install the respective Wallet libraries to interact with that wallet.

    In the Use-wallet library, you have the WalletManager library where you can add multiple wallets that support Algorand Blockchain, for some of them you need to install their respective libraries to start the interaction.

    For famous wallets like Pera, Defly you can install their libraries

npm install "perawallet/connect"
npm install "blockshake/defly-connect"

Wallet-specific dependencies

Some wallets require additional packages to be installed. The following table lists wallet providers and their corresponding packages.

Wallet Provider Package(s)

Defly Wallet @blockshake/defly-connect

Pera Wallet @perawallet/connect

WalletConnect @walletconnect/sign-client, @walletconnect/modal

Lute Wallet lute-connect

Magic magic-sdk, @magic-ext/algorand

Kibisis @agoralabs-sh/avm-web-provider

Liquid Auth @algorandfoundation/liquid-auth-use-wallet-client

Refer Here

You’re ready 🚀!!! You have all your tools and now can start implementing the Wallet connection module and interact with the Algorand Blockchain.

If you’re using NextJS for your project, please refer to this link to configure your config file for additional error resolution.

Step 3: Configure Wallet Providers

  • In your Provider.tsx, set up wallet configurations: ( If not create one file with Provider.tsx )
import { NetworkId, WalletId, WalletManager, WalletProvider } from '@txnlab/use-wallet-react';

const walletManager = new WalletManager({
    wallets: [
      WalletId.DEFLY,
      WalletId.PERA,
      {
        id: WalletId.WALLETCONNECT,
        options: { projectId: 'your_project_id' }
      }
    ],
    network: NetworkId.TESTNET
})

export function Providers({ children }: { children: React.ReactNode }) {
    return <WalletProvider manager={walletManager}>{children}</WalletProvider>
}

Reference Link, Link2

Supported Wallets

  • Wrap your Provider in the main component ( layout.tsx or main.tsx )
import { Providers } from "./Provider";

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        <Providers>
        {children}
        </Providers>
      </body>
    </html>
  );
}

Wallet Connection Implementation

Now you’re all set, you just need to create good modal with UI as you want, here we’re using shadcn UI library for WalletModal , you can install and read more about this here - link

Creating a Wallet Connection Modal

"use client";

import React , { useEffect }  from "react"
import { Dialog, DialogContent } from "@/components/ui/dialog"

interface ModalProps {
  isOpen: boolean
  onClose: () => void
  children: React.ReactNode
}

export function Modal({ isOpen, onClose, children }: ModalProps) {
    useEffect(() => {
        if (isOpen) {
          document.body.classList.add("modal-open");
        } else {
          document.body.classList.remove("modal-open");
        }
      }, [isOpen]);

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent className="max-w-lg" >{children}</DialogContent>
    </Dialog>
  )
}

Now you need to pass props to this Modal component from your Connect Wallet Button, and set UI


"use client";

import React, { useState , useEffect } from "react";
import { useWallet, type Wallet } from "@txnlab/use-wallet-react";
import { Modal } from "@/components/WalletModal";
import { Button } from "@/components/ui/button"
import algosdk from "algosdk";


export default function Home() {

  const {
    algodClient,
    activeAddress,
    activeNetwork,
    setActiveNetwork,
    transactionSigner,
    wallets,
  } = useWallet();

  // const [isSending, setIsSending] = React.useState(false);
  const [isModalOpen, setIsModalOpen] = useState(false)
  const [balance, setBalance] = useState<number | null>(null)
  const [transactionInProgress, setTransactionInProgress] =
  useState<boolean>(false);
const [isSending, setIsSending] = useState(false);
const [transactionLink, setTransactionLink] = useState('');

  const handleConnect = () => {
    setIsModalOpen(true)
  }

  const handleDisconnect = () => {
    const activeWallet = wallets.find(wallet => wallet.isConnected)
    if (activeWallet) {
      activeWallet.disconnect()

    }
  }

return (
    <>
      {activeAddress ? (
        <div className="flex justify-center items-center space-x-4 min-h-screen">
          <Button onClick={handleDisconnect} variant="outline">
            Disconnect
          </Button>
        </div>
      ) : (
        <div className="flex justify-center items-center min-h-screen">
        <Button onClick={handleConnect}>Connect Wallet</Button>
        </div>
      )}

      <Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)}>
        <WalletList onClose={() => setIsModalOpen(false)} />
      </Modal>
    </>
  )
}

function WalletList({ onClose }: { onClose: () => void }) {
  const { wallets } = useWallet()

  const handleConnect = async (wallet: Wallet) => {
    await wallet.connect()
    onClose()
  }

  return (
    <div className="p-2">
      <h2 className="text-lg font-bold mb-4 text-center">Connect Your Wallet</h2>
      <div className="space-y-2">
        {wallets.map((wallet) => (
          <div key={wallet.id} className="w-full mb-2 flex justify-center">
          <Button
            key={wallet.id}
            onClick={() => handleConnect(wallet)}
            className="w-[50%] justify-center"
          >
            {wallet.metadata.name}
            <span className="flex-1" />
            <img src={wallet.metadata.icon} alt="wallet icon" className="w-6 h-6 mr-2" />

          </Button>
          </div>
        ))}
      </div>
    </div>
  )
}

Now you can connect your wallet to your application easily! Link reference

Transaction Handling

From AlgoSdk you can use multiple different functions for signing the transaction, verifying, opt-in, in-app calls & many more. You can explore more here

 const sendTransaction = async () => {
      try {
        if (!activeAddress) {
          throw new Error("[App] No active account");
        }

        const at = new algosdk.AtomicTransactionComposer();
        const suggestedParams = await algodClient.getTransactionParams().do();
        const transaction = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
          from: activeAddress,
          to: activeAddress,
          amount: 0, // Zero amount for testing
          note: new Uint8Array(Buffer.from("Please verify your wallet!")),
          suggestedParams,
        });

        at.addTransaction({ txn: transaction, signer: transactionSigner });

        setIsSending(true);

        try {

          const result = await at.execute(algodClient,4);
          const explorerLink = `https://testnet.explorer.perawallet.app/tx/${result.txIDs}`;
          setTransactionLink(explorerLink);
          alert(`Transaction sent! ${explorerLink}`);
          console.log(explorerLink);

       console.info(`[App] ✅ Successfully sent transaction!`, result);


        } catch (error) {
          console.error('Transaction failed', error);

          } finally {
            setIsSending(false);
          }
        }
        catch (error) {
          console.error('Transaction failed', error);

        } finally {
          setIsSending(false);
        }
      };

Finally 🎉🎉🎉 YOU have interacted with the world’s fastest enterprise-grade blockchain - Algorand 🥳 ( Don’t worry your app will be quantum-proof on Algorand! )

  • Test Our Demo Application Here

Best Practices

  1. Always use testnet/localnet for development

  2. Implement proper error handling

  3. Validate transactions before sending

  4. Keep wallet connection logic modular

  5. Use environment variables for sensitive configurations

Conclusion

Connecting a NextJS/React application to Algorand opens up exciting possibilities for decentralized applications. By understanding wallet connections, transaction signing, and blockchain interactions, you're now equipped to build robust Dapps 😎.

Next Steps

  • Explore smart contract interactions

  • Implement more complex transaction types

  • Learn about Algokit where you can create a template for kickstarting your development!

In the next article of this series, we will explore more complex implementations using algosdk. Then, we will learn how to develop Python contracts and integrate them with our frontend.

Happy Building! #AlgorandCan