MUD Framework Documentation

repository·main·Indexed 21 days ago

https://github.com/latticexyz/mud

An onchain framework for Ethereum developers providing a composable foundation for data storage, upgrades, delegations, and frontend data synchronization. The ecosystem includes tools like create-mud for scaffolding, @latticexyz/dev-tools for data exploration, World Explorer for state manipulation, and utilities for ABI-to-TypeScript generation and blockchain event log streaming via @latticexyz/block-logs-stream.

Tokens
182.8K
Snippets
543
Records
800
Agent score
74%

What's inside MUD

  1. What is MUD?

    main

    MUD is a framework designed for building ambitious onchain applications on Ethereum. It provides a tightly integrated software stack that reduces the complexity of managing onchain state and synchronizing it with frontends.

    Key features include:

    • Standardized Data Model: Uses tables and fields for onchain storage.
    • Automatic Indexer: Provides an indexer out-of-the-box without requiring manual event handlers or custom backend logic.
    • Synchronized Client Libraries: Clients automatically handle fetching onchain state and keeping the frontend in sync with the chain.
    • Autonomous Worlds: Designed to be infinitely extendable with built-in access control, upgradability, hooks, and plugins.
    • Maximally Onchain: The entire application state resides in the EVM; clients only require access to an Ethereum Node.
  2. What is Stash?

    main

    Stash is a client state library optimized for the MUD data model. It uses a MUD store configuration to define local tables that support reading, writing, and subscribing to updates.

    Key features include:

    • ECS-style queries: An optimized query engine similar to @latticexyz/recs.
    • Composite Key Support: Native support for queries and lookups using composite keys.
  3. Understand the Vanilla template file structure

    main

    The vanilla template consists of onchain code (smart contracts) and offchain code (the web client). The primary files you will modify in the offchain client are:

    • packages/client/index.html: Controls the UI and information displayed to the user.
    • packages/client/src/index.ts: The main setup file where you register handlers for component updates.
    • packages/client/src/mud/createSystemCalls.ts: The location for writing logic that performs calls to onchain systems.
  4. Retrieve blockchain event logs with @latticexyz/block-logs-stream

    main

    The @latticexyz/block-logs-stream package provides utilities for efficiently retrieving blockchain event logs by combining viem for blockchain interaction and RxJS for reactive stream processing.

    Key capabilities include:

    • Creating streams of block data using createBlockStream.
    • Converting block ranges into log streams using blockRangeToLogs.
    • Grouping logs by their block number using groupLogsByBlockNumber.

    To use these utilities, you need a viem public client and an ABI parsed via parseAbi.

    import { filter, map, mergeMap } from "rxjs";
    import { createPublicClient, parseAbi } from "viem";
    import { createBlockStream, groupLogsByBlockNumber, blockRangeToLogs } from "@latticexyz/block-logs-stream";
    
    const publicClient = createPublicClient({
      // your viem public client config here
    });
    
    const latestBlock$ = await createBlockStream({ publicClient, blockTag: "latest" });
    const latestBlockNumber$ = latestBlock$.pipe(map((block) => block.number));
    
    latestBlockNumber$
      .pipe(
        map((latestBlockNumber) => ({ startBlock: 0n, endBlock: latestBlockNumber })),
        blockRangeToLogs({
          publicClient,
          address,
          events: parseAbi([
            "event Store_SetRecord(bytes32 indexed tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData)",
            "event Store_SpliceStaticData(bytes32 indexed tableId, bytes32[] keyTuple, uint48 start, bytes data)",
            "event Store_SpliceDynamicData(bytes32 indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes32 encodedLengths, bytes data)",
            "event Store_DeleteRecord(bytes32 indexed tableId, bytes32[] keyTuple)",
          ]),
        }),
        mergeMap(({ logs }) => from(groupLogsByBlockNumber(logs))),
      )
      .subscribe((block) => {
        console.log("got events for block", block);
      });
  5. What is a ResourceId in MUD?

    main

    A ResourceId is a 32-byte value used to uniquely identify any resource within a World. The structure of the 32 bytes is composed of:

    • 2 bytes: Resource type
    • 14 bytes: Namespace
    • 16 bytes: Resource name

    Supported resource types include:

    • tb (Table): An onchain table available both onchain (via view functions) and offchain (via events or an indexer).
    • ot (Offchain table): An offchain table available only offchain (via events or an indexer).
    • ns (Namespace): A container for tables, offchain tables, and systems, used for access control.
    • sy (System): Contains logic that interacts with table data onchain.
  6. What is recs (Reactive Entity Component System)?

    main
    recs is a Reactive Entity Component System (ECS) designed for high performance and seamless integration with other MUD libraries. Its core design principle is reactivity: Components and Queries expose an update$ stream, allowing Systems to react to changes in the world state automatically. It provides a simple, declarative TypeScript API for managing entities, components, and systems.
  7. What is account delegation in MUD

    main
    Account delegation allows one address to act on behalf of another. This is a common pattern used to improve user experience in games: instead of requiring a user to sign every single game move via a wallet extension, a user can authorize a 'burner wallet' to perform actions on their behalf. This enables seamless gameplay while maintaining security through controlled permissions.
  8. What is a System in MUD?

    main
    In MUD, a System contract is the primary unit for executing logic. Currently, the System contract acts as an alias for WorldContextConsumer. This design allows the System to access the WorldContext (the state of the world) while providing a stable interface that can be extended with default functionality in future updates.
  9. What is MUD Store?

    main

    MUD Store is an alternative to Solidity's native storage engine. It provides several key advantages for developers:

    • Relational Data Model: Enforces a data model that can be mapped directly to a relational database.
    • Automatic Indexing: Emits a standardized set of events for every mutation, allowing indexers to automatically replicate onchain state offchain.
    • Efficient Packing: Packs data more tightly than native Solidity storage.
    • Onchain Readability: Allows external contract storage to be read onchain without being limited by existing view functions or requiring new opcodes.

    Data is organized into tables, where each piece of data is stored as a record within a table. Tables can be conceptualized as either relational database tables or key-value stores.

  10. What is the Keys in Table module?

    main

    The KeysInTable module tracks which keys are used with a specific table. This is useful when you need to iterate through all the records of a table onchain.

    Warning: Using this module adds gas overhead to every write operation in the table it is monitoring. If gas efficiency is a priority, consider implementing your own custom "onchain index" pattern instead.

  11. What is the Keys with Value module?

    main

    The KeysWithValue module provides a reverse mapping for a MUD table. It maps a hash of a table entry's value to a list of keys that share that exact value. This allows you to perform onchain lookups of keys based on specific data values.

    Warning: Using this module adds gas overhead to every write operation in the associated table. For high-frequency write environments, consider implementing a custom "onchain index" pattern instead.

  12. What is StoreSwitch and how does it work?

    main

    The StoreSwitch library acts as an interface switch for interacting with the MUD store. It abstracts storage details by allowing a contract to either interact with its own internal storage or redirect all calls to a designated external store address.

    Key behaviors:

    • Abstraction: Calling functions do not need to know if they are interacting with local or external storage.
    • Fallback Mechanism: If the store address is uninitialized (zero address), StoreSwitch defaults to using msg.sender as the store.
    • Hooks: It supports registering IStoreHook contracts for specific tables to intercept or modify operations.
    // Concept: StoreSwitch redirects calls to an external address
    // If uninitialized, it uses msg.sender