Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions components/providers/ArweaveFallbackSwRegistration.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"use client";

import { useEffect } from "react";

const SW_PATH = "/arweave-fallback-sw.js";

export default function ArweaveFallbackSwRegistration() {
useEffect(() => {
if (typeof navigator === "undefined" || !("serviceWorker" in navigator)) {
return;
}
navigator.serviceWorker
.register(SW_PATH, { scope: "/" })
.catch(() => {});
}, []);
return null;
}
2 changes: 2 additions & 0 deletions components/providers/Providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { WaveEligibilityProvider } from "@/contexts/wave/WaveEligibilityContext"
import { AppWebSocketProvider } from "@/services/websocket/AppWebSocketProvider";
import { LayoutProvider } from "../brain/my-stream/layout/LayoutContext";
import { ViewProvider } from "../navigation/ViewContext";
import ArweaveFallbackSwRegistration from "./ArweaveFallbackSwRegistration";
import CapacitorSetup from "./CapacitorSetup";
import IpfsImageSetup from "./IpfsImageSetup";
import QueryClientSetup from "./QueryClientSetup";
Expand All @@ -34,6 +35,7 @@ export default function Providers({
<AppWalletsProvider>
<WagmiSetup>
<CapacitorSetup />
<ArweaveFallbackSwRegistration />
<IpfsImageSetup />
<ReactQueryWrapper>
<RefreshProvider>
Expand Down
1 change: 1 addition & 0 deletions config/nextConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export function sharedConfig(
{ protocol: "https", hostname: "6529.io" },
{ protocol: "https", hostname: "staging.6529.io" },
{ protocol: "https", hostname: "arweave.net" },
{ protocol: "https", hostname: "ar-io.net" },
{ protocol: "http", hostname: "localhost" },
{ protocol: "https", hostname: "media.generator.seize.io" },
{ protocol: "https", hostname: "d3lqz0a4bldqgf.cloudfront.net" },
Expand Down
2 changes: 1 addition & 1 deletion config/securityHeaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export function createSecurityHeaders(apiEndpoint: string | undefined = "") {
},
{
key: "Content-Security-Policy",
value: `default-src 'none'; script-src 'self' 'unsafe-inline' https://dnclu2fna0b2b.cloudfront.net https://www.google-analytics.com https://www.googletagmanager.com/ https://dataplane.rum.us-east-1.amazonaws.com 'unsafe-eval'; connect-src * 'self' blob: ${apiEndpoint} https://registry.walletconnect.com/api/v2/wallets wss://*.bridge.walletconnect.org wss://*.walletconnect.com wss://www.walletlink.org/rpc https://explorer-api.walletconnect.com/v3/wallets https://www.googletagmanager.com https://*.google-analytics.com https://cloudflare-eth.com/ https://arweave.net/* https://rpc.walletconnect.com/v1/ https://sts.us-east-1.amazonaws.com https://sts.us-west-2.amazonaws.com; font-src 'self' data: https://fonts.gstatic.com https://fonts.reown.com https://dnclu2fna0b2b.cloudfront.net https://cdnjs.cloudflare.com; img-src 'self' data: blob: ipfs: https://artblocks.io https://*.artblocks.io *; media-src 'self' blob: https://*.cloudfront.net https://videos.files.wordpress.com https://arweave.net https://*.arweave.net https://cf-ipfs.com/ipfs/* https://*.twimg.com https://artblocks.io https://*.artblocks.io; frame-src 'self' https://ipfs.io https://ipfs.io/ipfs/ https://cf-ipfs.com https://cf-ipfs.com/ipfs/ https://media.generator.seize.io https://media.generator.6529.io https://generator.seize.io https://arweave.net https://*.arweave.net https://nftstorage.link https://*.ipfs.nftstorage.link https://verify.walletconnect.com https://verify.walletconnect.org https://secure.walletconnect.com https://d3lqz0a4bldqgf.cloudfront.net https://www.youtube.com https://www.youtube-nocookie.com https://*.youtube.com https://artblocks.io https://*.artblocks.io https://docs.google.com https://drive.google.com https://*.google.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/css2 https://dnclu2fna0b2b.cloudfront.net https://cdnjs.cloudflare.com http://cdnjs.cloudflare.com https://cdn.jsdelivr.net; object-src data:;`,
value: `default-src 'none'; script-src 'self' 'unsafe-inline' https://dnclu2fna0b2b.cloudfront.net https://www.google-analytics.com https://www.googletagmanager.com/ https://dataplane.rum.us-east-1.amazonaws.com 'unsafe-eval'; connect-src * 'self' blob: ${apiEndpoint} https://registry.walletconnect.com/api/v2/wallets wss://*.bridge.walletconnect.org wss://*.walletconnect.com wss://www.walletlink.org/rpc https://explorer-api.walletconnect.com/v3/wallets https://www.googletagmanager.com https://*.google-analytics.com https://cloudflare-eth.com/ https://arweave.net/* https://ar-io.net https://ar-io.net/* https://rpc.walletconnect.com/v1/ https://sts.us-east-1.amazonaws.com https://sts.us-west-2.amazonaws.com; font-src 'self' data: https://fonts.gstatic.com https://fonts.reown.com https://dnclu2fna0b2b.cloudfront.net https://cdnjs.cloudflare.com; img-src 'self' data: blob: ipfs: https://artblocks.io https://*.artblocks.io *; media-src 'self' blob: https://*.cloudfront.net https://videos.files.wordpress.com https://arweave.net https://*.arweave.net https://ar-io.net https://*.ar-io.net https://cf-ipfs.com/ipfs/* https://*.twimg.com https://artblocks.io https://*.artblocks.io; frame-src 'self' https://ipfs.io https://ipfs.io/ipfs/ https://cf-ipfs.com https://cf-ipfs.com/ipfs/ https://media.generator.seize.io https://media.generator.6529.io https://generator.seize.io https://arweave.net https://*.arweave.net https://ar-io.net https://*.ar-io.net https://nftstorage.link https://*.ipfs.nftstorage.link https://verify.walletconnect.com https://verify.walletconnect.org https://secure.walletconnect.com https://d3lqz0a4bldqgf.cloudfront.net https://www.youtube.com https://www.youtube-nocookie.com https://*.youtube.com https://artblocks.io https://*.artblocks.io https://docs.google.com https://drive.google.com https://*.google.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/css2 https://dnclu2fna0b2b.cloudfront.net https://cdnjs.cloudflare.com http://cdnjs.cloudflare.com https://cdn.jsdelivr.net; object-src data:;`,
},
{ key: "X-Frame-Options", value: "SAMEORIGIN" },
{ key: "X-Content-Type-Options", value: "nosniff" },
Expand Down
24 changes: 24 additions & 0 deletions lib/arweave-fallback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const ARWEAVE_HOST = "arweave.net";
const FALLBACK_HOST = "ar-io.net";

export function isArweaveUrl(url: string): boolean {
try {
const u = new URL(url);
const h = u.hostname.toLowerCase();
return h === ARWEAVE_HOST || h === "www." + ARWEAVE_HOST;
} catch {
return false;
}
}

export function getArweaveFallbackUrl(url: string): string | null {
if (!isArweaveUrl(url)) return null;
try {
const u = new URL(url);
u.hostname = FALLBACK_HOST;
u.host = FALLBACK_HOST + (u.port ? ":" + u.port : "");
return u.toString();
} catch {
return null;
}
}
18 changes: 18 additions & 0 deletions public/arweave-fallback-sw.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const FALLBACK_HOST = "ar-io.net";

self.addEventListener("fetch", (event) => {
const url = event.request.url;
if (!url.includes("arweave.net") || event.request.mode === "navigate") return;
Comment thread Fixed
Comment thread
prxt6529 marked this conversation as resolved.
Outdated

event.respondWith(
(async () => {
const opts = { method: event.request.method, headers: event.request.headers, credentials: "omit" };
let res = await fetch(event.request, opts).catch(() => null);
if (res?.ok) return res;
const fallback = url.replace(/^(https?:\/\/)([^/]+)/, `$1${FALLBACK_HOST}`);
res = await fetch(fallback, opts).catch(() => null);
Comment thread
prxt6529 marked this conversation as resolved.
Outdated
if (res?.ok) return res;
return res || new Response(null, { status: 502 });
})()
);
});