5

I tried using @polkadot/util's formatBalance function to get the formatted balance of the account. But it doesn't make sense.

I believe unit conversion is not working properly and I wonder what I am doing wrong.

await this.api?.query.system.account('5C8Nk6HL1eYNu3NADXDGzARdNYv6uuqoQ2FCQH26odo3Tpvt', ({ nonce, data: balance }) => {
  console.log('balance:', balance.free.toHuman())
  const free = this.formatBalance(balance.free.toHuman().replace(',', '')).split(' ');
  console.log('$balanceChanges', `{"free": "${free[0]}", "freeUnit": "${free[1]}", "reserved": "${balance.reserved.toHuman()}", "nonce": "${nonce.toHuman()}"}`);
});
balance: 399,999,874,999,852 // should be 399 nanoDES
$balanceChanges {"free": "399.9986", "freeUnit": "mDES", "reserved": "0", "nonce": "4"}

balance: 1,000,399,999,874,999,852 // should be 1 DES
$balanceChanges {"free": "99.9639", "freeUnit": "kDES", "reserved": "0", "nonce": "4"}

balance: 99,399,999,499,999,407 // should be 99.39 milliDES
$balanceChanges {"free": "993.9869", "freeUnit": "DES", "reserved": "0", "nonce": "7"}
> this.api?.registry.chainDecimals
[18]
import { BN, formatBalance as mFormatBalance } from '@polkadot/util';

...

formatBalance(balance: number | string | BN | bigint): string {
    return mFormatBalance(balance, { withUnit: 'DES' }, this.api?.registry.chainDecimals[0]);
}

1 Answer 1

4

Good question. You could try something like this:

import { ApiPromise, WsProvider } from '@polkadot/api';
import { BN, formatBalance } from '@polkadot/util';

const formatAccountBalance = async () => {
    const wsProvider = new WsProvider('wss://rpc.polkadot.io');
    const api = await ApiPromise.create({ provider: wsProvider });
    const { nonce, data: balance } = await api.query.system.account('14RYaXRSqb9rPqMaAVp1UZW2czQ6dMNGMbvukwfifi6m8ZgZ');
    const chainDecimals = api.registry.chainDecimals[0];
    console.log('raw balance:', balance.free.toNumber())
    formatBalance.setDefaults({ unit: 'DOT' });
    const defaults = formatBalance.getDefaults();
    const free = formatBalance(balance.free, { withSiFull: true }, chainDecimals);
    const reserved = formatBalance(balance.reserved, { withSiFull: true }, chainDecimals);
    console.log('Formatted balance:', `{"free": "${free}", "unit": "${defaults.unit}", "reserved": "${reserved}", "nonce": "${nonce.toHuman()}"}`);
}

Should output something like this:

raw balance: 562262999731
Formatted balance: {"free": "56.2262 DOT", "unit": "DOT", "reserved": "220.2580 DOT", "nonce": "21"}

Shawn also wrote about this here:

There are also nice examples here:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.