@cartesi/cli 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +19 -0
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +25 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +8 -0
- package/dist/baseCommand.d.ts +26 -0
- package/dist/baseCommand.d.ts.map +1 -0
- package/dist/baseCommand.js +80 -0
- package/dist/commands/address-book.d.ts +9 -0
- package/dist/commands/address-book.d.ts.map +1 -0
- package/dist/commands/address-book.js +21 -0
- package/dist/commands/build.d.ts +24 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +219 -0
- package/dist/commands/clean.d.ts +8 -0
- package/dist/commands/clean.d.ts.map +1 -0
- package/dist/commands/clean.js +11 -0
- package/dist/commands/create.d.ts +16 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +66 -0
- package/dist/commands/deploy/build.d.ts +12 -0
- package/dist/commands/deploy/build.d.ts.map +1 -0
- package/dist/commands/deploy/build.js +61 -0
- package/dist/commands/deploy/index.d.ts +13 -0
- package/dist/commands/deploy/index.d.ts.map +1 -0
- package/dist/commands/deploy/index.js +78 -0
- package/dist/commands/doctor.d.ts +13 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +106 -0
- package/dist/commands/hash.d.ts +10 -0
- package/dist/commands/hash.d.ts.map +1 -0
- package/dist/commands/hash.js +22 -0
- package/dist/commands/run.d.ts +15 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +137 -0
- package/dist/commands/send/dapp-address.d.ts +9 -0
- package/dist/commands/send/dapp-address.d.ts.map +1 -0
- package/dist/commands/send/dapp-address.js +20 -0
- package/dist/commands/send/erc20.d.ts +14 -0
- package/dist/commands/send/erc20.d.ts.map +1 -0
- package/dist/commands/send/erc20.js +70 -0
- package/dist/commands/send/erc721.d.ts +14 -0
- package/dist/commands/send/erc721.d.ts.map +1 -0
- package/dist/commands/send/erc721.js +73 -0
- package/dist/commands/send/ether.d.ts +13 -0
- package/dist/commands/send/ether.d.ts.map +1 -0
- package/dist/commands/send/ether.js +32 -0
- package/dist/commands/send/generic.d.ts +15 -0
- package/dist/commands/send/generic.d.ts.map +1 -0
- package/dist/commands/send/generic.js +119 -0
- package/dist/commands/send/index.d.ts +28 -0
- package/dist/commands/send/index.d.ts.map +1 -0
- package/dist/commands/send/index.js +102 -0
- package/dist/commands/shell.d.ts +14 -0
- package/dist/commands/shell.d.ts.map +1 -0
- package/dist/commands/shell.js +65 -0
- package/dist/contracts.d.ts +4863 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +2074 -0
- package/dist/flags.d.ts +17 -0
- package/dist/flags.d.ts.map +1 -0
- package/dist/flags.js +28 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/node/DockerfileDeploy.txt +4 -0
- package/dist/node/default.env +28 -0
- package/dist/node/docker-compose-anvil.yaml +49 -0
- package/dist/node/docker-compose-database.yaml +15 -0
- package/dist/node/docker-compose-envfile.yaml +4 -0
- package/dist/node/docker-compose-explorer.yaml +84 -0
- package/dist/node/docker-compose-host.yaml +30 -0
- package/dist/node/docker-compose-prompt.yaml +17 -0
- package/dist/node/docker-compose-proxy.yaml +48 -0
- package/dist/node/docker-compose-snapshot-volume.yaml +8 -0
- package/dist/node/docker-compose-validator.yaml +59 -0
- package/dist/prompts.d.ts +62 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +159 -0
- package/dist/types/docker.d.ts +22 -0
- package/dist/types/docker.d.ts.map +1 -0
- package/dist/types/docker.js +1 -0
- package/dist/wallet.d.ts +24 -0
- package/dist/wallet.d.ts.map +1 -0
- package/dist/wallet.js +204 -0
- package/oclif.manifest.json +887 -0
- package/package.json +100 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,CAAC,OAAO,OAAO,KAAM,SAAQ,WAAW,CAAC,OAAO,KAAK,CAAC;IACxD,MAAM,CAAC,OAAO,SAA2C;IAEzD,MAAM,CAAC,WAAW,SAAwD;IAE1E,MAAM,CAAC,QAAQ,WAA2C;IAE7C,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAGpC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import fs from "fs-extra";
|
|
2
|
+
import { BaseCommand } from "../baseCommand.js";
|
|
3
|
+
class Clean extends BaseCommand {
|
|
4
|
+
async run() {
|
|
5
|
+
await fs.emptyDir(this.getContextPath());
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
Clean.summary = "Clean build artifacts of application.";
|
|
9
|
+
Clean.description = "Deletes all cached build artifacts of application.";
|
|
10
|
+
Clean.examples = ["<%= config.bin %> <%= command.id %>"];
|
|
11
|
+
export default Clean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BaseCommand } from "../baseCommand.js";
|
|
2
|
+
export declare const DEFAULT_TEMPLATES_BRANCH = "sdk-0.6";
|
|
3
|
+
export default class CreateCommand extends BaseCommand<typeof CreateCommand> {
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static args: {
|
|
7
|
+
name: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
template: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
11
|
+
branch: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
12
|
+
};
|
|
13
|
+
private download;
|
|
14
|
+
run(): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=create.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAElD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW,CAAC,OAAO,aAAa,CAAC;IACxE,MAAM,CAAC,WAAW,SAAwB;IAE1C,MAAM,CAAC,QAAQ,WAA2C;IAE1D,MAAM,CAAC,IAAI;;MAKT;IAEF,MAAM,CAAC,KAAK;;;MAoBV;YAEY,QAAQ;IAqBT,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAkBpC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { downloadTemplate } from "giget";
|
|
4
|
+
import ora from "ora";
|
|
5
|
+
import { BaseCommand } from "../baseCommand.js";
|
|
6
|
+
export const DEFAULT_TEMPLATES_BRANCH = "sdk-0.6";
|
|
7
|
+
class CreateCommand extends BaseCommand {
|
|
8
|
+
async download(template, branch, out) {
|
|
9
|
+
const cartesiProvider = async (input) => {
|
|
10
|
+
return {
|
|
11
|
+
name: "cartesi",
|
|
12
|
+
subdir: input,
|
|
13
|
+
url: "https://github.com/cartesi/application-templates",
|
|
14
|
+
tar: `https://codeload.github.com/cartesi/application-templates/tar.gz/refs/heads/${branch}`,
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
const input = `cartesi:${template}`;
|
|
18
|
+
return downloadTemplate(input, {
|
|
19
|
+
dir: out,
|
|
20
|
+
providers: { cartesi: cartesiProvider },
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async run() {
|
|
24
|
+
const { args, flags } = await this.parse(CreateCommand);
|
|
25
|
+
const spinner = ora("Creating application...").start();
|
|
26
|
+
try {
|
|
27
|
+
const { dir } = await this.download(flags.template, flags.branch, args.name);
|
|
28
|
+
spinner.succeed(`Application created at ${chalk.cyan(dir)}`);
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
spinner.fail(e instanceof Error
|
|
32
|
+
? `Error creating application: ${chalk.red(e.message)}`
|
|
33
|
+
: String(e));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
CreateCommand.description = "Create application";
|
|
38
|
+
CreateCommand.examples = ["<%= config.bin %> <%= command.id %>"];
|
|
39
|
+
CreateCommand.args = {
|
|
40
|
+
name: Args.string({
|
|
41
|
+
description: "application and directory name",
|
|
42
|
+
required: true,
|
|
43
|
+
}),
|
|
44
|
+
};
|
|
45
|
+
CreateCommand.flags = {
|
|
46
|
+
template: Flags.string({
|
|
47
|
+
description: "template name to use",
|
|
48
|
+
required: true,
|
|
49
|
+
options: [
|
|
50
|
+
"cpp",
|
|
51
|
+
"cpp-low-level",
|
|
52
|
+
"go",
|
|
53
|
+
"javascript",
|
|
54
|
+
"lua",
|
|
55
|
+
"python",
|
|
56
|
+
"ruby",
|
|
57
|
+
"rust",
|
|
58
|
+
"typescript",
|
|
59
|
+
],
|
|
60
|
+
}),
|
|
61
|
+
branch: Flags.string({
|
|
62
|
+
description: `cartesi/application-templates repository branch name to use`,
|
|
63
|
+
default: DEFAULT_TEMPLATES_BRANCH,
|
|
64
|
+
}),
|
|
65
|
+
};
|
|
66
|
+
export default CreateCommand;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from "../../baseCommand.js";
|
|
2
|
+
export default class DeployBuild extends BaseCommand<typeof DeployBuild> {
|
|
3
|
+
static summary: string;
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
platform: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
8
|
+
};
|
|
9
|
+
private buildRollupsImage;
|
|
10
|
+
run(): Promise<string>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/commands/deploy/build.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW,CAAC,OAAO,WAAW,CAAC;IACpE,MAAM,CAAC,OAAO,SAAmD;IAEjE,MAAM,CAAC,WAAW,SACoD;IAEtE,MAAM,CAAC,QAAQ,WAA2C;IAE1D,MAAM,CAAC,KAAK;;MAOV;YAEY,iBAAiB;IA6BlB,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;CAwBtC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import { execa } from "execa";
|
|
3
|
+
import fs from "fs-extra";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { tmpNameSync } from "tmp";
|
|
6
|
+
import { URL } from "url";
|
|
7
|
+
import { BaseCommand } from "../../baseCommand.js";
|
|
8
|
+
class DeployBuild extends BaseCommand {
|
|
9
|
+
async buildRollupsImage(platform) {
|
|
10
|
+
const buildResult = tmpNameSync();
|
|
11
|
+
const imagePath = this.getContextPath("image");
|
|
12
|
+
const binPath = path.join(path.dirname(new URL(import.meta.url).pathname), "..", "..");
|
|
13
|
+
const dockerfile = path.join(binPath, "node", "DockerfileDeploy.txt");
|
|
14
|
+
const args = [
|
|
15
|
+
"buildx",
|
|
16
|
+
"build",
|
|
17
|
+
"-f",
|
|
18
|
+
dockerfile,
|
|
19
|
+
"--load",
|
|
20
|
+
"--iidfile",
|
|
21
|
+
buildResult,
|
|
22
|
+
imagePath,
|
|
23
|
+
];
|
|
24
|
+
// optional platform, default to not defining, which will build for the host platform
|
|
25
|
+
if (platform) {
|
|
26
|
+
args.push("--platform", platform);
|
|
27
|
+
}
|
|
28
|
+
await execa("docker", args, { stdio: "inherit" });
|
|
29
|
+
return fs.readFileSync(buildResult, "utf8");
|
|
30
|
+
}
|
|
31
|
+
async run() {
|
|
32
|
+
const { flags } = await this.parse(DeployBuild);
|
|
33
|
+
// print machine hash
|
|
34
|
+
const templateHash = this.getMachineHash();
|
|
35
|
+
if (!templateHash) {
|
|
36
|
+
this.error(`Cartesi machine snapshot not found, run '${this.config.bin} build'`);
|
|
37
|
+
}
|
|
38
|
+
this.logPrompt({
|
|
39
|
+
title: "Cartesi machine templateHash",
|
|
40
|
+
value: templateHash,
|
|
41
|
+
});
|
|
42
|
+
this.log("Building application node Docker image...");
|
|
43
|
+
const image = await this.buildRollupsImage(flags.platform);
|
|
44
|
+
this.logPrompt({
|
|
45
|
+
title: "Application node Docker image",
|
|
46
|
+
value: image,
|
|
47
|
+
});
|
|
48
|
+
return image;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
DeployBuild.summary = "Build deployment Docker image of application.";
|
|
52
|
+
DeployBuild.description = "Package the application in a Docker image ready to be deployed.";
|
|
53
|
+
DeployBuild.examples = ["<%= config.bin %> <%= command.id %>"];
|
|
54
|
+
DeployBuild.flags = {
|
|
55
|
+
platform: Flags.string({
|
|
56
|
+
options: ["linux/amd64", "linux/arm64"],
|
|
57
|
+
summary: "Docker image target platform",
|
|
58
|
+
description: "Select the target platform for the produced Docker image. It depends on the platform where the application node will be deployed.",
|
|
59
|
+
}),
|
|
60
|
+
};
|
|
61
|
+
export default DeployBuild;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { BaseCommand } from "../../baseCommand.js";
|
|
3
|
+
export default class Deploy extends BaseCommand<typeof Deploy> {
|
|
4
|
+
static summary: string;
|
|
5
|
+
static description: string;
|
|
6
|
+
static examples: string[];
|
|
7
|
+
static flags: {
|
|
8
|
+
hosting: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
9
|
+
webapp: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<import("url").URL, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/deploy/index.ts"],"names":[],"mappings":";AAMA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW,CAAC,OAAO,MAAM,CAAC;IAC1D,MAAM,CAAC,OAAO,SAA2C;IAEzD,MAAM,CAAC,WAAW,SACoD;IAEtE,MAAM,CAAC,QAAQ,WAA2C;IAE1D,MAAM,CAAC,KAAK;;;MAWV;IAEW,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAiEpC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import confirm from "@inquirer/confirm";
|
|
2
|
+
import select from "@inquirer/select";
|
|
3
|
+
import { Flags } from "@oclif/core";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import open, { apps } from "open";
|
|
6
|
+
import { BaseCommand } from "../../baseCommand.js";
|
|
7
|
+
class Deploy extends BaseCommand {
|
|
8
|
+
async run() {
|
|
9
|
+
const { flags } = await this.parse(Deploy);
|
|
10
|
+
// print machine hash
|
|
11
|
+
const templateHash = this.getMachineHash();
|
|
12
|
+
if (!templateHash) {
|
|
13
|
+
this.error(`Cartesi machine snapshot not found, run '${this.config.bin} build'`);
|
|
14
|
+
}
|
|
15
|
+
this.logPrompt({
|
|
16
|
+
title: "Cartesi machine templateHash",
|
|
17
|
+
value: templateHash,
|
|
18
|
+
});
|
|
19
|
+
// ask for deployment type
|
|
20
|
+
const hosting = flags.hosting ||
|
|
21
|
+
(await select({
|
|
22
|
+
message: "Select hosting type",
|
|
23
|
+
choices: [
|
|
24
|
+
{
|
|
25
|
+
name: "Self-hosting",
|
|
26
|
+
description: `Select this option if you want to run the node for your application.
|
|
27
|
+
You will need the following infrastructure:
|
|
28
|
+
|
|
29
|
+
- a cloud server for the application node
|
|
30
|
+
- a postgres database
|
|
31
|
+
- a web3 node provider
|
|
32
|
+
- a funded wallet
|
|
33
|
+
`,
|
|
34
|
+
value: "self-hosted",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "Use third-party provider",
|
|
38
|
+
description: "Select this option to use a third-party service provider to run a node for your application.",
|
|
39
|
+
value: "third-party",
|
|
40
|
+
disabled: "(coming soon)",
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
}));
|
|
44
|
+
let queryString = "";
|
|
45
|
+
switch (hosting) {
|
|
46
|
+
case "self-hosted": {
|
|
47
|
+
// build docker image
|
|
48
|
+
await this.config.runCommand("deploy:build");
|
|
49
|
+
queryString = `?templateHash=${templateHash}`;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case "third-party": {
|
|
53
|
+
this.error("Third-party provider deployment not supported yet");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// prompt user to open webapp for onchain deployment
|
|
57
|
+
const deployUrl = `${flags.webapp}${queryString}`;
|
|
58
|
+
if (await confirm({ message: `Open ${chalk.cyan(deployUrl)}?` })) {
|
|
59
|
+
open(deployUrl, { app: { name: apps.chrome } });
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
Deploy.summary = "Deploy application to a live network.";
|
|
65
|
+
Deploy.description = "Package and deploy the application to a supported live network.";
|
|
66
|
+
Deploy.examples = ["<%= config.bin %> <%= command.id %>"];
|
|
67
|
+
Deploy.flags = {
|
|
68
|
+
hosting: Flags.string({
|
|
69
|
+
options: ["self-hosted", "third-party"],
|
|
70
|
+
summary: "hosting type",
|
|
71
|
+
description: "Select wheather the user will host an application node himself, or use a third-party node provider",
|
|
72
|
+
}),
|
|
73
|
+
webapp: Flags.url({
|
|
74
|
+
description: "address of deploy webapp",
|
|
75
|
+
required: true,
|
|
76
|
+
}),
|
|
77
|
+
};
|
|
78
|
+
export default Deploy;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from "../baseCommand.js";
|
|
2
|
+
export default class DoctorCommand extends BaseCommand<typeof DoctorCommand> {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
private static MINIMUM_DOCKER_VERSION;
|
|
6
|
+
private static MINIMUM_DOCKER_COMPOSE_VERSION;
|
|
7
|
+
private static MINIMUM_BUILDX_VERSION;
|
|
8
|
+
private checkDocker;
|
|
9
|
+
private checkCompose;
|
|
10
|
+
private checkBuildx;
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW,CAAC,OAAO,aAAa,CAAC;IACxE,MAAM,CAAC,WAAW,SAA2C;IAE7D,MAAM,CAAC,QAAQ,WAA2C;IAE1D,OAAO,CAAC,MAAM,CAAC,sBAAsB,CAAY;IACjD,OAAO,CAAC,MAAM,CAAC,8BAA8B,CAAY;IACzD,OAAO,CAAC,MAAM,CAAC,sBAAsB,CAAY;YAEnC,WAAW;YA+BX,YAAY;YAiCZ,WAAW;IAiDZ,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAYpC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { execa } from "execa";
|
|
2
|
+
import semver from "semver";
|
|
3
|
+
import { BaseCommand } from "../baseCommand.js";
|
|
4
|
+
class DoctorCommand extends BaseCommand {
|
|
5
|
+
async checkDocker() {
|
|
6
|
+
try {
|
|
7
|
+
const { stdout: dockerVersion } = await execa("docker", [
|
|
8
|
+
"version",
|
|
9
|
+
"--format",
|
|
10
|
+
"{{json .Client.Version}}",
|
|
11
|
+
]);
|
|
12
|
+
const v = semver.coerce(dockerVersion);
|
|
13
|
+
if (v !== null &&
|
|
14
|
+
!semver.gte(v, DoctorCommand.MINIMUM_DOCKER_VERSION)) {
|
|
15
|
+
throw new Error(`Unsupported Docker version. Minimum required version is ${DoctorCommand.MINIMUM_DOCKER_VERSION}. Installed version is ${v}.`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
if (e instanceof Error &&
|
|
20
|
+
e.code === "ENOENT") {
|
|
21
|
+
throw new Error("Docker not found");
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
throw e;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
async checkCompose() {
|
|
30
|
+
try {
|
|
31
|
+
const { stdout: dockerComposeVersion } = await execa("docker", [
|
|
32
|
+
"compose",
|
|
33
|
+
"version",
|
|
34
|
+
"--short",
|
|
35
|
+
]);
|
|
36
|
+
const v = semver.coerce(dockerComposeVersion);
|
|
37
|
+
if (v !== null &&
|
|
38
|
+
!semver.gte(v, DoctorCommand.MINIMUM_DOCKER_COMPOSE_VERSION)) {
|
|
39
|
+
throw new Error(`Unsupported Docker Compose version. Minimum required version is ${DoctorCommand.MINIMUM_DOCKER_COMPOSE_VERSION}. Installed version is ${v}.`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
if (e instanceof Error &&
|
|
44
|
+
e.exitCode === 125) {
|
|
45
|
+
throw new Error("Docker Compose is required but not installed or the command execution failed. Please refer to the Docker Compose documentation for installation instructions: https://docs.docker.com/compose/install/");
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
throw e;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
async checkBuildx() {
|
|
54
|
+
try {
|
|
55
|
+
const { stdout: buildxOutput } = await execa("docker", [
|
|
56
|
+
"buildx",
|
|
57
|
+
"version",
|
|
58
|
+
]);
|
|
59
|
+
const v = semver.coerce(buildxOutput);
|
|
60
|
+
if (v !== null &&
|
|
61
|
+
!semver.gte(v, DoctorCommand.MINIMUM_BUILDX_VERSION)) {
|
|
62
|
+
throw new Error(`Unsupported Docker Buildx version. Minimum required version is ${DoctorCommand.MINIMUM_BUILDX_VERSION}. Installed version is ${v}.`);
|
|
63
|
+
}
|
|
64
|
+
const { stdout: platformsOutput } = await execa("docker", [
|
|
65
|
+
"buildx",
|
|
66
|
+
"ls",
|
|
67
|
+
"--format",
|
|
68
|
+
"{{.Platforms}}",
|
|
69
|
+
]);
|
|
70
|
+
const buildxPlatforms = platformsOutput
|
|
71
|
+
.split(",")
|
|
72
|
+
.map((platform) => platform.trim());
|
|
73
|
+
if (!buildxPlatforms.includes("linux/riscv64")) {
|
|
74
|
+
throw new Error("Your system does not support riscv64 architecture. Run `docker run --privileged --rm tonistiigi/binfmt:riscv` to enable riscv64 support.");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
if (e instanceof Error &&
|
|
79
|
+
e.exitCode === 125) {
|
|
80
|
+
throw new Error("Docker Buildx is required but not installed. Please refer to the Docker Desktop documentation for installation instructions: https://docs.docker.com/desktop/");
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
throw e;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
async run() {
|
|
89
|
+
try {
|
|
90
|
+
if (await this.checkDocker()) {
|
|
91
|
+
await this.checkCompose();
|
|
92
|
+
await this.checkBuildx();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
this.error(e);
|
|
97
|
+
}
|
|
98
|
+
this.log("Your system is ready.");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
DoctorCommand.description = "Verify the minimal sytem requirements";
|
|
102
|
+
DoctorCommand.examples = ["<%= config.bin %> <%= command.id %>"];
|
|
103
|
+
DoctorCommand.MINIMUM_DOCKER_VERSION = "23.0.0"; // Replace with our minimum required Docker version
|
|
104
|
+
DoctorCommand.MINIMUM_DOCKER_COMPOSE_VERSION = "2.21.0"; // Replace with our minimum required Docker Compose version
|
|
105
|
+
DoctorCommand.MINIMUM_BUILDX_VERSION = "0.13.0"; // Replace with our minimum required Buildx version
|
|
106
|
+
export default DoctorCommand;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseCommand } from "../baseCommand.js";
|
|
2
|
+
export default class HashCommand extends BaseCommand<typeof HashCommand> {
|
|
3
|
+
static summary: string;
|
|
4
|
+
static description: string;
|
|
5
|
+
static enableJsonFlag: boolean;
|
|
6
|
+
run(): Promise<{
|
|
7
|
+
hash: `0x${string}`;
|
|
8
|
+
} | undefined>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/commands/hash.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,WAAW,CAAC,OAAO,WAAW,CAAC;IACpE,MAAM,CAAC,OAAO,SAA0D;IAExE,MAAM,CAAC,WAAW,SAC2F;IAE7G,OAAc,cAAc,UAAQ;IAEvB,GAAG;;;CAgBnB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { BaseCommand } from "../baseCommand.js";
|
|
3
|
+
class HashCommand extends BaseCommand {
|
|
4
|
+
async run() {
|
|
5
|
+
const hash = this.getMachineHash();
|
|
6
|
+
if (hash) {
|
|
7
|
+
if (!this.jsonEnabled()) {
|
|
8
|
+
process.stdout.write(`${chalk.green("?")} Cartesi machine templateHash ${chalk.cyan(hash)}\n`);
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
return { hash };
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
this.error(`Cartesi machine snapshot not found, run '${this.config.bin} build'`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
HashCommand.summary = "Prints out image hash generated by the build command";
|
|
20
|
+
HashCommand.description = "Converts the binary generated by the build command to hexadecimal and prints out the result to console";
|
|
21
|
+
HashCommand.enableJsonFlag = true;
|
|
22
|
+
export default HashCommand;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseCommand } from "../baseCommand.js";
|
|
2
|
+
export default class Run extends BaseCommand<typeof Run> {
|
|
3
|
+
static summary: string;
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
"block-time": import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
8
|
+
"epoch-duration": import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
9
|
+
"no-backend": import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
10
|
+
verbose: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
11
|
+
"listen-port": import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,CAAC,OAAO,OAAO,GAAI,SAAQ,WAAW,CAAC,OAAO,GAAG,CAAC;IACpD,MAAM,CAAC,OAAO,SAA2B;IAEzC,MAAM,CAAC,WAAW,SAAmD;IAErE,MAAM,CAAC,QAAQ,WAA2C;IAE1D,MAAM,CAAC,KAAK;;;;;;MAwBV;IAEW,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAwHpC"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import { execa } from "execa";
|
|
3
|
+
import fs from "fs-extra";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { BaseCommand } from "../baseCommand.js";
|
|
6
|
+
class Run extends BaseCommand {
|
|
7
|
+
async run() {
|
|
8
|
+
const { flags } = await this.parse(Run);
|
|
9
|
+
let projectName;
|
|
10
|
+
if (flags["no-backend"]) {
|
|
11
|
+
projectName = "cartesi-node";
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
// get machine hash
|
|
15
|
+
const hash = this.getMachineHash();
|
|
16
|
+
// Check if snapshot exists
|
|
17
|
+
if (!hash) {
|
|
18
|
+
throw new Error(`Cartesi machine snapshot not found, run '${this.config.bin} build'`);
|
|
19
|
+
}
|
|
20
|
+
projectName = hash.substring(2, 10);
|
|
21
|
+
}
|
|
22
|
+
// path of the tool instalation
|
|
23
|
+
const binPath = path.join(path.dirname(new URL(import.meta.url).pathname), "..");
|
|
24
|
+
// setup the environment variable used in docker compose
|
|
25
|
+
const blockInterval = flags["block-time"];
|
|
26
|
+
const epochDuration = flags["epoch-duration"];
|
|
27
|
+
const listenPort = flags["listen-port"];
|
|
28
|
+
const env = {
|
|
29
|
+
ANVIL_VERBOSITY: flags.verbose ? "--steps-tracing" : "--silent",
|
|
30
|
+
BLOCK_TIME: blockInterval.toString(),
|
|
31
|
+
BLOCK_TIMEOUT: (blockInterval + 3).toString(),
|
|
32
|
+
CARTESI_EPOCH_DURATION: epochDuration.toString(),
|
|
33
|
+
CARTESI_EXPERIMENTAL_DISABLE_CONFIG_LOG: flags.verbose
|
|
34
|
+
? "false"
|
|
35
|
+
: "true",
|
|
36
|
+
CARTESI_EXPERIMENTAL_SERVER_MANAGER_BYPASS_LOG: flags.verbose
|
|
37
|
+
? "false"
|
|
38
|
+
: "true",
|
|
39
|
+
CARTESI_LOG_LEVEL: flags.verbose ? "info" : "error",
|
|
40
|
+
CARTESI_SNAPSHOT_DIR: "/usr/share/rollups-node/snapshot",
|
|
41
|
+
CARTESI_BIN_PATH: binPath,
|
|
42
|
+
CARTESI_LISTEN_PORT: listenPort.toString(),
|
|
43
|
+
};
|
|
44
|
+
// validator
|
|
45
|
+
const composeFiles = ["docker-compose-validator.yaml"];
|
|
46
|
+
// prompt
|
|
47
|
+
composeFiles.push("docker-compose-prompt.yaml");
|
|
48
|
+
// database
|
|
49
|
+
composeFiles.push("docker-compose-database.yaml");
|
|
50
|
+
// proxy
|
|
51
|
+
composeFiles.push("docker-compose-proxy.yaml");
|
|
52
|
+
// anvil
|
|
53
|
+
composeFiles.push("docker-compose-anvil.yaml");
|
|
54
|
+
// explorer
|
|
55
|
+
composeFiles.push("docker-compose-explorer.yaml");
|
|
56
|
+
// load the no-backend compose file
|
|
57
|
+
if (flags["no-backend"]) {
|
|
58
|
+
composeFiles.push("docker-compose-host.yaml");
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// snapshot volume
|
|
62
|
+
composeFiles.push("docker-compose-snapshot-volume.yaml");
|
|
63
|
+
}
|
|
64
|
+
// add project env file loading
|
|
65
|
+
if (fs.existsSync("./.cartesi.env")) {
|
|
66
|
+
composeFiles.push("docker-compose-envfile.yaml");
|
|
67
|
+
}
|
|
68
|
+
// create the "--file <file>" list
|
|
69
|
+
const files = composeFiles
|
|
70
|
+
.map((f) => ["--file", path.join(binPath, "node", f)])
|
|
71
|
+
.flat();
|
|
72
|
+
const compose_args = [
|
|
73
|
+
"compose",
|
|
74
|
+
...files,
|
|
75
|
+
"--project-directory",
|
|
76
|
+
".",
|
|
77
|
+
"--project-name",
|
|
78
|
+
projectName,
|
|
79
|
+
];
|
|
80
|
+
const up_args = [];
|
|
81
|
+
if (!flags.verbose) {
|
|
82
|
+
compose_args.push("--progress", "quiet");
|
|
83
|
+
up_args.push("--attach", "validator");
|
|
84
|
+
up_args.push("--attach", "prompt");
|
|
85
|
+
}
|
|
86
|
+
// XXX: need this handler, so SIGINT can still call the finally block below
|
|
87
|
+
process.on("SIGINT", () => { });
|
|
88
|
+
try {
|
|
89
|
+
// run compose environment
|
|
90
|
+
await execa("docker", [...compose_args, "up", ...up_args], {
|
|
91
|
+
env,
|
|
92
|
+
stdio: "inherit",
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
// 130 is a graceful shutdown, so we can swallow it
|
|
97
|
+
if (e.exitCode !== 130) {
|
|
98
|
+
throw e;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
// shut it down, including volumes
|
|
103
|
+
await execa("docker", [...compose_args, "down", "--volumes"], {
|
|
104
|
+
env,
|
|
105
|
+
stdio: "inherit",
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
Run.summary = "Run application node.";
|
|
111
|
+
Run.description = "Run a local cartesi node for the application.";
|
|
112
|
+
Run.examples = ["<%= config.bin %> <%= command.id %>"];
|
|
113
|
+
Run.flags = {
|
|
114
|
+
"block-time": Flags.integer({
|
|
115
|
+
description: "interval between blocks (in seconds)",
|
|
116
|
+
default: 5,
|
|
117
|
+
}),
|
|
118
|
+
"epoch-duration": Flags.integer({
|
|
119
|
+
description: "duration of an epoch (in seconds)",
|
|
120
|
+
default: 3600,
|
|
121
|
+
}),
|
|
122
|
+
"no-backend": Flags.boolean({
|
|
123
|
+
description: "Run a node without the application code. Application must be executed by the developer on the host machine, fetching inputs from the node running at http://localhost:5004",
|
|
124
|
+
summary: "run a node without the application code",
|
|
125
|
+
default: false,
|
|
126
|
+
}),
|
|
127
|
+
verbose: Flags.boolean({
|
|
128
|
+
description: "verbose output",
|
|
129
|
+
default: false,
|
|
130
|
+
char: "v",
|
|
131
|
+
}),
|
|
132
|
+
"listen-port": Flags.integer({
|
|
133
|
+
description: "port to listen for incoming connections",
|
|
134
|
+
default: 8080,
|
|
135
|
+
}),
|
|
136
|
+
};
|
|
137
|
+
export default Run;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Address, PublicClient, WalletClient } from "viem";
|
|
2
|
+
import { SendBaseCommand } from "./index.js";
|
|
3
|
+
export default class SendAddress extends SendBaseCommand<typeof SendAddress> {
|
|
4
|
+
static summary: string;
|
|
5
|
+
static description: string;
|
|
6
|
+
static examples: string[];
|
|
7
|
+
send(publicClient: PublicClient, walletClient: WalletClient): Promise<Address>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=dapp-address.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dapp-address.d.ts","sourceRoot":"","sources":["../../../src/commands/send/dapp-address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAM3D,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,eAAe,CAAC,OAAO,WAAW,CAAC;IACxE,MAAM,CAAC,OAAO,SAAiD;IAE/D,MAAM,CAAC,WAAW,SAC4C;IAE9D,MAAM,CAAC,QAAQ,WAA2C;IAE7C,IAAI,CACb,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,YAAY,GAC3B,OAAO,CAAC,OAAO,CAAC;CActB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { dAppAddressRelayAbi, dAppAddressRelayAddress, } from "../../contracts.js";
|
|
2
|
+
import { SendBaseCommand } from "./index.js";
|
|
3
|
+
class SendAddress extends SendBaseCommand {
|
|
4
|
+
async send(publicClient, walletClient) {
|
|
5
|
+
// get dapp address from local node, or ask
|
|
6
|
+
const address = await super.getApplicationAddress();
|
|
7
|
+
const { request } = await publicClient.simulateContract({
|
|
8
|
+
address: dAppAddressRelayAddress,
|
|
9
|
+
abi: dAppAddressRelayAbi,
|
|
10
|
+
functionName: "relayDAppAddress",
|
|
11
|
+
args: [address],
|
|
12
|
+
account: walletClient.account,
|
|
13
|
+
});
|
|
14
|
+
return walletClient.writeContract(request);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
SendAddress.summary = "Send DApp address input to the application.";
|
|
18
|
+
SendAddress.description = "Sends an input to the application with its own address.";
|
|
19
|
+
SendAddress.examples = ["<%= config.bin %> <%= command.id %>"];
|
|
20
|
+
export default SendAddress;
|