Skip to content

Latest commit

 

History

History
187 lines (151 loc) · 6.7 KB

File metadata and controls

187 lines (151 loc) · 6.7 KB

Live NOVA Balance Header Integration

Overview

This PR implements live NOVA token balance display in the application header, replacing hardcoded placeholder values with real on-chain data from the Stellar network. The balance is fetched from the authenticated /api/wallet/balance endpoint and updates dynamically after transactions.

Problem Statement

The header was displaying a hardcoded placeholder balance instead of the user's actual NOVA token balance from the Stellar network. This is the most visible data point in the app and must reflect real on-chain data to provide users with accurate account information.

Solution

Implemented a complete balance display system with:

  • Backend API endpoint for authenticated balance retrieval
  • Frontend component with loading, error, and success states
  • Automatic balance refresh after transactions
  • Proper decimal formatting (7 places for Stellar)

Changes Made

Backend (novaRewards/backend/routes/wallet.js)

  • New Endpoint: GET /api/wallet/balance
    • Requires authentication via JWT Bearer token
    • Uses authenticateUser middleware to validate user
    • Retrieves live NOVA balance from Stellar network via walletService.getBalances()
    • Returns formatted balance with 7 decimal places
    • Handles errors gracefully (no wallet linked, server errors)

Frontend Components

BalanceDisplay.js (New Component)

  • Displays authenticated user's live NOVA token balance
  • Three States:
    • Loading: Shows skeleton animation while fetching
    • Error: Displays "—" with tooltip explaining the failure
    • Success: Shows formatted balance with 7 decimal places
  • Automatically fetches balance when wallet connects
  • Integrates with Zustand store for state management

Header.js (Modified)

  • Imports and renders BalanceDisplay component
  • Positioned next to wallet connection button
  • Displays balance only when wallet is connected

TransferForm.js (Modified)

  • Calls fetchBalanceFromAPI() after successful transfer
  • Ensures balance updates immediately after transaction

RedeemForm.js (Modified)

  • Calls fetchBalanceFromAPI() after successful redemption
  • Ensures balance updates immediately after transaction

State Management (walletStore.js)

  • New State Properties:
    • balanceLoading: Boolean flag for loading state
    • balanceError: Error message string
  • New Method: fetchBalanceFromAPI()
    • Fetches balance from /api/wallet/balance endpoint
    • Handles loading and error states
    • Updates store with formatted balance
    • Provides user-friendly error messages

Acceptance Criteria ✅

  • Header fetches and displays authenticated user's live NOVA balance

    • BalanceDisplay component fetches from /api/wallet/balance on mount
    • Balance updates when wallet connects
  • Balance updates on every successful transaction

    • TransferForm calls fetchBalanceFromAPI() after successful transfer
    • RedeemForm calls fetchBalanceFromAPI() after successful redemption
    • Balance reflects new on-chain state immediately
  • Loading state shows skeleton while first fetch completes

    • BalanceDisplay shows animated skeleton with two lines
    • Skeleton matches balance display dimensions
    • Smooth transition to actual balance
  • Error state shows — with tooltip explaining fetch failure

    • Displays "—" when balance fetch fails
    • Tooltip appears on hover with error message
    • User-friendly error messages from ERROR_MESSAGES object
  • Balance formatted with correct decimal precision (7 places for Stellar)

    • Backend formats to 7 decimal places using .toFixed(7)
    • Frontend uses toLocaleString() with minimumFractionDigits: 7
    • Consistent formatting across all displays

Technical Details

API Endpoint

GET /api/wallet/balance
Authorization: Bearer {token}

Response (Success):
{
  "success": true,
  "balance": "1234.5678901",
  "raw": "1234.5678901",
  "stellarPublicKey": "GXXXXXX..."
}

Response (Error):
{
  "success": false,
  "error": "no_wallet_linked",
  "message": "User has no linked Stellar wallet"
}

Component Integration

  • BalanceDisplay is rendered in Header.js next to WalletConnectButton
  • Uses Zustand store for state management
  • Integrates with existing authentication system
  • Follows existing error handling patterns

State Flow

  1. User connects wallet → publicKey set in store
  2. BalanceDisplay mounts → calls fetchBalanceFromAPI()
  3. balanceLoading set to true → skeleton displays
  4. API returns balance → balance updated, balanceLoading set to false
  5. User performs transaction → form calls fetchBalanceFromAPI()
  6. Balance refreshes with new on-chain value

Testing Recommendations

  1. Connection Flow

    • Connect wallet and verify balance displays
    • Verify skeleton shows during initial fetch
    • Verify balance updates after connection
  2. Transaction Flow

    • Perform transfer and verify balance updates
    • Perform redemption and verify balance updates
    • Verify balance reflects correct on-chain value
  3. Error Handling

    • Disconnect wallet and verify balance hides
    • Simulate API failure and verify error state
    • Verify tooltip displays on error hover
  4. Formatting

    • Verify balance displays with 7 decimal places
    • Test with various balance amounts
    • Verify formatting on different locales
  5. Network States

    • Test on mainnet and testnet
    • Verify network badge displays correctly
    • Verify balance updates on network switch

Files Modified

  • novaRewards/backend/routes/wallet.js (+42 lines)
  • novaRewards/frontend/components/BalanceDisplay.js (+84 lines, new)
  • novaRewards/frontend/components/layout/Header.js (+2 lines)
  • novaRewards/frontend/components/TransferForm.js (+6 lines)
  • novaRewards/frontend/components/RedeemForm.js (+8 lines)
  • novaRewards/frontend/store/walletStore.js (+25 lines)

Total: 6 files changed, 165 insertions(+), 2 deletions(-)

Breaking Changes

None. This is a backward-compatible enhancement.

Dependencies

No new dependencies added. Uses existing:

  • Zustand for state management
  • Axios for API calls
  • Lucide React for icons
  • Tailwind CSS for styling

Deployment Notes

  • No database migrations required
  • No environment variable changes required
  • API endpoint requires existing authentication middleware
  • Frontend changes are client-side only

Related Issues

Closes #[issue-number] - Live NOVA balance header display

Checklist

  • Code follows project style guidelines
  • All acceptance criteria met
  • Error handling implemented
  • Loading states implemented
  • Responsive design maintained
  • Dark mode support included
  • Accessibility considerations addressed
  • No console errors or warnings