From 18d63e14d75a5ad5ab82e4c743cb4b57684b8533 Mon Sep 17 00:00:00 2001 From: johba Date: Wed, 24 Sep 2025 10:57:22 +0200 Subject: [PATCH 1/3] podman wip --- containers/Caddyfile | 15 ++ containers/anvil-entrypoint.sh | 14 ++ containers/bootstrap.sh | 199 ++++++++++++++++++++++++++ containers/foundry.Containerfile | 25 ++++ containers/frontend-dev-entrypoint.sh | 32 +++++ containers/node-dev.Containerfile | 11 ++ containers/ponder-dev-entrypoint.sh | 22 +++ containers/txn-bot-entrypoint.sh | 19 +++ docs/podman.md | 44 ++++++ podman-compose.yml | 101 +++++++++++++ 10 files changed, 482 insertions(+) create mode 100644 containers/Caddyfile create mode 100755 containers/anvil-entrypoint.sh create mode 100755 containers/bootstrap.sh create mode 100644 containers/foundry.Containerfile create mode 100755 containers/frontend-dev-entrypoint.sh create mode 100644 containers/node-dev.Containerfile create mode 100755 containers/ponder-dev-entrypoint.sh create mode 100755 containers/txn-bot-entrypoint.sh create mode 100644 docs/podman.md create mode 100644 podman-compose.yml diff --git a/containers/Caddyfile b/containers/Caddyfile new file mode 100644 index 0000000..a8197c1 --- /dev/null +++ b/containers/Caddyfile @@ -0,0 +1,15 @@ +:80 { + route /graphql* { + reverse_proxy ponder:42069 + } + route /health* { + reverse_proxy ponder:42069 + } + route /rpc/anvil* { + reverse_proxy anvil:8545 + } + route /txn* { + reverse_proxy txn-bot:43069 + } + reverse_proxy frontend:5173 +} diff --git a/containers/anvil-entrypoint.sh b/containers/anvil-entrypoint.sh new file mode 100755 index 0000000..8a1a541 --- /dev/null +++ b/containers/anvil-entrypoint.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -euo pipefail + +MNEMONIC_FILE=/workspace/onchain/.secret.local +ANVIL_CMD=(anvil --fork-url "${FORK_URL:-https://sepolia.base.org}" --chain-id 31337 --block-time 1 --host 0.0.0.0 --port 8545) + +if [[ -f "$MNEMONIC_FILE" ]]; then + MNEMONIC="$(tr -d '\n\r' <"$MNEMONIC_FILE")" + if [[ -n "$MNEMONIC" ]]; then + ANVIL_CMD+=(--mnemonic "$MNEMONIC") + fi +fi + +exec "${ANVIL_CMD[@]}" diff --git a/containers/bootstrap.sh b/containers/bootstrap.sh new file mode 100755 index 0000000..c7b32c8 --- /dev/null +++ b/containers/bootstrap.sh @@ -0,0 +1,199 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR=/workspace +STATE_DIR=$ROOT_DIR/tmp/podman +LOG_DIR=$STATE_DIR/logs +SETUP_LOG=$LOG_DIR/setup.log +CONTRACT_ENV=$STATE_DIR/contracts.env +TXNBOT_ENV=$STATE_DIR/txnBot.env +MNEMONIC_FILE=$ROOT_DIR/onchain/.secret.local + +mkdir -p "$LOG_DIR" +: >"$SETUP_LOG" + +ANVIL_RPC=${ANVIL_RPC:-"http://anvil:8545"} +FEE_DEST=0xf6a3eef9088A255c32b6aD2025f83E57291D9011 +WETH=0x4200000000000000000000000000000000000006 +SWAP_ROUTER=0x94cC0AaC535CCDB3C01d6787D6413C739ae12bc4 +MAX_UINT=0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + +DEFAULT_DEPLOYER_PK=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +DEFAULT_DEPLOYER_ADDR=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 +DEPLOYER_PK=${DEPLOYER_PK:-$DEFAULT_DEPLOYER_PK} +DEPLOYER_ADDR=${DEPLOYER_ADDR:-$DEFAULT_DEPLOYER_ADDR} + +DEFAULT_TXNBOT_PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d +DEFAULT_TXNBOT_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 +TXNBOT_PRIVATE_KEY=${TXNBOT_PRIVATE_KEY:-$DEFAULT_TXNBOT_PRIVATE_KEY} +TXNBOT_ADDRESS=${TXNBOT_ADDRESS:-$DEFAULT_TXNBOT_ADDRESS} +TXNBOT_FUND_VALUE=${TXNBOT_FUND_VALUE:-1ether} + +log() { + echo "[bootstrap] $*" +} + +wait_for_rpc() { + for _ in {1..120}; do + if curl -s -o /dev/null -X POST "$ANVIL_RPC" \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'; then + return 0 + fi + sleep 1 + done + log "Timed out waiting for Anvil at $ANVIL_RPC" + return 1 +} + +maybe_set_deployer_from_mnemonic() { + if [[ -n "$DEPLOYER_PK" && -n "$DEPLOYER_ADDR" ]]; then + return + fi + if [[ -f "$MNEMONIC_FILE" ]]; then + local mnemonic pk addr + mnemonic="$(tr -d '\n\r' <"$MNEMONIC_FILE")" + if [[ -n "$mnemonic" ]]; then + pk="$(cast wallet private-key --mnemonic "$mnemonic" --mnemonic-derivation-path "m/44'/60'/0'/0/0")" + addr="$(cast wallet address --private-key "$pk")" + DEPLOYER_PK=${DEPLOYER_PK:-$pk} + DEPLOYER_ADDR=${DEPLOYER_ADDR:-$addr} + fi + fi + DEPLOYER_PK=${DEPLOYER_PK:-$DEFAULT_DEPLOYER_PK} + DEPLOYER_ADDR=${DEPLOYER_ADDR:-$DEFAULT_DEPLOYER_ADDR} +} + +run_forge_script() { + log "Deploying contracts to fork" + pushd "$ROOT_DIR/onchain" >/dev/null + forge script script/DeployLocal.sol --fork-url "$ANVIL_RPC" --broadcast >>"$SETUP_LOG" 2>&1 + popd >/dev/null +} + +extract_addresses() { + local run_file + run_file="$(ls -t "$ROOT_DIR/onchain/broadcast/DeployLocal.sol"/*/run-latest.json 2>/dev/null | head -n1)" + if [[ -z "$run_file" ]]; then + log "Deployment artifact not found" + exit 1 + fi + log "Using artifact ${run_file#$ROOT_DIR/}" + LIQUIDITY_MANAGER="$(jq -r '.transactions[] | select(.contractName=="LiquidityManager") | .contractAddress' "$run_file" | head -n1)" + KRAIKEN="$(jq -r '.transactions[] | select(.contractName=="Kraiken") | .contractAddress' "$run_file" | head -n1)" + STAKE="$(jq -r '.transactions[] | select(.contractName=="Stake") | .contractAddress' "$run_file" | head -n1)" + DEPLOY_BLOCK="$(jq -r '.receipts[0].blockNumber' "$run_file" | xargs printf "%d")" + if [[ -z "$LIQUIDITY_MANAGER" || "$LIQUIDITY_MANAGER" == "null" ]]; then + log "LiquidityManager address missing" + exit 1 + fi + cat >"$CONTRACT_ENV" <>"$SETUP_LOG" 2>&1 +} + +grant_recenter_access() { + log "Granting recenter access" + cast rpc --rpc-url "$ANVIL_RPC" anvil_impersonateAccount "$FEE_DEST" >>"$SETUP_LOG" 2>&1 + cast send --rpc-url "$ANVIL_RPC" --from "$FEE_DEST" --unlocked \ + "$LIQUIDITY_MANAGER" "setRecenterAccess(address)" "$DEPLOYER_ADDR" >>"$SETUP_LOG" 2>&1 + cast rpc --rpc-url "$ANVIL_RPC" anvil_stopImpersonatingAccount "$FEE_DEST" >>"$SETUP_LOG" 2>&1 + if [[ -n "$TXNBOT_ADDRESS" ]]; then + cast rpc --rpc-url "$ANVIL_RPC" anvil_impersonateAccount "$FEE_DEST" >>"$SETUP_LOG" 2>&1 + cast send --rpc-url "$ANVIL_RPC" --from "$FEE_DEST" --unlocked \ + "$LIQUIDITY_MANAGER" "setRecenterAccess(address)" "$TXNBOT_ADDRESS" >>"$SETUP_LOG" 2>&1 + cast rpc --rpc-url "$ANVIL_RPC" anvil_stopImpersonatingAccount "$FEE_DEST" >>"$SETUP_LOG" 2>&1 + fi +} + +call_recenter() { + log "Calling recenter()" + cast send --rpc-url "$ANVIL_RPC" --private-key "$DEPLOYER_PK" \ + "$LIQUIDITY_MANAGER" "recenter()" >>"$SETUP_LOG" 2>&1 +} + +seed_application_state() { + log "Wrapping ETH to WETH" + cast send --rpc-url "$ANVIL_RPC" --private-key "$DEPLOYER_PK" \ + "$WETH" "deposit()" --value 0.02ether >>"$SETUP_LOG" 2>&1 + log "Approving router" + cast send --rpc-url "$ANVIL_RPC" --private-key "$DEPLOYER_PK" \ + "$WETH" "approve(address,uint256)" "$SWAP_ROUTER" "$MAX_UINT" >>"$SETUP_LOG" 2>&1 + log "Executing initial KRK swap" + cast send --legacy --gas-limit 300000 --rpc-url "$ANVIL_RPC" --private-key "$DEPLOYER_PK" \ + "$SWAP_ROUTER" "exactInputSingle((address,address,uint24,address,uint256,uint256,uint160))" \ + "($WETH,$KRAIKEN,10000,$DEPLOYER_ADDR,10000000000000000,0,0)" >>"$SETUP_LOG" 2>&1 +} + +prime_chain() { + log "Pre-mining blocks" + for _ in {1..1200}; do + cast rpc --rpc-url "$ANVIL_RPC" evm_mine >/dev/null 2>&1 || true + done +} + +write_ponder_env() { + cat >"$ROOT_DIR/services/ponder/.env.local" <"$TXNBOT_ENV" <>"$SETUP_LOG" 2>&1 || true + local wei hex + wei="$(cast --to-unit "$TXNBOT_FUND_VALUE" wei)" + hex="$(cast --to-hex "$wei")" + cast rpc --rpc-url "$ANVIL_RPC" anvil_setBalance "$TXNBOT_ADDRESS" "$hex" >>"$SETUP_LOG" 2>&1 +} + +main() { + log "Waiting for Anvil" + wait_for_rpc + maybe_set_deployer_from_mnemonic + run_forge_script + extract_addresses + fund_liquidity_manager + grant_recenter_access + call_recenter + seed_application_state + prime_chain + write_ponder_env + write_txn_bot_env + fund_txn_bot_wallet + log "Bootstrap complete" + log "Kraiken: $KRAIKEN" + log "Stake: $STAKE" + log "LiquidityManager: $LIQUIDITY_MANAGER" +} + +main "$@" diff --git a/containers/foundry.Containerfile b/containers/foundry.Containerfile new file mode 100644 index 0000000..3b42feb --- /dev/null +++ b/containers/foundry.Containerfile @@ -0,0 +1,25 @@ +FROM debian:bookworm-slim + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + jq \ + git \ + build-essential \ + pkg-config \ + libssl-dev \ + libclang-dev \ + llvm \ + unzip \ + && rm -rf /var/lib/apt/lists/* + +RUN useradd -m -u 1000 foundry +USER foundry +WORKDIR /home/foundry + +RUN curl -L https://foundry.paradigm.xyz | bash \ + && /home/foundry/.foundry/bin/foundryup + +ENV PATH="/home/foundry/.foundry/bin:${PATH}" +WORKDIR /workspace diff --git a/containers/frontend-dev-entrypoint.sh b/containers/frontend-dev-entrypoint.sh new file mode 100755 index 0000000..c0f4e17 --- /dev/null +++ b/containers/frontend-dev-entrypoint.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR=/workspace +CONTRACT_ENV=$ROOT_DIR/tmp/podman/contracts.env +APP_DIR=$ROOT_DIR/web-app +SWAP_ROUTER=0x94cC0AaC535CCDB3C01d6787D6413C739ae12bc4 + +while [[ ! -f "$CONTRACT_ENV" ]]; do + echo "[frontend-entrypoint] waiting for contracts env" + sleep 2 +done + +# shellcheck disable=SC1090 +source "$CONTRACT_ENV" + +cd "$APP_DIR" +if [[ ! -d node_modules ]]; then + npm install +fi + +export VITE_DEFAULT_CHAIN_ID=${VITE_DEFAULT_CHAIN_ID:-31337} +export VITE_LOCAL_RPC_URL=${VITE_LOCAL_RPC_URL:-/rpc/anvil} +export VITE_LOCAL_RPC_PROXY_TARGET=${VITE_LOCAL_RPC_PROXY_TARGET:-http://anvil:8545} +export VITE_KRAIKEN_ADDRESS=$KRAIKEN +export VITE_STAKE_ADDRESS=$STAKE +export VITE_SWAP_ROUTER=$SWAP_ROUTER +export VITE_PONDER_BASE_SEPOLIA_LOCAL_FORK=${VITE_PONDER_BASE_SEPOLIA_LOCAL_FORK:-/graphql} +export VITE_TXNBOT_BASE_SEPOLIA_LOCAL_FORK=${VITE_TXNBOT_BASE_SEPOLIA_LOCAL_FORK:-/txn} +export CHOKIDAR_USEPOLLING=${CHOKIDAR_USEPOLLING:-1} + +exec npm run dev -- --host 0.0.0.0 --port 5173 diff --git a/containers/node-dev.Containerfile b/containers/node-dev.Containerfile new file mode 100644 index 0000000..1490337 --- /dev/null +++ b/containers/node-dev.Containerfile @@ -0,0 +1,11 @@ +FROM node:20-bookworm + +RUN apt-get update \ + && apt-get install -y --no-install-recommends dumb-init \ + && rm -rf /var/lib/apt/lists/* + +USER node +WORKDIR /workspace + +ENV PATH="/workspace/node_modules/.bin:${PATH}" +ENTRYPOINT ["dumb-init", "--"] diff --git a/containers/ponder-dev-entrypoint.sh b/containers/ponder-dev-entrypoint.sh new file mode 100755 index 0000000..9a79210 --- /dev/null +++ b/containers/ponder-dev-entrypoint.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR=/workspace +CONTRACT_ENV=$ROOT_DIR/tmp/podman/contracts.env +PONDER_WORKDIR=$ROOT_DIR/services/ponder + +while [[ ! -f "$CONTRACT_ENV" ]]; do + echo "[ponder-entrypoint] waiting for contracts env" + sleep 2 +done + +cd "$PONDER_WORKDIR" +if [[ ! -d node_modules ]]; then + npm install +fi + +export CHOKIDAR_USEPOLLING=${CHOKIDAR_USEPOLLING:-1} +export HOST=0.0.0.0 +export PORT=${PORT:-42069} + +exec npm run dev diff --git a/containers/txn-bot-entrypoint.sh b/containers/txn-bot-entrypoint.sh new file mode 100755 index 0000000..0f4a68c --- /dev/null +++ b/containers/txn-bot-entrypoint.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR=/workspace +TXNBOT_ENV_FILE=$ROOT_DIR/tmp/podman/txnBot.env +BOT_DIR=$ROOT_DIR/services/txnBot + +while [[ ! -f "$TXNBOT_ENV_FILE" ]]; do + echo "[txn-bot-entrypoint] waiting for env file" + sleep 2 +done + +cd "$BOT_DIR" +if [[ ! -d node_modules ]]; then + npm install +fi + +export TXN_BOT_ENV_FILE="$TXNBOT_ENV_FILE" +exec npm run start diff --git a/docs/podman.md b/docs/podman.md new file mode 100644 index 0000000..6553848 --- /dev/null +++ b/docs/podman.md @@ -0,0 +1,44 @@ +# Podman Staging Environment + +The Podman stack mirrors `scripts/local_env.sh` using long-lived containers. Every boot spins up a fresh Base Sepolia fork, redeploys contracts, seeds liquidity, and launches the live-reload services behind Caddy on port 80. + +## Service Topology +- `anvil` – Base Sepolia fork with optional mnemonic from `onchain/.secret.local` +- `bootstrap` – one-shot job running `DeployLocal.sol`, seeding liquidity, priming blocks, and writing shared env files +- `ponder` – `npm run dev` for the indexer (port 42069 inside the pod) +- `frontend` – Vite dev server for `web-app` (port 5173 inside the pod) +- `txn-bot` – automation loop plus Express status API (port 43069 inside the pod) +- `caddy` – front door at `http://:80`, routing `/graphql`, `/health`, `/rpc/anvil`, and `/txn` to the internal services + +All containers mount the repository so code edits hot-reload exactly as the local script. Named volumes keep `node_modules` caches between restarts. + +## Prerequisites +- Podman 4.x (rootless recommended) +- `podman-compose` + +## Launching +```bash +podman-compose -f podman-compose.yml build +podman-compose -f podman-compose.yml up +``` +- First run takes several minutes while Foundry installs deps, deploys contracts, and runs the seeding transactions. +- Use `podman-compose down` to stop. Bring-up always redeploys and rewrites `services/ponder/.env.local` plus `tmp/podman/txnBot.env`. + +### Access Points (via Caddy) +- Frontend: `http:///` +- GraphQL: `http:///graphql` +- RPC passthrough: `http:///rpc/anvil` +- Txn bot status: `http:///txn/status` + +## Configuration Knobs +Set environment variables before `podman-compose up`: +- `FORK_URL` – Anvil upstream RPC (defaults to `https://sepolia.base.org`) +- `DEPLOYER_PK`, `DEPLOYER_ADDR` – override deployer wallet; otherwise derived from `.secret.local` or Foundry defaults +- `TXNBOT_PRIVATE_KEY`, `TXNBOT_ADDRESS`, `TXNBOT_FUND_VALUE` – customise bot signer and funding + +Edit `containers/Caddyfile` if you need different routes or ports. + +## Known Limitations +- State is ephemeral; every restart wipes the fork and redeploys contracts. +- Processes run in dev/watch mode (`npm run dev`), so staging traffic is not production hardened. +- Secrets live in env files inside the repo mount because no external secret store is wired in. diff --git a/podman-compose.yml b/podman-compose.yml new file mode 100644 index 0000000..3bde1cb --- /dev/null +++ b/podman-compose.yml @@ -0,0 +1,101 @@ +version: "3.8" + +services: + anvil: + build: + context: . + dockerfile: containers/foundry.Containerfile + command: ["/workspace/containers/anvil-entrypoint.sh"] + volumes: + - .:/workspace:Z + expose: + - "8545" + restart: unless-stopped + + bootstrap: + build: + context: . + dockerfile: containers/foundry.Containerfile + command: ["/workspace/containers/bootstrap.sh"] + volumes: + - .:/workspace:Z + environment: + - ANVIL_RPC=http://anvil:8545 + depends_on: + anvil: + condition: service_started + restart: "no" + + ponder: + build: + context: . + dockerfile: containers/node-dev.Containerfile + entrypoint: ["/workspace/containers/ponder-dev-entrypoint.sh"] + volumes: + - .:/workspace:Z + - ponder-node-modules:/workspace/services/ponder/node_modules + working_dir: /workspace + environment: + - CHOKIDAR_USEPOLLING=1 + depends_on: + bootstrap: + condition: service_completed_successfully + expose: + - "42069" + restart: unless-stopped + + frontend: + build: + context: . + dockerfile: containers/node-dev.Containerfile + entrypoint: ["/workspace/containers/frontend-dev-entrypoint.sh"] + volumes: + - .:/workspace:Z + - frontend-node-modules:/workspace/web-app/node_modules + working_dir: /workspace + environment: + - CHOKIDAR_USEPOLLING=1 + depends_on: + bootstrap: + condition: service_completed_successfully + expose: + - "5173" + restart: unless-stopped + + txn-bot: + build: + context: . + dockerfile: containers/node-dev.Containerfile + entrypoint: ["/workspace/containers/txn-bot-entrypoint.sh"] + volumes: + - .:/workspace:Z + - txn-node-modules:/workspace/services/txnBot/node_modules + working_dir: /workspace + depends_on: + bootstrap: + condition: service_completed_successfully + expose: + - "43069" + restart: unless-stopped + + caddy: + image: caddy:2.8 + volumes: + - ./containers/Caddyfile:/etc/caddy/Caddyfile:Z + ports: + - "80:80" + depends_on: + anvil: + condition: service_started + ponder: + condition: service_started + frontend: + condition: service_started + txn-bot: + condition: service_started + restart: unless-stopped + +volumes: + frontend-node-modules: + ponder-node-modules: + txn-node-modules: From ea27fcb7221a9cccea6e1ebc04967a9946e72491 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 24 Sep 2025 12:10:41 +0000 Subject: [PATCH 2/3] feat: Complete Podman stack setup with working services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fixed service dependencies (removed bootstrap dependency for runtime services) - Added landing service for documentation site at root path - Moved web-app to /app path, landing to / path - Fixed permission issues with lowercase 'z' SELinux context - Added kraiken-lib compilation in txn-bot container - Fixed TypeScript build for kraiken-lib with proper volumes - Updated entrypoint scripts to handle npm installs properly - Added locale fixes to Containerfiles - Changed Caddy port from 80 to 8081 for external access - Updated Docs link to point to local landing page All services now working: - Landing page at / - Web app at /app/ - GraphQL at /graphql - Transaction bot at /txn - Anvil RPC at /rpc/anvil 🤖 Generated with Claude Code Co-Authored-By: Claude --- containers/Caddyfile | 7 ++- containers/bootstrap.sh | 10 +++- containers/foundry.Containerfile | 3 ++ containers/landing-dev-entrypoint.sh | 18 +++++++ containers/node-dev.Containerfile | 2 + containers/ponder-dev-entrypoint.sh | 8 +-- containers/txn-bot-entrypoint.sh | 47 +++++++++++++++- ...entrypoint.sh => webapp-dev-entrypoint.sh} | 16 +++--- podman-compose.yml | 54 +++++++++++++------ web-app/src/components/layouts/Navbar.vue | 2 +- 10 files changed, 135 insertions(+), 32 deletions(-) create mode 100755 containers/landing-dev-entrypoint.sh rename containers/{frontend-dev-entrypoint.sh => webapp-dev-entrypoint.sh} (66%) diff --git a/containers/Caddyfile b/containers/Caddyfile index a8197c1..8216164 100644 --- a/containers/Caddyfile +++ b/containers/Caddyfile @@ -1,4 +1,7 @@ :80 { + route /app* { + reverse_proxy webapp:5173 + } route /graphql* { reverse_proxy ponder:42069 } @@ -6,10 +9,12 @@ reverse_proxy ponder:42069 } route /rpc/anvil* { + uri strip_prefix /rpc/anvil reverse_proxy anvil:8545 } route /txn* { + uri strip_prefix /txn reverse_proxy txn-bot:43069 } - reverse_proxy frontend:5173 + reverse_proxy landing:5174 } diff --git a/containers/bootstrap.sh b/containers/bootstrap.sh index c7b32c8..1f035b6 100755 --- a/containers/bootstrap.sh +++ b/containers/bootstrap.sh @@ -115,8 +115,14 @@ grant_recenter_access() { } call_recenter() { - log "Calling recenter()" - cast send --rpc-url "$ANVIL_RPC" --private-key "$DEPLOYER_PK" \ + local recenter_pk="$DEPLOYER_PK" + local recenter_addr="$DEPLOYER_ADDR" + if [[ -n "$TXNBOT_ADDRESS" ]]; then + recenter_pk="$TXNBOT_PRIVATE_KEY" + recenter_addr="$TXNBOT_ADDRESS" + fi + log "Calling recenter() via $recenter_addr" + cast send --rpc-url "$ANVIL_RPC" --private-key "$recenter_pk" \ "$LIQUIDITY_MANAGER" "recenter()" >>"$SETUP_LOG" 2>&1 } diff --git a/containers/foundry.Containerfile b/containers/foundry.Containerfile index 3b42feb..9f0e6f3 100644 --- a/containers/foundry.Containerfile +++ b/containers/foundry.Containerfile @@ -17,6 +17,9 @@ RUN apt-get update \ RUN useradd -m -u 1000 foundry USER foundry WORKDIR /home/foundry +ENV SHELL=/bin/bash +ENV LANG=C.UTF-8 +ENV LC_ALL=C.UTF-8 RUN curl -L https://foundry.paradigm.xyz | bash \ && /home/foundry/.foundry/bin/foundryup diff --git a/containers/landing-dev-entrypoint.sh b/containers/landing-dev-entrypoint.sh new file mode 100755 index 0000000..d8d3e46 --- /dev/null +++ b/containers/landing-dev-entrypoint.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR=/workspace +LANDING_DIR=$ROOT_DIR/landing + +cd "$LANDING_DIR" +echo "[landing-entrypoint] Installing dependencies..." +npm install --no-save --loglevel error 2>&1 || { + echo "[landing-entrypoint] npm install failed, trying with --force" + npm install --force --no-save --loglevel error +} + +export CHOKIDAR_USEPOLLING=${CHOKIDAR_USEPOLLING:-1} +export HOST=0.0.0.0 +export PORT=${PORT:-5174} + +exec npm run dev -- --host 0.0.0.0 --port 5174 \ No newline at end of file diff --git a/containers/node-dev.Containerfile b/containers/node-dev.Containerfile index 1490337..717feaf 100644 --- a/containers/node-dev.Containerfile +++ b/containers/node-dev.Containerfile @@ -6,6 +6,8 @@ RUN apt-get update \ USER node WORKDIR /workspace +ENV LANG=C.UTF-8 +ENV LC_ALL=C.UTF-8 ENV PATH="/workspace/node_modules/.bin:${PATH}" ENTRYPOINT ["dumb-init", "--"] diff --git a/containers/ponder-dev-entrypoint.sh b/containers/ponder-dev-entrypoint.sh index 9a79210..7ecfffb 100755 --- a/containers/ponder-dev-entrypoint.sh +++ b/containers/ponder-dev-entrypoint.sh @@ -11,9 +11,11 @@ while [[ ! -f "$CONTRACT_ENV" ]]; do done cd "$PONDER_WORKDIR" -if [[ ! -d node_modules ]]; then - npm install -fi +echo "[ponder-entrypoint] Installing dependencies..." +npm install --no-save --loglevel error 2>&1 || { + echo "[ponder-entrypoint] npm install failed, trying with --force" + npm install --force --no-save --loglevel error +} export CHOKIDAR_USEPOLLING=${CHOKIDAR_USEPOLLING:-1} export HOST=0.0.0.0 diff --git a/containers/txn-bot-entrypoint.sh b/containers/txn-bot-entrypoint.sh index 0f4a68c..9734aea 100755 --- a/containers/txn-bot-entrypoint.sh +++ b/containers/txn-bot-entrypoint.sh @@ -4,16 +4,59 @@ set -euo pipefail ROOT_DIR=/workspace TXNBOT_ENV_FILE=$ROOT_DIR/tmp/podman/txnBot.env BOT_DIR=$ROOT_DIR/services/txnBot +KRAIKEN_LIB_DIR=$ROOT_DIR/kraiken-lib while [[ ! -f "$TXNBOT_ENV_FILE" ]]; do echo "[txn-bot-entrypoint] waiting for env file" sleep 2 done -cd "$BOT_DIR" +# Build kraiken-lib first +echo "[txn-bot-entrypoint] Building kraiken-lib..." +cd "$KRAIKEN_LIB_DIR" + +# Install dependencies if needed if [[ ! -d node_modules ]]; then - npm install + echo "[txn-bot-entrypoint] Installing kraiken-lib dependencies..." + npm install --loglevel error fi +# Install TypeScript if not present +if [[ ! -f node_modules/.bin/tsc ]]; then + echo "[txn-bot-entrypoint] Installing TypeScript..." + npm install --loglevel error typescript +fi + +# Build TypeScript files (dist is now a volume, writable by node user) +echo "[txn-bot-entrypoint] Compiling TypeScript..." +if [[ ! -f dist/index.js ]]; then + echo "[txn-bot-entrypoint] Running tsc to compile kraiken-lib..." + ./node_modules/.bin/tsc \ + --outDir dist \ + --declaration \ + --module commonjs \ + --target es2020 \ + --skipLibCheck \ + --esModuleInterop \ + --allowSyntheticDefaultImports \ + --resolveJsonModule \ + src/index.ts src/helpers.ts src/subgraph.ts src/__generated__/graphql.ts 2>&1 | head -20 || { + echo "[txn-bot-entrypoint] TypeScript compilation had some issues, checking if files were created..." + } + + # Verify the main file exists + if [[ ! -f dist/index.js ]]; then + echo "[txn-bot-entrypoint] ERROR: Failed to compile kraiken-lib" + exit 1 + fi +fi + +cd "$BOT_DIR" +echo "[txn-bot-entrypoint] Installing txn-bot dependencies..." +npm install --no-save --loglevel error 2>&1 || { + echo "[txn-bot-entrypoint] npm install failed, trying with --force" + npm install --force --no-save --loglevel error +} + export TXN_BOT_ENV_FILE="$TXNBOT_ENV_FILE" exec npm run start diff --git a/containers/frontend-dev-entrypoint.sh b/containers/webapp-dev-entrypoint.sh similarity index 66% rename from containers/frontend-dev-entrypoint.sh rename to containers/webapp-dev-entrypoint.sh index c0f4e17..62ba72e 100755 --- a/containers/frontend-dev-entrypoint.sh +++ b/containers/webapp-dev-entrypoint.sh @@ -15,18 +15,20 @@ done source "$CONTRACT_ENV" cd "$APP_DIR" -if [[ ! -d node_modules ]]; then - npm install -fi +echo "[frontend-entrypoint] Installing dependencies..." +npm install --no-save --loglevel error 2>&1 || { + echo "[frontend-entrypoint] npm install failed, trying with --force" + npm install --force --no-save --loglevel error +} export VITE_DEFAULT_CHAIN_ID=${VITE_DEFAULT_CHAIN_ID:-31337} -export VITE_LOCAL_RPC_URL=${VITE_LOCAL_RPC_URL:-/rpc/anvil} +export VITE_LOCAL_RPC_URL=${VITE_LOCAL_RPC_URL:-/app/rpc/anvil} export VITE_LOCAL_RPC_PROXY_TARGET=${VITE_LOCAL_RPC_PROXY_TARGET:-http://anvil:8545} export VITE_KRAIKEN_ADDRESS=$KRAIKEN export VITE_STAKE_ADDRESS=$STAKE export VITE_SWAP_ROUTER=$SWAP_ROUTER -export VITE_PONDER_BASE_SEPOLIA_LOCAL_FORK=${VITE_PONDER_BASE_SEPOLIA_LOCAL_FORK:-/graphql} -export VITE_TXNBOT_BASE_SEPOLIA_LOCAL_FORK=${VITE_TXNBOT_BASE_SEPOLIA_LOCAL_FORK:-/txn} +export VITE_PONDER_BASE_SEPOLIA_LOCAL_FORK=${VITE_PONDER_BASE_SEPOLIA_LOCAL_FORK:-/app/graphql} +export VITE_TXNBOT_BASE_SEPOLIA_LOCAL_FORK=${VITE_TXNBOT_BASE_SEPOLIA_LOCAL_FORK:-/app/txn} export CHOKIDAR_USEPOLLING=${CHOKIDAR_USEPOLLING:-1} -exec npm run dev -- --host 0.0.0.0 --port 5173 +exec npm run dev -- --host 0.0.0.0 --port 5173 --base /app/ diff --git a/podman-compose.yml b/podman-compose.yml index 3bde1cb..d6ac08e 100644 --- a/podman-compose.yml +++ b/podman-compose.yml @@ -32,70 +32,92 @@ services: dockerfile: containers/node-dev.Containerfile entrypoint: ["/workspace/containers/ponder-dev-entrypoint.sh"] volumes: - - .:/workspace:Z + - .:/workspace:z - ponder-node-modules:/workspace/services/ponder/node_modules working_dir: /workspace environment: - CHOKIDAR_USEPOLLING=1 depends_on: - bootstrap: - condition: service_completed_successfully + - anvil expose: - "42069" restart: unless-stopped - frontend: + webapp: build: context: . dockerfile: containers/node-dev.Containerfile - entrypoint: ["/workspace/containers/frontend-dev-entrypoint.sh"] + entrypoint: ["/workspace/containers/webapp-dev-entrypoint.sh"] volumes: - - .:/workspace:Z - - frontend-node-modules:/workspace/web-app/node_modules + - .:/workspace:z + - webapp-node-modules:/workspace/web-app/node_modules working_dir: /workspace environment: - CHOKIDAR_USEPOLLING=1 depends_on: - bootstrap: - condition: service_completed_successfully + - anvil expose: - "5173" restart: unless-stopped + landing: + build: + context: . + dockerfile: containers/node-dev.Containerfile + entrypoint: ["/workspace/containers/landing-dev-entrypoint.sh"] + volumes: + - .:/workspace:z + - landing-node-modules:/workspace/landing/node_modules + working_dir: /workspace + environment: + - CHOKIDAR_USEPOLLING=1 + depends_on: + - anvil + expose: + - "5174" + restart: unless-stopped + txn-bot: build: context: . dockerfile: containers/node-dev.Containerfile entrypoint: ["/workspace/containers/txn-bot-entrypoint.sh"] volumes: - - .:/workspace:Z + - .:/workspace:z - txn-node-modules:/workspace/services/txnBot/node_modules + - kraiken-node-modules:/workspace/kraiken-lib/node_modules + - kraiken-dist:/workspace/kraiken-lib/dist working_dir: /workspace depends_on: - bootstrap: - condition: service_completed_successfully + - anvil + - ponder expose: - "43069" restart: unless-stopped caddy: - image: caddy:2.8 + image: docker.io/library/caddy:2.8 volumes: - ./containers/Caddyfile:/etc/caddy/Caddyfile:Z ports: - - "80:80" + - "0.0.0.0:8081:80" depends_on: anvil: condition: service_started ponder: condition: service_started - frontend: + webapp: + condition: service_started + landing: condition: service_started txn-bot: condition: service_started restart: unless-stopped volumes: - frontend-node-modules: + webapp-node-modules: + landing-node-modules: ponder-node-modules: txn-node-modules: + kraiken-node-modules: + kraiken-dist: diff --git a/web-app/src/components/layouts/Navbar.vue b/web-app/src/components/layouts/Navbar.vue index 393f554..c3aa851 100644 --- a/web-app/src/components/layouts/Navbar.vue +++ b/web-app/src/components/layouts/Navbar.vue @@ -17,7 +17,7 @@ {{ navbarRoute.title }} - Docs + Docs