mirror of
https://github.com/Routstr/routstrd.git
synced 2026-08-11 12:38:01 +00:00
Three changes that harden the mint-fallback branch against upstream failures and enable proper provider failover: 1. Mint health cache (src/daemon/wallet/index.ts) Track mints that are temporarily unreachable (connection refused, DNS failure, TLS error). Unhealthy mints are skipped by getActiveMintUrl() and sendToken() so we don't waste a round-trip on every request. Mints are automatically retried after a 60s cooldown. The active mint switches to a healthy one when the current one goes unhealthy. This is critical for the xcashu 402 failover fix: when the primary provider (localhost:8011) is down, the wallet needs to successfully create a token via a healthy mint BEFORE the SDK's failover logic can route the request to the next provider (routstr.otrta.me). Without the health cache, every request wasted 2-3 seconds on a failed mint.minibits.cash fetch before falling back to cubabitcoin. 2. xcashu token sweep (src/daemon/index.ts) The scheduled refund loop now also sweeps pending xcashu tokens that failed inline refund (e.g. 'proofs already spent' — the token stays in storage and needs retry). This prevents orphaned IOUs from accumulating and ensures the background refundXcashuTokens path gets a chance to reclaim sats from tokens where the inline receive raced with the sweep. This is the race condition that caused the double-refund negative satsSpent bug (xcashu-double-refund-negative-sats, prio 998): the inline receive and the background sweep both received the same token, producing a negative satsSpent written to usage_tracking. 3. Network error patterns (src/daemon/wallet/mint-fallback.ts) Extend inspectForMintUnreachable to recognize Bun-specific network failures: 'Failed to fetch mint <url>', 'NetworkError when attempting to fetch resource', and 'Load failed'. These are treated as mint-unreachable so the fallback to the next configured mint kicks in immediately instead of surfacing the raw error. This pairs with the SDK fix (routstr-sdk PR #32) that adds 'Unable to connect' and 'ECONNREFUSED' to isNetworkErrorMessage so the SDK's failover path is triggered when the upstream provider is completely unreachable (not just returning an HTTP error). Related issues: - Nostr: xcashu-402-body-refund-no-failover (prio 990, event a4d7e1cd...) - Nostr: xcashu-double-refund-negative-sats (prio 998, event 14982f8d...) - SDK PR: https://github.com/Routstr/routstr-sdk/pull/32 - SDK PR: https://github.com/Routstr/routstr-sdk/pull/31 (clamp fix)