diff --git a/app/public/brand/arbitrum.svg b/app/public/brand/arbitrum.svg
new file mode 100644
index 00000000..00f30b9d
--- /dev/null
+++ b/app/public/brand/arbitrum.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/app/public/brand/optimism.svg b/app/public/brand/optimism.svg
new file mode 100644
index 00000000..c809fd13
--- /dev/null
+++ b/app/public/brand/optimism.svg
@@ -0,0 +1,6 @@
+
+
+
diff --git a/app/src/app/bridge/BridgePageLayout.tsx b/app/src/app/bridge/BridgePageLayout.tsx
new file mode 100644
index 00000000..782973b2
--- /dev/null
+++ b/app/src/app/bridge/BridgePageLayout.tsx
@@ -0,0 +1,74 @@
+import type { ReactNode } from "react";
+import { ArrowDown, ArrowLeftRight } from "lucide-react";
+import SectionIntro from "@/components/sections/SectionIntro";
+import shell from "@/components/sections/SectionShell.module.css";
+import { BRIDGE_ASSETS, BRIDGE_CHAINS, BRIDGE_DESTINATION_IDS, BRIDGE_FUNDING_IDS } from "@/lib/bridge/types";
+import styles from "./bridge.module.css";
+
+const STEPS = [
+ ["Pick a route and an amount", "A live quote appears with the fee, the gas and the least you will receive. Nothing is asked of your wallet yet."],
+ ["Approve, for tokens only", "USDC and USDG need an approval for the exact amount first. It is its own wallet step and moves nothing. ETH skips it."],
+ ["Confirm the deposit", "Slide the coin across or press the button, then confirm in your wallet. This is the one step that sends funds."],
+ ["Watch it arrive", "The board follows the transfer until the provider confirms delivery to the same address on the other network."],
+] as const;
+
+export default function BridgePageLayout({ panel, history, controls, introActions }: {
+ panel: ReactNode;
+ history: ReactNode;
+ controls?: ReactNode;
+ introActions?: ReactNode;
+}) {
+ return (
+
+ }
+ title="Move funds to where you launch"
+ description="Send ETH and dollars between Base, Robinhood Chain, Arc and Elysium, or bring them in from Ethereum, Arbitrum and Optimism. They arrive at the same wallet address. openlaunch charges nothing for it."
+ >
+ Your transfers
+ {introActions}
+
+ {controls}
+
+ {panel}
+
+
+
Networks and tokens
+
+ {BRIDGE_DESTINATION_IDS.map((id) =>
{BRIDGE_CHAINS[id].name}
{BRIDGE_ASSETS[id].join(", ")}Send and receive
)}
+ {BRIDGE_FUNDING_IDS.map((id) =>
{BRIDGE_CHAINS[id].name}
{BRIDGE_ASSETS[id].join(", ")}Send only
)}
+
+
+
+
How a transfer goes
+
+ {STEPS.map(([title, body]) =>
{title}{body}
)}
+
+
+
+
What it costs
+
+
openlaunch takes no fee on a transfer.
+
The bridge provider charges a fee that is shown before you confirm and is already taken out of the amount you receive.
+
Relay quotes every route. For USDC to USDC into Base or Arc, Circle is quoted too, and you get whichever delivers more. The quote names which one.
+
Gas on the network you send from is extra.
+
A quote that would cost more than 5% in fees, or lose more than 5% in conversion, is blocked.
+
+
+
+
Good to know
+
+
On Elysium the bridge carries USDC only. Its gas token, HYPE, is not bridged, so keep some HYPE there to use or send what arrives.
+
Funds go from your wallet to Relay's deposit contract, or to Circle's transfer contract on a Circle route. They never pass through an openlaunch wallet or contract.
+
Relay and Circle are third parties. openlaunch operates neither and cannot reverse a transfer.
+
A transfer is saved in this browser while it is in progress. Reopen the bridge with the same wallet to pick it up.
+
Finished transfers stay on the board below. It never asks your wallet for anything.
+
+
+
+
+ {history}
+
+ );
+}
diff --git a/app/src/app/bridge/page.tsx b/app/src/app/bridge/page.tsx
index 1112c28c..61eac368 100644
--- a/app/src/app/bridge/page.tsx
+++ b/app/src/app/bridge/page.tsx
@@ -1,13 +1,9 @@
import type { Metadata } from "next";
-import { ArrowLeftRight } from "lucide-react";
import { pageMetadata } from "@/lib/seo";
-import SectionIntro from "@/components/sections/SectionIntro";
-import shell from "@/components/sections/SectionShell.module.css";
import BridgePageSlot from "@/components/bridge/BridgePageSlot";
import BridgeHistory from "@/components/bridge/BridgeHistory";
import { parseBridgeLink } from "@/lib/bridge/link";
-import { BRIDGE_ASSETS, BRIDGE_CHAINS, BRIDGE_DESTINATION_IDS, BRIDGE_FUNDING_IDS } from "@/lib/bridge/types";
-import styles from "./bridge.module.css";
+import BridgePageLayout from "./BridgePageLayout";
/**
* The bridge as a page: the same panel the header opens, with room for the facts beside it. The panel is rendered by
@@ -17,64 +13,15 @@ import styles from "./bridge.module.css";
export const metadata: Metadata = pageMetadata({
path: "/bridge",
title: "Bridge",
- description: "Move ETH and dollars between Base, Robinhood Chain and Arc, or fund them from Ethereum, Arbitrum and Optimism. Same wallet, no openlaunch fee.",
+ description: "Move ETH and dollars between Base, Robinhood Chain, Arc and Elysium, or fund them from Ethereum, Arbitrum and Optimism. Same wallet, no openlaunch fee.",
});
-const STEPS = [
- ["Pick a route and an amount", "A live quote appears with the fee, the gas and the least you will receive. Nothing is asked of your wallet yet."],
- ["Approve, for tokens only", "USDC and USDG need an approval for the exact amount first. It is its own wallet step and moves nothing. ETH skips it."],
- ["Confirm the deposit", "Slide the coin across or press the button, then confirm in your wallet. This is the one step that sends funds."],
- ["Watch it arrive", "The board follows the transfer until the provider confirms delivery to the same address on the other network."],
-] as const;
-
export default async function BridgePage({ searchParams }: { searchParams: Promise> }) {
const link = parseBridgeLink(await searchParams);
return (
-
- }
- title="Move funds to where you launch"
- description="Send ETH and dollars between Base, Robinhood Chain and Arc, or bring them in from Ethereum, Arbitrum and Optimism. They arrive at the same wallet address. openlaunch charges nothing for it."
- />
-
-
-
-
-
Networks and tokens
-
- {BRIDGE_DESTINATION_IDS.map((id) =>
{BRIDGE_CHAINS[id].name}
{BRIDGE_ASSETS[id].join(", ")}Send and receive
)}
- {BRIDGE_FUNDING_IDS.map((id) =>
{BRIDGE_CHAINS[id].name}
{BRIDGE_ASSETS[id].join(", ")}Send only
)}
-
-
-
-
How a transfer goes
-
- {STEPS.map(([title, body]) =>
{title}{body}
)}
-
-
-
-
What it costs
-
-
openlaunch takes no fee on a transfer.
-
The bridge provider charges a fee that is shown before you confirm and is already taken out of the amount you receive.
-
Relay quotes every route. For USDC to USDC into Base or Arc, Circle is quoted too, and you get whichever delivers more. The quote names which one.
-
Gas on the network you send from is extra.
-
A quote that would cost more than 5% in fees, or lose more than 5% in conversion, is blocked.
-
-
-
-
Good to know
-
-
Funds go from your wallet to Relay's deposit contract, or to Circle's transfer contract on a Circle route. They never pass through an openlaunch wallet or contract.
-
Relay and Circle are third parties. openlaunch operates neither and cannot reverse a transfer.
-
A transfer is saved in this browser while it is in progress. Reopen the bridge with the same wallet to pick it up.
-
Finished transfers stay on the board below. It never asks your wallet for anything.
Development-only synthetic data. No wallet requests, API calls, or funds.
-
Base offers ETH and USDC. Arc uses USDC. Robinhood offers ETH; its USDC routes currently fail our safety checks. USDC sends use an exact-amount approval.
-
-
{scenes.map((value) => )}
-
-
-
Bridge
- Preview only · {scene} · no funds move
- {tracking ? : setScene("quote")} />}
-
{viaCircle ? "Powered by Circle CCTP" : "Powered by Relay"}0 Openlaunch fee
-
-
-
{HISTORY_SCENES.map((value) => )}
-
-
- {}} />
-
Bridge, then buy
-
The trade panel card, at trade panel width. Buttons do nothing here.