@nomicfoundation/hardhat-utils 3.0.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +5 -0
  3. package/dist/src/bigint.d.ts +32 -0
  4. package/dist/src/bigint.d.ts.map +1 -0
  5. package/dist/src/bigint.js +54 -0
  6. package/dist/src/bigint.js.map +1 -0
  7. package/dist/src/bytecode.d.ts +27 -0
  8. package/dist/src/bytecode.d.ts.map +1 -0
  9. package/dist/src/bytecode.js +60 -0
  10. package/dist/src/bytecode.js.map +1 -0
  11. package/dist/src/bytes.d.ts +34 -0
  12. package/dist/src/bytes.d.ts.map +1 -0
  13. package/dist/src/bytes.js +47 -0
  14. package/dist/src/bytes.js.map +1 -0
  15. package/dist/src/ci.d.ts +7 -0
  16. package/dist/src/ci.d.ts.map +1 -0
  17. package/dist/src/ci.js +18 -0
  18. package/dist/src/ci.js.map +1 -0
  19. package/dist/src/common-errors.d.ts +5 -0
  20. package/dist/src/common-errors.d.ts.map +1 -0
  21. package/dist/src/common-errors.js +7 -0
  22. package/dist/src/common-errors.js.map +1 -0
  23. package/dist/src/crypto.d.ts +25 -0
  24. package/dist/src/crypto.d.ts.map +1 -0
  25. package/dist/src/crypto.js +32 -0
  26. package/dist/src/crypto.js.map +1 -0
  27. package/dist/src/date.d.ts +21 -0
  28. package/dist/src/date.d.ts.map +1 -0
  29. package/dist/src/date.js +27 -0
  30. package/dist/src/date.js.map +1 -0
  31. package/dist/src/debug.d.ts +16 -0
  32. package/dist/src/debug.d.ts.map +1 -0
  33. package/dist/src/debug.js +28 -0
  34. package/dist/src/debug.js.map +1 -0
  35. package/dist/src/error.d.ts +80 -0
  36. package/dist/src/error.d.ts.map +1 -0
  37. package/dist/src/error.js +97 -0
  38. package/dist/src/error.js.map +1 -0
  39. package/dist/src/errors/bytecode.d.ts +18 -0
  40. package/dist/src/errors/bytecode.d.ts.map +1 -0
  41. package/dist/src/errors/bytecode.js +59 -0
  42. package/dist/src/errors/bytecode.js.map +1 -0
  43. package/dist/src/errors/fs.d.ts +25 -0
  44. package/dist/src/errors/fs.d.ts.map +1 -0
  45. package/dist/src/errors/fs.js +41 -0
  46. package/dist/src/errors/fs.js.map +1 -0
  47. package/dist/src/errors/package.d.ts +8 -0
  48. package/dist/src/errors/package.d.ts.map +1 -0
  49. package/dist/src/errors/package.js +12 -0
  50. package/dist/src/errors/package.js.map +1 -0
  51. package/dist/src/errors/request.d.ts +25 -0
  52. package/dist/src/errors/request.d.ts.map +1 -0
  53. package/dist/src/errors/request.js +64 -0
  54. package/dist/src/errors/request.js.map +1 -0
  55. package/dist/src/errors/subprocess.d.ts +8 -0
  56. package/dist/src/errors/subprocess.d.ts.map +1 -0
  57. package/dist/src/errors/subprocess.js +12 -0
  58. package/dist/src/errors/subprocess.js.map +1 -0
  59. package/dist/src/eth.d.ts +56 -0
  60. package/dist/src/eth.d.ts.map +1 -0
  61. package/dist/src/eth.js +78 -0
  62. package/dist/src/eth.js.map +1 -0
  63. package/dist/src/fs.d.ts +241 -0
  64. package/dist/src/fs.d.ts.map +1 -0
  65. package/dist/src/fs.js +581 -0
  66. package/dist/src/fs.js.map +1 -0
  67. package/dist/src/global-dir.d.ts +28 -0
  68. package/dist/src/global-dir.d.ts.map +1 -0
  69. package/dist/src/global-dir.js +42 -0
  70. package/dist/src/global-dir.js.map +1 -0
  71. package/dist/src/hex.d.ts +117 -0
  72. package/dist/src/hex.d.ts.map +1 -0
  73. package/dist/src/hex.js +187 -0
  74. package/dist/src/hex.js.map +1 -0
  75. package/dist/src/internal/bytecode.d.ts +45 -0
  76. package/dist/src/internal/bytecode.d.ts.map +1 -0
  77. package/dist/src/internal/bytecode.js +73 -0
  78. package/dist/src/internal/bytecode.js.map +1 -0
  79. package/dist/src/internal/eth.d.ts +21 -0
  80. package/dist/src/internal/eth.d.ts.map +1 -0
  81. package/dist/src/internal/eth.js +58 -0
  82. package/dist/src/internal/eth.js.map +1 -0
  83. package/dist/src/internal/global-dir.d.ts +4 -0
  84. package/dist/src/internal/global-dir.d.ts.map +1 -0
  85. package/dist/src/internal/global-dir.js +6 -0
  86. package/dist/src/internal/global-dir.js.map +1 -0
  87. package/dist/src/internal/hex.d.ts +2 -0
  88. package/dist/src/internal/hex.d.ts.map +1 -0
  89. package/dist/src/internal/hex.js +16 -0
  90. package/dist/src/internal/hex.js.map +1 -0
  91. package/dist/src/internal/lang.d.ts +2 -0
  92. package/dist/src/internal/lang.d.ts.map +1 -0
  93. package/dist/src/internal/lang.js +9 -0
  94. package/dist/src/internal/lang.js.map +1 -0
  95. package/dist/src/internal/package.d.ts +2 -0
  96. package/dist/src/internal/package.d.ts.map +1 -0
  97. package/dist/src/internal/package.js +15 -0
  98. package/dist/src/internal/package.js.map +1 -0
  99. package/dist/src/internal/request.d.ts +20 -0
  100. package/dist/src/internal/request.d.ts.map +1 -0
  101. package/dist/src/internal/request.js +101 -0
  102. package/dist/src/internal/request.js.map +1 -0
  103. package/dist/src/lang.d.ts +30 -0
  104. package/dist/src/lang.d.ts.map +1 -0
  105. package/dist/src/lang.js +41 -0
  106. package/dist/src/lang.js.map +1 -0
  107. package/dist/src/number.d.ts +23 -0
  108. package/dist/src/number.d.ts.map +1 -0
  109. package/dist/src/number.js +30 -0
  110. package/dist/src/number.js.map +1 -0
  111. package/dist/src/package.d.ts +75 -0
  112. package/dist/src/package.d.ts.map +1 -0
  113. package/dist/src/package.js +97 -0
  114. package/dist/src/package.js.map +1 -0
  115. package/dist/src/path.d.ts +26 -0
  116. package/dist/src/path.d.ts.map +1 -0
  117. package/dist/src/path.js +38 -0
  118. package/dist/src/path.js.map +1 -0
  119. package/dist/src/request.d.ts +118 -0
  120. package/dist/src/request.d.ts.map +1 -0
  121. package/dist/src/request.js +208 -0
  122. package/dist/src/request.js.map +1 -0
  123. package/dist/src/stream.d.ts +10 -0
  124. package/dist/src/stream.d.ts.map +1 -0
  125. package/dist/src/stream.js +16 -0
  126. package/dist/src/stream.js.map +1 -0
  127. package/dist/src/string.d.ts +45 -0
  128. package/dist/src/string.d.ts.map +1 -0
  129. package/dist/src/string.js +60 -0
  130. package/dist/src/string.js.map +1 -0
  131. package/dist/src/subprocess.d.ts +13 -0
  132. package/dist/src/subprocess.d.ts.map +1 -0
  133. package/dist/src/subprocess.js +33 -0
  134. package/dist/src/subprocess.js.map +1 -0
  135. package/dist/src/synchronization.d.ts +6 -0
  136. package/dist/src/synchronization.d.ts.map +1 -0
  137. package/dist/src/synchronization.js +107 -0
  138. package/dist/src/synchronization.js.map +1 -0
  139. package/package.json +90 -0
  140. package/src/bigint.ts +61 -0
  141. package/src/bytecode.ts +90 -0
  142. package/src/bytes.ts +51 -0
  143. package/src/ci.ts +19 -0
  144. package/src/common-errors.ts +7 -0
  145. package/src/crypto.ts +35 -0
  146. package/src/date.ts +28 -0
  147. package/src/debug.ts +38 -0
  148. package/src/error.ts +105 -0
  149. package/src/errors/bytecode.ts +75 -0
  150. package/src/errors/fs.ts +47 -0
  151. package/src/errors/package.ts +13 -0
  152. package/src/errors/request.ts +84 -0
  153. package/src/errors/subprocess.ts +17 -0
  154. package/src/eth.ts +91 -0
  155. package/src/fs.ts +678 -0
  156. package/src/global-dir.ts +51 -0
  157. package/src/hex.ts +232 -0
  158. package/src/internal/bytecode.ts +129 -0
  159. package/src/internal/eth.ts +71 -0
  160. package/src/internal/global-dir.ts +10 -0
  161. package/src/internal/hex.ts +21 -0
  162. package/src/internal/lang.ts +12 -0
  163. package/src/internal/package.ts +15 -0
  164. package/src/internal/request.ts +165 -0
  165. package/src/lang.ts +48 -0
  166. package/src/number.ts +38 -0
  167. package/src/package.ts +143 -0
  168. package/src/path.ts +45 -0
  169. package/src/request.ts +341 -0
  170. package/src/stream.ts +16 -0
  171. package/src/string.ts +69 -0
  172. package/src/subprocess.ts +46 -0
  173. package/src/synchronization.ts +126 -0
