Open
Conversation
This was referenced Jan 13, 2026
a1aa988 to
9feba57
Compare
9feba57 to
7b64a6a
Compare
| * The raw blockchain balance without decimals applied (e.g., "1500000000" for 1.5 SOL). | ||
| * This provides precision for calculations using BigInt/BigNumber. | ||
| */ | ||
| rawAmount: string(), |
There was a problem hiding this comment.
rawAmount lacks numeric validation unlike amount field
Medium Severity
The rawAmount field uses string() for validation while amount uses StringNumberStruct which validates the string is numeric. This inconsistency allows non-numeric values like "hello" or "" to pass validation for rawAmount. Since the PR states rawAmount is intended for "calculations using BigInt/BigNumber", invalid non-numeric strings would cause runtime errors when consumers attempt BigInt(rawAmount). Using the same StringNumberStruct (or a stricter integer-only pattern) would provide consistent validation and catch invalid values at the API boundary rather than during calculations.
Additional Locations (1)
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.
Description
This PR adds a new required
rawAmountfield to theBalanceStructandFungibleAssetAmountStructtypes in the keyring API. This field stores the raw blockchain balance without decimals applied, providing precision for calculations usingBigInt/BigNumber.Motivation
The Problem
When snaps return balance data via
keyring_getAccountBalances, theamountfield contains the human-readable value with decimals already applied (e.g.,"1.5"for 1.5 SOL). However, this causes two issues:Double division bug: If amount is already normalized ("1.5"), dividing by decimals again produces incorrect values
Precision loss: parseFloat() has limited precision (~15-17 significant digits), causing data loss for large numbers:
parseFloat("1000000000000000001"); // → 1000000000000000000 (last digit lost!)
parseFloat("1000000000000000001"); // → 1000000000000000000 (last digit lost!)
This PR
Add a rawAmount field that stores the exact blockchain value as a string:
{
amount: "1.5", // UI amount (backward compatible)
rawAmount: "1500000000", // Raw blockchain value (precise)
unit: "SOL"
}
{ amount: "1.5", // UI amount (backward compatible) rawAmount: "1500000000", // Raw blockchain value (precise) unit: "SOL"}
This enables:
Backward compatibility: Existing consumers continue using amount
Precision: New consumers use rawAmount with BigInt/BigNumber for exact calculations
Changes
@metamask/keyring-api
BalanceStruct - Used by keyring_getAccountBalances response:
export const BalanceStruct = object({ amount: StringNumberStruct, // Human-readable (e.g., "1.5") unit: string(), // Symbol (e.g., "SOL") rawAmount: string(), // NEW: Raw value (e.g., "1500000000")});
FungibleAssetAmountStruct - Used by AccountBalancesUpdated event and transaction assets:
Snap Updates (Solana, Tron, BTC)
Updated getAccountBalances to return both fields:
Breaking Change
This is a breaking change - all snaps implementing keyring_getAccountBalances must now return rawAmount. All snaps have been updated accordingly.
Testing
Updated unit tests for BalanceStruct validation
Updated type definition tests (*.test-d.ts)
Updated mock data in KeyringClient.test.ts and SnapKeyring.test.ts
Note
Breaking change: precise balances via
rawAmountrawAmountinBalanceandFungibleAssetAmount(balance.ts,asset.ts); keep human-readableamountfor compatibilityAssetStruct, transaction fee/participant examples, and docs to includerawAmount; refine comments for clarityrawAmountinAccountBalancesUpdatedpayloads; adjust validation and type tests (events.test-d.ts,balance.test(-d).ts,asset.test(-d).ts,transaction.test(-d).ts)rawAmount(SnapKeyring.test.ts,KeyringClient.test.ts)Written by Cursor Bugbot for commit 7b64a6a. This will update automatically on new commits. Configure here.