#!/usr/bin/env bash # Wire Chain 138 <-> Monad CCIP WETH bridges (addDestination both directions). # Also enables MONAD_SELECTOR on Chain 138 custom CCIPRouter allowlist when set. # # Requires in .env: # CCIPWETH9_BRIDGE_CHAIN138, CCIPWETH10_BRIDGE_CHAIN138 # CCIPWETH9_BRIDGE_MONAD, CCIPWETH10_BRIDGE_MONAD # CHAIN138_SELECTOR, MONAD_SELECTOR, CCIP_ROUTER (138 custom router) # RPC_URL_138 / CHAIN138_RPC, MONAD_MAINNET_RPC # # Usage: # DRY_RUN=1 ./scripts/deployment/complete-config-monad-chain138.sh # ./scripts/deployment/complete-config-monad-chain138.sh set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$PROJECT_ROOT" 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 DRY_RUN="${DRY_RUN:-0}" CHAIN138_RPC="${RPC_URL_138:-${CHAIN138_RPC:-http://192.168.11.211:8545}}" MONAD_RPC="${MONAD_MAINNET_RPC:-https://rpc.monad.xyz}" # Infura project keys often lack Monad access — prefer public RPC unless forced. if [[ "$MONAD_RPC" =~ infura\.io/v3 ]] && [[ "${MONAD_MAINNET_RPC_FORCE_INFURA:-0}" != "1" ]]; then MONAD_RPC="${MONAD_MAINNET_RPC_PUBLIC:-https://rpc.monad.xyz}" fi CHAIN138_SELECTOR="${CHAIN138_SELECTOR:-}" MONAD_SELECTOR="${MONAD_SELECTOR:-8481857512324358265}" CCIP_ROUTER="${CCIP_ROUTER:-}" GAS_138="--legacy --gas-limit 250000 --gas-price 2000000000 --timeout 600" W9_138="${CCIPWETH9_BRIDGE_CHAIN138:-}" W10_138="${CCIPWETH10_BRIDGE_CHAIN138:-}" W9_MONAD="${CCIPWETH9_BRIDGE_MONAD:-}" W10_MONAD="${CCIPWETH10_BRIDGE_MONAD:-}" missing=0 for v in W9_138 W10_138 W9_MONAD W10_MONAD CHAIN138_SELECTOR; do if [[ -z "${!v}" ]]; then echo "Missing: $v" >&2 missing=1 fi done [[ "$missing" == "1" ]] && exit 1 if ! require_private_key_env; then exit 1 fi dest_enabled() { local rpc="$1" bridge="$2" selector="$3" local enabled enabled=$(cast call "$bridge" "destinations(uint64)(uint64,address,bool)" "$selector" --rpc-url "$rpc" 2>/dev/null | awk 'NR==3{print $1}') [[ "$enabled" == "true" ]] } add_dest() { local rpc="$1" bridge="$2" selector="$3" receiver="$4" label="$5" local gas_opts="$6" if dest_enabled "$rpc" "$bridge" "$selector"; then echo "Skip (already enabled): $label" return 0 fi if [[ "$DRY_RUN" == "1" ]]; then echo "[DRY RUN] $label: cast send $bridge addDestination($selector,$receiver) --rpc-url ${rpc%%\?*} $gas_opts" return 0 fi echo "=== $label ===" # shellcheck disable=SC2086 cast send "$bridge" "addDestination(uint64,address)" "$selector" "$receiver" \ --rpc-url "$rpc" --private-key "$PRIVATE_KEY" $gas_opts } ensure_router_supports_monad() { [[ -z "$CCIP_ROUTER" ]] && return 0 local rout="${CCIP_ROUTER,,}" local supported supported=$(cast call "$rout" "supportedChains(uint64)(bool)" "$MONAD_SELECTOR" --rpc-url "$CHAIN138_RPC" 2>/dev/null || echo "false") if [[ "$supported" == "true" ]]; then echo "CCIP router: Monad selector already supported ($MONAD_SELECTOR)" return 0 fi if [[ "$DRY_RUN" == "1" ]]; then echo "[DRY RUN] CCIP router addSupportedChain($MONAD_SELECTOR) on $rout" return 0 fi echo "=== Chain 138 CCIP router: enable Monad selector ===" # shellcheck disable=SC2086 cast send "$rout" "addSupportedChain(uint64)" "$MONAD_SELECTOR" \ --rpc-url "$CHAIN138_RPC" --private-key "$PRIVATE_KEY" $GAS_138 } echo "=== Monad <-> Chain 138 CCIP destination wiring ===" ensure_router_supports_monad # 138 -> Monad add_dest "$CHAIN138_RPC" "$W9_138" "$MONAD_SELECTOR" "$W9_MONAD" "138 WETH9 -> Monad" "$GAS_138" add_dest "$CHAIN138_RPC" "$W10_138" "$MONAD_SELECTOR" "$W10_MONAD" "138 WETH10 -> Monad" "$GAS_138" # Monad -> 138 add_dest "$MONAD_RPC" "$W9_MONAD" "$CHAIN138_SELECTOR" "$W9_138" "Monad WETH9 -> 138" "--legacy --timeout 600" add_dest "$MONAD_RPC" "$W10_MONAD" "$CHAIN138_SELECTOR" "$W10_138" "Monad WETH10 -> 138" "--legacy --timeout 600" echo "Done. Fund bridges with LINK/MON per CCIP_BRIDGE_DESTINATIONS_AND_LINK_FUNDING.md before live transfers."