Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
e27c1ab
chore(cli): Add tsconfig.json to help TS recognize node/bun types in …
brunomenezes Jun 3, 2026
2c044a8
chore(cli): Bump @cartesi/devnet to alpha.14 and remove unused @carte…
brunomenezes Jun 3, 2026
9994885
feat(cli): Add the new TestUsdWithdrawalOutputBuilder address to the …
brunomenezes Jun 18, 2026
1c9388f
refactor(cli): Update flash-drive option from filename to data_filena…
brunomenezes Jun 18, 2026
8af2c60
refactor(cli): Recover the machine-hash from the new hash_tree.sht file.
brunomenezes Jun 18, 2026
d5c0edc
feat(cli): Add support to withdrawal-config through a toml file.
brunomenezes Jun 18, 2026
7c19db6
feat(cli): Add support to claim-staging-period and withdrawal-config …
brunomenezes Jun 18, 2026
80ac676
feat(cli): Refactor state for status and make room to the new enabled…
brunomenezes Jun 18, 2026
f01ff31
feat(cli): Add CORS configuration to the node proxy docker compose to…
brunomenezes Jun 18, 2026
dcf79de
feat(cli): Bump default sdk version to 0.12.0-alpha.41
brunomenezes Jun 18, 2026
4c193a2
refactor(cli): Remove node compose environment variable CARTESI_BLOCK…
brunomenezes Jun 19, 2026
612b1b2
refactor(cli): Add tty docker-option when using shell command.
brunomenezes Jun 19, 2026
40e29d6
feat(cli): Add support to load environment variables prefix with CART…
brunomenezes Jun 19, 2026
02bbb94
feat(cli): Add new flag to RUN command to return information about su…
brunomenezes Jun 19, 2026
dadcc2a
fix(cli): Remove non-existing flag --no-rollup that is pass down to t…
brunomenezes Jun 22, 2026
afe3049
chore(devnet): Use expected types.
brunomenezes Jun 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/busy-rats-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

Add support to read and check a withdrawal config through a toml file.
5 changes: 5 additions & 0 deletions .changeset/chubby-tires-melt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

Update docker flag by adding tty when using the shell command. It fixes "unable to open a TTY" error returned by cartesi-machine.
5 changes: 5 additions & 0 deletions .changeset/clever-bees-taste.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

Bump cartesi/sdk image to version 0.12.0-alpha.41.
5 changes: 5 additions & 0 deletions .changeset/funny-words-occur.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

Remove CARTESI_BLOCKCHAIN_WS_ENDPOINT environment variable from the node docker compose file construction. It is not supported by rollups-node alpha.12
5 changes: 5 additions & 0 deletions .changeset/good-dodos-love.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

Bump @cartesi/devnet package to alpha.14 and remove @cartesi/rollups package.
5 changes: 5 additions & 0 deletions .changeset/huge-games-fail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

Refactor how to retrieve the machine-hash from the image built. the hash file is not generated in the new emulator 0.20.0, instead it generates a hash_tree.sht file where the hash is.
5 changes: 5 additions & 0 deletions .changeset/legal-dragons-agree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

Add new TestUsdWithdrawalOutputBuilder to be listed in the address-book. Also, refactor deposits ERC-20 and ERC-721 to use new Fungible and non-fungible test token addresses.
5 changes: 5 additions & 0 deletions .changeset/light-singers-slide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

Add CORS declaration to the node proxy rules when building the docker compose file.
6 changes: 6 additions & 0 deletions .changeset/lucky-otters-write.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@cartesi/cli": patch
---

Add support to modify rollups-node environment variables by setting your own CARTESI\_\* environment variables in the host machine e.g. CARTESI_AUTH_MNEMONIC and CARTESI_AUTH_MNEMONIC_ACCOUNT_INDEX. This facilitates configuration when testing foreclosure/emergency-withdraws.

5 changes: 5 additions & 0 deletions .changeset/metal-otters-say.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

Add new --list-supported-variables to RUN command to return a JSON object by service listing all supported variables to that specific service e.g. rollups-node
5 changes: 5 additions & 0 deletions .changeset/soft-trees-think.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

Refactor Status command to use status instead of state and also display the new enabled property. Status and enabled are separated in intent.
5 changes: 5 additions & 0 deletions .changeset/spotty-clowns-draw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

Add support to withdrawal-config and way to setup claim-staging-period (Authority/Quorum only) when using the RUN command.
5 changes: 5 additions & 0 deletions .changeset/strong-eyes-glow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

Remove --no-rollup flag pass down to the cartesi-machine as this flag does not exist on 0.19 and 0.20 versions.
5 changes: 5 additions & 0 deletions .changeset/weak-tigers-shine.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