@@ -0,0 +1,75 @@
1
+ import type { LibraryAddresses, LibraryLink } from "../internal/bytecode.js";
2
+
3
+ import { CustomError } from "../error.js";
4
+
5
+ export class InvalidLibraryAddressError extends CustomError {
6
+ constructor(libraries: LibraryAddresses) {
7
+ const formattedLibraries = Object.entries(libraries)
8
+ .map(([libraryName, address]) => `\t* "${libraryName}": "${address}"`)
9
+ .join("\n");
10
+
11
+ super(`The following libraries have invalid addresses:
12
+ ${formattedLibraries}
13
+
14
+ Please provide valid Ethereum addresses for these libraries.`);
15
+ }
16
+ }
17
+
18
+ export class AmbiguousLibraryNameError extends CustomError {
19
+ constructor(libraries: Record<string, LibraryLink[]>) {
20
+ const formattedLibraries = Object.entries(libraries)
21
+ .map(
22
+ ([providedLibraryName, matchingLibraries]) =>
23
+ `\t* "${providedLibraryName}":\n${matchingLibraries
24
+ .map(({ libraryFqn }) => `\t\t* "${libraryFqn}"`)
25
+ .join("\n")}`,
26
+ )
27
+ .join("\n");
28
+
29
+ super(`The following libraries may resolve to multiple libraries:
30
+ ${formattedLibraries}
31
+
32
+ Please provide the fully qualified name for these libraries.`);
33
+ }
34
+ }
35
+
36
+ export class UnnecessaryLibraryError extends CustomError {
37
+ constructor(libraries: string[]) {
38
+ const formattedLibraries = libraries
39
+ .map((libraryName) => `\t* "${libraryName}"`)
40
+ .join("\n");
41
+
42
+ super(`The following libraries are not referenced by the contract:
43
+ ${formattedLibraries}
44
+
45
+ Please provide only the libraries that are needed.`);
46
+ }
47
+ }
48
+
49
+ export class OverlappingLibrariesError extends CustomError {
50
+ constructor(libraries: string[]) {
51
+ const formattedLibraries = libraries
52
+ .map((libraryFqn) => `\t* "${libraryFqn}"`)
53
+ .join("\n");
54
+
55
+ super(`The following libraries are provided more than once:
56
+ ${formattedLibraries}
57
+
58
+ Please ensure that each library is provided only once, either by its name or its fully qualified name.`);
59
+ }
60
+ }
61
+
62
+ export class MissingLibrariesError extends CustomError {
63
+ constructor(libraries: string[]) {
64
+ const formattedLibraries = libraries
65
+ .map((libraryFqn) => `\t* "${libraryFqn}"`)
66
+ .join("\n");
67
+
68
+ super(
69
+ `The following libraries are missing:
70
+ ${formattedLibraries}
71
+
72
+ Please provide all the required libraries.`,
73
+ );
74
+ }
75
+ }
@@ -0,0 +1,47 @@
1
+ import { CustomError } from "../error.js";
2
+
3
+ // We use this error to encapsulate any other error possibly thrown by node's
4
+ // fs apis, as sometimes their errors don't have stack traces.
5
+ export class FileSystemAccessError extends CustomError {}
6
+
7
+ export class FileNotFoundError extends CustomError {
8
+ constructor(filePath: string, cause?: Error) {
9
+ super(`File ${filePath} not found`, cause);
10
+ }
11
+ }
12
+
13
+ export class FileAlreadyExistsError extends CustomError {
14
+ constructor(filePath: string, cause?: Error) {
15
+ super(`File ${filePath} already exists`, cause);
16
+ }
17
+ }
18
+
19
+ export class InvalidFileFormatError extends CustomError {
20
+ constructor(filePath: string, cause: Error) {
21
+ super(`Invalid file format: ${filePath}`, cause);
22
+ }
23
+ }
24
+
25
+ export class JsonSerializationError extends CustomError {
26
+ constructor(filePath: string, cause: Error) {
27
+ super(`Error serializing JSON file ${filePath}`, cause);
28
+ }
29
+ }
30
+
31
+ export class NotADirectoryError extends CustomError {
32
+ constructor(filePath: string, cause: Error) {
33
+ super(`Path ${filePath} is not a directory`, cause);
34
+ }
35
+ }
36
+
37
+ export class IsDirectoryError extends CustomError {
38
+ constructor(filePath: string, cause: Error) {
39
+ super(`Path ${filePath} is a directory`, cause);
40
+ }
41
+ }
42
+
43
+ export class DirectoryNotEmptyError extends CustomError {
44
+ constructor(filePath: string, cause: Error) {
45
+ super(`Directory ${filePath} is not empty`, cause);
46
+ }
47
+ }
@@ -0,0 +1,13 @@
1
+ import { CustomError } from "../error.js";
2
+
3
+ export class PackageJsonNotFoundError extends CustomError {
4
+ constructor(filePathOrUrl: string, cause?: Error) {
5
+ super(`No package.json found for ${filePathOrUrl}`, cause);
6
+ }
7
+ }
8
+
9
+ export class PackageJsonReadError extends CustomError {
10
+ constructor(packageJsonPath: string, cause?: Error) {
11
+ super(`Failed to read package.json at ${packageJsonPath}`, cause);
12
+ }
13
+ }
@@ -0,0 +1,84 @@
1
+ import type UndiciT from "undici";
2
+
3
+ import { CustomError } from "../error.js";
4
+ import { sanitizeUrl } from "../internal/request.js";
5
+ import { isObject } from "../lang.js";
6
+
7
+ export class RequestError extends CustomError {
8
+ constructor(url: string, type: UndiciT.Dispatcher.HttpMethod, cause?: Error) {
9
+ super(`Failed to make ${type} request to ${sanitizeUrl(url)}`, cause);
10
+ }
11
+ }
12
+
13
+ export class DownloadError extends CustomError {
14
+ constructor(url: string, cause?: Error) {
15
+ super(`Failed to download file from ${sanitizeUrl(url)}`, cause);
16
+ }
17
+ }
18
+
19
+ export class DispatcherError extends CustomError {
20
+ constructor(message: string, cause?: Error) {
21
+ super(`Failed to create dispatcher: ${message}`, cause);
22
+ }
23
+ }
24
+
25
+ export class RequestTimeoutError extends CustomError {
26
+ constructor(url: string, cause?: Error) {
27
+ super(`Request to ${sanitizeUrl(url)} timed out`, cause);
28
+ }
29
+ }
30
+
31
+ export class ConnectionRefusedError extends CustomError {
32
+ constructor(url: string, cause?: Error) {
33
+ super(`Connection to ${sanitizeUrl(url)} was refused`, cause);
34
+ }
35
+ }
36
+
37
+ export class ResponseStatusCodeError extends CustomError {
38
+ public readonly statusCode: number;
39
+ public readonly headers:
40
+ | string[]
41
+ | Record<string, string | string[] | undefined>
42
+ | null;
43
+ public readonly body: null | Record<string, any> | string;
44
+
45
+ constructor(url: string, cause: Error) {
46
+ super(`Received an unexpected status code from ${sanitizeUrl(url)}`, cause);
47
+ this.statusCode =
48
+ "statusCode" in cause && typeof cause.statusCode === "number"
49
+ ? cause.statusCode
50
+ : -1;
51
+ this.headers = this.#extractHeaders(cause);
52
+ this.body = "body" in cause && isObject(cause.body) ? cause.body : null;
53
+ }
54
+
55
+ #extractHeaders(
56
+ cause: Error,
57
+ ): string[] | Record<string, string | string[] | undefined> | null {
58
+ if ("headers" in cause) {
59
+ const headers = cause.headers;
60
+ if (Array.isArray(headers)) {
61
+ return headers;
62
+ } else if (this.#isValidHeaders(headers)) {
63
+ return headers;
64
+ }
65
+ }
66
+ return null;
67
+ }
68
+
69
+ #isValidHeaders(
70
+ headers: unknown,
71
+ ): headers is Record<string, string | string[] | undefined> {
72
+ if (!isObject(headers)) {
73
+ return false;
74
+ }
75
+
76
+ return Object.values(headers).every(
77
+ (header) =>
78
+ typeof header === "string" ||
79
+ (Array.isArray(header) &&
80
+ header.every((item: unknown) => typeof item === "string")) ||
81
+ header === undefined,
82
+ );
83
+ }
84
+ }
@@ -0,0 +1,17 @@
1
+ import { CustomError } from "../error.js";
2
+
3
+ export class SubprocessFileNotFoundError extends CustomError {
4
+ constructor(filePath: string) {
5
+ super(
6
+ `Cannot find the subprocess file to execute, invalid file path: ${filePath}`,
7
+ );
8
+ }
9
+ }
10
+
11
+ export class SubprocessPathIsDirectoryError extends CustomError {
12
+ constructor(path: string) {
13
+ super(
14
+ `The provided path is a directory, only files are accepted. Path: ${path}`,
15
+ );
16
+ }
17
+ }
package/src/eth.ts ADDED
@@ -0,0 +1,91 @@
1
+ import type { PrefixedHexString } from "./hex.js";
2
+
3
+ import { bytesToHexString, numberToHexString, setLengthLeft } from "./hex.js";
4
+ import {
5
+ getAddressGenerator,
6
+ getHashGenerator,
7
+ isValidChecksum,
8
+ } from "./internal/eth.js";
9
+
10
+ /**
11
+ * Checks if a value is an Ethereum address.
12
+ *
13
+ * @param value The value to check.
14
+ * @returns True if the value is an Ethereum address, false otherwise.
15
+ */
16
+ export function isAddress(value: unknown): value is PrefixedHexString {
17
+ return typeof value === "string" && /^0x[0-9a-f]{40}$/i.test(value);
18
+ }
19
+
20
+ /**
21
+ * Checks if a value is an Ethereum address and if the checksum is valid.
22
+ *
23
+ * @param value The value to check.
24
+ * @returns True if the value is an Ethereum address with a valid checksum, false otherwise.
25
+ */
26
+ export async function isValidChecksumAddress(value: unknown): Promise<boolean> {
27
+ return isAddress(value) && isValidChecksum(value);
28
+ }
29
+
30
+ /**
31
+ * Checks if a value is an Ethereum hash.
32
+ *
33
+ * @param value The value to check.
34
+ * @returns True if the value is an Ethereum hash, false otherwise.
35
+ */
36
+ export function isHash(value: unknown): value is PrefixedHexString {
37
+ return typeof value === "string" && /^0x[0-9a-f]{64}$/i.test(value);
38
+ }
39
+
40
+ /**
41
+ * Converts a number to a hexadecimal string with a length of 32 bytes.
42
+ *
43
+ * @param value The number to convert.
44
+ * @returns The hexadecimal representation of the number padded to 32 bytes.
45
+ * @throws InvalidParameterError If the input is not a safe integer or is negative.
46
+ */
47
+ export function toEvmWord(value: bigint | number): PrefixedHexString {
48
+ return setLengthLeft(numberToHexString(value), 64);
49
+ }
50
+
51
+ /**
52
+ * Generates a pseudo-random sequence of hash bytes.
53
+ *
54
+ * @returns A pseudo-random sequence of hash bytes.
55
+ */
56
+ export async function generateHashBytes(): Promise<Uint8Array> {
57
+ const hashGenerator = await getHashGenerator();
58
+ return hashGenerator.next();
59
+ }
60
+
61
+ /**
62
+ * Generates a pseudo-random hash.
63
+ *
64
+ * @returns A pseudo-random hash.
65
+ */
66
+ export async function randomHash(): Promise<PrefixedHexString> {
67
+ const hashBytes = await generateHashBytes();
68
+ return bytesToHexString(hashBytes);
69
+ }
70
+
71
+ /**
72
+ * Generates a pseudo-random sequence of hash bytes that can be used as an
73
+ * address.
74
+ *
75
+ * @returns A pseudo-random sequence of hash bytes.
76
+ */
77
+ export async function generateAddressBytes(): Promise<Uint8Array> {
78
+ const addressGenerator = await getAddressGenerator();
79
+ const hashBytes = await addressGenerator.next();
80
+ return hashBytes.slice(0, 20);
81
+ }
82
+
83
+ /**
84
+ * Generates a pseudo-random address.
85
+ *
86
+ * @returns A pseudo-random address.
87
+ */
88
+ export async function randomAddress(): Promise<PrefixedHexString> {
89
+ const addressBytes = await generateAddressBytes();
90
+ return bytesToHexString(addressBytes);
91
+ }