GithubHelp home page GithubHelp logo

ltfschoen / mudtemplate Goto Github PK

View Code? Open in Web Editor NEW
3.0 3.0 0.0 158 KB

Build Ethereum DApps with MUD v2 in a Docker container

License: Apache License 2.0

Shell 53.46% Dockerfile 46.54%
docker ethereum foundry lattice mud vitejs anvil cast chisel forge

mudtemplate's Introduction

MUD v2 DApp Template (using Docker)

============

Table of Contents

Create First Project

  • Install Docker
  • Fork and/or clone repo.
    git clone https://github.com/ltfschoen/MUDTemplate && cd MUDTemplate
  • Configure DApp by generating a .env file from the .env.example file by following its instructions, if desired.
  • Build a Docker image and run a Docker container to create a DApp according to configuration in .env file.
    ./docker/docker.sh
  • Wait... until terminal logs output [client] Local: http://localhost:3000/
  • Open http://localhost:3000 in web browser to load MUD v2 DApp.

Restart Existing Project

  • Enter the Docker container shell with the following. It should display a prompt root@foundry:/opt#.
    docker exec -it foundry /bin/bash
  • To manually start the MUD v2 DApp switch to the folder of your MUD v2 DApp and run it with:
    cd /opt/projects/my-project
    pnpm run dev
  • Press CTRL+D to exit Docker container shell.

Create Additional Projects

  • Option 1
    • Run
      docker exec -it foundry ./docker/run.sh <PROJECT_NAME> <TEMPLATE> <LICENSE>
  • Option 2
    • Enter the Docker container shell with the following. It should display a prompt root@foundry:/opt#.
      docker exec -it foundry /bin/bash
    • Create a MUD v2 DApp by running:
      /opt/docker/run.sh <PROJECT_NAME> <TEMPLATE> <LICENSE>
    • Press CTRL+D to exit Docker container shell.

Note: See .env.example for possible values to use for <PROJECT_NAME>, <TEMPLATE>, and <LICENSE>.

Tips to configure Visual Studio Code

  • Edit my-project/.vscode/settings.json if necessary. Note in ./docker/run.sh we replace its contents with default values in the file ./snippets/content-settings.json

  • Verify that the Solidity version value specified in the following files for the following keys is the same (i.e. 0.8.x). See https://github.com/foundry-rs/foundry/blob/58a272997516046fd745f4b3c37f91d0eb113358/config/src/lib.rs#L179

    • solc_version or solc ./projects/my-project/packages/contracts/foundry.toml
    • solidity.compileUsingRemoteVersion in ./.vscode/settings.json.
    • solidity.compileUsingRemoteVersion in ./projects/my-project/.vscode/settings.json.

Tips for Docker

  • Delete Docker Container
    docker stop foundry && docker rm foundry
    
  • Show Docker Containers
    docker ps -a
  • Show Docker Images
    docker images
  • Previous Docker container
    CONTAINER_ID=$(docker ps -n=1 -q)
    echo $CONTAINER_ID
  • Show IP address. This may be provided as an environment variable with -e option
    HOST_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
    echo $HOST_IP
  • Check IP Address macOS
    brew install iproute2mac
  • Show bridge IP address
    docker network inspect bridge | grep Gateway

Note: It is not necessary to use --add-host=host.docker.internal:host-gateway or expose <PORT>

Note: Do not try to use --network host on macOS, since "The host networking driver only works on Linux hosts, and is not supported on Docker Desktop for Mac, Docker Desktop for Windows, or Docker EE for Windows Server."

Tips for Lattice, MUD, and Foundry

Definitions

  • MODE - is a service that mirrors the state of a Store in a Postgres database. Clients query directly without requiring Ethereum JSON-RPC
  • MUD - able to reconstruct the state of Store in the browser using a JSON-RPC or a MODE

Faucet

  • Faucet tokens request
    • Check the available flags via --help like npx @latticexyz/cli@canary faucet --help
    • Request Testnet tokens from faucet (FAST way)
      • Run in a project that has the MUD CLI installed as a dev dependency, or via npx like npx @latticexyz/cli@canary faucet --address <ADDRESS>.
    • Request Testnet Tokens from Faucet (SLOW way)
      • Install Foundry curl -L https://foundry.paradigm.xyz | bash
      • Install Go
      • Install MUD and request testnet token from faucet
        npm install pnpm --global && \
        git clone https://github.com/latticexyz/mud && \
        cd mud && \
        pnpm install && \
        pnpm run build && \
        cd packages/cli && \
        pnpm install && \
        pnpm run build && \
        node ./dist/mud.js faucet --faucetUrl "https://follower.testnet-chain.linfra.xyz" --address <ADDRESS>

Q&A

  • Where is MUD v2 code stored?

  • Where is the MUD v2 DApp template stored for React?

  • How to install additional global MUD v2 dependencies if necessary

    • Additional dependencies may be required such as: pnpm install --global concurrently wait-port
  • How to edit the Store config?

  • How to update the client/ and contracts/ folder of the MUD v2 DApp to the latest canary version?

    • Run pnpm mud set-version -v canary in both the client and contracts package of your project then run pnpm install at the root to update your project to the latest canary version

Tips when Troubleshooting

