Best practices
Truncate balances for display
When displaying player balances, truncate the value to the currency’s displayUnitScale
.
The @moneypot/frontend-utils package has various format currency helpers that we encourage you to use.
const balance = 123.456789;
const currency = { id: "BTC", displayUnitName: "bits", displayUnitScale: 100 };
// ✅ Show "123.45 bits"
// ❌ Not "123.456789 bits"
const displayBalance =
Math.floor(balance * currency.displayUnitScale) / currency.displayUnitScale;
displayBalance === 123.45;
This way, you only show an amount that the player can withdraw since the transfer system only allows integers of base unit amounts.
baseAmount = displayAmount * currency.displayUnitScale
Floor base amounts before transfer and withdrawal
Flooring user withdrawal amounts means that users leave behind <1.0 base units of currency in their game balance.
We consider this acceptable since a currency’s base unit amount is chosen to be small enough to be negligible (e.g. 1 satoshi).
The MoneyPot API (and thus @moneypot/hub) only allow integer amounts for transfers.
This means that when you implement a withdraw form, you should floor the amount to the nearest integer before sending it to the MoneyPot API.
const handleSubmit = () => {
// Player typed "12.34" bits (display units) into the box, so convert to base units and floor it.
const baseAmount = Math.floor(
Number.parseFloat(amountString) * currency.displayUnitScale
);
withdraw({
variables: {
amount: baseAmount,
currency,
},
});
};
This handles two cases:
- Too much precision, e.g.
1.123 bits
becomes1.123 * 100 = 112.3 satoshis
when instead you want112 satoshis
since the transfer system only supports integers. - Truncates floating point error, e.g.
1.12 bits * 100
becomes112.00000000000001 satoshis
when instead you want112 satoshis
.