Skip to content

Wallet balance endpoint returns simulated hardcoded balances: XLM and USDC values are fabricated, not fetched #366

Description

@usmanimamu17-create

Problem

WalletRegistry.get_balance (app/services/wallet_registry.py):

xlm_balance = "1.0000000" if wallet.funded else "0.0000000"
balances: dict[str, AssetBalance] = {"XLM": AssetBalance(balance=xlm_balance, asset_type="native")}
if wallet.trustline_ready:
    balances["USDC"] = AssetBalance(balance="0.0000000", asset_type="credit_alphanum4",
                                    asset_code="USDC", asset_issuer="TEST_ISSUER")

The balance is derived from two boolean flags; the USDC issuer is the literal string TEST_ISSUER.

Consequences:

  • Consumers receive fabricated financial data: the frontend wallet UI renders "1.0 XLM" for any funded wallet regardless of its real balance, and USDC always shows 0.0000000 with issuer TEST_ISSUER — there is no Horizon query anywhere in the path.
  • The values contradict the platform's own security posture: docs describe real on-chain settlement, but the balance endpoint reports hardcoded strings; a user checking their actual balance is misled.
  • last_updated/cached_at suggest freshness while the value never changes: the response shape implies a live read, so the simulation is invisible.

Root cause

The balance feature was scaffolded as a stub (booleans standing in for account state) before any Stellar client integration.

Why this is architecturally hard

  1. Real balances require a Horizon (or RPC) client call, network config (public vs testnet), and error handling for unreachable networks — the repo has STELLAR_NETWORK/SLA_CONTRACT_ADDRESS settings but no balance-fetch client.
  2. The response shape (WalletBalanceResponse with cache_status/cached_at) was designed for a live read; the fix must decide whether to cache, TTL, and degrade when the network is down.
  3. The contracts/frontend repos consume this shape; adding a simulated: true flag or failing when unconfigured is a contract change to coordinate.

Proposed design

Fetch balances from the configured network (Horizon for the configured STELLAR_NETWORK), mark responses as simulated when the fetch path is unavailable, and add tests with a mocked network returning known balances.

Acceptance criteria

Service

  • Balance responses reflect a real (or explicitly simulated) fetch.
  • No literal TEST_ISSUER value is returned in a non-simulated response.

Tests

  • A mocked-fetch test asserts balances propagate through the response.
  • Existing wallet tests pass.

Out of scope

Real key generation (tracked separately) and on-chain settlement.

Getting started

pytest tests/test_wallet_persistence.py -q
make typecheck

Good first files to read: app/services/wallet_registry.py, app/models/wallet.py, app/core/config.py.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardThird CampaignCampaign: Third Campaignarea/walletsImported campaign issue labelpriority/mediumStandard backlog item

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions