From eac2671529553e193dcb8ae6ed9966695607b0b6 Mon Sep 17 00:00:00 2001 From: consultoria-as Date: Thu, 26 Feb 2026 01:34:12 +0000 Subject: [PATCH] feat: add HTTPS RPC proxy for MetaMask mobile support Nginx SSL reverse proxy (port 8443) in front of Geth using Let's Encrypt cert via Cloudflare DNS challenge. MetaMask mobile requires HTTPS for custom RPC URLs. Also adds AFC token icon served from bridge API static files. Co-Authored-By: Claude Opus 4.6 --- docker/docker-compose.dev.yml | 14 +++ docker/nginx/rpc-ssl.conf | 32 +++++ services/afc-bridge/Dockerfile | 1 + services/afc-bridge/public/afc-icon.svg | 158 ++++++++++++++++++++++++ services/afc-bridge/src/index.js | 4 + 5 files changed, 209 insertions(+) create mode 100644 docker/nginx/rpc-ssl.conf create mode 100644 services/afc-bridge/public/afc-icon.svg diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index 11f59f5..3e34459 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -134,6 +134,17 @@ services: limits: memory: 1G + rpc-ssl: + image: nginx:alpine + restart: unless-stopped + depends_on: + - geth + volumes: + - ./nginx/rpc-ssl.conf:/etc/nginx/nginx.conf:ro + - certbot_etc:/etc/letsencrypt:ro + ports: + - "8443:8443" + afc-bridge: build: context: ../services/afc-bridge @@ -160,3 +171,6 @@ volumes: minecraft_ftb_data: geth_data: afc_bridge_data: + certbot_etc: + external: true + name: docker_certbot_etc diff --git a/docker/nginx/rpc-ssl.conf b/docker/nginx/rpc-ssl.conf new file mode 100644 index 0000000..e7b85be --- /dev/null +++ b/docker/nginx/rpc-ssl.conf @@ -0,0 +1,32 @@ +events { + worker_connections 256; +} + +http { + server { + listen 8443 ssl; + server_name play.consultoria-as.com; + + ssl_certificate /etc/letsencrypt/live/play.consultoria-as.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/play.consultoria-as.com/privkey.pem; + ssl_protocols TLSv1.2 TLSv1.3; + + # Geth JSON-RPC proxy + location / { + proxy_pass http://geth:8545; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Content-Type application/json; + + # CORS for MetaMask + add_header Access-Control-Allow-Origin * always; + add_header Access-Control-Allow-Methods "POST, GET, OPTIONS" always; + add_header Access-Control-Allow-Headers "Content-Type" always; + + if ($request_method = OPTIONS) { + return 204; + } + } + } +} diff --git a/services/afc-bridge/Dockerfile b/services/afc-bridge/Dockerfile index 4018b79..b9d6d6e 100644 --- a/services/afc-bridge/Dockerfile +++ b/services/afc-bridge/Dockerfile @@ -6,6 +6,7 @@ COPY package.json package-lock.json* ./ RUN npm install --production COPY contracts/ ./contracts/ +COPY public/ ./public/ COPY src/ ./src/ EXPOSE 3001 diff --git a/services/afc-bridge/public/afc-icon.svg b/services/afc-bridge/public/afc-icon.svg new file mode 100644 index 0000000..5547ca5 --- /dev/null +++ b/services/afc-bridge/public/afc-icon.svg @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AFC + + + AFTERCOIN + + + + + + + + + + diff --git a/services/afc-bridge/src/index.js b/services/afc-bridge/src/index.js index a0bfd00..faa74a9 100644 --- a/services/afc-bridge/src/index.js +++ b/services/afc-bridge/src/index.js @@ -1,3 +1,4 @@ +const path = require("path"); const express = require("express"); const config = require("./config"); const db = require("./db"); @@ -11,6 +12,9 @@ const walletRouter = require("./routes/wallet"); const app = express(); +// Serve static files (token icon, etc.) +app.use(express.static(path.join(__dirname, "..", "public"))); + // Parse JSON request bodies app.use(express.json());