Skip to content

Commit

Permalink
feat: v2 - add store, world and schema-type, cli table code generation (
Browse files Browse the repository at this point in the history
#422)

BREAKING CHANGE:
This commit removes the deprecated `mud deploy` CLI command. Use `mud deploy-contracts` instead.

---------

Co-authored-by: alvarius <89248902+alvrs@users.noreply.github.com>
Co-authored-by: alvrs <alvrs@users.noreply.github.com>
Co-authored-by: alvrs <alvarius@lattice.xyz>
Co-authored-by: dk1a <dk1a@protonmail.com>
Co-authored-by: dk1a <dk1a@users.noreply.github.com>
  • Loading branch information
6 people committed Feb 28, 2023
1 parent 3fdaa98 commit cb731e0
Show file tree
Hide file tree
Showing 176 changed files with 20,917 additions and 1,713 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/gasreport.yml
@@ -0,0 +1,34 @@
# .github/workflows/gasreport.yml
name: Gas report

on:
pull_request:
paths:
- packages/store/**
- packages/world/**

jobs:
gas-report:
runs-on: ubuntu-22.04
name: Generate gas report
steps:
- uses: actions/setup-node@v3
with:
node-version: 16

- name: git-checkout
uses: actions/checkout@v3

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Install dependencies
run: yarn install --network-concurrency 1

- name: Install local CLI
run: cd packages/cli && yarn build && npm link && cd ../..

- name: Verify that gas report is up to date
run: yarn workspace @latticexyz/store run gasreport && yarn workspace @latticexyz/world run gasreport && if [ -n "$(git status --porcelain)" ]; then exit 0; fi
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Expand Up @@ -5,6 +5,7 @@ on:
push:
branches:
- main
- v2
pull_request:
merge_group:

Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Expand Up @@ -9,6 +9,7 @@
"ds-test/=node_modules/ds-test/src/",
"solecs/=node_modules/@latticexyz/solecs/src/",
"royalty-registry/=node_modules/@manifoldxzy/royalty-registry/contracts/",
"std-contracts/=node_modules/@latticexyz/std-contracts/src/"
"std-contracts/=node_modules/@latticexyz/std-contracts/src/",
"@latticexyz/=node_modules/@latticexyz/"
]
}
5 changes: 4 additions & 1 deletion package.json
Expand Up @@ -10,7 +10,10 @@
"workspaces": {
"packages": [
"packages/utils",
"packages/schema-type",
"packages/solecs",
"packages/store",
"packages/world",
"packages/cli",
"packages/recs",
"packages/react",
Expand Down Expand Up @@ -44,7 +47,7 @@
"retypeapp": "^2.4.0",
"rimraf": "^3.0.2",
"run-pty": "^3.0.0",
"typescript": ">=3.0.0"
"typescript": "^4.9.5"
},
"config": {
"commitizen": {
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/modules.d.ts
@@ -1,2 +1,2 @@
declare module "netlify";
declare module "inquirer-prompt-suggest";
declare module "prettier-plugin-solidity";
declare module "long";
46 changes: 19 additions & 27 deletions packages/cli/package.json
Expand Up @@ -2,10 +2,12 @@
"name": "@latticexyz/cli",
"version": "1.39.0",
"description": "Command line interface for mud",
"main": "src/index.ts",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"type": "module",
"license": "MIT",
"bin": {
"mud": "./dist/index.js"
"mud": "./dist/mud.js"
},
"repository": {
"type": "git",
Expand All @@ -14,64 +16,54 @@
},
"scripts": {
"prepare": "yarn build && chmod u+x git-install.sh",
"build": "rimraf dist && esbuild ./src/index.ts ./src/commands/* --bundle --platform=node --outdir=dist --external:fsevents && chmod u+x dist/index.js",
"lint": "eslint . --ext .ts",
"dev": "tsup --watch",
"build": "tsup",
"link": "yarn link",
"test": "tsc && echo 'todo: add tests'",
"test": "vitest typecheck --run && echo 'todo: add tests'",
"git:install": "bash git-install.sh",
"release": "npm publish || echo 'version already published'"
},
"devDependencies": {
"@types/clear": "^0.1.2",
"@types/ejs": "^3.1.1",
"@types/figlet": "^1.5.4",
"@types/glob": "^7.2.0",
"@types/inquirer": "^8.2.1",
"@types/node": "^17.0.34",
"@types/openurl": "^1.0.0",
"@types/yargs": "^17.0.10",
"esbuild": "^0.15.16",
"nodemon": "^2.0.16",
"pkg": "^5.7.0",
"rimraf": "^3.0.2",
"ts-node": "^10.7.0",
"typescript": "^4.6.4"
"tsup": "^6.6.3",
"vitest": "^0.29.1"
},
"dependencies": {
"@improbable-eng/grpc-web": "^0.15.0",
"@improbable-eng/grpc-web-node-http-transport": "^0.15.0",
"@latticexyz/schema-type": "^1.34.0",
"@latticexyz/services": "^1.39.0",
"@latticexyz/solecs": "^1.39.0",
"@latticexyz/std-contracts": "^1.39.0",
"@latticexyz/utils": "^1.39.0",
"@typechain/ethers-v5": "^10.1.1",
"chalk": "^5.0.1",
"chokidar": "^3.5.3",
"clear": "^0.1.0",
"commander": "^9.2.0",
"ds-test": "https://github.com/dapphub/ds-test.git#c9ce3f25bde29fc5eb9901842bf02850dfd2d084",
"ejs": "^3.1.8",
"esm": "^3.2.25",
"ethers": "^5.7.2",
"execa": "^6.1.0",
"figlet": "^1.5.2",
"find-up": "^6.3.0",
"forge-std": "https://github.com/foundry-rs/forge-std.git#b4f121555729b3afb3c5ffccb62ff4b6e2818fd3",
"glob": "^8.0.3",
"inquirer": "^8.2.4",
"inquirer-prompt-suggest": "^0.1.0",
"listr2": "^4.0.5",
"netlify": "^11.0.1",
"nice-grpc-web": "^2.0.1",
"node-fetch": "^3.2.6",
"openurl": "^1.1.1",
"path": "^0.12.7",
"prettier": "^2.8.4",
"prettier-plugin-solidity": "^1.1.2",
"solmate": "https://github.com/Rari-Capital/solmate.git#9cf1428245074e39090dceacb0c28b1f684f584c",
"table": "^6.8.1",
"ts-node": "^10.9.1",
"typechain": "^8.1.1",
"uuid": "^8.3.2",
"yargs": "^17.5.1"
},
"pkg": {
"scripts": "build/**/*.js"
"typescript": "^4.9.5",
"yargs": "^17.7.1",
"zod": "^3.20.6",
"zod-validation-error": "^0.3.2"
},
"gitHead": "218f56893d268b0c5157a3e4c603b859e287a343"
}
76 changes: 41 additions & 35 deletions packages/cli/src/commands/bulkupload.ts
@@ -1,44 +1,50 @@
import { Arguments, CommandBuilder } from "yargs";
import { execa } from "execa";
import path from "path";
import type { CommandModule } from "yargs";

