From 82ef1edb6fcc99f1f7fde768fab959cb079a7002 Mon Sep 17 00:00:00 2001 From: Scorbajio Date: Wed, 9 Oct 2024 14:14:04 -0700 Subject: [PATCH] Add Units class for conversions (#3734) * Add static Units class to utils package * Add tests for Units class * Make review changes * Add tests for new error condition * Add docstrings --- packages/util/src/units.ts | 36 ++++++++++++++++ packages/util/test/units.spec.ts | 72 +++++++++++++++++++++++++++++++- 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/packages/util/src/units.ts b/packages/util/src/units.ts index 5465baf5b1..ac38668768 100644 --- a/packages/util/src/units.ts +++ b/packages/util/src/units.ts @@ -1,6 +1,9 @@ import { BIGINT_0, BIGINT_1 } from './constants.js' + /** Easy conversion from Gwei to wei */ export const GWEI_TO_WEI = BigInt(1000000000) +export const WEI_TO_EITHER = BigInt(10 ** 18) +export const WIE_TO_GWEI = BigInt(10 ** 9) export function formatBigDecimal( numerator: bigint, @@ -18,3 +21,36 @@ export function formatBigDecimal( const zerosPostDecimal = String(maxDecimalFactor).length - 1 - String(fraction).length return `${full}.${'0'.repeat(zerosPostDecimal)}${fraction}` } + +export class Units { + static validateInput(amount: number | bigint): void { + if (typeof amount === 'number' && !Number.isInteger(amount)) { + throw new Error('Input must be an integer number') + } + if (BigInt(amount) < 0) { + throw new Error('Input must be a positive number') + } + } + + /** + * Convert a number or bigint input of ether to wei + * + * @param {number | bigint} amount amount of units of ether to convert to wei + * @returns {bigint} amount of units in wei + */ + static ether(amount: number | bigint): bigint { + Units.validateInput(amount) + return BigInt(amount) * WEI_TO_EITHER + } + + /** + * Convert a number or bigint input of gwei to wei + * + * @param amount amount of units of gwei to convert to wei + * @returns {bigint} amount of units in wei + */ + static gwei(amount: number | bigint): bigint { + Units.validateInput(amount) + return BigInt(amount) * WIE_TO_GWEI + } +} diff --git a/packages/util/test/units.spec.ts b/packages/util/test/units.spec.ts index be78ec3927..e2b75f7f7c 100644 --- a/packages/util/test/units.spec.ts +++ b/packages/util/test/units.spec.ts @@ -1,6 +1,6 @@ import { assert, describe, it } from 'vitest' -import { formatBigDecimal } from '../src/index.js' +import { Units, formatBigDecimal } from '../src/index.js' describe('formatBigDecimal', function () { const testCases: [bigint, bigint, bigint, string][] = [ @@ -20,3 +20,73 @@ describe('formatBigDecimal', function () { }) } }) + +describe('Units', () => { + describe('ether()', () => { + it('should convert 1 ether to wei', () => { + const result = Units.ether(1) + assert.equal(result, BigInt(10 ** 18)) + }) + + it('should convert 0 ether to wei', () => { + const result = Units.ether(0) + assert.equal(result, BigInt(0)) + }) + + it('should convert a large number of ether to wei', () => { + const result = Units.ether(1000000) + assert.equal(result, BigInt(1000000) * BigInt(10 ** 18)) + }) + + it('should throw error when a non-integer number is used', () => { + assert.throws(() => { + Units.ether(0.5) + }, 'Input must be an integer number') + }) + + it('should throw error when a negative number is used', () => { + assert.throws(() => { + Units.ether(-1) + }, 'Input must be a positive number') + }) + + it('should convert a bigint amount of ether to wei', () => { + const result = Units.ether(BigInt(2)) + assert.equal(result, BigInt(2) * BigInt(10 ** 18)) + }) + }) + + describe('gwei()', () => { + it('should convert 1 gwei to wei', () => { + const result = Units.gwei(1) + assert.equal(result, BigInt(10 ** 9)) + }) + + it('should convert 0 gwei to wei', () => { + const result = Units.gwei(0) + assert.equal(result, BigInt(0)) + }) + + it('should convert a large number of gwei to wei', () => { + const result = Units.gwei(1000000) + assert.equal(result, BigInt(1000000) * BigInt(10 ** 9)) + }) + + it('should throw error when a non-integer number is used', () => { + assert.throws(function () { + Units.gwei(0.5) + }, 'Input must be an integer number') + }) + + it('should throw error when a negative number is used', () => { + assert.throws(() => { + Units.ether(-1) + }, 'Input must be a positive number') + }) + + it('should convert a bigint amount of gwei to wei', () => { + const result = Units.gwei(BigInt(2)) + assert.equal(result, BigInt(2) * BigInt(10 ** 9)) + }) + }) +})