Skip to main content

Examples

Real-world examples demonstrating common use cases and patterns with Midnight Auth.

Sign a Message

Use the signData function to cryptographically sign messages with the connected wallet.

import { useMidnightWallet } from '@uppzen/midnight-auth'
import { useState } from 'react'

export default function SignMessage() {
const { address, signData } = useMidnightWallet()
const [signature, setSignature] = useState<string>('')
const [error, setError] = useState<string>('')

const handleSign = async () => {
if (!address || !signData) return

try {
setError('')
const result = await signData(address, 'Hello Midnight Network!')
setSignature(result.signature)
console.log('Signature:', result.signature)
console.log('Key:', result.key)
} catch (err) {
setError('Failed to sign message')
console.error('Failed to sign:', err)
}
}

return (
<div>
<button onClick={handleSign} disabled={!address}>
Sign Message
</button>
{signature && (
<div>
<p>Signature:</p>
<code>{signature}</code>
</div>
)}
{error && <p style={{ color: 'red' }}>{error}</p>}
</div>
)
}

Submit a Transaction

Submit transactions to the Midnight Network using the submitTransaction function.

import { useMidnightWallet } from '@uppzen/midnight-auth'
import { useState } from 'react'

export default function SendTransaction() {
const { submitTransaction, isConnected } = useMidnightWallet()
const [txHash, setTxHash] = useState<string>('')
const [loading, setLoading] = useState(false)

const handleSend = async () => {
if (!isConnected || !submitTransaction) return

setLoading(true)
try {
const tx = {
// Your transaction object
to: '0x...',
value: '1000000000000000000'
}

const result = await submitTransaction(tx)

if (result.success) {
setTxHash(result.txHash)
console.log('Transaction hash:', result.txHash)
}
} catch (error) {
console.error('Failed to submit:', error)
} finally {
setLoading(false)
}
}

return (
<div>
<button
onClick={handleSend}
disabled={!isConnected || loading}
>
{loading ? 'Sending...' : 'Send Transaction'}
</button>
{txHash && (
<div>
<p>Transaction Hash:</p>
<code>{txHash}</code>
</div>
)}
</div>
)
}

Protected Dashboard

Create protected pages that require wallet connection before rendering content.

import { ProtectedRoute, useMidnightWallet } from '@uppzen/midnight-auth'

export default function Dashboard() {
return (
<ProtectedRoute
fallback={
<div className="text-center p-8">
<h2>Please connect your wallet</h2>
<p>You need to connect your Midnight wallet to access this page.</p>
</div>
}
>
<DashboardContent />
</ProtectedRoute>
)
}

function DashboardContent() {
const { address, balances } = useMidnightWallet()

return (
<div>
<h1>Welcome {address}!</h1>
{balances && (
<div>
<h2>Your Balances</h2>
<p>Shielded: {balances.shielded}</p>
<p>Unshielded: {balances.unshielded}</p>
<p>Total: {balances.total}</p>
</div>
)}
</div>
)
}

Session Management

Track and manage user sessions with automatic expiration handling.

import { useMidnightSession } from '@uppzen/midnight-auth'
import { useEffect, useState } from 'react'

export default function SessionInfo() {
const { session, isExpired, timeRemaining, refreshSession } = useMidnightSession()
const [formattedTime, setFormattedTime] = useState('')

useEffect(() => {
const formatTime = (ms: number) => {
const hours = Math.floor(ms / (1000 * 60 * 60))
const minutes = Math.floor((ms % (1000 * 60 * 60)) / (1000 * 60))
return `${hours}h ${minutes}m`
}

if (timeRemaining > 0) {
setFormattedTime(formatTime(timeRemaining))
}
}, [timeRemaining])

if (!session) {
return <p>No active session</p>
}

return (
<div>
<p>Connected: {new Date(session.connectedAt).toLocaleString()}</p>
{isExpired ? (
<div>
<p className="text-red-500">Session expired</p>
<button onClick={refreshSession}>Reconnect</button>
</div>
) : (
<p>Time remaining: {formattedTime}</p>
)}
<button onClick={refreshSession}>Refresh Session</button>
</div>
)
}

Custom Connect Button

Create a custom connect button with your own styling.

import { useMidnightAuth } from '@uppzen/midnight-auth'

