Amounts
Amounts are decimal strings in the asset's units, never floats. How the API and the SDKs take, return and convert them.
On this page
Amounts are decimal strings in the asset's own units: "49.90" USDT, "0.0015" BTC. They are
never JSON numbers, so no amount is ever rounded by floating point on its way to you.
- What you send: at most as many decimal places as the asset has (
GET /v1/assetslists each asset'sdecimals). A more precise amount is refused withamount_too_precise, not rounded. - What comes back: the canonical form, with no trailing zeros:
"49.90"comes back as"49.9", and zero as"0". - Minimums: every asset has a minimum payment, so network fees can't eat it.
GET /v1/assetsandGET /v1/min-amountshow them; a smaller amount is refused withamount_too_small. - Prices in a currency (
price_amount) are strings too, with at most two decimal places.
try {
await nowgate.payments.create({ network: "tron", asset: "USDT", amount: "25.0000001" });
} catch (err) {
if (!(err instanceof InvalidRequestError)) throw err;
// err.code is "amount_too_precise"; each field's problem has its JSON pointer
pointer = err.errors[0]?.pointer;
assert.equal(err.code, "amount_too_precise");
}try:
client.payments.create(network="tron", asset="USDT", amount="25.0000001")
except InvalidRequestError as err:
# err.code is "amount_too_precise"; each field's problem has its JSON pointer
pointer = err.errors[0]["pointer"]
check(err.code == "amount_too_precise", err.code)try {
$nowgate->payments->create(['network' => 'tron', 'asset' => 'USDT', 'amount' => '25.0000001']);
} catch (InvalidRequestException $e) {
// $e->errorCode is 'amount_too_precise'; each field's problem has its JSON pointer
$pointer = $e->errors[0]['pointer'] ?? null;
check($e->errorCode === 'amount_too_precise', $e->errorCode);
}In the SDKs#
The SDKs check that an amount is a string before sending, and leave its format to the API, so every client gets the same answer with the field's pointer.
| Accepted | Refused before sending | |
|---|---|---|
| TypeScript | string | number and bigint: a TypeError naming the field |
| Python | str, int, a finite decimal.Decimal | float and bool: a TypeError naming the field |
| PHP | string, int | float and bool: an InvalidArgumentException naming the field |
Converting#
Each SDK has exact helpers, without floating point, for an asset's smallest units (its
decimals from assets.list()):
| TypeScript | Python | PHP | |
|---|---|---|---|
"1.5" with 6 decimals to units | Amounts.toUnits("1.5", 6) → 1500000n | Amounts.to_units("1.5", 6) → 1500000 | Amounts::toUnits('1.5', 6) → '1500000' |
| units back to an amount | Amounts.fromUnits(1500000n, 6) → "1.5" | Amounts.from_units(1500000, 6) → "1.5" | Amounts::fromUnits('1500000', 6) → '1.5' |
| compare | Amounts.compare("1.5", "1.50") → 0 | Amounts.compare("1.5", "1.50") → 0 | Amounts::compare('1.5', '1.50') → 0 |