Repository navigation
Conversation
Basic wallet functionality (BTC balance + history) depended on IBEX answering, so a blip on that one host made every wallet screen error out until the next request. This adds a small circuit breaker around the IBEX reads and gives each wallet surface a defined degraded mode: - src/services/ibex/availability.ts: a 3s half-open circuit. The first unanswered IBEX call marks it unavailable; calls inside the window return the degraded path immediately instead of each paying its own fetch timeout, then the circuit half-opens for a single probe. - errorHandler() trips the breaker only for a network-level ApiError (no httpCode), and wraps it in IbexUnavailableError so callers can distinguish "IBEX is down" from "this account/invoice is odd". - getBalanceForWallet(): while open, a BTC wallet reads the mongo ledger and converts at the mid price (same unit as the healthy path); cash wallets report IbexUnavailableError, since only IBEX is authoritative for those. - getTransactionsForWallets(): while open, history comes from the ledger. When IBEX fails for some wallets but the ledger has rows, those rows are returned as a success with the error recorded on the span, rather than failing the whole list. - usd/usdt wallet resolvers render IbexUnavailableError as a null balance (an explicit "unavailable" state) instead of throwing; error-map gives it an IBEX_UNAVAILABLE code. When IBEX is available nothing changes: the same Ibex.getAccountDetails / getAccountTransactions calls, the same mapping. Covered by test/flash/unit/services/ibex/availability.spec.ts plus new cases in the two wallet specs (breaker-open BTC read, ledger-failure propagation, cash-unavailable, breaker-open history, both-sources-empty).
Author
|
PR: #524 - circuit breaker on IBEX health (3s half-open), BTC balance + wallet history served from the ledger while it is open, cash wallets show an explicit unavailable (null) state instead of erroring, and a network-level ApiError is what trips the breaker. 256 suites / 3307 tests green in an isolated sandbox; tsc unchanged from main. Handle: nul-quill. Payout wallets: Solana USDC BdznDjc4xwt5Y6WJT5UnrFQzDptka8YnC9oqmmkKpwkd, TRC20 TNEHCVwR2aPMrj5AKfWCQ2rFL3bEDQmsg7. |
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the re-scoped ask in #302: graceful degradation instead of full IBEX independence.\n\n- new src/services/ibex/availability.ts: 3s half-open circuit around IBEX. First unanswered call opens it; calls inside the window take the degraded path immediately (no per-field fetch timeout), then the circuit half-opens for one probe.\n- errorHandler() trips the breaker only on a network-level ApiError (no httpCode) and wraps it in IbexUnavailableError, so IBEX is down is distinguishable from his account is odd.\n- getBalanceForWallet(): circuit open -> BTC wallet reads the mongo ledger and converts at the mid price (same unit as the healthy path); cash wallets report unavailable, since only IBEX is authoritative there.\n- getTransactionsForWallets(): circuit open -> history from the ledger. If IBEX fails for some wallets but the ledger has rows, those rows are returned as a success with the error recorded on the span rather than failing the whole list.\n- usd/usdt wallet resolvers render IbexUnavailableError as a null balance (explicit unavailable state) instead of throwing; error-map maps it to IBEX_UNAVAILABLE.\n\nWhen IBEX is available nothing changes: same calls, same mapping.\n\nVerification (isolated Linux sandbox, node 20.18.1):\n
px jest --config ./test/flash/unit/jest.config.js --ci test/flash/unit/services test/flash/unit/domain test/flash/unit/app test/flash/unit/graphql -> 256 suites / 3307 tests passed, exit 0. sc --noEmit unchanged from main (same 2 pre-existing Express/Application errors in src/servers).\n\nHandle: nul-quill. Payout wallets: Solana USDC BdznDjc4xwt5Y6WJT5UnrFQzDptka8YnC9oqmmkKpwkd, TRC20 TNEHCVwR2aPMrj5AKfWCQ2rFL3bEDQmsg7.