Skip to content

refactor(price): answer the price fetch on one typed outcome channel - #1298

Open
zancas wants to merge 1 commit into
devfrom
price_fetch_typed_outcome
Open

refactor(price): answer the price fetch on one typed outcome channel#1298
zancas wants to merge 1 commit into
devfrom
price_fetch_typed_outcome

Conversation

@zancas

@zancas zancas commented Aug 22, 2026

Copy link
Copy Markdown
Member

What this changes

getZecPrice returned one number that carried both the price and the failure.
Zero, minus one and minus two each named a different outcome. A prose string
travelled beside the number.

callFfi already gives this function a discriminated FfiResult. Its code
is a ZingolibError variant name. The sentinels discarded that typing.

The function now returns a ZecPriceOutcome. One arm is zecPrice and holds
the quote. The other arm is ErrorKeyed and holds a catalog key with the
diagnostic detail. ADR 0002 and ADR 0003 ask this of every module boundary.
The file's own header already claimed it.

What the sentinels were hiding

Three defects go away with them.

  • NaN is falsy. The guard above the isNaN arm therefore always won, and
    that arm was unreachable. A malformed number reported as "no price yet".
  • The payload's error field is dead. zec_price returns only
    current_price. It signals every failure by rejecting.
  • The store retried every non-positive answer. A deliberate mixnet-off refusal
    under ADR 0011 therefore cost two failing calls, not one clear answer.

A quote must now be a positive finite number. An absent, null or non-positive
value fails as a malformed payload. It cannot pass as a price.

Behaviour change

A failed refresh now always leaves the last good price on screen. Two of the
three old failure arms did that. The third overwrote the price with zero. The
same fetch failing two ways therefore produced opposite displays.

Scope

This is a mobile backend change. The snackbar copy is untouched, and the two
translation keys keep their present wording. Those two strings read almost
identically, so a reader cannot tell the two failures apart. That is a
user-facing concern and belongs in its own change.

Verification

  • npm run typecheck passes.
  • npx eslint reports nothing on the four changed files.
  • npx prettier --check passes.
  • The walletUtils unit suite passes with 24 tests. Its price cases now
    assert the error key rather than a sentinel, and they cover a null price and
    a non-positive price, which the old shape could not express.
  • The PriceFetcher snapshot passes unchanged.

🤖 Generated with Claude Code

getZecPrice returned a number carrying both the price and the failure, with
zero, minus one and minus two standing for three different outcomes, beside a
prose string. callFfi already hands it a discriminated FfiResult whose code is
a ZingolibError variant name, and the sentinels threw that typing away. The
function now returns a ZecPriceOutcome: a zecPrice arm holding the quote, or
an ErrorKeyed arm holding a catalog key and the diagnostic detail. This is
what ADR 0002 and ADR 0003 ask of every module boundary, and this file's own
header already claimed it.

Three defects fall out with the sentinels. NaN is falsy, so the guard above
the isNaN arm always won and that arm was unreachable, which reported a
malformed number as no price yet. The payload's error field is dead, because
zec_price returns only current_price and signals every failure by rejecting.
The store retried every non-positive answer, so a deliberate mixnet-off
refusal under ADR 0011 cost two failing calls rather than one clear answer.

A quote is now required to be a positive finite number, so an absent, null or
non-positive value fails as a malformed payload instead of passing as a price.

One behaviour changes. A failed refresh now always leaves the last good price
on screen. Previously two of the three failure arms did that and the third
overwrote the price with zero, so the same fetch failing two ways produced
opposite displays.

The snackbar copy is untouched. The two translation keys keep their present
wording, which reads identically for both failures. That is a user-facing
concern and belongs in its own change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant