Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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/few-carrots-count.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

`cartesi run --default-block` no longer accepts `pending`, which the rollups-node no longer supports. Use `latest`, `safe` or `finalized`.
5 changes: 5 additions & 0 deletions .changeset/hot-rings-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

`cartesi run`'s Build and redeploy no longer fails with "CARTESI_CONTRACTS_APPLICATION_FACTORY_ADDRESS: variable not defined". The CLI now passes the devnet's ApplicationFactory address to the node, which `CARTESI_CONTRACTS_APPLICATION_FACTORY_ADDRESS` can still override.
5 changes: 5 additions & 0 deletions .changeset/lazy-cougars-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": minor
---

`cartesi run --prt` now runs a sling node for each `[[prt.sentries]]` entry with `type = "sling"`, as container `sentry-<label>`, so claims the sentries agree with are accepted without waiting out `--claim-staging-period`. Pool sentries (devnet accounts 20 to 29) are funded with 10,000 ETH by the CLI; an entry with `private_key_file` runs on your own key, whose address becomes the sentry's, and you fund it. The sentries are stopped before a rebuild and started again for the redeployed application.
5 changes: 5 additions & 0 deletions .changeset/mighty-otters-know.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": minor
---

`cartesi send` and `cartesi deposit` now default to devnet account 8 instead of account 0, which the node uses to sign its claims. Pass `--from` to pick another account.
5 changes: 5 additions & 0 deletions .changeset/pretty-lilies-taste.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": minor
---

`cartesi logs` and the shell's View logs now show the PRT sentries next to the node. Name services to pick some, e.g. `cartesi logs sentry-green`.
5 changes: 5 additions & 0 deletions .changeset/quick-dancers-pick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

`CARTESI_*_FILE` key files set on the host now reach the node container as copies the node can read. Before, only the path was forwarded and the node couldn't read the file.
5 changes: 5 additions & 0 deletions .changeset/seven-moments-prove.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": minor
---

Require cartesi-machine 0.22. Machines stored by 0.21 can't be loaded by 0.22: rebuild and redeploy every application.
5 changes: 5 additions & 0 deletions .changeset/stale-clubs-end.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": minor
---

`cartesi run` now rejects a `CARTESI_BLOCKCHAIN_HTTP_ENDPOINT` the rollups-node can't use before starting anything. It must be an http(s) URL with a DNS name or IP address. The error doesn't show the value, which may hold credentials.
5 changes: 5 additions & 0 deletions .changeset/strict-grapes-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

Use the Dave 3.0.0-alpha.6 PRT contracts. Every PRT address moves, including the devnet DaveAppFactory. The rollups contract addresses are unchanged.
5 changes: 5 additions & 0 deletions .changeset/swift-berries-tie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": patch
---

Keep `$` in the `CARTESI_*` variables `cartesi run` forwards to the node and in its `--fork-url`. Docker Compose read `$name` in them as a variable, so a value such as a password or an API key in a URL arrived changed.
5 changes: 5 additions & 0 deletions .changeset/witty-crews-repeat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cartesi/cli": minor
---

