diff --git a/apps/web/app/(blobstream)/[network]/blobstream/page.tsx b/apps/web/app/(blobstream)/[network]/blobstream/page.tsx
new file mode 100644
index 00000000..174e7868
--- /dev/null
+++ b/apps/web/app/(blobstream)/[network]/blobstream/page.tsx
@@ -0,0 +1,202 @@
+import type { Metadata } from "next";
+import Image from "next/image";
+import Link from "next/link";
+import { capitalize } from "~/lib/shared-utils";
+import { Button } from "~/ui/button";
+import { ArCube } from "~/ui/icons";
+import { cn } from "~/ui/shadcn/utils";
+
+export type BlobStreamPageProps = {
+ params: {
+ network: string;
+ };
+ searchParams?: {
+ stream?: string;
+ };
+};
+
+export function generateMetadata(props: BlobStreamPageProps) {
+ const names = props.params.network.split("-");
+ const formattedName = names.map(capitalize).join(" ");
+ return {
+ title: `${formattedName} Blobstream`,
+ };
+}
+
+export default function BlobStreamPage({ searchParams }: BlobStreamPageProps) {
+ const streamSources = ["arbitrum_one", "base"];
+
+ const selectedStream = streamSources.includes(searchParams?.stream ?? "")
+ ? searchParams?.stream
+ : streamSources[0];
+ return (
+
+
+
+
Blobstream
+ Select to see blob streams:
+
+
+
+
+
+
+
+
+
+
+
+
+
- Latest Block on Celestia
+
+ -
+
+
- 1300
+
+
+
+
- Latest Synched Block
+
+ -
+
+
- 1000
+
+
+
+
+
+
+
+
+ |
+ Transfer
+ |
+
+ File
+ |
+
+ Time
+ |
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+type BlobStreamImageCardProps = {
+ className?: string;
+ image: string;
+ title: string;
+ subtitle: string;
+ selected?: boolean;
+ link: string;
+ isUnavailable?: boolean;
+};
+
+function BlobStreamImageCard({
+ className,
+ image,
+ title,
+ subtitle,
+ link,
+ selected = false,
+ isUnavailable = false,
+}: BlobStreamImageCardProps) {
+ return (
+
+
+
+
+
+
+ {title}
+
+
{subtitle}
+
+
+
+
+
+ {selected && (
+
+ )}
+
+
+
+ );
+}
+
+export const runtime = "edge";
diff --git a/apps/web/public/images/arbitrum_one.svg b/apps/web/public/images/arbitrum_one.svg
new file mode 100644
index 00000000..a44288ba
--- /dev/null
+++ b/apps/web/public/images/arbitrum_one.svg
@@ -0,0 +1,36 @@
+
diff --git a/apps/web/public/images/base.svg b/apps/web/public/images/base.svg
new file mode 100644
index 00000000..a814b760
--- /dev/null
+++ b/apps/web/public/images/base.svg
@@ -0,0 +1,5 @@
+
diff --git a/apps/web/public/images/dots-mask.svg b/apps/web/public/images/dots-mask.svg
new file mode 100644
index 00000000..dc4e1f6e
--- /dev/null
+++ b/apps/web/public/images/dots-mask.svg
@@ -0,0 +1,354 @@
+
diff --git a/apps/web/ui/icon-svgs/ARCube.svg b/apps/web/ui/icon-svgs/ARCube.svg
new file mode 100644
index 00000000..0d6661a2
--- /dev/null
+++ b/apps/web/ui/icon-svgs/ARCube.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/apps/web/ui/icons/ArCube.tsx b/apps/web/ui/icons/ArCube.tsx
new file mode 100644
index 00000000..be7015f3
--- /dev/null
+++ b/apps/web/ui/icons/ArCube.tsx
@@ -0,0 +1,18 @@
+import * as React from "react";
+import type { SVGProps } from "react";
+const SvgArCube = (props: SVGProps) => (
+
+);
+export default SvgArCube;
diff --git a/apps/web/ui/icons/index.ts b/apps/web/ui/icons/index.ts
index bf37d6df..ab6c9e9b 100644
--- a/apps/web/ui/icons/index.ts
+++ b/apps/web/ui/icons/index.ts
@@ -1,3 +1,4 @@
+export { default as ArCube } from "./ArCube";
export { default as ArrowDown } from "./ArrowDown";
export { default as ArrowLeftRight } from "./ArrowLeftRight";
export { default as ArrowOff } from "./ArrowOff";