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:
2026-03-30 17:09:06 +02:00
parent bf730dcb4a
commit 816e258d4c
11734 changed files with 2001707 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
# @nomicfoundation/hardhat-zod-utils
## 3.0.2
### Patch Changes
- 6674b00: Bump `hardhat-utils` major
## 3.0.1
### Patch Changes
- 8c1cb1e: Fixed dependencies for Hardhat so `rpc` utils can be loaded ([#7415](https://github.com/NomicFoundation/hardhat/issues/7415))
## 3.0.0
### Major Changes
- 29cc141: First release of Hardhat 3!

View File

@@ -0,0 +1,9 @@
MIT License
Copyright (c) 2024 Nomic Foundation
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,5 @@
# hardhat-zod-utils
> ⚠️ This package is an internal Hardhat component and it's not meant to be used directly.
This package contains zod utilities to validate Hardhat 3 configurations. It's used by Hardhat and its plugins.

View File

@@ -0,0 +1,151 @@
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}.
*/
export declare const unionType: (types: Parameters<typeof z.union>[0], errorMessage: string) => z.ZodEffects<z.ZodAny, any, any>;
/**
* 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.
*/
export declare const conditionalUnionType: (cases: Array<[predicate: (data: unknown) => boolean, zodType: ZodType<any>]>, noMatchMessage: string) => z.ZodEffects<z.ZodAny, any, any>;
/**
* 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 declare const incompatibleFieldType: (errorMessage?: string) => z.ZodOptional<z.ZodNever>;
/**
* A Zod type to validate Hardhat's ConfigurationVariable objects.
*/
export declare const configurationVariableSchema: z.ZodObject<{
_type: z.ZodLiteral<"ConfigurationVariable">;
name: z.ZodString;
}, "strip", z.ZodTypeAny, {
_type: "ConfigurationVariable";
name: string;
}, {
_type: "ConfigurationVariable";
name: string;
}>;
/**
* A Zod type to validate Hardhat's ResolvedConfigurationVariable objects.
*/
export declare const resolvedConfigurationVariableSchema: z.ZodObject<{
_type: z.ZodLiteral<"ResolvedConfigurationVariable">;
get: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
getUrl: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
getBigInt: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
getHexString: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodUnknown>;
}, "strip", z.ZodTypeAny, {
_type: "ResolvedConfigurationVariable";
get: (...args: unknown[]) => unknown;
getUrl: (...args: unknown[]) => unknown;
getBigInt: (...args: unknown[]) => unknown;
getHexString: (...args: unknown[]) => unknown;
}, {
_type: "ResolvedConfigurationVariable";
get: (...args: unknown[]) => unknown;
getUrl: (...args: unknown[]) => unknown;
getBigInt: (...args: unknown[]) => unknown;
getHexString: (...args: unknown[]) => unknown;
}>;
/**
* A Zod type to validate Hardhat's SensitiveString values.
*/
export declare const sensitiveStringSchema: z.ZodType<string | z.infer<typeof configurationVariableSchema>>;
/**
* 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 declare const sensitiveUrlSchema: z.ZodType<string | z.infer<typeof configurationVariableSchema>>;
/**
* 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 declare function validateUserConfigZodType<Output, Def extends ZodTypeDef = ZodTypeDef, Input = Output>(hardhatUserConfig: HardhatUserConfigToValidate, configType: ZodType<Output, Def, Input>): HardhatUserConfigValidationError[];
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAE/C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,MAAM,2BAA2B,GAAG,OAAO,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,SAAS,GACpB,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EACpC,cAAc,MAAM,qCAelB,CAAC;AAEL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,eAAO,MAAM,oBAAoB,GAC/B,OAAO,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAC5E,gBAAgB,MAAM,qCAoBpB,CAAC;AAEL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,qBAAqB,GAAI,qBAAkC,8BAOzD,CAAC;AAEhB;;GAEG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;EAGtC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;EAM9C,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,CAAC,CAAC,OAAO,CAC3C,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAIrD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,CAAC,CAAC,OAAO,CACxC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAOrD,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EACN,GAAG,SAAS,UAAU,GAAG,UAAU,EACnC,KAAK,GAAG,MAAM,EAEd,iBAAiB,EAAE,2BAA2B,EAC9C,UAAU,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,GACtC,gCAAgC,EAAE,CAWpC"}

View File

@@ -0,0 +1,171 @@
import { z } from "zod";
/**
* 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, errorMessage) =>
// 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, noMatchMessage) => 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 = 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 = 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(hardhatUserConfig, configType) {
const result = configType.safeParse(hardhatUserConfig);
if (result.success) {
return [];
}
else {
return result.error.errors.map((issue) => ({
path: issue.path,
message: issue.message,
}));
}
}
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,12 @@
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";
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/rpc/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC"}

View File

@@ -0,0 +1,12 @@
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";
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/rpc/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC"}

View File

@@ -0,0 +1,10 @@
import type { ZodType } from "zod";
import { z } from "zod";
declare const rpcAccessListTuple: ZodType<{
address: Uint8Array;
storageKeys: Uint8Array[] | null;
}>;
export type RpcAccessListTuple = z.infer<typeof rpcAccessListTuple>;
export declare const rpcAccessList: ZodType<RpcAccessListTuple[]>;
export {};
//# sourceMappingURL=access-list.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"access-list.d.ts","sourceRoot":"","sources":["../../../../src/rpc/types/access-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,QAAA,MAAM,kBAAkB,EAAE,OAAO,CAAC;IAChC,OAAO,EAAE,UAAU,CAAC;IACpB,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;CAClC,CAGC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,eAAO,MAAM,aAAa,EAAE,OAAO,CAAC,kBAAkB,EAAE,CAC3B,CAAC"}

View File

@@ -0,0 +1,9 @@
import { z } from "zod";
import { rpcData } from "./data.js";
const nullable = (schema) => schema.nullable();
const rpcAccessListTuple = z.object({
address: rpcData,
storageKeys: nullable(z.array(rpcData)),
});
export const rpcAccessList = z.array(rpcAccessListTuple);
//# sourceMappingURL=access-list.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"access-list.js","sourceRoot":"","sources":["../../../../src/rpc/types/access-list.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,QAAQ,GAAG,CAAyB,MAAS,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;AAE1E,MAAM,kBAAkB,GAGnB,CAAC,CAAC,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO;IAChB,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;CACxC,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,aAAa,GACxB,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC"}

View File

@@ -0,0 +1,4 @@
import type { ZodType } from "zod";
export declare const rpcAddress: ZodType<Uint8Array>;
export declare const nullableRpcAddress: ZodType<Uint8Array | null>;
//# sourceMappingURL=address.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../../../../src/rpc/types/address.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAUnC,eAAO,MAAM,UAAU,EAAE,OAAO,CAAC,UAAU,CAS0B,CAAC;AAEtE,eAAO,MAAM,kBAAkB,EAAE,OAAO,CAAC,UAAU,GAAG,IAAI,CAIvD,CAAC"}

View File

@@ -0,0 +1,16 @@
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 = 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 = rpcAddress
.or(z.null())
.describe("Expected a Buffer with correct length, a valid RPC address string, or the null value");
//# sourceMappingURL=address.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"address.js","sourceRoot":"","sources":["../../../../src/rpc/types/address.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEhC,MAAM,CAAC,MAAM,UAAU,GAAwB,oBAAoB,CACjE;IACE;QACE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,oBAAoB;QACvE,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;KACzB;IACD,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;CACxB,EACD,qEAAqE,CACtE,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtE,MAAM,CAAC,MAAM,kBAAkB,GAA+B,UAAU;KACrE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;KACZ,QAAQ,CACP,sFAAsF,CACvF,CAAC"}

View File

@@ -0,0 +1,3 @@
import type { ZodType } from "zod";
export declare const rpcAny: ZodType<any>;
//# sourceMappingURL=any.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"any.d.ts","sourceRoot":"","sources":["../../../../src/rpc/types/any.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAInC,eAAO,MAAM,MAAM,EAAE,OAAO,CAAC,GAAG,CAAW,CAAC"}

View File

@@ -0,0 +1,3 @@
import { z } from "zod";
export const rpcAny = z.any();
//# sourceMappingURL=any.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"any.js","sourceRoot":"","sources":["../../../../src/rpc/types/any.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,MAAM,GAAiB,CAAC,CAAC,GAAG,EAAE,CAAC"}

View File

@@ -0,0 +1,14 @@
import type { ZodType } from "zod";
import { z } from "zod";
declare const rpcAuthorizationListTuple: ZodType<{
chainId: bigint;
address: Uint8Array;
nonce: bigint;
yParity: Uint8Array;
r: Uint8Array;
s: Uint8Array;
}>;
export type RpcAuthorizationListTuple = z.infer<typeof rpcAuthorizationListTuple>;
export declare const rpcAuthorizationList: ZodType<RpcAuthorizationListTuple[]>;
export {};
//# sourceMappingURL=authorization-list.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"authorization-list.d.ts","sourceRoot":"","sources":["../../../../src/rpc/types/authorization-list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,QAAA,MAAM,yBAAyB,EAAE,OAAO,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,CAAC;IACpB,CAAC,EAAE,UAAU,CAAC;IACd,CAAC,EAAE,UAAU,CAAC;CACf,CAOC,CAAC;AAEH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAC7C,OAAO,yBAAyB,CACjC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,OAAO,CAAC,yBAAyB,EAAE,CAClC,CAAC"}

View File

@@ -0,0 +1,15 @@
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 = z.object({
chainId: rpcQuantity,
address: rpcAddress,
nonce: rpcQuantity,
yParity: rpcParity,
r: rpcHash,
s: rpcHash,
});
export const rpcAuthorizationList = z.array(rpcAuthorizationListTuple);
//# sourceMappingURL=authorization-list.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"authorization-list.js","sourceRoot":"","sources":["../../../../src/rpc/types/authorization-list.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,yBAAyB,GAO1B,CAAC,CAAC,MAAM,CAAC;IACZ,OAAO,EAAE,WAAW;IACpB,OAAO,EAAE,UAAU;IACnB,KAAK,EAAE,WAAW;IAClB,OAAO,EAAE,SAAS;IAClB,CAAC,EAAE,OAAO;IACV,CAAC,EAAE,OAAO;CACX,CAAC,CAAC;AAMH,MAAM,CAAC,MAAM,oBAAoB,GAC/B,CAAC,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC"}

View File

@@ -0,0 +1,3 @@
import type { ZodType } from "zod";
export declare const rpcData: ZodType<Uint8Array>;
//# sourceMappingURL=data.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../../src/rpc/types/data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AASnC,eAAO,MAAM,OAAO,EAAE,OAAO,CAAC,UAAU,CAM6B,CAAC"}

View File

@@ -0,0 +1,9 @@
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 = 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));
//# sourceMappingURL=data.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../../../src/rpc/types/data.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,CAAC,MAAM,OAAO,GAAwB,oBAAoB,CAC9D;IACE,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAC3C,CAAC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;CAC9B,EACD,8CAA8C,CAC/C,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC"}

View File

@@ -0,0 +1,3 @@
import type { ZodType } from "zod";
export declare const rpcHash: ZodType<Uint8Array>;
//# sourceMappingURL=hash.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../../../src/rpc/types/hash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAUnC,eAAO,MAAM,OAAO,EAAE,OAAO,CAAC,UAAU,CAWvC,CAAC"}

View File

@@ -0,0 +1,13 @@
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 = 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);
//# sourceMappingURL=hash.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../../../src/rpc/types/hash.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B,MAAM,CAAC,MAAM,OAAO,GAAwB,oBAAoB,CAC9D;IACE;QACE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,iBAAiB;QACpE,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;KACzB;IACD,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;CACrB,EACD,sEAAsE,CACvE,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAChB,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAC7D,CAAC"}

View File

@@ -0,0 +1,3 @@
import type { ZodType } from "zod";
export declare const rpcQuantity: ZodType<bigint>;
//# sourceMappingURL=quantity.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"quantity.d.ts","sourceRoot":"","sources":["../../../../src/rpc/types/quantity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAQnC,eAAO,MAAM,WAAW,EAAE,OAAO,CAAC,MAAM,CAMmB,CAAC"}

View File

@@ -0,0 +1,8 @@
import { z } from "zod";
import { conditionalUnionType } from "@nomicfoundation/hardhat-zod-utils";
import { isRpcQuantityString } from "../utils.js";
export const rpcQuantity = 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));
//# sourceMappingURL=quantity.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"quantity.js","sourceRoot":"","sources":["../../../../src/rpc/types/quantity.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,CAAC,MAAM,WAAW,GAAoB,oBAAoB,CAC9D;IACE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IAChD,CAAC,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;CAClC,EACD,kDAAkD,CACnD,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC"}

View File

@@ -0,0 +1,3 @@
import type { ZodType } from "zod";
export declare const rpcParity: ZodType<Buffer>;
//# sourceMappingURL=rpc-parity.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"rpc-parity.d.ts","sourceRoot":"","sources":["../../../../src/rpc/types/rpc-parity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AASnC,eAAO,MAAM,SAAS,EAAE,OAAO,CAAC,MAAM,CAWrC,CAAC"}

View File

@@ -0,0 +1,15 @@
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 = 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) {
return typeof u === "string" && u.match(/^0x[0-9a-fA-F]{1,2}$/) !== null;
}
//# sourceMappingURL=rpc-parity.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"rpc-parity.js","sourceRoot":"","sources":["../../../../src/rpc/types/rpc-parity.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B,MAAM,CAAC,MAAM,SAAS,GAAoB,oBAAoB,CAC5D;IACE;QACE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,mBAAmB;QACtE,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;KACzB;IACD,CAAC,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;CAChC,EACD,0CAA0C,CAC3C,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAChB,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAC7D,CAAC;AAEF,SAAS,iBAAiB,CAAC,CAAU;IACnC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,KAAK,IAAI,CAAC;AAC3E,CAAC"}

View File

@@ -0,0 +1,29 @@
import type { ZodType } from "zod";
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 declare const rpcTransactionRequest: ZodType<RpcTransactionRequest>;
//# sourceMappingURL=tx-request.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"tx-request.d.ts","sourceRoot":"","sources":["../../../../src/rpc/types/tx-request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAanC,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,UAAU,CAAC;QAAC,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,mBAAmB,CAAC,EAAE,UAAU,EAAE,CAAC;IACnC,iBAAiB,CAAC,EAAE,KAAK,CAAC;QACxB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,UAAU,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,UAAU,CAAC;QACpB,CAAC,EAAE,UAAU,CAAC;QACd,CAAC,EAAE,UAAU,CAAC;KACf,CAAC,CAAC;CACJ;AAED,eAAO,MAAM,qBAAqB,EAAE,OAAO,CAAC,qBAAqB,CAe/D,CAAC"}

View File

@@ -0,0 +1,25 @@
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 = (schema) => schema.optional();
export const 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),
});
//# sourceMappingURL=tx-request.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"tx-request.js","sourceRoot":"","sources":["../../../../src/rpc/types/tx-request.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,QAAQ,GAAG,CAAyB,MAAS,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;AA0B1E,MAAM,CAAC,MAAM,qBAAqB,GAAmC,CAAC,CAAC,MAAM,CAAC;IAC5E,IAAI,EAAE,UAAU;IAChB,EAAE,EAAE,QAAQ,CAAC,kBAAkB,CAAC;IAChC,GAAG,EAAE,QAAQ,CAAC,WAAW,CAAC;IAC1B,QAAQ,EAAE,QAAQ,CAAC,WAAW,CAAC;IAC/B,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC;IAC5B,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC;IAC5B,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC;IACvB,UAAU,EAAE,QAAQ,CAAC,aAAa,CAAC;IACnC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC;IAC9B,YAAY,EAAE,QAAQ,CAAC,WAAW,CAAC;IACnC,oBAAoB,EAAE,QAAQ,CAAC,WAAW,CAAC;IAC3C,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjC,mBAAmB,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/C,iBAAiB,EAAE,QAAQ,CAAC,oBAAoB,CAAC;CAClD,CAAC,CAAC"}

View File

@@ -0,0 +1,3 @@
export declare function isRpcQuantityString(u: unknown): u is string;
export declare function isRpcDataString(u: unknown): u is string;
//# sourceMappingURL=utils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/rpc/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAI3D;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAEvD"}

View File

@@ -0,0 +1,7 @@
export function isRpcQuantityString(u) {
return (typeof u === "string" && /^0x(?:0|(?:[1-9a-fA-F][0-9a-fA-F]*))$/.test(u));
}
export function isRpcDataString(u) {
return typeof u === "string" && /^0x(?:[0-9a-fA-F]{2})*$/.test(u);
}
//# sourceMappingURL=utils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/rpc/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,mBAAmB,CAAC,CAAU;IAC5C,OAAO,CACL,OAAO,CAAC,KAAK,QAAQ,IAAI,uCAAuC,CAAC,IAAI,CAAC,CAAC,CAAC,CACzE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,CAAU;IACxC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC"}

View File

@@ -0,0 +1,5 @@
import type { ZodType } from "zod";
export declare function validateParams<TypesT extends ReadonlyArray<ZodType<any>>>(params: any[], ...types: TypesT): {
[i in keyof TypesT]: TypesT[i] extends ZodType<infer TypeT> ? TypeT : never;
};
//# sourceMappingURL=validate-params.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"validate-params.d.ts","sourceRoot":"","sources":["../../../src/rpc/validate-params.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAInC,wBAAgB,cAAc,CAAC,MAAM,SAAS,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EACvE,MAAM,EAAE,GAAG,EAAE,EACb,GAAG,KAAK,EAAE,MAAM,GACf;KACA,CAAC,IAAI,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,KAAK,CAAC,GAAG,KAAK,GAAG,KAAK;CAC5E,CAoDA"}

View File

@@ -0,0 +1,40 @@
import { HardhatError } from "@nomicfoundation/hardhat-errors";
export function validateParams(params, ...types) {
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 = [];
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;
}
//# sourceMappingURL=validate-params.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"validate-params.js","sourceRoot":"","sources":["../../../src/rpc/validate-params.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,MAAM,UAAU,cAAc,CAC5B,MAAa,EACb,GAAG,KAAa;IAIhB,IAAI,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,YAAY,CACpB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,uBAAuB,EACxD;YACE,MAAM,EAAE,oCAAoC,MAAM,CAAC,MAAM,EAAE;SAC5D,CACF,CAAC;IACJ,CAAC;IAED,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC;YACnD,cAAc,IAAI,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,MAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,cAAc,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;YACnC,MAAM,IAAI,YAAY,CACpB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,uBAAuB,EACxD;gBACE,MAAM,EAAE,oBAAoB,KAAK,CAAC,MAAM,sBAAsB,MAAM,CAAC,MAAM,EAAE;aAC9E,CACF,CAAC;QACJ,CAAC;IACH,CAAC;SAAM,CAAC;QACN,IACE,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;YAC5B,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,cAAc,EAC7C,CAAC;YACD,MAAM,IAAI,YAAY,CACpB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,uBAAuB,EACxD;gBACE,MAAM,EAAE,oBAAoB,KAAK,CAAC,MAAM,GAAG,cAAc,QACvD,KAAK,CAAC,MACR,sBAAsB,MAAM,CAAC,MAAM,EAAE;aACtC,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAU,EAAE,CAAC;IAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IAED,2HAA2H;IAC3H,OAAO,OAAc,CAAC;AACxB,CAAC"}

View File

@@ -0,0 +1,64 @@
{
"name": "@nomicfoundation/hardhat-zod-utils",
"version": "3.0.2",
"description": "Utilities to use Zod to validate Hardhat plugins' config",
"homepage": "https://github.com/nomicfoundation/hardhat/tree/v-next/v-next/hardhat-zod-utils",
"repository": {
"type": "git",
"url": "https://github.com/NomicFoundation/hardhat",
"directory": "v-next/hardhat-zod-utils"
},
"author": "Nomic Foundation",
"license": "MIT",
"type": "module",
"types": "dist/src/index.d.ts",
"exports": {
".": "./dist/src/index.js",
"./rpc": "./dist/src/rpc/index.js"
},
"keywords": [
"ethereum",
"smart-contracts",
"hardhat"
],
"files": [
"dist/src/",
"src/",
"CHANGELOG.md",
"LICENSE",
"README.md"
],
"devDependencies": {
"@nomicfoundation/hardhat-node-test-reporter": "^3.0.0",
"@types/node": "^22.0.0",
"c8": "^9.1.0",
"eslint": "9.25.1",
"expect-type": "^1.2.1",
"prettier": "3.2.5",
"rimraf": "^5.0.5",
"tsx": "^4.19.3",
"typescript": "~5.8.0",
"zod": "^3.23.8",
"@nomicfoundation/hardhat-test-utils": "^2.0.2"
},
"dependencies": {
"@nomicfoundation/hardhat-errors": "^3.0.7",
"@nomicfoundation/hardhat-utils": "^4.0.0"
},
"peerDependencies": {
"zod": "^3.23.8"
},
"scripts": {
"lint": "pnpm prettier --check && pnpm eslint",
"lint:fix": "pnpm prettier --write && pnpm eslint --fix",
"eslint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"",
"prettier": "prettier \"**/*.{ts,js,md,json}\"",
"test": "node --import tsx/esm --test --test-reporter=@nomicfoundation/hardhat-node-test-reporter \"test/*.ts\" \"test/!(fixture-projects|helpers)/**/*.ts\"",
"test:only": "node --import tsx/esm --test --test-only --test-reporter=@nomicfoundation/hardhat-node-test-reporter \"test/*.ts\" \"test/!(fixture-projects|helpers)/**/*.ts\"",
"test:coverage": "c8 --reporter html --reporter text --all --exclude test --exclude \"src/**/{types,type-extensions}.ts\" --src src node --import tsx/esm --test --test-reporter=@nomicfoundation/hardhat-node-test-reporter \"test/*.ts\" \"test/!(fixture-projects|helpers)/**/*.ts\"",
"pretest": "pnpm build",
"pretest:only": "pnpm build",
"build": "tsc --build .",
"clean": "rimraf dist"
}
}

View 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,
}));
}
}

View 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";

View 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);

View 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",
);

View File

@@ -0,0 +1,5 @@
import type { ZodType } from "zod";
import { z } from "zod";
export const rpcAny: ZodType<any> = z.any();

View 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);

View 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));

View 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,
);

View 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));

View 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;
}

View 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),
});

View 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);
}

View 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;
}