Skip to content

feat: add redundant worker deployments on Deno Deploy and Vercel#354

Open
AugustoL wants to merge 9 commits intoopenscan-explorer:devfrom
AugustoL:feat/worker-multi-platform-deploy
Open

feat: add redundant worker deployments on Deno Deploy and Vercel#354
AugustoL wants to merge 9 commits intoopenscan-explorer:devfrom
AugustoL:feat/worker-multi-platform-deploy

Conversation

@AugustoL
Copy link
Copy Markdown
Collaborator

@AugustoL AugustoL commented Apr 1, 2026

Description

Add support for deploying the OpenScan worker proxy on Vercel Edge Functions alongside the existing Cloudflare Workers deployment. A Deno Deploy entry point is also included for future use. The frontend automatically fails over between platforms.

Related Issue

Closes #339

Type of Change

  • Bug fix
  • New feature
  • Documentation update
  • Refactoring
  • Performance improvement
  • Other (please describe):

Changes Made

Deno Deploy entry point (ready for future activation):

  • worker/src/entry-deno.ts: Sources env vars from Deno.env and passes them to the shared Hono app via app.fetch(request, env)
  • worker/deno.json: Config with sloppy-imports for Node-style resolution and npm import maps for hono

Vercel Edge Functions (active failover):

  • worker/api/index.ts: Sources env vars from process.env and passes them to the shared Hono app
  • worker/vercel.json: Catch-all rewrite to route all paths to the edge function handler
  • Deployed and verified at https://openscan-worker-proxy.vercel.app

Frontend failover:

  • src/config/workerConfig.ts: Exports WORKER_URLS array (Cloudflare → Vercel) and fetchWithWorkerFailover() that tries each URL in order, falling through on network errors, 429, 502, and 503 responses
  • Updated contractLookup.ts, useEtherscan.ts, AIService.ts to use fetchWithWorkerFailover for all direct worker proxy calls
  • Updated isWorkerProxyUrl to check against all worker URLs

Documentation:

  • worker/README.md: Architecture overview, routes table, env vars, and step-by-step deployment guides for Cloudflare, Deno Deploy, and Vercel

Architecture: All platforms share the exact same Hono app (worker/src/index.ts). Each entry point just bridges platform-specific env var access into Hono's app.fetch(request, env) — zero code duplication.

Verified Endpoints (Vercel)

  • GET /health{"status":"ok"}
  • POST /evm/alchemy/eip155:1 — Returns block number (eth_blockNumber)
  • POST /etherscan/verify — Returns verified contract source code and ABI

Checklist

  • I have run npm run format:fix and npm run lint:fix
  • I have run npm run typecheck with no errors
  • I have run tests with npm run test:run
  • I have tested my changes locally
  • I have updated documentation if needed
  • My code follows the project's architecture patterns

Additional Notes

  • Deno Deploy entry point is ready but not in the active failover chain yet (auth/token setup pending). Can be activated by deploying and adding the URL to WORKER_URLS.
  • The RPC endpoints in rpcStorage.ts still use only the primary Cloudflare URL, which is fine since the RPC client already has multi-provider fallback (Alchemy, Infura, dRPC, Ankr). The critical single-provider paths (AI and Etherscan) are covered by the failover.

AugustoL added 3 commits April 1, 2026 09:52
Add entry-deno.ts that sources env vars from Deno.env and passes them
to the shared Hono app via app.fetch(request, env). All existing route
handlers and middleware work unchanged.

Add deno.json with sloppy-imports for Node-style resolution and npm
import maps for the hono dependency.

Ref openscan-explorer#339
Add api/index.ts that sources env vars from process.env and passes them
to the shared Hono app via app.fetch(request, env). All existing route
handlers and middleware work unchanged.

Add vercel.json with a catch-all rewrite to route all paths to the
edge function handler.

Ref openscan-explorer#339
Add fetchWithWorkerFailover() that tries each worker URL in order
(Cloudflare → Deno Deploy → Vercel) and falls through on network
errors, 429, 502, and 503 responses.

Update all direct worker proxy consumers (contractLookup, useEtherscan,
AIService) to use the failover function. Update isWorkerProxyUrl to
check against all worker URLs.

Closes openscan-explorer#339
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 1, 2026

🚀 Preview: https://pr-354--openscan.netlify.app
📝 Commit: 9104be500254528ad1626b00caaf29c572186d9c

AugustoL added 4 commits April 1, 2026 10:12
The worker tsconfig only includes @cloudflare/workers-types, so
process.env is unknown. Declare it locally instead of adding @types/node.
Document the worker proxy architecture, routes, environment variables,
and step-by-step deployment instructions for Cloudflare Workers,
Deno Deploy, and Vercel Edge Functions.
Deno Deploy entry point and config remain available for future use
but are not included in the active failover chain until deployment
is configured. Failover is now Cloudflare → Vercel.
@AugustoL AugustoL requested review from MatiasOS April 1, 2026 22:06
@AugustoL AugustoL self-assigned this Apr 1, 2026
Copy link
Copy Markdown
Member

@MatiasOS MatiasOS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to add how the workers are used within the app

Merge dev into feat/worker-multi-platform-deploy and resolve the
workerConfig.ts conflict. The primary worker URL now reads from
import.meta.env.OPENSCAN_WORKER_URL (matching the REACT_APP_ → Vite
env migration already on dev) while keeping the failover array and
fetchWithWorkerFailover logic from this branch.
- Add 15s AbortController timeout per request so a hanging worker
  doesn't block the entire failover chain
- On 429 (rate limited): wait Retry-After header (capped at 10s,
  default 3s) and retry once on the same worker before failing over
- 502/503 still trigger immediate failover to the next worker
- Extracted fetchWithTimeout helper for clean abort handling
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants