fix: stop upcasting transaction version to bigint - #1917
Merged
mcintyre94 merged 1 commit intoAug 13, 2026
Conversation
🦋 Changeset detectedLatest commit: de5dea7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 48 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Kit's RPC response transformer upcasts every JSON integer to a `bigint` unless the field's keypath appears in a per-method allow-list. `version` was missing from that list on `getTransaction`, `getBlock` transactions, and `getTransactionsForAddress`, so it arrived at runtime as `0n` while still typechecking as `TransactionVersion` (`'legacy' | 0 | 1`). The result is a silent mismatch between the declared type and the runtime value. A check like `if (transaction.version === 0)` compiles cleanly and is always false, because `0n === 0` is false. There is no compiler error and no runtime error; the branch simply never runs. The keypath is now allow-listed on all three methods, so `version` arrives as a number and matches its declared type.
amilz
force-pushed
the
fix/DEV-858-get-transaction-version-bigint
branch
from
August 12, 2026 23:46
e6e8eab to
de5dea7
Compare
version and token balance numerics to bigintversion to bigint
BundleMonFiles updated (4)
Unchanged files (146)
Total files change +63B +0.01% Final result: ✅ View report in BundleMon website ➡️ |
mcintyre94
approved these changes
Aug 13, 2026
mcintyre94
left a comment
Member
There was a problem hiding this comment.
Nice, thanks!
On your follow ups, uiTokenAmount.uiAmount is defined as Option<f64> on the RPC, so agreed that shouldn't be bigint either
I'm unsure about the notifications one, happy to take a look at a PR but feel free to just open an issue on that if it's easier/needs more investigation.
This was referenced Aug 13, 2026
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.
Kit's RPC response transformer upcasts every JSON integer to a
bigintunless the field's keypath appears in a per-method allow-list (getAllowedNumericKeypaths()inpackages/rpc-api/src/index.ts).versionwas missing from that list ongetTransaction,getBlocktransactions, andgetTransactionsForAddress, so it arrives at runtime as0nwhile still typechecking asTransactionVersion('legacy' | 0 | 1).The result is a silent mismatch between the declared type and the runtime value:
There is no compiler error and no runtime error; the branch simply never runs. This was found in Explorer, where it silently disabled an entire feature.
Changes
Allow-list
versionon all three methods. Three added keypaths.Testing
New unit tests in
packages/rpc-api/src/__tests__/allowed-numeric-keypaths-test.tspush canned responses throughcreateSolanaRpcApi()and assertversionarrives as a number. Three of the four fail against the unpatched allow-list; the fourth covers the'legacy'string case, which was never affected and guards against over-correcting.Follow-ups, deliberately not in this PR
Token balance numerics. The same audit found that
uiTokenAmount.uiAmountis missing from the allow-list on these same three methods, and thatsimulateTransactionhas no token balance keypaths allow-listed at all.uiAmountis anf64, and the transformer's guard isNumber.isInteger, so a whole-number balance was upcast while a fractional one was not. That fix is ready and will follow immediately after this merges. It is kept separate because it adds a new public export to@solana/rpc-transformersand so carries aminorbump, whereas this change is a purepatch.@solana/rpc-subscriptions-api. Same class of bug, different root cause. Its allow-list is keyed by notification method name (blockNotifications), but the response transformer is invoked with the subscribe request, whosemethodNameisblockSubscribe(rpc-subscriptions-pubsub-plan.ts:96). The lookup never matches, so the entire subscriptions allow-list is dead code and every field it names is upcast. There is a second defect underneath: the publisher is memoized per(channel, responseTransformer)and its closure captures the firstsubscribeRequest, so the transform is resolved per channel where it needs to be per subscription. Fixing it flips affected fields frombiginttonumberat runtime, which is breaking for anyone who adapted, so it needs its own change and its own bump. Adding correct keypaths to a list that is never consulted would ship an inert change that reads as fixed.