feat(scripting): add zod schemas and viem transform helpers#690
Merged
feat(scripting): add zod schemas and viem transform helpers#690
Conversation
Prepare token bridge deployment transactions without requiring an orbit chain RPC. enqueueTokenBridgeDeployment encodes the createTokenBridge call with caller-provided gas params. enqueueSetWethGateway encodes the setGateways call through UpgradeExecutor with explicit retryable costs.
- Rename maxFeePerGas to maxGasPrice in enqueueSetWethGateway for consistency with enqueueTokenBridgeDeployment and the constant name - Nest rollup/rollupOwner in params object to match existing createTokenBridgePrepareTransactionRequest pattern - Update idempotency comment to explain parent-chain-only check rationale and that failed retryables should be manually redeemed - Restore gas override comments from reference implementation - Replace duplicate deposit test with calldata verification test for enqueueSetWethGateway
…red ABI - Rename enqueueTokenBridgeDeployment to enqueueTokenBridgePrepareTransactionRequest - Rename enqueueSetWethGateway to enqueueSetWethGatewayPrepareTransactionRequest - Extract parentChainGatewayRouterAbi to src/contracts/GatewayRouter.ts, replacing inline copies in both enqueue and existing set weth gateway files
…tion - Split maxSubmissionFee into maxSubmissionCostForFactory and maxSubmissionCostForContracts to match existing retryable fee formula - Update retryable fee calculation to sum both submission costs - Rename enqueueSetWethGateway* to enqueueTokenBridgePrepareSetWethGateway* to match createTokenBridgePrepareSetWethGateway* naming convention - Remove CR comments
Fixes vitest type checker failure caused by dynamic import syntax.
Extract getFactoryDeploymentDataSize and getContractsDeploymentData from the existing estimation functions so that the enqueue variants can reuse the same data-size logic for calculating retryable submission fees.
Replicates the SDK's estimateSubmissionFee logic: calls the Inbox's calculateRetryableSubmissionFee on the parent chain with the current base fee, then applies a 300% safety buffer matching the SDK default.
…tions The enqueue functions now estimate maxSubmissionCost from parent chain state using the shared data-size helpers and the Inbox's calculateRetryableSubmissionFee, matching the approach used by the create* variants via the SDK. Callers no longer need to provide maxSubmissionCostForFactory, maxSubmissionCostForContracts, or maxSubmissionCost.
The contracts deployment (7+ contracts + initialization) needs more gas than the factory deployment (single contract creation).
Instead of using a hardcoded default, read gasLimitForL2FactoryDeployment from the TokenBridgeCreator contract. The caller can still override via the maxGasForFactory parameter.
Replace the separate enqueue* and create* prepare functions with a single implementation that estimates retryable gas from parent chain state and does not require an orbit chain connection. The createTokenBridge orchestrator now calls registerNewNetwork explicitly before waiting for retryables, since the prepare functions no longer do this internally.
Add zod v4 validation schemas and transform functions for all SDK operations. Includes shared primitives (address, hex, bigint schemas), per-function schema/transform pairs, and viem client factory helpers.
Abitype's peer dep on zod ^3 caused pnpm to keep zod@3.22.4 in the tree, creating non-portable abitype resolution paths that TypeScript couldn't name in .d.ts output.
The enqueue-token-bridge-deployment refactor removed orbitChainPublicClient from createTokenBridgePrepareTransactionRequest and its setWethGateway variant. Update schemas to match.
Add overrides for vite, flatted, picomatch, brace-expansion, and yaml to resolve transitive vulnerabilities in dev tooling (vitest, eslint, typescript-eslint, @wagmi/cli, ts-morph, patch-package).
…ction schemas The build* actions take account: Address, not a private key. The schemas should only require what the function actually needs.
# Conflicts: # package.json # pnpm-lock.yaml
Add publicClientSchema, parentChainPublicClientSchema, and actionWriteBaseSchema to common.ts. Add withPublicClient helper to viemTransforms.ts. Update 26 schema files to extend base schemas instead of redeclaring fields. Simplify 9 destructure-and-spread transforms to use withPublicClient.
Inline parentChainPublicClientSchema directly instead of assigning it to a local alias. Use .extend().strict() instead of z.strictObject() with .shape extraction.
Add connection transform functions (withPublicClient, withParentChainPublicClient, withChainSign, withParentChainSign, withChildChainSign, withParentReadChildSign, withPublicClientPositional, withPublicClientOptionalChain) to viemTransforms.ts. Every schema now has its transform baked in via .transform(), eliminating separate transform/resolver exports. Schemas export a single pre-transformed schema that consumers use directly. Move upgradeExecutor ?? false default into actionWriteBaseSchema.
…t type Replace the inline `typeof import(...)` form with a regular named import. Matches the style used by the sibling schemas in the same file and keeps the import list in one place. No behavior change -- both forms produce a type-only reference that TypeScript erases.
douglance
reviewed
Apr 22, 2026
|
|
||
| export const addressSchema = z | ||
| .string() | ||
| .regex(/^0x[0-9a-fA-F]{40}$/, 'Invalid Ethereum address') |
Contributor
Contributor
There was a problem hiding this comment.
are we sure we need these?
…tion Replace regex-based hex and address validators with viem's isHex and isAddress. isAddress does EIP-55 checksum validation on mixed-case addresses, catching a class of typo that the regex silently passed. Same module viem is already a dependency of the SDK -- no new deps.
Removed vite, flatted, picomatch, brace-expansion, and yaml from pnpm.overrides. Tested by removing them and running pnpm install + pnpm audit-ci -- the natural version resolution satisfies the former override floor in every case, and audit-ci still passes. Kept tmp (active CVE) and zod (prevents a v3/v4 dual install via abitype).
The SDK function isTokenBridgeDeployed was removed as unused in the merge from feat/enqueue-token-bridge-deployment. Clean up the scripting references that depended on it: - delete src/scripting/schemas/isTokenBridgeDeployed.ts - drop the re-export from src/scripting/schemas/index.ts - drop the type-level assertion in schemas.type.test.ts Users wanting the same check can call createTokenBridgeFetchTokenBridgeContracts and test the returned router/gateway addresses for the zero address.
The coverage test framework derives test values from the schema's regex patterns. Stripping the regex in favor of bare refine() left the generator falling back to 'string_0', which fails address/hex validation. Layer the viem checks on top of the regex so both the generator and runtime validation work.
The regex layer was subsumed by viem's isHex/isAddress and was only retained to feed the schema coverage test generator. Drop it here; the coverage generator in feat/schema-coverage will need to learn about the address/hex formats directly (follow-up on that branch).
douglance
approved these changes
Apr 22, 2026
Replace the regex with viem's isHex + size(v) === 32. Matches the style of hexSchema / addressSchema (refine-backed, no regex). Coverage generator follow-up lands on feat/schema-coverage.
Replace the regex with isHex + v.length === 66 (0x prefix plus 64 hex chars). Matches the style of hexSchema / addressSchema. Coverage generator follow-up lands on feat/schema-coverage. Supersedes the earlier isHex + size attempt; viem's size() rounds odd-length hex up via Math.ceil, so it couldn't strictly enforce length. An explicit length check is accurate.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds zod schemas and transforms for every SDK function that takes RPC/client input. Schemas validate JSON input and transforms convert it to SDK-ready arguments -- RPC URLs become viem clients, private keys become accounts, strings become bigints. The target audience here is devs who are already familiar with zod, and helping them to write scripts without messing up the arg parsing, and letting them follow a opinionated structure. Devs who arent familiar with zod dont get benefit here, but it's not a complicated library to learn, and I think it's a useful thing to know about.
WARNING: we're creating schemas for every function, so there's a lot of code being added here, but two things are worth focusing on which help us to gain confidence in the correctness of the code:
Not included for now