fix(wallet): gate the received-payment toast on status, not absent pending #169

Merged
padreug merged 1 commit from fix/wallet-payment-toast-guard into dev 2026-09-22 21:16:07 +00:00
Owner

The last remaining reader of the phantom pending field, same root cause as #161. It is a pydantic @property and never appears in the payload, so !payment.pending was always true. The guard reduced to amount > 0 alone and never actually suppressed an unsettled payment, which is the one thing it was there to do.

Now checks status === 'success'.

Stacked on #168. That one unbreaks the build, so this is cut from it to be verifiable. Merge #168 first and this reduces to its own commit.

Also removed: an unreachable branch

if (payment.amount > 0 && !payment.pending) {
  if (payment.amount > 0) {
    toast.success(`Received ...`)
  } else {
    toast.info(`Sent ...`)      // unreachable
  }
}

The enclosing condition already required amount > 0, so the "Sent" toast could never fire.

I dropped it rather than repairing it. A send made from this app is already confirmed by SendDialog's own success toast, so re-announcing it here would double up. An outgoing payment made from another client on the same wallet still appears in the history list; it just does not raise a toast. Say the word if you would rather have that toast and I will widen the guard instead.

Verification

A real settled payment over the websocket:

amount=44000  status=success  pending key present=False

Found while checking that the six merged wallet PRs behaved correctly together, which is also how #168 surfaced.

The last remaining reader of the phantom `pending` field, same root cause as #161. It is a pydantic `@property` and never appears in the payload, so `!payment.pending` was always true. The guard reduced to `amount > 0` alone and never actually suppressed an unsettled payment, which is the one thing it was there to do. Now checks `status === 'success'`. **Stacked on #168.** That one unbreaks the build, so this is cut from it to be verifiable. Merge #168 first and this reduces to its own commit. ## Also removed: an unreachable branch ```js if (payment.amount > 0 && !payment.pending) { if (payment.amount > 0) { toast.success(`Received ...`) } else { toast.info(`Sent ...`) // unreachable } } ``` The enclosing condition already required `amount > 0`, so the "Sent" toast could never fire. I dropped it rather than repairing it. A send made from this app is already confirmed by SendDialog's own success toast, so re-announcing it here would double up. An outgoing payment made from another client on the same wallet still appears in the history list; it just does not raise a toast. Say the word if you would rather have that toast and I will widen the guard instead. ## Verification A real settled payment over the websocket: ``` amount=44000 status=success pending key present=False ``` Found while checking that the six merged wallet PRs behaved correctly together, which is also how #168 surfaced.
`dev` does not build. This is fallout from #162: `vue-tsc -b` rejects
`section.value` with

    error TS2339: Property 'value' does not exist on type 'Section'.
      Property 'value' does not exist on type '{ name: "checksum"; letters: string; }'.

`Section` is a discriminated union and its "checksum" member carries
only `letters`. The predicate was written as `(s: any) => ...`, which is
not a type guard, so `find` returned the whole union and `.value` could
not resolve against every member.

Replaced with a real type predicate narrowing to the `amount` member.

My fault for how I verified #162: I ran `vue-tsc --noEmit`, but the
build script runs `vue-tsc -b`, which uses the project-reference config
and is stricter. The two disagree, so `--noEmit` alone is not evidence
that the build passes. #166 did run a full build, but it was branched
off #165 and so never contained this code.

Amountless behaviour is unchanged, re-verified after the narrowing:
  amountless BOLT11 -> 0        (amount_msat sent)
  live 777-sat       -> 777000  (amount_msat omitted)
  malformed          -> null    (defer to server)

`npm run build:wallet` now succeeds.
Last remaining reader of the phantom `pending` field, same root cause as
#161: it is a pydantic `@property` and never appears in the payload, so
`!payment.pending` was always true. The guard reduced to `amount > 0`
alone and never actually suppressed an unsettled payment, which is what
it was there to do. Now checks `status === 'success'`.

The nested `else` that toasted "Sent N sats" was unreachable: the
enclosing condition already required `amount > 0`. Dropped rather than
repaired, because a send made from this app is already confirmed by
SendDialog's own success toast and re-announcing it here would double
up. An outgoing payment made from another client on the same wallet
still lands in the history list; it just does not raise a toast.

Verified against a live settled payment over the websocket:

  amount=44000  status=success  pending key present=False

Found while checking that the six merged wallet PRs behaved correctly
together.
padreug deleted branch fix/wallet-payment-toast-guard 2026-09-22 21:16:07 +00:00
Sign in to join this conversation.
No description provided.