#!/usr/bin/env bash # Complete LINK Token Setup - All Next Steps # Runs database migration, verifies token, checks CCIP config 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" load_explorer_runtime_env LINK_TOKEN="$(resolve_address_value LINK_TOKEN LINK_TOKEN_138 0x514910771AF9Ca656af840dff83E8264EcF986CA)" CHAIN_ID=138 RPC_URL="${RPC_URL_138:-http://192.168.11.250:8545}" CCIP_ROUTER="$(resolve_address_value CCIP_ROUTER_ADDRESS CCIP_ROUTER_ADDRESS 0x8078A09637e47Fa5Ed34F626046Ea2094a5CDE5e)" echo "╔══════════════════════════════════════════════════════════════╗" echo "║ COMPLETE LINK TOKEN SETUP ║" echo "╚══════════════════════════════════════════════════════════════╝" echo "" echo "LINK Token: $LINK_TOKEN" echo "Chain ID: $CHAIN_ID" echo "RPC: $RPC_URL" echo "" # Step 1: Verify token on chain echo "=== Step 1: Verifying LINK Token on Chain ===" CODE=$(cast code "$LINK_TOKEN" --rpc-url "$RPC_URL" 2>/dev/null || echo "") if [ -n "$CODE" ] && [ "$CODE" != "0x" ] && [ ${#CODE} -gt 100 ]; then echo "✅ LINK token EXISTS on ChainID $CHAIN_ID" echo " Bytecode length: ${#CODE} chars" NAME=$(cast call "$LINK_TOKEN" "name()" --rpc-url "$RPC_URL" 2>/dev/null | cast --to-ascii 2>/dev/null | tr -d '\0' || echo "") SYMBOL=$(cast call "$LINK_TOKEN" "symbol()" --rpc-url "$RPC_URL" 2>/dev/null | cast --to-ascii 2>/dev/null | tr -d '\0' || echo "") DECIMALS=$(cast call "$LINK_TOKEN" "decimals()" --rpc-url "$RPC_URL" 2>/dev/null || echo "") echo " Name: $NAME" echo " Symbol: $SYMBOL" echo " Decimals: $DECIMALS" TOKEN_EXISTS=true else echo "⚠ LINK token NOT FOUND on ChainID $CHAIN_ID" echo " Code length: ${#CODE}" echo " Note: The Ethereum Mainnet LINK address may not exist on ChainID 138" echo " Options:" echo " 1. Deploy LINK token to ChainID 138" echo " 2. Bridge LINK from Ethereum Mainnet" echo " 3. Use a different LINK token address for ChainID 138" TOKEN_EXISTS=false fi echo "" # Step 2: Check CCIP Router echo "=== Step 2: Checking CCIP Router Configuration ===" FEE_TOKEN=$(cast call "$CCIP_ROUTER" "getFeeToken()" --rpc-url "$RPC_URL" 2>/dev/null || echo "") if [ -n "$FEE_TOKEN" ] && [ "$FEE_TOKEN" != "0x" ]; then FEE_TOKEN_CLEAN=$(echo "$FEE_TOKEN" | tr -d '[:space:]' | grep -oE "0x[a-fA-F0-9]{40}" | head -1 || echo "") if [ -n "$FEE_TOKEN_CLEAN" ]; then echo "CCIP Router Fee Token: $FEE_TOKEN_CLEAN" if [ "${FEE_TOKEN_CLEAN,,}" = "${LINK_TOKEN,,}" ]; then echo "✅ CCIP Router fee token matches configured LINK address" else echo "⚠ CCIP Router uses different fee token" echo " Configured LINK: $LINK_TOKEN" echo " Router Fee Token: $FEE_TOKEN_CLEAN" fi else echo "⚠ Could not parse fee token from router response" fi else echo "⚠ Could not query CCIP Router fee token" echo " Router: $CCIP_ROUTER" echo " This may indicate the router doesn't support getFeeToken() or RPC issues" fi echo "" # Step 3: Run database migration echo "=== Step 3: Running Database Migration ===" DB_HOST="${DB_HOST:-localhost}" DB_PORT="${DB_PORT:-5432}" DB_NAME="${DB_NAME:-explorer}" DB_USER="${DB_USER:-postgres}" DB_PASSWORD="${DB_PASSWORD:-}" MIGRATION_FILE="$PROJECT_ROOT/backend/database/migrations/0009_add_link_token.up.sql" if [ ! -f "$MIGRATION_FILE" ]; then echo "❌ Migration file not found: $MIGRATION_FILE" exit 1 fi if [ -z "$DB_PASSWORD" ]; then echo "⚠ DB_PASSWORD not set in environment" echo " Skipping database migration" echo " To run manually:" echo " export PGPASSWORD=''" echo " psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -f $MIGRATION_FILE" MIGRATION_SKIPPED=true else export PGPASSWORD="$DB_PASSWORD" if command -v psql &> /dev/null; then echo "Running migration..." if psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -f "$MIGRATION_FILE" 2>&1; then echo "✅ Migration completed successfully" echo "" echo "Verifying LINK token in database..." psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c \ "SELECT chain_id, address, name, symbol, decimals, verified FROM tokens WHERE chain_id = $CHAIN_ID AND address = '$LINK_TOKEN';" \ 2>&1 | grep -v "password" || true MIGRATION_COMPLETE=true else echo "❌ Migration failed" MIGRATION_COMPLETE=false fi else echo "⚠ psql not found, skipping database migration" MIGRATION_SKIPPED=true fi fi echo "" # Step 4: Check bridge balances (if token exists) if [ "${TOKEN_EXISTS:-false}" = "true" ]; then echo "=== Step 4: Checking Bridge LINK Balances ===" WETH9_BRIDGE="$(resolve_address_value CCIPWETH9_BRIDGE CCIPWETH9_BRIDGE 0x971cD9D156f193df8051E48043C476e53ECd4693)" WETH10_BRIDGE="$(resolve_address_value CCIPWETH10_BRIDGE CCIPWETH10_BRIDGE 0xe0E93247376aa097dB308B92e6Ba36bA015535D0)" WETH9_LINK=$(cast call "$LINK_TOKEN" "balanceOf(address)" "$WETH9_BRIDGE" --rpc-url "$RPC_URL" 2>/dev/null || echo "0") WETH9_LINK_ETH=$(cast --from-wei "$WETH9_LINK" ether 2>/dev/null || echo "0") WETH10_LINK=$(cast call "$LINK_TOKEN" "balanceOf(address)" "$WETH10_BRIDGE" --rpc-url "$RPC_URL" 2>/dev/null || echo "0") WETH10_LINK_ETH=$(cast --from-wei "$WETH10_LINK" ether 2>/dev/null || echo "0") echo "WETH9 Bridge: $WETH9_LINK_ETH LINK" echo "WETH10 Bridge: $WETH10_LINK_ETH LINK" echo "" if (( $(echo "$WETH9_LINK_ETH < 10" | bc -l 2>/dev/null || echo 1) )) || \ (( $(echo "$WETH10_LINK_ETH < 10" | bc -l 2>/dev/null || echo 1) )); then echo "⚠ Bridges need LINK funding (recommended: 10 LINK each)" ACCOUNT=$(cast wallet address "$PRIVATE_KEY" 2>/dev/null || echo "") if [ -n "$ACCOUNT" ]; then ACCOUNT_BALANCE=$(cast call "$LINK_TOKEN" "balanceOf(address)" "$ACCOUNT" --rpc-url "$RPC_URL" 2>/dev/null || echo "0") ACCOUNT_BALANCE_ETH=$(cast --from-wei "$ACCOUNT_BALANCE" ether 2>/dev/null || echo "0") echo "Account LINK Balance: $ACCOUNT_BALANCE_ETH LINK" if (( $(echo "$ACCOUNT_BALANCE_ETH >= 20" | bc -l 2>/dev/null || echo 0) )); then echo "" echo "Funding bridges..." export LINK_TOKEN "$SCRIPT_DIR/fund-bridge-contracts.sh" 10 2>&1 | tail -20 else echo " Account balance insufficient for funding" fi fi else echo "✅ Bridges have sufficient LINK balance" fi else echo "=== Step 4: Bridge Balance Check ===" echo "⚠ Skipped - LINK token not found on chain" fi echo "" # Final Summary echo "╔══════════════════════════════════════════════════════════════╗" echo "║ SETUP SUMMARY ║" echo "╚══════════════════════════════════════════════════════════════╝" echo "" echo "Configuration:" echo " ✓ Address inventory available for LINK_TOKEN" echo " ✓ Token lists updated" echo " ✓ CCIP configuration documented" echo "" if [ "${TOKEN_EXISTS:-false}" = "true" ]; then echo "✅ Token Status: LINK token EXISTS on ChainID $CHAIN_ID" else echo "⚠ Token Status: LINK token NOT FOUND on ChainID $CHAIN_ID" echo " Action Required: Deploy or bridge LINK token" fi if [ "${MIGRATION_COMPLETE:-false}" = "true" ]; then echo "✅ Database: Migration completed" elif [ "${MIGRATION_SKIPPED:-false}" = "true" ]; then echo "⚠ Database: Migration skipped (run manually)" else echo "❌ Database: Migration failed" fi echo "" echo "Next Actions:" if [ "${TOKEN_EXISTS:-false}" != "true" ]; then echo " 1. Deploy LINK token to ChainID 138, OR" echo " 2. Bridge LINK from Ethereum Mainnet, OR" echo " 3. Update configuration to use existing LINK token address" fi if [ "${MIGRATION_COMPLETE:-false}" != "true" ] && [ "${MIGRATION_SKIPPED:-false}" != "true" ]; then echo " 1. Fix database connection and run migration manually" fi echo "" echo "✅ Setup script completed!" echo ""