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:
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