Skip to content

Implement Horizon balance fetch to validate deposit amount against real wallet balance #27

Description

@prodbycorne

Problem

The planned deposit modal (issue #19) requires validating the user's input against their actual Stellar wallet balance. Currently there is no utility to fetch a wallet's asset balance from Horizon. Without this, the UI cannot prevent users from attempting to deposit more than they hold, which would produce a confusing contract error.

Expected Behaviour

Before the deposit modal renders (or within it as a side-effect), the connected wallet's balance for the pool's staking asset is fetched from Horizon and displayed. The amount input's max value is capped at this balance, and attempting to submit more shows an inline validation error.

Acceptance Criteria

  • src/lib/stellar.ts (new file) exports fetchAccountBalances(publicKey: string, horizonUrl: string): Promise<Balance[]> where Balance = { asset_code: string; asset_issuer?: string; balance: string; is_native?: boolean }
  • It uses Horizon GET /accounts/{id} (not the SDK's AccountCallBuilder) so it works in a static-export Next.js environment without a Node.js server
  • useAccountBalance(assetCode, assetIssuer) hook in src/hooks/useAccountBalance.ts calls fetchAccountBalances with React Query (staleTime: 15000, refetch on wallet focus)
  • Native XLM balance is handled: minimum reserve of 1 XLM + 0.5 XLM per trustline is subtracted from the spendable balance before display
  • The deposit modal shows the spendable balance next to the amount input and enables a Max button that fills the input to that amount
  • A Vitest test mocks the Horizon fetch and asserts the correct spendable XLM balance after subtracting base reserve

Relevant Files

  • src/lib/stellar.ts — create this file
  • src/hooks/useAccountBalance.ts — create this hook
  • src/config/index.tshorizonUrl already exported

Metadata

Metadata

Assignees

No one assigned

    Labels

    Official CampaignCampaign: Official CampaignfarmFarming/staking flow — deposit, lock, unlock, creditshardRequires deep domain knowledge — Soroban, Stellar SDK, or complex statesorobanSoroban smart-contract integration (XDR, RPC, transaction building)walletFreighter wallet integration, session, and network switching

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions