refactor: consolidate CI and local dev orchestration (#108)
## Summary - Extract shared bootstrap functions into `scripts/bootstrap-common.sh` (eliminates ~120 lines of duplicated forge/cast commands from e2e.yml) - Create reusable `scripts/wait-for-service.sh` for health checks (replaces 60-line inline wait-for-stack) - Merge dev and CI entrypoints into unified scripts branching on `CI` env var (delete `docker/ci-entrypoints/`) - Replace 4 per-service CI Dockerfiles with parameterized `docker/Dockerfile.service-ci` - Add `sync-tax-rates.mjs` to CI image builder stage - Fix: CI now grants txnBot recenter access (was missing) - Fix: txnBot funding parameterized (CI=10eth, local=1eth) - Delete 5 obsolete migration docs and 4 DinD integration files Net: -1540 lines removed Closes #107 ## Test plan - [ ] E2E pipeline passes (bootstrap sources shared script, services use old images with commands override) - [ ] build-ci-images pipeline builds all 4 services with unified Dockerfile - [ ] Local dev stack boots via `./scripts/dev.sh start` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: openhands <openhands@all-hands.dev> Reviewed-on: https://codeberg.org/johba/harb/pulls/108
This commit is contained in:
parent
4277f19b68
commit
e5e1308e72
45 changed files with 882 additions and 2627 deletions
|
|
@ -26,48 +26,30 @@ if [[ -n "$GIT_BRANCH" ]]; then
|
|||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
STATE_DIR=$ROOT_DIR/tmp/containers
|
||||
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"
|
||||
|
||||
# ── Configure shared bootstrap variables ──
|
||||
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}
|
||||
|
||||
CONTRACT_ENV=$STATE_DIR/contracts.env
|
||||
LOG_FILE=$SETUP_LOG
|
||||
ONCHAIN_DIR=$ROOT_DIR/onchain
|
||||
TXNBOT_FUND_VALUE=${TXNBOT_FUND_VALUE:-1ether}
|
||||
|
||||
log() {
|
||||
echo "[bootstrap] $*"
|
||||
}
|
||||
# Source shared bootstrap functions
|
||||
# shellcheck source=../scripts/bootstrap-common.sh
|
||||
source "$ROOT_DIR/scripts/bootstrap-common.sh"
|
||||
|
||||
BOOTSTRAP_START=$(date +%s%3N)
|
||||
|
||||
wait_for_rpc() {
|
||||
for _ in {1..120}; do
|
||||
if cast chain-id --rpc-url "$ANVIL_RPC" >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
log "Timed out waiting for Anvil at $ANVIL_RPC"
|
||||
return 1
|
||||
}
|
||||
# ── Local-only helpers ─────────────────────────────────────────────────
|
||||
|
||||
maybe_set_deployer_from_mnemonic() {
|
||||
if [[ -n "$DEPLOYER_PK" && -n "$DEPLOYER_ADDR" ]]; then
|
||||
if [[ -n "$DEPLOYER_PK" && "$DEPLOYER_PK" != "$DEFAULT_DEPLOYER_PK" ]]; then
|
||||
return
|
||||
fi
|
||||
if [[ -f "$MNEMONIC_FILE" ]]; then
|
||||
|
|
@ -76,12 +58,10 @@ maybe_set_deployer_from_mnemonic() {
|
|||
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}
|
||||
DEPLOYER_PK=${pk}
|
||||
DEPLOYER_ADDR=${addr}
|
||||
fi
|
||||
fi
|
||||
DEPLOYER_PK=${DEPLOYER_PK:-$DEFAULT_DEPLOYER_PK}
|
||||
DEPLOYER_ADDR=${DEPLOYER_ADDR:-$DEFAULT_DEPLOYER_ADDR}
|
||||
}
|
||||
|
||||
derive_txnbot_wallet() {
|
||||
|
|
@ -91,115 +71,14 @@ derive_txnbot_wallet() {
|
|||
if [[ -n "$mnemonic" ]]; then
|
||||
TXNBOT_PRIVATE_KEY="$(cast wallet private-key --mnemonic "$mnemonic" --mnemonic-index 2)"
|
||||
TXNBOT_ADDRESS="$(cast wallet address --private-key "$TXNBOT_PRIVATE_KEY")"
|
||||
log "Derived txnBot wallet: $TXNBOT_ADDRESS (account index 2)"
|
||||
bootstrap_log "Derived txnBot wallet: $TXNBOT_ADDRESS (account index 2)"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
# Fallback to hardcoded Anvil account 1
|
||||
TXNBOT_PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
|
||||
TXNBOT_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8
|
||||
log "Using default txnBot wallet: $TXNBOT_ADDRESS"
|
||||
}
|
||||
|
||||
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" <<EOCONTRACTS
|
||||
LIQUIDITY_MANAGER=$LIQUIDITY_MANAGER
|
||||
KRAIKEN=$KRAIKEN
|
||||
STAKE=$STAKE
|
||||
EOCONTRACTS
|
||||
}
|
||||
|
||||
fund_liquidity_manager() {
|
||||
log "Funding LiquidityManager"
|
||||
cast send --rpc-url "$ANVIL_RPC" --private-key "$DEPLOYER_PK" \
|
||||
"$LIQUIDITY_MANAGER" --value 0.1ether >>"$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() {
|
||||
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
|
||||
}
|
||||
|
||||
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 5 blocks (minimal warmup for fast Ponder sync)..."
|
||||
# Mine just 5 blocks - enough for Ponder to have some history but keeps sync fast
|
||||
if cast rpc --rpc-url "$ANVIL_RPC" anvil_mine "0x5" "0x1" >/dev/null 2>&1; then
|
||||
log "Mined 5 blocks"
|
||||
else
|
||||
log "Batch mining failed, using individual evm_mine calls"
|
||||
for i in {1..5}; do
|
||||
cast rpc --rpc-url "$ANVIL_RPC" evm_mine >/dev/null 2>&1 || true
|
||||
done
|
||||
fi
|
||||
log "Pre-mining complete"
|
||||
}
|
||||
|
||||
write_deployments_json() {
|
||||
cat >"$ROOT_DIR/onchain/deployments-local.json" <<EODEPLOYMENTS
|
||||
{
|
||||
"contracts": {
|
||||
"Kraiken": "$KRAIKEN",
|
||||
"Stake": "$STAKE",
|
||||
"LiquidityManager": "$LIQUIDITY_MANAGER"
|
||||
}
|
||||
}
|
||||
EODEPLOYMENTS
|
||||
TXNBOT_PRIVATE_KEY=$DEFAULT_TXNBOT_PK
|
||||
TXNBOT_ADDRESS=$DEFAULT_TXNBOT_ADDR
|
||||
bootstrap_log "Using default txnBot wallet: $TXNBOT_ADDRESS"
|
||||
}
|
||||
|
||||
write_ponder_env() {
|
||||
|
|
@ -215,9 +94,10 @@ EOPONDER
|
|||
}
|
||||
|
||||
write_txn_bot_env() {
|
||||
local txnbot_env=$STATE_DIR/txnBot.env
|
||||
local provider_url=${TXNBOT_PROVIDER_URL:-$ANVIL_RPC}
|
||||
local graphql_endpoint=${TXNBOT_GRAPHQL_ENDPOINT:-http://ponder:42069/graphql}
|
||||
cat >"$TXNBOT_ENV" <<EOTXNBOT
|
||||
cat >"$txnbot_env" <<EOTXNBOT
|
||||
ENVIRONMENT=BASE_SEPOLIA_LOCAL_FORK
|
||||
PROVIDER_URL=$provider_url
|
||||
PRIVATE_KEY=$TXNBOT_PRIVATE_KEY
|
||||
|
|
@ -229,26 +109,32 @@ PORT=43069
|
|||
EOTXNBOT
|
||||
}
|
||||
|
||||
fund_txn_bot_wallet() {
|
||||
if [[ -z "$TXNBOT_ADDRESS" ]]; then
|
||||
return
|
||||
prime_chain() {
|
||||
bootstrap_log "Pre-mining 5 blocks (minimal warmup for fast Ponder sync)..."
|
||||
if cast rpc --rpc-url "$ANVIL_RPC" anvil_mine "0x5" "0x1" >/dev/null 2>&1; then
|
||||
bootstrap_log "Mined 5 blocks"
|
||||
else
|
||||
bootstrap_log "Batch mining failed, using individual evm_mine calls"
|
||||
for i in {1..5}; do
|
||||
cast rpc --rpc-url "$ANVIL_RPC" evm_mine >/dev/null 2>&1 || true
|
||||
done
|
||||
fi
|
||||
log "Funding txnBot wallet $TXNBOT_ADDRESS"
|
||||
cast send --rpc-url "$ANVIL_RPC" --private-key "$DEPLOYER_PK" \
|
||||
"$TXNBOT_ADDRESS" --value "$TXNBOT_FUND_VALUE" >>"$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
|
||||
bootstrap_log "Pre-mining complete"
|
||||
}
|
||||
|
||||
# ── Main ───────────────────────────────────────────────────────────────
|
||||
|
||||
main() {
|
||||
log "Waiting for Anvil"
|
||||
local start_time
|
||||
start_time=$(date +%s%3N)
|
||||
|
||||
bootstrap_log "Waiting for Anvil"
|
||||
wait_for_rpc
|
||||
maybe_set_deployer_from_mnemonic
|
||||
derive_txnbot_wallet
|
||||
run_forge_script
|
||||
extract_addresses
|
||||
write_contracts_env
|
||||
fund_liquidity_manager
|
||||
grant_recenter_access
|
||||
call_recenter
|
||||
|
|
@ -260,14 +146,17 @@ main() {
|
|||
prime_chain &
|
||||
local prime_pid=$!
|
||||
wait "$prime_pid"
|
||||
BOOTSTRAP_END=$(date +%s%3N)
|
||||
elapsed_ms=$((BOOTSTRAP_END - BOOTSTRAP_START))
|
||||
|
||||
local end_time
|
||||
end_time=$(date +%s%3N)
|
||||
local elapsed_ms=$((end_time - start_time))
|
||||
local elapsed_sec
|
||||
elapsed_sec=$(awk -v ms="$elapsed_ms" 'BEGIN { printf "%.3f", ms/1000 }')
|
||||
log "Bootstrap complete in ${elapsed_sec}s"
|
||||
log "Kraiken: $KRAIKEN"
|
||||
log "Stake: $STAKE"
|
||||
log "LiquidityManager: $LIQUIDITY_MANAGER"
|
||||
log "txnBot: $TXNBOT_ADDRESS"
|
||||
bootstrap_log "Bootstrap complete in ${elapsed_sec}s"
|
||||
bootstrap_log "Kraiken: $KRAIKEN"
|
||||
bootstrap_log "Stake: $STAKE"
|
||||
bootstrap_log "LiquidityManager: $LIQUIDITY_MANAGER"
|
||||
bootstrap_log "txnBot: $TXNBOT_ADDRESS"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue