Get Started
Back to all articles

How to parse crypto wallet API balance decimals

Parse crypto wallet API balance decimals without rounding errors. Keep raw integers exact, validate metadata, and separate display values from agent logic.

BUContent TeamOct 23, 2026 — 9 min read
How to parse crypto wallet API balance decimals

Parse crypto wallet API balance decimals by keeping the raw balance as an integer string and applying the asset’s decimal scale with exact arithmetic. For developers building wallet-data workflows, the rule is display balance = raw balance / 10^decimals, provided the API actually returns base units. Never apply that division to an already normalized balance, and never convert a large raw balance to a JavaScript Number first.

TL;DR
  • Crypto wallet API balance decimals describe a scale; confirm whether the returned amount is raw or already normalized.
  • Keep raw balances as integer strings and use exact arithmetic, not floating-point division.
  • BuildAWallet NON-HUMAN serves machine-facing wallet data workflows; balance reads do not grant signing authority.
  • Reject missing decimal metadata instead of silently assuming a scale.

Why this matters for agent wallet data

BuildAWallet NON-HUMAN is the machine-facing side for AI agents and the developers building them; HUMAN is a separate wallet-blueprint design experience. Start with the distinctions on the BuildAWallet homepage, then validate the intended read-only operation and its deployment requirements before connecting an application.

A balance parser sits between a network response and decisions about funds. If the parser mistakes base units for whole tokens, every downstream threshold, notification and displayed amount uses the wrong scale.

BuildAWallet NON-HUMAN is for developers seeking machine-facing wallet data access, not autonomous signing authority. Its Base and Solana balance-read scope does not establish that every documented operation works in a particular deployment.

How do you parse crypto wallet API balance decimals?

First identify the amount’s representation, then obtain the matching decimal scale, and only then format the value. Decimal metadata tells you where to place the decimal point; it does not establish asset identity or prove that the response is current.

The following amounts are illustrative examples, not responses from a named provider. Field names such as raw and decimals below belong to the application examples, not a verified API schema.

RepresentationExampleCorrect handlingLimitation
Raw integer1234567, scale 6Format as 1.234567Requires matching decimal metadata
Normalized decimal1.234567Preserve as an exact decimal stringMust not be divided again
Display text1.23 tokensUse for presentation onlyLabels and rounding prevent exact arithmetic
  1. Identify the asset. Match the network and token contract or mint, not just the ticker symbol.
  2. Check the response contract. Confirm whether the amount contains base units, normalized units or presentation text.
  3. Validate the scale. Require a nonnegative integer from the appropriate asset metadata or documented response field.
  4. Preserve precision. Keep the raw amount as a string until an exact-integer or decimal implementation handles it.
  5. Format separately. Produce a display string without replacing the original accounting value.

A successful HTTP response is not sufficient validation. You still need a supported schema, the expected asset, a valid amount and an acceptable network observation.

Raw integer balances: place the decimal point exactly

For an illustrative asset with 6 decimal places, a raw balance of 1234567 means 1.234567 tokens. A raw balance of 1 means 0.000001 tokens. The scale changes the unit; it does not change the underlying integer.

The following JavaScript formatter uses string operations rather than floating-point division. Its 255-decimal ceiling is an application-specific validation limit, not a universal network rule; choose and document limits that fit your integration.

function formatBaseUnits(raw, decimals) {
  if (typeof raw !== 'string' || !/^[0-9]+$/.test(raw)) {
    throw new TypeError('Expected an unsigned integer string');
  }
  if (!Number.isSafeInteger(decimals) || decimals < 0 || decimals > 255) {
    throw new RangeError('Unsupported decimal scale');
  }

  const digits = raw.replace(/^0+(?=\d)/, '');
  if (decimals === 0) return digits;

  const padded = digits.padStart(decimals + 1, '0');
  const whole = padded.slice(0, -decimals);
  const fraction = padded.slice(-decimals).replace(/0+$/, '');

  return fraction ? `${whole}.${fraction}` : whole;
}

formatBaseUnits('1234567', 6); // '1.234567'
formatBaseUnits('1', 6);       // '0.000001'
formatBaseUnits('0', 6);       // '0'

This function returns a string. It intentionally removes insignificant trailing fractional zeros, so it formats 1230000 at scale 6 as 1.23, not 1.230000.

Use this formatter for presentation, not as a substitute for accounting records. Retain the raw integer, decimal scale and asset identity together. Also bound response sizes before processing untrusted input; a valid digit string can still be excessively large.

Normalized balances: do not scale them twice

A normalized balance already expresses whole-token units. If a documented field contains 1.234567, applying another division by a scale of 6 produces the wrong answer.

Your adapter should distinguish normalized values from raw values explicitly. Avoid a generic property named balance that sometimes contains base units and sometimes contains display units.

Useful application-side names include:

  • rawAmount: an unsigned integer string in base units.
  • decimals: the scale attached to that exact asset.
  • normalizedAmount: an exact decimal string in whole-token units.
  • displayAmount: text prepared for a person, potentially rounded or abbreviated.

These names are a proposed internal model, not a claim about any provider’s response fields. Map the verified provider schema into your model at the boundary rather than making every downstream component interpret provider-specific values.

Why wallet balance decimal handling varies

