Smart Gates—player-created wormhole connections governed by blockchain access control lists—represent EVE Frontier's most innovative navigation feature. For EF-Map, integrating them meant solving a fascinating technical challenge: how do we visualize and route through on-chain authorization without compromising privacy, performance, or user experience?
This post documents our six-phase rollout strategy that took Smart Gates from basic overlay rendering to wallet-authenticated routing—all delivered through preview deployments with zero production downtime.
The Vision: Intelligence View + Authenticated Routing
Design Goals
We wanted to deliver two distinct user experiences:
1. Intelligence View ("All Gates")
- Show every Smart Gate deployment on the map (visual intelligence)
- Color-coded by ownership (tribe/owner/static palette)
- Available to all users without authentication
- Toggle visibility independently from Stargates
2. Authorized Routing ("Traversable Only")
- Filter to gates the connected user can actually traverse
- Requires wallet authentication (Sign-In with Ethereum)
- Routing algorithm respects authorized gate edges only
- Opt-in checkbox: "Use Smart Gates in routing"
This dual-mode approach balanced tactical intelligence (who controls what routes) with practical navigation (which shortcuts work for me).
Technical Constraints
Our platform stack imposed specific challenges:
- Cloudflare Pages + Workers: Serverless execution; no persistent database; D1 bindings disabled in production Pages environment
- Privacy-first: No PII in KV storage; aggregate-only analytics
- Performance: Blockchain RPC calls (200-500ms) unacceptable for real-time overlay/routing
- Preview-first deployments: Validate on branch URLs before touching production custom domains
Phase 0: Baseline Overlay Polish (UI Foundation)
Starting Point
Before authentication and routing, we needed rock-solid visual integration. Phase 0 focused purely on UI:
Smart Gates Panel Controls:
- Show/Hide toggle (independent from Stargates)
- Color mode selector: By Owner, By Tribe, Static Accent
- Viewing mode dropdown: "All Gates" (always available), "Traversable Only" (disabled until Phase 3)
Theme Consistency Fixes:
- Dark and orange theme gate line colors matched in-game UI
- Z-order adjustments prevented route lines from clipping behind Smart Gate overlays
- Shader blending ensured legibility when multiple overlays overlapped
Acceptance Criteria:
- Visually correct in both dark and orange themes
- No z-fighting or aliasing artifacts
- Route lines remain visible when Smart Gate overlay is active
This phase shipped to production on 2025-09-27 with zero backend changes—pure frontend polish.
Phase 1: Snapshot Schema with Directionality (Data Foundation)
Blockchain Data Modeling
Smart Gates aren't symmetric—they have directional traversal. A gate from System A → B doesn't automatically grant B → A access.
We designed a snapshot schema capturing:
{
"updatedAt": "2025-09-29T12:00:00Z",
"worldVersion": "v2.1",
"links": [
{
"gate_id": "0x1a2b3c...",
"fromSystemId": "30000142",
"toSystemId": "30000148",
"linked": true,
"online": true,
"traversalCost": 0,
"appliedSystemId": "0x0000...0000", // zero = public
"isPublic": true,
"owner": "0xABCD...",
"tribeId": "1000167"
}
]
}
Key fields:
- appliedSystemId: Smart contract address enforcing access control (zero address = unrestricted)
- isPublic: Derived flag (
appliedSystemId == 0x000...000) - traversalCost: Fuel/resource cost (0 for free gates; future expansion)
- Directionality:
fromSystemId → toSystemIdrepresents a single directed edge
Backend Integration
Updated Node.js snapshot exporter (tools/snapshot-exporter/exporter.js):
- Query PostgreSQL indexer for Smart Gate events (deployments, ACL changes, ownership transfers)
- Join with system IDs and ownership tables
- Classify gates as public/private based on applied system address
- Publish to Cloudflare KV namespace
EF_SNAPSHOTS, keysmart_gate_links_v1
Worker endpoint: GET /api/smart-gate-links serves snapshot with ETag + Cache-Control.
Production deployment: 2025-09-29
Phase 2: Sign-In with Ethereum (SIWE Authentication)
Wallet Connect Flow
Before we could filter to "Traversable Only" gates, users needed to prove ownership of a wallet address.
We implemented SIWE (EIP-4361 standard):
1. Nonce Generation
GET /api/auth/nonce
→ { nonce: "abc123", issuedAt: "2025-09-30T10:00:00Z", expiresInSec: 300 }
Server generates a cryptographically random nonce with HMAC signature (using AUTH_HMAC_SECRET) to prevent replay attacks.
2. Message Signing (Client-Side)
Browser detects EIP-1193 provider (MetaMask, EVE Vault) and constructs SIWE message:
ef-map.com wants you to sign in with your Ethereum account:
0x1234...5678
Sign in to EF-Map
URI: https://ef-map.com
Version: 1
Chain ID: 31415 // EVE Frontier chain
Nonce: abc123
Issued At: 2025-09-30T10:00:00Z
Expiration Time: 2025-09-30T10:05:00Z
User signs via wallet popup. Browser receives signature.
3. Signature Verification (Server-Side)
POST /api/auth/verify
{ message: "...", signature: "0x..." }
Server:
1. Parse SIWE message (validate domain, URI, version, chainId)
2. Verify nonce HMAC (prevent replay)
3. Check expiration window (≤5 minutes)
4. Recover signer address from signature (ecrecover)
5. Match recovered address to message address
On success:
→ Set HttpOnly cookie: ef_ses = { addr, iat, exp, nonce }
→ Return 200 { authenticated: true, address: "0x..." }
Security Properties:
- Cookie is HttpOnly, Secure, SameSite=Lax (XSS-resistant)
- Session TTL: 1-6 hours (configurable)
- No PII stored (only wallet address in cookie, never persisted to KV)
- Domain + URI binding enforced (prevents cross-site abuse)
4. Session Check
GET /api/auth/session
→ { authenticated: true, address: "0x1234...", expiresAt: "..." }
Client UI shows "Signed in as 0x1234..." badge. "Traversable Only" mode becomes enabled.
Production deployment: 2025-09-30 (preview first, then promoted)
Phase 3: Authorized Gates API + Overlay Filtering
Per-User Gate Access
Now authenticated users could request gates they can traverse:
GET /api/authorized-gates
(Requires ef_ses cookie)
Response:
{
"updatedAt": "2025-10-01T14:00:00Z",
"snapshotEtag": "v1-abc123",
"edges": [
{ "fromSystemId": "30000142", "toSystemId": "30000148", "gate_id": "0x..." },
{ "fromSystemId": "30000148", "toSystemId": "30000201", "gate_id": "0x..." }
]
}
Implementation Strategy (MVP: Public-Only)
Full per-wallet ACL checks require on-chain view calls against each gate's applied system contract:
canTraverse(gateId, fromSystemId, toSystemId, userAddress) → boolean
At 200-500ms per RPC call, checking hundreds of gates would be prohibitively slow.
MVP Approach: Filter to public gates only (using isPublic flag from snapshot). This provides immediate value:
- Users see only gates guaranteed traversable (no ACL restrictions)
- Zero RPC calls required
- Instant response (< 50ms)
Future Enhancement: Batch on-chain checks for non-public gates in viewport or routing frontier, with strict throttling and caching.
Client-Side Filtering
When user toggles to "Traversable Only":
- Fetch
/api/authorized-gates(requires authentication) - Filter Smart Gate overlay lines to authorized edges only
- Update legend counts ("Showing 23 / 96 gates")
Toggle back to "All Gates": restore full overlay (intelligence view).
Production deployment: 2025-10-01
Phase 4: Routing Integration (Opt-In)
Routing Panel Controls
Added checkbox: "Use Smart Gates" (default: off)
- When disabled: routing uses only Stargates + ship jumps (legacy behavior)
- When enabled: include authorized Smart Gate edges in pathfinding graph
Worker Algorithm Changes
Modified routing_worker.ts (Web Worker running A*/Dijkstra):
function buildRoutingGraph(systems, stargates, smartGates, useSmartGates) {
const graph = new Map();
// Always include Stargates
for (const gate of stargates) {
addEdge(graph, gate.from, gate.to, { type: 'stargate', cost: 0 });
}
// Conditionally include Smart Gates
if (useSmartGates) {
for (const gate of smartGates) {
// Enforce directionality
addEdge(graph, gate.fromSystemId, gate.toSystemId, {
type: 'smart_gate',
cost: gate.traversalCost,
gate_id: gate.gate_id
});
}
}
return graph;
}
Cache Invalidation: Spatial grid and neighbor caches keyed by (useSmartGates, maxJumpRange). Toggling Smart Gates triggers graph rebuild.
Cost Model
- Stargates: Cost = 0 (instant travel)
- Smart Gates: Cost =
traversalCost(currently 0 for free gates; future: fuel/resource costs) - Ship jumps: Cost = distance (light-years)
Pathfinding prioritizes: Stargates > Smart Gates > Ship Jumps
Acceptance Criteria
- When "Use Smart Gates" is off: identical routes to baseline (pre-Smart Gates implementation)
- When on: routes may include Smart Gate shortcuts (verified via route notes)
- Time to first route: unchanged within ±10% on medium routes (50-100 hops)
Production deployment: 2025-10-03
Phase 5 & 6: Visual Integration + Automation (Operational Maturity)
Phase 5: Visual Integration (Not Required)
Original plan included distinct styling for Smart Gate segments in route lines (e.g., dashed/gradient).
After baseline release, user feedback indicated current route styling was sufficient. Route notes already listed gate types ("via Smart Gate 0x1a2b3c...").
Decision: Mark phase as complete without additional styling work. No regressions; standard styling accepted.
Phase 6: Automation & Operations (Production Cron)
Snapshot Exporter Cron:
- Runs every 30 minutes (local scheduled task or CI cron)
- Queries Postgres for latest Smart Gate events (deployments, ACL changes)
- Generates
smart_gate_links_v1snapshot - Publishes to Cloudflare KV via Wrangler API
Worker Diagnostics:
GET /api/smart-gate-links: includesX-Gates-Sourceheader (KV vs fallback)GET /api/gate-access: exposes minimal ACL snapshot for debugging- ETag-based caching reduces redundant KV reads
Production deployment: 2025-10-02 (cron active)
Metrics & Observability
New Event Types (Added Phase 3-4)
We instrumented Smart Gates features via aggregate-only counters:
Authentication:
smart_gates_connect_click: User clicks "Connect Wallet"smart_gates_connected: Successful SIWE verificationsmart_gates_auth_fail: Signature verification failed
Viewing Modes:
smart_gates_traversable_mode: Sessions with "Traversable Only" enabledsmart_gates_mode_switch: Toggle between "All" and "Traversable"
Routing:
smart_gates_paths_used: Routes calculated with "Use Smart Gates" enabledsmart_gates_saved_hops: Sum of light-years saved via Smart Gate shortcuts
All events whitelisted in Worker EVENT_MAP; Stats page dashboard displays adoption trends.
Lessons from Phased Rollout
What Worked
1. Preview-first deployments eliminated risk
Every phase deployed to Cloudflare Pages preview branch first (e.g., https://feature-smart-gates.ef-map.pages.dev). We validated:
- Endpoint responses (auth, gates)
- UI behavior (overlay toggles, routing checkbox)
- Performance (time to first route, FPS)
Only after all gates passed did we promote to production via merge to main. Zero production incidents.
2. Authentication before routing prevented partial states
Original temptation: add routing integration first, defer auth to "later." But this would create confusing UX:
- Routing with Smart Gates enabled but no auth → uses ALL gates (incorrect for non-public gates)
- Users expect "Use Smart Gates" to respect their access, not global intelligence
By landing auth (Phase 2) before routing (Phase 4), we ensured routing always reflected user's actual traversal rights.
3. Public-only MVP delivered value immediately
Instead of waiting months for full per-wallet ACL checks (requires on-chain RPC batching infrastructure), we shipped public gates filtering first. This covered ~40% of deployed gates and provided:
- Immediate utility (users found free shortcuts)
- Proof of concept for routing integration
- Foundation for future non-public gate support
4. Metrics captured adoption without PII
Aggregate counters (smart_gates_connected, smart_gates_paths_used) showed feature adoption trends without storing wallet addresses or route details. Privacy-preserving by design.
What We'd Improve
Earlier RPC latency benchmarking: We should have profiled blockchain RPC call latency distribution (p50, p95, p99) earlier to better estimate feasibility of non-public ACL checks. This would have informed MVP scope more accurately.
Batch gate access validation: For routes with 5-10 candidate Smart Gates, we could batch-check traversal permissions in a single Worker request (parallel RPC calls via Promise.all). This remains a high-value enhancement for Phase 4.5.
UI tooltip clarity: "Traversable Only" label confused some users—they expected all gates they could traverse (including tribe/org-restricted). We should rename to "Public Gates Only" for MVP, then "Your Accessible Gates" when full ACL support ships.
Conclusion: Blockchain Integration Without Compromise
Integrating Smart Gates into EF-Map required balancing three competing priorities:
- Intelligence value: Show all gate deployments for tactical awareness
- Practical navigation: Route only through gates the user can actually traverse
- Performance: Maintain < 1s route calculations despite slow blockchain RPC calls
Our six-phase rollout achieved all three by:
- Separating concerns: Overlay (Phase 0-1) → Auth (Phase 2-3) → Routing (Phase 4)
- Preview-first deployments: Validate on branch URLs before production
- Public-only MVP: Ship immediate value while building toward full ACL support
- Aggregate metrics: Measure adoption without compromising privacy
The result: Players can now view all Smart Gates for intelligence (who controls which routes) and route through their accessible gates (practical shortcuts)—all without breaking existing features or exposing private data.
And when we're ready to add non-public gate support? The architecture is already in place. We'll just swap the isPublic filter for batched on-chain ACL checks, validate on preview, and ship.
That's the power of phased rollouts: deliver value incrementally while building the foundation for tomorrow's features.
Related Posts
- Smart Gate Authorization: Blockchain-Powered Access Control in EVE Frontier - Deep dive into the three-tier caching system for Smart Gates
- Building the Helper Bridge: Native Desktop Integration for EVE Frontier - The authentication infrastructure that enables wallet connect
- Requirements-Driven Development: Building EF-Map from Vision to Reality - The planning approach behind our phased strategy
- A* vs Dijkstra: Choosing the Right Pathfinding Algorithm - The routing algorithms that power Smart Gate pathfinding
- Privacy-First Analytics: Learning Without Tracking - How we measure Smart Gates adoption without PII