147 lines
7.3 KiB
Bash
147 lines
7.3 KiB
Bash
#!/usr/bin/env bash
|
||
# Load project environment: .env, config, and secrets
|
||
# No hardcoded IPs or secrets - all from config and .env
|
||
#
|
||
# Usage: source "${SCRIPT_DIR}/lib/load-project-env.sh"
|
||
#
|
||
# Env precedence (first wins): 1) .env 2) config/ip-addresses.conf 3) smom-dbis-138/.env 4) dbis_core config
|
||
# Version: 2026-04-13 (get_host_for_vmid: explicit Sankofa 7800–7806 on r630-01)
|
||
|
||
[[ -n "${PROJECT_ROOT:-}" ]] || PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||
export PROJECT_ROOT
|
||
|
||
# err_exit: print message and exit (use when load-project-env is sourced)
|
||
err_exit() { echo "ERROR: $1" >&2; exit 1; }
|
||
|
||
# Dotenv / shell env snippets may use ${OTHER_VAR} without :- defaults; callers may use set -u.
|
||
_lpr_source_relaxed() {
|
||
local f="$1"
|
||
[[ -f "$f" ]] || return 0
|
||
local _had_u=0
|
||
[[ -o nounset ]] && _had_u=1
|
||
set +u
|
||
# shellcheck disable=SC1090
|
||
source "$f" 2>/dev/null || true
|
||
if [[ "$_had_u" -eq 1 ]]; then
|
||
set -u
|
||
else
|
||
set +u
|
||
fi
|
||
}
|
||
|
||
_lpr_dotenv_source() {
|
||
local f="$1"
|
||
[[ -f "$f" ]] || return 0
|
||
local _had_u=0
|
||
[[ -o nounset ]] && _had_u=1
|
||
set +u
|
||
set -a
|
||
# shellcheck disable=SC1090
|
||
source "$f" 2>/dev/null || true
|
||
set +a
|
||
if [[ "$_had_u" -eq 1 ]]; then
|
||
set -u
|
||
else
|
||
set +u
|
||
fi
|
||
}
|
||
|
||
# Path validation
|
||
[[ -d "$PROJECT_ROOT" ]] || err_exit "PROJECT_ROOT not a directory: $PROJECT_ROOT"
|
||
[[ -f "${PROJECT_ROOT}/config/ip-addresses.conf" ]] || echo "WARN: config/ip-addresses.conf not found; using defaults" >&2
|
||
|
||
# 1. Root .env (Cloudflare, Proxmox, etc.)
|
||
_lpr_dotenv_source "${PROJECT_ROOT}/.env"
|
||
|
||
# 2. IP/config from centralized config
|
||
[[ -f "${PROJECT_ROOT}/config/ip-addresses.conf" ]] && _lpr_source_relaxed "${PROJECT_ROOT}/config/ip-addresses.conf" || true
|
||
|
||
# 3. smom-dbis-138 .env (PRIVATE_KEY, bridge addrs, RPC) — PRIVATE_KEY is read from this dotenv when not set
|
||
_lpr_dotenv_source "${PROJECT_ROOT}/smom-dbis-138/.env"
|
||
|
||
# 3b. Secure secrets (PRIVATE_KEY) — when not set, try ~/.secure-secrets/private-keys.env
|
||
[[ -z "${PRIVATE_KEY:-}" ]] && [[ -f "${HOME}/.secure-secrets/private-keys.env" ]] && _lpr_dotenv_source "${HOME}/.secure-secrets/private-keys.env"
|
||
|
||
# 3c. Dedicated keeper key (KEEPER_PRIVATE_KEY) — separate signer for keeper/upkeep flows
|
||
KEEPER_SECRET_FILE="${KEEPER_SECRET_FILE:-${HOME}/.secure-secrets/chain138-keeper.env}"
|
||
[[ -z "${KEEPER_PRIVATE_KEY:-}" ]] && [[ -f "${KEEPER_SECRET_FILE}" ]] && _lpr_dotenv_source "${KEEPER_SECRET_FILE}"
|
||
|
||
# 4. dbis_core config if present
|
||
[[ -f "${PROJECT_ROOT}/dbis_core/config/dbis-core-proxmox.conf" ]] && _lpr_source_relaxed "${PROJECT_ROOT}/dbis_core/config/dbis-core-proxmox.conf" || true
|
||
|
||
# 4b. Strip trailing CR/LF from RPC URL vars (editor mistakes; breaks cast/curl)
|
||
for _lpr_k in RPC_URL_138 RPC_URL CHAIN138_RPC CHAIN138_RPC_URL CHAIN_138_RPC_URL \
|
||
TOKEN_AGG_CHAIN138_RPC_URL TOKEN_AGGREGATION_CHAIN138_RPC_URL TOKEN_AGGREGATION_PMM_RPC_URL \
|
||
ETHEREUM_MAINNET_RPC \
|
||
XDC_PARENTNET_URL PARENTNET_URL SUBNET_URL XDC_ZERO_PEER_RPC_URL \
|
||
RPC_URL_138_PUBLIC GNOSIS_MAINNET_RPC GNOSIS_RPC CRONOS_RPC_URL CRONOS_RPC \
|
||
CELO_MAINNET_RPC CELO_RPC WEMIX_RPC WEMIX_MAINNET_RPC BSC_RPC_URL \
|
||
POLYGON_MAINNET_RPC BASE_MAINNET_RPC OPTIMISM_MAINNET_RPC ARBITRUM_MAINNET_RPC \
|
||
AVALANCHE_RPC_URL AVALANCHE_RPC CHAIN_651940_RPC_URL FLASH_PROVIDER_RPC_URL; do
|
||
_lpr_v="${!_lpr_k:-}"
|
||
[[ -z "$_lpr_v" ]] && continue
|
||
_lpr_v="${_lpr_v%$'\r'}"
|
||
_lpr_v="${_lpr_v%$'\n'}"
|
||
export "$_lpr_k=$_lpr_v"
|
||
done
|
||
unset _lpr_k _lpr_v 2>/dev/null || true
|
||
|
||
# 4c. economics-toolkit gas-quote overrides: ECONOMICS_GAS_RPC_<chainId> (same strip)
|
||
for _lpr_id in 1 10 25 56 100 137 138 1111 8453 42161 42220 43114 651940; do
|
||
_lpr_k="ECONOMICS_GAS_RPC_${_lpr_id}"
|
||
_lpr_v="${!_lpr_k:-}"
|
||
[[ -z "$_lpr_v" ]] && continue
|
||
_lpr_v="${_lpr_v%$'\r'}"
|
||
_lpr_v="${_lpr_v%$'\n'}"
|
||
export "$_lpr_k=$_lpr_v"
|
||
done
|
||
unset _lpr_k _lpr_v _lpr_id 2>/dev/null || true
|
||
|
||
# 5. Contract addresses from master JSON (config/smart-contracts-master.json) when not set by .env
|
||
[[ -f "${PROJECT_ROOT}/scripts/lib/load-contract-addresses.sh" ]] && source "${PROJECT_ROOT}/scripts/lib/load-contract-addresses.sh" 2>/dev/null || true
|
||
|
||
# Ensure hosts have fallbacks (from config or defaults)
|
||
PROXMOX_HOST_R630_01="${PROXMOX_HOST_R630_01:-${PROXMOX_R630_01:-192.168.11.11}}"
|
||
PROXMOX_HOST_R630_02="${PROXMOX_HOST_R630_02:-${PROXMOX_R630_02:-192.168.11.12}}"
|
||
PROXMOX_HOST_R630_03="${PROXMOX_HOST_R630_03:-${PROXMOX_R630_03:-192.168.11.13}}"
|
||
PROXMOX_HOST_R630_04="${PROXMOX_HOST_R630_04:-${PROXMOX_R630_04:-192.168.11.14}}"
|
||
PROXMOX_HOST_ML110="${PROXMOX_HOST_ML110:-${PROXMOX_ML110:-192.168.11.10}}"
|
||
# Proxmox hypervisor FQDNs (canonical: <host>.sankofa.nexus — align with LAN DNS)
|
||
export PROXMOX_FQDN_ML110="${PROXMOX_FQDN_ML110:-ml110.sankofa.nexus}"
|
||
export PROXMOX_FQDN_R630_01="${PROXMOX_FQDN_R630_01:-r630-01.sankofa.nexus}"
|
||
export PROXMOX_FQDN_R630_02="${PROXMOX_FQDN_R630_02:-r630-02.sankofa.nexus}"
|
||
export PROXMOX_FQDN_R630_03="${PROXMOX_FQDN_R630_03:-r630-03.sankofa.nexus}"
|
||
export PROXMOX_FQDN_R630_04="${PROXMOX_FQDN_R630_04:-r630-04.sankofa.nexus}"
|
||
|
||
# Derived vars (from config; fallbacks for missing config)
|
||
export RPC_CORE_1="${RPC_CORE_1:-192.168.11.211}"
|
||
export RPC_PUBLIC_1="${RPC_PUBLIC_1:-192.168.11.221}"
|
||
# Chain 138 two standards: (1) Core RPC_URL_138 admin/deploy VMID 2101; (2) Public RPC_URL_138_PUBLIC bridge/frontend VMID 2201. Alias: RPC_URL -> RPC_URL_138.
|
||
export RPC_URL_138="${RPC_URL_138:-${CHAIN138_RPC_URL:-${RPC_URL:-http://${RPC_CORE_1}:8545}}}"
|
||
export CHAIN138_RPC_URL="$RPC_URL_138"
|
||
export CHAIN138_RPC="$RPC_URL_138"
|
||
# Foundry uses ETH_RPC_URL; set so forge create/script use Chain 138 when --rpc-url not passed
|
||
export ETH_RPC_URL="${ETH_RPC_URL:-$RPC_URL_138}"
|
||
export RPC_URL_138_PUBLIC="${RPC_URL_138_PUBLIC:-http://${RPC_PUBLIC_1}:8545}"
|
||
export WS_URL_138_PUBLIC="${WS_URL_138_PUBLIC:-ws://${RPC_PUBLIC_1}:8546}"
|
||
export SMOM_DIR="${SMOM_DBIS_138_DIR:-${PROJECT_ROOT}/smom-dbis-138}"
|
||
export DBIS_CORE_DIR="${DBIS_CORE_DIR:-${PROJECT_ROOT}/dbis_core}"
|
||
|
||
# VMID -> Proxmox host (for pct/qm operations)
|
||
# Covers: DBIS (101xx), RPC (2101-2103, 2201, 2301, etc.), Blockscout (5000), CCIP (5400-5476), NPMplus (10233, 10234), Sankofa stack (7800–7806)
|
||
# Live placement (2026-04-09): validators 1003/1004, sentries 1503-1510, and RPCs 2102, 2301, 2304, 2400, 2402, 2403 on r630-03;
|
||
# RPCs 2201, 2303, 2305-2308, 2401 on r630-02; 2101 + 2103 remain on r630-01 — see ALL_VMIDS_ENDPOINTS.md
|
||
get_host_for_vmid() {
|
||
local vmid="$1"
|
||
case "$vmid" in
|
||
7800|7801|7802|7803|7804|7805|7806) echo "${PROXMOX_HOST_R630_01}";;
|
||
10130|10150|10151|106|107|108|10000|10001|10020|10100|10101|10120|10203|10233|10235) echo "${PROXMOX_HOST_R630_01}";;
|
||
1000|1001|1002|1500|1501|1502|2101|2103) echo "${PROXMOX_HOST_R630_01}";;
|
||
1003|1004|1503|1504|1505|1506|1507|1508|1509|1510|2102|2301|2304|2400|2402|2403) echo "${PROXMOX_HOST_R630_03}";;
|
||
5000|5700|7810|2201|2303|2305|2306|2307|2308|2401|6200|6201|6202|6203|6204|6205|10234|10237|5800|5801) echo "${PROXMOX_HOST_R630_02}";;
|
||
2420|2430|2440|2460|2470|2480) echo "${PROXMOX_HOST_R630_01}";;
|
||
5400|5401|5402|5403|5410|5411|5412|5413|5414|5415|5416|5417|5418|5419|5420|5421|5422|5423|5424|5425|5440|5441|5442|5443|5444|5445|5446|5447|5448|5449|5450|5451|5452|5453|5454|5455|5470|5471|5472|5473|5474|5475|5476) echo "${PROXMOX_HOST_R630_02}";;
|
||
*) echo "${PROXMOX_HOST_R630_01:-${PROXMOX_R630_02}}";;
|
||
esac
|
||
}
|