diff --git a/src/components/icons/GasIcon.tsx b/src/components/icons/GasIcon.tsx
new file mode 100644
index 0000000..d6f37d0
--- /dev/null
+++ b/src/components/icons/GasIcon.tsx
@@ -0,0 +1,24 @@
+import { DefaultIconProps } from '@hyperlane-xyz/widgets';
+import { memo } from 'react';
+import { Color } from '../../styles/Color';
+
+// TODO move to widgets lib
+function _GasIcon({ color, ...rest }: DefaultIconProps) {
+ return (
+
+ );
+}
+
+export const GasIcon = memo(_GasIcon);
diff --git a/src/components/icons/StopIcon.tsx b/src/components/icons/StopIcon.tsx
new file mode 100644
index 0000000..b3f8309
--- /dev/null
+++ b/src/components/icons/StopIcon.tsx
@@ -0,0 +1,24 @@
+import { DefaultIconProps } from '@hyperlane-xyz/widgets';
+import { memo } from 'react';
+import { Color } from '../../styles/Color';
+
+// TODO move to widgets lib
+function _StopIcon({ color, ...rest }: DefaultIconProps) {
+ return (
+
+ );
+}
+
+export const StopIcon = memo(_StopIcon);
diff --git a/src/components/text/H1.tsx b/src/components/text/H1.tsx
index c756749..74269b7 100644
--- a/src/components/text/H1.tsx
+++ b/src/components/text/H1.tsx
@@ -1,3 +1,8 @@
-export function H1({ children }: { children: React.ReactNode }) {
- return
{children}
;
+import clsx from 'clsx';
+import { HTMLAttributes, PropsWithChildren } from 'react';
+
+type Props = PropsWithChildren>;
+
+export function H1({ className, ...props }: Props) {
+ return ;
}
diff --git a/src/features/deployment/warp/WarpDeploymentDeploy.tsx b/src/features/deployment/warp/WarpDeploymentDeploy.tsx
new file mode 100644
index 0000000..e3eda59
--- /dev/null
+++ b/src/features/deployment/warp/WarpDeploymentDeploy.tsx
@@ -0,0 +1,87 @@
+import { ArrowIcon, Button, WalletIcon } from '@hyperlane-xyz/widgets';
+import { useState } from 'react';
+import { toast } from 'react-toastify';
+import { SolidButton } from '../../../components/buttons/SolidButton';
+import { GasIcon } from '../../../components/icons/GasIcon';
+import { StopIcon } from '../../../components/icons/StopIcon';
+import { H1 } from '../../../components/text/H1';
+import { CardPage } from '../../../flows/CardPage';
+import { useCardNav } from '../../../flows/hooks';
+import { Color } from '../../../styles/Color';
+import { useWarpDeploymentConfig } from '../hooks';
+
+export function WarpDeploymentDeploy() {
+ return (
+
+
+
+
+
+ );
+}
+
+function HeaderSection() {
+ return Deploying Warp Route
;
+}
+
+function StatusSection() {
+ const { deploymentConfig } = useWarpDeploymentConfig();
+ const _chains = deploymentConfig?.chains || [];
+
+ return (
+
+
+
+ );
+}
+
+function FundAccounts() {
+ const { deploymentConfig } = useWarpDeploymentConfig();
+ const chains = deploymentConfig?.chains || [];
+ const numChains = chains.length;
+
+ const [currentChainIndex, setCurrentChainIndex] = useState(0);
+ const currentChain = chains[currentChainIndex];
+
+ const onClickFund = () => {
+ // TODO create a temp deployer account and trigger a
+ if (currentChainIndex < numChains - 1) {
+ setCurrentChainIndex(currentChainIndex + 1);
+ }
+ };
+
+ return (
+
+
+
+ To deploy your route, a temporary account must be funded for each chain. Unused amounts are
+ refunded.
+
+
{`Fund on ${currentChain} (Chain ${currentChainIndex + 1} / ${numChains})`}
+
+ );
+}
+
+function ButtonSection() {
+ const { setPage } = useCardNav();
+ const onClickCancel = () => {
+ // TODO cancel in SDK if possible?
+ toast.warn('Deployment cancelled');
+ setPage(CardPage.WarpReview);
+ };
+
+ return (
+
+ );
+}
diff --git a/src/flows/CardFlow.tsx b/src/flows/CardFlow.tsx
index cab4534..da59c44 100644
--- a/src/flows/CardFlow.tsx
+++ b/src/flows/CardFlow.tsx
@@ -1,4 +1,5 @@
import { AnimatePresence, motion } from 'framer-motion';
+import { WarpDeploymentDeploy } from '../features/deployment/warp/WarpDeploymentDeploy';
import { WarpDeploymentForm } from '../features/deployment/warp/WarpDeploymentForm';
import { WarpDeploymentReview } from '../features/deployment/warp/WarpDeploymentReview';
import { CardPage } from './CardPage';
@@ -25,6 +26,7 @@ export function CardFlow() {
{page === CardPage.Landing && }
{page === CardPage.WarpForm && }
{page === CardPage.WarpReview && }
+ {page === CardPage.WarpDeploy && }
;
diff --git a/src/flows/LandingCard.tsx b/src/flows/LandingCard.tsx
index 88b3f82..ceaba02 100644
--- a/src/flows/LandingCard.tsx
+++ b/src/flows/LandingCard.tsx
@@ -10,17 +10,17 @@ export function LandingPage() {
const { setPage } = useCardNav();
return (
-
+
-
+
Deploy a Warp Route
-
+
Anyone can permissionlessly create an interchain token bridge by deploying Hyperlane Warp
Route contracts.
-
+
Follow three steps to create a new route: configure your options, deploy your contracts, and
set up a bridge UI.
diff --git a/src/images/icons/arrow-right.svg b/src/images/icons/arrow-right.svg
deleted file mode 100644
index 2b05235..0000000
--- a/src/images/icons/arrow-right.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-