From eec3f5946a48150a510f2a2c0fa1bc402d5cc949 Mon Sep 17 00:00:00 2001 From: Danilo Tuler Date: Mon, 9 Jun 2025 19:22:43 -0400 Subject: [PATCH 1/3] feat(devnet): porto service --- packages/devnet/cannonfile.toml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/devnet/cannonfile.toml b/packages/devnet/cannonfile.toml index 5d7d12f4..bf6692f1 100644 --- a/packages/devnet/cannonfile.toml +++ b/packages/devnet/cannonfile.toml @@ -77,6 +77,12 @@ source = "alchemy-light-account:2.0.0@main" [pull.alchemyModularAccountV2] source = "alchemy-modular-account:2.0.0@main" +[pull.portoAccount] +source = "porto-account:0.2.0@main" + +[pull.portoDemo] +source = "porto-demo:0.0.28@main" + [var.Settings] token_owner = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" From de790538b44fa60df8de2893a1c3498a2a5cd6e1 Mon Sep 17 00:00:00 2001 From: Danilo Tuler Date: Mon, 9 Jun 2025 19:21:44 -0400 Subject: [PATCH 2/3] feat(sdk): porto service --- packages/sdk/Dockerfile | 21 +++++++++++++++++++++ packages/sdk/docker-bake.hcl | 1 + 2 files changed, 22 insertions(+) diff --git a/packages/sdk/Dockerfile b/packages/sdk/Dockerfile index 3822205e..d4acdc04 100644 --- a/packages/sdk/Dockerfile +++ b/packages/sdk/Dockerfile @@ -215,6 +215,22 @@ RUN /usr/local/bin/docker-ensure-initdb.sh postgres FROM ${POSTGRES_BASE_IMAGE} AS rollups-database COPY --from=postgresql-initdb /var/lib/postgresql/data /var/lib/postgresql/data +################################################################################ +# porto build +FROM node:${NODE_VERSION} AS porto +ARG PORTO_VERSION + +WORKDIR /src/app + +RUN < Date: Mon, 9 Jun 2025 19:22:38 -0400 Subject: [PATCH 3/3] feat(cli): porto service --- .../cli/src/compose/docker-compose-anvil.yaml | 2 +- .../cli/src/compose/docker-compose-porto.yaml | 74 +++++++++++++++++++ .../cli/src/compose/docker-compose-proxy.yaml | 5 +- apps/cli/src/compose/porto/proxy.ts | 20 +++++ apps/cli/src/compose/porto/registry.yaml | 6 ++ apps/cli/src/compose/porto/relay.yaml | 43 +++++++++++ apps/cli/src/compose/proxy/porto.yaml | 55 ++++++++++++++ apps/cli/src/exec/rollups.ts | 9 +++ 8 files changed, 211 insertions(+), 3 deletions(-) create mode 100644 apps/cli/src/compose/docker-compose-porto.yaml create mode 100644 apps/cli/src/compose/porto/proxy.ts create mode 100644 apps/cli/src/compose/porto/registry.yaml create mode 100644 apps/cli/src/compose/porto/relay.yaml create mode 100644 apps/cli/src/compose/proxy/porto.yaml diff --git a/apps/cli/src/compose/docker-compose-anvil.yaml b/apps/cli/src/compose/docker-compose-anvil.yaml index 4e024fbd..5b35bd8f 100644 --- a/apps/cli/src/compose/docker-compose-anvil.yaml +++ b/apps/cli/src/compose/docker-compose-anvil.yaml @@ -22,7 +22,7 @@ configs: services: anvil: image: ${CARTESI_SDK_IMAGE} - command: ["devnet", "--block-time", "${CARTESI_BLOCK_TIME:-2}"] + command: ["devnet", "--odyssey", "--block-time", "${CARTESI_BLOCK_TIME:-2}"] healthcheck: test: ["CMD", "eth_isready"] start_period: 10s diff --git a/apps/cli/src/compose/docker-compose-porto.yaml b/apps/cli/src/compose/docker-compose-porto.yaml new file mode 100644 index 00000000..abf79b14 --- /dev/null +++ b/apps/cli/src/compose/docker-compose-porto.yaml @@ -0,0 +1,74 @@ +services: + porto-relay: + image: ghcr.io/ithacaxyz/relay:3fc0de2 + platform: linux/x86_64 + depends_on: + anvil: + condition: service_healthy + expose: + - 9119 + environment: + RUST_LOG: warn + RELAY_MNEMONIC: ${CARTESI_AUTH_MNEMONIC:-test test test test test test test test test test test junk} + command: ["--config-only"] + healthcheck: + test: + [ + "CMD", + "cast", + "rpc", + "--rpc-url", + "http://localhost:9119", + "health", + ] + interval: 2s + retries: 5 + volumes: + - ./porto:/app + + porto-rpc: + image: oven/bun:latest + expose: + - 9220 + volumes: + - ./porto/proxy.ts:/app/proxy.ts + command: ["bun", "run", "/app/proxy.ts"] + depends_on: + anvil: + condition: service_healthy + environment: + PORT: 9220 + RELAY_URL: http://porto-relay:9119 + ANVIL_URL: http://anvil:8545 + + porto-dialog: + image: ${CARTESI_SDK_IMAGE} + command: + ["busybox", "httpd", "-f", "-h", "/usr/share/porto/dialog", "-vv"] + expose: + - 80 + healthcheck: + test: ["CMD", "curl", "-fsS", "http://127.0.0.1/"] + start_period: 10s + start_interval: 200ms + interval: 10s + timeout: 1s + retries: 5 + + porto-manager: + image: ${CARTESI_SDK_IMAGE} + command: + ["busybox", "httpd", "-f", "-h", "/usr/share/porto/manager", "-vv"] + expose: + - 80 + healthcheck: + test: ["CMD", "curl", "-fsS", "http://127.0.0.1/"] + start_period: 10s + start_interval: 200ms + interval: 10s + timeout: 1s + retries: 5 + + proxy: + volumes: + - ./proxy/porto.yaml:/etc/traefik/conf.d/porto.yaml diff --git a/apps/cli/src/compose/docker-compose-proxy.yaml b/apps/cli/src/compose/docker-compose-proxy.yaml index 4d1012aa..e6d98637 100644 --- a/apps/cli/src/compose/docker-compose-proxy.yaml +++ b/apps/cli/src/compose/docker-compose-proxy.yaml @@ -1,6 +1,6 @@ services: proxy: - image: traefik:v3.3.4 + image: traefik:v3.4.1 healthcheck: test: ["CMD", "traefik", "healthcheck", "--ping"] start_period: 10s @@ -18,7 +18,8 @@ services: "--providers.file.directory=/etc/traefik/conf.d", "--providers.file.watch=true", "--log", - "--log.level=INFO", + "--log.level=DEBUG", + "--accesslog=true", ] ports: - ${CARTESI_LISTEN_PORT:-6751}:8088 diff --git a/apps/cli/src/compose/porto/proxy.ts b/apps/cli/src/compose/porto/proxy.ts new file mode 100644 index 00000000..95c9ff2a --- /dev/null +++ b/apps/cli/src/compose/porto/proxy.ts @@ -0,0 +1,20 @@ +Bun.serve({ + async fetch(request) { + if (request.method === "GET") return new Response("Nada"); + + const body = await request.json(); + const target = + body.method && + (body.method.startsWith("wallet_") || body.method === "health") + ? Bun.env.RELAY_URL! + : Bun.env.ANVIL_URL!; + return fetch(target, { + body: JSON.stringify(body), + headers: { + "Content-Type": "application/json", + }, + method: "POST", + }); + }, + port: Number(Bun.env.PORT!), +}); diff --git a/apps/cli/src/compose/porto/registry.yaml b/apps/cli/src/compose/porto/registry.yaml new file mode 100644 index 00000000..187d513e --- /dev/null +++ b/apps/cli/src/compose/porto/registry.yaml @@ -0,0 +1,6 @@ +"13370": + - address: 0x700b6A60ce7EaaEA56F065753d8dcB9653dbAD35 + kind: USDT + - address: 0xA15BB66138824a1c7167f5E85b957d04Dd34E468 + kind: USDT + - kind: ETH diff --git a/apps/cli/src/compose/porto/relay.yaml b/apps/cli/src/compose/porto/relay.yaml new file mode 100644 index 00000000..e4cbbec1 --- /dev/null +++ b/apps/cli/src/compose/porto/relay.yaml @@ -0,0 +1,43 @@ +server: + address: 0.0.0.0 + port: 9119 + metrics_port: 9120 + max_connections: 5000 +chain: + endpoints: + - http://anvil:8545 + sequencer_endpoints: {} + fee_tokens: + - "0x0000000000000000000000000000000000000000" + - "0x700b6A60ce7EaaEA56F065753d8dcB9653dbAD35" + - "0xA15BB66138824a1c7167f5E85b957d04Dd34E468" + fee_recipient: "0x0000000000000000000000000000000000000000" +quote: + constantRate: 1.0 + gas: + intentBuffer: 100000 + txBuffer: 100000 + ttl: 30 + rateTtl: 300 +onramp: + banxa: + apiUrl: https://api.banxa-sandbox.com/ + blockchain: base + secrets: + api_key: "" +transactions: + num_signers: 16 + max_pending_transactions: 100 + max_transactions_per_signer: 16 + max_queued_per_eoa: 1 + balance_check_interval: 5 + nonce_check_interval: 60 + transaction_timeout: 60 + public_node_endpoints: {} + priority_fee_percentile: 20 +orchestrator: "0xA16c8d51c3E2e80509489eF5147d30b33Af4E233" +legacy_orchestrators: [] +legacy_delegations: [] +delegation_proxy: "0x4F3Ab48173433c831741262Ac71B6c78D6d0C622" +simulator: "0xDe8e1bF42165bB8223DC3889AE0901D966834F41" +database_url: null diff --git a/apps/cli/src/compose/proxy/porto.yaml b/apps/cli/src/compose/proxy/porto.yaml new file mode 100644 index 00000000..ab064058 --- /dev/null +++ b/apps/cli/src/compose/proxy/porto.yaml @@ -0,0 +1,55 @@ +http: + routers: + porto-rpc: + rule: "Path(`/porto/rpc`)" + middlewares: + - cors + - remove-porto-rpc-prefix + service: porto-rpc + porto-dialog: + rule: "PathPrefix(`/porto/dialog`)" + middlewares: + - remove-porto-dialog-prefix + service: porto-dialog + porto-manager: + rule: "PathPrefix(`/porto/manager`)" + middlewares: + - remove-porto-manager-prefix + service: porto-manager + middlewares: + remove-porto-rpc-prefix: + replacePathRegex: + regex: "^/porto/rpc" + replacement: "" + remove-porto-dialog-prefix: + replacePathRegex: + regex: "^/porto/dialog/(.*)" + replacement: "/$1" + remove-porto-manager-prefix: + replacePathRegex: + regex: "^/porto/manager/(.*)" + replacement: "/$1" + cors: + headers: + accessControlAllowMethods: + - GET + - OPTIONS + - PUT + accessControlAllowHeaders: "*" + accessControlAllowOriginList: + - "*" + accessControlMaxAge: 100 + addVaryHeader: true + services: + porto-rpc: + loadBalancer: + servers: + - url: "http://porto-rpc:9220" + porto-dialog: + loadBalancer: + servers: + - url: "http://porto-dialog:80" + porto-manager: + loadBalancer: + servers: + - url: "http://porto-manager:80" diff --git a/apps/cli/src/exec/rollups.ts b/apps/cli/src/exec/rollups.ts index 8ec7c15b..4a36b8d5 100644 --- a/apps/cli/src/exec/rollups.ts +++ b/apps/cli/src/exec/rollups.ts @@ -188,6 +188,15 @@ const availableServices: Service[] = [ waitTitle: `${chalk.cyan("passkey")} service starting...`, errorTitle: `${chalk.red("passkey")} service failed`, }, + { + name: "porto", + file: "docker-compose-porto.yaml", + healthySemaphore: "porto-relay", + healthyTitle: (port) => + `${chalk.cyan("porto")} service ready at ${chalk.cyan(`${host}:${port}/porto/{rpc,dialog,manager}`)}`, + waitTitle: `${chalk.cyan("porto")} service starting...`, + errorTitle: `${chalk.red("porto")} service failed`, + }, ]; export const AVAILABLE_SERVICES = availableServices.map(({ name }) => name);