← Back to Blog

Smart Gates Phased Rollout: From Vision to Wallet-Authenticated Routing

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")

2. Authorized Routing ("Traversable Only")

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:

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:

Theme Consistency Fixes:

Acceptance Criteria:

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:

Backend Integration

Updated Node.js snapshot exporter (tools/snapshot-exporter/exporter.js):

  1. Query PostgreSQL indexer for Smart Gate events (deployments, ACL changes, ownership transfers)
  2. Join with system IDs and ownership tables
  3. Classify gates as public/private based on applied system address
  4. Publish to Cloudflare KV namespace EF_SNAPSHOTS, key smart_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:

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:

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

  1. Fetch /api/authorized-gates (requires authentication)
  2. Filter Smart Gate overlay lines to authorized edges only
  3. 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)

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

Pathfinding prioritizes: Stargates > Smart Gates > Ship Jumps

Acceptance Criteria

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:

Worker Diagnostics:

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:

Viewing Modes:

Routing:

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:

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:

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:

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:

  1. Intelligence value: Show all gate deployments for tactical awareness
  2. Practical navigation: Route only through gates the user can actually traverse
  3. Performance: Maintain < 1s route calculations despite slow blockchain RPC calls

Our six-phase rollout achieved all three by:

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 gates blockchain routing siwe authentication wallet connect metamask integration phased rollout preview deployments access control lists