diff options
| author | Adam Soltys <[email protected]> | 2026-06-28 21:59:07 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-06-28 21:59:07 -0700 |
| commit | fcd971da0c110607ccdc7637667beb0fa79d42a7 (patch) | |
| tree | 4b81bb348c8d6ed25bec03f6e5adf10b68908226 /dev.js | |
| parent | 656726e17684071e929a2f0453cdd306c4d8dc12 (diff) | |
| download | coinosv3-fcd971da0c110607ccdc7637667beb0fa79d42a7.tar.gz coinosv3-fcd971da0c110607ccdc7637667beb0fa79d42a7.zip | |
Swaps(regtest dev): proxy boltz through the dev server to fix CORS 'failed to fetch'
The regtest boltz API (localhost:9001) sends no CORS headers, so the browser
blocked cross-origin fetches — creating a Lightning invoice failed with 'failed
to fetch', and the limits GET silently fell back to defaults (min showed 25k
instead of regtest's real 50k). bun E2E tests didn't hit this (no CORS enforced).
dev.js now proxies /boltz/* to localhost:9001 (adding CORS + handling the OPTIONS
preflight), and the 'local' boltz preset points at the same-origin /boltz path.
Public providers (mainnet/testnet) already send CORS and are unaffected.
Verified: GET limits via proxy returns the real 50k/40.29M with CORS; POST
create-reverse succeeds; the browser swap form now shows Min 50,000.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Diffstat (limited to 'dev.js')
| -rw-r--r-- | dev.js | 14 |
1 files changed, 14 insertions, 0 deletions
@@ -13,6 +13,20 @@ Bun.serve({ const NO_STORE = 'no-store, must-revalidate'; try { const path = new URL(req.url).pathname; + // The regtest boltz API (localhost:9001) sends no CORS headers, so the + // browser can't fetch it cross-origin. Proxy /boltz/* to it (adding CORS) + // so Lightning swaps work same-origin in dev. + if (path === '/boltz' || path.startsWith('/boltz/')) { + const CORS = { 'access-control-allow-origin': '*', 'access-control-allow-methods': 'GET,POST,OPTIONS', 'access-control-allow-headers': 'content-type' }; + if (req.method === 'OPTIONS') return new Response(null, { status: 204, headers: CORS }); + const target = 'http://localhost:9001' + path.replace(/^\/boltz/, '') + new URL(req.url).search; + const r = await fetch(target, { + method: req.method, + headers: req.headers.get('content-type') ? { 'content-type': req.headers.get('content-type') } : {}, + body: ['GET', 'HEAD'].includes(req.method) ? undefined : await req.text(), + }); + return new Response(await r.text(), { status: r.status, headers: { 'content-type': r.headers.get('content-type') || 'application/json', ...CORS } }); + } if (path === '/jsqr.js') { return new Response(await buildJsQr({ minify: false }), { headers: { 'content-type': 'text/javascript; charset=utf-8', 'cache-control': NO_STORE }, |
