#!/usr/bin/env bash # Generate MCP allowlist for Chain 138 from DODOPMMIntegration. # Reads getAllPools() and getPoolConfig(pool) via RPC and outputs allowlist JSON. # # Usage: # ./scripts/generate-mcp-allowlist-from-chain138.sh # print to stdout # ./scripts/generate-mcp-allowlist-from-chain138.sh -o allowlist.json # write file # OUT_PATH=ai-mcp-pmm-controller/config/allowlist-138.json ./scripts/generate-mcp-allowlist-from-chain138.sh # # Requires: RPC_URL_138 (or RPC_URL), DODO_PMM_INTEGRATION_ADDRESS in env (or .env in smom-dbis-138). # Optional: MAX_POOLS (default 200), PROFILE (default dodo_pmm_v2_like). set -euo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$REPO_ROOT" # Load env from smom-dbis-138 if present if [[ -f "$REPO_ROOT/smom-dbis-138/.env" ]]; then set -a source "$REPO_ROOT/smom-dbis-138/.env" set +a fi RPC="${RPC_URL_138:-${RPC_URL:-http://192.168.11.211:8545}}" INT="${DODO_PMM_INTEGRATION_ADDRESS:-${DODO_PMM_INTEGRATION:-}}" OUT_PATH="" PROFILE="${PROFILE:-dodo_pmm_v2_like}" MAX_POOLS="${MAX_POOLS:-200}" while [[ $# -gt 0 ]]; do case "$1" in -o) OUT_PATH="$2"; shift 2 ;; *) shift ;; esac done [[ -z "${1:-}" ]] || true [[ -n "$INT" ]] || { echo "DODO_PMM_INTEGRATION_ADDRESS not set"; exit 1; } command -v cast &>/dev/null || { echo "cast (foundry) required"; exit 1; } command -v jq &>/dev/null || { echo "jq required"; exit 1; } # Fetch pool count: call allPools(length) by trying 0..MAX_POOLS (contract has allPools(uint256)) pools=() for ((i=0; i/dev/null | cast --to-addr 2>/dev/null || true) [[ -n "$addr" && "$addr" != "0x0000000000000000000000000000000000000000" ]] || break pools+=("$addr") done echo "Found ${#pools[@]} pools on Chain 138" >&2 # Build JSON array of pool entries entries="[]" for pool in "${pools[@]}"; do # poolConfigs(pool) -> (pool, baseToken, quoteToken, lpFeeRate, i, k, isOpenTWAP, createdAt) config=$(cast call "$INT" "poolConfigs(address)(address,address,address,uint256,uint256,uint256,bool,uint256)" "$pool" --rpc-url "$RPC" 2>/dev/null || true) if [[ -z "$config" ]]; then echo " Skip $pool (poolConfigs failed)" >&2 continue fi # cast may output "addr0 addr1 addr2 ..." or "( addr0 addr1 addr2 ..."; first=pool, second=base, third=quote addrs=($(echo "$config" | grep -oE '0x[0-9a-fA-F]{40}' || true)) base="${addrs[1]:-}" quote="${addrs[2]:-}" [[ -n "$base" && -n "$quote" ]] || continue name="pool-${pool:2:8}" entry=$(jq -n \ --arg name "$name" \ --arg pool "$pool" \ --arg base "$base" \ --arg quote "$quote" \ --arg profile "$PROFILE" \ '{name: $name, pool_address: $pool, base_token: $base, quote_token: $quote, profile: $profile, limits: {max_slippage_bps: 50, max_single_tx_notional_usd: 2500, max_daily_notional_usd: 10000, cooldown_seconds: 1800, max_oracle_deviation_bps: 75, gas_cap_gwei: 35}}') entries=$(echo "$entries" | jq --argjson e "$entry" '. + [$e]') done result=$(jq -n \ --arg chain "138" \ --argjson pools "$entries" \ '{chain: $chain, description: "Chain 138 (DeFi Oracle) DODO PMM pools. Auto-generated from DODOPMMIntegration.getAllPools/getPoolConfig. Set ALLOWLIST_PATH and CHAIN=138 when running MCP.", pools: $pools}') if [[ -n "$OUT_PATH" ]]; then mkdir -p "$(dirname "$OUT_PATH")" echo "$result" | jq . > "$OUT_PATH" echo "Wrote $OUT_PATH" >&2 else echo "$result" | jq . fi