Skip to content

fix(wallets): never emit unresolvable via types from IBEX transaction mapping#454

Merged
islandbitcoin merged 2 commits into
mainfrom
fix/ibex-unknown-via-union-crash
Jul 17, 2026
Merged

fix(wallets): never emit unresolvable via types from IBEX transaction mapping#454
islandbitcoin merged 2 commits into
mainfrom
fix/ibex-unknown-via-union-crash

Conversation

@islandbitcoin

Copy link
Copy Markdown
Contributor

Problem

Any IBEX transaction row with an unrecognized currencyId or transactionTypeId maps to initiationVia/settlementVia: { type: "unknown" }. The InitiationVia/SettlementVia GraphQL unions resolve members via isTypeOf checks that only match intraledger/lightning/onchain, and both fields are NonNull — so graphql-js throws:

Abstract type 'InitiationVia' must resolve to an Object type at runtime for field 'Transaction.initiationVia'

One bad row fails the entire transaction list query for the account: home screen and transaction history go down in the mobile app. This is live on TEST today (dev builds default to the Test instance) and becomes a prod incident as soon as the #413 code path meets a legacy/BTC-denominated or new-swap-type IBEX row on Main, because #413 narrowed the currency mapping to USD (3) / USDT (29) only and the type switch handles only 1,2 (LN) and 3,4,10 (onchain).

Fix

  • Unknown currencyId → exclude the row from the list (error log kept). It cannot be represented truthfully; a fabricated $0 USD row or a crashed query are both worse. This keeps feat(epic): bridge integration #413's deliberate decision not to misclassify unknown currencies as BTC.
  • Unknown transactionTypeId → amounts and currency are valid, so render as a generic intraledger transaction (all union fields nullable) instead of hiding money movement (error log kept, includes the offending type id).
  • Remove UnknownTypeTransaction from the domain types so no code path can emit { type: "unknown" } again — the compiler now rejects it.
  • Defense in depth: add resolveType with a logged intraledger fallback on both unions, so an unrecognized source degrades to a renderable member instead of failing the whole list, whatever the producer.

No schema change (yarn check:sdl clean — union membership is untouched).

Tests

  • test/flash/unit/app/wallets/get-transactions-for-wallet.spec.ts: unknown currency rows are excluded + logged; unknown type ids render as intraledger with correct amounts + logged; exhaustive sweep asserting every currencyId × transactionTypeId combination only ever emits union-resolvable via types.
  • test/flash/unit/graphql/shared/types/abstract/via-unions.spec.ts (new): both unions resolve all known methods to the right object types and fall back with a logged error for unrecognized sources.
  • Full unit suite: 137 suites / 1088 tests green. yarn tsc-check clean.

Ops note

The two error-log paths (Failed to parse Ibex transaction currency/type) include the concrete currencyId/transactionTypeId — worth watching after deploy to add explicit mappings for whatever IBEX is actually returning (the ibex-swap A/B on TEST is a likely source).

🤖 Generated with Claude Code

bobodread876 and others added 2 commits July 17, 2026 00:39
… mapping

Transaction.initiationVia/settlementVia are NonNull unions resolved via
isTypeOf checks that only match intraledger/lightning/onchain. Since #413,
IBEX rows with an unrecognized currencyId or transactionTypeId map to
{ type: "unknown" }, which no union member accepts — graphql-js throws
"Abstract type 'InitiationVia' must resolve to an Object type at runtime"
and the entire transaction list query fails for the account (home screen
and history in the mobile app).

- Unknown currencyId: exclude the row from the list (it cannot be
  represented truthfully) and keep the error log.
- Unknown transactionTypeId: amounts and currency are valid, so render as
  a generic intraledger transaction instead of hiding money movement.
- Remove the UnknownTypeTransaction domain type so no code path can emit
  { type: "unknown" } again.
- Add resolveType with a logged intraledger fallback on both unions as
  defense in depth: one bad row can no longer fail the whole list.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Make the sign caveat for unrecognized IBEX send types an explicit code
  comment (sign convention is only known for mapped type ids).
- Remove now-dead isTypeOf checks on union members: graphql-js ignores
  isTypeOf when the union defines resolveType, and two parallel resolution
  mechanisms can drift.
- Widen InitiationViaIntraledger/SettlementViaIntraledger
  counterPartyWalletId (and initiation counterPartyUsername) to allow
  undefined instead of lying to the compiler with double-casts — the
  GraphQL fields were already nullable.
- Close the unbalanced brace in the transaction-type error log.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@islandbitcoin
islandbitcoin merged commit 9ca698b into main Jul 17, 2026
15 checks passed
@islandbitcoin
islandbitcoin deleted the fix/ibex-unknown-via-union-crash branch July 17, 2026 16:08
islandbitcoin added a commit that referenced this pull request Jul 17, 2026
* feat(wallets): map IBEX crypto and taproot transaction types

Type 9 (Crypto Receive — USDT deposits via Bridge) was the row behind the
InitiationVia union crash fixed in #454; it and taproot (11/12) now map to
on-chain instead of the logged intraledger fallback. Taproot send (12)
joins the negate-on-send list. Ids from GET /v2/transaction-types/all:
1/2 LN receive/send, 3/4 on-chain receive/send, 5 Fund, 6 Defund, 7 Bank
Deposit, 8 Bank Withdrawal, 9/10 crypto receive/send, 11/12 taproot
receive/send. Bank/funding ops (5-8) are org-level and intentionally stay
on the logged fallback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(wallets): pin bank/funding ops (5-8) to the logged fallback

Review finding: the sweep proved 5-8 emit resolvable vias but nothing
enforced the deliberate decision to keep them on the logged intraledger
fallback — a future change could silently map type 8 (Bank Withdrawal)
positive-signed with all tests green. Assert each of 5-8 renders as
intraledger and logs its transactionTypeId.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Dread <bobodread@bobodread.com>
Co-authored-by: Claude Fable 5 <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.

2 participants