Please create an issue by clicking here and describing the error and upload a screenshot of any errors.

  • How to resolve PNPM global bin directory error

    • If you get the following error when running pnpm run dev, then it may be because you previously built the files on a host machine and copied them to a Docker container.
      sh: 1: run-pty: not found
       ELIFECYCLE  Command failed.
      root@docker-desktop:/opt/projects/my-first-mud-project# pnpm install --global run-pty
       ERR_PNPM_NO_GLOBAL_BIN_DIR  Unable to find the global bin directory
      Run "pnpm setup" to create it automatically, or set the global-bin-dir setting, or the PNPM_HOME env variable. The global bin directory should be in the PATH.
    • Solution is to run pnpm setup, which added this to ~/.bashrc:
      # pnpm
      export PNPM_HOME="/root/.local/share/pnpm"
      case ":$PATH:" in
        *":$PNPM_HOME:"*) ;;
        *) export PATH="$PNPM_HOME:$PATH" ;;
      esac
      
    • Then run the following where ~/.local/share/pnpm is $PNPM_HOME
      source ~/.bashrc
      pnpm config set global-bin-dir ~/.local/share/pnpm
  • How to resolve PNPM dashboard errors

    • Note: If after running DApp with pnpm run dev, if you click 1-pnpm dev:client then it should show that it is exposed at http://localhost:3000 and maybe http://172.17.0.2:3000, where 172.17.0.2 is the eth0 IP address shown if you run ifconfig
    • If any errors running pnpm run dev in the dashboard, then press CTRL+C and then Enter to restart the dashboard and the error should disappear
  • How to resolve CORS error Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://127.0.0.1:8545/. (Reason: CORS request did not succeed). Status code: (null)

    • Refer to solution here of running with export ANVIL_IP_ADDR=0.0.0.0 && pnpm run dev vitejs/vite#13240 (comment)
    • Note that in the latest MUD v2 updates where they use concurrently instead of run-pty you would get CORS errors but we use wait-port so it only loads the DApp when port 8545 is ready.
  • How to configure CORS

    • The CORS configuration may include adding "proxy": "http://<HOST>:<PORT>", in a package.json file and updating /packages/client/vite.config.ts with a cors configuration with keys and values like the below example and replacing with an actual port. The below example is not intended to actually work. Refer to Vite.js configuration documentation for more information https://vitejs.dev/config/server-options.html#server-cors, and also https://github.com/http-party/node-http-proxy#options

    • If you change the CORS configuration for the Vite.js DApp frontend by configuring ./projects/my-project/packages/client/vite.config.ts. See https://vitejs.dev/config/server-options.html#server-cors, then run pnpm store prune and restart the DApp.

    • Note that you may open all origins with: cors: { origin: "*", methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE', 'OPTIONS'] },.

      Example CORS code snippet
      cors: {
        // origin: ["ws://127.0.0.1:<PORT>/", "http://127.0.0.1:<PORT>/"],
        origin: "*",
        methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE', 'OPTIONS'],
        allowedHeaders: ['Content-Type', 'Authorization'],
        credentials: true,
        exposedHeaders: ['Content-Range', 'X-Content-Range'],
        preflightContinue: true,
        optionsSuccessStatus: 204
      },
      hmr: {
        clientPort: <PORT>,
        port: <PORT>,
        overlay: false,
      },
      proxy: {
        '/socket.io': {
          target: 'ws://localhost:<PORT>',
          changeOrigin: true,
          ws: true,
          xfwd: true,
        },
      },
      strictPort: false,
  • How to resolve a port being in use?

    • If port 3000 is in use, then find its PID lsof -i | grep :3000 and then kill it by running kill -9 <PID>

Tips with Links

mudtemplate's People

Contributors

ltfschoen avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

mudtemplate's Issues

CORS: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://127.0.0.1:8545/. (Reason: CORS request did not succeed). Status code: (null)

  • Unresolved CORS issue as shown in below screenshot when I open my browser at http://localhost:3000 on the host machine after running pnpm run dev (following README instructions), with the anvil server running and all contracts deployed via RPC to 127.0.0.1:8545.
Screen Shot 2023-05-17 at 8 44 17 pm
  • At this stage to try to avoid this CORS issue accessing the DApp in the Docker container from the host machine (see latticexyz/mud#860), I tried doing what was suggested here latticexyz/mud#860 (comment) by editing my-project/node_modules/.pnpm/[email protected]/node_modules/vite/dist/client/client.mjs by changing the line const socketHost = ${__HMR_HOSTNAME__ || importMetaUrl.hostname}:${hmrPort || importMetaUrl.port}${__HMR_BASE__}; to instead be const socketHost = '127.0.0.1:8545';. Relates to vitejs/vite#652 that possibly hasn't been resolved yet and possibly should be re-opened. Unfortunately that doesn't appear to resolve the issue.
  • I have also tried to modify packages/client/vite.config.ts. See the Vitejs docs https://vitejs.dev/config/server-options.html#server-cors. But even if I allow all origins and headers it still generates the error after I restart it.
export default defineConfig({
  plugins: [react()],
  server: {
    port: 3000,
    fs: {
      strict: false,
    },
    cors: {
      // origin: ["ws://127.0.0.1:8545/", "http://127.0.0.1:8545/", "http://localhost:3000/"],
      origin: "*",
      // methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE', 'OPTIONS'],
      methods: "*",
      // allowedHeaders: ['Content-Type', 'Authorization'],
      allowedHeaders: "*",
      credentials: true,
      // exposedHeaders: ['Content-Range', 'X-Content-Range'],
      exposedHeaders: "*",
      // preflightContinue: true,
      // optionsSuccessStatus: 204
    },
    // hmr: {
    //   clientPort: 8545,
    //   port: 3000,
    //   overlay: true,
    // }
    // proxy: {
    //   '/socket.io': {
    //     target: 'ws://127.0.0.1:8545',
    //     ws: true,
    //   },
    // },
    // strictPort: false,
  },

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.