diff --git a/src/core/Base58.ts b/src/core/Base58.ts index 34a07226..b9c00f0c 100644 --- a/src/core/Base58.ts +++ b/src/core/Base58.ts @@ -125,8 +125,9 @@ export function toHex(value: string): Hex.Hex { integer = integer + internal.alphabetToInteger[char]! } - if (!pad) return `0x${integer.toString(16)}` as Hex.Hex - return `0x${'0'.repeat(pad * 2)}${integer.toString(16)}` as Hex.Hex + const body = integer === 0n ? '' : integer.toString(16) + if (!pad) return `0x${body}` as Hex.Hex + return `0x${'0'.repeat(pad * 2)}${body}` as Hex.Hex } export declare namespace toHex { diff --git a/src/core/_test/Base58.test.ts b/src/core/_test/Base58.test.ts index 54c50119..f1e2e492 100644 --- a/src/core/_test/Base58.test.ts +++ b/src/core/_test/Base58.test.ts @@ -17,6 +17,16 @@ describe('fromHex', () => { test('default', () => { expect(Base58.fromHex('0x00000000287fb4cd')).toBe('1111233QC4') }) + + test('leading zeros (all-zero value)', () => { + expect(Base58.fromHex('0x00')).toBe('1') + expect(Base58.fromHex('0x0000')).toBe('11') + expect(Base58.fromHex('0x000000')).toBe('111') + }) + + test('empty', () => { + expect(Base58.fromHex('0x')).toBe('') + }) }) describe('fromString', () => { @@ -47,6 +57,15 @@ describe('toBytes', () => { ] `) }) + + test('leading zeros', () => { + expect(Base58.toBytes('1')).toStrictEqual(new Uint8Array([0])) + expect(Base58.toBytes('1112NEpo7TZRRrLZSi2U')).toStrictEqual( + new Uint8Array([ + 0, 0, 0, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, + ]), + ) + }) }) describe('toHex', () => { @@ -57,6 +76,16 @@ describe('toHex', () => { '[Error: invalid base58 character: I]', ) }) + + test('leading ones (all-zero value)', () => { + expect(Base58.toHex('1')).toBe('0x00') + expect(Base58.toHex('11')).toBe('0x0000') + expect(Base58.toHex('111')).toBe('0x000000') + }) + + test('empty', () => { + expect(Base58.toHex('')).toBe('0x') + }) }) describe('toString', () => { diff --git a/src/core/internal/base58.ts b/src/core/internal/base58.ts index c9dc818a..e3bf9aa5 100644 --- a/src/core/internal/base58.ts +++ b/src/core/internal/base58.ts @@ -77,6 +77,7 @@ export function from(value: Hex.Hex | Bytes.Bytes) { let integer = (() => { let hex = value if (value instanceof Uint8Array) hex = Hex.fromBytes(bytes) + if (hex === '0x') return 0n return BigInt(hex as string) })() @@ -87,7 +88,7 @@ export function from(value: Hex.Hex | Bytes.Bytes) { result = integerToAlphabet[remainder] + result } - while (bytes.length > 1 && bytes[0] === 0) { + while (bytes.length > 0 && bytes[0] === 0) { result = '1' + result bytes = bytes.slice(1) }