From 03cdda89b5e561a43d3fd1dc8908821af7a64943 Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Wed, 3 Sep 2025 10:35:04 -0700 Subject: [PATCH] Add support for number output from unit denomination convert function. --- src/lib/tools.ts | 37 +++++++++++++++++++++++++++---------- src/types.d.ts | 5 ++++- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/lib/tools.ts b/src/lib/tools.ts index 592f760..0b5e5af 100644 --- a/src/lib/tools.ts +++ b/src/lib/tools.ts @@ -16,10 +16,13 @@ import { Wallet } from './wallet' * @param {(bigint|number|string)} amount - Decimal amount to convert * @param {string} inputUnit - Current denomination * @param {string} outputUnit - Desired denomination +* @param {string} [format] - Data type of output */ export function convert (amount: bigint | number | string, inputUnit: string, outputUnit: string): string -export function convert (amount: bigint | number | string, inputUnit: string, outputUnit: string, format?: 'bigint' | 'string'): bigint -export function convert (amount: unknown, inputUnit: unknown, outputUnit: unknown, format?: unknown): bigint | string { +export function convert (amount: bigint | number | string, inputUnit: string, outputUnit: string, format?: 'bigint'): bigint +export function convert (amount: bigint | number | string, inputUnit: string, outputUnit: string, format?: 'number'): number +export function convert (amount: bigint | number | string, inputUnit: string, outputUnit: string, format?: 'string'): string +export function convert (amount: unknown, inputUnit: unknown, outputUnit: unknown, format?: unknown): bigint | number | string { if (typeof amount !== 'bigint' && typeof amount !== 'number' && typeof amount !== 'string') { throw new Error('Invalid amount', { cause: typeof amount }) } @@ -29,15 +32,20 @@ export function convert (amount: unknown, inputUnit: unknown, outputUnit: unknow if (typeof inputUnit !== 'string') { throw new TypeError('Invalid input unit', { cause: typeof inputUnit }) } + (inputUnit as string) = inputUnit.toUpperCase() if (typeof outputUnit !== 'string') { throw new TypeError('Invalid output unit', { cause: typeof outputUnit }) } - if (typeof inputUnit !== 'string' || UNITS[inputUnit.toUpperCase()] == null) { + (outputUnit as string) = outputUnit.toUpperCase() + if (UNITS[inputUnit] == null) { throw new Error(`Unknown denomination ${inputUnit}, expected one of the following: ${Object.keys(UNITS)}`) } - if (typeof outputUnit !== 'string' || UNITS[outputUnit.toUpperCase()] == null) { + if (UNITS[outputUnit] == null) { throw new Error(`Unknown denomination ${outputUnit}, expected one of the following: ${Object.keys(UNITS)}`) } + if (format !== undefined && format !== 'bigint' && format !== 'number' && format !== 'string') { + throw new Error('Invalid output format', { cause: format }) + } let [i, f] = typeof amount === 'string' ? amount.split('.') @@ -45,7 +53,7 @@ export function convert (amount: unknown, inputUnit: unknown, outputUnit: unknow i = i.replace(/^0*/g, '') f = f?.replace(/0*$/g, '') - const inUnit = UNITS[inputUnit.toUpperCase()] + const inUnit = UNITS[inputUnit] const intShift = i.length + inUnit if (f?.length > inUnit) { throw new RangeError('Amount contains fractional raw') @@ -65,17 +73,26 @@ export function convert (amount: unknown, inputUnit: unknown, outputUnit: unknow if (int < 0n) { throw new Error('Amount must be non-negative') } - if (format === 'bigint') { - return int - } // convert to desired denomination - const outUnit = UNITS[outputUnit.toUpperCase()] + const outUnit = UNITS[outputUnit] i = int.toString().padStart(40, '0') f = i.slice(40 - outUnit).replace(/0*$/g, '') i = i.slice(0, 40 - outUnit).replace(/^0*/g, '') + const output = `${i === '' ? '0' : i}${f === '' ? '' : '.'}${f}` - return `${i === '' ? '0' : i}${f === '' ? '' : '.'}${f}` + switch (format) { + case 'bigint': { + if (!f) return BigInt(output) + throw new RangeError('Output fractional amount truncated') + } + case 'number': { + if (Number(i) <= Number.MAX_SAFE_INTEGER) return Number(output) + throw new RangeError('Output larger than Number.MAX_SAFE_INTEGER') + } + case 'string': + default: return output + } } function hash (data: string | string[], encoding?: 'hex'): Uint8Array diff --git a/src/types.d.ts b/src/types.d.ts index 995d0af..cb41fc1 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -518,9 +518,12 @@ type SweepResult = { * @param {(bigint|number|string)} amount - Decimal amount to convert * @param {string} inputUnit - Current denomination * @param {string} outputUnit - Desired denomination +* @param {string} [format] - Data type of output */ export declare function convert (amount: bigint | number | string, inputUnit: string, outputUnit: string): string -export declare function convert (amount: bigint | number | string, inputUnit: string, outputUnit: string, format?: 'bigint' | 'string'): bigint +export declare function convert (amount: bigint | number | string, inputUnit: string, outputUnit: string, format?: 'bigint'): bigint +export declare function convert (amount: bigint | number | string, inputUnit: string, outputUnit: string, format?: 'number'): number +export declare function convert (amount: bigint | number | string, inputUnit: string, outputUnit: string, format?: 'string'): string declare function hash (data: string | string[], encoding?: 'hex'): Uint8Array /** * Signs arbitrary strings with a private key using the Ed25519 signature scheme. -- 2.47.3