Files
minibits_wallet/__tests__
minibits-cashandClaude Opus 4.8 3caf54fa35 fix(melt): recover NUT-08 change when mint reorders signatures
Some mints (nutshell < 0.20.1) return paid-melt-quote change[]
signatures in an order that does not match the blank outputs the
wallet sent. cashu-ts OutputData.toProof assumes positional pairing
and throws on its DLEQ check, so mapping over the array aborted on the
first mismatch and the catch discarded ALL change — recording it as
fee. A user lost ~100k sats of change on a single transfer this way.

Add CashuUtils.recoverMeltChange, a resilient helper that:
  - matches each signature to the blank whose blinded message makes the
    mint's DLEQ proof verify (verifyDLEQProof as alignment oracle),
    correctly re-pairing reordered change while keeping DLEQ as a hard
    guarantee;
  - on a genuine DLEQ failure (no blank verifies) falls back to
    unblinding the positional blank WITHOUT DLEQ so funds are recovered
    rather than dropped, logged at error level;
  - returns stats so callers can surface anomalies.

Both melt finalize paths (transferOperationApi._finalizePaid and
meltOperations.handlePendingMeltTask) use the helper and append a
COMPLETED-status tx.data entry with the recovery stats when a genuine
error occurred (no-DLEQ fallback / unmatched) — benign reordering is
not flagged.

Covered by __tests__/recoverMeltChange.test.ts (in-order, shuffled,
fewer-sigs-than-blanks, duplicate denominations, no-DLEQ fallback,
unmatched).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 21:55:04 +02:00
..