const importExeca = eval('import("execa")') as Promise<typeof import("execa")>;
const contractsDirectory = new URL("../src/contracts", import.meta.url).pathname;

type Options = {
statePath: string;
worldAddress: string;
rpc: string;
};

export const command = "bulkupload";
export const desc = "Uploads the provided ECS state to the provided World";

export const builder: CommandBuilder<Options, Options> = (yargs) =>
yargs.options({
statePath: { type: "string", demandOption: true, desc: "Path to the ECS state to upload" },
worldAddress: { type: "string", demandOption: true, desc: "Contract address of the World to upload to" },
rpc: { type: "string", demandOption: true, desc: "JSON RPC endpoint" },
});

export const handler = async (argv: Arguments<Options>): Promise<void> => {
const { execa } = await importExeca;
const { statePath, worldAddress, rpc } = argv;
console.log("Uploading state at ", statePath, "to", worldAddress, "on", rpc);
const url = __dirname + "/../../src/contracts/BulkUpload.sol";
console.log("Using BulkUpload script from", url);

try {
await execa("forge", [
"script",
"--sig",
'"run(string, address)"',
"--rpc-url",
rpc,
`${url}:BulkUpload`,
statePath,
worldAddress,
]);
} catch (e) {
console.error(e);
}

process.exit(0);
const commandModule: CommandModule<Options, Options> = {
command: "bulkupload",

describe: "Uploads the provided ECS state to the provided World",

builder(yargs) {
return yargs.options({
statePath: { type: "string", demandOption: true, desc: "Path to the ECS state to upload" },
worldAddress: { type: "string", demandOption: true, desc: "Contract address of the World to upload to" },
rpc: { type: "string", demandOption: true, desc: "JSON RPC endpoint" },
});
},

async handler({ statePath, worldAddress, rpc }) {
console.log("Uploading state at ", statePath, "to", worldAddress, "on", rpc);
const url = path.join(contractsDirectory, "BulkUpload.sol");
console.log("Using BulkUpload script from", url);

try {
await execa("forge", [
"script",
"--sig",
'"run(string, address)"',
"--rpc-url",
rpc,
`${url}:BulkUpload`,
statePath,
worldAddress,
]);
} catch (e) {
console.error(e);
}

process.exit(0);
},
};

export default commandModule;
98 changes: 51 additions & 47 deletions packages/cli/src/commands/call-system.ts
@@ -1,66 +1,70 @@
import { defaultAbiCoder as abi } from "ethers/lib/utils";
import { defaultAbiCoder as abi } from "ethers/lib/utils.js";
import path from "path";
import { Arguments, CommandBuilder } from "yargs";
import { execLog } from "../utils";
import { getTestDirectory } from "../utils/forgeConfig";
import type { CommandModule } from "yargs";
import { execLog } from "../utils/index.js";
import { getTestDirectory } from "../utils/forgeConfig.js";

type Options = {
rpc?: string;
caller?: string;
world: string;
systemId?: string;
systemAddress?: string;
argTypes?: any[];
args?: any[];
argTypes?: string[];
args?: (string | number)[];
calldata?: string;
broadcast?: boolean;
callerPrivateKey?: string;
debug?: boolean;
};

export const command = "call-system";
export const desc = "Execute a mud system";
const commandModule: CommandModule<Options, Options> = {
command: "call-system",

export const builder: CommandBuilder<Options, Options> = (yargs) =>
yargs.options({
rpc: { type: "string", description: "json rpc endpoint, defaults to http://localhost:8545" },
caller: { type: "string", description: "caller address" },
world: { type: "string", required: true, description: "world contract address" },
systemId: { type: "string", description: "system id preimage (eg mud.system.Move)" },
systemAddress: { type: "string", description: "system address (alternative to system id)" },
argTypes: { type: "array", description: "system argument types for abi encoding" },
args: { type: "array", description: "system arguments" },
calldata: { type: "string", description: "abi encoded system arguments (instead of args/argTypes)" },
broadcast: { type: "boolean", description: "send txs to the chain" },
callerPrivateKey: {
type: "string",
description: "must be set if broadcast is set, must correspond to caller address",
},
debug: { type: "boolean", description: "open debugger" },
});
describe: "Execute a mud system",

export const handler = async (argv: Arguments<Options>): Promise<void> => {
const { rpc, caller, world, systemId, argTypes, args, calldata, broadcast, callerPrivateKey, debug } = argv;
const encodedArgs = calldata ?? (argTypes && args && abi.encode(argTypes, args)) ?? "";
const testDir = await getTestDirectory();
builder(yargs) {
return yargs.options({
rpc: { type: "string", description: "json rpc endpoint, defaults to http://localhost:8545" },
caller: { type: "string", description: "caller address" },
world: { type: "string", required: true, description: "world contract address" },
systemId: { type: "string", description: "system id preimage (eg mud.system.Move)" },
systemAddress: { type: "string", description: "system address (alternative to system id)" },
argTypes: { type: "array", string: true, description: "system argument types for abi encoding" },
args: { type: "array", description: "system arguments" },
calldata: { type: "string", description: "abi encoded system arguments (instead of args/argTypes)" },
broadcast: { type: "boolean", description: "send txs to the chain" },
callerPrivateKey: {
type: "string",
description: "must be set if broadcast is set, must correspond to caller address",
},
debug: { type: "boolean", description: "open debugger" },
});
},

await execLog("forge", [
"script",
"--fork-url",
rpc ?? "http://localhost:8545", // default anvil rpc
"--sig",
"debug(address,address,string,bytes,bool)",
path.join(testDir, "utils/Debug.sol"), // the cli expects the Debug.sol file at this path
caller ?? "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", // default anvil deployer
world,
systemId || "",
encodedArgs,
broadcast ? "true" : "false",
"-vvvvv",
broadcast ? "--broadcast" : "",
callerPrivateKey ? `--private-key ${callerPrivateKey}` : "",
debug ? "--debug" : "",
]);
async handler({ rpc, caller, world, systemId, argTypes, args, calldata, broadcast, callerPrivateKey, debug }) {
const encodedArgs = calldata ?? (argTypes && args && abi.encode(argTypes, args)) ?? "";
const testDir = await getTestDirectory();
await execLog("forge", [
"script",
"--fork-url",
rpc ?? "http://localhost:8545", // default anvil rpc
"--sig",
"debug(address,address,string,bytes,bool)",
path.join(testDir, "utils/Debug.sol"), // the cli expects the Debug.sol file at this path
caller ?? "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", // default anvil deployer
world,
systemId || "",
encodedArgs,
broadcast ? "true" : "false",
"-vvvvv",
broadcast ? "--broadcast" : "",
callerPrivateKey ? `--private-key ${callerPrivateKey}` : "",
debug ? "--debug" : "",
]);

process.exit(0);
process.exit(0);
},
};

export default commandModule;

0 comments on commit cb731e0

Please sign in to comment.