|
| 1 | +import { LumTypes, LumConstants } from '..'; |
| 2 | + |
| 3 | +/** |
| 4 | + * Converts the Coin amount into the destination denom. |
| 5 | + * This method does not do any actual math and only "move" the floating precision of the amoun in order to avoid any |
| 6 | + * possible floating point precision issue. |
| 7 | + * It does nothing if src denom = dst denom. |
| 8 | + * |
| 9 | + * @param coin Coin to convert into toDenom |
| 10 | + * @param toDenom destination denom to convert into |
| 11 | + * @returns the amount converted |
| 12 | + */ |
| 13 | +export const convertUnit = (coin: LumTypes.Coin, toDenom: string): string => { |
| 14 | + const parts = coin.amount.split('.'); |
| 15 | + if (parts.length > 2) { |
| 16 | + throw new Error('More than one separator found'); |
| 17 | + } |
| 18 | + |
| 19 | + if (coin.denom.startsWith('u') && coin.denom.endsWith(toDenom)) { |
| 20 | + // from micro to base |
| 21 | + if (parts.length !== 1) { |
| 22 | + throw new Error('Micro units cannot have floating precision'); |
| 23 | + } |
| 24 | + let res = parts[0]; |
| 25 | + for (let i = res.length; res.length <= LumConstants.LumExponent; i++) { |
| 26 | + res = '0' + res; |
| 27 | + } |
| 28 | + const floatIdx = res.length - LumConstants.LumExponent; |
| 29 | + return (res.substring(0, floatIdx) + '.' + res.substring(floatIdx)).replace(/0+$/, ''); |
| 30 | + } else if (toDenom.startsWith('u') && toDenom.endsWith(coin.denom)) { |
| 31 | + // form base to micro |
| 32 | + if (parts.length === 2 && parts[1].length > LumConstants.LumExponent) { |
| 33 | + throw new Error(`Floating precision cannot exceed ${LumConstants.LumExponent} digits`); |
| 34 | + } |
| 35 | + let res = parts[0] + (parts[1] || ''); |
| 36 | + for (let i = parts.length === 2 ? parts[1].length : 0; i < LumConstants.LumExponent; i++) { |
| 37 | + res += '0'; |
| 38 | + } |
| 39 | + return res.replace(/^0+/, ''); |
| 40 | + } |
| 41 | + return coin.amount; |
| 42 | +}; |
0 commit comments