feat!: adopt SDK v3 — bigint money, dollar display, pre-sign verification - #1
Merged
Conversation
…tion The SDK's breaking v3 makes fares, balances and amounts bigint and adds optional verification of the hub-returned unsigned transaction, so this app had to move with it: mixing bigint and number under + or < throws at runtime, which would have been a crash rather than a rounding bug. Every ClutchHubSdk construction now passes chainId from src/config.js - the app's own config, never the hub's chainInfo, since the hub is the untrusted party the verification defends against. Without it the chain-bound auth challenge cannot produce a valid token at all. All six signTransaction calls now pass the values the app itself asked for as `expected`, so a compromised hub altering a fare is caught before the user signs. The hub-injected referrer cannot be verified, so it is now displayed before signing instead - the only defence the user has against a swapped referrer address. Money is shown via formatUsd ($5.00, not 5000000), and dollar input goes through parseUsdToClt in src/utils/money.js, which pads the fraction to six digits: a naive dollars-and-cents split turns "5.005" into $5.05. Deliberately NOT included: the top-up/redeem screens from the plan. They call a payment orchestrator that does not exist yet, so they land with the plan that builds it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Companion to clutchprotocol/clutch-hub-sdk-js#4 (and the node/hub PRs behind it). This app consumes the SDK via
file:../clutch-hub-sdk-js, so it moves in lockstep.Why this was forced, not optional
SDK v3 makes
fare,farePaid,amountand balancesbigint. In JavaScript, mixingbigintandnumberunder+or<throws aTypeErrorat runtime — so a partial migration is a crash, not a rounding bug. Every money path had to move together.The underlying reason for bigint:
JSON.parsesilently rounds integers above 2^53, and at the peg of 1 USD = 1,000,000 CLT anumberfare was lossy before it was ever signed — the user would sign one amount believing they had approved another.What changed
chainId is now passed to every
ClutchHubSdkconstruction (six sites), sourced fromsrc/config.js— the app's own config, never from the hub'schainInforesponse. Asking the untrusted party which chain it is would defeat the check entirely. It is also required for the chain-bound auth challenge, so without it the app cannot obtain a token at all.All six
signTransactioncalls now passexpected, so the SDK's new verification actually runs. The expectation is the values the app itself asked for, not values read back from the hub's reply — otherwise it would be verifying the hub against itself. A compromised hub altering a fare is now caught before the user signs.The hub-injected referrer is displayed before signing. The client cannot verify it (that needs the signed-quote flow a later plan adds), so
verifyUnsignedTransactionreturns it and the confirm UI renders it. This is the user's only defence against a hub swapping in its own referrer address, and it is worthless if never shown.Money display and input:
formatUsd—$5.00, not5000000. Raw CLT only as secondary detail.parseUsdToCltin the newsrc/utils/money.js, integer-only. It pads the fraction to six digits, not two: a naive dollars-and-cents split turns"5.005"into$5.05. Input not matching^\d+(\.\d{1,6})?$is rejected rather than silently coerced.The surviving
toFixedcalls are on latitude/longitude, which are genuinely floats — not money.Deliberately not included
The plan for this app also described a top-up / redeem UI (deposit intents, payment instructions, redemption status). It is not here: those screens call a payment-orchestrator service that does not exist yet, and a UI against a non-existent backend is speculative code. They land with the plan that builds the orchestrator. The SDK's orchestrator client was cut for the same reason.
Verification
npm run buildpasses. Note itsprebuildrebuilds the SDK from source, so this also proves the SDK v3 ↔ app integration compiles rather than just this app in isolation.Lint: zero new errors and zero new warnings. Verified against the same files on
mainrather than assumed — this repo carries pre-existing eslint errors, and the two inTransactionHistory.jsxplus thereact-hooks/exhaustive-depswarning inPassengerView.jsxall exist onmainat shifted line numbers. None were introduced here, and none unrelated were "fixed" along the way.The 595 kB bundle-size warning is also pre-existing.
🤖 Generated with Claude Code