Skip to main content

Usage with Next.js

Before you begin, see the installation guide for details.

Setup

Step 1: Create Next.js Project

# Create a new Next.js project
npx create-next-app@latest my-hedera-app
cd my-hedera-app

Step 2: Configure Next.js

Create or update next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config) => {
config.resolve.fallback = {
...config.resolve.fallback,
"crypto": require.resolve("crypto-browserify"),
"stream": require.resolve("stream-browserify"),
"buffer": require.resolve("buffer"),
};
return config;
},
}

module.exports = nextConfig

Step 3: Create WalletProvider

Create providers/WalletProvider.tsx:

'use client';

import { HashinalsWalletConnectSDK } from '@hashgraph/hedera-wallet-connect';
import { createContext, useContext, useEffect, useState, ReactNode } from 'react';

interface WalletContextType {
connect: () => Promise<void>;
disconnect: () => Promise<void>;
accountId: string | null;
balance: number | null;
isConnecting: boolean;
}

const WalletContext = createContext<WalletContextType>({} as WalletContextType);

const PROJECT_ID = process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID!;
const APP_METADATA = {
name: 'My Hedera App',
description: 'Next.js app using Hashinal WalletConnect',
url: typeof window !== 'undefined' ? window.location.origin : '',
icons: ['https://your-app-icon.com/icon.png']
};

export function WalletProvider({ children }: { children: ReactNode }) {
const [sdk, setSdk] = useState<HashinalsWalletConnectSDK | null>(null);
const [accountId, setAccountId] = useState<string | null>(null);
const [balance, setBalance] = useState<number | null>(null);
const [isConnecting, setIsConnecting] = useState(false);

useEffect(() => {
const initSDK = async () => {
const instance = HashinalsWalletConnectSDK.getInstance();
setSdk(instance);

try {
const existingAccount = await instance.initAccount(
PROJECT_ID,
APP_METADATA
);
if (existingAccount) {
setAccountId(existingAccount.accountId);
setBalance(existingAccount.balance);
}
} catch (error) {
console.error('Failed to init wallet:', error);
}
};

initSDK();
}, []);

const connect = async () => {
if (!sdk) return;
setIsConnecting(true);
try {
const { accountId, balance } = await sdk.connectWallet(
PROJECT_ID,
APP_METADATA
);
setAccountId(accountId);
setBalance(balance);
} catch (error) {
console.error('Failed to connect wallet:', error);
throw error;
} finally {
setIsConnecting(false);
}
};

const disconnect = async () => {
if (!sdk) return;
try {
await sdk.disconnectWallet();
setAccountId(null);
setBalance(null);
} catch (error) {
console.error('Failed to disconnect wallet:', error);
throw error;
}
};

return (
<WalletContext.Provider
value={{
connect,
disconnect,
accountId,
balance,
isConnecting
}}
>
{children}
</WalletContext.Provider>
);
}

export const useWallet = () => useContext(WalletContext);

Step 4: Update Root Layout

Update app/layout.tsx:

import { WalletProvider } from '@/providers/WalletProvider'

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<WalletProvider>
{children}
</WalletProvider>
</body>
</html>
)
}

Step 5: Create Wallet Component

Create components/WalletButton.tsx:

'use client';

import { useWallet } from '@/providers/WalletProvider';

export function WalletButton() {
const { connect, disconnect, accountId, balance, isConnecting } = useWallet();

if (isConnecting) {
return <button disabled>Connecting...</button>;
}

if (accountId) {
return (
<div>
<div>Account: {accountId}</div>
<div>Balance: {balance} HBAR</div>
<button onClick={disconnect}>Disconnect</button>
</div>
);
}

return <button onClick={connect}>Connect Wallet</button>;
}

Step 6: Use in Page

Update app/page.tsx:

import { WalletButton } from '@/components/WalletButton';

export default function Home() {
return (
<main className="min-h-screen p-24">
<h1>My Hedera App</h1>
<WalletButton />
</main>
);
}

Environment Setup

Create .env.local:

NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_project_id_here

Usage Examples

Send Transaction

import { useWallet } from '@/providers/WalletProvider';

export function SendButton() {
const { sdk, accountId } = useWallet();

const sendTransaction = async () => {
if (!sdk || !accountId) return;

try {
const result = await sdk.transferHBAR({
recipientId: "0.0.123456",
amount: 1, // 1 HBAR
});
console.log('Transaction success:', result);
} catch (error) {
console.error('Transaction failed:', error);
}
};

return (
<button onClick={sendTransaction} disabled={!accountId}>
Send 1 HBAR
</button>
);
}

Remember to replace your_project_id_here with your actual WalletConnect project ID from the WalletConnect Dashboard!