diff --git a/package-lock.json b/package-lock.json index 6532145c..d8c45aa3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "dependencies": { "@types/pbkdf2": "^3.1.2", "big-varint": "^0.1.3", + "decimal.js": "^10.4.3", "pbkdf2": "^3.1.2" }, "devDependencies": { @@ -5009,8 +5010,7 @@ "node_modules/decimal.js": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, "node_modules/dedent": { "version": "1.5.1", diff --git a/package.json b/package.json index f17c560a..0889f3c0 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "dependencies": { "@types/pbkdf2": "^3.1.2", "big-varint": "^0.1.3", + "decimal.js": "^10.4.3", "pbkdf2": "^3.1.2" } } diff --git a/packages/massa-web3/src/experimental/basicElements/mas.ts b/packages/massa-web3/src/experimental/basicElements/mas.ts index b72913b5..c7897b2f 100644 --- a/packages/massa-web3/src/experimental/basicElements/mas.ts +++ b/packages/massa-web3/src/experimental/basicElements/mas.ts @@ -1,4 +1,5 @@ -import { FIRST, FIVE, ONE, ZERO } from '../utils' +import Decimal from 'decimal.js' +import { FIRST, ONE } from '../utils' import { U64, fromNumber } from './serializers/number/u64' export const NB_DECIMALS = 9 @@ -104,7 +105,7 @@ export function fromString(value: string): Mas { * Converts a Mas value to a string with rounding approximation. * * @param value - The Mas value. - * @param decimalPlaces - The number of decimal places to include in the string. If null, trailing zeros are removed. + * @param decimalPlaces - The number of decimal places to include in the string. * @returns The value as a string. * * @throws An error if the value is too large to be represented by a U256. @@ -113,33 +114,15 @@ export function toString( value: Mas, decimalPlaces: number | null = null ): string { - if (value >= BigInt(ONE) << BigInt(SIZE_U256_BIT)) { + if (BigInt(value) >= BigInt(ONE) << BigInt(SIZE_U256_BIT)) { throw new Error(ERROR_VALUE_TOO_LARGE) } - const valueString = value.toString() - const integerPart = valueString.slice(ZERO, -NB_DECIMALS) || '0' - let decimalPart = valueString.slice(-NB_DECIMALS).padStart(NB_DECIMALS, '0') + const scaledValue = new Decimal(value.toString()).div(`1e+${NB_DECIMALS}`) - if (decimalPlaces === null) { - // If decimalPlaces is null, remove trailing zeros from the decimal part - decimalPart = decimalPart.replace(/0+$/, '') - } else if (decimalPlaces < NB_DECIMALS) { - // If decimalPlaces is specified and less than NB_DECIMALS, handle rounding - const roundingDigit = parseInt(decimalPart[decimalPlaces]) - - if (roundingDigit >= FIVE) { - // If the rounding digit is 5 or greater, round up - decimalPart = ( - BigInt(decimalPart.slice(ZERO, decimalPlaces)) + BigInt(ONE) - ) - .toString() - .padStart(decimalPlaces, '0') - } else { - // Otherwise, truncate the decimal part to the specified number of places - decimalPart = decimalPart.slice(ZERO, decimalPlaces) - } + if (decimalPlaces !== null) { + return scaledValue.toFixed(decimalPlaces, Decimal.ROUND_HALF_UP) } - return decimalPart.length ? `${integerPart}.${decimalPart}` : integerPart + return scaledValue.toString() }