Update flashdrive label option from filename to data_filename. Also bump required-version for cartesi-machine tests to 0.20.0
3 changes: 1 addition & 2 deletions apps/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@
"yaml": "^2.8.2"
},
"devDependencies": {
"@cartesi/devnet": "2.0.0-alpha.11",
"@cartesi/rollups": "2.2.0",
"@cartesi/devnet": "2.0.0-alpha.14",
"@sunodo/wagmi-plugin-hardhat-deploy": "^0.4.0",
"@types/bun": "^1.3.6",
"@types/bytes": "^3.1.5",
Expand Down
41 changes: 33 additions & 8 deletions apps/cli/src/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ import {
etherPortalAddress,
inputBoxAddress,
selfHostedApplicationFactoryAddress,
testFungibleTokenAddress,
testMultiTokenAddress,
testNftAddress,
testTokenAddress,
testNonFungibleTokenAddress,
testUsdWithdrawalOutputBuilderAddress,
} from "./contracts.js";
import { getApplicationAddress, getForkChainId } from "./exec/rollups.js";
import type { PsResponse } from "./types/docker.js";
Expand All @@ -35,11 +36,18 @@ export const getContextPath = (...paths: string[]): string => {

export const getMachineHash = (): Hash | undefined => {
// read hash of the cartesi machine snapshot, if one exists
const hashPath = getContextPath("image", "hash");
const hashPath = getContextPath("image", "hash_tree.sht");
if (fs.existsSync(hashPath)) {
const hash = fs.readFileSync(hashPath).toString("hex");
if (isHash(`0x${hash}`)) {
return `0x${hash}`;
const fileBuffer = fs.readFileSync(hashPath);
const hashLength = 32;
// root hash is located at this offset (0x60)
const offset = 0x60;

const hashBuffer = fileBuffer.subarray(offset, offset + hashLength);
const hash = `0x${hashBuffer.toString("hex")}`;

if (isHash(hash)) {
return hash;
}
}
return undefined;
Expand All @@ -62,6 +70,22 @@ export const getProjectName = (options: { projectName?: string }) => {
return options.projectName ?? path.basename(process.cwd());
};

export type CartesiEnvironmentVariables = Record<string, string>;
/**
* Generic function to get all environment variables that start with "CARTESI_"
* It is the responsibility of the caller to filter and use only the relevant variables.
* @returns A record of environment variables with keys starting with "CARTESI_"
*/
export function getCartesiEnvironmentVariables(): CartesiEnvironmentVariables {
const env: CartesiEnvironmentVariables = {};
for (const [key, value] of Object.entries(process.env)) {
if (key.startsWith("CARTESI_") && value !== undefined) {
env[key] = value;
}
}
return env;
}

export type AddressBook = Record<string, Address>;

export const getAddressBook = async (options: {
Expand Down Expand Up @@ -99,9 +123,10 @@ export const getAddressBook = async (options: {

// contracts that are present only on devnet state
const devnetContracts: AddressBook = {
TestToken: testTokenAddress,
TestNFT: testNftAddress,
TestToken: testFungibleTokenAddress,
TestNFT: testNonFungibleTokenAddress,
TestMultiToken: testMultiTokenAddress,
TestUsdWithdrawalOutputBuilder: testUsdWithdrawalOutputBuilderAddress,
};

// contracts that are present on both devnet and live chains
Expand Down
4 changes: 2 additions & 2 deletions apps/cli/src/commands/deposit/erc20.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { getProjectName } from "../../base.js";
import {
erc20PortalAbi,
erc20PortalAddress,
testTokenAddress,
testFungibleTokenAddress,
} from "../../contracts.js";
import {
addressInput,
Expand Down Expand Up @@ -68,7 +68,7 @@ const parseToken = async (options: {
? getAddress(options.token)
: await addressInput({
message: "Token address",
default: testTokenAddress,
default: testFungibleTokenAddress,
});

return readToken(testClient, address);
Expand Down
10 changes: 6 additions & 4 deletions apps/cli/src/commands/deposit/erc721.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import { getProjectName } from "../../base.js";
import {
erc721PortalAbi,
erc721PortalAddress,
testNftAbi,
testNftAddress,
testNonFungibleTokenAbi,
testNonFungibleTokenAddress,
} from "../../contracts.js";
import {
addressInput,
Expand Down Expand Up @@ -63,7 +63,7 @@ const parseToken = async (options: {
? getAddress(options.token)
: await addressInput({
message: "Token address",
default: testNftAddress,
default: testNonFungibleTokenAddress,
});

return readToken(testClient, address);
Expand Down Expand Up @@ -100,7 +100,9 @@ export const createErc721Command = () => {
token: options.token,
});
const tokenAbi =
token.address === testNftAddress ? testNftAbi : erc721Abi;
token.address === testNonFungibleTokenAddress
? testNonFungibleTokenAbi
: erc721Abi;

// get dapp address from local node, or ask
const application = await getInputApplicationAddress({
Expand Down
83 changes: 79 additions & 4 deletions apps/cli/src/commands/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,17 @@ import {
http,
numberToHex,
} from "viem";
import { getMachineHash, getProjectName } from "../base.js";
import { DEFAULT_SDK_VERSION, PREFERRED_PORT } from "../config.js";
import {
getApplicationConfig,
getMachineHash,
getProjectName,
} from "../base.js";
import { nodeAllowedEnvironmentVariables } from "../compose/node.js";
import {
DEFAULT_SDK_VERSION,
PREFERRED_PORT,
type WithdrawalConfig,
} from "../config.js";
import {
AVAILABLE_SERVICES,
deployApplication,
Expand Down Expand Up @@ -45,8 +54,18 @@ const shell = async (options: {
projectName: string;
prt?: boolean;
salt: number;
withdrawalConfig?: WithdrawalConfig;
claimStagingPeriod: number;
}) => {
const { build, epochLength, log, projectName, prt } = options;
const {
build,
epochLength,
log,
projectName,
prt,
withdrawalConfig,
claimStagingPeriod,
} = options;

let lastDeployment = options.deployment;
let salt = options.salt;
Expand Down Expand Up @@ -100,6 +119,8 @@ const shell = async (options: {
projectName,
prt,
salt: numberToHex(salt++, { size: 32 }),
withdrawalConfig,
claimStagingPeriod,
});
}

Expand Down Expand Up @@ -137,8 +158,19 @@ const deploy = async (options: {
projectName: string;
prt?: boolean;
salt: Hex;
withdrawalConfig?: WithdrawalConfig;
claimStagingPeriod: number;
}) => {
const { consensus, epochLength, hash, projectName, prt, salt } = options;
const {
consensus,
epochLength,
hash,
projectName,
prt,
salt,
withdrawalConfig,
claimStagingPeriod,
} = options;

// deploy application to node (onchain and offchain)
const progress = ora(
Expand All @@ -153,6 +185,8 @@ const deploy = async (options: {
prt,
salt,
snapshotPath: "/var/lib/cartesi-rollups-node/snapshots/image",
withdrawalConfig,
claimStagingPeriod,
});
progress.succeed(
`${chalk.cyan(projectName)} machine hash is ${chalk.cyan(hash)}`,
Expand Down Expand Up @@ -221,6 +255,11 @@ export const createRunCommand = () => {
.default("latest"),
)
.option("--dry-run", "show the docker compose configuration", false)
.option(
"--list-supported-variables",
"Returns JSON formatted information about the environment variables allowed and which service will use them.",
false,
)
.option("--fork-url <url>", "RPC URL to fork from")
.addOption(
new Option(
Expand All @@ -243,6 +282,20 @@ export const createRunCommand = () => {
.default(720),
)
.option("-p, --port <number>", "port to listen on", Number)
.addOption(
new Option(
"--claim-staging-period <number>",
"claim staging period (in blocks). Number of blocks between a claim being submitted and accepted (Authority/Quorum Only)",
)
.argParser(Number)
.default(0),
)
.option(
"-c, --config <config>",
"Path to the configuration file (.toml)",
(value, prev) => prev.concat([value]),
["cartesi.toml"],
)
.addOption(
new Option(
"--runtime-version <version>",
Expand Down Expand Up @@ -274,10 +327,25 @@ export const createRunCommand = () => {
runtimeVersion,
services,
verbose,
listSupportedVariables,
claimStagingPeriod,
config: configFiles,
} = options;

const progress = ora();

if (listSupportedVariables) {
const allowedVarsByService = {
rollupsNode: nodeAllowedEnvironmentVariables,
};

// output the allowed environment variables by service in a JSON format and quit
process.stdout.write(
JSON.stringify(allowedVarsByService, null, 2),
);
Comment thread
endersonmaia marked this conversation as resolved.
return;
}

if (defaultBlock !== "finalized") {
console.warn(
chalk.yellow(
Expand All @@ -289,6 +357,9 @@ export const createRunCommand = () => {
// project name explicitly defined or the current directory name
const projectName = getProjectName(options);

// get application configuration (e.g. use withdrawal config if present)
const applicationConfig = getApplicationConfig(configFiles);

// resolve port number, using the first free port in a range, unless explicitly set
const port =
options.port ||
Expand Down Expand Up @@ -351,6 +422,8 @@ export const createRunCommand = () => {
projectName,
prt,
salt: numberToHex(salt++, { size: 32 }),
claimStagingPeriod,
withdrawalConfig: applicationConfig?.withdrawalConfig,
});
} else {
console.warn(
Expand Down Expand Up @@ -392,6 +465,8 @@ export const createRunCommand = () => {
projectName,
prt,
salt,
claimStagingPeriod,
withdrawalConfig: applicationConfig?.withdrawalConfig,
});
await shutdown();
} else {
Expand Down
1 change: 1 addition & 0 deletions apps/cli/src/commands/shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const createShellCommand = () => {
{
cwd: destination,
stdio: "inherit",
tty: true,
},
);
} catch (error: unknown) {
Expand Down
Loading
Loading