Skip to content

Conversation

0xpolarzero
Copy link
Collaborator

@0xpolarzero 0xpolarzero commented May 27, 2025

Creates an examples/mud package from the React template, for integrating the Tevm optimistic plugin.

This just pnpm create mud@latest with 0 change to reduce the relevant diff from subsequent PRs.

Summary by CodeRabbit

  • New Features

    • Introduced a full-stack MUD example with React client, smart contracts, and development tooling for blockchain-based player movement.
    • Added Move system contract and position table supporting on-chain player movement in four directions.
    • Developed React UI with real-time sync, account management, keyboard and button controls, and an explorer panel.
    • Added asynchronous button component and error boundary fallback UI for improved user experience.
  • Documentation

    • Greatly expanded Tevm documentation with detailed features, architecture, APIs, usage examples, and integration guidance.
  • Chores

    • Added numerous configuration files for ESLint, Prettier, Solhint, TypeScript, Tailwind CSS, Vite, Foundry, pnpm workspace, and VS Code to enhance development workflow and code quality.
    • Included process management YAML and package.json files for streamlined development and deployment.
  • Tests

    • Added Solidity tests verifying player movement logic and contract deployment.
    • Added Zig benchmarks for EVM stack operations assessing performance and robustness.
  • Refactor

    • Centralized EVM constants and utility functions into a single module for consistent access and maintainability.
  • Examples

    • Provided example usage files demonstrating contract deployment, EVM constant usage, and stack benchmarking.

@0xpolarzero 0xpolarzero self-assigned this May 27, 2025
@changeset-bot
Copy link

changeset-bot bot commented May 27, 2025

⚠️ No Changeset found

Latest commit: 88f0ece

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented May 27, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
node ❌ Failed (Inspect) Jun 23, 2025 11:26am
tevm-monorepo-app ✅ Ready (Inspect) Visit Preview Jun 23, 2025 11:26am
1 Skipped Deployment
Name Status Preview Updated (UTC)
tevm-monorepo-tevm ⬜️ Ignored (Inspect) Jun 23, 2025 11:26am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 27, 2025

Walkthrough

This update introduces a comprehensive MUD example project, featuring a full-stack Ethereum dapp with smart contracts, a React client, and extensive configuration for development workflows. It adds new Solidity contracts, TypeScript/React components, workspace management files, and EVM benchmarking and constants modules, along with supporting documentation and configuration files.

Changes

