2026-02-26 22:35:24 -08:00
#!/usr/bin/env bash
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
# Security: do not use `bash -x` or `curl -v` when debugging auth in production — logs may capture secrets.
# Auth failures: only a short error message is printed by default. For a redacted JSON snippet set NPM_DEBUG_AUTH=1.
2026-02-12 15:46:57 -08:00
set -euo pipefail
2026-03-27 00:30:28 -07:00
# Repo root (…/proxmox) — same as second block below; load IPs once from the right path
2026-02-12 15:46:57 -08:00
SCRIPT_DIR = " $( cd " $( dirname " ${ BASH_SOURCE [0] } " ) " && pwd ) "
2026-03-27 00:30:28 -07:00
PROJECT_ROOT = " $( cd " $SCRIPT_DIR /../.. " && pwd ) "
2026-02-12 15:46:57 -08:00
source " ${ PROJECT_ROOT } /config/ip-addresses.conf " 2>/dev/null || true
# Update existing NPMplus proxy hosts via API with correct VMIDs and IPs
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
# This script updates existing proxy hosts, not creates new ones.
# PUT payload includes only forward_* / websocket / block_exploits — existing certificate_id and ssl_forced are preserved by NPMplus.
2026-02-12 15:46:57 -08:00
set -e
# Preserve NPM credentials from environment so "export NPM_PASSWORD=...; ./script" works
_orig_npm_url = " ${ NPM_URL :- } "
_orig_npm_email = " ${ NPM_EMAIL :- } "
_orig_npm_password = " ${ NPM_PASSWORD :- } "
2026-03-04 02:03:08 -08:00
# Load dotenv: repo root .env then smom-dbis-138/.env (operator creds)
2026-02-12 15:46:57 -08:00
if [ -f " $PROJECT_ROOT /.env " ] ; then
set +u
# shellcheck source=/dev/null
source " $PROJECT_ROOT /.env "
set -u
fi
2026-03-04 02:03:08 -08:00
if [ -f " $PROJECT_ROOT /smom-dbis-138/.env " ] ; then
set +u
# shellcheck source=/dev/null
source " $PROJECT_ROOT /smom-dbis-138/.env "
set -u
fi
[ -n " $_orig_npm_url " ] && NPM_URL = " $_orig_npm_url "
[ -n " $_orig_npm_email " ] && NPM_EMAIL = " $_orig_npm_email "
[ -n " $_orig_npm_password " ] && NPM_PASSWORD = " $_orig_npm_password "
2026-02-12 15:46:57 -08:00
[ -f " $PROJECT_ROOT /config/ip-addresses.conf " ] && source " $PROJECT_ROOT /config/ip-addresses.conf " 2>/dev/null || true
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
# Default: NPMplus (VMID 10233) — IP_NPMPLUS from config/ip-addresses.conf (prefer eth1 / .167); override with NPM_URL in .env
2026-02-12 15:46:57 -08:00
NPM_URL = " ${ NPM_URL :- https : // ${ IP_NPMPLUS } : 81 } "
NPM_EMAIL = " ${ NPM_EMAIL :- nsatoshi2007 @hotmail.com } "
NPM_PASSWORD = " ${ NPM_PASSWORD :- } "
if [ -z " $NPM_PASSWORD " ] ; then
echo "❌ NPM_PASSWORD is required. Set it in .env or export NPM_PASSWORD=..."
echo " Example: echo 'NPM_PASSWORD=your-password' >> $PROJECT_ROOT /.env "
exit 1
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🔄 Updating NPMplus Proxy Hosts via API"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
# NPMplus API can stall indefinitely without --max-time (override e.g. NPM_CURL_MAX_TIME=300)
NPM_CURL_MAX_TIME = " ${ NPM_CURL_MAX_TIME :- 120 } "
2026-03-27 00:30:28 -07:00
# -L: port 81 often 301s HTTP→HTTPS; POST /api/tokens without -L returns 400 "Payload is undefined"
curl_npm( ) { curl -s -k -L --connect-timeout 10 --max-time " $NPM_CURL_MAX_TIME " " $@ " ; }
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
# Connection check (NPMplus is on LAN 192.168.11.x). Try HTTP if HTTPS fails; try alternate IP .166/.167 if unreachable.
2026-02-12 15:46:57 -08:00
echo "🔐 Authenticating to NPMplus..."
2026-03-27 00:30:28 -07:00
try_connect( ) { curl -s -k -L -o /dev/null --connect-timeout 5 --max-time 15 " $1 " 2>/dev/null; }
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
if ! try_connect " $NPM_URL / " ; then
# Try HTTP instead of HTTPS (NPM admin often listens on HTTP only on port 81)
http_url = " ${ NPM_URL /https : /http : } "
if try_connect " $http_url / " ; then
NPM_URL = " $http_url "
echo " Using HTTP (HTTPS timed out): $NPM_URL "
2026-02-12 15:46:57 -08:00
else
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
alt_url = ""
if [ [ " $NPM_URL " = = *" ${ IP_NPMPLUS_ETH0 } " * ] ] ; then
alt_url = " https:// ${ IP_NPMPLUS } :81 "
2026-03-27 00:30:28 -07:00
elif [ [ " $NPM_URL " = = *" ${ IP_NPMPLUS } " * ] ] || [ [ -n " ${ IP_NPMPLUS_ETH1 :- } " && " $NPM_URL " = = *" ${ IP_NPMPLUS_ETH1 } " * ] ] ; then
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
alt_url = " https:// ${ IP_NPMPLUS_ETH0 } :81 "
fi
connected = ""
if [ -n " $alt_url " ] && try_connect " $alt_url / " ; then connected = " $alt_url " ; fi
if [ -z " $connected " ] && [ -n " $alt_url " ] && try_connect " ${ alt_url /https : /http : } / " ; then connected = " ${ alt_url /https : /http : } " ; fi
if [ -n " $connected " ] ; then
NPM_URL = " $connected "
echo " Using alternate NPMplus URL: $NPM_URL "
else
echo " ❌ Cannot connect to NPMplus at $NPM_URL "
[ -n " $alt_url " ] && echo " Tried alternate: $alt_url and ${ alt_url /https : /http : } "
echo " Try in browser: http:// ${ IP_NPMPLUS } :81 (not https). If not on LAN, use SSH tunnel: ssh -L 8181: ${ IP_NPMPLUS } :81 -N root@ ${ PROXMOX_HOST_R630_01 } then http://127.0.0.1:8181 "
echo " Run this script from a host on the same LAN as NPMplus. Ensure container 10233 is running."
exit 1
fi
2026-02-12 15:46:57 -08:00
fi
fi
AUTH_JSON = $( jq -n --arg identity " $NPM_EMAIL " --arg secret " $NPM_PASSWORD " '{identity:$identity,secret:$secret}' )
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
TOKEN_RESPONSE = $( curl_npm -X POST " $NPM_URL /api/tokens " \
2026-02-12 15:46:57 -08:00
-H "Content-Type: application/json" \
-d " $AUTH_JSON " )
TOKEN = $( echo " $TOKEN_RESPONSE " | jq -r '.token // empty' 2>/dev/null || echo "" )
if [ -z " $TOKEN " ] || [ " $TOKEN " = "null" ] ; then
ERROR_MSG = $( echo " $TOKEN_RESPONSE " | jq -r '.message // .error.message // .error // "Unknown error"' 2>/dev/null || echo "" )
echo " ❌ Authentication failed: ${ ERROR_MSG :- No token in response } "
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
if [ " ${ NPM_DEBUG_AUTH :- 0 } " = "1" ] ; then
# Strip .token from body before preview (never print bearer tokens)
RESP_PREVIEW = $( echo " $TOKEN_RESPONSE " | jq -c 'del(.token) | del(.data)' 2>/dev/null | head -c 300)
[ -z " $RESP_PREVIEW " ] && RESP_PREVIEW = $( echo " $TOKEN_RESPONSE " | head -c 200)
echo " Debug (NPM_DEBUG_AUTH=1, token field stripped if jq OK): $RESP_PREVIEW "
2026-02-12 15:46:57 -08:00
fi
exit 1
fi
echo "✅ Authentication successful"
echo ""
# Get all proxy hosts
echo "📋 Fetching existing proxy hosts..."
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
PROXY_HOSTS_JSON = $( curl_npm -X GET " $NPM_URL /api/nginx/proxy-hosts " \
2026-02-12 15:46:57 -08:00
-H " Authorization: Bearer $TOKEN " )
if [ $? -ne 0 ] ; then
echo "❌ Failed to fetch proxy hosts"
exit 1
fi
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
# Match proxy host id by domain (case-insensitive). Avoids "not found" when NPM stores different casing.
resolve_proxy_host_id( ) {
local domain = " $1 "
local json = " ${ 2 :- $PROXY_HOSTS_JSON } "
echo " $json " | jq -r --arg d " $domain " '
.[ ] | select ( .domain_names | type = = "array" ) |
select ( any( .domain_names[ ] ; ( . | tostring | ascii_downcase) = = ( $d | ascii_downcase) ) ) |
.id' 2>/dev/null | head -n1
}
2026-03-27 12:29:40 -07:00
# www → apex redirect: only https://hostname[:port] (no path/query); rejects characters that could break nginx advanced_config.
validate_canonical_https_redirect( ) {
local url = " $1 "
local ctx = " ${ 2 :- canonical_https } "
if [ [ " $url " != https://* ] ] ; then
echo " ❌ $ctx : canonical_https must start with https:// (got: $url ) "
return 1
fi
if [ [ " $url " = = *$'\n' * || " $url " = = *$'\r' * || " $url " = = *' ' * || " $url " = = *';' * || " $url " = = *'$' * || " $url " = = *'`' * ] ] ; then
echo " ❌ $ctx : canonical_https contains forbidden characters (no spaces, semicolons, dollar, backticks) "
return 1
fi
local rest = " ${ url #https : // } "
if [ [ " $rest " = = */* ] ] ; then
echo " ❌ $ctx : canonical_https must not include a path (got: $url ) "
return 1
fi
if ! [ [ " $rest " = ~ ^[ a-zA-Z0-9._-] +( :[ 0-9] { 1,5} ) ?$ ] ] ; then
echo " ❌ $ctx : canonical_https must be https://hostname or https://hostname:port (got: $url ) "
return 1
fi
return 0
}
2026-02-21 15:46:06 -08:00
# Function to add proxy host (POST) when domain does not exist
2026-03-27 00:30:28 -07:00
# Optional 6th arg: canonical HTTPS apex for www-style hosts (sets advanced_config 301 → apex$request_uri)
2026-02-21 15:46:06 -08:00
add_proxy_host( ) {
local domain = $1
local forward_host = $2
local forward_port = $3
local websocket = $4
local block_exploits = ${ 5 :- false }
2026-03-27 00:30:28 -07:00
local canonical_https = " ${ 6 :- } "
local adv_line = ""
2026-03-27 12:29:40 -07:00
if [ -n " $canonical_https " ] && ! validate_canonical_https_redirect " $canonical_https " " add_proxy_host( $domain ) " ; then
return 1
fi
2026-03-27 00:30:28 -07:00
if [ -n " $canonical_https " ] ; then
adv_line = " return 301 ${ canonical_https } \$request_uri; "
fi
2026-02-21 15:46:06 -08:00
local payload
payload = $( jq -n \
--arg domain " $domain " \
--arg host " $forward_host " \
--argjson port " $forward_port " \
--argjson ws " $websocket " \
--argjson block_exploits " $( [ " $block_exploits " = "true" ] && echo true || echo false ) " \
2026-03-27 00:30:28 -07:00
--arg adv " $adv_line " \
2026-02-21 15:46:06 -08:00
' {
domain_names: [ $domain ] ,
forward_scheme: "http" ,
forward_host: $host ,
forward_port: $port ,
allow_websocket_upgrade: $ws ,
block_exploits: $block_exploits ,
certificate_id: null,
ssl_forced: false
2026-03-27 00:30:28 -07:00
} + ( if $adv != "" then { advanced_config: $adv } else { } end) ' 2>/dev/null)
2026-02-21 15:46:06 -08:00
if [ -z " $payload " ] ; then
echo " ❌ Failed to build payload for $domain "
return 1
fi
local resp
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
resp = $( curl_npm -X POST " $NPM_URL /api/nginx/proxy-hosts " \
2026-02-21 15:46:06 -08:00
-H " Authorization: Bearer $TOKEN " \
-H "Content-Type: application/json" \
-d " $payload " 2>/dev/null)
local id
id = $( echo " $resp " | jq -r '.id // empty' 2>/dev/null)
if [ -n " $id " ] && [ " $id " != "null" ] ; then
2026-03-27 12:29:40 -07:00
if [ -n " $canonical_https " ] ; then
echo " ✅ Added: $domain -> http:// ${ forward_host } : ${ forward_port } (WebSocket: $websocket ) + 301 → ${ canonical_https } \$request_uri "
else
echo " ✅ Added: $domain -> http:// ${ forward_host } : ${ forward_port } (WebSocket: $websocket ) "
fi
2026-02-21 15:46:06 -08:00
return 0
else
local err
err = $( echo " $resp " | jq -r '.message // .error // "unknown"' 2>/dev/null)
echo " ❌ Add failed for $domain : $err "
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
if echo " $err " | grep -qiE 'already|in use|exist|duplicate|unique' ; then
echo " ↪ Host likely exists; refreshing list and attempting PUT update..."
PROXY_HOSTS_JSON = $( curl_npm -X GET " $NPM_URL /api/nginx/proxy-hosts " \
-H " Authorization: Bearer $TOKEN " )
2026-03-27 00:30:28 -07:00
if update_proxy_host " $domain " " http:// ${ forward_host } : ${ forward_port } " " $websocket " " $block_exploits " " $canonical_https " ; then
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
echo " ✅ Updated after duplicate-create error: $domain "
return 0
fi
fi
2026-02-21 15:46:06 -08:00
return 1
fi
}
2026-02-12 15:46:57 -08:00
# Function to update proxy host
# block_exploits: set false for RPC hosts (JSON-RPC uses POST to /; block_exploits can cause 405)
2026-03-27 00:30:28 -07:00
# Optional 5th arg: canonical HTTPS URL (no path) — sets advanced_config to 301 redirect (www → apex)
2026-02-12 15:46:57 -08:00
update_proxy_host( ) {
local domain = $1
local target = $2
local websocket = $3
local block_exploits = ${ 4 :- true }
2026-03-27 00:30:28 -07:00
local canonical_https = " ${ 5 :- } "
2026-03-27 12:29:40 -07:00
if [ -n " $canonical_https " ] && ! validate_canonical_https_redirect " $canonical_https " " update_proxy_host( $domain ) " ; then
return 1
fi
2026-02-12 15:46:57 -08:00
# Parse target URL
local scheme = $( echo " $target " | sed -E 's|^([^:]+):.*|\1|' )
local hostname = $( echo " $target " | sed -E 's|^[^/]+//([^:]+):.*|\1|' )
local port = $( echo " $target " | sed -E 's|^[^:]+://[^:]+:([0-9]+).*|\1|' )
# Handle https URLs
if [ [ " $target " = = https://* ] ] ; then
scheme = "https"
hostname = $( echo " $target " | sed -E 's|^https://([^:]+):.*|\1|' )
port = $( echo " $target " | sed -E 's|^https://[^:]+:([0-9]+).*|\1|' || echo "443" )
fi
2026-03-27 00:30:28 -07:00
# Reject bad parses (e.g. https://:443 when forward IP env is empty) — NPM returns errors without .id and jq message is empty.
if [ [ -z " $hostname " || " $hostname " = = *"://" * || " $hostname " = = *"/" * ] ] ; then
echo " ❌ Invalid forward target for $domain (check env / ip-addresses.conf): $target → host=[ $hostname ] "
return 1
fi
port = " ${ port //[^0-9]/ } "
if [ [ -z " $port " || " $port " -lt 1 || " $port " -gt 65535 ] ] ; then
echo " ❌ Invalid forward port for $domain : $target (parsed port= $port ) "
return 1
fi
2026-02-12 15:46:57 -08:00
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
# Get host ID (case-insensitive); refresh once if missing (stale list / race with other writers)
HOST_ID = $( resolve_proxy_host_id " $domain " " $PROXY_HOSTS_JSON " )
if [ -z " $HOST_ID " ] || [ " $HOST_ID " = "null" ] ; then
echo " 📋 Refreshing proxy host list (retry lookup for $domain )... "
PROXY_HOSTS_JSON = $( curl_npm -X GET " $NPM_URL /api/nginx/proxy-hosts " \
-H " Authorization: Bearer $TOKEN " )
HOST_ID = $( resolve_proxy_host_id " $domain " " $PROXY_HOSTS_JSON " )
fi
2026-02-12 15:46:57 -08:00
if [ -z " $HOST_ID " ] || [ " $HOST_ID " = "null" ] ; then
echo " ⚠️ Domain $domain not found (skipping) "
return 1
fi
echo " 📋 Updating $domain (ID: $HOST_ID )... "
# Create minimal update payload - NPMplus API only accepts specific fields
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
# block_exploits must be false for RPC so POST to / is allowed (JSON-RPC); explicit false fixes 405
local be_json = "false"
[ " $block_exploits " = "true" ] && be_json = "true"
2026-03-27 00:30:28 -07:00
local adv_line = ""
if [ -n " $canonical_https " ] ; then
adv_line = " return 301 ${ canonical_https } \$request_uri; "
fi
2026-02-12 15:46:57 -08:00
UPDATE_PAYLOAD = $( jq -n \
--arg scheme " $scheme " \
--arg hostname " $hostname " \
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
--argjson port " $( echo " $port " | sed 's/[^0-9]//g' || echo "80" ) " \
2026-02-12 15:46:57 -08:00
--argjson websocket " $websocket " \
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
--argjson block_exploits " $be_json " \
2026-03-27 00:30:28 -07:00
--arg adv " $adv_line " \
2026-02-12 15:46:57 -08:00
' {
forward_scheme: $scheme ,
forward_host: $hostname ,
forward_port: $port ,
allow_websocket_upgrade: $websocket ,
block_exploits: $block_exploits
2026-03-27 00:30:28 -07:00
} + ( if $adv != "" then { advanced_config: $adv } else { } end) ' 2>/dev/null || echo "" )
2026-02-12 15:46:57 -08:00
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
UPDATE_RESPONSE = $( curl_npm -X PUT " $NPM_URL /api/nginx/proxy-hosts/ $HOST_ID " \
2026-02-12 15:46:57 -08:00
-H " Authorization: Bearer $TOKEN " \
-H "Content-Type: application/json" \
-d " $UPDATE_PAYLOAD " )
UPDATE_ID = $( echo " $UPDATE_RESPONSE " | jq -r '.id // empty' 2>/dev/null || echo "" )
if [ -n " $UPDATE_ID " ] && [ " $UPDATE_ID " != "null" ] ; then
2026-03-27 00:30:28 -07:00
if [ -n " $canonical_https " ] ; then
echo " ✅ Updated: $scheme :// $hostname : $port (WebSocket: $websocket ) + 301 → ${ canonical_https } \$request_uri "
else
echo " ✅ Updated: $scheme :// $hostname : $port (WebSocket: $websocket ) "
fi
2026-02-12 15:46:57 -08:00
return 0
else
2026-03-27 00:30:28 -07:00
ERROR = $( echo " $UPDATE_RESPONSE " | jq -r '.error.message // .message // .error // empty' 2>/dev/null || echo "" )
[ -z " $ERROR " ] && ERROR = $( echo " $UPDATE_RESPONSE " | head -c 400 | tr -d '\r\n' )
[ -z " $ERROR " ] && ERROR = "(empty API response — timeout or connection error; try NPM_CURL_MAX_TIME=300)"
2026-02-12 15:46:57 -08:00
echo " ❌ Failed: $ERROR "
return 1
fi
}
# Update all domains
updated_count = 0
failed_count = 0
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
# Blockscout / SolaceScanScout (VMID 5000) - Port 80 (nginx serves web UI, proxies /api/* to 4000 internally)
2026-02-12 15:46:57 -08:00
update_proxy_host "explorer.d-bis.org" " http:// ${ IP_BLOCKSCOUT } :80 " false && updated_count = $(( updated_count + 1 )) || failed_count = $(( failed_count + 1 ))
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
update_proxy_host "blockscout.defi-oracle.io" " http:// ${ IP_BLOCKSCOUT } :80 " false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "blockscout.defi-oracle.io" " ${ IP_BLOCKSCOUT } " 80 false false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
# docs.d-bis.org — same backend as explorer; nginx on VMID 5000 must serve /transaction-explanation/ (see deploy README)
update_proxy_host "docs.d-bis.org" " http:// ${ IP_BLOCKSCOUT } :80 " false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "docs.d-bis.org" " ${ IP_BLOCKSCOUT } " 80 false false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
# RPC hosts: block_exploits must be false so POST to / works (JSON-RPC). Add if missing to avoid 405.
update_proxy_host "rpc-http-pub.d-bis.org" " http:// ${ RPC_PUBLIC_1 } :8545 " true false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "rpc-http-pub.d-bis.org" " ${ RPC_PUBLIC_1 } " 8545 true false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "rpc-ws-pub.d-bis.org" " http:// ${ RPC_PUBLIC_1 } :8546 " true false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "rpc-ws-pub.d-bis.org" " ${ RPC_PUBLIC_1 } " 8546 true false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "rpc-http-prv.d-bis.org" " http:// ${ RPC_CORE_1 } :8545 " true false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "rpc-http-prv.d-bis.org" " ${ RPC_CORE_1 } " 8545 true false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "rpc-ws-prv.d-bis.org" " http:// ${ RPC_CORE_1 } :8546 " true false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "rpc-ws-prv.d-bis.org" " ${ RPC_CORE_1 } " 8546 true false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
# ThirdWeb Admin Core RPC — VMID ${RPC_THIRDWEB_ADMIN_CORE_VMID:-2103} @ ${RPC_THIRDWEB_ADMIN_CORE} (HTTPS + WSS via NPMplus; block_exploits off for JSON-RPC POST)
RPC_THIRDWEB_ADMIN_CORE = " ${ RPC_THIRDWEB_ADMIN_CORE :- 192 .168.11.217 } "
update_proxy_host "rpc.tw-core.d-bis.org" " http:// ${ RPC_THIRDWEB_ADMIN_CORE } :8545 " true false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "rpc.tw-core.d-bis.org" " ${ RPC_THIRDWEB_ADMIN_CORE } " 8545 true false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "wss.tw-core.d-bis.org" " http:// ${ RPC_THIRDWEB_ADMIN_CORE } :8546 " true false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "wss.tw-core.d-bis.org" " ${ RPC_THIRDWEB_ADMIN_CORE } " 8546 true false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
# Catch-all for foo.tw-core.d-bis.org → Besu HTTP JSON-RPC :8545 (exact rpc./wss. hosts above take precedence for nginx server_name)
update_proxy_host '*.tw-core.d-bis.org' " http:// ${ RPC_THIRDWEB_ADMIN_CORE } :8545 " true false && updated_count = $(( updated_count + 1 )) || { add_proxy_host '*.tw-core.d-bis.org' " ${ RPC_THIRDWEB_ADMIN_CORE } " 8545 true false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
2026-02-12 15:46:57 -08:00
# RPC Core-2 (Nathan) is on the THIRD NPMplus (192.168.11.169) — use add-rpc-core-2-npmplus-proxy.sh and update-npmplus-alltra-hybx-proxy-hosts.sh
2026-03-27 00:30:28 -07:00
# ThirdWeb / public-0138 edge (VMID 2400 nginx HTTPS) — default IP must match ALL_VMIDS_ENDPOINTS if env is unset
RPC_THIRDWEB_PRIMARY = " ${ RPC_THIRDWEB_PRIMARY :- 192 .168.11.240 } "
update_proxy_host "rpc.public-0138.defi-oracle.io" " https:// ${ RPC_THIRDWEB_PRIMARY } :443 " true false && updated_count = $(( updated_count + 1 )) || { sleep 2; echo " ↪ Retry rpc.public-0138.defi-oracle.io after transient NPM/API error..." ; update_proxy_host "rpc.public-0138.defi-oracle.io" " https:// ${ RPC_THIRDWEB_PRIMARY } :443 " true false && updated_count = $(( updated_count + 1 )) || failed_count = $(( failed_count + 1 )) ; }
2026-02-12 15:46:57 -08:00
# rpc.defi-oracle.io / wss.defi-oracle.io → same backend as rpc-http-pub / rpc-ws-pub (VMID 2201)
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
update_proxy_host "rpc.defi-oracle.io" " http:// ${ RPC_PUBLIC_1 } :8545 " true false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "rpc.defi-oracle.io" " ${ RPC_PUBLIC_1 } " 8545 true false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "wss.defi-oracle.io" " http:// ${ RPC_PUBLIC_1 } :8546 " true false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "wss.defi-oracle.io" " ${ RPC_PUBLIC_1 } " 8546 true false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
# rpc.d-bis.org / rpc2.d-bis.org and WS variants → VMID 2201 (besu-rpc-public-1); add if missing to fix 405
update_proxy_host "rpc.d-bis.org" " http:// ${ RPC_PUBLIC_1 } :8545 " true false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "rpc.d-bis.org" " ${ RPC_PUBLIC_1 } " 8545 true false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "rpc2.d-bis.org" " http:// ${ RPC_PUBLIC_1 } :8545 " true false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "rpc2.d-bis.org" " ${ RPC_PUBLIC_1 } " 8545 true false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "ws.rpc.d-bis.org" " http:// ${ RPC_PUBLIC_1 } :8546 " true false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "ws.rpc.d-bis.org" " ${ RPC_PUBLIC_1 } " 8546 true false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "ws.rpc2.d-bis.org" " http:// ${ RPC_PUBLIC_1 } :8546 " true false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "ws.rpc2.d-bis.org" " ${ RPC_PUBLIC_1 } " 8546 true false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
2026-02-21 15:46:06 -08:00
# Fireblocks-dedicated RPC (VMID 2301)
update_proxy_host "rpc-fireblocks.d-bis.org" " http:// ${ RPC_FIREBLOCKS_1 :- ${ RPC_PRIVATE_1 } } :8545 " true false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "rpc-fireblocks.d-bis.org" " ${ RPC_FIREBLOCKS_1 :- ${ RPC_PRIVATE_1 } } " 8545 true false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "ws.rpc-fireblocks.d-bis.org" " http:// ${ RPC_FIREBLOCKS_1 :- ${ RPC_PRIVATE_1 } } :8546 " true false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "ws.rpc-fireblocks.d-bis.org" " ${ RPC_FIREBLOCKS_1 :- ${ RPC_PRIVATE_1 } } " 8546 true false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
2026-02-12 15:46:57 -08:00
update_proxy_host "dbis-admin.d-bis.org" " http:// ${ IP_DBIS_FRONTEND :- 192 .168.11.130 } :80 " false && updated_count = $(( updated_count + 1 )) || failed_count = $(( failed_count + 1 ))
update_proxy_host "dbis-api.d-bis.org" " http:// ${ IP_DBIS_API :- 192 .168.11.155 } :3000 " false && updated_count = $(( updated_count + 1 )) || failed_count = $(( failed_count + 1 ))
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
update_proxy_host "dbis-api-2.d-bis.org" " http:// ${ IP_DBIS_API_2 :- 192 .168.11.156 } :3000 " false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "dbis-api-2.d-bis.org" " ${ IP_DBIS_API_2 :- 192 .168.11.156 } " 3000 false true && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "secure.d-bis.org" " http:// ${ IP_DBIS_FRONTEND :- 192 .168.11.130 } :80 " false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "secure.d-bis.org" " ${ IP_DBIS_FRONTEND :- 192 .168.11.130 } " 80 false true && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
# DApp (VMID 5801) — frontend-dapp for Chain 138 bridge
update_proxy_host "dapp.d-bis.org" " http:// ${ IP_DAPP_LXC :- 192 .168.11.58 } :80 " false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "dapp.d-bis.org" " ${ IP_DAPP_LXC :- 192 .168.11.58 } " 80 false false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
2026-02-12 15:46:57 -08:00
# MIM4U - VMID 7810 (mim-web-1) @ ${IP_MIM_WEB:-192.168.11.37} - Web Frontend serves main site and proxies /api/* to 7811
chore: BSC relay fund script, CCIP RTT report, NPM proxy fixes, submodule
- Add scripts/bridge/fund-bsc-relay-bridge.sh (mirror mainnet helper)
- Add reports/ccip-rtt-138-bsc-source-execution-2026-03-24.json (5/5 baseline)
- update-npmplus-proxy-hosts-api: case-insensitive host id, refresh on miss,
recover duplicate POST via PUT, add-if-missing for dbis-api-2, secure, mim4u*
- smom-dbis-138: relay log chunking, START_BLOCK parsing, README, .env.bsc.example
Made-with: Cursor
2026-03-24 16:18:29 -07:00
update_proxy_host "mim4u.org" " http:// ${ IP_MIM_WEB :- 192 .168.11.37 } :80 " false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "mim4u.org" " ${ IP_MIM_WEB :- 192 .168.11.37 } " 80 false true && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "www.mim4u.org" " http:// ${ IP_MIM_WEB :- 192 .168.11.37 } :80 " false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "www.mim4u.org" " ${ IP_MIM_WEB :- 192 .168.11.37 } " 80 false true && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "secure.mim4u.org" " http:// ${ IP_MIM_WEB :- 192 .168.11.37 } :80 " false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "secure.mim4u.org" " ${ IP_MIM_WEB :- 192 .168.11.37 } " 80 false true && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "training.mim4u.org" " http:// ${ IP_MIM_WEB :- 192 .168.11.37 } :80 " false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "training.mim4u.org" " ${ IP_MIM_WEB :- 192 .168.11.37 } " 80 false true && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
# Gov Portals xom-dev (VMID 7804) — public https:// at NPM (LE); upstream HTTP
IP_GOV_PORTALS_DEV = " ${ IP_GOV_PORTALS_DEV :- 192 .168.11.54 } "
update_proxy_host "dbis.xom-dev.phoenix.sankofa.nexus" " http:// ${ IP_GOV_PORTALS_DEV } :3001 " false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "dbis.xom-dev.phoenix.sankofa.nexus" " ${ IP_GOV_PORTALS_DEV } " 3001 false false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "iccc.xom-dev.phoenix.sankofa.nexus" " http:// ${ IP_GOV_PORTALS_DEV } :3002 " false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "iccc.xom-dev.phoenix.sankofa.nexus" " ${ IP_GOV_PORTALS_DEV } " 3002 false false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "omnl.xom-dev.phoenix.sankofa.nexus" " http:// ${ IP_GOV_PORTALS_DEV } :3003 " false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "omnl.xom-dev.phoenix.sankofa.nexus" " ${ IP_GOV_PORTALS_DEV } " 3003 false false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "xom.xom-dev.phoenix.sankofa.nexus" " http:// ${ IP_GOV_PORTALS_DEV } :3004 " false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "xom.xom-dev.phoenix.sankofa.nexus" " ${ IP_GOV_PORTALS_DEV } " 3004 false false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
2026-03-27 00:30:28 -07:00
# Sankofa portal (Next.js CT 7801) and Phoenix API (Fastify CT 7800) — not Blockscout / SolaceScanScout (that is explorer.d-bis.org / IP_BLOCKSCOUT:80)
# Public URL policy: https://sankofa.nexus = sovereign technology utility (portal); https://phoenix.sankofa.nexus = Phoenix division (API host; marketing site may share hostname later).
# www.sankofa.nexus → 301 https://sankofa.nexus$request_uri; www.phoenix → phoenix; www.the-order → the-order (NPM advanced_config).
IP_SANKOFA_PORTAL = " ${ IP_SANKOFA_PORTAL :- ${ IP_SERVICE_51 :- 192 .168.11.51 } } "
IP_SANKOFA_PHOENIX_API = " ${ IP_SANKOFA_PHOENIX_API :- ${ IP_SERVICE_50 :- 192 .168.11.50 } } "
SANKOFA_PORTAL_PORT = " ${ SANKOFA_PORTAL_PORT :- 3000 } "
SANKOFA_PHOENIX_API_PORT = " ${ SANKOFA_PHOENIX_API_PORT :- 4000 } "
update_proxy_host "sankofa.nexus" " http:// ${ IP_SANKOFA_PORTAL } : ${ SANKOFA_PORTAL_PORT } " false false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "sankofa.nexus" " ${ IP_SANKOFA_PORTAL } " " ${ SANKOFA_PORTAL_PORT } " false false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "www.sankofa.nexus" " http:// ${ IP_SANKOFA_PORTAL } : ${ SANKOFA_PORTAL_PORT } " false false "https://sankofa.nexus" && updated_count = $(( updated_count + 1 )) || { add_proxy_host "www.sankofa.nexus" " ${ IP_SANKOFA_PORTAL } " " ${ SANKOFA_PORTAL_PORT } " false false "https://sankofa.nexus" && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "phoenix.sankofa.nexus" " http:// ${ IP_SANKOFA_PHOENIX_API } : ${ SANKOFA_PHOENIX_API_PORT } " false false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "phoenix.sankofa.nexus" " ${ IP_SANKOFA_PHOENIX_API } " " ${ SANKOFA_PHOENIX_API_PORT } " false false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
update_proxy_host "www.phoenix.sankofa.nexus" " http:// ${ IP_SANKOFA_PHOENIX_API } : ${ SANKOFA_PHOENIX_API_PORT } " false false "https://phoenix.sankofa.nexus" && updated_count = $(( updated_count + 1 )) || { add_proxy_host "www.phoenix.sankofa.nexus" " ${ IP_SANKOFA_PHOENIX_API } " " ${ SANKOFA_PHOENIX_API_PORT } " false false "https://phoenix.sankofa.nexus" && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
# Keycloak (CT 7802) — portal SSO; NPM must forward X-Forwarded-* (Keycloak KC_PROXY_HEADERS=xforwarded on upstream)
IP_KEYCLOAK = " ${ IP_KEYCLOAK :- 192 .168.11.52 } "
update_proxy_host "keycloak.sankofa.nexus" " http:// ${ IP_KEYCLOAK } :8080 " false false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "keycloak.sankofa.nexus" " ${ IP_KEYCLOAK } " 8080 false false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
# the-order.sankofa.nexus — public hostname for the Sovereign Military Order of Malta (OSJ) management portal (secure auth).
# Application source (operator workstation): repo the_order at ~/projects/the_order (e.g. /home/intlc/projects/the_order).
2026-03-27 14:05:37 -07:00
# Default upstream: VMID 10210 order-haproxy @ IP_ORDER_HAPROXY:80 (provision: scripts/deployment/provision-order-haproxy-10210.sh).
# If 10210 is down: THE_ORDER_UPSTREAM_IP=${IP_SANKOFA_PORTAL} THE_ORDER_UPSTREAM_PORT=${SANKOFA_PORTAL_PORT} (direct portal 7801).
2026-03-27 00:30:28 -07:00
# www.the-order.sankofa.nexus → 301 https://the-order.sankofa.nexus$request_uri (same pattern as www.sankofa / www.phoenix).
IP_ORDER_HAPROXY = " ${ IP_ORDER_HAPROXY :- 192 .168.11.39 } "
2026-03-27 14:05:37 -07:00
THE_ORDER_UPSTREAM_IP = " ${ THE_ORDER_UPSTREAM_IP :- ${ IP_ORDER_HAPROXY } } "
THE_ORDER_UPSTREAM_PORT = " ${ THE_ORDER_UPSTREAM_PORT :- 80 } "
2026-03-27 11:27:09 -07:00
# block_exploits false — same policy as sankofa.nexus portal (Next/API-friendly; avoid 405 on some POST paths)
update_proxy_host "the-order.sankofa.nexus" " http:// ${ THE_ORDER_UPSTREAM_IP } : ${ THE_ORDER_UPSTREAM_PORT } " false false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "the-order.sankofa.nexus" " ${ THE_ORDER_UPSTREAM_IP } " " ${ THE_ORDER_UPSTREAM_PORT } " false false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
2026-03-27 00:30:28 -07:00
update_proxy_host "www.the-order.sankofa.nexus" " http:// ${ THE_ORDER_UPSTREAM_IP } : ${ THE_ORDER_UPSTREAM_PORT } " false false "https://the-order.sankofa.nexus" && updated_count = $(( updated_count + 1 )) || { add_proxy_host "www.the-order.sankofa.nexus" " ${ THE_ORDER_UPSTREAM_IP } " " ${ THE_ORDER_UPSTREAM_PORT } " false false "https://the-order.sankofa.nexus" && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
# Sankofa Studio (FusionAI) — VMID 7805; UI at /studio/ on same origin (port 8000). Prefer IP_SANKOFA_STUDIO from ip-addresses.conf / .env
IP_SANKOFA_STUDIO = " ${ IP_SANKOFA_STUDIO :- 192 .168.11.72 } "
SANKOFA_STUDIO_PORT = " ${ SANKOFA_STUDIO_PORT :- 8000 } "
2026-03-27 12:29:40 -07:00
# block_exploits false — studio UI/API may POST; align with portal policy (avoid spurious 405 from NPM WAF)
update_proxy_host "studio.sankofa.nexus" " http:// ${ IP_SANKOFA_STUDIO } : ${ SANKOFA_STUDIO_PORT } " false false && updated_count = $(( updated_count + 1 )) || { add_proxy_host "studio.sankofa.nexus" " ${ IP_SANKOFA_STUDIO } " " ${ SANKOFA_STUDIO_PORT } " false false && updated_count = $(( updated_count + 1 )) ; } || failed_count = $(( failed_count + 1 ))
2026-02-12 15:46:57 -08:00
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📊 Summary"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " ✅ Updated: $updated_count "
echo " ❌ Failed: $failed_count "
echo ""