From 72a7ce5671c0eb539a5482b53b5a534ad5d05a6d Mon Sep 17 00:00:00 2001 From: airdropzamani Date: Fri, 4 Sep 2026 03:49:49 +0300 Subject: [PATCH] fix(keys): accept uppercase 0X prefix in isHexString Align the hex type guard with hexStringToBytes, which already strips a case-insensitive 0x prefix. Values like 0XABCDEF decoded successfully but failed isHexString. Co-authored-by: Cursor --- .changeset/is-hex-string-uppercase-prefix.md | 5 +++++ packages/keys/src/encoding/hex.test.ts | 5 +++++ packages/keys/src/encoding/hex.ts | 5 ++++- 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 .changeset/is-hex-string-uppercase-prefix.md diff --git a/.changeset/is-hex-string-uppercase-prefix.md b/.changeset/is-hex-string-uppercase-prefix.md new file mode 100644 index 00000000..fd4b5416 --- /dev/null +++ b/.changeset/is-hex-string-uppercase-prefix.md @@ -0,0 +1,5 @@ +--- +"@agentcommercekit/keys": patch +--- + +Accept an uppercase `0X` prefix in `isHexString`, matching `hexStringToBytes`. diff --git a/packages/keys/src/encoding/hex.test.ts b/packages/keys/src/encoding/hex.test.ts index c66e3b36..1cc9f2bd 100644 --- a/packages/keys/src/encoding/hex.test.ts +++ b/packages/keys/src/encoding/hex.test.ts @@ -40,6 +40,11 @@ describe("isHexString", () => { expect(isHexString("0x1234567890abcdef")).toBe(true) }) + test("returns true for valid hex strings with uppercase 0X prefix", () => { + // `hexStringToBytes` already accepts this form; the guard must agree. + expect(isHexString("0XABCDEF")).toBe(true) + }) + test("returns true for valid hex strings without 0x prefix", () => { expect(isHexString("1234567890abcdef")).toBe(true) }) diff --git a/packages/keys/src/encoding/hex.ts b/packages/keys/src/encoding/hex.ts index aa4de17b..bc1bd439 100644 --- a/packages/keys/src/encoding/hex.ts +++ b/packages/keys/src/encoding/hex.ts @@ -47,6 +47,9 @@ export function isHexString(value: unknown): value is string { return false } - const hexWithoutPrefix = value.startsWith("0x") ? value.slice(2) : value + // Match `hexStringToBytes`: accept both `0x` and `0X` prefixes. + const hexWithoutPrefix = value.toLowerCase().startsWith("0x") + ? value.slice(2) + : value return /^[0-9A-Fa-f]+$/.test(hexWithoutPrefix) }