From e3a8b9695600188cb9a9d433f67e0e6d752794ac Mon Sep 17 00:00:00 2001 From: Danilo Tuler Date: Tue, 4 Mar 2025 11:04:33 -0500 Subject: [PATCH 1/3] feat (cli): improve doctor command --- .changeset/flat-ears-explain.md | 5 +++++ apps/cli/src/commands/doctor.ts | 34 ++++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 .changeset/flat-ears-explain.md diff --git a/.changeset/flat-ears-explain.md b/.changeset/flat-ears-explain.md new file mode 100644 index 00000000..242e8359 --- /dev/null +++ b/.changeset/flat-ears-explain.md @@ -0,0 +1,5 @@ +--- +"@cartesi/cli": minor +--- + +improve doctor command diff --git a/apps/cli/src/commands/doctor.ts b/apps/cli/src/commands/doctor.ts index 6fe64390..9cccc5e5 100755 --- a/apps/cli/src/commands/doctor.ts +++ b/apps/cli/src/commands/doctor.ts @@ -1,13 +1,16 @@ import { Command } from "@commander-js/extra-typings"; +import chalk from "chalk"; import { execa } from "execa"; +import ora, { Ora } from "ora"; import semver from "semver"; const MINIMUM_DOCKER_VERSION = "23.0.0"; // Replace with our minimum required Docker version const MINIMUM_DOCKER_COMPOSE_VERSION = "2.21.0"; // Replace with our minimum required Docker Compose version const MINIMUM_BUILDX_VERSION = "0.13.0"; // Replace with our minimum required Buildx version -const checkDocker = async (): Promise => { +const checkDocker = async (progress: Ora): Promise => { try { + progress.start("Checking Docker Engine version..."); const { stdout: dockerVersion } = await execa("docker", [ "version", "--format", @@ -20,6 +23,7 @@ const checkDocker = async (): Promise => { `Unsupported Docker version. Minimum required version is ${MINIMUM_DOCKER_VERSION}. Installed version is ${v}.`, ); } + progress.succeed(`Docker Engine ${chalk.cyan(v)}`); } catch (e: unknown) { if ( e instanceof Error && @@ -34,8 +38,9 @@ const checkDocker = async (): Promise => { return true; }; -const checkCompose = async (): Promise => { +const checkCompose = async (progress: Ora): Promise => { try { + progress.start("Checking Docker Compose version..."); const { stdout: dockerComposeVersion } = await execa("docker", [ "compose", "version", @@ -48,6 +53,7 @@ const checkCompose = async (): Promise => { `Unsupported Docker Compose version. Minimum required version is ${MINIMUM_DOCKER_COMPOSE_VERSION}. Installed version is ${v}.`, ); } + progress.succeed(`Docker Compose ${chalk.cyan(dockerComposeVersion)}`); } catch (e: unknown) { if ( e instanceof Error && @@ -64,8 +70,9 @@ const checkCompose = async (): Promise => { return true; }; -const checkBuildx = async (): Promise => { +const checkBuildx = async (progress: Ora): Promise => { try { + progress.start("Checking Docker Buildx version..."); const { stdout: buildxOutput } = await execa("docker", [ "buildx", "version", @@ -77,7 +84,9 @@ const checkBuildx = async (): Promise => { `Unsupported Docker Buildx version. Minimum required version is ${MINIMUM_BUILDX_VERSION}. Installed version is ${v}.`, ); } + progress.succeed(`Docker Buildx ${chalk.cyan(v)}`); + progress.start("Checking Docker RISC-V support..."); const { stdout: platformsOutput } = await execa("docker", [ "buildx", "ls", @@ -94,6 +103,9 @@ const checkBuildx = async (): Promise => { "Your system does not support riscv64 architecture. Run `docker run --privileged --rm tonistiigi/binfmt:riscv` to enable riscv64 support.", ); } + progress.succeed( + `Docker RISC-V support ${chalk.cyan("linux/riscv64")}`, + ); } catch (e: unknown) { if ( e instanceof Error && @@ -111,16 +123,16 @@ const checkBuildx = async (): Promise => { }; export const registerDoctorCommand = (program: Command) => { - program.command("doctor").action(async (_, command) => { + program.command("doctor").action(async () => { + const progress = ora(); try { - if (await checkDocker()) { - await checkCompose(); - await checkBuildx(); - } + await checkDocker(progress); + await checkCompose(progress); + await checkBuildx(progress); + progress.succeed("Your system is ready."); } catch (e: unknown) { - command.error((e as Error).message); + progress.fail((e as Error).message); + process.exit(1); } - - console.log("Your system is ready."); }); }; From d6883690c3e4737df719378ecec1df18618bce59 Mon Sep 17 00:00:00 2001 From: Enderson Maia Date: Tue, 29 Oct 2024 13:33:09 -0300 Subject: [PATCH 2/3] feat(cli): rollups v2 commands --- .changeset/floppy-eggs-rescue.md | 5 + .changeset/huge-jeans-love.md | 5 + .changeset/kind-mice-help.md | 5 + .changeset/soft-bats-pump.md | 5 + .changeset/solid-owls-burn.md | 5 + apps/cli/package.json | 40 +- apps/cli/src/base.ts | 39 +- apps/cli/src/commands/address-book.ts | 5 +- apps/cli/src/commands/build.ts | 5 +- apps/cli/src/commands/clean.ts | 5 +- apps/cli/src/commands/create.ts | 5 +- apps/cli/src/commands/deploy.ts | 14 +- apps/cli/src/commands/deploy/build.ts | 12 +- apps/cli/src/commands/doctor.ts | 4 +- apps/cli/src/commands/hash.ts | 5 +- apps/cli/src/commands/rollups.ts | 26 + apps/cli/src/commands/rollups/deploy.ts | 323 +++++ apps/cli/src/commands/rollups/start.ts | 194 +++ apps/cli/src/commands/rollups/status.ts | 51 + apps/cli/src/commands/rollups/stop.ts | 31 + apps/cli/src/commands/run.ts | 249 +--- apps/cli/src/commands/send.ts | 83 +- apps/cli/src/commands/send/erc20.ts | 26 +- apps/cli/src/commands/send/erc721.ts | 26 +- apps/cli/src/commands/send/ether.ts | 26 +- apps/cli/src/commands/send/generic.ts | 26 +- apps/cli/src/commands/shell.ts | 5 +- .../src/compose/rollups/DockerfileDeploy.txt | 4 + apps/cli/src/compose/rollups/default.env | 35 + .../compose/rollups/docker-compose-anvil.yaml | 24 + .../rollups}/docker-compose-bundler.yaml | 25 +- .../rollups}/docker-compose-database.yaml | 0 .../rollups/docker-compose-espresso.yaml | 57 + .../rollups}/docker-compose-explorer.yaml | 35 +- .../rollups/docker-compose-graphql.yaml | 47 + .../rollups/docker-compose-node-cpus.yaml | 7 + .../rollups/docker-compose-node-memory.yaml | 6 + .../compose/rollups/docker-compose-node.yaml | 42 + .../rollups/docker-compose-paymaster.yaml | 16 + .../rollups}/docker-compose-prompt.yaml | 0 .../rollups}/docker-compose-proxy.yaml | 25 +- .../src/compose/rollups/proxy/bundler.yaml | 17 + .../src/compose/rollups/proxy/espresso.yaml | 56 + .../compose/rollups/proxy/explorer-api.yaml | 17 + .../src/compose/rollups/proxy/explorer.yaml | 10 + .../src/compose/rollups/proxy/graphql.yaml | 10 + .../src/compose/rollups/proxy/paymaster.yaml | 17 + .../compose/rollups/proxy/rollups-node.yaml | 17 + apps/cli/src/config.ts | 2 +- apps/cli/src/exec/rollups.ts | 62 + apps/cli/src/index.ts | 45 +- apps/cli/src/node/DockerfileDeploy.txt | 4 - apps/cli/src/node/default.env | 27 - apps/cli/src/node/docker-compose-anvil.yaml | 50 - apps/cli/src/node/docker-compose-envfile.yaml | 4 - .../cli/src/node/docker-compose-espresso.yaml | 127 -- apps/cli/src/node/docker-compose-host.yaml | 30 - .../src/node/docker-compose-paymaster.yaml | 33 - .../node/docker-compose-snapshot-volume.yaml | 8 - .../node/docker-compose-validator-cpus.yaml | 6 - .../node/docker-compose-validator-memory.yaml | 6 - .../src/node/docker-compose-validator.yaml | 59 - apps/cli/src/wallet.ts | 38 +- package.json | 8 +- .../docker-compose.yaml | 4 +- pnpm-lock.yaml | 1226 +++++++---------- 66 files changed, 1861 insertions(+), 1570 deletions(-) create mode 100644 .changeset/floppy-eggs-rescue.md create mode 100644 .changeset/huge-jeans-love.md create mode 100644 .changeset/kind-mice-help.md create mode 100644 .changeset/soft-bats-pump.md create mode 100644 .changeset/solid-owls-burn.md create mode 100644 apps/cli/src/commands/rollups.ts create mode 100644 apps/cli/src/commands/rollups/deploy.ts create mode 100644 apps/cli/src/commands/rollups/start.ts create mode 100644 apps/cli/src/commands/rollups/status.ts create mode 100644 apps/cli/src/commands/rollups/stop.ts create mode 100644 apps/cli/src/compose/rollups/DockerfileDeploy.txt create mode 100644 apps/cli/src/compose/rollups/default.env create mode 100644 apps/cli/src/compose/rollups/docker-compose-anvil.yaml rename apps/cli/src/{node => compose/rollups}/docker-compose-bundler.yaml (64%) rename apps/cli/src/{node => compose/rollups}/docker-compose-database.yaml (100%) create mode 100644 apps/cli/src/compose/rollups/docker-compose-espresso.yaml rename apps/cli/src/{node => compose/rollups}/docker-compose-explorer.yaml (58%) create mode 100644 apps/cli/src/compose/rollups/docker-compose-graphql.yaml create mode 100644 apps/cli/src/compose/rollups/docker-compose-node-cpus.yaml create mode 100644 apps/cli/src/compose/rollups/docker-compose-node-memory.yaml create mode 100644 apps/cli/src/compose/rollups/docker-compose-node.yaml create mode 100644 apps/cli/src/compose/rollups/docker-compose-paymaster.yaml rename apps/cli/src/{node => compose/rollups}/docker-compose-prompt.yaml (100%) rename apps/cli/src/{node => compose/rollups}/docker-compose-proxy.yaml (50%) create mode 100644 apps/cli/src/compose/rollups/proxy/bundler.yaml create mode 100644 apps/cli/src/compose/rollups/proxy/espresso.yaml create mode 100644 apps/cli/src/compose/rollups/proxy/explorer-api.yaml create mode 100644 apps/cli/src/compose/rollups/proxy/explorer.yaml create mode 100644 apps/cli/src/compose/rollups/proxy/graphql.yaml create mode 100644 apps/cli/src/compose/rollups/proxy/paymaster.yaml create mode 100644 apps/cli/src/compose/rollups/proxy/rollups-node.yaml create mode 100644 apps/cli/src/exec/rollups.ts delete mode 100644 apps/cli/src/node/DockerfileDeploy.txt delete mode 100644 apps/cli/src/node/default.env delete mode 100644 apps/cli/src/node/docker-compose-anvil.yaml delete mode 100644 apps/cli/src/node/docker-compose-envfile.yaml delete mode 100644 apps/cli/src/node/docker-compose-espresso.yaml delete mode 100644 apps/cli/src/node/docker-compose-host.yaml delete mode 100644 apps/cli/src/node/docker-compose-paymaster.yaml delete mode 100644 apps/cli/src/node/docker-compose-snapshot-volume.yaml delete mode 100644 apps/cli/src/node/docker-compose-validator-cpus.yaml delete mode 100644 apps/cli/src/node/docker-compose-validator-memory.yaml delete mode 100644 apps/cli/src/node/docker-compose-validator.yaml diff --git a/.changeset/floppy-eggs-rescue.md b/.changeset/floppy-eggs-rescue.md new file mode 100644 index 00000000..63d3613c --- /dev/null +++ b/.changeset/floppy-eggs-rescue.md @@ -0,0 +1,5 @@ +--- +"@cartesi/cli": major +--- + +new: cartesi rollups deploy diff --git a/.changeset/huge-jeans-love.md b/.changeset/huge-jeans-love.md new file mode 100644 index 00000000..f348eabf --- /dev/null +++ b/.changeset/huge-jeans-love.md @@ -0,0 +1,5 @@ +--- +"@cartesi/cli": major +--- + +DEPRECATED: cartesi run diff --git a/.changeset/kind-mice-help.md b/.changeset/kind-mice-help.md new file mode 100644 index 00000000..51f34fa6 --- /dev/null +++ b/.changeset/kind-mice-help.md @@ -0,0 +1,5 @@ +--- +"@cartesi/cli": major +--- + +new: cartesi rollups stop diff --git a/.changeset/soft-bats-pump.md b/.changeset/soft-bats-pump.md new file mode 100644 index 00000000..f94397bf --- /dev/null +++ b/.changeset/soft-bats-pump.md @@ -0,0 +1,5 @@ +--- +"@cartesi/cli": major +--- + +new: cartesi rollups start diff --git a/.changeset/solid-owls-burn.md b/.changeset/solid-owls-burn.md new file mode 100644 index 00000000..afd29626 --- /dev/null +++ b/.changeset/solid-owls-burn.md @@ -0,0 +1,5 @@ +--- +"@cartesi/cli": major +--- + +new: cartesi rollups status diff --git a/apps/cli/package.json b/apps/cli/package.json index c8f519c2..53894783 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -18,50 +18,50 @@ ], "dependencies": { "@commander-js/extra-typings": "^13.1.0", - "@inquirer/confirm": "^5.0.0", - "@inquirer/core": "^10.0.0", - "@inquirer/input": "^4.0.0", - "@inquirer/select": "^4.0.0", - "@inquirer/type": "^3.0.0", + "@inquirer/confirm": "^5.1.6", + "@inquirer/core": "^10.1.7", + "@inquirer/input": "^4.1.6", + "@inquirer/select": "^4.0.9", + "@inquirer/type": "^3.0.4", "bytes": "^3.1.2", - "chalk": "^5.3.0", + "chalk": "^5.4.1", "cli-table3": "^0.6.5", "commander": "^13.1.0", - "execa": "^9.4.1", - "fs-extra": "^11.2.0", - "giget": "^1.2.3", - "lookpath": "^1.2.2", + "execa": "^9.5.2", + "fs-extra": "^11.3.0", + "giget": "^2.0.0", + "lookpath": "^1.2.3", "open": "^10.1.0", - "ora": "^8.1.0", + "ora": "^8.2.0", "progress-stream": "^2.0.0", - "semver": "^7.6.3", - "smol-toml": "^1.3.0", + "semver": "^7.7.1", + "smol-toml": "^1.3.1", "tmp": "^0.2.3", - "viem": "^2.21.27" + "viem": "^2.23.6" }, "devDependencies": { "@cartesi/devnet": "workspace:*", "@cartesi/eslint-config": "workspace:*", "@sunodo/wagmi-plugin-hardhat-deploy": "^0.3.0", - "@types/bytes": "^3.1.4", + "@types/bytes": "^3.1.5", "@types/fs-extra": "^11.0.4", "@types/inquirer": "^9.0.7", - "@types/node": "^22.7.6", - "@types/node-fetch": "^2.6.11", + "@types/node": "^22.13.9", + "@types/node-fetch": "^2.6.12", "@types/progress-stream": "^2.0.5", "@types/prompts": "^2.4.9", "@types/semver": "^7.5.8", "@types/tmp": "^0.2.6", "@vitest/coverage-istanbul": "^2.1.3", - "@wagmi/cli": "^2.1.16", + "@wagmi/cli": "^2.2.0", "copyfiles": "^2.4.1", "eslint": "^8.57.0", "npm-run-all": "^4.1.5", "rimraf": "^6.0.1", "ts-node": "^10.9.2", "tsconfig": "workspace:*", - "tslib": "^2.8.0", - "typescript": "^5.6.3", + "tslib": "^2.8.1", + "typescript": "^5.8.2", "vitest": "^2.1.3" }, "scripts": { diff --git a/apps/cli/src/base.ts b/apps/cli/src/base.ts index dfef2eca..54cab2ea 100644 --- a/apps/cli/src/base.ts +++ b/apps/cli/src/base.ts @@ -1,8 +1,9 @@ +import { InvalidArgumentError } from "@commander-js/extra-typings"; import chalk from "chalk"; import { execa } from "execa"; import fs from "fs"; import path from "path"; -import { Address, getAddress, Hash, isHash } from "viem"; +import { Address, getAddress, Hash, isAddress, isHash, zeroHash } from "viem"; import { Config, parse } from "./config.js"; import { applicationFactoryAddress, @@ -18,6 +19,7 @@ import { testNftAddress, testTokenAddress, } from "./contracts.js"; +import { getApplicationAddress } from "./exec/rollups.js"; import { PsResponse } from "./types/docker.js"; export const getContextPath = (...paths: string[]): string => { @@ -42,11 +44,6 @@ export const getApplicationConfig = (configPath: string): Config => { : parse(""); }; -export const getApplicationAddress = async (): Promise
=> { - // fixed value, as we do deterministic deployment with a zero hash - return getAddress("0xab7528bb862fb57e8a2bcd567a2e929a0be56a5e"); -}; - export type AddressBook = Record; export const getAddressBook = async (): Promise => { @@ -54,7 +51,6 @@ export const getAddressBook = async (): Promise => { // build rollups contracts address book const contracts: AddressBook = { - Application: applicationAddress, ApplicationFactory: applicationFactoryAddress, AuthorityFactory: authorityFactoryAddress, EntryPointV06: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", @@ -79,6 +75,10 @@ export const getAddressBook = async (): Promise => { VerifyingPaymasterV07: "0xc5c97885C67F7361aBAfD2B95067a5bBdA603608", }; + if (applicationAddress) { + contracts.Application = applicationAddress; + } + return contracts; }; @@ -109,3 +109,28 @@ export const getServiceState = async ( const ps = stdout ? (JSON.parse(stdout) as PsResponse) : undefined; return ps?.State; }; + +export const parseAddress = ( + value: string, + _previous: Address | undefined, +): Address | undefined => { + if (isAddress(value)) { + return getAddress(value); + } else { + if (value !== "") { + throw new InvalidArgumentError(`Invalid address: ${value}`); + } + return undefined; + } +}; + +export const parseHash = (value: string, _previous: Hash): Hash => { + if (isHash(value)) { + return value; + } else { + if (value !== "") { + throw new InvalidArgumentError(`Invalid hash: ${value}`); + } + return zeroHash; + } +}; diff --git a/apps/cli/src/commands/address-book.ts b/apps/cli/src/commands/address-book.ts index 609b6a62..cca474df 100755 --- a/apps/cli/src/commands/address-book.ts +++ b/apps/cli/src/commands/address-book.ts @@ -2,9 +2,8 @@ import { Command } from "@commander-js/extra-typings"; import Table from "cli-table3"; import { getAddressBook } from "../base.js"; -export const registerAddressBookCommand = (program: Command) => { - program - .command("address-book") +export const createAddressBookCommand = () => { + return new Command("address-book") .description( "Prints the addresses of all smart contracts deployed to the runtime environment of the application.", ) diff --git a/apps/cli/src/commands/build.ts b/apps/cli/src/commands/build.ts index 73c4c106..58a776b5 100755 --- a/apps/cli/src/commands/build.ts +++ b/apps/cli/src/commands/build.ts @@ -38,9 +38,8 @@ const buildDrive = async ( } }; -export const registerBuildCommand = (program: Command) => { - program - .command("build") +export const createBuildCommand = () => { + return new Command("build") .description( "Build application by building Cartesi machine drives, configuring a machine and booting it.", ) diff --git a/apps/cli/src/commands/clean.ts b/apps/cli/src/commands/clean.ts index 7deccfc9..71bd0824 100755 --- a/apps/cli/src/commands/clean.ts +++ b/apps/cli/src/commands/clean.ts @@ -2,9 +2,8 @@ import { Command } from "@commander-js/extra-typings"; import fs from "fs-extra"; import { getContextPath } from "../base.js"; -export const registerCleanCommand = (program: Command) => { - program - .command("clean") +export const createCleanCommand = () => { + return new Command("clean") .description("Deletes all cached build artifacts of application.") .action(async () => { await fs.emptyDir(getContextPath()); diff --git a/apps/cli/src/commands/create.ts b/apps/cli/src/commands/create.ts index d3370d48..ce3af435 100755 --- a/apps/cli/src/commands/create.ts +++ b/apps/cli/src/commands/create.ts @@ -39,9 +39,8 @@ const download = async ( }); }; -export const registerCreateCommand = (program: Command) => { - program - .command("create") +export const createCreateCommand = () => { + return new Command("create") .argument("", "application and directory name") .addOption( new Option("-t, --template