-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: AurelienFT <[email protected]> Co-authored-by: BenRey <[email protected]> Co-authored-by: ASAPSegfault <[email protected]> Co-authored-by: BenRey <[email protected]>
- Loading branch information
1 parent
04b3e14
commit e0f6fcf
Showing
4 changed files
with
180 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
131 changes: 131 additions & 0 deletions
131
packages/massa-web3/src/experimental/basicElements/mas.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import { FIRST, ONE } from '../utils' | ||
|
||
const NB_DECIMALS = 9 | ||
const POWER_TEN = 10 | ||
const SIZE_U256_BIT = 256 | ||
|
||
export const ERROR_NOT_SAFE_INTEGER = 'value is not a safe integer.' | ||
export const ERROR_VALUE_TOO_LARGE = 'value is too large.' | ||
|
||
export type Mas = bigint | ||
|
||
/** | ||
* Converts an integer value to the smallest unit of the Massa currency. | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger#description | ||
* | ||
* @param value - The integer value. | ||
* @returns The value in the smallest unit of the Massa currency. | ||
* | ||
* @throws An error if the value is not a safe integer. | ||
*/ | ||
export function fromMas(value: number): Mas { | ||
if (!Number.isSafeInteger(value)) { | ||
throw new Error(ERROR_NOT_SAFE_INTEGER) | ||
} | ||
|
||
return BigInt(value * POWER_TEN ** NB_DECIMALS) | ||
} | ||
|
||
/** | ||
* Converts an integer value in milli Massa to the smallest unit of the Massa currency. | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger#description | ||
* | ||
* @param value - The value in milli Massa. | ||
* @returns The value in the smallest unit of the Massa currency. | ||
* | ||
* @throws An error if the value is not a safe integer. | ||
*/ | ||
export function fromMilliMas(value: number): Mas { | ||
if (!Number.isSafeInteger(value)) { | ||
throw new Error(ERROR_NOT_SAFE_INTEGER) | ||
} | ||
const milli = 3 | ||
return BigInt(value * POWER_TEN ** (NB_DECIMALS - milli)) | ||
} | ||
|
||
/** | ||
* Converts an integer value in micro Massa to the smallest unit of the Massa currency. | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger#description | ||
* | ||
* @param value - The value in micro Massa. | ||
* @returns The value in the smallest unit of the Massa currency. | ||
* | ||
* @throws An error if the value is not a safe integer. | ||
*/ | ||
export function fromMicroMas(value: number): Mas { | ||
if (!Number.isSafeInteger(value)) { | ||
throw new Error(ERROR_NOT_SAFE_INTEGER) | ||
} | ||
const micro = 6 | ||
return BigInt(value * POWER_TEN ** (NB_DECIMALS - micro)) | ||
} | ||
|
||
/** | ||
* Converts an integer value in nano Massa to the smallest unit of the Massa currency. | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger#description | ||
* | ||
* @param value - The value in nano Massa. | ||
* @returns The value in the smallest unit of the Massa currency. | ||
* | ||
* @throws An error if the value is not a safe integer. | ||
*/ | ||
export function fromNanoMas(value: number): Mas { | ||
if (!Number.isSafeInteger(value)) { | ||
throw new Error(ERROR_NOT_SAFE_INTEGER) | ||
} | ||
|
||
const nano = 9 | ||
return BigInt(value * POWER_TEN ** (NB_DECIMALS - nano)) | ||
} | ||
|
||
/** | ||
* Converts a decimal value to the smallest unit of the Massa currency. | ||
* | ||
* @param value - The decimal value. | ||
* @returns The value in the smallest unit of the Massa currency. | ||
* | ||
* @throws An error if the format is not a decimal. | ||
* @throws An error if the value is too large to be represented by an U256 or has too many decimals. | ||
*/ | ||
export function fromString(value: string): Mas { | ||
const parts = value.split('.') | ||
// eslint-disable-next-line @typescript-eslint/no-magic-numbers | ||
if (parts.length > 2) { | ||
throw new Error('invalid format') | ||
} | ||
|
||
const integerPart = parts[FIRST] | ||
const decimalPart = parts[ONE] || '' | ||
if (decimalPart.length > NB_DECIMALS) { | ||
throw new Error(ERROR_VALUE_TOO_LARGE) | ||
} | ||
|
||
const mas = BigInt(integerPart + decimalPart.padEnd(NB_DECIMALS, '0')) | ||
if (mas >= BigInt(ONE) << BigInt(SIZE_U256_BIT)) { | ||
throw new Error(ERROR_VALUE_TOO_LARGE) | ||
} | ||
|
||
return mas | ||
} | ||
|
||
/** | ||
* Converts a value in the smallest unit of the Massa currency to a decimal value. | ||
* | ||
* @param value - The value in the smallest unit of the Massa currency. | ||
* @returns The decimal value. | ||
* | ||
* @throws An error if the value is too large to be represented by an U256. | ||
*/ | ||
export function toString(value: Mas): string { | ||
if (value >= BigInt(ONE) << BigInt(SIZE_U256_BIT)) { | ||
throw new Error(ERROR_VALUE_TOO_LARGE) | ||
} | ||
const valueString = value.toString() | ||
const integerPart = valueString.slice(FIRST, -NB_DECIMALS) || '0' | ||
const decimalPart = valueString.slice(-NB_DECIMALS).replace(/0+$/, '') | ||
return `${integerPart}${decimalPart.length ? '.' + decimalPart : ''}` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { Mas } from '../../../src/experimental/basicElements' | ||
|
||
describe('amount conversion', () => { | ||
it('converts from integer', () => { | ||
expect(Mas.fromMas(1)).toStrictEqual(1_000_000_000n) | ||
expect(Mas.fromMas(1234)).toStrictEqual(1_234_000_000_000n) | ||
expect(() => Mas.fromMas(1.1)).toThrow(Mas.ERROR_NOT_SAFE_INTEGER) | ||
|
||
expect(Mas.fromMilliMas(1)).toStrictEqual(1_000_000n) | ||
expect(Mas.fromMilliMas(1234)).toStrictEqual(1_234_000_000n) | ||
expect(() => Mas.fromMilliMas(1.1)).toThrow(Mas.ERROR_NOT_SAFE_INTEGER) | ||
|
||
expect(Mas.fromMicroMas(1)).toStrictEqual(1_000n) | ||
expect(Mas.fromMicroMas(1234)).toStrictEqual(1_234_000n) | ||
expect(() => Mas.fromMicroMas(1.1)).toThrow(Mas.ERROR_NOT_SAFE_INTEGER) | ||
|
||
expect(Mas.fromNanoMas(1)).toStrictEqual(1n) | ||
expect(Mas.fromNanoMas(1234)).toStrictEqual(1_234n) | ||
expect(() => Mas.fromNanoMas(1.1)).toThrow(Mas.ERROR_NOT_SAFE_INTEGER) | ||
}) | ||
|
||
it('converts from string', () => { | ||
expect(Mas.fromString('1')).toStrictEqual(1_000_000_000n) | ||
expect(Mas.fromString('1.1')).toStrictEqual(1_100_000_000n) | ||
expect(Mas.fromString('01234.56789')).toStrictEqual(1_234_567_890_000n) | ||
expect(Mas.fromString('01234.567890000')).toStrictEqual(1_234_567_890_000n) | ||
expect(() => Mas.fromString('1.1.1')).toThrow() | ||
expect(() => Mas.fromString('0.1234567890')).toThrow() | ||
expect(() => | ||
Mas.fromString((BigInt(1) << BigInt(256)).toString()) | ||
).toThrow() | ||
}) | ||
|
||
it('converts to string', () => { | ||
expect(Mas.toString(1_000_000_000n)).toStrictEqual('1') | ||
expect(Mas.toString(1_100_000_000n)).toStrictEqual('1.1') | ||
expect(Mas.toString(1_234_567_890_000n)).toStrictEqual('1234.56789') | ||
expect(() => Mas.toString(BigInt(1) << BigInt(256))).toThrow() | ||
}) | ||
}) |
e0f6fcf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coverage report for experimental massa-web3
Test suite run success
57 tests passing in 10 suites.
Report generated by π§ͺjest coverage report action from e0f6fcf
e0f6fcf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coverage report for experimental massa-web3
Test suite run success
57 tests passing in 10 suites.
Report generated by π§ͺjest coverage report action from e0f6fcf