#!/usr/bin/env bash set -euo pipefail root="${EVERY_CHANNEL_OP_STACK_ROOT:?set EVERY_CHANNEL_OP_STACK_ROOT}" private_key_file="${EVERY_CHANNEL_OP_STACK_PRIVATE_KEY_FILE:?set EVERY_CHANNEL_OP_STACK_PRIVATE_KEY_FILE}" l1_rpc_url="${EVERY_CHANNEL_OP_STACK_L1_RPC_URL:-https://ethereum-sepolia-rpc.publicnode.com}" l1_beacon_url="${EVERY_CHANNEL_OP_STACK_L1_BEACON_URL:-https://ethereum-sepolia-beacon-api.publicnode.com}" chain_id="${EVERY_CHANNEL_OP_STACK_CHAIN_ID:-245245}" p2p_advertise_ip="${EVERY_CHANNEL_OP_STACK_P2P_ADVERTISE_IP:-127.0.0.1}" op_deployer_bin="${EVERY_CHANNEL_OP_DEPLOYER_BIN:-${root}/bin/op-deployer}" download_script="${EVERY_CHANNEL_OP_DEPLOYER_DOWNLOAD_SCRIPT:-}" download_tag="${EVERY_CHANNEL_OP_DEPLOYER_TAG:-op-deployer/v0.6.0-rc.3}" skip_apply="${EVERY_CHANNEL_OP_STACK_SKIP_APPLY:-false}" challenger_prestate_file="${EVERY_CHANNEL_OP_STACK_CHALLENGER_PRESTATE_FILE:-}" deployer_dir="${root}/deployer" sequencer_dir="${root}/sequencer" batcher_dir="${root}/batcher" proposer_dir="${root}/proposer" challenger_dir="${root}/challenger" dispute_mon_dir="${root}/dispute-mon" challenger_prestate_name="" log() { printf '[op-stack] %s\n' "$*" >&2 } require_cmd() { command -v "$1" >/dev/null 2>&1 || { log "missing required command: $1" exit 2 } } trimmed_file_contents() { tr -d '\r\n' <"$1" } set_toml_value() { local key="$1" local value="$2" local file="$3" if ! grep -q "^${key} = " "$file"; then log "missing key ${key} in ${file}" exit 1 fi python - "$key" "$value" "$file" <<'PY' import sys from pathlib import Path key, value, path = sys.argv[1:] text = Path(path).read_text() needle = f"{key} = " out = [] replaced = False for line in text.splitlines(): if line.startswith(needle): out.append(f'{key} = "{value}"') replaced = True else: out.append(line) if not replaced: raise SystemExit(f"failed to replace {key}") Path(path).write_text("\n".join(out) + "\n") PY } mkdir -p "${root}/bin" "$deployer_dir" "$sequencer_dir" "$batcher_dir" "$proposer_dir" \ "$challenger_dir" "$challenger_dir/data" "$dispute_mon_dir" require_cmd cast require_cmd curl require_cmd jq require_cmd openssl if [[ ! -x "$op_deployer_bin" ]]; then if [[ -z "$download_script" ]]; then log "op-deployer missing and no download script configured" exit 2 fi log "downloading op-deployer via ${download_script}" EVERY_CHANNEL_OP_DEPLOYER_TAG="$download_tag" \ EVERY_CHANNEL_OP_DEPLOYER_OUT="$op_deployer_bin" \ "$download_script" fi private_key="$(trimmed_file_contents "$private_key_file")" private_key="${private_key#0x}" if [[ ${#private_key} -ne 64 ]]; then log "private key file must contain exactly 32 bytes of hex" exit 2 fi operator_address="$(cast wallet address --private-key "0x${private_key}")" cat > "${deployer_dir}/.env" <"${sequencer_dir}/genesis.json" "$op_deployer_bin" inspect rollup --workdir "${deployer_dir}/.deployer" "${chain_id_hex}" >"${sequencer_dir}/rollup.json" openssl rand -hex 32 >"${sequencer_dir}/jwt.txt" chmod 0600 "${sequencer_dir}/jwt.txt" state_json="${deployer_dir}/.deployer/state.json" system_config_proxy="$(jq -r '.opChainDeployments[0].systemConfigProxyAddress // .opChainDeployments[0].SystemConfigProxy // empty' <"${state_json}")" dispute_game_factory="$(jq -r '.opChainDeployments[0].disputeGameFactoryProxyAddress // .opChainDeployments[0].DisputeGameFactoryProxy // empty' <"${state_json}")" l1_standard_bridge="$(jq -r '.opChainDeployments[0].l1StandardBridgeProxyAddress // .opChainDeployments[0].L1StandardBridgeProxy // empty' <"${state_json}")" if [[ -z "${system_config_proxy}" || "${system_config_proxy}" == "null" ]]; then log "failed to extract systemConfigProxyAddress from state.json" exit 1 fi if [[ -z "${dispute_game_factory}" || "${dispute_game_factory}" == "null" ]]; then log "failed to extract disputeGameFactoryProxyAddress from state.json" exit 1 fi if [[ -n "${challenger_prestate_file}" ]]; then if [[ ! -f "${challenger_prestate_file}" ]]; then log "challenger prestate file does not exist: ${challenger_prestate_file}" exit 1 fi challenger_prestate_name="$(basename "${challenger_prestate_file}")" cp "${challenger_prestate_file}" "${challenger_dir}/${challenger_prestate_name}" chmod 0640 "${challenger_dir}/${challenger_prestate_name}" fi cat > "${sequencer_dir}/.env" < "${batcher_dir}/.env" < "${proposer_dir}/.env" < "${challenger_dir}/.env" <> "${challenger_dir}/.env" < "${dispute_mon_dir}/.env" < "${root}/deployment.json" <