The one rule
Callbacks always exchange the decimal value.
12.45, never 1245. Zero-Dash converts to and from integer storage internally; you never see minor units on the wire.How Zero-Dash stores money
Internally every monetary value is a 64-bit integer. Each currency carries adecimal_places value that converts between that integer and the decimal exchanged in callbacks.
This matters to you for one reason: it fixes the precision each currency gets, and anything beyond it is truncated.
Fiat
Fiat values are stored in cents —decimal_places = 2.
Crypto
Every crypto asset is capped at 8 decimal places, even when the chain supports more.
Worked examples of the internal representation:
Precision on your side
Use a decimal type, never a float
BigDecimal, decimal.Decimal, shopspring/decimal, Prisma.Decimal — anything exact. IEEE-754 binary floats cannot represent 0.1, and rounding errors in a wallet turn into reconciliation tickets.Parse JSON numbers as strings
Most JSON parsers hand you a
double before you can intervene. Configure the parser to keep raw numbers — json.Number in Go, parse_float=Decimal in Python, JsonNumberHandling in .NET — then build your decimal from the text.Round only at the boundary
Compute in full precision; truncate to the currency’s places only when writing the value out.
Currency codes
Codes follow ISO-4217 —EUR, USD, BTC, ETH — and crypto uses the same convention.
FUN is the virtual currency used by free-to-play sessions. It never reaches your wallet: demo sessions produce no callbacks at all.Currency consistency
One currency is fixed for the entire life of an account ID. It must be the same value across:Launch
The
currency parameter you pass to Obtain game launch URL.Authorization
balance.currency returned by Player authorization.Every movement
stake.currency and payout.currency in each debit, credit and rollback.Free rounds
currencyCode on both the campaign and the bonus code.Balance semantics
Thebalance you return is the balance after the operation was applied.