From 5527b12ef687cb457f87c57d37254337cad9568d Mon Sep 17 00:00:00 2001 From: Toni Tabak Date: Fri, 29 Nov 2024 22:56:33 +0900 Subject: [PATCH] feat: units utils --- __tests__/utils/utils.test.ts | 25 ++++++++++++++++++++++- src/index.ts | 1 + src/utils/units.ts | 37 +++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 src/utils/units.ts diff --git a/__tests__/utils/utils.test.ts b/__tests__/utils/utils.test.ts index a1f6e0b7c..24f9135ae 100644 --- a/__tests__/utils/utils.test.ts +++ b/__tests__/utils/utils.test.ts @@ -1,8 +1,31 @@ import * as starkCurve from '@scure/starknet'; -import { constants, ec, hash, num, stark } from '../../src'; + +import { constants, ec, hash, num, stark, units } from '../../src'; const { IS_BROWSER } = constants; +test('units', () => { + expect(units(1n, 'fri')).toEqual('0.000000000000000001'); + expect(units(1000n, 'fri')).toEqual('0.000000000000001'); + expect(units(123123123n, 'fri')).toEqual('0.000000000123123123'); + expect(units('123123123', 'fri')).toEqual('0.000000000123123123'); + expect(units(10n ** 18n, 'fri')).toEqual('1'); + expect(units(30n * 10n ** 16n, 'fri')).toEqual('0.3'); + expect(units(30n * 10n ** 22n, 'fri')).toEqual('300000'); + expect(units('0x40ff', 'fri')).toEqual('0.000000000000016639'); + + expect(units('0.3', 'strk')).toEqual('300000000000000000'); + expect(units('1', 'strk')).toEqual('1000000000000000000'); + expect(units('1000', 'strk')).toEqual('1000000000000000000000'); + expect(units('123123123.123', 'strk')).toEqual('123123123123000000000000000'); + expect(units('0x40ff', 'strk')).toEqual('16639000000000000000000'); + + const toTest = ['0.333', '123123123.123', '1000.1', '123123123.123123', '0.0000003']; + toTest.forEach((element) => { + expect(units(units(element, 'strk'), 'fri')).toEqual(element); + }); +}); + test('isNode', () => { expect(IS_BROWSER).toBe(false); }); diff --git a/src/index.ts b/src/index.ts index e62bfadfc..543cee52e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -45,6 +45,7 @@ export * from './utils/calldata'; export * from './utils/calldata/enum'; export * from './utils/contract'; export * from './utils/transactionReceipt'; +export * from './utils/units'; export * as wallet from './wallet/connect'; /** diff --git a/src/utils/units.ts b/src/utils/units.ts new file mode 100644 index 000000000..5a0f10881 --- /dev/null +++ b/src/utils/units.ts @@ -0,0 +1,37 @@ +import { isHex } from './num'; + +/** + * Convert strk to fri or fri to strk + * @example + * ```typescript + * units(1000n, 'fri') // '0.000000000000001' strk + * units('1', 'strk') // '1000000000000000000' fri + * ``` + */ +export function units(amount: string | bigint, simbol: 'fri' | 'strk' = 'fri') { + if (simbol === 'strk') { + let numStr = ''; + if (typeof amount === 'bigint') numStr = amount.toString(); + else if (typeof amount === 'string') { + if (isHex(amount)) { + numStr = BigInt(amount).toString(); + } else { + numStr = amount; + } + } + + const [integer, decimal = '0'] = numStr.split('.'); + const pdec = decimal.padEnd(18, '0'); + return `${integer}${pdec}`.replace(/\b0+/g, ''); + } + + const bis = BigInt(amount).toString(); + let strk; + if (bis.length <= 18) { + strk = `0.${bis.padStart(18, '0')}`; + } else { + strk = `${bis.slice(0, bis.length - 18)}.${bis.slice(bis.length - 18)}`; + } + + return strk.replace(/(\.[0-9]*[1-9])0+$|\.0*$/, '$1'); +}