#!/usr/bin/env bash # Automatically Configure All Bridge Destinations # Uses PRIVATE_KEY from .env file # Usage: ./configure-all-destinations-auto.sh set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" source "$PROJECT_ROOT/scripts/lib/address-inventory.sh" source "$PROJECT_ROOT/scripts/lib/ccip-destinations.sh" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } log_fix() { echo -e "${CYAN}[FIX]${NC} $1"; } load_explorer_runtime_env # Configuration RPC_URL="${RPC_URL_138:-http://192.168.11.250:8545}" WETH9_BRIDGE="$(resolve_address_value CCIPWETH9_BRIDGE CCIPWETH9_BRIDGE 0x971cD9D156f193df8051E48043C476e53ECd4693)" WETH10_BRIDGE="$(resolve_address_value CCIPWETH10_BRIDGE CCIPWETH10_BRIDGE 0xe0E93247376aa097dB308B92e6Ba36bA015535D0)" # Check PRIVATE_KEY if [ -z "${PRIVATE_KEY:-}" ]; then log_error "PRIVATE_KEY not available in effective environment" log_info "Export PRIVATE_KEY or place it in a sourced parent env file" exit 1 fi # Get account address ACCOUNT=$(cast wallet address "$PRIVATE_KEY" 2>/dev/null || echo "") if [ -z "$ACCOUNT" ]; then log_error "Could not derive address from PRIVATE_KEY" exit 1 fi log_info "=========================================" log_info "Automatic Bridge Destination Configuration" log_info "=========================================" log_info "" log_info "Account: $ACCOUNT" log_info "RPC URL: $RPC_URL" log_info "" # Run pre-flight check log_info "Running pre-flight checks..." if ! "$SCRIPT_DIR/pre-flight-check.sh" > /dev/null 2>&1; then log_warn "Pre-flight checks had warnings, but continuing..." fi log_info "" declare -A WETH9_DESTINATIONS=() declare -A WETH10_DESTINATIONS=() declare -A CHAIN_NAMES=() while IFS=$'\t' read -r chain_name selector weth9_dest weth10_dest _rpc_url; do CHAIN_NAMES["$selector"]="$chain_name" WETH9_DESTINATIONS["$selector"]="$weth9_dest" WETH10_DESTINATIONS["$selector"]="$weth10_dest" done < <(ccip_destination_rows) # Function to configure destination with verification configure_destination() { local bridge="$1" local selector="$2" local dest_address="$3" local chain_name="$4" local token_name="$5" # Check if already configured # destinations() returns a tuple: (uint64, address, bool) local current=$(cast call "$bridge" "destinations(uint64)" "$selector" --rpc-url "$RPC_URL" 2>/dev/null || echo "") # Extract address from tuple (second element) local current_hex=$(echo "$current" | sed 's/0x//') local current_clean="" if [ ${#current_hex} -ge 128 ]; then local addr_hex=$(echo "$current_hex" | cut -c65-128) current_clean="0x${addr_hex:24:40}" # Address is right-aligned fi if [ -n "$current_clean" ] && ! echo "$current_clean" | grep -qE "^0x0+$"; then if [ "$(echo "$current_clean" | tr '[:upper:]' '[:lower:]')" = "$(echo "$dest_address" | tr '[:upper:]' '[:lower:]')" ]; then log_success "✓ $token_name $chain_name: Already configured correctly" return 0 else log_warn "⚠ $token_name $chain_name: Configured with different address ($current_clean)" log_info " Expected: $dest_address" fi fi log_info "Configuring $token_name $chain_name..." local nonce=$(cast nonce "$ACCOUNT" --rpc-url "$RPC_URL" 2>/dev/null || echo "0") # Get optimal gas price local gas_price=5000000000 # Default 5 gwei if [ -f "$SCRIPT_DIR/get-optimal-gas-from-api.sh" ]; then api_gas=$("$SCRIPT_DIR/get-optimal-gas-from-api.sh" "proposed" 2>/dev/null || echo "") if [ -n "$api_gas" ] && [ "$api_gas" != "0" ]; then gas_price=$(echo "scale=0; $api_gas * 1.5 / 1" | bc 2>/dev/null || echo "$gas_price") else current_gas=$(cast gas-price --rpc-url "$RPC_URL" 2>/dev/null || echo "1000000000") gas_price=$(echo "scale=0; $current_gas * 1.5 / 1" | bc 2>/dev/null || echo "$gas_price") fi else current_gas=$(cast gas-price --rpc-url "$RPC_URL" 2>/dev/null || echo "1000000000") gas_price=$(echo "scale=0; $current_gas * 1.5 / 1" | bc 2>/dev/null || echo "$gas_price") fi local tx_output=$(cast send "$bridge" \ "addDestination(uint64,address)" \ "$selector" \ "$dest_address" \ --rpc-url "$RPC_URL" \ --private-key "$PRIVATE_KEY" \ --gas-price "$gas_price" \ --nonce "$nonce" \ 2>&1 || echo "FAILED") if echo "$tx_output" | grep -qE "(blockHash|transactionHash)"; then local tx_hash=$(echo "$tx_output" | grep -oE "(blockHash|transactionHash)[[:space:]]+0x[0-9a-fA-F]{64}" | awk '{print $2}' | head -1) log_success "✓ $token_name $chain_name: Transaction sent ($tx_hash)" # Wait for transaction log_info " Waiting for transaction confirmation..." sleep 5 # Verify configuration local verify_current=$(cast call "$bridge" "destinations(uint64)" "$selector" --rpc-url "$RPC_URL" 2>/dev/null || echo "") # Extract address from tuple local verify_hex=$(echo "$verify_current" | sed 's/0x//') local verify_clean="" if [ ${#verify_hex} -ge 128 ]; then local verify_addr_hex=$(echo "$verify_hex" | cut -c65-128) verify_clean="0x${verify_addr_hex:24:40}" fi if [ -n "$verify_clean" ] && ! echo "$verify_clean" | grep -qE "^0x0+$"; then if [ "$(echo "$verify_clean" | tr '[:upper:]' '[:lower:]')" = "$(echo "$dest_address" | tr '[:upper:]' '[:lower:]')" ]; then log_success " ✓ Verified: Configuration successful" return 0 else log_warn " ⚠ Verification: Different address ($verify_clean)" return 1 fi else log_warn " ⚠ Verification: Transaction may still be pending" return 1 fi else log_error "✗ $token_name $chain_name: Transaction failed" log_info " Output: $(echo "$tx_output" | head -3)" return 1 fi } # Configure WETH9 destinations log_fix "=========================================" log_fix "Configuring WETH9 Bridge Destinations" log_fix "=========================================" log_info "" WETH9_SUCCESS=0 WETH9_FAILED=0 WETH9_SKIPPED=0 for SELECTOR in "${!WETH9_DESTINATIONS[@]}"; do DEST_ADDRESS="${WETH9_DESTINATIONS[$SELECTOR]}" CHAIN_NAME="${CHAIN_NAMES[$SELECTOR]}" if configure_destination "$WETH9_BRIDGE" "$SELECTOR" "$DEST_ADDRESS" "$CHAIN_NAME" "WETH9"; then ((WETH9_SUCCESS++)) || true else ((WETH9_FAILED++)) || true fi # Small delay between transactions sleep 2 done log_info "" log_info "WETH9 Results: $WETH9_SUCCESS configured, $WETH9_FAILED failed" log_info "" # Configure WETH10 destinations log_fix "=========================================" log_fix "Configuring WETH10 Bridge Destinations" log_fix "=========================================" log_info "" WETH10_SUCCESS=0 WETH10_FAILED=0 for SELECTOR in "${!WETH10_DESTINATIONS[@]}"; do DEST_ADDRESS="${WETH10_DESTINATIONS[$SELECTOR]}" CHAIN_NAME="${CHAIN_NAMES[$SELECTOR]}" if configure_destination "$WETH10_BRIDGE" "$SELECTOR" "$DEST_ADDRESS" "$CHAIN_NAME" "WETH10"; then ((WETH10_SUCCESS++)) || true else ((WETH10_FAILED++)) || true fi # Small delay between transactions sleep 2 done log_info "" log_info "WETH10 Results: $WETH10_SUCCESS configured, $WETH10_FAILED failed" log_info "" # Final verification log_info "=========================================" log_info "Final Verification" log_info "=========================================" log_info "" "$SCRIPT_DIR/check-bridge-config.sh" # Summary log_info "" log_info "=========================================" log_info "Configuration Summary" log_info "=========================================" log_info "" log_info "WETH9 Bridge:" log_info " Configured: $WETH9_SUCCESS" log_info " Failed: $WETH9_FAILED" log_info "" log_info "WETH10 Bridge:" log_info " Configured: $WETH10_SUCCESS" log_info " Failed: $WETH10_FAILED" log_info "" if [ $WETH9_FAILED -eq 0 ] && [ $WETH10_FAILED -eq 0 ] && [ $WETH9_SUCCESS -eq 7 ] && [ $WETH10_SUCCESS -eq 7 ]; then log_success "✓ All destinations configured successfully!" exit 0 elif [ $WETH9_SUCCESS -gt 0 ] || [ $WETH10_SUCCESS -gt 0 ]; then log_warn "⚠ Partial success - Some destinations configured" log_info " Re-run script to configure remaining destinations" exit 0 else log_error "✗ Configuration failed" log_info " Check transaction outputs above for details" exit 1 fi