@@ -13,8 +13,39 @@ export type Hex = `0x${string}`;
1313export type HexLike = BytesLike ;
1414
1515/**
16- * Converts a HexLike value to a Hex string.
17- * @public
16+ * Determines whether a given string is a properly formatted hexadecimal string (ccc.Hex).
17+ *
18+ * A valid hexadecimal string:
19+ * - Has at least two characters.
20+ * - Starts with "0x".
21+ * - Has an even length.
22+ * - Contains only characters representing digits (0-9) or lowercase letters (a-f) after the "0x" prefix.
23+ *
24+ * @param s - The string to validate as a hexadecimal (ccc.Hex) string.
25+ * @returns True if the string is a valid hex string, false otherwise.
26+ */
27+ export function isHex ( s : string ) : s is Hex {
28+ if (
29+ s . length < 2 ||
30+ s . charCodeAt ( 0 ) !== 48 || // ascii code for '0'
31+ s . charCodeAt ( 1 ) !== 120 || // ascii code for 'x'
32+ s . length % 2 !== 0
33+ ) {
34+ return false ;
35+ }
36+
37+ for ( let i = 2 ; i < s . length ; i ++ ) {
38+ const c = s . charCodeAt ( i ) ;
39+ // Allow characters '0'-'9' and 'a'-'f'
40+ if ( ! ( ( c >= 48 && c <= 57 ) || ( c >= 97 && c <= 102 ) ) ) {
41+ return false ;
42+ }
43+ }
44+ return true ;
45+ }
46+
47+ /**
48+ * Returns the hexadecimal representation of the given value.
1849 *
1950 * @param hex - The value to convert, which can be a string, Uint8Array, ArrayBuffer, or number array.
2051 * @returns A Hex string representing the value.
@@ -26,5 +57,10 @@ export type HexLike = BytesLike;
2657 * ```
2758 */
2859export function hexFrom ( hex : HexLike ) : Hex {
60+ // Passthru an already normalized hex. V8 optimization: maintain existing hidden string fields.
61+ if ( typeof hex === "string" && isHex ( hex ) ) {
62+ return hex ;
63+ }
64+
2965 return `0x${ bytesTo ( bytesFrom ( hex ) , "hex" ) } ` ;
3066}
0 commit comments