refactor: move brother_node development artifact to dev/test-nodes subdirectory
Development Artifact Cleanup: ✅ BROTHER_NODE REORGANIZATION: Moved development test node to appropriate location - dev/test-nodes/brother_node/: Moved from root directory for better organization - Contains development configuration, test logs, and test chain data - No impact on production systems - purely development/testing artifact ✅ DEVELOPMENT ARTIFACTS IDENTIFIED: - Chain ID: aitbc-brother-chain (test/development chain) - Ports: 8010 (P2P) and 8011 (RPC) - different from production - Environment: .env file with test configuration - Logs: rpc.log and node.log from development testing session (March 15, 2026) ✅ ROOT DIRECTORY CLEANUP: Removed development clutter from production directory - brother_node/ moved to dev/test-nodes/brother_node/ - Root directory now contains only production-ready components - Development artifacts properly organized in dev/ subdirectory DIRECTORY STRUCTURE IMPROVEMENT: 📁 dev/test-nodes/: Development and testing node configurations 🏗️ Root Directory: Clean production structure with only essential components 🧪 Development Isolation: Test environments separated from production BENEFITS: ✅ Clean Production Directory: No development artifacts in root ✅ Better Organization: Development nodes grouped in dev/ subdirectory ✅ Clear Separation: Production vs development environments clearly distinguished ✅ Maintainability: Easier to identify and manage development components RESULT: Successfully moved brother_node development artifact to dev/test-nodes/ subdirectory, cleaning up the root directory while preserving development testing environment for future use.
This commit is contained in:
222
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/index.ts
generated
vendored
Executable file
222
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/index.ts
generated
vendored
Executable file
@@ -0,0 +1,222 @@
|
||||
import type { ZodTypeDef, ZodType } from "zod";
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
/**
|
||||
* We use `unknown` here to avoid a circular dependency between the Hardhat and
|
||||
* the Zod utils packages.
|
||||
*/
|
||||
export type HardhatUserConfigToValidate = unknown;
|
||||
|
||||
/**
|
||||
* For the same reason, we duplicate the type here.
|
||||
*/
|
||||
export interface HardhatUserConfigValidationError {
|
||||
path: Array<string | number>;
|
||||
message: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Zod untagged union type that returns a custom error message if the value
|
||||
* is missing or invalid.
|
||||
*
|
||||
* WARNING: In most cases you should use {@link conditionalUnionType} instead.
|
||||
*
|
||||
* This union type is valid for simple cases, where the union is made of
|
||||
* primitive or simple types.
|
||||
*
|
||||
* If you have a type that's complex, like an object or array, you must use
|
||||
* {@link conditionalUnionType}.
|
||||
*/
|
||||
// TODO: improve the return type of this function to be more specific
|
||||
export const unionType = (
|
||||
types: Parameters<typeof z.union>[0],
|
||||
errorMessage: string,
|
||||
) =>
|
||||
// NOTE: The reason we use `z.any().superRefine` instead of `z.union` is that
|
||||
// we found a bug with the `z.union` method that causes it to return a
|
||||
// "deeper" validation error, when we expected the `errorMessage`.
|
||||
// See: https://github.com/colinhacks/zod/issues/2940#issuecomment-2380836931
|
||||
z.any().superRefine((val, ctx) => {
|
||||
if (types.some((t) => t.safeParse(val).success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: errorMessage,
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* A Zod union type that allows you to provide hints to Zod about which of the
|
||||
* type variant it should use.
|
||||
*
|
||||
* It receives an array of tuples, where each tuple contains a predicate
|
||||
* function and a ZodType. The predicate function takes the data to be parsed
|
||||
* and returns a boolean. If the predicate function returns true, the ZodType
|
||||
* is used to parse the data.
|
||||
*
|
||||
* If none of the predicates returns true, an error is added to the context
|
||||
* with the noMatchMessage message.
|
||||
*
|
||||
* For example, you can use this to conditionally validate a union type based
|
||||
* on the values `typeof` and its fields:
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const fooType = conditionalUnionType(
|
||||
* [
|
||||
* [(data) => typeof data === "string", z.string()],
|
||||
* [(data) => Array.isArray(data), z.array(z.string()).nonempty()],
|
||||
* [(data) => isObject(data), z.object({foo: z.string().optional()})]
|
||||
* ],
|
||||
* "Expected a string, an array of strings, or an object with an optional 'foo' property",
|
||||
* );
|
||||
* ```
|
||||
*
|
||||
* @param cases An array of tuples of a predicate function and a ZodType.
|
||||
* @param noMatchMessage THe error message to return if none of the predicates
|
||||
* returns true.
|
||||
* @returns The conditional union ZodType.
|
||||
*/
|
||||
// TODO: improve the return type of this function to be more specific
|
||||
export const conditionalUnionType = (
|
||||
cases: Array<[predicate: (data: unknown) => boolean, zodType: ZodType<any>]>,
|
||||
noMatchMessage: string,
|
||||
) =>
|
||||
z.any().superRefine((data, ctx) => {
|
||||
const matchingCase = cases.find(([predicate]) => predicate(data));
|
||||
if (matchingCase === undefined) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: noMatchMessage,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const zodeType = matchingCase[1];
|
||||
|
||||
const parsedData = zodeType.safeParse(data);
|
||||
if (parsedData.error !== undefined) {
|
||||
for (const issue of parsedData.error.issues) {
|
||||
ctx.addIssue(issue);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates a Zod type to validate that a field of an object doesn't exist.
|
||||
*
|
||||
* This is useful when you have a {@link conditionalUnionType} that represents
|
||||
* a union of object types with incompatible fields between each other.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const typeWithFoo = z.object({
|
||||
* foo: z.string(),
|
||||
* bar: unexpecteddFieldType("This field is incompatible with `foo`"),
|
||||
* });
|
||||
*
|
||||
* const typeWithBar = z.object({
|
||||
* bar: z.string(),
|
||||
* foo: unexpecteddFieldType("This field is incompatible with `bar`"),
|
||||
* });
|
||||
*
|
||||
* const union = conditionalUnionType(
|
||||
* [
|
||||
* [(data) => isObject(data) && "foo" in data, typeWithFoo],
|
||||
* [(data) => isObject(data) && "bar" in data, typeWithBar],
|
||||
* ],
|
||||
* "Expected an object with either a `foo` or a `bar` field",
|
||||
* );
|
||||
* ```
|
||||
*
|
||||
* @param errorMessage The error message to display if the field is present.
|
||||
* @returns A Zod type that validates that a field of an object doesn't exist.
|
||||
*/
|
||||
export const incompatibleFieldType = (errorMessage = "Unexpectedd field") =>
|
||||
z
|
||||
.never({
|
||||
errorMap: () => ({
|
||||
message: errorMessage,
|
||||
}),
|
||||
})
|
||||
.optional();
|
||||
|
||||
/**
|
||||
* A Zod type to validate Hardhat's ConfigurationVariable objects.
|
||||
*/
|
||||
export const configurationVariableSchema = z.object({
|
||||
_type: z.literal("ConfigurationVariable"),
|
||||
name: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* A Zod type to validate Hardhat's ResolvedConfigurationVariable objects.
|
||||
*/
|
||||
export const resolvedConfigurationVariableSchema = z.object({
|
||||
_type: z.literal("ResolvedConfigurationVariable"),
|
||||
get: z.function(),
|
||||
getUrl: z.function(),
|
||||
getBigInt: z.function(),
|
||||
getHexString: z.function(),
|
||||
});
|
||||
|
||||
/**
|
||||
* A Zod type to validate Hardhat's SensitiveString values.
|
||||
*/
|
||||
export const sensitiveStringSchema: z.ZodType<
|
||||
string | z.infer<typeof configurationVariableSchema>
|
||||
> = unionType(
|
||||
[z.string(), configurationVariableSchema],
|
||||
"Expected a string or a Configuration Variable",
|
||||
);
|
||||
|
||||
/**
|
||||
* A Zod type to validate Hardhat's SensitiveString values that expect a URL.
|
||||
*
|
||||
* TODO: The custom error message in the unionType function doesn't work
|
||||
* correctly when using string().url() for validation, see:
|
||||
* https://github.com/colinhacks/zod/issues/2940
|
||||
* As a workaround, we provide the error message directly in the url() call.
|
||||
* We should remove this when the issue is fixed.
|
||||
*/
|
||||
export const sensitiveUrlSchema: z.ZodType<
|
||||
string | z.infer<typeof configurationVariableSchema>
|
||||
> = unionType(
|
||||
[
|
||||
z.string().url("Expected a URL or a Configuration Variable"),
|
||||
configurationVariableSchema,
|
||||
],
|
||||
"Expected a URL or a Configuration Variable",
|
||||
);
|
||||
|
||||
/**
|
||||
* A function to validate the user's configuration object against a Zod type.
|
||||
*
|
||||
* Note: The zod type MUST represent the HardhatUserConfig type, or a subset of
|
||||
* it. You shouldn't use this function to validate their fields individually.
|
||||
* The reason for this is that the paths of the validation errors must start
|
||||
* from the root of the config object, so that they are correctly reported to
|
||||
* the user.
|
||||
*/
|
||||
export function validateUserConfigZodType<
|
||||
Output,
|
||||
Def extends ZodTypeDef = ZodTypeDef,
|
||||
Input = Output,
|
||||
>(
|
||||
hardhatUserConfig: HardhatUserConfigToValidate,
|
||||
configType: ZodType<Output, Def, Input>,
|
||||
): HardhatUserConfigValidationError[] {
|
||||
const result = configType.safeParse(hardhatUserConfig);
|
||||
|
||||
if (result.success) {
|
||||
return [];
|
||||
} else {
|
||||
return result.error.errors.map((issue) => ({
|
||||
path: issue.path,
|
||||
message: issue.message,
|
||||
}));
|
||||
}
|
||||
}
|
||||
11
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/index.ts
generated
vendored
Executable file
11
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/index.ts
generated
vendored
Executable file
@@ -0,0 +1,11 @@
|
||||
export * from "./utils.js";
|
||||
export * from "./validate-params.js";
|
||||
export * from "./types/access-list.js";
|
||||
export * from "./types/address.js";
|
||||
export * from "./types/any.js";
|
||||
export * from "./types/authorization-list.js";
|
||||
export * from "./types/data.js";
|
||||
export * from "./types/hash.js";
|
||||
export * from "./types/quantity.js";
|
||||
export * from "./types/rpc-parity.js";
|
||||
export * from "./types/tx-request.js";
|
||||
20
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/access-list.ts
generated
vendored
Executable file
20
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/access-list.ts
generated
vendored
Executable file
@@ -0,0 +1,20 @@
|
||||
import type { ZodType } from "zod";
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
import { rpcData } from "./data.js";
|
||||
|
||||
const nullable = <T extends ZodType<any>>(schema: T) => schema.nullable();
|
||||
|
||||
const rpcAccessListTuple: ZodType<{
|
||||
address: Uint8Array;
|
||||
storageKeys: Uint8Array[] | null;
|
||||
}> = z.object({
|
||||
address: rpcData,
|
||||
storageKeys: nullable(z.array(rpcData)),
|
||||
});
|
||||
|
||||
export type RpcAccessListTuple = z.infer<typeof rpcAccessListTuple>;
|
||||
|
||||
export const rpcAccessList: ZodType<RpcAccessListTuple[]> =
|
||||
z.array(rpcAccessListTuple);
|
||||
26
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/address.ts
generated
vendored
Executable file
26
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/address.ts
generated
vendored
Executable file
@@ -0,0 +1,26 @@
|
||||
import type { ZodType } from "zod";
|
||||
|
||||
import { isAddress } from "@nomicfoundation/hardhat-utils/eth";
|
||||
import { hexStringToBytes } from "@nomicfoundation/hardhat-utils/hex";
|
||||
import { z } from "zod";
|
||||
|
||||
import { conditionalUnionType } from "@nomicfoundation/hardhat-zod-utils";
|
||||
|
||||
const ADDRESS_LENGTH_BYTES = 20;
|
||||
|
||||
export const rpcAddress: ZodType<Uint8Array> = conditionalUnionType(
|
||||
[
|
||||
[
|
||||
(data) => Buffer.isBuffer(data) && data.length === ADDRESS_LENGTH_BYTES,
|
||||
z.instanceof(Uint8Array),
|
||||
],
|
||||
[isAddress, z.string()],
|
||||
],
|
||||
"Expected a Buffer with correct length or a valid RPC address string",
|
||||
).transform((v) => (typeof v === "string" ? hexStringToBytes(v) : v));
|
||||
|
||||
export const nullableRpcAddress: ZodType<Uint8Array | null> = rpcAddress
|
||||
.or(z.null())
|
||||
.describe(
|
||||
"Expected a Buffer with correct length, a valid RPC address string, or the null value",
|
||||
);
|
||||
5
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/any.ts
generated
vendored
Executable file
5
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/any.ts
generated
vendored
Executable file
@@ -0,0 +1,5 @@
|
||||
import type { ZodType } from "zod";
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
export const rpcAny: ZodType<any> = z.any();
|
||||
31
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/authorization-list.ts
generated
vendored
Executable file
31
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/authorization-list.ts
generated
vendored
Executable file
@@ -0,0 +1,31 @@
|
||||
import type { ZodType } from "zod";
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
import { rpcAddress } from "./address.js";
|
||||
import { rpcHash } from "./hash.js";
|
||||
import { rpcQuantity } from "./quantity.js";
|
||||
import { rpcParity } from "./rpc-parity.js";
|
||||
|
||||
const rpcAuthorizationListTuple: ZodType<{
|
||||
chainId: bigint;
|
||||
address: Uint8Array;
|
||||
nonce: bigint;
|
||||
yParity: Uint8Array;
|
||||
r: Uint8Array;
|
||||
s: Uint8Array;
|
||||
}> = z.object({
|
||||
chainId: rpcQuantity,
|
||||
address: rpcAddress,
|
||||
nonce: rpcQuantity,
|
||||
yParity: rpcParity,
|
||||
r: rpcHash,
|
||||
s: rpcHash,
|
||||
});
|
||||
|
||||
export type RpcAuthorizationListTuple = z.infer<
|
||||
typeof rpcAuthorizationListTuple
|
||||
>;
|
||||
|
||||
export const rpcAuthorizationList: ZodType<RpcAuthorizationListTuple[]> =
|
||||
z.array(rpcAuthorizationListTuple);
|
||||
16
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/data.ts
generated
vendored
Executable file
16
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/data.ts
generated
vendored
Executable file
@@ -0,0 +1,16 @@
|
||||
import type { ZodType } from "zod";
|
||||
|
||||
import { hexStringToBytes } from "@nomicfoundation/hardhat-utils/hex";
|
||||
import { z } from "zod";
|
||||
|
||||
import { conditionalUnionType } from "@nomicfoundation/hardhat-zod-utils";
|
||||
|
||||
import { isRpcDataString } from "../utils.js";
|
||||
|
||||
export const rpcData: ZodType<Uint8Array> = conditionalUnionType(
|
||||
[
|
||||
[Buffer.isBuffer, z.instanceof(Uint8Array)],
|
||||
[isRpcDataString, z.string()],
|
||||
],
|
||||
"Expected a Buffer or a valid RPC data string",
|
||||
).transform((v) => (typeof v === "string" ? hexStringToBytes(v) : v));
|
||||
22
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/hash.ts
generated
vendored
Executable file
22
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/hash.ts
generated
vendored
Executable file
@@ -0,0 +1,22 @@
|
||||
import type { ZodType } from "zod";
|
||||
|
||||
import { isHash } from "@nomicfoundation/hardhat-utils/eth";
|
||||
import { hexStringToBytes } from "@nomicfoundation/hardhat-utils/hex";
|
||||
import { z } from "zod";
|
||||
|
||||
import { conditionalUnionType } from "@nomicfoundation/hardhat-zod-utils";
|
||||
|
||||
const HASH_LENGTH_BYTES = 32;
|
||||
|
||||
export const rpcHash: ZodType<Uint8Array> = conditionalUnionType(
|
||||
[
|
||||
[
|
||||
(data) => Buffer.isBuffer(data) && data.length === HASH_LENGTH_BYTES,
|
||||
z.instanceof(Uint8Array),
|
||||
],
|
||||
[isHash, z.string()],
|
||||
],
|
||||
"Expected a Buffer with the correct length or a valid RPC hash string",
|
||||
).transform((v) =>
|
||||
typeof v === "string" ? Buffer.from(hexStringToBytes(v)) : v,
|
||||
);
|
||||
15
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/quantity.ts
generated
vendored
Executable file
15
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/quantity.ts
generated
vendored
Executable file
@@ -0,0 +1,15 @@
|
||||
import type { ZodType } from "zod";
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
import { conditionalUnionType } from "@nomicfoundation/hardhat-zod-utils";
|
||||
|
||||
import { isRpcQuantityString } from "../utils.js";
|
||||
|
||||
export const rpcQuantity: ZodType<bigint> = conditionalUnionType(
|
||||
[
|
||||
[(data) => typeof data === "bigint", z.bigint()],
|
||||
[isRpcQuantityString, z.string()],
|
||||
],
|
||||
"Expected a bigint or a valid RPC quantity string",
|
||||
).transform((v) => (typeof v === "string" ? BigInt(v) : v));
|
||||
25
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/rpc-parity.ts
generated
vendored
Executable file
25
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/rpc-parity.ts
generated
vendored
Executable file
@@ -0,0 +1,25 @@
|
||||
import type { ZodType } from "zod";
|
||||
|
||||
import { hexStringToBytes } from "@nomicfoundation/hardhat-utils/hex";
|
||||
import { z } from "zod";
|
||||
|
||||
import { conditionalUnionType } from "@nomicfoundation/hardhat-zod-utils";
|
||||
|
||||
const PARITY_LENGTH_BYTES = 1;
|
||||
|
||||
export const rpcParity: ZodType<Buffer> = conditionalUnionType(
|
||||
[
|
||||
[
|
||||
(data) => Buffer.isBuffer(data) && data.length === PARITY_LENGTH_BYTES,
|
||||
z.instanceof(Uint8Array),
|
||||
],
|
||||
[isRpcParityString, z.string()],
|
||||
],
|
||||
"Expected a Buffer or valid parity string",
|
||||
).transform((v) =>
|
||||
typeof v === "string" ? Buffer.from(hexStringToBytes(v)) : v,
|
||||
);
|
||||
|
||||
function isRpcParityString(u: unknown): u is string {
|
||||
return typeof u === "string" && u.match(/^0x[0-9a-fA-F]{1,2}$/) !== null;
|
||||
}
|
||||
53
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/tx-request.ts
generated
vendored
Executable file
53
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/types/tx-request.ts
generated
vendored
Executable file
@@ -0,0 +1,53 @@
|
||||
import type { ZodType } from "zod";
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
import { rpcAccessList } from "./access-list.js";
|
||||
import { nullableRpcAddress, rpcAddress } from "./address.js";
|
||||
import { rpcAuthorizationList } from "./authorization-list.js";
|
||||
import { rpcData } from "./data.js";
|
||||
import { rpcHash } from "./hash.js";
|
||||
import { rpcQuantity } from "./quantity.js";
|
||||
|
||||
const optional = <T extends ZodType<any>>(schema: T) => schema.optional();
|
||||
|
||||
export interface RpcTransactionRequest {
|
||||
from: Uint8Array;
|
||||
to?: Uint8Array | null;
|
||||
gas?: bigint;
|
||||
gasPrice?: bigint;
|
||||
value?: bigint;
|
||||
nonce?: bigint;
|
||||
data?: Uint8Array;
|
||||
accessList?: Array<{ address: Uint8Array; storageKeys: Uint8Array[] | null }>;
|
||||
chainId?: bigint;
|
||||
maxFeePerGas?: bigint;
|
||||
maxPriorityFeePerGas?: bigint;
|
||||
blobs?: Uint8Array[];
|
||||
blobVersionedHashes?: Uint8Array[];
|
||||
authorizationList?: Array<{
|
||||
chainId: bigint;
|
||||
address: Uint8Array;
|
||||
nonce: bigint;
|
||||
yParity: Uint8Array;
|
||||
r: Uint8Array;
|
||||
s: Uint8Array;
|
||||
}>;
|
||||
}
|
||||
|
||||
export const rpcTransactionRequest: ZodType<RpcTransactionRequest> = z.object({
|
||||
from: rpcAddress,
|
||||
to: optional(nullableRpcAddress),
|
||||
gas: optional(rpcQuantity),
|
||||
gasPrice: optional(rpcQuantity),
|
||||
value: optional(rpcQuantity),
|
||||
nonce: optional(rpcQuantity),
|
||||
data: optional(rpcData),
|
||||
accessList: optional(rpcAccessList),
|
||||
chainId: optional(rpcQuantity),
|
||||
maxFeePerGas: optional(rpcQuantity),
|
||||
maxPriorityFeePerGas: optional(rpcQuantity),
|
||||
blobs: optional(z.array(rpcData)),
|
||||
blobVersionedHashes: optional(z.array(rpcHash)),
|
||||
authorizationList: optional(rpcAuthorizationList),
|
||||
});
|
||||
9
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/utils.ts
generated
vendored
Executable file
9
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/utils.ts
generated
vendored
Executable file
@@ -0,0 +1,9 @@
|
||||
export function isRpcQuantityString(u: unknown): u is string {
|
||||
return (
|
||||
typeof u === "string" && /^0x(?:0|(?:[1-9a-fA-F][0-9a-fA-F]*))$/.test(u)
|
||||
);
|
||||
}
|
||||
|
||||
export function isRpcDataString(u: unknown): u is string {
|
||||
return typeof u === "string" && /^0x(?:[0-9a-fA-F]{2})*$/.test(u);
|
||||
}
|
||||
62
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/validate-params.ts
generated
vendored
Executable file
62
dev/env/node_modules/@nomicfoundation/hardhat-zod-utils/src/rpc/validate-params.ts
generated
vendored
Executable file
@@ -0,0 +1,62 @@
|
||||
import type { ZodType } from "zod";
|
||||
|
||||
import { HardhatError } from "@nomicfoundation/hardhat-errors";
|
||||
|
||||
export function validateParams<TypesT extends ReadonlyArray<ZodType<any>>>(
|
||||
params: any[],
|
||||
...types: TypesT
|
||||
): {
|
||||
[i in keyof TypesT]: TypesT[i] extends ZodType<infer TypeT> ? TypeT : never;
|
||||
} {
|
||||
if (types === undefined && params.length > 0) {
|
||||
throw new HardhatError(
|
||||
HardhatError.ERRORS.CORE.NETWORK.WRONG_VALIDATION_PARAMS,
|
||||
{
|
||||
reason: `No argument was expected and got ${params.length}`,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
let optionalParams = 0;
|
||||
for (let i = types.length - 1; i >= 0; i--) {
|
||||
if (types[i].isOptional() || types[i].isNullable()) {
|
||||
optionalParams += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optionalParams === 0) {
|
||||
if (params.length !== types.length) {
|
||||
throw new HardhatError(
|
||||
HardhatError.ERRORS.CORE.NETWORK.WRONG_VALIDATION_PARAMS,
|
||||
{
|
||||
reason: `Expected exactly ${types.length} arguments and got ${params.length}`,
|
||||
},
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
params.length > types.length ||
|
||||
params.length < types.length - optionalParams
|
||||
) {
|
||||
throw new HardhatError(
|
||||
HardhatError.ERRORS.CORE.NETWORK.WRONG_VALIDATION_PARAMS,
|
||||
{
|
||||
reason: `Expected between ${types.length - optionalParams} and ${
|
||||
types.length
|
||||
} arguments and got ${params.length}`,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const decoded: any[] = [];
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
const res = types[i].parse(params[i]);
|
||||
decoded.push(res);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- TypeScript can't infer the complex return type
|
||||
return decoded as any;
|
||||
}
|
||||
Reference in New Issue
Block a user