export default function CustomConnectButton() {
const { isConnected, isConnecting, connect, disconnect, walletState } = useMidnightAuth()

if (isConnecting) {
return (
<button disabled className="custom-button">
Connecting...
</button>
)
}

if (isConnected && walletState) {
return (
<div className="wallet-dropdown">
<button className="custom-button">
{walletState.address?.slice(0, 6)}...{walletState.address?.slice(-4)}
</button>
<div className="dropdown-menu">
<p>Balance: {walletState.balance}</p>
<button onClick={disconnect}>Disconnect</button>
</div>
</div>
)
}

return (
<button onClick={connect} className="custom-button">
Connect Wallet
</button>
)
}

Wallet Balance Display

Display wallet balance with automatic refresh.

import { useMidnightWallet } from '@uppzen/midnight-auth'
import { useEffect } from 'react'

export default function BalanceDisplay() {
const { balances, refreshBalance, isConnected } = useMidnightWallet()

useEffect(() => {
if (isConnected) {
// Refresh balance every 30 seconds
const interval = setInterval(() => {
refreshBalance()
}, 30000)

return () => clearInterval(interval)
}
}, [isConnected, refreshBalance])

if (!isConnected) {
return <p>Connect wallet to view balance</p>
}

if (!balances) {
return <p>Loading balance...</p>
}

return (
<div className="balance-card">
<h3>Wallet Balance</h3>
<div className="balance-item">
<span>Shielded:</span>
<span>{balances.shielded}</span>
</div>
<div className="balance-item">
<span>Unshielded:</span>
<span>{balances.unshielded}</span>
</div>
<div className="balance-total">
<span>Total:</span>
<span>{balances.total}</span>
</div>
<button onClick={refreshBalance}>Refresh</button>
</div>
)
}

Multi-Step Transaction Flow

Handle complex transaction flows with multiple steps.

import { useMidnightWallet } from '@uppzen/midnight-auth'
import { useState } from 'react'

type Step = 'idle' | 'signing' | 'submitting' | 'complete' | 'error'

export default function MultiStepTransaction() {
const { address, signData, submitTransaction } = useMidnightWallet()
const [step, setStep] = useState<Step>('idle')
const [txHash, setTxHash] = useState('')

const handleTransaction = async () => {
if (!address || !signData || !submitTransaction) return

try {
// Step 1: Sign the message
setStep('signing')
const signature = await signData(address, 'Transaction authorization')

// Step 2: Submit transaction
setStep('submitting')
const tx = {
signature: signature.signature,
// ... other tx data
}

const result = await submitTransaction(tx)

if (result.success) {
setTxHash(result.txHash)
setStep('complete')
} else {
setStep('error')
}
} catch (error) {
console.error(error)
setStep('error')
}
}

return (
<div>
<h2>Multi-Step Transaction</h2>

{step === 'idle' && (
<button onClick={handleTransaction}>Start Transaction</button>
)}

{step === 'signing' && <p>Step 1/2: Signing message...</p>}
{step === 'submitting' && <p>Step 2/2: Submitting transaction...</p>}

{step === 'complete' && (
<div>
<p>✅ Transaction complete!</p>
<p>Hash: {txHash}</p>
</div>
)}

{step === 'error' && (
<div>
<p>❌ Transaction failed</p>
<button onClick={() => setStep('idle')}>Try Again</button>
</div>
)}
</div>
)
}

Error Boundary with Wallet

Wrap wallet components in an error boundary for better error handling.

import { Component, ReactNode } from 'react'
import { useMidnightAuth } from '@uppzen/midnight-auth'

class WalletErrorBoundary extends Component<
{ children: ReactNode },
{ hasError: boolean; error: Error | null }
> {
constructor(props: { children: ReactNode }) {
super(props)
this.state = { hasError: false, error: null }
}

static getDerivedStateFromError(error: Error) {
return { hasError: true, error }
}

render() {
if (this.state.hasError) {
return (
<div>
<h2>Something went wrong with the wallet connection</h2>
<p>{this.state.error?.message}</p>
<button onClick={() => this.setState({ hasError: false, error: null })}>
Try Again
</button>
</div>
)
}

return this.props.children
}
}

export default function App() {
return (
<WalletErrorBoundary>
<WalletFeatures />
</WalletErrorBoundary>
)
}

function WalletFeatures() {
const { isConnected } = useMidnightAuth()
return <div>{isConnected ? 'Connected' : 'Not connected'}</div>
}

Next Steps

  • Check the API Reference for detailed documentation
  • Learn about Hooks for more programmatic control
  • Explore Components for pre-built UI elements