Files
routstrd/src
Paperclip Deployment Engineer 8009714cda feat: mint health cache, xcashu token sweep, network error fallback patterns
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)
2026-07-28 13:24:14 +00:00
..
2026-07-11 16:33:28 +02:00
2026-07-24 12:32:58 +00:00
2026-03-19 16:25:57 +00:00
2026-02-24 05:55:21 +00:00
2026-03-21 21:26:36 +00:00