Skip to content

refactor: replace raw bigint with Amount VO on Proof and BlindedMessage - #609

Merged
robwoodgate merged 21 commits into
mainfrom
v4-json-tweaks
Apr 11, 2026
Merged

refactor: replace raw bigint with Amount VO on Proof and BlindedMessage#609
robwoodgate merged 21 commits into
mainfrom
v4-json-tweaks

Conversation

@robwoodgate

@robwoodgate robwoodgate commented Apr 10, 2026

Copy link
Copy Markdown
Collaborator

Replaces raw bigint with the Amount value object on the two most app-facing types (Proof.amount and SerializedBlindedMessage.amount) so downstream consumers no longer need to manually wrap every amount in Amount.from(). Also introduces ProofLike as inputs in the core wallet flows, so consumers get more flexibility using proofs from storage.

Changes

  • JSONInt.stringify is now Amount-aware: calls .toBigInt(), for unquoted integers on the wire.
  • JSON.stringify continues to use Amount.toJSON() → quoted string (safe for app storage).
  • Proof.amount: bigint → Amount: eliminates the bulk of Amount.from() wrapping in downstream apps. normalizeProofAmounts() now produces Amount directly.
  • Token encode/decode, OutputData.toProof(), SelectProofs, and restore logic updated accordingly.
  • SerializedBlindedMessage.amount: bigint → Amount: natural follow-on — BlindedMessage no longer needs .toBigInt() at construction, restore logic simplified.
  • SwapPreview.amount/fees: AmountLike → Amount: tightened to match what the library actually constructs.
  • Amount.toJSON() returns string only: removes the previous number | string ambiguity.
  • Added Amount.fromJSON() and exported AmountJson type for round-trip convenience.
  • Preview TSDOCs updated: replaced misleading instructions with accurate remark that previews contain non-JSON-safe values (bigint, Uint8Array) and are not intended for direct serialization.
  • Fixes tests for Amount, fixes logs for Amount.toString()
  • Adds ProofLike in the send/receive/melt wallet flows for flexible input

@codecov

codecov Bot commented Apr 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.87500% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.55%. Comparing base (d88f1a9) to head (ba851b6).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/wallet/SelectProofs.ts 71.42% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #609      +/-   ##
==========================================
+ Coverage   91.49%   91.55%   +0.05%     
==========================================
  Files          49       49              
  Lines        4493     4513      +20     
  Branches     1119     1120       +1     
==========================================
+ Hits         4111     4132      +21     
  Misses        166      166              
+ Partials      216      215       -1     
Flag Coverage Δ
integration 40.70% <67.18%> (+0.13%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@robwoodgate

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 50809ea30f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/model/SigAll.ts Outdated
@robwoodgate
robwoodgate merged commit c8302f3 into main Apr 11, 2026
12 checks passed
@robwoodgate
robwoodgate deleted the v4-json-tweaks branch April 11, 2026 18:53
@github-project-automation github-project-automation Bot moved this from Backlog to Done in cashu-ts Apr 11, 2026
robwoodgate added a commit that referenced this pull request Aug 12, 2026
## Description

Nothing has ever type checked `test/`. Vitest strips types via esbuild
without checking them, and `test/tsconfig.json` existed only to give
eslint's typed rules a project covering the test tree, which catches
rule violations rather than assignability. `src/` was covered all along,
indirectly: `api:check` runs `vite-plugin-dts`, which type checks it.

The result was 89 errors across 12 files, accumulated silently as the
library types moved. The great majority is one field: `method` became
required on `MintQuoteBaseResponse` and `MeltQuoteBaseResponse`, and
mint quotes also gained `amount_paid` / `amount_issued` / `updated_at`.

## Changes

- `npm run check-types` runs `tsc -p test/tsconfig.json`. The tests
import the library source directly rather than the built package, so tsc
follows those imports and pulls all 87 files in `src/` into the same
program. One command therefore covers both trees, and there is no need
for a second project for `src/`. `test/tsconfig.json` gained `rootDir`
and `noEmit` so a bare `tsc -p` behaves the same on the command line as
it already did in an editor.
- `test/consumer/` is excluded. Those harnesses deliberately import the
package by its published name to simulate an external consumer, so they
only resolve after a build. They are covered by `consumers.yml`, which
builds first, and eslint skips them for the same reason.
- Wired into `prtasks`, a `types.yml` workflow following the existing
`lint.yml` shape, and the pre-push hook. A full pass takes about 3.5
seconds.
- Fixtures realigned with the current types. Unpaid quotes get `0/0`
accounting, which `validateMintQuoteAvailableAmount` short-circuits on,
so those tests take the same runtime path as before. Deliberately
malformed fixtures kept their hostile shape behind an explicit cast
rather than being "fixed".
- Fixed the pre-push condition. It read `if ! npm run check-lint && npm
run check-format`, where `!` binds only to the first command. It aborted
only when lint failed and format passed: when lint passed it
short-circuited and format never ran, and when both failed it did
nothing.
- `AGENTS-CONTRIBUTING.md` said `Proof.amount` is `bigint` and to
construct with `Amount.from(x).toBigInt()`. That was correct when
written but has been wrong since #609 moved it to `Amount`, and it is
where the payment request fixtures came from.

## Reviewer Notes

- No files under `src/` are touched and `etc/cashu-ts.api.md` is
unchanged, so there is no public API movement here.
- The obvious alternative was shared fixture factories, so that a future
field addition would need fixing in one place instead of 47. I left them
out on purpose: with the gate in place, the next type change breaks the
build immediately, at however many sites exist that day, rather than
piling up unnoticed until someone opens the file. Fixing one or two
sites as they break is cheaper than maintaining factories, and the
factories would not have prevented today's cleanup anyway.
- The gate was checked for teeth rather than assumed: planting a `Proof`
with a raw `bigint` amount makes `check-types` exit 2 and the hook exit
1, and both return to 0 once removed.
- The sweep also surfaced several `src/` defects where a declared type
asserts more than the code delivers. Those are deliberately not in this
PR; they follow in a separate one stacked on this branch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants