#!/usr/bin/env bash # Complete CCIP bridge configuration for Config-Ready chains (Gnosis, Celo, Wemix). # - Adds each chain as destination on Chain 138 bridges (138 → Gnosis/Celo/Wemix). # - Adds Chain 138 as destination on each chain's bridges (Gnosis/Celo/Wemix → 138). # Requires: bridge addresses and RPCs in .env; PRIVATE_KEY; CHAIN138_SELECTOR for step 2. # Usage: ./scripts/deployment/complete-config-ready-chains.sh # DRY_RUN=1 ./scripts/deployment/complete-config-ready-chains.sh # print commands only set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" [[ -f "$SCRIPT_DIR/../lib/init.sh" ]] && source "$SCRIPT_DIR/../lib/init.sh" 2>/dev/null || true PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then # shellcheck disable=SC1090 source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" load_deployment_env --repo-root "$PROJECT_ROOT" elif [[ -f "$PROJECT_ROOT/.env" ]]; then set -a # shellcheck disable=SC1090 source "$PROJECT_ROOT/.env" set +a fi # Chain selectors (decimal, for addDestination(uint64,address)) ETH_MAINNET_SELECTOR="${ETH_MAINNET_SELECTOR:-5009297550715157269}" GNOSIS_SELECTOR="${GNOSIS_SELECTOR:-465200170687744372}" CRONOS_SELECTOR="${CRONOS_SELECTOR:-1456215246176062136}" CELO_SELECTOR="${CELO_SELECTOR:-1346049177634351622}" WEMIX_SELECTOR="${WEMIX_SELECTOR:-5142893604156789321}" CHAIN138_SELECTOR="${CHAIN138_SELECTOR:-}" # Prefer LAN/core RPC for 138 when set (matches fund / deploy scripts). CHAIN138_RPC="${RPC_URL_138:-${CHAIN138_RPC:-${RPC_URL:-https://rpc-core.d-bis.org}}}" CHAIN138_RPC="${CHAIN138_RPC//$'\r'/}" CHAIN138_RPC="${CHAIN138_RPC//$'\n'/}" # Align with fund-ccip-bridges-with-link.sh / .env.example (MAINNET_RPC aliases). GNOSIS_RPC="${GNOSIS_RPC:-${GNOSIS_MAINNET_RPC:-https://rpc.gnosischain.com}}" CRONOS_RPC="${CRONOS_RPC:-${CRONOS_RPC_URL:-https://evm.cronos.org}}" CELO_RPC="${CELO_RPC:-${CELO_MAINNET_RPC:-https://forno.celo.org}}" WEMIX_RPC="${WEMIX_RPC:-${WEMIX_MAINNET_RPC:-https://api.wemix.com}}" PRIVATE_KEY="${PRIVATE_KEY:-}" if [[ -n "$PRIVATE_KEY" && ! "$PRIVATE_KEY" =~ ^0x ]]; then PRIVATE_KEY="0x$PRIVATE_KEY" fi # Chain 138 bridge addresses (required) WETH9_138=$(grep "CCIPWETH9_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH9_BRIDGE_CHAIN138:-}") WETH10_138=$(grep "CCIPWETH10_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH10_BRIDGE_CHAIN138:-}") # Config-ready chain bridge addresses (optional; if set, we configure them) WETH9_GNOSIS=$(grep "CCIPWETH9_BRIDGE_GNOSIS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH9_BRIDGE_GNOSIS:-}") WETH10_GNOSIS=$(grep "CCIPWETH10_BRIDGE_GNOSIS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH10_BRIDGE_GNOSIS:-}") WETH9_CRONOS=$(grep "CCIPWETH9_BRIDGE_CRONOS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH9_BRIDGE_CRONOS:-}") WETH10_CRONOS=$(grep "CCIPWETH10_BRIDGE_CRONOS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH10_BRIDGE_CRONOS:-}") WETH9_CELO=$(grep "CCIPWETH9_BRIDGE_CELO=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH9_BRIDGE_CELO:-}") WETH10_CELO=$(grep "CCIPWETH10_BRIDGE_CELO=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH10_BRIDGE_CELO:-}") WETH9_WEMIX=$(grep "CCIPWETH9_BRIDGE_WEMIX=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH9_BRIDGE_WEMIX:-}") WETH10_WEMIX=$(grep "CCIPWETH10_BRIDGE_WEMIX=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "\r\n' || echo "${CCIPWETH10_BRIDGE_WEMIX:-}") # Besu eth_call via `cast call` can return -32602; lowercase 20-byte addresses avoids some failures on sends. WETH9_138="${WETH9_138,,}" WETH10_138="${WETH10_138,,}" DRY_RUN="${DRY_RUN:-0}" log_info "=== Config-Ready Chains Completion (Gnosis, Cronos, Celo, Wemix) ===" if [[ -z "$WETH9_138" || -z "$WETH10_138" ]]; then echo "Error: Chain 138 bridge addresses not set. Set in .env: CCIPWETH9_BRIDGE_CHAIN138, CCIPWETH10_BRIDGE_CHAIN138" >&2 exit 1 fi if [[ -z "$PRIVATE_KEY" ]]; then echo "Error: PRIVATE_KEY not set in .env" >&2 exit 1 fi run_or_echo() { if [[ "$DRY_RUN" = "1" ]]; then echo " [DRY RUN] $*" else # With set -e, _out=$(eval ...) would exit the whole script on failure; use if to absorb it. local _out if _out=$(eval "$*" 2>&1); then log_success " OK" [[ -n "$_out" ]] && echo " $_out" else log_warn " Failed (non-fatal)" echo " $_out" >&2 fi fi } configure_chain_138_destination() { local label="$1" local selector="$2" local addr9="$3" local addr10="$4" if [[ -z "$addr9" && -z "$addr10" ]]; then echo " Skip $label (no bridge addresses in .env)" return 0 fi echo " Configuring Chain 138 → $label..." if [[ -n "$addr9" ]]; then run_or_echo "cast send $WETH9_138 \"addDestination(uint64,address)\" $selector ${addr9,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy --gas-limit 250000 --gas-price 2000000000" fi if [[ -n "$addr10" ]]; then run_or_echo "cast send $WETH10_138 \"addDestination(uint64,address)\" $selector ${addr10,,} --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy --gas-limit 250000 --gas-price 2000000000" fi } configure_remote_chain_destination() { local label="$1" local rpc="$2" local addr9="$3" local addr10="$4" if [[ -z "$addr9" && -z "$addr10" ]]; then echo " Skip $label (no bridge addresses)" return 0 fi echo " Configuring $label → Chain 138..." if [[ -n "$addr9" ]]; then run_or_echo "cast send ${addr9,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH9_138 --rpc-url $rpc --private-key \$PRIVATE_KEY --legacy --gas-limit 400000" fi if [[ -n "$addr10" ]]; then run_or_echo "cast send ${addr10,,} \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH10_138 --rpc-url $rpc --private-key \$PRIVATE_KEY --legacy --gas-limit 400000" fi } # ---- Step A: On Chain 138, add Gnosis/Cronos/Celo/Wemix as destinations ---- echo "" echo "Step A: Chain 138 bridges → add Gnosis, Cronos, Celo, Wemix as destinations" configure_chain_138_destination "Gnosis" "$GNOSIS_SELECTOR" "$WETH9_GNOSIS" "$WETH10_GNOSIS" configure_chain_138_destination "Cronos" "$CRONOS_SELECTOR" "$WETH9_CRONOS" "$WETH10_CRONOS" configure_chain_138_destination "Celo" "$CELO_SELECTOR" "$WETH9_CELO" "$WETH10_CELO" configure_chain_138_destination "Wemix" "$WEMIX_SELECTOR" "$WETH9_WEMIX" "$WETH10_WEMIX" # ---- Step B: On Gnosis/Cronos/Celo/Wemix, add Chain 138 as destination ---- if [[ -z "$CHAIN138_SELECTOR" ]]; then echo "" echo "Step B: Skipped (CHAIN138_SELECTOR not set in .env). Set it to configure remote chains → Chain 138." echo " Example: CHAIN138_SELECTOR=" else echo "" echo "Step B: Gnosis/Cronos/Celo/Wemix bridges → add Chain 138 as destination" configure_remote_chain_destination "Gnosis" "$GNOSIS_RPC" "$WETH9_GNOSIS" "$WETH10_GNOSIS" configure_remote_chain_destination "Cronos" "$CRONOS_RPC" "$WETH9_CRONOS" "$WETH10_CRONOS" configure_remote_chain_destination "Celo" "$CELO_RPC" "$WETH9_CELO" "$WETH10_CELO" configure_remote_chain_destination "Wemix" "$WEMIX_RPC" "$WETH9_WEMIX" "$WETH10_WEMIX" fi echo "" log_success "Config-ready chains script finished." echo " Next: Fund each remote bridge with LINK (see docs/07-ccip/CONFIG_READY_CHAINS_COMPLETION_RUNBOOK.md)."