Skip to content
IC Reactor

parseTokenAmount

parseTokenAmount(text, decimals, options?): bigint

Defined in: core/src/utils/token-amount.ts:364

Read a decimal amount a person typed, such as "1.5", as the token’s base units, exactly.

The text is digits with at most one ., and may be surrounded by whitespace; "5." and ".5" are accepted. Grouping separators, exponents ("1e-8") and any other character are refused rather than guessed at, since "1,5" means 1.5 in one locale and 15 in another. More fraction digits than the token has are refused too, unless the extra ones are all zeros: 0.1 ICP is 10000000 e8s, but 0.123456789 ICP is no amount of e8s, and rounding it would send something other than what was typed.

A DisplayReactor takes a nat as its decimal text, so pass the result to one as amount.toString(); a Reactor takes the bigint itself.

string

The decimal amount, as a person types it.

string | number | bigint

The token’s decimals, from 0 to 255, as icrc1_decimals returns them.

ParseTokenAmountOptions = {}

allowNegative for an int amount.

bigint

The amount in base units: 150000000n for "1.5" at 8 decimals.

TypeError when text is not a decimal amount (blank, letters, grouping, an exponent), or decimals is not a whole number.

RangeError when text has more significant fraction digits than decimals, is negative without allowNegative, or decimals is outside 0-255.

import { parseTokenAmount } from "@ic-reactor/core"
parseTokenAmount("0.29", 8) // 29000000n (Number math gives 28999999)
parseTokenAmount("1.1", 18) // 1100000000000000000n
parseTokenAmount("0.123456789", 8) // throws RangeError: 9 fraction digits
// In a form: show the message and send nothing, or send the exact amount
const onSubmit = () => {
let amount: bigint
try {
amount = parseTokenAmount(input, decimals)
} catch (error) {
setAmountError((error as Error).message)
return
}
// A DisplayReactor's mutation takes the nat as text
transfer.mutate([{ to: { owner }, amount: amount.toString() }])
}