]> git.codecow.com Git - libnemo.git/commitdiff
Add support for number output from unit denomination convert function.
authorChris Duncan <chris@zoso.dev>
Wed, 3 Sep 2025 17:35:04 +0000 (10:35 -0700)
committerChris Duncan <chris@zoso.dev>
Wed, 3 Sep 2025 17:35:04 +0000 (10:35 -0700)
src/lib/tools.ts
src/types.d.ts

index 592f760bce6309cb1ce174820a74712f86167b07..0b5e5af7e2e6d19970782555a22e5f226028c69d 100644 (file)
@@ -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<ArrayBuffer>
index 995d0afd244897518b5a9dabd85b348bf17e35ff..cb41fc1c4a73b7d5a9ad2f4db802556d69755b00 100644 (file)
@@ -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<ArrayBuffer>
 /**
 * Signs arbitrary strings with a private key using the Ed25519 signature scheme.