Adding support to format roundDigits (for tokenDust)
Nice library.
We'd like to do a PR to add following functionality to better display token dust. E.g. when amounts are < 0.0
dnum.format([ 126, 8], roundDust: 1)
=> 0.00001
dnum.format([ 126, 8], roundDust: 2)
=> 0.000013
Would you accept a PR for that, any considerations?
@yodlmeister I'm not familiar with your exact usecase, but a relatively simple helper function that leverages the existing digits and trailingZeros options could achieve what you're looking for:
import * as dn from 'dnum';
function roundDust(dnum: dn.Dnum, dustDigits: number): string {
const sigZeros = Math.max(dnum[1] - dnum[0].toString().length, 0);
return dn.format(dnum, { digits: sigZeros + dustDigits, trailingZeros: false });
}
console.log(dn.format([126n, 8])); // 0.00000126
console.log(roundDust([126n, 8], 1)); // 0.000001
console.log(roundDust([126n, 8], 2)); // 0.0000013
Nice solution @carpntr, thanks!
@yodlmeister I think it could be nice to have this in the library yes, especially if the implementation can be compact enough.
Some thoughts:
On naming, I think we could skip "round", as format() already rounds decimals with the other options. Some ideas:
-
dust -
trail -
leadingZeros, this one is weird because it doesn’t really mirrortrailingZeros, but I’ve been wondering if havingzerosin the name could make it more clear :thinking:
I wonder how the option would impact digits, and if it would be clear enough. I can see users setting dust and expecting it to work, but it would only do digits is set:
// digits defaults to 18, so dust does nothing
dn.format([123126n, 18], { dust: 2 }) // "0.000000000000123126"
// digits is small enough for dust to take precedence
dn.format([123126n, 18], { digits: 2, dust: 2 }) // "0.00000000000012"
Is there a need for choosing the number of dust decimals, versus only having a boolean (= 1 digit)? The dust could be at any position in the decimals depending on the number, so choosing the dust digits doesn’t offer as much control as digit:
let dust1 = { digits: 0, dust: 1 }
let dust2 = { digits: 0, dust: 2 }
dn.format([126n, 18], dust1) // "0.0000000000000001"
dn.format([126n, 18], dust2) // "0.00000000000000013"
dn.format([126000000000000000n, 18], dust1) // "0.1"
dn.format([126000000000000000n, 18], dust2) // "0.13"
Or would it be useful for certain cases?
Another idea: what if the option was set to the number of digits until which the dust gets displayed?
It would basically take over digits when the number of leading zeros exceeds its value:
let o = { digits: 2, trailingZeros: true }
dn.format([126n, 8], { ...o, dust: 5 }) // "0.00013" (dust applies)
dn.format([126n, 8], { ...o, dust: 4 }) // "0.0001" (dust applies)
dn.format([126n, 8], { ...o, dust: 3 }) // "0.00" (digits applies)
@carpntr @yodlmeister what do you guys think?
@carpntr @yodlmeister what do you guys think?
@carpntr your solution worked perfectly. I'll deploy this and a few small modifications and write a PR once this is running smoothly.