This release follows the simplified core revision of the nutroot spec, makes proof verification and restore yield to the event loop, and tidies a few APIs before GA. There are more breaking changes since rc.11; the migration guide has each one with before and after code.
Upgrading from rc.11: read these even if you never touch a v3 keyset
prepareSwapToSend()andwallet.ops.send(...).prepare()return{ preview, unselected }, andcompleteSwap()returns only what the swap produced. Returnunselectedto your store as soon asprepare()returns: it is no longer inkeep, so code that savedkeepas the whole remainder will drop those proofs. One-shotsend()andrun()are unchanged.hasValidDleqandverifyProofsForReceiveare replaced by asyncverifyMintSignaturesandverifyReceivedProofs, which return{ valid, invalid }instead of throwing per proof, run in chunks and accept asignal.checkProofsStatesand restore yield to the event loop too.Mint.getLazyMintInfo()is replaced byMint.fetchMintInfo({ forceRefresh? }), andMint.getInfo()returns/v1/infoas the mint sent it, soSwapMethod.method_name,min_amountandmax_amountare optional.Wallet.loadMint()now reuses info a sharedMintalready holds; callloadMint(true)for a fresh fetch.- The NUT-13 derivation helpers called directly now require the 64-byte BIP-39 seed, as
Walletalready did. - P2PK: a locktime of
0reads as expired, and a lock expires only once the clock is past its locktime, matching NUT-11 and both mints. - New:
MintErrorCodeand predicates such asisAlreadyIssuedErrorfor handling mint errors by code, andgetTokenMetadataaccepts a raw binary token.
v3 keysets
Nutroot is still a draft and v3 keysets are served only by demo mints, so nothing here affects funds on a public mint. rc.12 tracks the simplified core revision of cashubtc/nuts#443, so rc.11 v3 transcripts no longer verify against an up-to-date mint: blinded outputs enter the transcript as SHA256(B_), a mint quote input commits the quote's lock key and amount_issued, and container types carry their section in the high nibble. Check-state now returns a v3 proof's witness from PENDING on, so spend commitments and receipts are gone, as are the leaf disclosure field and derived quote ids. A v3 mint request may span several v3 keysets, a lock is refused if it uses a leaf type the mint does not list, and the version 02 BAT target is relative to the mint URL. The ScriptPath signing package was refactored for co-signed spends and is marked @experimental while cashubtc/nuts#464 is a draft.
What's Changed
- test(transport): wait for state instead of the clock in the keepalive tests by @robwoodgate in #1255
- docs(fees): lead with prepare() for send cost, name the input fee in the shortfall message by @robwoodgate in #1258
- feat(wallet): return unselected proofs beside the send preview by @robwoodgate in #1260
- docs(fees): say receiver's swap fee, and how to read it off a send result by @robwoodgate in #1261
- docs: name things the way the object does by @robwoodgate in #1262
- fix(model): let isSupported take a NUT number from a loop by @robwoodgate in #1263
- test(integration): run against a v3-only mint by @robwoodgate in #1268
- feat(wallet): verify proofs and restore in chunks that yield to the event loop by @robwoodgate in #1264
- chore(deps): bump the dev-tooling group with 4 updates by @dependabot[bot] in #1267
- chore(deps): bump vitest from 5.0.0 to 5.0.1 in the vitest group by @dependabot[bot] in #1266
- chore(deps): bump prettier from 3.9.6 to 3.9.7 in the prettier group by @dependabot[bot] in #1265
- fix(wallet): yield during witnesses and subscriptions, share the restore budget by @robwoodgate in #1271
- fix(wallet): v3 quote inputs commit the amount issued by @robwoodgate in #1272
- fix(deps): bump fast-uri from 3.1.6 to 3.1.8 by @dependabot[bot] in #1275
- docs: add responsible disclosure guidance for agents by @ye0man in #1273
- chore: pass bare literals to Amount methods by @robwoodgate in #1276
- chore(docs): contributing using ai section by @robwoodgate in #1278
- chore(deps): bump the dev-tooling group with 5 updates by @dependabot[bot] in #1283
- chore(deps): bump vite from 8.3.0 to 8.3.1 in the vitest group by @dependabot[bot] in #1282
- chore(deps): bump typescript-eslint from 8.70.0 to 8.70.1 in the eslint group by @dependabot[bot] in #1281
- chore(deps): bump prettier from 3.9.7 to 3.9.9 in the prettier group by @dependabot[bot] in #1280
- chore(deps): bump korthout/backport-action from 4.6.0 to 4.7.0 in the github-actions group by @dependabot[bot] in #1279
- chore(deps): bump brace-expansion from 1.1.18 to 1.1.21 by @dependabot[bot] in #1284
- chore(deps): bump markdown-it from 14.3.0 to 14.3.2 by @dependabot[bot] in #1285
- feat(crypto): transcript container types carry their section in the high nibble by @robwoodgate in #1289
- feat(crypto): detect legacy keyset derivation collisions by @KvngMikey in #1287
- feat(errors): add mint error codes and predicates by @KvngMikey in #1288
- docs: move error handling guide to usage by @robwoodgate in #1293
- test(vectors): carry the NUT-13 v3 seed as 64 bytes by @robwoodgate in #1295
- feat(nut13)!: derivation helpers take the 64-byte BIP-39 seed by @robwoodgate in #1296
- fix(nut13): a v3 derivation scope must be 33 bytes by @robwoodgate in #1299
- feat(crypto)!: transcript and signing package refactor for co-signed spends by @robwoodgate in #1294
- fix(nutroot): receipts refuse a malformed signature entry or a stray preimage by @robwoodgate in #1298
- fix(nutroot): an empty tree or a NUMS offset without a tree is malformed spend info by @robwoodgate in #1300
- chore(deps): bump the dev-tooling group with 8 updates by @dependabot[bot] in #1303
- chore(deps): bump typescript-eslint from 8.70.1 to 8.71.0 in the eslint group by @dependabot[bot] in #1301
- chore(deps): bump vite from 8.3.1 to 8.3.2 in the vitest group across 1 directory by @dependabot[bot] in #1305
- chore(deps): bump source-map-js from 1.2.1 to 1.2.2 by @dependabot[bot] in #1304
- fix(nutroot): a hashlock preimage is exactly 32 bytes by @robwoodgate in #1306
- fix(core): validate text fields when decoding a v4 token by @robwoodgate in #1307
- feat(utils): getTokenMetadata accepts a raw binary token by @robwoodgate in #1310
- feat(nutroot)!: blinded outputs enter the transcript as a hash, derived quote ids by @robwoodgate in #1313
- fix(auth)!: the version 02 BAT target is relative to the mint URL by @robwoodgate in #1314
- feat(nutroot)!: a mint quote input commits the quote's amount_issued by @robwoodgate in #1315
- test(wallet): restore spies between abort tests so the mutation run passes by @robwoodgate in #1322
- chore(deps): bump typescript-eslint from 8.71.0 to 8.71.1 in the eslint group by @dependabot[bot] in #1318
- chore(docker): update CDK_IMAGE to cashubtc/mintd:0.18.2 by @robwoodgate in #1317
- chore(deps): bump the dev-tooling group with 3 updates by @dependabot[bot] in #1320
- chore(deps): bump the vitest group with 2 updates by @dependabot[bot] in #1319
- fix(nut11): read locktime 0 as an expired lock, expire only after locktime by @robwoodgate in #1323
- fix(mint): log only the op when a melt quote check answers for another quote by @robwoodgate in #1326
- chore(deps): bump msw from 2.15.0 to 3.0.2 by @dependabot[bot] in #1321
- chore(deps): bump markdown-it from 14.3.2 to 14.3.3 by @dependabot[bot] in #1331
- chore(deps): bump the dev-tooling group with 5 updates by @dependabot[bot] in #1335
- chore(deps): bump the vitest group with 2 updates by @dependabot[bot] in #1334
- chore(deps): bump typescript-eslint from 8.71.1 to 8.71.2 in the eslint group by @dependabot[bot] in #1333
- chore(deps): bump prettier from 3.9.9 to 3.9.10 in the prettier group by @dependabot[bot] in #1332
- fix(mint): null a melt payment_preimage that is not a string by @robwoodgate in #1337
- refactor(mint)!: fetchMintInfo replaces getLazyMintInfo; getInfo returns the wire response by @robwoodgate in #1341
- feat(nutroot)!: align with the simplified core revision by @robwoodgate in #1328
- chore(scripts): leave no branches behind after an experimental publish by @robwoodgate in #1342
- fix(wallet): let a v3 mint span v3 keysets by @robwoodgate in #1343
- fix(payment-request): accept quoted proof amounts in decodePayload by @robwoodgate in #1344
- fix(payment-request): reject a malformed sm list with a CTSError by @robwoodgate in #1349
- fix(auth): drop request path from BAT log context by @robwoodgate in #1350
- ci: run weekly agenda at 00:23 UTC by @robwoodgate in #1354
- fix(deps): bump qs from 6.15.3 to 6.17.0 by @dependabot[bot] in #1355
- fix(deps): bump fast-uri from 3.1.8 to 3.1.9 by @dependabot[bot] in #1356
- chore(main): release 5.0.0-rc.12 by @robwoodgate in #1256
Full Changelog: v5.0.0-rc.11...v5.0.0-rc.12