Skip to content

Implement real-time credit accrual ticker in farm rows without polling the contract #23

Description

@prodbycorne

Problem

The Earned column in each farm row shows a static credit value fetched from the contract. Credits accrue continuously at dailyRate × lockedAmount / 86400 per second, but the UI only updates when the React Query cache refreshes (every 5 seconds per useUserCredits). This makes the earned display feel stale and disconnected from reality, especially given that SmartDrop's core value proposition is watching credits accumulate.

Expected Behaviour

After the initial credit snapshot is fetched from the contract, the row interpolates the earned value client-side at 1-second granularity using the known rate, without issuing additional RPC calls. When the cache refreshes, the interpolated value snaps to the authoritative on-chain figure.

Acceptance Criteria

  • A useLiveCredits(baseCredits, dailyRate, lockedAmount, lastFetchedAt) hook is added to src/hooks/ that ticks every second: displayed = baseCredits + (dailyRate / 86400) × lockedAmount × (Date.now() - lastFetchedAt) / 1000
  • The hook resets when baseCredits or lastFetchedAt change (i.e. when React Query delivers a fresh value from the contract)
  • The farm row's Earned column uses useLiveCredits and formats the output to 4 decimal places
  • The ticker interval is cleared on unmount to prevent memory leaks
  • Performance: a Vitest test advances fake timers by 1 second and asserts the displayed value increments by dailyRate / 86400 × lockedAmount with ±0.001 tolerance

Relevant Files

  • src/app/farm/page.tsxEarningRow, the earned display field
  • src/hooks/useSorobanQuery.tsuseUserCredits provides baseCredits and dataUpdatedAt
  • src/types/farm.tsFarmPosition.earned is currently a static string; may need to become numeric

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 stateperformanceRendering performance, caching, or bundle size

    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