Files
proxmox/scripts/bridge/run-send-cross-chain.sh
defiQUG 7ac74f432b chore: sync docs, config schemas, scripts, and meta task alignment
- Institutional / JVMTM / reserve-provenance / GRU transport + standards JSON
- Validation and verify scripts (Blockscout labels, x402, GRU preflight, P1 local path)
- Wormhole wiring in AGENTS, MCP_SETUP, MASTER_INDEX, 04-configuration README
- Meta docs, integration gaps, live verification log, architecture updates
- CI validate-config workflow updates

Operator/LAN items, submodule working trees, and public token-aggregation edge
routes remain follow-up (see TODOS_CONSOLIDATED P1).

Made-with: Cursor
2026-03-31 22:31:39 -07:00

93 lines
4.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Send WETH cross-chain via CCIP (Chain 138 → destination chain).
# Usage: ./scripts/bridge/run-send-cross-chain.sh <amount_eth> [recipient] [--dry-run]
# Env: CCIP_DEST_CHAIN_SELECTOR, GAS_PRICE, GAS_LIMIT, CONFIRM_ABOVE_ETH (prompt above this amount)
# Version: 2026-03-30
set -euo pipefail
[[ "${DEBUG:-0}" = "1" ]] && set -x
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
had_nounset=0
if [[ $- == *u* ]]; then
had_nounset=1
set +u
fi
source "${SCRIPT_DIR}/../lib/load-project-env.sh"
(( had_nounset )) && set -u
[[ -z "${PRIVATE_KEY:-}" ]] && { echo "PRIVATE_KEY required"; exit 1; }
[[ -z "${CCIPWETH9_BRIDGE_CHAIN138:-}" ]] && { echo "CCIPWETH9_BRIDGE_CHAIN138 required"; exit 1; }
command -v cast &>/dev/null || { echo "ERROR: cast not found (install Foundry)"; exit 1; }
DRY_RUN=false
ARGS=()
for a in "$@"; do
[[ "$a" = "--dry-run" ]] && DRY_RUN=true || ARGS+=("$a")
done
AMOUNT_ETH="${ARGS[0]:?Usage: $0 amount_eth [recipient] [--dry-run]}"
RECIPIENT="${ARGS[1]:-$(cast wallet address "$PRIVATE_KEY" 2>/dev/null)}"
DEST_SELECTOR="${CCIP_DEST_CHAIN_SELECTOR:-5009297550715157269}"
GAS_PRICE="${GAS_PRICE:-1000000000}"
GAS_LIMIT="${GAS_LIMIT:-}"
RPC="${RPC_URL_138:-$CHAIN138_RPC}"
[[ -z "$RPC" ]] && { echo "ERROR: RPC_URL_138 or CHAIN138_RPC required"; exit 1; }
BRIDGE="${CCIPWETH9_BRIDGE_CHAIN138}"
extract_first_address() {
echo "$1" | grep -oE '0x[a-fA-F0-9]{40}' | sed -n '1p'
}
lower() {
echo "$1" | tr '[:upper:]' '[:lower:]'
}
DEST_RAW="$(cast call "$BRIDGE" 'destinations(uint64)((uint64,address,bool))' "$DEST_SELECTOR" --rpc-url "$RPC" 2>/dev/null || echo "")"
DEST_ADDR="$(extract_first_address "$DEST_RAW")"
AVALANCHE_SELECTOR_VALUE="${AVALANCHE_SELECTOR:-6433500567565415381}"
if [[ "$DEST_SELECTOR" == "$AVALANCHE_SELECTOR_VALUE" ]]; then
AVALANCHE_NATIVE_BRIDGE="${CCIPWETH9_BRIDGE_AVALANCHE:-}"
if [[ -n "$AVALANCHE_NATIVE_BRIDGE" ]] && [[ "$(lower "$DEST_ADDR")" == "$(lower "$AVALANCHE_NATIVE_BRIDGE")" ]] && [[ "${ALLOW_UNSUPPORTED_AVAX_NATIVE:-0}" != "1" ]]; then
cat <<EOF
ERROR: current Avalanche destination mapping points at the native AVAX WETH9 bridge ($DEST_ADDR).
That path is not live from the current Chain 138 router. On 2026-03-30, a live test message to the
native AVAX bridge remained unprocessed because the Chain 138 router emits MessageSent events but
the AVAX native bridge only accepts ccipReceive from its own trusted AVAX router.
Use the relay-backed AVAX receiver instead, or set ALLOW_UNSUPPORTED_AVAX_NATIVE=1 if you are
intentionally testing the unsupported native path.
EOF
exit 1
fi
if [[ -n "$DEST_ADDR" ]]; then
echo "Info: Avalanche send will use current mapped receiver $DEST_ADDR"
fi
fi
# Confirmation for large amounts
CONFIRM_ABOVE="${CONFIRM_ABOVE_ETH:-1}"
if [[ -n "$CONFIRM_ABOVE" ]] && awk -v a="$AMOUNT_ETH" -v b="$CONFIRM_ABOVE" 'BEGIN{exit !(a+0>=b+0)}' 2>/dev/null; then
read -p "Send $AMOUNT_ETH ETH to $RECIPIENT? [y/N] " r
[[ "${r,,}" != "y" ]] && [[ "${r,,}" != "yes" ]] && exit 0
fi
AMOUNT_WEI=$(cast --to-wei "$AMOUNT_ETH" ether)
FEE_WEI=$(cast call "$BRIDGE" "calculateFee(uint64,uint256)" "$DEST_SELECTOR" "$AMOUNT_WEI" --rpc-url "$RPC" 2>/dev/null | cast --to-dec || echo "0")
FEE_TOKEN=$(cast call "$BRIDGE" "feeToken()(address)" --rpc-url "$RPC" 2>/dev/null || echo "0x0")
V=""; [[ "$FEE_TOKEN" = "0x0000000000000000000000000000000000000000" ]] && [[ -n "$FEE_WEI" ]] && [[ "$FEE_WEI" != "0" ]] && V="--value $FEE_WEI"
GAS_OPT=""; [[ -n "$GAS_LIMIT" ]] && GAS_OPT="--gas-limit $GAS_LIMIT"
if [[ "$DRY_RUN" = true ]]; then
echo "DRY-RUN: cast send $BRIDGE sendCrossChain($DEST_SELECTOR,$RECIPIENT,$AMOUNT_WEI) --gas-price $GAS_PRICE --legacy $V $GAS_OPT"
cast call "$BRIDGE" "sendCrossChain(uint64,address,uint256)" "$DEST_SELECTOR" "$RECIPIENT" "$AMOUNT_WEI" --rpc-url "$RPC" --private-key "$PRIVATE_KEY" $V 2>/dev/null && echo "Simulation: OK" || echo "Simulation: (check params)"
exit 0
fi
# Real execution: broadcasts sendCrossChain transaction (no --dry-run)
cast send "$BRIDGE" "sendCrossChain(uint64,address,uint256)" "$DEST_SELECTOR" "$RECIPIENT" "$AMOUNT_WEI" --rpc-url "$RPC" --private-key "$PRIVATE_KEY" --gas-price "$GAS_PRICE" --legacy $V $GAS_OPT