Cashu ts v4#1108
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
Scope classification doc for the @cashu/cashu-ts 3.6.1 → v4 bump: breaking changes summary, file-by-file audit, per-bucket counts, 10 open questions, recommended 3-PR sequencing. No code changes.
cashu-ts v4.0 (#536) fixed the proof.id mutation bug in getEncodedToken, so the deep-clone wrapper in app/lib/cashu/token.ts is no longer needed. Call getEncodedToken directly at all sites.
v4 KeyChain cache is mint-wide rather than unit-scoped, so the first unit argument has been removed from the signature.
v4 types MintQuoteBolt11Response.expiry as `number | null` to match NUT-23 — null means the mint did not communicate one, not that the quote never expires. Per NUT-23 the field *is* the bolt11 invoice expiry, so fall back to the decoded invoice's expiry (which decodeBolt11 already returns) when the mint omits it, instead of substituting a sentinel. MeltQuoteBolt11Response.expiry remains non-nullable in v4 per its type declaration, so no change is needed on the send-quote side.
| const isKeysetActive = (ks: MintKeyset | Keyset): boolean => | ||
| 'isActive' in ks ? ks.isActive : ks.active; | ||
|
|
||
| const getKeysetFinalExpiry = ( |
There was a problem hiding this comment.
we need these hepter now because the property names changes? Do we actually use the below functions with both types?
There was a problem hiding this comment.
Yes — both types are genuinely used, so these are load-bearing. findFirstActiveKeyset / getKeysetExpiry are called with:
MintKeyset[]fromaccount-service.ts(viaMint.getKeySets()— propsactive/final_expiry)Keyset[]fromreceive-cashu-token-service.ts(viawallet.keyChain.getKeysets()— propsisActive/expiry)
v4 names the same fields differently across the two types, so isKeysetActive / getKeysetFinalExpiry normalize them. Removing the helpers would break one of the two call sites. (Could inline the normalization at each call site instead, but the helper is less code.)
- classify-input.test.ts: drop the removed `{ version }` option from
getEncodedToken (v4 has a single encoding) and wrap proof.amount in
Amount.from() to match the new Proof type.
- blind-signature-matching.test.ts: drop the `amount` arg from
createBlindSignature (v4 takes only B_, privateKey, id) and read the
amount from the local parameter wrapped in Amount.from(), since the
returned BlindSignature no longer carries an amount field.
- blind-signature-matching: sig.amount is now an Amount value object, not a number, so it can't index keyset.keys directly — call toNumber(). - tokenToMoney: post-Bucket-A, sumProofs returns Amount; call toNumber() so Money still receives a primitive amount.
| tokenProofs: params.meltData.tokenProofs.map((p) => ({ | ||
| ...p, | ||
| amount: p.amount.toNumber(), | ||
| })), |
There was a problem hiding this comment.
nitpick: this is duplicated on a lot of places, maybe we should extract it in a helper
export const toStoredProofs = (proofs: Proof[]) =>
proofs.map((p) => ({ ...p, amount: p.amount.toNumber() }));or maybe even the whole toStoredMeltData.
Up to you, not sure if it's worth it
Updates to cashu-ts v4
The biggest change is that cashu-ts v4 introduced an Amount type that handles big ints and units. I decided to just use
toNumberon all theAmounts to keep the refactor minimial, but maybe there's something we can do here to better integrate with our existing money lib.Another change is that we no longer need a custom wrapper for encoding tokens. Cashu-ts v3 was mutating the v2 keyset ID when encoding, but that is fixed in v4 so we can use
getEncodedTokendirectly.