chore: metamask networks, explorer SPA, nginx scripts; ignore Python cache
Some checks failed
Deploy Explorer Live / deploy (push) Failing after 12s
Some checks failed
Deploy Explorer Live / deploy (push) Failing after 12s
- Dual-chain / GRU deployment JSON sync - Frontend explorer SPA + MetaMask components - Scripts: nginx fixes, link deploy, local SPA serve helper - Token icon chain-138.png; .gitignore __pycache__ Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
# Add nginx proxy for token-aggregation service at /api/v1/ on explorer.d-bis.org (VMID 5000).
|
||||
# Run on the explorer VM. Requires token-aggregation running (default port 3000).
|
||||
# Run on the explorer VM. Requires token-aggregation listening on TOKEN_AGG_PORT (VMID 5000
|
||||
# production default 3001 per fix-nginx-conflicts-vmid5000.sh; local dev often PORT=3000).
|
||||
# Chain 138 Snap companion site (GATSBY_SNAP_API_BASE_URL=https://explorer.d-bis.org) then gets
|
||||
# market data, swap quotes, and bridge routes from this API.
|
||||
# Usage: [TOKEN_AGG_PORT=3000] [CONFIG_FILE=/etc/nginx/sites-available/blockscout] bash apply-nginx-token-aggregation-proxy.sh
|
||||
# Usage: [TOKEN_AGG_PORT=3001] [CONFIG_FILE=/etc/nginx/sites-available/blockscout] bash apply-nginx-token-aggregation-proxy.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TOKEN_AGG_PORT="${TOKEN_AGG_PORT:-3000}"
|
||||
TOKEN_AGG_PORT="${TOKEN_AGG_PORT:-3001}"
|
||||
CONFIG_FILE="${CONFIG_FILE:-/etc/nginx/sites-available/blockscout}"
|
||||
|
||||
if [ ! -f "$CONFIG_FILE" ]; then
|
||||
|
||||
@@ -128,5 +128,5 @@ echo ""
|
||||
echo "If deployment still pending:"
|
||||
echo " 1. Wait additional time (5-10 minutes)"
|
||||
echo " 2. Use Remix IDE (instructions above)"
|
||||
echo " 3. Check block explorer: https://explorer.d-bis.org/address/$ACCOUNT"
|
||||
echo " 3. Check block explorer: https://explorer.d-bis.org/addresses/$ACCOUNT"
|
||||
echo ""
|
||||
|
||||
@@ -154,7 +154,7 @@ if [ "$CONFIRMED" != "true" ]; then
|
||||
echo "2. Transaction may have failed"
|
||||
echo "3. RPC node may be out of sync"
|
||||
echo ""
|
||||
echo "Check block explorer: https://explorer.d-bis.org/address/$ACCOUNT"
|
||||
echo "Check block explorer: https://explorer.d-bis.org/addresses/$ACCOUNT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -255,7 +255,7 @@ if [ -n "$DEPLOYED_ADDRESS" ] && [ "$DEPLOYED_ADDRESS" != "0x0000000000000000000
|
||||
log_info "Next steps:"
|
||||
log_info "1. Update config/address-inventory.json with LINK token address"
|
||||
log_info "2. Fund bridge contracts: ./scripts/fund-bridge-contracts.sh 10"
|
||||
log_info "3. Verify contract on explorer: https://explorer.d-bis.org/address/$DEPLOYED_ADDRESS"
|
||||
log_info "3. Verify contract on explorer: https://explorer.d-bis.org/addresses/$DEPLOYED_ADDRESS"
|
||||
|
||||
exit 0
|
||||
else
|
||||
|
||||
@@ -66,6 +66,36 @@ server {
|
||||
}
|
||||
location = /snap { rewrite ^ /snap/ last; }
|
||||
|
||||
# Token-aggregation + static config on HTTP (plain :80) so /api/v1/* never hits Blockscout by mistake
|
||||
location /api/v1/ {
|
||||
proxy_pass http://127.0.0.1:3001/api/v1/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 60s;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
}
|
||||
location = /api/config/token-list {
|
||||
default_type application/json;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Cache-Control "public, max-age=3600";
|
||||
alias /var/www/html/config/DUAL_CHAIN_TOKEN_LIST.tokenlist.json;
|
||||
}
|
||||
location = /api/config/networks {
|
||||
default_type application/json;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Cache-Control "public, max-age=3600";
|
||||
alias /var/www/html/config/DUAL_CHAIN_NETWORKS.json;
|
||||
}
|
||||
location = /api/config/capabilities {
|
||||
default_type application/json;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Cache-Control "public, max-age=3600";
|
||||
alias /var/www/html/config/CHAIN138_RPC_CAPABILITIES.json;
|
||||
}
|
||||
|
||||
location / {
|
||||
if ($redirect_to_https = 1) { return 301 https://$host$request_uri; }
|
||||
proxy_pass http://127.0.0.1:4000;
|
||||
@@ -112,24 +142,7 @@ server {
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate";
|
||||
}
|
||||
|
||||
# Blockscout Explorer endpoint - proxy to Blockscout
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:4000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Connection "";
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_connect_timeout 75s;
|
||||
}
|
||||
|
||||
# Token-aggregation API at /api/v1/ (Chain 138 Snap: market data, swap quote, bridge). Service runs on port 3001.
|
||||
# Token-aggregation API at /api/v1/ — define BEFORE /api/ and / so longest-prefix routing is explicit (Snap + dApps).
|
||||
location /api/v1/ {
|
||||
proxy_pass http://127.0.0.1:3001/api/v1/;
|
||||
proxy_http_version 1.1;
|
||||
@@ -162,7 +175,7 @@ server {
|
||||
alias /var/www/html/config/CHAIN138_RPC_CAPABILITIES.json;
|
||||
}
|
||||
|
||||
# API endpoint (for Blockscout API)
|
||||
# Blockscout API (excludes /api/v1/ which is handled above)
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:4000;
|
||||
proxy_http_version 1.1;
|
||||
@@ -184,6 +197,23 @@ server {
|
||||
proxy_set_header Host $host;
|
||||
add_header Content-Type application/json;
|
||||
}
|
||||
|
||||
# Blockscout Explorer UI (catch-all)
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:4000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Connection "";
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_connect_timeout 75s;
|
||||
}
|
||||
}
|
||||
|
||||
# WebSocket upgrade mapping
|
||||
|
||||
@@ -1,26 +1,16 @@
|
||||
#!/bin/bash
|
||||
# Simple local server for explorer (fallback option)
|
||||
# Usage: ./serve-explorer-local.sh [port]
|
||||
#!/usr/bin/env bash
|
||||
# Local static explorer with SPA path fallback (/institution, /compare, /addresses/… → index.html).
|
||||
# Usage: SERVE_BIND=0.0.0.0 ./scripts/serve-explorer-local.sh [port]
|
||||
# Requires: Python 3.7+
|
||||
|
||||
PORT=${1:-8080}
|
||||
FRONTEND_DIR="$(cd "$(dirname "$0")/../frontend/public" && pwd)"
|
||||
set -euo pipefail
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PORT="${1:-8080}"
|
||||
BIND="${SERVE_BIND:-127.0.0.1}"
|
||||
|
||||
if [ ! -f "$FRONTEND_DIR/index.html" ]; then
|
||||
echo "❌ Frontend not found at: $FRONTEND_DIR/index.html"
|
||||
exit 1
|
||||
if ! command -v python3 >/dev/null 2>&1; then
|
||||
echo "python3 required" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Serving explorer on http://localhost:$PORT"
|
||||
echo "Frontend: $FRONTEND_DIR"
|
||||
|
||||
cd "$FRONTEND_DIR"
|
||||
|
||||
# Try Python 3 first, then Python 2
|
||||
if command -v python3 >/dev/null 2>&1; then
|
||||
python3 -m http.server "$PORT"
|
||||
elif command -v python >/dev/null 2>&1; then
|
||||
python -m SimpleHTTPServer "$PORT"
|
||||
else
|
||||
echo "❌ Python not found. Install Python to use this script."
|
||||
exit 1
|
||||
fi
|
||||
exec python3 "$SCRIPT_DIR/serve_explorer_spa.py" "$PORT" --bind "$BIND"
|
||||
|
||||
56
scripts/serve_explorer_spa.py
Executable file
56
scripts/serve_explorer_spa.py
Executable file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Static explorer with SPA fallback: unknown paths serve index.html (client router).
|
||||
API paths (/api/, /explorer-api/) are not rewritten so missing backends still 404 clearly."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
|
||||
from urllib.parse import urlparse
|
||||
|
||||
|
||||
def main() -> int:
|
||||
p = argparse.ArgumentParser(description="Serve explorer-monorepo/frontend/public with SPA fallback.")
|
||||
p.add_argument("port", nargs="?", type=int, default=8080, help="Listen port (default 8080)")
|
||||
p.add_argument(
|
||||
"--bind",
|
||||
default="127.0.0.1",
|
||||
help="Bind address (default 127.0.0.1)",
|
||||
)
|
||||
args = p.parse_args()
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
root = os.path.normpath(os.path.join(script_dir, "..", "frontend", "public"))
|
||||
if not os.path.isfile(os.path.join(root, "index.html")):
|
||||
print(f"ERROR: index.html not found under {root}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
class Handler(SimpleHTTPRequestHandler):
|
||||
def __init__(self, *a, **kw):
|
||||
super().__init__(*a, directory=root, **kw)
|
||||
|
||||
def do_GET(self) -> None: # noqa: N802
|
||||
path = urlparse(self.path).path
|
||||
if path.startswith("/api/") or path.startswith("/explorer-api"):
|
||||
return super().do_GET()
|
||||
rel = path.lstrip("/")
|
||||
if rel.startswith(".."):
|
||||
self.send_error(403, "Forbidden")
|
||||
return
|
||||
fs = os.path.join(root, rel) if rel else root
|
||||
if os.path.isfile(fs):
|
||||
return super().do_GET()
|
||||
self.path = "/index.html"
|
||||
return super().do_GET()
|
||||
|
||||
httpd = ThreadingHTTPServer((args.bind, args.port), Handler)
|
||||
print(f"Serving SPA explorer: http://{args.bind}:{args.port}/ (root={root})", flush=True)
|
||||
try:
|
||||
httpd.serve_forever()
|
||||
except KeyboardInterrupt:
|
||||
print("\nStopped.", flush=True)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user