The formula stays constant, but the inputs and responsibilities differ. Check these factors before reusing a parser across operations:

  • Representation: a raw integer needs scaling; a normalized amount does not.
  • Asset metadata: the scale must belong to the requested contract, mint or native asset.
  • Network context: the same symbol is not a reliable cross-network asset identifier.
  • Serialization: a JSON string preserves digits; a JavaScript numeric value can lose integer precision.
  • Aggregation: token-account or position-level amounts require an explicit aggregation rule.
  • Presentation: rounded display text serves a different purpose from exact balance comparisons.

Do not solve these differences with a universal fallback scale. A parser that rejects an unknown representation is easier to diagnose than one that silently produces a plausible amount.

Keep reads, parsing and signing separate

Treat balance processing as a read-only pipeline: validate the response, preserve the raw amount, format it, and keep signing outside that path. No parsing function needs a private key or recovery phrase.

The following diagram separates the stages rather than implying that a balance response authorizes a transaction.

A balance-processing sequence that keeps response validation and display formatting separate from signing.
Formatting a balance does not grant permission to move it.

For BuildAWallet NON-HUMAN, validate the intended balance operation and deployment configuration before relying on its output. The supplied documentation context distinguishes Base and Solana balance reads, locally signed transaction workflows, and policy-controlled agent signing described as unavailable or in development.

Those distinctions matter operationally:

  • Data access lets an application retrieve an observation.
  • Local signing uses separately controlled signing material.
  • Signing authority determines who or what can authorize a transaction.

The crypto wallets for AI agents guide provides related context for keeping wallet access and spending authority separate. Instructions in an agent prompt are not an enforced transaction policy.

Validate the adapter before trusting the balance

Use a small read-only fixture set before connecting the parser to alerts or agent decisions. Fixtures are saved example inputs with known expected outputs; they test your application without implying that a live provider passed the same checks.

Check exact output

For the formatter above, these illustrative fixtures exercise decimal placement and zero handling:

Raw amountDecimal scaleExpected stringWhat it checks
060Genuine zero
160.000001Smallest represented unit
100000061Whole-token boundary
123456789091.23456789Fractional formatting
42042No fractional units

Also test rejection of negative balances, scientific notation, embedded commas, whitespace and missing metadata. This formatter deliberately accepts only unsigned digit strings; another operation with signed quantities needs a separately defined contract.

Check precision before parsing

JavaScript’s maximum safe integer is 9007199254740991. Beyond that boundary, a Number cannot represent every integer exactly, so converting an already rounded value to BigInt does not recover the original digits.

Require the API adapter to receive exact amounts in an appropriate representation. If a response has already crossed a lossy numeric conversion, reject it or obtain the original exact value; do not manufacture precision by appending zeros.

Check identity and observation context

Verify that the returned network and asset match the request. Retain a block reference or observation timestamp when the operation supplies one, without inventing freshness guarantees when it does not.

An exact decimal string can still describe the wrong asset or an old observation. Precision checks and freshness checks solve different problems.

Handle failures without inventing a zero balance

Unknown is not zero. A timeout, authorization failure, malformed amount or missing scale must remain distinguishable from a successful response reporting 0.

Represent failure states explicitly in your application. An agent should receive a structured unavailable or invalid result instead of a fabricated numeric balance, and retries should follow the operation’s documented behavior.

Keep logs useful without storing secrets. Record validation failures and request context needed for diagnosis, but exclude private keys, recovery material and authentication credentials; wallet addresses and balance observations also deserve deliberate handling.

Can I compare balances without converting them to decimals?

For the same asset and scale, compare raw integers directly using exact integer arithmetic. An illustrative threshold of 1.5 tokens at scale 6 becomes 1500000 base units, which can be compared against the raw balance.

Convert the threshold from an exact decimal string, not a binary floating-point calculation. Reject fractional precision beyond the asset’s scale unless your application explicitly defines a rounding rule.

Should I round a balance before an agent uses it?

No—keep the exact raw amount for agent decisions and round only the display value. A shortened amount can hide a remainder or make a threshold comparison disagree with the underlying balance.

Formatting a balance also does not establish spendable funds. Fees and transaction-specific requirements need separate validation before any signing workflow.

FAQ

What do decimals mean in a crypto wallet balance API?

Decimals specify the scale between base units and whole-token units. For an illustrative scale of 6, a raw balance of 1000000 represents 1 token; confirm that the field actually contains raw units before applying the scale.

Can I use parseFloat to parse a raw token balance?

Do not use parseFloat for exact raw-balance handling. Preserve the integer string and use exact integer or decimal arithmetic, because floating-point conversion can lose digits.

What should I do when token decimals are missing?

Reject the value as unscaled or retrieve verified metadata for the exact asset. Do not silently substitute a familiar scale or display the raw integer as whole tokens.

Does a missing token account mean the wallet balance is zero?

A missing token account does not by itself establish a wallet-wide zero balance. Follow the operation’s documented account scope and aggregation rules, and distinguish an absent account from a failed lookup.

Can I send a JavaScript BigInt directly as JSON?

Standard JSON.stringify does not serialize BigInt directly without custom handling. Convert exact integer amounts to strings at the JSON boundary and validate those strings when reading them back.

Does BuildAWallet balance access let an agent sign transactions?

BuildAWallet balance access does not grant signing authority. Validate operation-specific availability and deployment requirements, and treat locally signed transaction workflows separately from unavailable or in-development policy-controlled agent signing.

Next step: prove the smallest unit survives

Run an illustrative balance of 1 base unit through your entire read-only pipeline, including storage, JSON serialization and display. Confirm that the final exact amount still represents that smallest unit, even if the interface rounds its visible label to zero. Only then connect the parser to balance-dependent decisions.

You might also like