- CCIP/trustless bridge contracts, GRU tokens, DEX/PMM tests, reserve vault. - Token-aggregation service routes, planner, chain config, relay env templates. - Config snapshots and multi-chain deployment markdown updates. - gitignore services/btc-intake/dist/ (tsc output); do not track dist. Run forge build && forge test before deploy (large solc graph). Made-with: Cursor
98 lines
4.1 KiB
Bash
Executable File
98 lines
4.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Send WETH9/10 cross-chain via CCIP bridge
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
source "$SCRIPT_DIR/../lib/init.sh"
|
|
load_env --file "$SCRIPT_DIR/../../.env" ${ENV_PROFILE:+--profile "$ENV_PROFILE"}
|
|
SCRIPT_NAME="ccip-send.sh"
|
|
SCRIPT_DESC="Approve fee/token and call sendCrossChain for WETH bridge"
|
|
SCRIPT_USAGE="${SCRIPT_NAME} --token {weth9|weth10} --selector <chainSelector> --recipient <address> --amount <wei> --pk <hex> [--rpc <url>] [--help]"
|
|
SCRIPT_OPTIONS="--token <name> Bridge token type (weth9|weth10)\n--selector N Destination chain selector (uint64)\n--recipient ADDR Recipient address on destination chain\n--amount WEI Amount of token to send (wei)\n--pk HEX Deployer private key (0x...)\n--rpc URL RPC URL (default: ETHEREUM_MAINNET_RPC or public)\n--help Show help"
|
|
SCRIPT_REQUIREMENTS="foundry cast, LINK balance for fees, token allowance"
|
|
handle_help "${1:-}"
|
|
|
|
ensure_azure_cli >/dev/null 2>&1 || true
|
|
|
|
TOKEN=""; SELECTOR=""; RECIPIENT=""; AMOUNT=""; PK=""; RPC_URL="${ETHEREUM_MAINNET_RPC:-https://eth.llamarpc.com}"
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--token) TOKEN="$2"; shift 2;;
|
|
--selector) SELECTOR="$2"; shift 2;;
|
|
--recipient) RECIPIENT="$2"; shift 2;;
|
|
--amount) AMOUNT="$2"; shift 2;;
|
|
--pk) PK="$2"; shift 2;;
|
|
--rpc) RPC_URL="$2"; shift 2;;
|
|
--help) handle_help "--help";;
|
|
*) log_error "Unknown arg: $1"; exit 1;;
|
|
esac
|
|
done
|
|
|
|
if [ -z "$TOKEN" ] || [ -z "$SELECTOR" ] || [ -z "$RECIPIENT" ] || [ -z "$AMOUNT" ] || [ -z "$PK" ]; then
|
|
log_error "Missing required args. See --help"
|
|
exit 1
|
|
fi
|
|
|
|
case "$TOKEN" in
|
|
weth9)
|
|
BRIDGE_ADDR="${MAINNET_CCIP_WETH9_BRIDGE:-${CCIPWETH9_BRIDGE_MAINNET:-}}"
|
|
TOKEN_ADDR="${WETH9_ADDRESS:?set in .env}"
|
|
;;
|
|
weth10)
|
|
BRIDGE_ADDR="${MAINNET_CCIP_WETH10_BRIDGE:-${CCIPWETH10_BRIDGE_MAINNET:-}}"
|
|
TOKEN_ADDR="${WETH10_ADDRESS:?set in .env}"
|
|
;;
|
|
*) log_error "Invalid --token: $TOKEN"; exit 1;;
|
|
esac
|
|
|
|
if [[ -z "$BRIDGE_ADDR" ]]; then
|
|
log_error "Mainnet bridge address is not set in .env"
|
|
exit 1
|
|
fi
|
|
|
|
if ! FEE_TOKEN="$(cast call "$BRIDGE_ADDR" 'feeToken()(address)' --rpc-url "$RPC_URL" 2>/dev/null | tail -n1)"; then
|
|
log_error "Could not resolve fee token from bridge $BRIDGE_ADDR"
|
|
exit 1
|
|
fi
|
|
|
|
log_section "CCIP SEND"
|
|
log_info "Bridge: $BRIDGE_ADDR"
|
|
log_info "Token: $TOKEN ($TOKEN_ADDR)"
|
|
log_info "Fee Token: $FEE_TOKEN"
|
|
log_info "Selector: $SELECTOR"
|
|
log_info "Recipient: $RECIPIENT"
|
|
log_info "Amount: $AMOUNT"
|
|
|
|
DRY_RUN="${DRY_RUN:-0}"
|
|
run() { if [ "$DRY_RUN" = "1" ]; then echo "[DRY RUN] $*"; else "$@"; fi }
|
|
trim_word() { echo "$1" | awk '{print $1}'; }
|
|
|
|
calculate_fee_or_die() {
|
|
local out
|
|
if ! out="$(cast call "$BRIDGE_ADDR" "calculateFee(uint64,uint256)(uint256)" "$SELECTOR" "$AMOUNT" --rpc-url "$RPC_URL" 2>&1)"; then
|
|
log_error "Fee quote failed on source bridge $BRIDGE_ADDR for selector $SELECTOR."
|
|
log_error "This source bridge/router path is currently blocked until the quote/send path is repaired."
|
|
log_error "$(echo "$out" | tail -n 1)"
|
|
exit 1
|
|
fi
|
|
trim_word "$out"
|
|
}
|
|
|
|
log_subsection "Preflighting source fee quote"
|
|
FEE_QUOTE="$(calculate_fee_or_die)"
|
|
log_info "Quoted fee: $FEE_QUOTE"
|
|
|
|
# Approve LINK fee to router via bridge (bridge approves downstream internally; here user approves bridge to pull fee)
|
|
log_subsection "Approving LINK fee allowance to bridge"
|
|
run cast send --rpc-url "$RPC_URL" --private-key "$PK" "$FEE_TOKEN" "approve(address,uint256)(bool)" "$BRIDGE_ADDR" 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff >/dev/null
|
|
|
|
# Approve WETH to bridge
|
|
log_subsection "Approving token allowance to bridge"
|
|
run cast send --rpc-url "$RPC_URL" --private-key "$PK" "$TOKEN_ADDR" "approve(address,uint256)(bool)" "$BRIDGE_ADDR" "$AMOUNT" >/dev/null
|
|
|
|
# Call sendCrossChain
|
|
log_subsection "Calling sendCrossChain"
|
|
TX_HASH=$(run cast send --rpc-url "$RPC_URL" --private-key "$PK" "$BRIDGE_ADDR" "sendCrossChain(uint64,address,uint256)(bytes32)" "$SELECTOR" "$RECIPIENT" "$AMOUNT" | awk '/Transaction/ {print $2}' || true)
|
|
log_success "Submitted. Tx: ${TX_HASH:-(see output)}"
|
|
echo "$TX_HASH"
|