File(s) / Path(s) Change Summary
CLAUDE.md Expanded documentation: features, architecture, API, usage, examples, bundler integration, JSON-RPC, and developer workflows.
CONSTANTS_MODULE_SUMMARY.md, src/evm/constants.zig, src/evm/constants_usage_example.zig, src/evm/evm.zig, src/evm/opcodes.zig, test/Evm/constants_test.zig, build.zig Added centralized EVM constants module, usage examples, tests, and refactored related modules to use shared constants/utilities.
test/Bench/stack_benchmark.zig Added stack operation benchmark and stress test suite for EVM stack implementation.
src/package.zig Exported Stack type from the EVM module.
packages/actions/src/Mine/mineHandler.spec.ts Redundant duplicate import added (no functional effect).
examples/mud/** (multiple files and directories) Introduced a complete MUD example project including:
- Contracts: Solidity sources, codegen, tests, and deployment scripts.
- Client: React app with game logic, UI, hooks, and configuration.
- Workspace: pnpm, TypeScript, ESLint, Prettier, VSCode, and Foundry configs.
- Build, lint, and development scripts.
- Supporting files for explorer, ABI, and chain integration.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ReactClient
    participant Providers
    participant Wagmi/EntryKit/Sync
    participant Blockchain (Anvil/World)
    participant SolidityContract

    User->>ReactClient: Loads app (index.tsx)
    ReactClient->>Providers: Setup context (Wagmi, EntryKit, Sync)
    Providers->>Wagmi/EntryKit/Sync: Initialize blockchain, wallet, sync
    User->>ReactClient: Interacts (move, spawn, sign in)
    ReactClient->>SolidityContract: Send transaction via contract hook
    SolidityContract->>Blockchain (Anvil/World): Executes contract logic
    Blockchain (Anvil/World)->>SolidityContract: Updates state (Position)
    SolidityContract->>ReactClient: Emits events/state changes
    ReactClient->>User: Updates UI (GameMap, Explorer)
Loading

Possibly related PRs

Suggested reviewers

  • roninjin10

Poem

In a meadow of code where the smart contracts grow,
A rabbit hops swiftly—oh, what a show!
With stacks to benchmark and constants to share,
A MUD world emerges with logic laid bare.
From React to Solidity, all bunnies agree:
This patch is a carrot for devs—bug-free!
🐇✨


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

roninjin10 and others added 5 commits May 27, 2025 22:27
## Description

Optimized the EVM stack implementation for better performance and cache
efficiency. Key improvements include:

- Aligned stack data to 32-byte boundaries for optimal cache performance
- Implemented dual safe/unsafe API pattern for performance-critical code
paths
- Added optimized swap operations with manual implementation to avoid
compiler issues
- Introduced bulk operations like `popn` and `popn_top` for efficient
multi-value handling
- Added support for EIP-663 operations (dupn, swapn, exchange)
- Improved error handling with more specific error types
- Replaced `OutOfMemory` error with `InvalidPosition` for better
semantics
- Added comprehensive utility methods for stack manipulation
- Created a static binary library for the stack implementation

Added extensive test coverage and benchmarking to verify performance
improvements against revm/evmone targets.

## Testing

- Added comprehensive unit tests in `test/Evm/stack_test.zig` covering
all operations
- Created benchmarking suite in `test/Bench/stack_benchmark.zig` to
measure performance
- Verified performance targets against revm and evmone implementations
- Tested edge cases including stack overflow, underflow, and boundary
conditions
- Validated memory safety with explicit clearing of popped values

## Additional Information

- [x] I read the [contributing docs](../docs/contributing.md) (if this
is your first contribution)

Your ENS/address:

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced a robust, high-performance EVM stack implementation with
enhanced safety, flexibility, and support for advanced stack operations,
including EIP-663 dynamic manipulations.
- Publicly exposed stack types, constants, and utilities for broader
use.
- **Refactor**
- Unified and optimized stack operations for clarity, performance, and
maintainability.
- **Tests**
- Added comprehensive test suite covering all stack behaviors, error
conditions, and edge cases.
- Introduced a benchmark suite to measure stack performance and
stress-test various scenarios.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
…#1725)

## Description

Created a centralized constants module for the EVM implementation to
eliminate circular dependencies and provide a single source of truth for
all EVM specifications. This module includes opcode constants, EVM
limits, gas costs, and utility functions for the Zig implementation.

The constants module contains:
- Opcode byte values (ADD, MUL, PUSH, etc.)
- EVM limits (stack, memory, code sizes)
- Gas constants with hardfork-specific values
- Utility functions for opcode classification and gas calculations
- System constants like empty hashes and special addresses

## Testing

Added comprehensive test suite in `test/Evm/constants_test.zig`
covering:
- Opcode constant values
- EVM limits and sizes
- Gas constant values
- Utility functions with edge cases
- Memory gas cost calculations
- Hardfork-specific gas constants

## Additional Information

- [x] I read the [contributing docs](../docs/contributing.md) (if this
is your first contribution)

Your ENS/address:

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Documentation**
- Expanded and enhanced project documentation with detailed sections on
key features, core architecture, API conventions, package structure,
JSON-RPC support, bundler integration, and advanced usage examples.

- **New Features**
- Introduced a centralized module for Ethereum Virtual Machine
constants, limits, gas costs, and utility functions.
  - Added example usage patterns for EVM constants and gas calculations.

- **Refactor**
- Consolidated opcode and gas constants usage throughout the codebase
for consistency and maintainability.

- **Tests**
- Added comprehensive tests to verify EVM constants, gas calculations,
and utility functions.
  - Integrated new test suites into the build and test process.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description

Reordered the build steps in the `release:publish` script to ensure
proper dependency resolution. The new order is: `build:dist`,
`build:types`, and then `build:app`.

## Testing

Verified that the updated build order successfully completes the release
process without dependency issues.

## Additional Information

- [ ] I read the [contributing docs](../docs/contributing.md) (if this
is your first contribution)

Your ENS/address:
"@tevm/vm": patch
---

Skip balance & nonce in mineHandler when adding tx to BlockBuilder.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn’t this already merge?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it should have been merged in, I'll rebase

@roninjin10
Copy link
Collaborator

This needs rebased

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🧹 Nitpick comments (24)
CONSTANTS_MODULE_SUMMARY.md (1)

89-89: Minor grammar improvement needed.

Add the missing article "the" for better readability.

- 2. Remove any duplicate constant definitions throughout codebase
+ 2. Remove any duplicate constant definitions throughout the codebase
🧰 Tools
🪛 LanguageTool

[uncategorized] ~89-~89: You might be missing the article “the” here.
Context: ...plicate constant definitions throughout codebase 3. Consider adding more hardfork-specif...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

test/Bench/stack_benchmark.zig (3)

121-149: Consider more robust error handling in safe vs unsafe comparison.

The safe operations use try which could potentially skew timing measurements if errors occur. Consider pre-validating conditions or using a separate error-free test scenario.

     // Benchmark safe push/pop
+    // Ensure stack is in valid state for safe operations
+    if (stack.len() > 0) {
+        stack.clear(); // or similar reset method
+    }
     self.timer.reset();

309-318: Handle edge cases in random operation selection.

The random operations could lead to invalid states. Consider adding more robust bounds checking for the random operations.

             3 => if (stack.len() > 0 and stack.len() < Stack.capacity) {
-                stack.dup_unsafe(1 + (random.int(u8) % @min(stack.len(), 16)));
+                const dup_depth = 1 + (random.int(u8) % @min(stack.len(), 16));
+                if (dup_depth <= stack.len()) {
+                    stack.dup_unsafe(dup_depth);
+                }
             },

327-334: Consider adding error handling for main benchmark execution.

The main function could benefit from better error handling and reporting if any benchmark fails.

 pub fn main() !void {
-    var benchmark = try StackBenchmark.init();
-    try benchmark.runAll();
-    
-    try stressTestMaxDepth();
-    try stressTestRapidOperations();
+    var benchmark = try StackBenchmark.init();
+    
+    benchmark.runAll() catch |err| {
+        std.debug.print("Benchmark failed: {}\n", .{err});
+        return err;
+    };
+    
+    stressTestMaxDepth() catch |err| {
+        std.debug.print("Max depth stress test failed: {}\n", .{err});
+    };
+    
+    stressTestRapidOperations() catch |err| {
+        std.debug.print("Rapid operations stress test failed: {}\n", .{err});
+    };
 }
examples/mud/packages/client/.gitignore (1)

1-1: Confirm package‐level ignore scope.
You’ve excluded dist/ to keep build artifacts out of source control, which is good. Please verify that your repo’s root .gitignore already covers node_modules/, environment files, and any other common artifacts so you don’t accidentally commit dependencies or sensitive files here.

examples/mud/packages/contracts/.gitignore (1)

1-13: Consider adding trailing slashes for directory clarity.
You’ve unignored the out/IWorld.sol directory but then re-ignored its contents except the two ABI files. For readability, you can make it explicit that out/IWorld.sol is a directory by adding a trailing slash:

-!out/IWorld.sol
+!out/IWorld.sol/

This won’t change behavior but improves pattern clarity.

packages/actions/src/Mine/mineHandler.spec.ts (1)

9-9: Remove duplicate import
The setAccountHandler import is duplicated on lines 7 and 9. Please remove the redundant line to avoid confusion and maintain clarity.

Apply this diff:

- import { setAccountHandler } from '../SetAccount/setAccountHandler.js'
examples/mud/packages/client/src/mud/stash.ts (1)

4-4: Consider adding an explicit type annotation for stash
For enhanced readability and stronger type safety, you could annotate the export, e.g.:

export const stash: ReturnType<typeof createStash> = createStash(config);
examples/mud/packages/client/index.html (2)

6-6: Consider a more descriptive title.

The generic title "a MUD app" could be more descriptive for better user experience and identification during development.

-    <title>a MUD app</title>
+    <title>MUD Example App</title>

1-12: Consider adding common HTML improvements.

While the basic structure is functional, consider adding these common improvements for better development experience:

  • A favicon reference
  • Meta description for SEO
  • Viewport meta tag optimization
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta name="description" content="MUD example application demonstrating on-chain game mechanics" />
+    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
-    <title>a MUD app</title>
+    <title>MUD Example App</title>
  </head>
examples/mud/packages/client/package.json (1)

25-26: Consider updating React to the latest stable version.

React 18.2.0 is a stable version but not the latest. Consider updating to React 18.3.x for the latest features and security updates.

examples/mud/packages/contracts/script/PostDeploy.s.sol (1)

21-21: Complete the TODO implementation.

The script has a TODO placeholder that should be implemented for a complete example. Consider adding sample post-deployment operations like initializing world state or setting up initial data.

Would you like me to suggest some common post-deployment operations that could be implemented here?

examples/mud/packages/client/src/index.tsx (1)

10-10: Add null check for DOM element safety.

The non-null assertion operator (!) assumes the element with ID "react-root" exists. If this element is missing from the HTML, the application will crash at runtime.

Consider adding a null check for better error handling:

-createRoot(document.getElementById("react-root")!).render(
+const rootElement = document.getElementById("react-root");
+if (!rootElement) throw new Error("Failed to find the root element");
+createRoot(rootElement).render(
examples/mud/packages/client/src/Providers.tsx (1)

18-18: Consider memoizing the world address retrieval.

The getWorldAddress() function is called on every render. Since this reads from environment variables, consider memoizing it for better performance:

export function Providers({ children }: Props) {
-  const worldAddress = getWorldAddress();
+  const worldAddress = useMemo(() => getWorldAddress(), []);
examples/mud/mprocs.yaml (1)

15-15: Development private key is safe but should be clearly documented.

The static analysis tool flagged this as a potential security issue, but this is the well-known Anvil default private key that's safe for development use. The comment correctly identifies it as such.

To improve clarity and address security scanning concerns, consider:

      # Anvil default account (0x70997970C51812dc3A010C7d01b50e0d17dc79C8)
+      # WARNING: This is a well-known test key. NEVER use in production!
      PRIVATE_KEY: "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"
🧰 Tools
🪛 Gitleaks (8.26.0)

15-15: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

examples/mud/packages/client/src/ui/icons/ArrowDownIcon.tsx (1)

4-4: Consider consolidating the Props type definition.

The Props type is identical to the one in MUDIcon.tsx (line 4). Consider extracting this to a shared types file to reduce duplication and improve maintainability.

Create a shared types file:

+// src/ui/icons/types.ts
+import { DetailedHTMLProps, SVGAttributes } from "react";
+
+export type IconProps = DetailedHTMLProps<SVGAttributes<SVGSVGElement>, SVGSVGElement>;

Then update the import:

-import { DetailedHTMLProps, SVGAttributes } from "react";
+import { IconProps } from "./types";
-
-export type Props = DetailedHTMLProps<SVGAttributes<SVGSVGElement>, SVGSVGElement>;
examples/mud/packages/client/src/wagmiConfig.ts (2)

38-39: Address the TODO: Replace or remove the default WalletConnect project ID.

The hardcoded WalletConnect project ID should be replaced with a project-specific one or made configurable through environment variables.

Consider this approach for better configuration management:

-  // TODO: swap this with another default project ID or leave empty
-  walletConnectProjectId: "14ce88fdbc0f9c294e26ec9b4d848e44",
+  walletConnectProjectId: process.env.VITE_WALLETCONNECT_PROJECT_ID || "",

Do you want me to help create an environment variable configuration setup for this?


15-17: Consider making the paymaster address configurable.

The paymaster address is hardcoded, which may not be suitable for different deployment environments.

Consider making it configurable:

       paymaster: {
-        address: "0xf03E61E7421c43D9068Ca562882E98d1be0a6b6e",
+        address: (process.env.VITE_PAYMASTER_ADDRESS as `0x${string}`) || "0xf03E61E7421c43D9068Ca562882E98d1be0a6b6e",
       },
examples/mud/packages/client/src/mud/useWorldContract.ts (1)

37-37: Use Number.POSITIVE_INFINITY instead of global Infinity.

Following ES2015 standards, use the Number namespace for consistency.

-    staleTime: Infinity,
+    staleTime: Number.POSITIVE_INFINITY,
🧰 Tools
🪛 Biome (1.9.4)

[error] 37-37: Use Number.POSITIVE_INFINITY instead of the equivalent global.

ES2015 moved some globals into the Number namespace for consistency.
Safe fix: Use Number.POSITIVE_INFINITY instead.

(lint/style/useNumberNamespace)

examples/mud/packages/client/src/ui/AsyncButton.tsx (2)

10-10: Address the TODO comment for better maintainability.

The TODO comment suggests extracting this logic into a reusable hook, which would improve maintainability and allow other components to benefit from async event handling.

Would you like me to help implement the suggested hook to extract this async handling logic?


13-13: Consider using a boolean type for better clarity.

The promisePending state uses true | undefined which is unconventional. Consider using a boolean type for better readability:

-  const [promisePending, setPromisePending] = useState<true | undefined>(undefined);
+  const [promisePending, setPromisePending] = useState(false);

And update the corresponding setter calls:

-      setPromisePending(true);
+      setPromisePending(true);
-          setPromisePending(undefined);
+          setPromisePending(false);
examples/mud/packages/client/src/ui/ErrorFallback.tsx (1)

38-48: Consider using React state instead of direct DOM manipulation.

The direct manipulation of ariaBusy bypasses React's state management. Consider using React state for better consistency:

+  const [isRetrying, setIsRetrying] = useState(false);
+
   onClick={async (event) => {
-    event.currentTarget.ariaBusy = "true";
+    setIsRetrying(true);
     await wait(1000);
     resetErrorBoundary();
     if (isMounted.current) {
       setRetries((value) => value - 1);
-      event.currentTarget.ariaBusy = null;
+      setIsRetrying(false);
     }
   }}

And update the button's aria-busy attribute:

-  className="group bg-red-500 text-white px-4 py-2 rounded-md hover:bg-red-600 active:bg-red-700 transition aria-busy:pointer-events-none aria-busy:animate-pulse"
+  className="group bg-red-500 text-white px-4 py-2 rounded-md hover:bg-red-600 active:bg-red-700 transition aria-busy:pointer-events-none aria-busy:animate-pulse"
+  aria-busy={isRetrying}
CLAUDE.md (1)

59-59: Fix markdown formatting issue.

The static analysis tool detected spaces inside emphasis markers. This can cause rendering issues in some markdown parsers.

Apply this diff to fix the formatting:

-For a list of all packages, see the `workspaces` key in the root level [package.json](./package.json)
+For a list of all packages, see the `workspaces` key in the root level [package.json](./package.json)

Note: The actual issue might be with surrounding text that contains emphasis markers with spaces.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

59-59: Spaces inside emphasis markers
null

(MD037, no-space-in-emphasis)

examples/mud/packages/contracts/src/codegen/tables/Position.sol (1)

19-22: Consider coordinate range implications.

The PositionData struct uses int32 for x and y coordinates, providing a range of approximately -2.1 billion to +2.1 billion. This should be sufficient for most game worlds, but verify this matches your intended game scale.

If you need a larger coordinate system or want to optimize for smaller values, consider:

 struct PositionData {
-  int32 x;
-  int32 y;
+  int16 x;  // Range: -32,768 to 32,767 (more gas efficient)
+  int16 y;
 }

Or for larger worlds:

 struct PositionData {
-  int32 x;
-  int32 y;
+  int64 x;  // Much larger range
+  int64 y;
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c0ac76 and 92169f5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (59)
  • CLAUDE.md (2 hunks)
  • CONSTANTS_MODULE_SUMMARY.md (1 hunks)
  • examples/mud/.eslintrc (1 hunks)
  • examples/mud/.gitattributes (1 hunks)
  • examples/mud/.gitignore (1 hunks)
  • examples/mud/.vscode/extensions.json (1 hunks)
  • examples/mud/.vscode/settings.json (1 hunks)
  • examples/mud/mprocs.yaml (1 hunks)
  • examples/mud/package.json (1 hunks)
  • examples/mud/packages/client/.eslintrc (1 hunks)
  • examples/mud/packages/client/.gitignore (1 hunks)
  • examples/mud/packages/client/index.html (1 hunks)
  • examples/mud/packages/client/package.json (1 hunks)
  • examples/mud/packages/client/postcss.config.cjs (1 hunks)
  • examples/mud/packages/client/src/App.tsx (1 hunks)
  • examples/mud/packages/client/src/Providers.tsx (1 hunks)
  • examples/mud/packages/client/src/common.ts (1 hunks)
  • examples/mud/packages/client/src/game/GameMap.tsx (1 hunks)
  • examples/mud/packages/client/src/game/useKeyboardMovement.ts (1 hunks)
  • examples/mud/packages/client/src/index.tsx (1 hunks)
  • examples/mud/packages/client/src/mud/Explorer.tsx (1 hunks)
  • examples/mud/packages/client/src/mud/Synced.tsx (1 hunks)
  • examples/mud/packages/client/src/mud/stash.ts (1 hunks)
  • examples/mud/packages/client/src/mud/useSyncStatus.ts (1 hunks)
  • examples/mud/packages/client/src/mud/useWorldContract.ts (1 hunks)
  • examples/mud/packages/client/src/ui/AsyncButton.tsx (1 hunks)
  • examples/mud/packages/client/src/ui/ErrorFallback.tsx (1 hunks)
  • examples/mud/packages/client/src/ui/icons/ArrowDownIcon.tsx (1 hunks)
  • examples/mud/packages/client/src/ui/icons/MUDIcon.tsx (1 hunks)
  • examples/mud/packages/client/src/wagmiConfig.ts (1 hunks)
  • examples/mud/packages/client/tailwind.config.ts (1 hunks)
  • examples/mud/packages/client/tsconfig.json (1 hunks)
  • examples/mud/packages/client/vite.config.ts (1 hunks)
  • examples/mud/packages/contracts/.gitignore (1 hunks)
  • examples/mud/packages/contracts/.prettierrc (1 hunks)
  • examples/mud/packages/contracts/.solhint.json (1 hunks)
  • examples/mud/packages/contracts/foundry.toml (1 hunks)
  • examples/mud/packages/contracts/mud.config.ts (1 hunks)
  • examples/mud/packages/contracts/out/IWorld.sol/IWorld.abi.json (1 hunks)
  • examples/mud/packages/contracts/package.json (1 hunks)
  • examples/mud/packages/contracts/remappings.txt (1 hunks)
  • examples/mud/packages/contracts/script/PostDeploy.s.sol (1 hunks)
  • examples/mud/packages/contracts/src/MoveSystem.sol (1 hunks)
  • examples/mud/packages/contracts/src/codegen/common.sol (1 hunks)
  • examples/mud/packages/contracts/src/codegen/index.sol (1 hunks)
  • examples/mud/packages/contracts/src/codegen/tables/Position.sol (1 hunks)
  • examples/mud/packages/contracts/src/codegen/world/IMoveSystem.sol (1 hunks)
  • examples/mud/packages/contracts/src/codegen/world/IWorld.sol (1 hunks)
  • examples/mud/packages/contracts/test/MoveTest.t.sol (1 hunks)
  • examples/mud/packages/contracts/test/WorldTest.t.sol (1 hunks)
  • examples/mud/packages/contracts/tsconfig.json (1 hunks)
  • examples/mud/packages/contracts/worlds.json (1 hunks)
  • examples/mud/packages/contracts/worlds.json.d.ts (1 hunks)
  • examples/mud/pnpm-workspace.yaml (1 hunks)
  • examples/mud/tsconfig.json (1 hunks)
  • packages/actions/src/Mine/mineHandler.spec.ts (1 hunks)
  • src/evm/constants_usage_example.zig (1 hunks)
  • src/package.zig (1 hunks)
  • test/Bench/stack_benchmark.zig (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (6)
examples/mud/packages/client/src/game/useKeyboardMovement.ts (1)
examples/mud/packages/client/src/common.ts (1)
  • Direction (11-11)
examples/mud/packages/client/src/Providers.tsx (2)
examples/mud/packages/client/src/common.ts (4)
  • worldAddress (6-6)
  • getWorldAddress (13-18)
  • chainId (5-5)
  • startBlock (7-7)
examples/mud/packages/client/src/wagmiConfig.ts (1)
  • wagmiConfig (36-49)
examples/mud/packages/client/src/ui/icons/ArrowDownIcon.tsx (1)
examples/mud/packages/client/src/ui/icons/MUDIcon.tsx (1)
  • Props (4-4)
examples/mud/packages/client/src/mud/useWorldContract.ts (2)
tevm/index.ts (1)
  • Account (141-141)
examples/mud/packages/client/src/common.ts (1)
  • getWorldAddress (13-18)
examples/mud/packages/client/src/common.ts (1)
examples/mud/packages/client/src/wagmiConfig.ts (1)
  • chains (7-27)
examples/mud/packages/client/src/ui/icons/MUDIcon.tsx (1)
examples/mud/packages/client/src/ui/icons/ArrowDownIcon.tsx (1)
  • Props (4-4)
🪛 LanguageTool
examples/mud/packages/contracts/remappings.txt

[misspelling] ~1-~1: Hoewel het woord correct kan zijn, is er een grote kans dat het een typefout is van “noden”. Zo niet, dan is het waarschijnlijk een ouderwetse uitdrukking.
Context: ds-test/=node_modules/ds-test/src/ forge-std/=node_mo...

(MACHTE)


[misspelling] ~2-~2: Hoewel het woord correct kan zijn, is er een grote kans dat het een typefout is van “noden”. Zo niet, dan is het waarschijnlijk een ouderwetse uitdrukking.
Context: ...t/=node_modules/ds-test/src/ forge-std/=node_modules/forge-std/src/ @latticexyz/=nod...

(MACHTE)


[misspelling] ~3-~3: Hoewel het woord correct kan zijn, is er een grote kans dat het een typefout is van “noden”. Zo niet, dan is het waarschijnlijk een ouderwetse uitdrukking.
Context: ...ode_modules/forge-std/src/ @latticexyz/=node_modules/@latticexyz/

(MACHTE)

CONSTANTS_MODULE_SUMMARY.md

[uncategorized] ~89-~89: You might be missing the article “the” here.
Context: ...plicate constant definitions throughout codebase 3. Consider adding more hardfork-specif...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

🪛 Biome (1.9.4)
examples/mud/packages/client/src/mud/Explorer.tsx

[error] 29-29: Provide a title attribute when using iframe elements.

Screen readers rely on the title set on an iframe to describe the content being displayed.

(lint/a11y/useIframeTitle)

examples/mud/packages/client/src/ui/icons/ArrowDownIcon.tsx

[error] 8-14: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

examples/mud/packages/client/src/game/GameMap.tsx

[error] 45-55: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 90-94: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)

examples/mud/packages/client/src/mud/useWorldContract.ts

[error] 37-37: Use Number.POSITIVE_INFINITY instead of the equivalent global.

ES2015 moved some globals into the Number namespace for consistency.
Safe fix: Use Number.POSITIVE_INFINITY instead.

(lint/style/useNumberNamespace)

examples/mud/packages/client/src/ui/icons/MUDIcon.tsx

[error] 8-15: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

🪛 Gitleaks (8.26.0)
examples/mud/mprocs.yaml

15-15: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 markdownlint-cli2 (0.17.2)
CLAUDE.md

59-59: Spaces inside emphasis markers
null

(MD037, no-space-in-emphasis)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: CI Checks
  • GitHub Check: Nx Cloud - Main Job
🔇 Additional comments (72)
src/evm/constants_usage_example.zig (8)

1-8: LGTM! Well-structured file header and imports.

The file documentation clearly explains its purpose as a usage example for the constants module, and the imports are appropriate.


10-32: Memory cost calculation logic is correct.

The calculateMemoryOperationCost function properly handles the memory expansion gas calculation with overflow protection and already-paid cost subtraction. The edge case handling for when expansion cost is less than already paid (lines 23-26) is well thought out.


35-52: Hardfork validation logic is accurate.

The opcode hardfork validation correctly maps opcodes to their introduction hardforks (PUSH0 in Shanghai, BASEFEE in London, blob opcodes in Cancun). The default case appropriately assumes most opcodes are valid across all hardforks.


55-84: SSTORE gas calculation demonstrates proper pattern.

The simplified SSTORE gas calculation effectively demonstrates the pattern for dynamic gas costs, including EIP-2929 cold access costs and different storage operation types. The comment acknowledging this is simplified (line 67) is helpful.


87-112: Opcode stack effect implementation is comprehensive.

The function covers major opcode categories using the constants module utilities. The fallback logic for unknown opcodes (line 110) is safe, returning zero pop/push counts.


114-131: Test coverage validates memory cost calculations.

The tests cover important scenarios: no expansion, single word expansion, and large expansion with quadratic costs. The expected values appear correct based on EVM memory pricing rules.


133-150: Hardfork validation tests are thorough.

The tests verify opcode availability across different hardforks, covering both positive and negative cases for hardfork-specific opcodes like PUSH0 and BASEFEE.


1-150: Inconsistency with PR objectives.

This file appears to be related to EVM constants and utilities rather than a MUD example project. The PR summary mentions creating a MUD example using React template, but this Zig file doesn't align with that description.

Please verify if this file belongs in the correct PR. The PR objectives mention a MUD example with React, but this appears to be EVM-related Zig code.

Likely an incorrect or invalid review comment.

CONSTANTS_MODULE_SUMMARY.md (3)

1-60: Comprehensive and well-structured documentation.

The documentation provides excellent coverage of the EVM constants module implementation, clearly explaining the purpose, structure, and benefits. The organization into logical sections makes it easy to follow.


63-84: Clear and practical usage examples.

The code examples effectively demonstrate how to use the constants module in real scenarios. The examples cover the main use cases: opcode constants, gas constants, utility functions, and hardfork-specific values.


1-99: Documentation content doesn't match PR objectives.

This documentation describes an EVM constants module implementation in Zig, which doesn't align with the PR summary that mentions creating a MUD example project using React template.

Please verify if this documentation file belongs in the correct PR. The PR objectives mention a MUD example with React, but this documents EVM constants in Zig.

Likely an incorrect or invalid review comment.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~89-~89: You might be missing the article “the” here.
Context: ...plicate constant definitions throughout codebase 3. Consider adding more hardfork-specif...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

src/package.zig (1)

10-11: LGTM! Clean and consistent API export.

The Stack export follows the same pattern as the existing Memory export and provides a clean public API for the benchmark suite to use.

test/Bench/stack_benchmark.zig (3)

20-46: Excellent benchmark structure with proper warmup.

The push/pop benchmark follows good practices with warmup iterations and proper timing. The performance target of >500M ops/sec provides a clear baseline for comparison.


1-6:

✅ Verification successful

Verify the import path for Stack.

The import path "src/package.zig" may not be correct depending on the project's module structure. In Zig, you typically use relative imports or configured module names.


🏁 Script executed:

#!/bin/bash
# Check the project structure to verify correct import path
echo "=== Project structure around src/package.zig ==="
fd -t f "package.zig" | head -10

echo -e "\n=== Current directory structure ==="
ls -la

echo -e "\n=== Source directory structure ==="
fd -t d "src" | head -5
ls -la src/ 2>/dev/null || echo "src/ directory not found"

Length of output: 7936


Import path is correct

The file src/package.zig exists at the project root and correctly exports Stack. No changes are required.


180-188:

❓ Verification inconclusive

Verify popn method exists and handle potential errors.

The code calls try stack.popn(4) but doesn't handle the case where this might fail due to insufficient stack items. Consider pre-validating stack depth.


🏁 Script executed:

#!/bin/bash
# Search for popn method definition
echo "=== Searching for Stack popn method ==="
ast-grep --pattern 'fn popn($$$) $$$'
rg -A 5 "fn.*popn" --type zig

Length of output: 160


🏁 Script executed:

#!/bin/bash
echo "=== Searching for popn definition with ripgrep ==="
rg -n "fn.*popn" --type zig || echo "No popn definition found via --type zig"

echo "=== Searching for any popn occurrences ==="
rg -n "popn\(" || echo "No popn occurrences found in repository"

echo "=== Locating Stack type definition ==="
rg -n "const Stack = struct" --type zig || rg -n "struct Stack" --type zig || echo "No Stack struct definition found via ripgrep"

echo "=== Inspecting Stack struct via ast-grep ==="
ast-grep --pattern $'const Stack = struct { $$$ }' || echo "No match for Stack struct via ast-grep"

Length of output: 1384


Unable to locate popn – please confirm its existence and error handling

I wasn’t able to find a popn method on your Stack struct. The call

_ = try stack.popn(4);

at test/Bench/stack_benchmark.zig:181
assumes:

  • A pub fn popn(n: usize) ![]T is implemented on Stack.
  • It returns a clear error (e.g. Error.OutOfBounds) when there aren’t enough items.

Please verify that popn is defined and either:

  • Pre-check stack.len() >= 4 before calling popn(4), or
  • Handle the error returned by popn(4) to avoid unexpected crashes when the stack underflows.
examples/mud/.gitattributes (1)

1-3: Generated files marked correctly.
Flagging pnpm-lock.yaml and all codegen Solidity sources as linguist-generated will suppress unnecessary diffs on GitHub, which aligns well with your project structure.

examples/mud/.gitignore (1)

1-17: Root ignore rules look good.
You’ve excluded system files (.DS_Store), logs, node_modules/, .env.*, and Foundry build artifacts while whitelisting only the essential JSON/TS artifacts. This setup should keep your repository clean of generated and sensitive files.

examples/mud/pnpm-workspace.yaml (1)

1-3: Workspace configuration is correct.
Including all packages under packages/* ensures pnpm will hoist dependencies and link the client and contracts modules properly. No issues spotted here.

examples/mud/tsconfig.json (1)

1-4: Approve TypeScript configuration
This minimal config correctly extends the shared base without overrides, ensuring consistency across the example project.

examples/mud/packages/contracts/tsconfig.json (1)

1-4: Approve TypeScript configuration
The package-level tsconfig correctly extends the root config (../../tsconfig.json) with no additional overrides, keeping the contracts workspace aligned with the overall setup.

examples/mud/packages/contracts/worlds.json (1)

1-6: Approve deployed world mapping
The JSON correctly maps network ID 31337 to the deployed address and follows the expected schema for runtime configuration.

examples/mud/.eslintrc (1)

1-11: Approve ESLint configuration
The root ESLint setup is appropriately configured for TypeScript, enabling linting across the example without conflicting with package-specific rules.

examples/mud/packages/contracts/.prettierrc (1)

1-8: Formatting rules look solid
This Prettier configuration correctly sets up Solidity formatting with the prettier-plugin-solidity, enforces a 120-character line width, semicolons, 2-space indentation, no tabs, and bracket spacing.

examples/mud/.vscode/settings.json (1)

1-3: Local TypeScript SDK path is set correctly
Pointing VS Code to node_modules/typescript/lib ensures the editor uses the project’s TypeScript version.

examples/mud/packages/contracts/remappings.txt (1)

1-3: Solidity import remappings appear correct
The mappings for ds-test/, forge-std/, and @latticexyz/ point to their respective source directories in node_modules and follow the expected format.

🧰 Tools
🪛 LanguageTool

[misspelling] ~1-~1: Hoewel het woord correct kan zijn, is er een grote kans dat het een typefout is van “noden”. Zo niet, dan is het waarschijnlijk een ouderwetse uitdrukking.
Context: ds-test/=node_modules/ds-test/src/ forge-std/=node_mo...

(MACHTE)


[misspelling] ~2-~2: Hoewel het woord correct kan zijn, is er een grote kans dat het een typefout is van “noden”. Zo niet, dan is het waarschijnlijk een ouderwetse uitdrukking.
Context: ...t/=node_modules/ds-test/src/ forge-std/=node_modules/forge-std/src/ @latticexyz/=nod...

(MACHTE)


[misspelling] ~3-~3: Hoewel het woord correct kan zijn, is er een grote kans dat het een typefout is van “noden”. Zo niet, dan is het waarschijnlijk een ouderwetse uitdrukking.
Context: ...ode_modules/forge-std/src/ @latticexyz/=node_modules/@latticexyz/

(MACHTE)

examples/mud/packages/client/postcss.config.cjs (1)

1-6: PostCSS plugin configuration is in place
Tailwind CSS and Autoprefixer are properly enabled for the client build pipeline. No issues found.

examples/mud/packages/client/src/mud/stash.ts (1)

1-2: Verify TypeScript path alias for contracts/mud.config
Ensure your tsconfig.json (or Vite config) includes a path mapping for "contracts/*" or sets baseUrl appropriately so this import resolves correctly during build and editor validation.

examples/mud/.vscode/extensions.json (1)

1-3: VS Code extension recommendations look good
The chosen extensions (Hardhat Solidity, ESLint, Prettier) align well with the technologies used in this workspace.

examples/mud/packages/client/vite.config.ts (1)

1-12: Vite configuration is correctly set up
The React and Mud plugins are configured properly, with appropriate build targets, minification, and source maps for development and production workflows.

examples/mud/packages/contracts/src/codegen/common.sol (1)

1-11: Autogenerated file – skip manual review
This file is marked as autogenerated. The SPDX license and pragma version are appropriate; no manual changes should be made here.

examples/mud/packages/contracts/worlds.json.d.ts (1)

1-2: Type declaration for worlds.json is sound
The Partial<Record<string, { address: \0x${string}`; blockNumber?: number }>>` pattern correctly enforces type safety for imported JSON data.

examples/mud/packages/contracts/src/codegen/world/IMoveSystem.sol (1)

1-15: Well-structured autogenerated interface.

The interface follows MUD conventions properly:

  • Clear warning about manual editing (line 4, 11)
  • Proper license and pragma declarations
  • Good documentation with @title, @author, @dev tags
  • Clean single-purpose interface design

The app__move function signature correctly uses the imported Direction enum and follows the MUD naming convention with the app__ prefix.

examples/mud/packages/contracts/src/codegen/index.sol (1)

1-6: Minimal and correct autogenerated entry point.

This file serves its purpose well as a centralized import hub for the Position table components. The implementation is minimal but appropriate for an autogenerated entry point.

examples/mud/packages/client/src/mud/useSyncStatus.ts (1)

7-21: Well-implemented React hook with good performance practices.

The hook demonstrates excellent React patterns:

  • Proper use of useRecord for reactive data subscription
  • Performance optimization with useMemo and correct dependency array
  • Clean API design combining raw progress data with computed isLive flag
  • Follows React hooks naming conventions

The implementation efficiently tracks sync progress and provides a convenient boolean flag for UI components to determine if sync is live.

examples/mud/packages/contracts/src/codegen/world/IWorld.sol (1)

1-16: LGTM! Autogenerated MUD interface follows standard patterns.

This autogenerated interface correctly composes the base world functionality with the move system interface. The documentation is comprehensive and the structure follows MUD framework conventions.

examples/mud/packages/client/tsconfig.json (1)

1-11: LGTM! Standard React + Vite + MUD TypeScript configuration.

The configuration properly extends the monorepo base config and includes all necessary compiler options for React development with Vite and MUD integration.

examples/mud/packages/contracts/test/WorldTest.t.sol (1)

7-16: LGTM! Simple but effective deployment verification test.

The test correctly uses inline assembly to verify that the world contract has been deployed by checking for non-zero code size. This is an appropriate and common pattern for deployment verification.

examples/mud/packages/contracts/mud.config.ts (1)

1-14: LGTM! Well-designed MUD world configuration for movement example.

The configuration appropriately defines:

  • A clear namespace ("app")
  • A complete Direction enum for movement
  • A properly structured Position table with address key and int32 coordinates

The data types and structure are suitable for a movement-based game example and follow MUD best practices.

examples/mud/packages/contracts/src/MoveSystem.sol (1)

9-26: LGTM! Clean MUD movement system implementation.

The movement logic is correct and follows MUD framework patterns properly. The use of _msgSender(), Position table operations, and Direction enum integration all look good.

Note: There's no bounds checking on coordinates, so players can move to negative positions or very large values. This may be intentional for an example project, but consider adding bounds if needed for your specific use case.

examples/mud/packages/client/tailwind.config.ts (1)

1-10: Excellent Tailwind configuration!

This is a well-structured Tailwind config with proper TypeScript typing. The hoverOnlyWhenSupported future flag is a nice touch for better touch device support, and the content paths are appropriately configured.

examples/mud/packages/client/src/game/useKeyboardMovement.ts (1)

11-26: Well-implemented keyboard movement hook!

This React hook follows excellent practices:

  • Proper event listener cleanup
  • Correct useEffect dependency array
  • Graceful handling of undefined move callback
  • Prevents default behavior to avoid unwanted page scrolling
  • Clean mapping of arrow keys to directions

The Direction type integration ensures consistency with the contract layer.

examples/mud/packages/contracts/.solhint.json (1)

1-12: Appropriate Solhint configuration for MUD development.

This configuration is well-tailored for the MUD framework:

  • Extends both recommended rules and MUD-specific linting
  • Sensible rule customizations that align with MUD patterns
  • Proper compiler version enforcement (>=0.8.0)
  • Allows necessary low-level operations that MUD may require
examples/mud/packages/client/package.json (1)

13-31: LGTM! Well-structured dependency configuration.

The dependency setup looks good with consistent @latticexyz package versions (2.2.21) and appropriate React/Vite tooling. The workspace reference to the contracts package correctly enables local development integration.

examples/mud/packages/contracts/foundry.toml (2)

1-23: Excellent Foundry configuration setup.

This configuration follows best practices:

  • Solidity 0.8.24 is a stable, secure version
  • Optimizer settings (3000 runs) are well-tuned for production
  • Filesystem permissions correctly handle pnpm workspace structure
  • Appropriate extra output files for ABI and bytecode generation

25-29: Network configurations look appropriate.

The garnet and redstone chain RPC URLs are correctly configured for the MUD ecosystem.

examples/mud/package.json (2)

4-12: Excellent monorepo script configuration.

The scripts provide a great developer experience:

  • Automated Foundry installation in prepare hook
  • Development orchestration with mprocs
  • Proper workspace filtering for packages
  • MUD version management utilities

27-30: Appropriate engine requirements.

Node 20+ and pnpm 9+ requirements are well-chosen for modern development with good stability and performance.

examples/mud/packages/contracts/script/PostDeploy.s.sol (1)

10-25: Well-structured Foundry script with proper security practices.

The script follows best practices:

  • Correct use of StoreSwitch for MUD table access
  • Environment variable for private key (secure)
  • Proper broadcast transaction handling
  • Clear imports and contract structure
examples/mud/packages/client/src/index.tsx (1)

1-19: Excellent React application setup.

The structure follows React best practices with StrictMode for development warnings, error boundaries for graceful error handling, and proper component composition.

examples/mud/packages/contracts/test/MoveTest.t.sol (1)

11-25: Well-structured movement test.

The test correctly verifies the movement system functionality:

  • Proper setup with test address generation using vm.addr
  • Correct use of vm.startPrank for impersonation
  • Clear assertions for initial and final positions
  • Follows MUD testing patterns
examples/mud/packages/client/src/mud/Explorer.tsx (1)

5-32: Clean component design with proper state management.

The Explorer component demonstrates good React patterns:

  • Proper state management with useState
  • Conditional rendering based on available configuration
  • Early return for missing explorer URL
  • Clean toggle functionality
🧰 Tools
🪛 Biome (1.9.4)

[error] 29-29: Provide a title attribute when using iframe elements.

Screen readers rely on the title set on an iframe to describe the content being displayed.

(lint/a11y/useIframeTitle)

examples/mud/packages/contracts/package.json (2)

6-17: Comprehensive script configuration.

The scripts provide excellent coverage for development workflows:

  • Build and clean operations
  • Multiple deployment profiles (garnet, local, redstone)
  • Integrated linting with prettier and solhint
  • Combined TypeScript and MUD testing

18-25:

✅ Verification successful

Verify MUD framework version is current.

All MUD dependencies are pinned to version 2.2.21. Ensure this is the latest stable version to benefit from recent improvements and security fixes.


🌐 Web query:

What is the latest version of @latticexyz/cli and other MUD framework packages?

💡 Result:

Based on the search results, I can provide you with information about the latest versions of @latticexyz/cli and other MUD framework packages.

The latest stable version of @latticexyz/cli is 2.2.21, which was published approximately 2 months ago as of June 2025[2]. There is also a development version 2.2.22-d2c77c206d94a00082a25939b786df04d8249fcb that appears in the search results[4][10], but this seems to be a pre-release version rather than a stable release.

For the broader MUD framework, the latest version information available is:

  1. @latticexyz/world: version 2.2.21, released on March 24, 2025[9]

  2. The MUD framework has had several recent releases, with the following version history:

    • Version 2.2.19: Released on February 6, 2025[1][6]
    • Version 2.2.16: Released on January 17, 2025[1][6]
    • Version 2.2.14: Released on October 24, 2024[6]
    • Version 2.2.7: Released on September 20, 2024[1]

The MUD framework itself appears to be actively maintained, with the most recent commit to the repository on May 30, 2025[9]. The framework includes several packages beyond just the CLI tool, such as:

  • @latticexyz/entrykit
  • @latticexyz/explorer
  • @latticexyz/store
  • @latticexyz/world
  • @latticexyz/stash

MUD is described as a "framework for ambitious Ethereum applications" that provides a composable foundation for EVM developers, handling data storage, upgrades, delegations, and data-sync with frontends[3][7][9].

Citations:


MUD dependencies are on the latest stable release (2.2.21).

Verification confirms that version 2.2.21 is the most recent stable version for all @latticexyz packages. No updates are required.

• File: examples/mud/packages/contracts/package.json (lines 18–25)

examples/mud/packages/client/src/Providers.tsx (1)

17-35: Well-structured provider composition with proper nesting order.

The component correctly sets up the blockchain integration stack with appropriate provider nesting. The configuration objects are properly passed to each provider.

examples/mud/mprocs.yaml (1)

1-21: Well-configured development workflow processes.

The mprocs configuration appropriately sets up all necessary development processes with proper working directories and environment variables.

🧰 Tools
🪛 Gitleaks (8.26.0)

15-15: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

examples/mud/packages/client/src/App.tsx (2)

12-26: Excellent React patterns with proper hook usage and memoization.

The component correctly uses hooks and memoizes the onMove callback with appropriate dependencies. The conditional logic ensures the callback is only available when both sync data and world contract are ready.


28-46: Clean and accessible UI structure.

The layout uses appropriate CSS classes and provides a good user experience with the fixed positioning for the account button and centered game area.

examples/mud/packages/client/src/ui/icons/MUDIcon.tsx (1)

4-6: Consistent component structure with proper TypeScript types.

The component follows the same pattern as other icon components in the codebase, using the same Props type definition and accepting all standard SVG attributes.

examples/mud/packages/client/src/ui/icons/ArrowDownIcon.tsx (1)

6-22: Well-implemented icon component with proper prop spreading.

The component follows React best practices with proper prop destructuring, className merging using tailwind-merge, and clean SVG implementation.

🧰 Tools
🪛 Biome (1.9.4)

[error] 8-14: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

examples/mud/packages/client/src/mud/Synced.tsx (1)

11-14: Clean and well-typed conditional rendering component.

The component correctly implements conditional rendering based on sync status with proper TypeScript typing for the fallback function. The use of optional chaining for the fallback ensures safe execution.

examples/mud/packages/client/src/wagmiConfig.ts (1)

7-49: Well-structured Wagmi configuration with appropriate chain and transport setup.

The configuration properly sets up multiple chains with appropriate transport protocols and polling intervals. The custom anvil chain configuration with paymaster and block explorer is well-implemented.

examples/mud/packages/client/src/mud/useWorldContract.ts (2)

21-42: Excellent caching strategy and error handling for contract instance.

The hook properly implements:

  • Conditional execution with dependency tracking via queryKey
  • Appropriate error throwing for missing clients
  • Infinite stale time to prevent unnecessary contract re-instantiation
  • Disabled refetch options for stable contract instances
  • Observer middleware extension for enhanced functionality
🧰 Tools
🪛 Biome (1.9.4)

[error] 37-37: Use Number.POSITIVE_INFINITY instead of the equivalent global.

ES2015 moved some globals into the Number namespace for consistency.
Safe fix: Use Number.POSITIVE_INFINITY instead.

(lint/style/useNumberNamespace)


9-17: Well-typed return type with proper generic constraints.

The complex return type correctly represents the contract instance with both public and wallet clients, providing full type safety for contract interactions.

examples/mud/packages/client/src/ui/AsyncButton.tsx (1)

15-29: The async click handler implementation looks correct.

The promise handling with ref comparison to prevent stale state updates is well implemented. The Promise.resolve(result) ensures both sync and async return values are handled consistently.

examples/mud/packages/client/src/common.ts (1)

11-11: Direction type alias implementation looks correct.

The type alias correctly extracts the Direction enum values from the MUD config, providing type safety for the client code.

examples/mud/packages/client/src/ui/ErrorFallback.tsx (1)

17-57: Error display and user experience implementation is well done.

The error message display with timestamp, stack trace, and retry functionality provides a good user experience. The retry limit prevents infinite retry loops.

examples/mud/packages/client/src/game/GameMap.tsx (2)

35-102: Well-structured component with good separation of concerns.

The component effectively separates rendering logic, event handling, and conditional UI states. The integration with keyboard movement and account management is well implemented.

🧰 Tools
🪛 Biome (1.9.4)

[error] 45-55: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


[error] 90-94: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)


69-71:

❓ Verification inconclusive

Verify coordinate calculation logic for edge cases.

The coordinate calculations use complex modulo operations for wrapping. Consider verifying the behavior with negative coordinates and edge cases:

left: `${((((player.x + size / 2) % size) + size) % size) * scale}%`,
top: `${((size - ((player.y + size / 2) % size)) % size) * scale}%`,

🏁 Script executed:

#!/bin/bash
# Description: Check if there are any tests for coordinate calculations
# Expected: Find test files that verify coordinate wrapping behavior

# Search for tests related to GameMap or coordinate calculations
rg -i "gameMap|coordinate|position.*test" --type ts --type tsx

Length of output: 92


Add unit tests for coordinate wrapping logic

To ensure the modulo-based wrapping in GameMap handles negative and boundary values correctly, please add targeted tests covering edge cases for both left and top computations:

File: examples/mud/packages/client/src/game/GameMap.tsx
Lines: 69–71

- left: `${((((player.x + size / 2) % size) + size) % size) * scale}%`,
- top:  `${((size - ((player.y + size / 2) % size)) % size) * scale}%`,

Suggested test scenarios:

  • Player at exactly -size/2, 0, size/2, size - 1
  • Negative coordinates beyond one wrap (e.g. -size - 1)
  • Coordinates exceeding size by one wrap (e.g. size + 1)
  • Varying scale values (e.g. 0.5, 1, 2)

Cover both axes to confirm the wrapping yields the correct percentage positions.

CLAUDE.md (1)

18-341: Excellent comprehensive documentation additions.

The expanded documentation provides thorough coverage of Tevm's architecture, features, and usage patterns. The code examples are well-structured and demonstrate practical implementations including:

  • Core architecture components (EVM, Blockchain, StateManager, etc.)
  • API conventions (Ethereumjs vs Viem)
  • JSON-RPC support with real examples
  • Bundler integration for direct Solidity imports
  • Low-level VM access patterns

The examples appear syntactically correct and follow established patterns for the respective libraries.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

59-59: Spaces inside emphasis markers
null

(MD037, no-space-in-emphasis)

examples/mud/packages/contracts/src/codegen/tables/Position.sol (1)

1-318: Well-structured autogenerated table library.

This autogenerated Position library follows MUD framework conventions correctly and provides comprehensive functionality:

Strengths:

  • Proper resource ID encoding with namespace "app" and table name "Position"
  • Comprehensive field layout and schema definitions
  • Dual API support (StoreSwitch vs StoreCore)
  • Type-safe encoding/decoding functions
  • Complete CRUD operations

Architecture:

  • Uses int32 for coordinates, which supports positions from -2.1B to +2.1B
  • Address-based keying allows per-player position tracking
  • Follows MUD's static field patterns for gas efficiency

The implementation appears correct for the intended use case of tracking player positions in a game world.

examples/mud/packages/contracts/out/IWorld.sol/IWorld.abi.json (2)

1-2021: Comprehensive and well-structured World contract ABI.

This ABI defines a complete interface for a MUD World contract with excellent coverage:

Key Features:

  • Game Logic: app__move function for player movement
  • Store Operations: Complete CRUD operations for table data
  • System Management: Registration and lifecycle functions
  • Access Control: Permission management and delegation
  • Batch Operations: Efficient multi-call functionality
  • Events & Errors: Comprehensive event logging and error handling

Security Considerations:

  • Proper access control with grantAccess/revokeAccess functions
  • Delegation system with controls and limits
  • Resource-based permissions model
  • Owner-based namespace management

The interface appears complete and follows MUD framework patterns correctly.


3-14: Core game function properly defined.

The app__move function signature correctly accepts a Direction enum parameter and has no return value, which is appropriate for a state-changing game action.

Comment on lines +266 to +267
for (0..Stack.capacity) |i| {
try stack.push(@as(u256, i));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Handle potential stack overflow in stress test.

The stress test fills the stack to capacity but should handle the case where Stack.capacity might not be defined or the push operations might fail.

     // Fill to capacity
     timer.reset();
-    for (0..Stack.capacity) |i| {
-        try stack.push(@as(u256, i));
-    }
+    var filled: usize = 0;
+    for (0..Stack.capacity) |i| {
+        stack.push(@as(u256, i)) catch break;
+        filled += 1;
+    }
     const fill_ns = timer.read();
     
     // Verify full
-    std.debug.print("Filled to capacity: {} items\n", .{stack.len()});
+    std.debug.print("Filled to capacity: {} items\n", .{filled});
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for (0..Stack.capacity) |i| {
try stack.push(@as(u256, i));
// Fill to capacity
timer.reset();
var filled: usize = 0;
for (0..Stack.capacity) |i| {
stack.push(@as(u256, i)) catch break;
filled += 1;
}
const fill_ns = timer.read();
// Verify full
std.debug.print("Filled to capacity: {} items\n", .{filled});
🤖 Prompt for AI Agents
In test/Bench/stack_benchmark.zig around lines 266 to 267, the loop pushes
values up to Stack.capacity without checking if Stack.capacity is defined or if
push operations fail. Modify the code to first verify that Stack.capacity is
defined or has a valid value before the loop. Then, handle potential errors from
stack.push by using try or a conditional check to gracefully handle push
failures, ensuring the stress test does not panic unexpectedly.

Comment on lines +50 to +89
pub fn benchmarkSwap(self: *StackBenchmark) !void {
var stack = Stack{};

// Fill stack
for (0..20) |j| {
stack.push_unsafe(@as(u256, j));
}

// Benchmark swap1
self.timer.reset();
var i: usize = 0;
while (i < iterations) : (i += 1) {
stack.swapN_unsafe(1);
}
var elapsed_ns = self.timer.read();

var ops_per_sec = (@as(f64, iterations) * 1_000_000_000) / @as(f64, elapsed_ns);
var ns_per_op = @as(f64, elapsed_ns) / @as(f64, iterations);

std.debug.print("\nSwap1 Performance:\n", .{});
std.debug.print(" Operations: {d:.2} million ops/sec\n", .{ops_per_sec / 1_000_000});
std.debug.print(" Latency: {d:.2} ns/op\n", .{ns_per_op});
std.debug.print(" Target: >400M ops/sec ✓\n", .{});

// Benchmark swap16
self.timer.reset();
i = 0;
while (i < iterations) : (i += 1) {
stack.swapN_unsafe(16);
}
elapsed_ns = self.timer.read();

ops_per_sec = (@as(f64, iterations) * 1_000_000_000) / @as(f64, elapsed_ns);
ns_per_op = @as(f64, elapsed_ns) / @as(f64, iterations);

std.debug.print("\nSwap16 Performance:\n", .{});
std.debug.print(" Operations: {d:.2} million ops/sec\n", .{ops_per_sec / 1_000_000});
std.debug.print(" Latency: {d:.2} ns/op\n", .{ns_per_op});
std.debug.print(" Target: >300M ops/sec ✓\n", .{});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify Stack method names and consider edge cases.

The benchmark calls swapN_unsafe(1) and swapN_unsafe(16), but ensure these method names match the actual Stack implementation. Also consider testing edge cases like swapping at stack boundaries.


🏁 Script executed:

#!/bin/bash
# Search for Stack swap method definitions
echo "=== Searching for Stack swap methods ==="
ast-grep --pattern 'fn swapN_unsafe($$$) $$$'
ast-grep --pattern 'fn swap$_($$$) $$$'
rg -A 3 "fn.*swap.*unsafe" --type zig

Length of output: 720


Fix incorrect method names and add boundary tests

The benchmark is calling swapN_unsafe(...), but the actual Zig API uses snake_case:

• Replace swapN_unsafe(…) with swap_n_unsafe(…)
• Example diff in test/Bench/stack_benchmark.zig:

@@ pub fn benchmarkSwap(self: *StackBenchmark) !void {
-        while (i < iterations) : (i += 1) {
-            stack.swapN_unsafe(1);
+        while (i < iterations) : (i += 1) {
+            stack.swap_n_unsafe(1);
@@
-        while (i < iterations) : (i += 1) {
-            stack.swapN_unsafe(16);
+        while (i < iterations) : (i += 1) {
+            stack.swap_n_unsafe(16);

Consider also adding edge‐case benchmarks:

  • Dynamic swap_unsafe(n) with out-of-bounds n to exercise the Error!void path
  • Compile‐time swaps at the extreme valid boundary (e.g. swap_n_unsafe( size - 1 ))

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In test/Bench/stack_benchmark.zig between lines 50 and 89, the benchmark calls
the method swapN_unsafe which does not match the actual Stack API naming
convention. Rename all calls from swapN_unsafe to swap_n_unsafe to align with
the snake_case method names. Additionally, add new benchmark tests to cover edge
cases such as calling swap_n_unsafe with out-of-bounds indices to trigger error
paths and compile-time swaps at the maximum valid index (size - 1) to ensure
boundary conditions are tested.

Comment on lines +248 to +252
std.debug.print("Stack size: {} bytes (32KB)\n", .{@sizeOf(Stack)});
std.debug.print("Alignment: {} bytes\n", .{@alignOf(Stack)});
std.debug.print("revm: Dynamic Vec<U256> with variable memory\n", .{});
std.debug.print("evmone: std::vector<uint256> with aligned allocation\n", .{});
std.debug.print("Tevm: Fixed 32KB with guaranteed alignment ✓\n", .{});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify Stack.capacity constant and memory calculations.

The code references Stack.capacity and uses @sizeOf(Stack) without verifying these exist. Ensure the Stack implementation defines these constants.


🏁 Script executed:

#!/bin/bash
# Search for Stack capacity definition and size information
echo "=== Searching for Stack capacity and size definitions ==="
rg -A 2 -B 2 "capacity.*=" --type zig src/
ast-grep --pattern 'const capacity = $_'
ast-grep --pattern 'pub const capacity = $_'

Length of output: 1288


🏁 Script executed:

#!/bin/bash
echo "=== Searching for 'struct Stack' across the repository ==="
rg -n -C3 "struct Stack" -t zig

echo
echo "=== Listing Zig files matching '*stack*.zig' ==="
find . -type f -iname "*stack*.zig"

echo
echo "=== Inspecting each Stack-related file for a 'capacity' definition ==="
for file in $(find . -type f -iname "*stack*.zig"); do
    echo "----> $file"
    rg -n "capacity" "$file" || echo "    ❌ No capacity definition found in $file"
done

Length of output: 1553


Define Stack.capacity constant in src/evm/stack.zig

The Stack struct doesn’t currently expose a capacity constant, so references like Stack.capacity in your benchmark will fail to compile. Add an explicit constant that matches your intended maximum depth (e.g. 1024) to the struct:

  • File: src/evm/stack.zig
    Insert inside the pub const Stack = struct { … } block:
--- a/src/evm/stack.zig
+++ b/src/evm/stack.zig
@@ pub const Stack = struct {
     // existing fields...
+    /// Maximum number of stack elements (matches the comment above)
+    pub const capacity: usize = 1024;
     // existing methods…
 }

This will satisfy all uses of Stack.capacity in test/Bench/stack_benchmark.zig while @sizeOf(Stack) and @alignOf(Stack) continue to work as builtins.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
std.debug.print("Stack size: {} bytes (32KB)\n", .{@sizeOf(Stack)});
std.debug.print("Alignment: {} bytes\n", .{@alignOf(Stack)});
std.debug.print("revm: Dynamic Vec<U256> with variable memory\n", .{});
std.debug.print("evmone: std::vector<uint256> with aligned allocation\n", .{});
std.debug.print("Tevm: Fixed 32KB with guaranteed alignment ✓\n", .{});
// File: src/evm/stack.zig
pub const Stack = struct {
// existing fields...
/// Maximum number of stack elements (matches the comment above)
pub const capacity: usize = 1024;
// existing methods…
}
🤖 Prompt for AI Agents
In src/evm/stack.zig inside the pub const Stack struct (not shown in the
snippet), define a new constant named capacity with the intended maximum stack
depth value (e.g., 1024). This will ensure that references to Stack.capacity in
test/Bench/stack_benchmark.zig compile correctly. Keep the existing
@sizeOf(Stack) and @alignOf(Stack) usages unchanged, as they are built-in
functions and do not require modification.

Comment on lines +1 to +7
{
"extends": ["../../.eslintrc", "plugin:react/recommended", "plugin:react-hooks/recommended"],
"plugins": ["react", "react-hooks"],
"rules": {
"react/react-in-jsx-scope": "off"
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add TypeScript ESLint parser and plugin for TS files
Since the client is a TypeScript React project, extending plugin:@typescript-eslint/recommended and specifying the @typescript-eslint/parser will enforce TS-specific lint rules.

Proposed diff:

 {
-  "extends": ["../../.eslintrc", "plugin:react/recommended", "plugin:react-hooks/recommended"],
-  "plugins": ["react", "react-hooks"],
+  "extends": [
+    "../../.eslintrc",
+    "plugin:react/recommended",
+    "plugin:react-hooks/recommended",
+    "plugin:@typescript-eslint/recommended"
+  ],
+  "parser": "@typescript-eslint/parser",
+  "plugins": ["react", "react-hooks", "@typescript-eslint"],
   "rules": {
     "react/react-in-jsx-scope": "off"
   }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{
"extends": ["../../.eslintrc", "plugin:react/recommended", "plugin:react-hooks/recommended"],
"plugins": ["react", "react-hooks"],
"rules": {
"react/react-in-jsx-scope": "off"
}
}
{
"extends": [
"../../.eslintrc",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": ["react", "react-hooks", "@typescript-eslint"],
"rules": {
"react/react-in-jsx-scope": "off"
}
}
🤖 Prompt for AI Agents
In examples/mud/packages/client/.eslintrc lines 1 to 7, the ESLint config lacks
TypeScript support which is essential for a TypeScript React project. Add
"@typescript-eslint/parser" as the parser and include
"plugin:@typescript-eslint/recommended" in the extends array. Also add
"@typescript-eslint" to the plugins array to enable TypeScript-specific linting
rules.

</>
)}
</button>
{open ? <iframe src={`${explorerUrl}/${worldAddress}`} className="bg-black h-[50vh]" /> : null}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add title attribute to iframe for accessibility.

The iframe is missing a title attribute, which is essential for screen readers to describe the content being displayed.

Apply this fix to improve accessibility:

-{open ? <iframe src={`${explorerUrl}/${worldAddress}`} className="bg-black h-[50vh]" /> : null}
+{open ? <iframe src={`${explorerUrl}/${worldAddress}`} title="Blockchain Explorer" className="bg-black h-[50vh]" /> : null}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{open ? <iframe src={`${explorerUrl}/${worldAddress}`} className="bg-black h-[50vh]" /> : null}
{open ? <iframe
src={`${explorerUrl}/${worldAddress}`}
title="Blockchain Explorer"
className="bg-black h-[50vh]"
/> : null}
🧰 Tools
🪛 Biome (1.9.4)

[error] 29-29: Provide a title attribute when using iframe elements.

Screen readers rely on the title set on an iframe to describe the content being displayed.

(lint/a11y/useIframeTitle)

🤖 Prompt for AI Agents
In examples/mud/packages/client/src/mud/Explorer.tsx at line 29, the iframe
element lacks a title attribute, which is important for accessibility to help
screen readers describe the iframe content. Add a descriptive title attribute to
the iframe tag, such as title="Explorer view" or another relevant description,
to improve accessibility compliance.

Comment on lines +8 to +14
<svg
className={twMerge("h-[1em] w-[1em]", className)}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
{...props}
>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add accessibility support to the SVG icon.

The SVG lacks alternative text, which impacts accessibility for screen readers.

Apply this diff to add proper accessibility attributes:

     <svg
       className={twMerge("h-[1em] w-[1em]", className)}
       xmlns="http://www.w3.org/2000/svg"
       viewBox="0 0 16 16"
       fill="currentColor"
+      role="img"
+      aria-label="Arrow down"
       {...props}
     >

Alternatively, if the icon is purely decorative, add aria-hidden="true":

     <svg
       className={twMerge("h-[1em] w-[1em]", className)}
       xmlns="http://www.w3.org/2000/svg"
       viewBox="0 0 16 16"
       fill="currentColor"
+      aria-hidden="true"
       {...props}
     >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<svg
className={twMerge("h-[1em] w-[1em]", className)}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
{...props}
>
<svg
className={twMerge("h-[1em] w-[1em]", className)}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
role="img"
aria-label="Arrow down"
{...props}
>
🧰 Tools
🪛 Biome (1.9.4)

[error] 8-14: Alternative text title element cannot be empty

For accessibility purposes, SVGs should have an alternative text, provided via title element. If the svg element has role="img", you should add the aria-label or aria-labelledby attribute.

(lint/a11y/noSvgWithoutTitle)

🤖 Prompt for AI Agents
In examples/mud/packages/client/src/ui/icons/ArrowDownIcon.tsx around lines 8 to
14, the SVG element lacks accessibility attributes. To fix this, add appropriate
accessibility support by either including a descriptive aria-label or role="img"
with a title element for screen readers, or if the icon is purely decorative,
add aria-hidden="true" to the SVG element to hide it from assistive
technologies.

import { chains } from "./wagmiConfig";
import { Chain } from "viem";

export const chainId = import.meta.env.CHAIN_ID;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add type validation for chainId to prevent runtime errors.

The chainId could be undefined or invalid, which would cause getChain() to fail. Consider adding validation:

-export const chainId = import.meta.env.CHAIN_ID;
+export const chainId = import.meta.env.CHAIN_ID;
+
+if (!chainId) {
+  throw new Error("CHAIN_ID environment variable is required");
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const chainId = import.meta.env.CHAIN_ID;
export const chainId = import.meta.env.CHAIN_ID;
if (!chainId) {
throw new Error("CHAIN_ID environment variable is required");
}
🤖 Prompt for AI Agents
In examples/mud/packages/client/src/common.ts at line 5, the exported chainId is
assigned directly from an environment variable without validation, which can
lead to runtime errors if it is undefined or invalid. Add type validation to
check if chainId exists and is of the expected type (e.g., a string or number),
and handle the case where it is missing or invalid by throwing an error or
providing a default value to prevent failures in getChain().

Comment on lines +20 to +26
export function getChain(): Chain {
const chain = chains.find((c) => c.id === chainId);
if (!chain) {
throw new Error(`No chain configured for chain ID ${chainId}.`);
}
return chain;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify chainId type compatibility with chain.id comparison.

Ensure that the environment variable chainId type matches the chain.id type used in the comparison. Environment variables are typically strings, but chain IDs might be numbers.


🏁 Script executed:

#!/bin/bash
# Description: Check the types used for chain ID in the codebase
# Expected: Verify chainId types are consistent across files

# Find chain ID usages and types
rg -A 3 -B 3 "chain.*\.id|chainId|CHAIN_ID" --type ts --type tsx

Length of output: 94


🏁 Script executed:

#!/bin/bash
# Search for chainId declarations and imports in TypeScript files
rg -n "chainId" --glob "*.ts" --glob "*.tsx"

# Search for environment variable usage of CHAIN_ID
rg -n "process\.env\.CHAIN_ID" --glob "*.ts" --glob "*.tsx"

Length of output: 16588


Convert CHAIN_ID env var to a number before comparing to Chain.id

The chain.id property is a number, but import.meta.env.CHAIN_ID is always a string. Update the chainId export in examples/mud/packages/client/src/common.ts to parse and validate the value so that getChain() can correctly match by number:

• File: examples/mud/packages/client/src/common.ts
• Location: replace the export const chainId line

-export const chainId = import.meta.env.CHAIN_ID;
+const rawChainId = import.meta.env.CHAIN_ID;
+const parsedChainId = Number(rawChainId);
+if (Number.isNaN(parsedChainId)) {
+  throw new Error(`Invalid CHAIN_ID environment variable: "${rawChainId}"`);
+}
+export const chainId: Chain['id'] = parsedChainId;

This ensures chain.id === chainId is comparing two numbers, avoiding silent mismatches at runtime.

🤖 Prompt for AI Agents
In examples/mud/packages/client/src/common.ts around lines 20 to 26, the chainId
used for comparison with chain.id is currently a string from the environment
variable, while chain.id is a number. To fix this, update the export of chainId
to parse the environment variable as a number and validate it before use. This
ensures the comparison in getChain() is between two numbers, preventing runtime
mismatches.

Comment on lines +90 to +96
<button
className="group outline-0 p-4 border-4 border-green-400 transition ring-green-300 hover:ring-4 active:scale-95 rounded-lg text-lg font-medium aria-busy:pointer-events-none aria-busy:animate-pulse"
onClick={openAccountModal}
>
Sign in to play
</button>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add explicit button type for consistency.

Similar to the movement buttons, this button should have an explicit type:

   <button
+    type="button"
     className="group outline-0 p-4 border-4 border-green-400 transition ring-green-300 hover:ring-4 active:scale-95 rounded-lg text-lg font-medium aria-busy:pointer-events-none aria-busy:animate-pulse"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<button
className="group outline-0 p-4 border-4 border-green-400 transition ring-green-300 hover:ring-4 active:scale-95 rounded-lg text-lg font-medium aria-busy:pointer-events-none aria-busy:animate-pulse"
onClick={openAccountModal}
>
Sign in to play
</button>
</div>
<button
type="button"
className="group outline-0 p-4 border-4 border-green-400 transition ring-green-300 hover:ring-4 active:scale-95 rounded-lg text-lg font-medium aria-busy:pointer-events-none aria-busy:animate-pulse"
onClick={openAccountModal}
>
Sign in to play
</button>
🧰 Tools
🪛 Biome (1.9.4)

[error] 90-94: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)

🤖 Prompt for AI Agents
In examples/mud/packages/client/src/game/GameMap.tsx around lines 90 to 96, the
button element lacks an explicit type attribute, which can cause inconsistent
behavior across browsers. Add type="button" to the button element to explicitly
define its behavior and maintain consistency with other buttons in the codebase.

Comment on lines +44 to +58
? mudConfig.enums.Direction.map((direction) => (
<button
key={direction}
title={`Move ${direction.toLowerCase()}`}
className={twMerge(
"outline-0 absolute inset-0 cursor-pointer grid p-4",
rotateClassName[direction],
"transition bg-gradient-to-t from-transparent via-transparent to-blue-50 text-blue-400 opacity-0 hover:opacity-40 active:opacity-100",
)}
style={{ clipPath: "polygon(0% 0%, 100% 0%, 50% 50%)" }}
onClick={() => onMove(direction)}
>
<ArrowDownIcon className="rotate-180 text-4xl self-start justify-self-center" />
</button>
))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add explicit button type to prevent form submission.

The static analysis correctly identifies missing type attribute. Buttons default to type="submit" which can cause unintended form submissions.

   <button
+    type="button"
     key={direction}
     title={`Move ${direction.toLowerCase()}`}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
? mudConfig.enums.Direction.map((direction) => (
<button
key={direction}
title={`Move ${direction.toLowerCase()}`}
className={twMerge(
"outline-0 absolute inset-0 cursor-pointer grid p-4",
rotateClassName[direction],
"transition bg-gradient-to-t from-transparent via-transparent to-blue-50 text-blue-400 opacity-0 hover:opacity-40 active:opacity-100",
)}
style={{ clipPath: "polygon(0% 0%, 100% 0%, 50% 50%)" }}
onClick={() => onMove(direction)}
>
<ArrowDownIcon className="rotate-180 text-4xl self-start justify-self-center" />
</button>
))
? mudConfig.enums.Direction.map((direction) => (
<button
+ type="button"
key={direction}
title={`Move ${direction.toLowerCase()}`}
className={twMerge(
"outline-0 absolute inset-0 cursor-pointer grid p-4",
rotateClassName[direction],
"transition bg-gradient-to-t from-transparent via-transparent to-blue-50 text-blue-400 opacity-0 hover:opacity-40 active:opacity-100",
)}
style={{ clipPath: "polygon(0% 0%, 100% 0%, 50% 50%)" }}
onClick={() => onMove(direction)}
>
<ArrowDownIcon className="rotate-180 text-4xl self-start justify-self-center" />
</button>
))
🧰 Tools
🪛 Biome (1.9.4)

[error] 45-55: Provide an explicit type prop for the button element.

The default type of a button is submit, which causes the submission of a form when placed inside a form element. This is likely not the behaviour that you want inside a React application.
Allowed button types are: submit, button or reset

(lint/a11y/useButtonType)

🤖 Prompt for AI Agents
In examples/mud/packages/client/src/game/GameMap.tsx around lines 44 to 58, the
button elements lack an explicit type attribute, causing them to default to
type="submit" and potentially trigger unintended form submissions. Add
type="button" to each button element to explicitly specify their behavior and
prevent accidental form submissions.

@0xpolarzero
Copy link
Collaborator Author

@roninjin10 What can we do about that? MUD doesn't support node >20 and afaik it has bugs with pnpm >9.
image

Copy link
Collaborator

@roninjin10 roninjin10 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this pr still being worked on or are some of the other prs meant to replace this?

@0xpolarzero
Copy link
Collaborator Author

Is this pr still being worked on or are some of the other prs meant to replace this?

This one is just the mud react template to demonstrate optimistic updates.

Just need to figure out how to use a different pnpm version during ci, I can actually look into it #1730 (comment)

@roninjin10
Copy link
Collaborator

Don't use a different pnpm version. @claude can you fix the mud example package.json to not have engines field?

@claude
Copy link
Contributor

claude bot commented Jun 15, 2025

Claude finished @roninjin10's task —— View job


Fixing MUD Example Package.json Engines Field

I successfully removed the engines field from the MUD example package.json files to resolve the pnpm version compatibility issues.

Tasks:

  • Read MUD example package.json files to identify engines fields
  • Remove engines field from main examples/mud/package.json if present
  • Remove engines field from client package.json if present
  • Remove engines field from contracts package.json if present
  • Commit the changes to the PR branch

Analysis Complete:

  • examples/mud/package.json: ✅ Found and removed engines field with "node": "^20", "pnpm": "^9"
  • examples/mud/packages/client/package.json: ✅ No engines field present
  • examples/mud/packages/contracts/package.json: ✅ No engines field present

Changes Made:

Removed engines field from examples/mud/package.json that was constraining:

  • Node.js to ^20
  • pnpm to ^9

This change allows the MUD example to build successfully with the current CI environment versions without requiring specific pnpm/Node.js version constraints.

Commit: 17a6320


Remove the engines constraint for node ^20 and pnpm ^9 to avoid version
compatibility issues during CI. This allows the build to succeed with
the current environment versions.

Co-authored-by: Will Cory <[email protected]>
@vercel vercel bot temporarily deployed to Preview – node June 15, 2025 09:07 Inactive
@0xpolarzero
Copy link
Collaborator Author

Maybe pnpm 10 is fine but MUD will fail to deploy contracts with node >20 tho.

@roninjin10
Copy link
Collaborator

What error happens if you have a more recent node?

@0xpolarzero
Copy link
Collaborator Author

What error happens if you have a more recent node?

This: latticexyz/mud#3389

@roninjin10
Copy link
Collaborator

Let’s just fix mud

@roninjin10
Copy link
Collaborator

@0xpolarzero did fix here latticexyz/mud#3739

@claude
Copy link
Contributor

claude bot commented Jun 23, 2025

Claude finished @0xpolarzero's task —— View job


PR Review: MUD Example Project

This PR adds a comprehensive MUD (Autonomous Worlds Framework) example project to demonstrate Tevm integration. Here's my detailed analysis:

Review Summary:

  • Read repository guidelines and setup (CLAUDE.md)
  • Review MUD example project structure and configuration
  • Examine React/TypeScript client code quality
  • Review Solidity smart contracts and tests
  • Check Zig EVM-related additions
  • Assess security practices and potential vulnerabilities
  • Evaluate test coverage
  • Provide comprehensive feedback and recommendations

🎯 Overall Assessment

Status: ✅ Recommended for approval with minor fixes

This PR successfully adds a well-structured MUD example that demonstrates onchain game mechanics with React frontend integration. The codebase follows MUD framework conventions and integrates properly with Tevm.

🔍 Detailed Findings

MUD Project Structure & Configuration (✅ Excellent)

  • Monorepo Setup: Proper pnpm workspace with client and contracts packages
  • MUD Configuration: Clean world definition with Direction enum and Position table
  • Dependencies: All MUD packages consistently use version 2.2.21 (latest stable)
  • Build System: Comprehensive scripts for development, deployment, and testing

React/TypeScript Client Code (✅ Good with minor issues)

Strengths:

  • Clean component architecture with proper separation of concerns
  • Good use of React hooks (useRecords, useSync, useWorldContract)
  • Type-safe integration with MUD config via TypeScript
  • Proper keyboard event handling with cleanup
  • Responsive UI with Tailwind CSS

Issues Found:

  1. Missing Button Types (examples/mud/packages/client/src/game/GameMap.tsx:45, 90):

    // Missing type="button" attribute
    <button onClick={() => onMove(direction)}>
  2. Environment Variable Validation (examples/mud/packages/client/src/common.ts:5):

    // chainId could be undefined causing runtime errors
    export const chainId = import.meta.env.CHAIN_ID;
  3. Error Handling (examples/mud/packages/client/src/App.tsx:21):

    // indexOf could return -1 causing invalid contract calls
    mudConfig.enums.Direction.indexOf(direction)
  4. Accessibility Issues: SVG icons missing title attributes or aria-label

Solidity Smart Contracts (✅ Good)

Strengths:

  • Simple, well-structured MoveSystem with clear logic
  • Proper use of MUD framework patterns (System, Position table)
  • Clean separation of concerns
  • Uses _msgSender() for sender identification

Observations:

  • No bounds checking on coordinates (intentional for infinite world?)
  • No access control (players can move freely)
  • Basic functionality appropriate for example/demo

Testing Coverage (⚠️ Needs Improvement)

Existing Tests:

  • ✅ Basic movement test in MoveTest.t.sol
  • ✅ World deployment verification in WorldTest.t.sol
  • ✅ TypeScript compilation check via tsc --noEmit

Missing Tests:

  • ❌ No React component tests
  • ❌ No integration tests for client-contract interaction
  • ❌ No edge case testing (boundary values, error scenarios)

Security Analysis (✅ Good for Development)

Development Security:

  • ✅ Uses well-known Anvil test private key (safe for development)
  • ✅ Proper environment variable handling for sensitive data
  • ✅ No hardcoded secrets in production code

Smart Contract Security:

  • ✅ No obvious vulnerabilities in simple move logic
  • ℹ️ No access control (acceptable for open game mechanics)
  • ℹ️ No reentrancy concerns (state-only operations)

Zig EVM Additions (✅ High Quality)

Stack Benchmark Suite:

  • ✅ Comprehensive performance testing with realistic targets
  • ✅ Proper warmup and measurement methodology
  • ✅ Stress testing for edge cases
  • ✅ Good documentation and clear performance goals

EVM Constants Module:

  • ✅ Well-organized utility functions with examples
  • ✅ Proper hardfork validation patterns
  • ✅ Comprehensive test coverage

🔧 Required Fixes

  1. Remove Duplicate Import (packages/actions/src/Mine/mineHandler.spec.ts:9):

    - import { setAccountHandler } from '../SetAccount/setAccountHandler.js'
  2. Add Button Types (Multiple locations in GameMap.tsx):

    + type="button"
  3. Environment Variable Validation (examples/mud/packages/client/src/common.ts):

    const rawChainId = import.meta.env.CHAIN_ID;
    if (!rawChainId) throw new Error("CHAIN_ID required");
    export const chainId = Number(rawChainId);

💡 Recommendations

  1. Add Test Suite: Consider adding React Testing Library tests for key components
  2. Error Boundaries: The existing error boundary is good, consider more granular error handling
  3. Performance: The coordinate wrapping logic in GameMap could benefit from unit tests
  4. Documentation: Consider adding a README.md for the MUD example with setup instructions

🏆 Excellent Practices Observed

  • ✅ Consistent code formatting and linting setup
  • ✅ Proper TypeScript configuration across packages
  • ✅ Good separation of client and contracts concerns
  • ✅ Comprehensive development tooling (mprocs, explorer, etc.)
  • ✅ Following MUD framework conventions properly
  • ✅ High-quality Zig benchmarking code

🎯 Conclusion

This PR successfully demonstrates MUD integration with Tevm and provides a solid foundation for onchain game development. The issues found are minor and easily addressable. The codebase shows good understanding of both MUD patterns and React best practices.

Verdict: Approve with minor fixes


Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 17a6320 and 88f0ece.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (1)
  • CLAUDE.md (2 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
CLAUDE.md

59-59: Spaces inside emphasis markers
null

(MD037, no-space-in-emphasis)

🔇 Additional comments (1)
CLAUDE.md (1)

26-31: Content looks great—clear rationale for JS usage
This “### Why JavaScript for Ethereum?” section succinctly captures the benefits. No changes required here.

Comment on lines +115 to +119
#### Common JSON-RPC Methods

```typescript
// Using with Viem client interface
const client = createMemoryClient();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Make the example snippet self-contained
The code block jumps straight into usage without showing required imports. For copy-paste clarity, add at least:

import { createMemoryClient } from "tevm";

above the comment and instantiation.

🤖 Prompt for AI Agents
In CLAUDE.md around lines 115 to 119, the example snippet using
createMemoryClient lacks the necessary import statement, making it incomplete
for users to copy and run directly. Add the import line 'import {
createMemoryClient } from "tevm";' above the existing comment and client
instantiation to make the snippet self-contained and clear.

Comment on lines +18 to +24
### Key Features

- **Forking:** Fork from any EVM-compatible network (mainnet, testnet) with efficient caching
- **Transaction Pool:** Track and manage pending transactions locally
- **Flexible Mining:** Choose between automatic, interval-based, manual, or gas-limit-based mining
- **Zero Native Dependencies:** Works seamlessly in browsers and JavaScript runtimes
- **Highly Extensible:** Customize the VM, add precompiles, handle receipts, and more
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consolidate and standardize feature sections
The new “### Key Features” section overlaps with the earlier “Unique Features:” list and uses a different heading/bold style and colon usage. Recommend merging these into one “### Features” section (or similar), using consistent Markdown headings and uniform bullet formatting (e.g., all bullets with - **Title**:).

🤖 Prompt for AI Agents
In CLAUDE.md around lines 18 to 24, the "### Key Features" section duplicates
content from the earlier "**Unique Features:**" list and uses inconsistent
heading and bullet styles. Merge these two sections into a single "### Features"
section, standardizing the Markdown heading and formatting all bullet points
uniformly with the pattern "- **Title**:" for clarity and consistency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants