Skip to content

Commit

Permalink
Merge pull request #5812 from NomicFoundation/hh-utils-improvements
Browse files Browse the repository at this point in the history
hardhat-utils return type improvements
  • Loading branch information
kanej authored Oct 21, 2024
2 parents aa4d1b4 + d9a87ca commit 6f55402
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 44 deletions.
4 changes: 1 addition & 3 deletions v-next/hardhat-utils/src/bigint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ export function max(x: bigint, y: bigint): bigint {
* @returns The input value converted to a bigint.
* @throws InvalidParameterError If the input value cannot be converted to a bigint.
*/
export async function toBigInt(
value: number | string | bigint,
): Promise<bigint> {
export function toBigInt(value: number | string | bigint): bigint {
switch (typeof value) {
case "number":
if (!Number.isInteger(value)) {
Expand Down
10 changes: 4 additions & 6 deletions v-next/hardhat-utils/src/eth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
* @param value The value to check.
* @returns True if the value is an Ethereum address, false otherwise.
*/
export function isAddress(value: unknown): boolean {
export function isAddress(value: unknown): value is PrefixedHexString {
return typeof value === "string" && /^0x[0-9a-f]{40}$/i.test(value);
}

Expand All @@ -24,9 +24,7 @@ export function isAddress(value: unknown): boolean {
* @returns True if the value is an Ethereum address with a valid checksum, false otherwise.
*/
export async function isValidChecksumAddress(value: unknown): Promise<boolean> {
return (
typeof value === "string" && isAddress(value) && isValidChecksum(value)
);
return isAddress(value) && isValidChecksum(value);
}

/**
Expand All @@ -35,7 +33,7 @@ export async function isValidChecksumAddress(value: unknown): Promise<boolean> {
* @param value The value to check.
* @returns True if the value is an Ethereum hash, false otherwise.
*/
export function isHash(value: unknown): boolean {
export function isHash(value: unknown): value is PrefixedHexString {
return typeof value === "string" && /^0x[0-9a-f]{64}$/i.test(value);
}

Expand All @@ -46,7 +44,7 @@ export function isHash(value: unknown): boolean {
* @returns The hexadecimal representation of the number padded to 32 bytes.
* @throws InvalidParameterError If the input is not a safe integer or is negative.
*/
export function toEvmWord(value: bigint | number): string {
export function toEvmWord(value: bigint | number): PrefixedHexString {
return setLengthLeft(numberToHexString(value), 64);
}

Expand Down
15 changes: 9 additions & 6 deletions v-next/hardhat-utils/src/hex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export function normalizeHexString(hexString: string): PrefixedHexString {
);
}

return isHexStringPrefixed(normalizedHexString)
return isPrefixedHexString(normalizedHexString)
? normalizedHexString
: `0x${normalizedHexString}`;
}
Expand All @@ -153,7 +153,7 @@ export function normalizeHexString(hexString: string): PrefixedHexString {
* @param hexString The string to check.
* @returns True if the string starts with "0x", false otherwise.
*/
export function isHexStringPrefixed(
export function isPrefixedHexString(
hexString: string,
): hexString is PrefixedHexString {
return hexString.toLowerCase().startsWith("0x");
Expand All @@ -168,7 +168,7 @@ export function isHexStringPrefixed(
* @returns The hexadecimal string without the "0x" prefix.
*/
export function getUnprefixedHexString(hexString: string): string {
return isHexStringPrefixed(hexString) ? hexString.substring(2) : hexString;
return isPrefixedHexString(hexString) ? hexString.substring(2) : hexString;
}

/**
Expand All @@ -179,8 +179,8 @@ export function getUnprefixedHexString(hexString: string): string {
* @param hexString The hexadecimal string.
* @returns The hexadecimal string with the "0x" prefix.
*/
export function getPrefixedHexString(hexString: string): string {
return isHexStringPrefixed(hexString) ? hexString : `0x${hexString}`;
export function getPrefixedHexString(hexString: string): PrefixedHexString {
return isPrefixedHexString(hexString) ? hexString : `0x${hexString}`;
}

/**
Expand Down Expand Up @@ -218,7 +218,10 @@ export function unpadHexString(hexString: string): string {
* @param length The desired length of the hexadecimal string.
* @returns The padded hexadecimal string.
*/
export function setLengthLeft(hexString: string, length: number): string {
export function setLengthLeft(
hexString: string,
length: number,
): PrefixedHexString {
const unprefixedHexString = getUnprefixedHexString(hexString);

// if the string is longer than the desired length, truncate it
Expand Down
4 changes: 2 additions & 2 deletions v-next/hardhat-utils/src/internal/hex.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {
getPrefixedHexString,
getUnprefixedHexString,
isHexStringPrefixed,
isPrefixedHexString,
} from "../hex.js";

export function padToEven(value: string): string {
const isPrefixed = isHexStringPrefixed(value);
const isPrefixed = isPrefixedHexString(value);
const unprefixed = getUnprefixedHexString(value);

let padded;
Expand Down
2 changes: 1 addition & 1 deletion v-next/hardhat-utils/src/number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
* @param bytes The Uint8Array to convert.
* @returns The converted bigint.
*/
export function bytesToBigInt(bytes: Uint8Array): number | bigint {
export function bytesToBigInt(bytes: Uint8Array): bigint {
return hexStringToBigInt(bytesToHexString(bytes));
}

Expand Down
36 changes: 18 additions & 18 deletions v-next/hardhat-utils/test/bigint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,41 +39,41 @@ describe("bigint", () => {
});

describe("toBigInt", () => {
it("Should convert a number to a BigInt", async () => {
assert.equal(await toBigInt(0), 0n);
assert.equal(await toBigInt(1), 1n);
assert.equal(await toBigInt(-1), -1n);
it("Should convert a number to a BigInt", () => {
assert.equal(toBigInt(0), 0n);
assert.equal(toBigInt(1), 1n);
assert.equal(toBigInt(-1), -1n);
});

it("Should convert a BigInt to a BigInt", async () => {
assert.equal(await toBigInt(0n), 0n);
assert.equal(await toBigInt(1n), 1n);
assert.equal(await toBigInt(-1n), -1n);
it("Should convert a BigInt to a BigInt", () => {
assert.equal(toBigInt(0n), 0n);
assert.equal(toBigInt(1n), 1n);
assert.equal(toBigInt(-1n), -1n);
});

it("Should convert a string to a BigInt", async () => {
assert.equal(await toBigInt("0"), 0n);
assert.equal(await toBigInt("1"), 1n);
assert.equal(await toBigInt("-1"), -1n);
it("Should convert a string to a BigInt", () => {
assert.equal(toBigInt("0"), 0n);
assert.equal(toBigInt("1"), 1n);
assert.equal(toBigInt("-1"), -1n);
});

it("Should throw on non-integer numbers", async () => {
await assert.rejects(toBigInt(0.5), {
it("Should throw on non-integer numbers", () => {
assert.throws(() => toBigInt(0.5), {
name: "InvalidParameterError",
message: "0.5 is not an integer",
});
});

it("Should throw on unsafe integers", async () => {
await assert.rejects(toBigInt(Number.MAX_SAFE_INTEGER + 1), {
it("Should throw on unsafe integers", () => {
assert.throws(() => toBigInt(Number.MAX_SAFE_INTEGER + 1), {
name: "InvalidParameterError",
message: `Integer ${Number.MAX_SAFE_INTEGER + 1} is unsafe. Consider using ${Number.MAX_SAFE_INTEGER + 1}n instead. For more details, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger`,
});
});

it("Should throw on unsupported types", async () => {
it("Should throw on unsupported types", () => {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Intentionally testing an type mismatch
await assert.rejects(toBigInt(true as any), {
assert.throws(() => toBigInt(true as any), {
name: "InvalidParameterError",
message: "Unsupported type: boolean",
});
Expand Down
12 changes: 6 additions & 6 deletions v-next/hardhat-utils/test/hex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
bytesToHexString,
hexStringToBytes,
normalizeHexString,
isHexStringPrefixed,
isPrefixedHexString,
isHexString,
getUnprefixedHexString,
getPrefixedHexString,
Expand Down Expand Up @@ -255,12 +255,12 @@ describe("hex", () => {
});
});

describe("isHexStringPrefixed", () => {
describe("isPrefixedHexString", () => {
it("Should check if a string is prefixed with '0x'", () => {
assert.equal(isHexStringPrefixed("0x0"), true);
assert.equal(isHexStringPrefixed("ffff"), false);
assert.equal(isHexStringPrefixed("0X100000000"), true);
assert.equal(isHexStringPrefixed("20000000000000"), false);
assert.equal(isPrefixedHexString("0x0"), true);
assert.equal(isPrefixedHexString("ffff"), false);
assert.equal(isPrefixedHexString("0X100000000"), true);
assert.equal(isPrefixedHexString("20000000000000"), false);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { EthereumProvider } from "../../../../../types/providers.js";
import { assertHardhatInvariant } from "@ignored/hardhat-vnext-errors";
import {
hexStringToNumber,
isHexStringPrefixed,
isPrefixedHexString,
} from "@ignored/hardhat-vnext-utils/hex";

/**
Expand Down Expand Up @@ -53,6 +53,6 @@ export abstract class ChainId {

// There's a node returning this as decimal instead of QUANTITY.
// TODO: from V2 - Document here which node does that
return isHexStringPrefixed(id) ? hexStringToNumber(id) : parseInt(id, 10);
return isPrefixedHexString(id) ? hexStringToNumber(id) : parseInt(id, 10);
}
}

0 comments on commit 6f55402

Please sign in to comment.