`cartesi run --prt` now deploys the application with the PRT sentries set in `cartesi.toml`. A `[prt]` section names an optional `sentry_manager` and `[[prt.sentries]]` entries, appointed on the consensus in that order. An entry with `type = "sling"` and no `address` gets one of the CLI's sentry pool, devnet accounts 20 to 29; an entry with only an `address` is appointed and run elsewhere. Without `--prt` the section is ignored.
29 changes: 29 additions & 0 deletions .github/workflows/cli.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ on:
pull_request:
paths:
- ".github/workflows/cli.yaml"
- ".github/workflows/sdk.yaml"
- "apps/cli/**"
- "packages/sdk/**"
- "packages/tsconfig/**"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
Expand All @@ -13,11 +15,21 @@ permissions:
packages: write
pull-requests: write
jobs:
sdk:
uses: ./.github/workflows/sdk.yaml
secrets: inherit
permissions:
contents: read
packages: write
id-token: write
actions: write
build:
needs: sdk
runs-on: ubuntu-latest
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
SDK_TAG: pr-${{ github.event.pull_request.number }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand All @@ -28,6 +40,20 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1

- name: Login to GitHub Container Registry
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Retag SDK images
run: |
for image in sdk rollups-runtime rollups-database; do
docker pull "ghcr.io/cartesi/$image:$SDK_TAG"
docker tag "ghcr.io/cartesi/$image:$SDK_TAG" "cartesi/$image:$SDK_TAG"
done

- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0

- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
Expand All @@ -45,6 +71,9 @@ jobs:

- name: Test
run: bun test apps/cli/
env:
CARTESI_TEST_SDK: cartesi/sdk:${{ env.SDK_TAG }}
CARTESI_TEST_RUNTIME_VERSION: ${{ env.SDK_TAG }}

- name: Coverage Report
uses: 70-10/bun-coverage-report-action@6173866ce2a31456a726ff3f4c91f230bd94a9e9 # v1.0.3
Expand Down
11 changes: 6 additions & 5 deletions .github/workflows/sdk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,8 @@ on:
required: true
DOCKERHUB_TOKEN:
required: true
pull_request:
paths:
- ".github/workflows/sdk.yaml"
- "packages/sdk/**"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
group: sdk-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
Expand Down Expand Up @@ -83,6 +79,11 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

# WIP: the run id is the script's default, the same one a local
# `bun run build` takes, so CI and reviewers build the same node
- name: Fetch rollups-node packages
run: ./packages/sdk/scripts/fetch-rollups-node.sh

- name: Build and push
uses: docker/bake-action@018cb6412ab401ebaa809aa5f85966b74628600f # v7.4.0
if: ${{ !startsWith(github.ref, 'refs/tags/sdk@') }}
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"/dist"
],
"devDependencies": {
"@cartesi/wagmi-plugin": "1.0.0-alpha.7",
"@cartesi/wagmi-plugin": "1.0.0-alpha.9",
"@commander-js/extra-typings": "^15.0.0",
"@inquirer/confirm": "^6.3.3",
"@inquirer/core": "^12.0.4",
Expand Down
5 changes: 4 additions & 1 deletion apps/cli/src/commands/deposit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ export const createDepositCommand = () => {
const command = new Command("deposit")
.description("Deposits an asset to the application")
.configureHelp({ showGlobalOptions: true })
.option("--from <address>", "input sender address")
.option(
"--from <address>",
"input sender address (default: devnet account 8)",
)
.option("--application <address>", "application address")
.option(
"--project-name <string>",
Expand Down
6 changes: 3 additions & 3 deletions apps/cli/src/commands/deposit/erc1155.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
bigintInput,
getInputApplicationAddress,
} from "../../prompts.js";
import { connect } from "../../wallet.js";
import { connect, getDefaultSender } from "../../wallet.js";
import type { DepositCommandOpts } from "../deposit.js";

type ERC1155Token = {
Expand Down Expand Up @@ -75,7 +75,7 @@ export const createErc1155SingleCommand = () => {
const account =
from && isAddress(from)
? getAddress(from)
: (await testClient.getAddresses())[0];
: await getDefaultSender(testClient);

const amount = amountString
? BigInt(amountString)
Expand Down Expand Up @@ -253,7 +253,7 @@ export const createErc1155BatchCommand = () => {
const account =
from && isAddress(from)
? getAddress(from)
: (await testClient.getAddresses())[0];
: await getDefaultSender(testClient);

const tokenAbi = testMultiTokenAbi;

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 @@ -22,7 +22,7 @@ import {
bigintInput,
getInputApplicationAddress,
} from "../../prompts.js";
import { connect } from "../../wallet.js";
import { connect, getDefaultSender } from "../../wallet.js";
import type { DepositCommandOpts } from "../deposit.js";

type ERC20Token = {
Expand Down Expand Up @@ -93,7 +93,7 @@ export const createErc20Command = () => {
const account =
from && isAddress(from)
? getAddress(from)
: (await testClient.getAddresses())[0];
: await getDefaultSender(testClient);

const token = await parseToken({
testClient,
Expand Down
4 changes: 2 additions & 2 deletions apps/cli/src/commands/deposit/erc721.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
bigintInput,
getInputApplicationAddress,
} from "../../prompts.js";
import { connect } from "../../wallet.js";
import { connect, getDefaultSender } from "../../wallet.js";
import type { DepositCommandOpts } from "../deposit.js";

type ERC721Token = {
Expand Down Expand Up @@ -93,7 +93,7 @@ export const createErc721Command = () => {
const account =
from && isAddress(from)
? getAddress(from)
: (await testClient.getAddresses())[0];
: await getDefaultSender(testClient);

const token = await parseToken({
testClient,
Expand Down
4 changes: 2 additions & 2 deletions apps/cli/src/commands/deposit/ether.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { formatUnits, getAddress, isAddress, isHex, parseUnits } from "viem";
import { getProjectName } from "../../base.js";
import { etherPortalAbi, etherPortalAddress } from "../../contracts.js";
import { bigintInput, getInputApplicationAddress } from "../../prompts.js";
import { connect } from "../../wallet.js";
import { connect, getDefaultSender } from "../../wallet.js";
import type { DepositCommandOpts } from "../deposit.js";

export const createEtherCommand = () => {
Expand All @@ -26,7 +26,7 @@ export const createEtherCommand = () => {
const account =
from && isAddress(from)
? getAddress(from)
: (await testClient.getAddresses())[0];
: await getDefaultSender(testClient);

// get dapp address from local node, or ask
const application = await getInputApplicationAddress({
Expand Down
111 changes: 94 additions & 17 deletions apps/cli/src/commands/logs.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,89 @@
import { Command } from "@commander-js/extra-typings";
import { execa } from "execa";
import { getProjectName, getServiceInfo } from "../base.js";
import { getProjectName } from "../base.js";
import { isSentryService } from "../compose/sentry.js";

/** The node's compose service, shown by default and first. */
export const NODE_SERVICE = "rollups_node";

/**
* The services of a running environment, as compose lists them; an exited
* container is still listed, so its last logs can be read.
*/
export const listServices = async (projectName: string): Promise<string[]> => {
const { stdout } = await execa("docker", [
"compose",
"--project-name",
projectName,
"ps",
"--services",
"--all",
]);
return stdout
.split("\n")
.map((line) => line.trim())
.filter((line) => line.length > 0);
};

/**
* The services to show: the ones named, checked against the environment, or
* the node followed by every sentry.
* @param services the environment's services, from `listServices`
* @param requested the services named on the command line
* @throws when the node isn't there, or a named service isn't
*/
export const selectLogServices = (
services: string[],
requested: string[],
): string[] => {
if (requested.length === 0) {
if (!services.includes(NODE_SERVICE)) {
throw new Error(`service ${NODE_SERVICE} not found`);
}
return [NODE_SERVICE, ...services.filter(isSentryService)];
}
// compose shows nothing for an unknown service, without an error
const unknown = requested.filter((service) => !services.includes(service));
if (unknown.length > 0) {
throw new Error(
`service ${unknown.join(", ")} not found; the environment has ${services.join(", ")}`,
);
}
return requested;
};

/**
* The `docker compose logs` arguments. One service is shown as it is, like
* `docker container logs`; more than one get compose's per-service prefix,
* which tells the node's lines from the sentries'.
*/
export const buildLogsArgs = (options: {
follow?: boolean;
projectName: string;
services: string[];
since?: string;
tail?: string;
until?: string;
}): string[] => {
const { follow, projectName, services, since, tail, until } = options;
const args = ["compose", "--project-name", projectName, "logs"];
if (follow) args.push("--follow");
if (since) args.push("--since", since);
if (tail) args.push("--tail", tail);
if (until) args.push("--until", until);
if (services.length === 1) args.push("--no-log-prefix");
return [...args, ...services];
};

export const createLogsCommand = () => {
return new Command("logs")
.description("Show logs of a local environment.")
.description(
"Show logs of a local environment: the node and its sentries, or the services named.",
)
.argument(
"[service...]",
"services to show, as cartesi run names them (default: the node and the sentries)",
)
.option(
"--project-name <string>",
"name of project (used by docker compose and cartesi-rollups-node)",
Expand All @@ -24,26 +103,24 @@ export const createLogsCommand = () => {
"Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)",
)
.configureHelp({ showGlobalOptions: true })
.action(async (options) => {
.action(async (requested, options) => {
const { follow, since, tail, until } = options;
const projectName = getProjectName(options);
const logOptions: string[] = [];
if (follow) logOptions.push("--follow");
if (since) logOptions.push("--since", since);
if (tail) logOptions.push("--tail", tail);
if (until) logOptions.push("--until", until);

const serviceInfo = await getServiceInfo({
projectName,
service: "rollups_node",
});
if (!serviceInfo) {
throw new Error(`service rollups_node not found`);
}
const services = selectLogServices(
await listServices(projectName),
requested,
);

await execa(
"docker",
["container", "logs", ...logOptions, serviceInfo.ID],
buildLogsArgs({
follow,
projectName,
services,
since,
tail,
until,
}),
{ stdio: "inherit" },
);
});
Expand Down
Loading
Loading