Merge pull request #273 from hyperlane-xyz/main-to-ezeth

Main to ezeth
pull/282/head
J M Rossy 1 month ago committed by GitHub
commit 0f101d07ba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 19
      CUSTOMIZE.md
  2. 6
      package.json
  3. 1
      public/backgrounds/lines-bg-top.svg
  4. 1
      public/backgrounds/main.svg
  5. BIN
      public/fonts/NeueHaasDisplayBold.woff
  6. BIN
      public/fonts/NeueHaasDisplayBold.woff2
  7. BIN
      public/fonts/NeueHaasDisplayLight.woff
  8. BIN
      public/fonts/NeueHaasDisplayLight.woff2
  9. BIN
      public/fonts/NeueHaasDisplayMedium.woff
  10. BIN
      public/fonts/NeueHaasDisplayMedium.woff2
  11. BIN
      public/fonts/NeueHaasDisplayRoman.woff
  12. BIN
      public/fonts/NeueHaasDisplayRoman.woff2
  13. BIN
      public/fonts/NeueHaasDisplayThin.woff
  14. BIN
      public/fonts/NeueHaasDisplayThin.woff2
  15. BIN
      public/logos/everclear.png
  16. 4
      src/components/banner/FormWarningBanner.tsx
  17. 4
      src/components/buttons/ConnectAwareSubmitButton.tsx
  18. 37
      src/components/buttons/SolidButton.tsx
  19. 2
      src/components/icons/Chevron.tsx
  20. 2
      src/components/icons/Identicon.tsx
  21. 2
      src/components/icons/WideChevron.tsx
  22. 2
      src/components/input/TextField.tsx
  23. 11
      src/components/layout/AppLayout.tsx
  24. 9
      src/components/layout/Card.tsx
  25. 45
      src/components/nav/Footer.tsx
  26. 12
      src/components/tip/TipCard.tsx
  27. 16
      src/consts/app.ts
  28. 28
      src/consts/config.ts
  29. 1
      src/consts/links.ts
  30. 2
      src/context/WarpContext.tsx
  31. 27
      src/features/chains/ChainSelectField.tsx
  32. 6
      src/features/chains/ChainSelectModal.tsx
  33. 2
      src/features/tokens/SelectTokenIdField.tsx
  34. 4
      src/features/tokens/TokenSelectField.tsx
  35. 14
      src/features/transfer/TransferTokenCard.tsx
  36. 57
      src/features/transfer/TransferTokenForm.tsx
  37. 12
      src/features/transfer/TransfersDetailsModal.tsx
  38. 19
      src/features/transfer/useTokenTransfer.ts
  39. 36
      src/features/wallet/SideBarMenu.tsx
  40. 4
      src/features/wallet/WalletControlBar.tsx
  41. 2
      src/features/wallet/WalletEnvSelectionModal.tsx
  42. 2
      src/features/wallet/context/EvmWalletContext.tsx
  43. 1
      src/images/backgrounds/footer-bg.svg
  44. 4
      src/images/backgrounds/main-bg.svg
  45. 6
      src/images/logos/app-logo.svg
  46. 18
      src/images/logos/app-name.svg
  47. 3
      src/images/logos/github copy.svg
  48. BIN
      src/images/planets/planet-1.webp
  49. BIN
      src/images/planets/planet-2.webp
  50. 6
      src/pages/_app.tsx
  51. 6
      src/pages/_document.tsx
  52. 2
      src/pages/index.tsx
  53. 39
      src/styles/Color.ts
  54. 39
      src/styles/fonts.css
  55. 10
      src/styles/globals.css
  56. 80
      tailwind.config.js
  57. 58
      yarn.lock

@ -27,10 +27,15 @@ Or it can be hidden entirely with the `showTipBox` setting in `./src/consts/conf
## Branding
## App name
## App name and description
The values to describe the app itself (e.g. to WalletConnect) are in `./src/consts/app.ts`
### Color Scheme
To update the color scheme, make changes in the Tailwind config file at `./tailwind.config.js`
To modify just the background color, that can be changed in `./src/consts/app.ts`
### Metadata
The HTML metadata tags are located in `./src/pages/_document.tsx`
@ -55,15 +60,3 @@ The links used in the footer can be found here: `./src/consts/links.ts`
### Public assets / Favicons
The images and manifest files under `./public` should also be updated.
### Fonts
The web-formatted font files are located in `./public/fonts`
And the CSS to configure them is in `./src/styles/fonts.css`
### Color Scheme
To update the color scheme, make changes in the Tailwind config and Color consts file:
- `./tailwind.config.js`
- `./src/styles/Color.ts`

@ -18,9 +18,9 @@
"@emotion/styled": "^11.13.0",
"@headlessui/react": "^1.7.14",
"@hyperlane-xyz/registry": "4.3.6",
"@hyperlane-xyz/sdk": "5.2.1",
"@hyperlane-xyz/utils": "5.2.1",
"@hyperlane-xyz/widgets": "5.2.1",
"@hyperlane-xyz/sdk": "5.3.0",
"@hyperlane-xyz/utils": "5.3.0",
"@hyperlane-xyz/widgets": "5.3.0",
"@interchain-ui/react": "^1.23.28",
"@metamask/jazzicon": "https://github.com/jmrossy/jazzicon#7a8df28974b4e81129bfbe3cab76308b889032a6",
"@metamask/post-message-stream": "6.1.2",

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" viewBox="2 39 882.5 72"><path d="M783.5 40.2C622 124.6 158.7 96.4 8 40.2" style="fill:none;stroke:#fff;stroke-width:2px;"/><path d="M884.5 39C586 166.9 152.9 96.9 2 39" style="fill:none;stroke:#fff;stroke-width:4px;"/></svg>

Before

Width:  |  Height:  |  Size: 278 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

@ -1,12 +1,12 @@
import { ComponentProps } from 'react';
import { WarningBanner } from '../../components/banner/WarningBanner';
import { cardStyles } from '../layout/Card';
export function FormWarningBanner({ className, ...props }: ComponentProps<typeof WarningBanner>) {
return (
<WarningBanner
// The margins here should be the inverse of those in Card.tsx
className={`z-20 -m-1.5 mb-0 sm:-m-3 sm:mb-0 md:-m-3.5 md:mb-0 ${className}`}
className={`z-20 ${cardStyles.inverseMargin} mb-0 sm:mb-0 md:mb-0 ${className}`}
{...props}
/>
);

@ -28,8 +28,8 @@ export function ConnectAwareSubmitButton<FormValues = any>({ chainName, text, cl
const hasError = Object.keys(touched).length > 0 && Object.keys(errors).length > 0;
const firstError = `${Object.values(errors)[0]}` || 'Unknown error';
const color = hasError ? 'red' : 'green';
const content = hasError ? firstError : isAccountReady ? text : 'Connect Wallet';
const color = hasError ? 'red' : 'accent';
const content = hasError ? firstError : isAccountReady ? text : 'Connect wallet';
const type = isAccountReady ? 'submit' : 'button';
const onClick = isAccountReady ? undefined : connectFn;

@ -2,7 +2,7 @@ import { PropsWithChildren, ReactElement } from 'react';
interface ButtonProps {
type?: 'submit' | 'reset' | 'button';
color?: 'white' | 'blue' | 'green' | 'red' | 'gray' | 'pink' | 'mint'; // defaults to blue
color?: 'white' | 'primary' | 'accent' | 'green' | 'red' | 'gray'; // defaults to primary
bold?: boolean;
classes?: string;
icon?: ReactElement;
@ -22,42 +22,33 @@ export function SolidButton(
title,
...passThruProps
} = props;
const color = _color ?? 'blue';
const color = _color ?? 'primary';
const base = 'flex items-center justify-center rounded-full transition-all duration-500';
let baseColors, onHover, onActive;
if (color === 'blue') {
baseColors = 'bg-blue-500 text-white';
onHover = 'hover:bg-blue-600';
onActive = 'active:bg-blue-700';
} else if (color === 'pink') {
baseColors = 'bg-pink-500 text-white';
onHover = 'hover:bg-pink-600';
onActive = 'active:bg-pink-700';
const base =
'flex items-center justify-center rounded-lg transition-all duration-500 active:scale-95';
let baseColors, onHover;
if (color === 'primary') {
baseColors = 'bg-primary-500 text-white';
onHover = 'hover:bg-primary-600';
} else if (color === 'accent') {
baseColors = 'bg-accent-500 text-white';
onHover = 'hover:bg-accent-600';
} else if (color === 'green') {
baseColors = 'bg-green-500';
onHover = 'hover:bg-green-600';
onActive = 'active:bg-green-700';
} else if (color === 'mint') {
baseColors = 'bg-mint-500 text-white';
onHover = 'hover:bg-mint-600';
onActive = 'active:bg-mint-700';
} else if (color === 'red') {
baseColors = 'bg-red-600 text-white';
onHover = 'hover:bg-red-500';
onActive = 'active:bg-red-400';
} else if (color === 'white') {
baseColors = 'bg-white text-black';
onHover = 'hover:bg-blue-100';
onActive = 'active:bg-blue-200';
onHover = 'hover:bg-primary-100';
} else if (color === 'gray') {
baseColors = 'bg-gray-100 text-blue-500';
baseColors = 'bg-gray-100 text-primary-500';
onHover = 'hover:bg-gray-200';
onActive = 'active:bg-gray-300';
}
const onDisabled = 'disabled:bg-gray-300 disabled:text-gray-500';
const weight = bold ? 'font-semibold' : '';
const allClasses = `${base} ${baseColors} ${onHover} ${onDisabled} ${onActive} ${weight} ${classes}`;
const allClasses = `${base} ${baseColors} ${onHover} ${onDisabled} ${weight} ${classes}`;
return (
<button

@ -40,7 +40,7 @@ function _ChevronIcon({ width, height, direction, color, classes }: Props) {
<path
d="M1 1l6 6 6-6"
strokeWidth="2"
stroke={color || Color.primaryBlack}
stroke={color || Color.black}
fill="none"
fillRule="evenodd"
strokeLinecap="round"

@ -21,7 +21,7 @@ function _Identicon({ address, size: _size }: Props) {
// TODO better handling of non-evm addresses here
if (!address || !isValidAddressEvm(address)) {
return <Circle size={size} classes="bg-blue-500" title="" />;
return <Circle size={size} classes="bg-primary-500" title="" />;
}
const jazziconResult = jazzicon(size, addressToSeed(address));

@ -5,7 +5,7 @@ import { Color } from '../../styles/Color';
export function WideChevron({ classes }: { classes?: string }) {
return (
<WideChevronInner
width="17"
width="16"
height="100%"
direction="e"
color={Color.lightGray}

@ -26,4 +26,4 @@ export function TextInput({ onChange, classes, ...props }: InputProps) {
}
const defaultInputClasses =
'mt-1.5 px-2.5 py-2 text-sm rounded-full border border-blue-300 focus:border-blue-500 disabled:bg-gray-150 outline-none transition-all duration-300';
'mt-1.5 px-2.5 py-2.5 text-sm rounded-lg border border-primary-300 focus:border-primary-500 disabled:bg-gray-150 outline-none transition-all duration-300';

@ -1,7 +1,7 @@
import Head from 'next/head';
import { PropsWithChildren } from 'react';
import { APP_NAME } from '../../consts/app';
import { APP_NAME, BACKGROUND_COLOR, BACKGROUND_IMAGE } from '../../consts/app';
import { Footer } from '../nav/Footer';
import { Header } from '../nav/Header';
@ -16,7 +16,7 @@ export function AppLayout({ children }: PropsWithChildren) {
<div
style={styles.container}
id="app-content"
className="relative flex flex-col justify-between h-full min-h-screen w-full min-w-screen bg-blue-500"
className="relative flex flex-col justify-between h-full min-h-screen w-full min-w-screen"
>
<Header />
<div className="sm:px-4 mx-auto grow flex items-center max-w-screen-xl">
@ -30,9 +30,10 @@ export function AppLayout({ children }: PropsWithChildren) {
const styles = {
container: {
backgroundImage: 'url(/backgrounds/lines-bg-top.svg)',
backgroundSize: '94vw',
backgroundColor: BACKGROUND_COLOR,
backgroundImage: BACKGROUND_IMAGE,
backgroundSize: 'cover',
backgroundRepeat: 'no-repeat',
backgroundPosition: 'center 80px',
backgroundPosition: 'center',
},
};

@ -7,9 +7,16 @@ interface Props {
export function Card({ className, children }: PropsWithChildren<Props>) {
return (
<div
className={`p-1.5 sm:p-3 md:p-3.5 relative bg-white ring-blue-300 rounded-3xl overflow-auto ${className}`}
className={`${cardStyles.padding} relative bg-white rounded-2xl overflow-auto ${className}`}
>
{children}
</div>
);
}
export const cardStyles = {
padding: 'p-1.5 xs:p-2 sm:p-3 md:p-4',
// Should be inverse of cardPadding, used when something
// should be flush with card edge
inverseMargin: '-m-1.5 xs:-m-2 sm:-m-3 md:-m-4',
};

@ -4,39 +4,47 @@ import Link from 'next/link';
import { links } from '../../consts/links';
import { Discord } from '../icons/Discord';
import { Github } from '../icons/Github';
import { Medium } from '../icons/Medium';
import { Twitter } from '../icons/Twitter';
const footerLinks1 = [
{ title: 'Docs', url: links.docs, external: true },
{ title: 'Homepage', url: links.home, external: true },
{ title: 'Explorer', url: links.explorer, external: true },
{ title: 'Terms', url: links.terms, external: true },
];
const footerLinks3 = [
{ title: 'Twitter', url: links.twitter, external: true, icon: <Twitter fill="#000" /> },
{ title: 'Discord', url: links.discord, external: true, icon: <Discord fill="#000" /> },
{ title: 'Github', url: links.github, external: true, icon: <Github fill="#000" /> },
{ title: 'Blog', url: links.blog, external: true, icon: <Medium fill="#000" /> },
{ title: 'Twitter', url: links.twitter, external: true, icon: <Twitter fill="#fff" /> },
{ title: 'Discord', url: links.discord, external: true, icon: <Discord fill="#fff" /> },
{ title: 'Github', url: links.github, external: true, icon: <Github fill="#fff" /> },
];
export function Footer() {
return (
<footer className="relative">
<div className="relative z-10 px-8 pb-5 pt-2 sm:pt-0">
<footer className="text-white relative">
<div className="relative z-10 px-8 pb-5 pt-2 sm:pt-0 bg-gradient-to-b from-transparent to-black/40">
<div className="flex flex-col sm:flex-row gap-8 sm:gap-10 items-center justify-between">
<div className="flex items-center justify-center">
<div className="text-lg sm:text-xl font-medium ml-6 space-y-1 ">
<div className="flex items-center font-medium space-x-1">
<span>Built with</span>
<Image src="/logos/everclear.png" alt="" width={130} height={18} />
<span> and </span>
<Image src="/logos/renzo.svg" alt="" width={24} height={18} />
<span>Renzo</span>
<FooterLogo />
<FooterNav />
</div>
</div>
</footer>
);
}
function FooterLogo() {
return (
<div className="flex items-center justify-center text-lg sm:text-xl font-medium ml-6 space-y-1 gap-1.5">
<span>Built with</span>
<Image src="/logos/everclear.png" alt="" width={24} height={24} />
<span>Everclear and</span>
<Image src="/logos/renzo.svg" alt="" width={22} height={22} />
<span>Renzo</span>
</div>
);
}
function FooterNav() {
return (
<nav className="flex text-md font-medium">
<ul className={`${styles.linkCol} mr-14`}>
{footerLinks1.map((item) => (
@ -59,16 +67,13 @@ export function Footer() {
target={item.external ? '_blank' : '_self'}
href={item.url}
>
{item?.icon && <div className="mr-4 w-6">{item?.icon}</div>}
{item?.icon && <div className="mr-4 w-5">{item?.icon}</div>}
<div className="">{item.title}</div>
</Link>
</li>
))}
</ul>
</nav>
</div>
</div>
</footer>
);
}

@ -12,10 +12,10 @@ export function TipCard() {
const [show, setShow] = useState(config.showTipBox);
if (!show) return null;
return (
<Card className="w-100 sm:w-[31rem]">
<h2 className="text-blue-500 sm:text-lg">Bridge Tokens with Hyperlane Warp Routes!</h2>
<Card className="w-100 sm:w-[31rem] p-2">
<h2 className="text-primary-500">Bridge Tokens with Hyperlane Warp Routes!</h2>
<div className="flex items-end justify-between">
<p className="mt-1 text-xs sm:text-sm max-w-[70%]">
<p className="mt-1 text-xs max-w-[75%]">
Warp Routes make it easy to permissionlessly take your tokens interchain. Fork this
template to get started!
</p>
@ -23,10 +23,10 @@ export function TipCard() {
href={links.github}
target="_blank"
rel="noopener noreferrer"
className="ml-2 px-3 py-1.5 flex items-center bg-gray-100 hover:bg-gray-200 active:bg-gray-300 text-xs sm:text-sm text-blue-500 rounded-full transition-all"
className="ml-2 px-3 py-1.5 flex items-center bg-gray-100 hover:bg-gray-200 active:bg-gray-300 text-xs sm:text-sm text-primary-500 rounded-lg transition-all"
>
<Image src={InfoCircle} width={16} alt="" />
<span className="ml-1.5">Learn More</span>
<Image src={InfoCircle} width={12} alt="" />
<span className="hidden sm:inline ml-1.5 text-sm">More</span>
</a>
</div>
<div className="absolute right-3 top-3">

@ -1,5 +1,17 @@
import { Space_Grotesk } from 'next/font/google';
import { Color } from '../styles/Color';
export const MAIN_FONT = Space_Grotesk({
subsets: ['latin'],
variable: '--font-main',
preload: true,
fallback: ['sans-serif'],
});
export const APP_NAME = 'Hyperlane Renzo Bridge';
export const APP_DESCRIPTION = 'A DApp for ezETH transfers';
export const APP_DESCRIPTION = 'A token bridge for ezETH transfers, created by Hyperlane';
export const APP_URL = 'renzo.hyperlane.xyz';
export const APP_BRAND_COLOR = '#C4FF61';
export const BRAND_COLOR = Color.primary;
export const BACKGROUND_COLOR = Color.primary;
export const BACKGROUND_IMAGE = 'url(/backgrounds/main.svg)';
export const PROXY_DEPLOYED_URL = 'https://proxy.hyperlane.xyz';

@ -12,31 +12,31 @@ const transferBlacklist = process?.env?.NEXT_PUBLIC_TRANSFER_BLACKLIST || '';
const chainWalletWhitelists = JSON.parse(process?.env?.NEXT_PUBLIC_CHAIN_WALLET_WHITELISTS || '{}');
interface Config {
addressBlacklist: string[]; // A list of addresses that are blacklisted and cannot be used in the app
chainWalletWhitelists: ChainMap<string[]>; // A map of chain names to a list of wallet names that work for it
enableExplorerLink: boolean; // Include a link to the hyperlane explorer in the transfer modal
explorerApiKeys: Record<string, string>; // Optional map of API keys for block explorer
isDevMode: boolean; // Enables some debug features in the app
version: string; // Matches version number in package.json
registryUrl: string | undefined; // Optional URL to use a custom registry instead of the published canonical version
explorerApiKeys: Record<string, string>; // Optional map of API keys for block explorer
showTipBox: boolean; // Show/Hide the blue tip box above the transfer form
showDisabledTokens: boolean; // Show/Hide invalid token options in the selection modal
showTipBox: boolean; // Show/Hide the blue tip box above the transfer form
transferBlacklist: string; // comma-separated list of routes between which transfers are disabled. Expects Caip2Id-Caip2Id (e.g. ethereum:1-sealevel:1399811149)
version: string; // Matches version number in package.json
walletConnectProjectId: string; // Project ID provided by walletconnect
withdrawalWhitelist: string; // comma-separated list of CAIP2 chain IDs to which transfers are supported
transferBlacklist: string; // comma-separated list of routes between which transfers are disabled. Expects Caip2Id-Caip2Id (e.g. ethereum:1-sealevel:1399811149)
enableExplorerLink: boolean; // Include a link to the hyperlane explorer in the transfer modal
addressBlacklist: string[]; // A list of addresses that are blacklisted and cannot be used in the app
chainWalletWhitelists: ChainMap<string[]>; // A map of chain names to a list of wallet names that work for it
}
export const config: Config = Object.freeze({
addressBlacklist: ADDRESS_BLACKLIST.map((address) => address.toLowerCase()),
chainWalletWhitelists,
enableExplorerLink: true,
explorerApiKeys,
isDevMode,
version,
registryUrl,
explorerApiKeys,
showTipBox: false,
showDisabledTokens: true,
showTipBox: false,
version,
transferBlacklist,
walletConnectProjectId,
withdrawalWhitelist,
transferBlacklist,
enableExplorerLink: true,
addressBlacklist: ADDRESS_BLACKLIST.map((address) => address.toLowerCase()),
chainWalletWhitelists,
});

@ -8,5 +8,4 @@ export const links = {
chains: 'https://docs.hyperlane.xyz/docs/resources/domains',
twitter: 'https://twitter.com/hyperlane',
blog: 'https://medium.com/hyperlane',
terms: 'https://hyperlane.xyz/tos',
};

@ -31,7 +31,7 @@ export function WarpContext({ children }: PropsWithChildren<unknown>) {
if (isLoading || !warpContext)
return (
<div className="flex items-center justify-center h-screen bg-blue-500">
<div className="flex items-center justify-center h-screen bg-primary-500">
<Spinner classes="opacity-50" white />
</div>
);

@ -37,24 +37,23 @@ export function ChainSelectField({ name, label, chains, onChange, disabled }: Pr
};
return (
<div className="flex flex-col items-center">
<div className="flex flex-col items-center justify-center rounded-full bg-gray-100 h-[5.5rem] w-[5.5rem] p-1.5">
<div className="flex items-end h-11">
<ChainLogo chainName={field.value} size={34} />
</div>
<label htmlFor={name} className="mt-2 mb-1 text-sm text-gray-500 uppercase">
{label}
</label>
</div>
<div className="flex-[4]">
<button
type="button"
name={field.name}
className={`${styles.base} ${disabled ? styles.disabled : styles.enabled}`}
onClick={onClick}
>
<div className="flex items-center">
<ChainLogo chainName={field.value} size={14} />
<span className="ml-2">{getChainDisplayName(field.value, true)}</span>
<div className="flex items-center gap-3">
<div className="max-w-[1.4rem] sm:max-w-fit">
<ChainLogo chainName={field.value} size={32} />
</div>
<div className="flex flex-col gap-1 items-start">
<label htmlFor={name} className="text-xs text-gray-600">
{label}
</label>
{getChainDisplayName(field.value, true)}
</div>
</div>
<Image src={ChevronIcon} width={12} height={8} alt="" />
</button>
@ -69,7 +68,7 @@ export function ChainSelectField({ name, label, chains, onChange, disabled }: Pr
}
const styles = {
base: 'w-36 px-2.5 py-2 relative -top-1.5 flex items-center justify-between text-sm bg-white rounded-full border border-blue-300 outline-none transition-colors duration-500',
enabled: 'hover:bg-gray-50 active:bg-gray-100 focus:border-blue-500',
base: 'px-2 py-1.5 w-full flex items-center justify-between text-sm bg-white rounded-lg border border-primary-300 outline-none transition-colors duration-500',
enabled: 'hover:bg-gray-100 active:scale-95 focus:border-primary-500',
disabled: 'bg-gray-150 cursor-default',
};

@ -1,3 +1,5 @@
import { useMemo } from 'react';
import { ChainLogo } from '../../components/icons/ChainLogo';
import { Modal } from '../../components/layout/Modal';
@ -21,10 +23,12 @@ export function ChainSelectListModal({
};
};
const sortedChains = useMemo(() => chains.sort(), [chains]);
return (
<Modal isOpen={isOpen} title="Select Chain" close={close}>
<div className="mt-2 flex flex-col space-y-1">
{chains.map((c) => (
{sortedChains.map((c) => (
<button
key={c}
className="py-1.5 px-2 text-sm flex items-center rounded hover:bg-gray-100 active:bg-gray-200 transition-all duration-200"

@ -100,6 +100,6 @@ export function SelectTokenIdModal({
const styles = {
base: 'mt-1.5 w-full px-2.5 py-2 flex items-center justify-between text-sm bg-white rounded border border-gray-400 outline-none transition-colors duration-500',
enabled: 'hover:bg-gray-50 active:bg-gray-100 focus:border-blue-500',
enabled: 'hover:bg-gray-50 active:bg-gray-100 focus:border-primary-500',
disabled: 'bg-gray-150 cursor-default',
};

@ -105,7 +105,7 @@ function TokenButton({
}
const styles = {
base: 'mt-1.5 w-full px-2.5 py-2 flex items-center justify-between text-sm rounded-full border border-blue-300 outline-none transition-colors duration-500',
enabled: 'hover:bg-gray-50 active:bg-gray-100 focus:border-blue-500',
base: 'mt-1.5 w-full px-2.5 py-2.5 flex items-center justify-between text-sm rounded-lg border border-primary-300 outline-none transition-colors duration-500',
enabled: 'hover:bg-gray-100 active:scale-95 focus:border-primary-500',
disabled: 'bg-gray-100 cursor-default',
};

@ -1,25 +1,11 @@
import { WideChevron } from '@hyperlane-xyz/widgets';
import { Card } from '../../components/layout/Card';
import { Color } from '../../styles/Color';
import { TransferTokenForm } from './TransferTokenForm';
export function TransferTokenCard() {
return (
<Card className="w-100 sm:w-[31rem]">
<>
<div className="absolute left-0 right-0 -top-36 xs:-top-[6.5rem] flex justify-center overflow-hidden z-10">
<WideChevron
direction="s"
height="100%"
width="100"
rounded={true}
color={Color.primaryBlue}
/>
</div>
<TransferTokenForm />
</>
</Card>
);
}

@ -11,7 +11,6 @@ import { ConnectAwareSubmitButton } from '../../components/buttons/ConnectAwareS
import { IconButton } from '../../components/buttons/IconButton';
import { SolidButton } from '../../components/buttons/SolidButton';
import { ChevronIcon } from '../../components/icons/Chevron';
import { WideChevron } from '../../components/icons/WideChevron';
import { TextField } from '../../components/input/TextField';
import { getIndexForToken, getTokenByIndex, getTokens, getWarpCore } from '../../context/context';
import SwapIcon from '../../images/icons/swap.svg';
@ -67,7 +66,7 @@ export function TransferTokenForm() {
<Form className="flex flex-col items-stretch w-full">
<ChainWalletWarning originChain={values.origin} />
<ChainSelectSection isReview={isReview} />
<div className="mt-3 flex justify-between items-end space-x-4">
<div className="mt-3.5 flex justify-between items-end space-x-4">
<TokenSection setIsNft={setIsNft} isReview={isReview} />
<AmountSection isNft={isNft} isReview={isReview} />
</div>
@ -100,8 +99,8 @@ function SwapChainsButton({ disabled }: { disabled?: boolean }) {
return (
<IconButton
imgSrc={SwapIcon}
width={22}
height={22}
width={20}
height={20}
title="Swap chains"
classes={!disabled ? 'hover:rotate-180' : undefined}
onClick={onClick}
@ -114,14 +113,9 @@ function ChainSelectSection({ isReview }: { isReview: boolean }) {
const chains = useMemo(() => getWarpCore().getTokenChains(), []);
return (
<div className="mt-2 flex items-center justify-center space-x-7 sm:space-x-10">
<div className="mt-4 flex items-center justify-between gap-4">
<ChainSelectField name="origin" label="From" chains={chains} disabled={isReview} />
<div className="flex flex-col items-center">
<div className="flex mb-6 sm:space-x-1.5">
<WideChevron classes="hidden sm:block" />
<WideChevron />
<WideChevron />
</div>
<div className="flex flex-col items-center flex-1">
<SwapChainsButton disabled={isReview} />
</div>
<ChainSelectField name="destination" label="To" chains={chains} disabled={isReview} />
@ -138,7 +132,7 @@ function TokenSection({
}) {
return (
<div className="flex-1">
<label htmlFor="tokenIndex" className="block uppercase text-sm text-gray-500 pl-0.5">
<label htmlFor="tokenIndex" className="block text-sm text-gray-600 pl-0.5">
Token
</label>
<TokenSelectField name="tokenIndex" disabled={isReview} setIsNft={setIsNft} />
@ -153,7 +147,7 @@ function AmountSection({ isNft, isReview }: { isNft: boolean; isReview: boolean
return (
<div className="flex-1">
<div className="flex justify-between pr-1">
<label htmlFor="amount" className="block uppercase text-sm text-gray-500 pl-0.5">
<label htmlFor="amount" className="block text-sm text-gray-600 pl-0.5">
Amount
</label>
<TokenBalance label="My balance" balance={balance} />
@ -185,8 +179,8 @@ function RecipientSection({ isReview }: { isReview: boolean }) {
return (
<div className="mt-4">
<div className="flex justify-between pr-1">
<label htmlFor="recipient" className="block uppercase text-sm text-gray-500 pl-0.5">
Recipient Address
<label htmlFor="recipient" className="block text-sm text-gray-600 pl-0.5">
Recipient address
</label>
<TokenBalance label="Remote balance" balance={balance} />
</div>
@ -205,7 +199,7 @@ function RecipientSection({ isReview }: { isReview: boolean }) {
function TokenBalance({ label, balance }: { label: string; balance?: TokenAmount | null }) {
const value = balance?.getDecimalFormattedAmount().toFixed(4) || '0';
return <div className="text-xs text-gray-500 text-right">{`${label}: ${value}`}</div>;
return <div className="text-xs text-gray-600 text-right">{`${label}: ${value}`}</div>;
}
function ButtonSection({
@ -235,6 +229,7 @@ function ButtonSection({
if (isSanctioned) {
return;
}
setIsReview(false);
setTransferLoading(true);
await triggerTransactions(values);
};
@ -253,16 +248,16 @@ function ButtonSection({
<div className="mt-4 flex items-center justify-between space-x-4">
<SolidButton
type="button"
color="gray"
color="primary"
onClick={() => setIsReview(false)}
classes="px-6 py-1.5"
icon={<ChevronIcon direction="w" width={10} height={6} color={Color.primaryBlue} />}
icon={<ChevronIcon direction="w" width={10} height={6} color={Color.white} />}
>
<span>Edit</span>
</SolidButton>
<SolidButton
type="button"
color="pink"
color="accent"
onClick={triggerTransactionsHandler}
classes="flex-1 px-3 py-1.5"
>
@ -291,16 +286,16 @@ function MaxButton({ balance, disabled }: { balance?: TokenAmount; disabled?: bo
<SolidButton
type="button"
onClick={onClick}
color="gray"
color="primary"
disabled={disabled}
classes="text-xs absolute right-0.5 top-2 bottom-0.5 px-2"
classes="text-xs absolute right-1 top-2.5 bottom-1 px-2 opacity-90 all:rounded"
>
{isLoading ? (
<div className="flex items-center">
<SmallSpinner />
<SmallSpinner className="text-white" />
</div>
) : (
'MAX'
'Max'
)}
</SolidButton>
);
@ -323,11 +318,11 @@ function SelfButton({ disabled }: { disabled?: boolean }) {
<SolidButton
type="button"
onClick={onClick}
color="gray"
color="primary"
disabled={disabled}
classes="text-xs absolute right-0.5 top-2 bottom-0.5 px-2"
classes="text-xs absolute right-1 top-2.5 bottom-1 px-2 opacity-90 all:rounded"
>
SELF
Self
</SolidButton>
);
}
@ -358,7 +353,7 @@ function ReviewDetails({ visible }: { visible: boolean }) {
visible ? 'max-h-screen duration-1000 ease-in' : 'max-h-0 duration-500'
} overflow-hidden transition-all`}
>
<label className="mt-4 block uppercase text-sm text-gray-500 pl-0.5">Transactions</label>
<label className="mt-4 block text-sm text-gray-600 pl-0.5">Transactions</label>
<div className="mt-1.5 px-2.5 py-2 space-y-2 rounded border border-gray-400 bg-gray-150 text-sm break-all">
{isLoading ? (
<div className="py-6 flex items-center justify-center">
@ -382,17 +377,17 @@ function ReviewDetails({ visible }: { visible: boolean }) {
<div className="mt-1.5 ml-1.5 pl-2 border-l border-gray-300 space-y-1.5 text-xs">
{destinationToken?.addressOrDenom && (
<p className="flex">
<span className="min-w-[7rem]">Remote Token</span>
<span className="min-w-[6.5rem]">Remote Token</span>
<span>{destinationToken.addressOrDenom}</span>
</p>
)}
<p className="flex">
<span className="min-w-[7rem]">{isNft ? 'Token ID' : 'Amount'}</span>
<span className="min-w-[6.5rem]">{isNft ? 'Token ID' : 'Amount'}</span>
<span>{`${amount} ${originTokenSymbol}`}</span>
</p>
{fees?.localQuote && fees.localQuote.amount > 0n && (
<p className="flex">
<span className="min-w-[7rem]">Local Gas (est.)</span>
<span className="min-w-[6.5rem]">Local Gas (est.)</span>
<span>{`${fees.localQuote.getDecimalFormattedAmount().toFixed(4) || '0'} ${
fees.localQuote.token.symbol || ''
}`}</span>
@ -400,7 +395,7 @@ function ReviewDetails({ visible }: { visible: boolean }) {
)}
{fees?.interchainQuote && fees.interchainQuote.amount > 0n && (
<p className="flex">
<span className="min-w-[7rem]">Interchain Gas</span>
<span className="min-w-[6.5rem]">Interchain Gas</span>
<span>{`${fees.interchainQuote.getDecimalFormattedAmount().toFixed(4) || '0'} ${
fees.interchainQuote.token.symbol || ''
}`}</span>

@ -120,7 +120,7 @@ export function TransfersDetailsModal({
<h2 className="text-gray-600 font-medium">{date}</h2>
<div className="flex items-center font-medium">
{isSent ? (
<h3 className="text-blue-500">Sent</h3>
<h3 className="text-primary-500">Sent</h3>
) : (
<h3 className="text-red-500">Failed</h3>
)}
@ -135,7 +135,7 @@ export function TransfersDetailsModal({
</div>
)}
<div className="mt-4 p-3 flex items-center justify-center w-full rounded-full bg-blue-200">
<div className="mt-4 p-3 flex items-center justify-center w-full rounded-full bg-primary-200">
<TokenIcon token={token} size={30} />
<div className="ml-2 flex items items-baseline">
<span className="text-xl font-medium">{amount}</span>
@ -203,8 +203,9 @@ export function TransfersDetailsModal({
{statusDescription}
</div>
{showSignWarning && (
<div className="mt-3 text-sm text-center text-pink-600 font-medium">
If your wallet does not show a transaction request, please try the transfer again.
<div className="mt-3 text-sm text-center text-gray-600">
If your wallet does not show a transaction request or never confirms, please try the
transfer again.
</div>
)}
</div>
@ -265,7 +266,8 @@ function TransferProperty({ name, value, url }: { name: string; value: string; u
function useSignIssueWarning(status: TransferStatus) {
const [showWarning, setShowWarning] = useState(false);
const warningCallback = useCallback(() => {
if (status === TransferStatus.SigningTransfer) setShowWarning(true);
if (status === TransferStatus.SigningTransfer || status === TransferStatus.ConfirmingTransfer)
setShowWarning(true);
}, [status, setShowWarning]);
useTimeout(warningCallback, 20_000);
return showWarning;

@ -7,6 +7,7 @@ import { toTitleCase, toWei } from '@hyperlane-xyz/utils';
import { toastTxSuccess } from '../../components/toast/TxSuccessToast';
import { getTokenByIndex, getWarpCore } from '../../context/context';
import { logger } from '../../utils/logger';
import { getChainDisplayName } from '../chains/utils';
import { AppState, useStore } from '../store';
import {
getAccountAddressForChain,
@ -18,6 +19,10 @@ import {
import { TransferContext, TransferFormValues, TransferStatus } from './types';
import { tryGetMsgIdFromTransferReceipt } from './utils';
const CHAIN_MISMATCH_ERROR = 'ChainMismatchError';
const TRANSFER_TIMEOUT_ERROR1 = 'block height exceeded';
const TRANSFER_TIMEOUT_ERROR2 = 'timeout';
export function useTokenTransfer(onDone?: () => void) {
const { transfers, addTransfer, updateTransferStatus } = useStore((s) => ({
transfers: s.transfers,
@ -90,8 +95,8 @@ async function executeTransfer({
let transferStatus: TransferStatus = TransferStatus.Preparing;
updateTransferStatus(transferIndex, transferStatus);
try {
const { origin, destination, tokenIndex, amount, recipient } = values;
try {
const originToken = getTokenByIndex(tokenIndex);
const connection = originToken?.getConnectionForChain(destination);
if (!originToken || !connection) throw new Error('No token route found between chains');
@ -152,12 +157,20 @@ async function executeTransfer({
originTxHash: hashes.at(-1),
msgId,
});
} catch (error) {
} catch (error: any) {
logger.error(`Error at stage ${transferStatus}`, error);
const errorDetails = error.message || error.toString();
updateTransferStatus(transferIndex, TransferStatus.Failed);
if (JSON.stringify(error).includes('ChainMismatchError')) {
if (errorDetails.includes(CHAIN_MISMATCH_ERROR)) {
// Wagmi switchNetwork call helps prevent this but isn't foolproof
toast.error('Wallet must be connected to origin chain');
} else if (
errorDetails.includes(TRANSFER_TIMEOUT_ERROR1) ||
errorDetails.includes(TRANSFER_TIMEOUT_ERROR2)
) {
toast.error(
`Transaction timed out, ${getChainDisplayName(origin)} may be busy. Please try again.`,
);
} else {
toast.error(errorMessages[transferStatus] || 'Unable to transfer tokens.');
}

@ -83,27 +83,27 @@ export function SideBarMenu({
</button>
)}
<div className="w-full h-full flex flex-col overflow-y-auto">
<div className="w-full rounded-t-md bg-blue-500 py-2 px-3.5 text-white text-base font-normal tracking-wider">
<div className="w-full rounded-t-md bg-primary-500 py-2 px-3.5 text-white text-base font-normal tracking-wider">
Connected Wallets
</div>
<div className="my-3 px-3 space-y-3">
<div className="my-3 px-3 space-y-2">
{readyAccounts.map((acc, i) => (
<AccountSummary key={i} account={acc} />
))}
<button onClick={onConnectWallet} className={styles.btn}>
<button onClick={onConnectWallet} className={`${styles.btn} pl-2.5`}>
<Icon src={Wallet} alt="" size={18} />
<div className="ml-2">Connect wallet</div>
</button>
<button onClick={onClickDisconnect} className={styles.btn}>
<button onClick={onClickDisconnect} className={`${styles.btn} pl-2.5`}>
<Icon src={Logout} alt="" size={20} />
<div className="ml-2">Disconnect all wallets</div>
</button>
</div>
<div className="w-full bg-blue-500 py-2 px-3.5 mb-4 text-white text-base font-normal tracking-wider">
<div className="w-full bg-primary-500 py-2 px-3.5 mb-4 text-white text-base font-normal tracking-wider">
Transfer History
</div>
<div className="flex grow flex-col px-3.5">
<div className="grow flex flex-col w-full">
<div className="grow flex flex-col w-full divide-y">
{sortedTransfers?.length > 0 &&
sortedTransfers.map((t, i) => (
<TransferSummary
@ -117,7 +117,7 @@ export function SideBarMenu({
))}
</div>
{sortedTransfers?.length > 0 && (
<button onClick={resetTransfers} className="my-5 mx-2 flex flex-row items-center">
<button onClick={resetTransfers} className={`${styles.btn} my-5 mx-2`}>
<Image className="mr-4" src={ResetIcon} width={17} height={17} alt="" />
<span className="text-gray-900 text-sm font-normal">Reset transaction history</span>
</button>
@ -154,9 +154,7 @@ function AccountSummary({ account }: { account: AccountInfo }) {
return (
<button
onClick={onClickCopy}
className={`${styles.btn} border border-gray-200 rounded-xl ${
numAddresses > 1 && 'cursor-default'
}`}
className={`${styles.btn} ${numAddresses > 1 && 'all:cursor-default'}`}
>
<div className="shrink-0">
<WalletLogo walletDetails={walletDetails} size={42} />
@ -182,13 +180,9 @@ function TransferSummary({
const token = tryFindToken(origin, originTokenAddressOrDenom);
return (
<button
key={timestamp}
onClick={onClick}
className="flex justify-between items-center rounded-xl border border-gray-200 px-2.5 py-2 mb-2.5 hover:bg-gray-200 active:bg-gray-300 transition-all duration-500"
>
<div className="flex">
<div className="mr-2.5 flex flex-col items-center justify-center rounded-full bg-gray-100 h-[2.25rem] w-[2.25rem] p-1.5">
<button key={timestamp} onClick={onClick} className={`${styles.btn} justify-between py-3`}>
<div className="flex gap-2.5">
<div className="px-1.5 flex flex-col items-center justify-center rounded-full bg-gray-100 h-[2.25rem] w-[2.25rem]">
<ChainLogo chainName={origin} size={20} />
</div>
<div className="flex flex-col">
@ -198,18 +192,18 @@ function TransferSummary({
<span className="text-gray-800 text-sm font-normal ml-1">{token?.symbol || ''}</span>
</div>
<div className="mt-1 flex flex-row items-center">
<span className="text-thin text-gray-900 font-normal tracking-wide">
<span className="text-xxs text-gray-900 font-normal tracking-wide">
{getChainDisplayName(origin, true)}
</span>
<Image className="mx-1" src={ArrowRightIcon} width={10} height={10} alt="" />
<span className="text-thin text-gray-900 font-normal tracking-wide">
<span className="text-xxs text-gray-900 font-normal tracking-wide">
{getChainDisplayName(destination, true)}
</span>
</div>
</div>
</div>
</div>
<div className="flex w-6 h-6">
<div className="flex w-5 h-5">
{STATUSES_WITH_ICON.includes(status) ? (
<Image src={getIconByTransferStatus(status)} width={25} height={25} alt="" />
) : (
@ -239,5 +233,5 @@ function Icon({
}
const styles = {
btn: 'w-full flex items-center px-2.5 py-2 text-sm hover:bg-gray-200 active:bg-gray-300 rounded transition-all duration-500',
btn: 'w-full flex items-center px-1 py-2 text-sm hover:bg-gray-200 active:scale-95 transition-all duration-500 cursor-pointer rounded-sm',
};

@ -41,7 +41,7 @@ export function WalletControlBar() {
icon={<Image src={Wallet} alt="" width={16} height={16} />}
color="white"
>
<div className="ml-1.5 text-xs sm:text-sm">Connect Wallet</div>
<div className="ml-1.5 text-xs sm:text-sm">Connect wallet</div>
</SolidButton>
)}
@ -66,7 +66,7 @@ export function WalletControlBar() {
<div className="flex items-center justify-center">
<div
style={{ height: 26, width: 26 }}
className="bg-pink-500 text-white flex items-center justify-center rounded-full"
className="bg-accent-500 text-white flex items-center justify-center rounded-full"
>
{numReady}
</div>

@ -70,7 +70,7 @@ function EnvButton({
className="w-full py-3.5 space-y-2.5 flex flex-col items-center rounded-lg border border-gray-200 hover:bg-gray-100 hover:border-gray-200 active:bg-gray-200 transition-all"
>
{logo}
<div className="uppercase text-gray-800 tracking-wide">{children}</div>
<div className="text-gray-800 tracking-wide">{children}</div>
<div className="text-sm text-gray-500">{`Connect to ${subTitle} compatible wallet`}</div>
</button>
);

@ -79,7 +79,7 @@ export function EvmWalletContext({ children }: PropsWithChildren<unknown>) {
<RainbowKitProvider
chains={chains}
theme={lightTheme({
accentColor: Color.primaryBlue,
accentColor: Color.primary,
borderRadius: 'small',
fontStack: 'system',
})}

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="10 0 1430 135.87"><defs><style>.cls-1{stroke-width:8px;}.cls-1,.cls-2{fill:none;stroke:#fff;}.cls-3{fill:#d631b9;}.cls-2{stroke-width:4px;}</style></defs><path class="cls-3" d="m3.23,20.37l83.5,24.75,127.5,27.5,140.5,23,190,19.5,185,6.75h119l111.5-4,145-10.25,139-15.5,137-21.75,61.98-12.2v77.69H3.23V20.37Z"/><path class="cls-2" d="m1449.18,1.9c-28.89,9.34-56.79,16.73-56.79,16.73C859.76,144.83,458.49,146.53,5.87,20.51"/><path class="cls-1" d="m1449.99,56.89c-2.24.46-4.47.92-6.71,1.37C911.32,166.5,318.58,125.03,1.27,18.54"/></svg>

Before

Width:  |  Height:  |  Size: 583 B

@ -1,4 +0,0 @@
<svg width="886" height="114" viewBox="0 0 886 114" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M783.5 -3.5C621.953 133.053 158.722 87.2984 8 -3.5" stroke="white" stroke-width="2"/>
<path d="M884.5 -5.5C586 201.5 152.904 88.164 2 -5.5" stroke="white" stroke-width="4"/>
</svg>

Before

Width:  |  Height:  |  Size: 290 B

@ -1,5 +1,5 @@
<svg width="492" height="494" viewBox="0 0 492 494" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M270.652 0H371.119C384.826 0 397.089 7.95912 401.874 19.9606L490.058 241.148C490.739 242.854 490.747 244.731 490.081 246.443L489.587 247.714L489.582 247.726L401.769 473.524C397.054 485.646 384.726 493.716 370.923 493.716H270.471C264.822 493.716 260.862 488.506 262.724 483.523L353.271 241.148L262.946 10.2988C260.989 5.29678 264.952 0 270.652 0Z" fill="black"/>
<path d="M8.39276 0H108.86C122.567 0 134.83 7.95912 139.614 19.9606L227.799 241.148C228.479 242.854 228.487 244.731 227.822 246.443L227.327 247.714L227.322 247.726L139.509 473.524C134.795 485.646 122.467 493.716 108.664 493.716H8.2115C2.56253 493.716 -1.39662 488.506 0.465105 483.523L91.0122 241.148L0.686825 10.2988C-1.27034 5.29678 2.69291 0 8.39276 0Z" fill="black"/>
<path d="M338.826 194H197V301H338.826L362 245.971L338.826 194Z" fill="black"/>
<path d="M270.652 0H371.119C384.826 0 397.089 7.95912 401.874 19.9606L490.058 241.148C490.739 242.854 490.747 244.731 490.081 246.443L489.587 247.714L489.582 247.726L401.769 473.524C397.054 485.646 384.726 493.716 370.923 493.716H270.471C264.822 493.716 260.862 488.506 262.724 483.523L353.271 241.148L262.946 10.2988C260.989 5.29678 264.952 0 270.652 0Z" fill="white"/>
<path d="M8.39276 0H108.86C122.567 0 134.83 7.95912 139.614 19.9606L227.799 241.148C228.479 242.854 228.487 244.731 227.822 246.443L227.327 247.714L227.322 247.726L139.509 473.524C134.795 485.646 122.467 493.716 108.664 493.716H8.2115C2.56253 493.716 -1.39662 488.506 0.465105 483.523L91.0122 241.148L0.686825 10.2988C-1.27034 5.29678 2.69291 0 8.39276 0Z" fill="white"/>
<path d="M338.826 194H197V301H338.826L362 245.971L338.826 194Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 929 B

After

Width:  |  Height:  |  Size: 929 B

@ -1,11 +1,11 @@
<svg width="1325" height="266" viewBox="0 0 1325 266" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.5 215V0.5H44V84.5H128.3V0.5H171.8V215H128.3V120.5H44V215H0.5Z" fill="black"/>
<path d="M204.699 265.4V233.3H219.099C234.299 233.3 241.899 226.3 241.899 212.3C241.899 205.5 237.999 191.6 230.199 170.6L188.799 61.1H231.699L254.499 130.4L264.399 164H264.999C267.799 151 270.799 139.8 273.999 130.4L295.599 61.1H336.699L282.999 218.9C276.999 236.5 270.199 248.6 262.599 255.2C255.199 262 243.899 265.4 228.699 265.4H204.699Z" fill="black"/>
<path d="M350.52 265.4V61.1H389.82V80.3H390.72C402.12 64.7 417.22 56.9 436.02 56.9C456.22 56.9 472.42 64.4 484.62 79.4C496.82 94.4 502.92 114 502.92 138.2C502.92 163 496.82 182.8 484.62 197.6C472.42 212.2 456.32 219.5 436.32 219.5C416.32 219.5 401.52 212.2 391.92 197.6H391.32V265.4H350.52ZM427.62 185.6C438.02 185.6 446.22 181.5 452.22 173.3C458.42 165.1 461.52 153.8 461.52 139.4C461.52 124 458.62 111.9 452.82 103.1C447.02 94.3 438.12 89.9 426.12 89.9C413.92 89.9 404.92 94.5 399.12 103.7C393.32 112.7 390.42 124.6 390.42 139.4C390.42 153.6 393.62 164.9 400.02 173.3C406.42 181.5 415.62 185.6 427.62 185.6Z" fill="black"/>
<path d="M594.207 219.5C569.407 219.5 549.907 211.9 535.707 196.7C521.507 181.3 514.407 161.7 514.407 137.9C514.407 114.9 521.507 95.7 535.707 80.3C549.907 64.7 568.107 56.9 590.307 56.9C614.507 56.9 633.207 65.3 646.407 82.1C659.607 98.9 666.207 121.4 666.207 149.6H554.607C556.207 161.8 560.307 171.3 566.907 178.1C573.507 184.7 582.507 188 593.907 188C608.907 188 618.807 181.7 623.607 169.1H663.807C660.807 183.5 653.207 195.5 641.007 205.1C628.807 214.7 613.207 219.5 594.207 219.5ZM590.907 88.4C571.107 88.4 559.207 99.4 555.207 121.4H623.607C623.007 111.6 619.707 103.7 613.707 97.7C607.707 91.5 600.107 88.4 590.907 88.4Z" fill="black"/>
<path d="M724.391 61.1V85.7H725.291C730.091 76.7 735.391 70.1 741.191 65.9C746.991 61.5 754.291 59.3 763.091 59.3C767.291 59.3 770.491 59.7 772.691 60.5V96.2H771.791C757.991 94.8 746.891 97.8 738.491 105.2C730.091 112.6 725.891 124.2 725.891 140V215H685.091V61.1H724.391Z" fill="black"/>
<path d="M790.866 215V0.5H831.666V215H790.866Z" fill="black"/>
<path d="M955.428 215C953.428 212.4 951.828 206.7 950.628 197.9H950.028C945.628 204.5 940.028 209.6 933.228 213.2C926.428 216.8 916.928 218.6 904.728 218.6C888.528 218.6 875.528 214.5 865.728 206.3C855.928 198.1 851.028 186.5 851.028 171.5C851.028 155.9 856.428 144.5 867.228 137.3C878.028 129.9 893.228 124.8 912.828 122C927.228 120 937.028 118 942.228 116C947.428 113.8 950.028 110 950.028 104.6C950.028 99 947.828 94.6 943.428 91.4C939.028 88 932.628 86.3 924.228 86.3C905.628 86.3 895.728 93.5 894.528 107.9H858.228C858.828 93.3 864.728 81.2 875.928 71.6C887.128 62 903.328 57.2 924.528 57.2C967.728 57.2 989.328 76.1 989.328 113.9V192.2C989.328 203.8 991.128 210.9 994.728 213.5V215H955.428ZM914.628 190.1C925.828 190.1 934.628 187.2 941.028 181.4C947.628 175.6 950.928 168.7 950.928 160.7V137.6C946.528 140.2 937.028 143.2 922.428 146.6C910.828 149.2 902.628 152.2 897.828 155.6C893.028 158.8 890.628 163.8 890.628 170.6C890.628 183.6 898.628 190.1 914.628 190.1Z" fill="black"/>
<path d="M1055.17 61.1V82.1H1056.07C1066.67 65.3 1081.87 56.9 1101.67 56.9C1117.47 56.9 1130.27 62.3 1140.07 73.1C1149.87 83.7 1154.77 97.5 1154.77 114.5V215H1113.97V120.5C1113.97 112.1 1111.57 105.3 1106.77 100.1C1102.17 94.9 1095.67 92.3 1087.27 92.3C1078.27 92.3 1070.77 95.6 1064.77 102.2C1058.97 108.8 1056.07 117.3 1056.07 127.7V215H1015.27V61.1H1055.17Z" fill="black"/>
<path d="M1252.21 219.5C1227.41 219.5 1207.91 211.9 1193.71 196.7C1179.51 181.3 1172.41 161.7 1172.41 137.9C1172.41 114.9 1179.51 95.7 1193.71 80.3C1207.91 64.7 1226.11 56.9 1248.31 56.9C1272.51 56.9 1291.21 65.3 1304.41 82.1C1317.61 98.9 1324.21 121.4 1324.21 149.6H1212.61C1214.21 161.8 1218.31 171.3 1224.91 178.1C1231.51 184.7 1240.51 188 1251.91 188C1266.91 188 1276.81 181.7 1281.61 169.1H1321.81C1318.81 183.5 1311.21 195.5 1299.01 205.1C1286.81 214.7 1271.21 219.5 1252.21 219.5ZM1248.91 88.4C1229.11 88.4 1217.21 99.4 1213.21 121.4H1281.61C1281.01 111.6 1277.71 103.7 1271.71 97.7C1265.71 91.5 1258.11 88.4 1248.91 88.4Z" fill="black"/>
<path d="M0.5 215V0.5H44V84.5H128.3V0.5H171.8V215H128.3V120.5H44V215H0.5Z" fill="white"/>
<path d="M204.699 265.4V233.3H219.099C234.299 233.3 241.899 226.3 241.899 212.3C241.899 205.5 237.999 191.6 230.199 170.6L188.799 61.1H231.699L254.499 130.4L264.399 164H264.999C267.799 151 270.799 139.8 273.999 130.4L295.599 61.1H336.699L282.999 218.9C276.999 236.5 270.199 248.6 262.599 255.2C255.199 262 243.899 265.4 228.699 265.4H204.699Z" fill="white"/>
<path d="M350.52 265.4V61.1H389.82V80.3H390.72C402.12 64.7 417.22 56.9 436.02 56.9C456.22 56.9 472.42 64.4 484.62 79.4C496.82 94.4 502.92 114 502.92 138.2C502.92 163 496.82 182.8 484.62 197.6C472.42 212.2 456.32 219.5 436.32 219.5C416.32 219.5 401.52 212.2 391.92 197.6H391.32V265.4H350.52ZM427.62 185.6C438.02 185.6 446.22 181.5 452.22 173.3C458.42 165.1 461.52 153.8 461.52 139.4C461.52 124 458.62 111.9 452.82 103.1C447.02 94.3 438.12 89.9 426.12 89.9C413.92 89.9 404.92 94.5 399.12 103.7C393.32 112.7 390.42 124.6 390.42 139.4C390.42 153.6 393.62 164.9 400.02 173.3C406.42 181.5 415.62 185.6 427.62 185.6Z" fill="white"/>
<path d="M594.207 219.5C569.407 219.5 549.907 211.9 535.707 196.7C521.507 181.3 514.407 161.7 514.407 137.9C514.407 114.9 521.507 95.7 535.707 80.3C549.907 64.7 568.107 56.9 590.307 56.9C614.507 56.9 633.207 65.3 646.407 82.1C659.607 98.9 666.207 121.4 666.207 149.6H554.607C556.207 161.8 560.307 171.3 566.907 178.1C573.507 184.7 582.507 188 593.907 188C608.907 188 618.807 181.7 623.607 169.1H663.807C660.807 183.5 653.207 195.5 641.007 205.1C628.807 214.7 613.207 219.5 594.207 219.5ZM590.907 88.4C571.107 88.4 559.207 99.4 555.207 121.4H623.607C623.007 111.6 619.707 103.7 613.707 97.7C607.707 91.5 600.107 88.4 590.907 88.4Z" fill="white"/>
<path d="M724.391 61.1V85.7H725.291C730.091 76.7 735.391 70.1 741.191 65.9C746.991 61.5 754.291 59.3 763.091 59.3C767.291 59.3 770.491 59.7 772.691 60.5V96.2H771.791C757.991 94.8 746.891 97.8 738.491 105.2C730.091 112.6 725.891 124.2 725.891 140V215H685.091V61.1H724.391Z" fill="white"/>
<path d="M790.866 215V0.5H831.666V215H790.866Z" fill="white"/>
<path d="M955.428 215C953.428 212.4 951.828 206.7 950.628 197.9H950.028C945.628 204.5 940.028 209.6 933.228 213.2C926.428 216.8 916.928 218.6 904.728 218.6C888.528 218.6 875.528 214.5 865.728 206.3C855.928 198.1 851.028 186.5 851.028 171.5C851.028 155.9 856.428 144.5 867.228 137.3C878.028 129.9 893.228 124.8 912.828 122C927.228 120 937.028 118 942.228 116C947.428 113.8 950.028 110 950.028 104.6C950.028 99 947.828 94.6 943.428 91.4C939.028 88 932.628 86.3 924.228 86.3C905.628 86.3 895.728 93.5 894.528 107.9H858.228C858.828 93.3 864.728 81.2 875.928 71.6C887.128 62 903.328 57.2 924.528 57.2C967.728 57.2 989.328 76.1 989.328 113.9V192.2C989.328 203.8 991.128 210.9 994.728 213.5V215H955.428ZM914.628 190.1C925.828 190.1 934.628 187.2 941.028 181.4C947.628 175.6 950.928 168.7 950.928 160.7V137.6C946.528 140.2 937.028 143.2 922.428 146.6C910.828 149.2 902.628 152.2 897.828 155.6C893.028 158.8 890.628 163.8 890.628 170.6C890.628 183.6 898.628 190.1 914.628 190.1Z" fill="white"/>
<path d="M1055.17 61.1V82.1H1056.07C1066.67 65.3 1081.87 56.9 1101.67 56.9C1117.47 56.9 1130.27 62.3 1140.07 73.1C1149.87 83.7 1154.77 97.5 1154.77 114.5V215H1113.97V120.5C1113.97 112.1 1111.57 105.3 1106.77 100.1C1102.17 94.9 1095.67 92.3 1087.27 92.3C1078.27 92.3 1070.77 95.6 1064.77 102.2C1058.97 108.8 1056.07 117.3 1056.07 127.7V215H1015.27V61.1H1055.17Z" fill="white"/>
<path d="M1252.21 219.5C1227.41 219.5 1207.91 211.9 1193.71 196.7C1179.51 181.3 1172.41 161.7 1172.41 137.9C1172.41 114.9 1179.51 95.7 1193.71 80.3C1207.91 64.7 1226.11 56.9 1248.31 56.9C1272.51 56.9 1291.21 65.3 1304.41 82.1C1317.61 98.9 1324.21 121.4 1324.21 149.6H1212.61C1214.21 161.8 1218.31 171.3 1224.91 178.1C1231.51 184.7 1240.51 188 1251.91 188C1266.91 188 1276.81 181.7 1281.61 169.1H1321.81C1318.81 183.5 1311.21 195.5 1299.01 205.1C1286.81 214.7 1271.21 219.5 1252.21 219.5ZM1248.91 88.4C1229.11 88.4 1217.21 99.4 1213.21 121.4H1281.61C1281.01 111.6 1277.71 103.7 1271.71 97.7C1265.71 91.5 1258.11 88.4 1248.91 88.4Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-github" viewBox="0 0 16 16">
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/>
</svg>

Before

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

@ -10,11 +10,11 @@ import '@hyperlane-xyz/widgets/styles.css';
import { ErrorBoundary } from '../components/errors/ErrorBoundary';
import { AppLayout } from '../components/layout/AppLayout';
import { MAIN_FONT } from '../consts/app';
import { WarpContext } from '../context/WarpContext';
import { CosmosWalletContext } from '../features/wallet/context/CosmosWalletContext';
import { EvmWalletContext } from '../features/wallet/context/EvmWalletContext';
import { SolanaWalletContext } from '../features/wallet/context/SolanaWalletContext';
import '../styles/fonts.css';
import '../styles/globals.css';
import { useIsSsr } from '../utils/ssr';
@ -34,7 +34,10 @@ export default function App({ Component, pageProps }: AppProps) {
return <div></div>;
}
// Note, the font definition is required both here and in _document.tsx
// Otherwise Next.js will not load the font
return (
<div className={`${MAIN_FONT.variable} font-sans text-black`}>
<ErrorBoundary>
<QueryClientProvider client={reactQueryClient}>
<WarpContext>
@ -56,5 +59,6 @@ export default function App({ Component, pageProps }: AppProps) {
</WarpContext>
</QueryClientProvider>
</ErrorBoundary>
</div>
);
}

@ -1,6 +1,6 @@
import { Head, Html, Main, NextScript } from 'next/document';
import { APP_BRAND_COLOR, APP_DESCRIPTION, APP_NAME, APP_URL } from '../consts/app';
import { APP_DESCRIPTION, APP_NAME, APP_URL, BRAND_COLOR, MAIN_FONT } from '../consts/app';
export default function Document() {
return (
@ -12,7 +12,7 @@ export default function Document() {
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="mask-icon" href="/safari-pinned-tab.svg" color={APP_BRAND_COLOR} />
<link rel="mask-icon" href="/safari-pinned-tab.svg" color={BRAND_COLOR} />
<link rel="shortcut icon" href="/favicon.png" />
<meta name="msapplication-TileColor" content="#ffffff" />
<meta name="theme-color" content="#ffffff" />
@ -31,7 +31,7 @@ export default function Document() {
<meta property="og:image" content={`${APP_URL}/logo.png`} />
<meta property="og:description" content={APP_DESCRIPTION} />
</Head>
<body className="text-black">
<body className={`${MAIN_FONT.variable} font-sans text-black`}>
<Main />
<NextScript />
</body>

@ -5,7 +5,7 @@ import { TransferTokenCard } from '../features/transfer/TransferTokenCard';
const Home: NextPage = () => {
return (
<div className="pt-4 sm:pt-8 space-y-3">
<div className="pt-4 space-y-3">
<TipCard />
<TransferTokenCard />
</div>

@ -1,27 +1,14 @@
// Should match tailwind.config.js
export enum Color {
primaryBlack = '#010101',
primaryWhite = '#FFFFFF',
primaryGray = '#6B7280',
lightGray = '#D0D4DB',
primaryBlue = '#C4FF61',
primaryPink = '#ACE732',
primaryBeige = '#F1EDE9',
primaryRed = '#BF1B15',
primaryMint = '#31D99C',
}
// @ts-ignore
import { theme } from '../../tailwind.config';
// Useful for cases when using class names isn't convenient
// such as in svg fills
export function classNameToColor(className) {
switch (className) {
case 'bg-blue-500':
return Color.primaryBlue;
case 'bg-red-500':
return Color.primaryRed;
case 'bg-gray-500':
return Color.primaryGray;
default:
throw new Error('Missing color for className: ' + className);
}
}
const themeColors = theme.extend.colors as unknown as Record<string, string>;
export const Color = {
black: themeColors.black,
white: themeColors.white,
gray: themeColors.gray[500],
lightGray: themeColors.gray[200],
primary: themeColors.primary[500],
accent: themeColors.accent[500],
red: themeColors.red[500],
} as const;

@ -1,39 +0,0 @@
@font-face {
font-family: 'Neue Haas Grotesk';
font-style: normal;
font-weight: 200;
src: url('/fonts/NeueHaasDisplayThin.woff2') format('woff2'),
url('/fonts/NeueHaasDisplayThin.woff') format('woff');
}
@font-face {
font-family: 'Neue Haas Grotesk';
font-style: normal;
font-weight: 300;
src: url('/fonts/NeueHaasDisplayLight.woff2') format('woff2'),
url('/fonts/NeueHaasDisplayLight.woff') format('woff');
}
@font-face {
font-family: 'Neue Haas Grotesk';
font-style: normal;
font-weight: 400;
src: url('/fonts/NeueHaasDisplayRoman.woff2') format('woff2'),
url('/fonts/NeueHaasDisplayRoman.woff') format('woff');
}
@font-face {
font-family: 'Neue Haas Grotesk';
font-style: normal;
font-weight: 500;
src: url('/fonts/NeueHaasDisplayMedium.woff2') format('woff2'),
url('/fonts/NeueHaasDisplayMedium.woff') format('woff');
}
@font-face {
font-family: 'Neue Haas Grotesk';
font-style: normal;
font-weight: 600;
src: url('/fonts/NeueHaasDisplayBold.woff2') format('woff2'),
url('/fonts/NeueHaasDisplayBold.woff') format('woff');
}

@ -34,16 +34,6 @@ select:focus {
outline: none;
}
/*
Backgrounds
============
*/
#app-content {
background: url('/bg-home.jpg') no-repeat top;
background-color: rgb(241 241 241);
}
/*
Text and shadows
================

@ -1,36 +1,48 @@
/** @type {import('tailwindcss').Config} */
const defaultTheme = require('tailwindcss/defaultTheme')
const defaultTheme = require('tailwindcss/defaultTheme');
module.exports = {
content: ['./src/**/*.{js,ts,jsx,tsx}'],
theme: {
fontFamily: {
sans: ['Neue Haas Grotesk', 'Helvetica', 'sans-serif'],
sans: ['var(--font-main)'],
serif: ['Garamond', 'serif'],
mono: ['Courier New', 'monospace'],
},
screens: {
all: '1px',
xs: '480px',
...defaultTheme.screens,
},
extend: {
colors: {
black: '#010101',
black2: '#15171a',
white: '#ffffff',
gray: { ...defaultTheme.colors.gray, 150: '#EBEDF0', 250: '#404040', 350: '#6B6B6B' },
blue: {
50: '#E6EDF9',
100: '#CDDCF4',
200: '#A7C2EC',
300: '#82A8E4',
400: '#5385D2',
500: '#2362C0',
600: '#1D4685',
700: '#162A4A',
800: '#11213B',
900: '#0D192C',
primary: {
50: '#e7e7fa',
100: '#cdcbf5',
200: '#8d91ea',
300: '#2731d8',
400: '#131961',
500: '#040512',
600: '#03030f',
700: '#02020d',
800: '#02020b',
900: '#020209',
},
accent: {
50: '#f8fcee',
100: '#eff8db',
200: '#dff2b9',
300: '#c9e792',
400: '#afd868',
500: '#9ad041',
600: '#78ae26',
700: '#5c8622',
800: '#4c6b22',
900: '#415b22',
},
red: {
100: '#EBBAB8',
@ -55,34 +67,12 @@ module.exports = {
800: '#17462E',
900: '#0F2F1E',
},
pink: {
50: '#FAEAF8',
100: '#F2C1EA',
200: '#EA98DC',
300: '#E26ECE',
400: '#DA45C0',
500: '#D631B9',
600: '#C02CA6',
700: '#952281',
800: '#6B185C',
900: '#400E37',
},
// Neutron mint/teal
mint: {
50: '#e5faf4',
100: '#b3f1e0',
200: '#88e9ce',
300: '#5ce1bc',
400: '#47ddb3',
500: '#31D99C',
600: '#25cb9d',
700: '#21b68c',
800: '#1ea07b'
}
},
fontSize: {
xxs: '0.7rem',
xs: '0.775rem',
sm: '0.85rem',
md: '0.95rem',
thin: '0.625rem',
},
spacing: {
88: '22rem',
@ -93,10 +83,10 @@ module.exports = {
},
borderRadius: {
none: '0',
sm: '0.25rem',
DEFAULT: '0.35rem',
md: '0.45rem',
lg: '0.55rem',
sm: '0.20rem',
DEFAULT: '0.30rem',
md: '0.40rem',
lg: '0.50rem',
full: '9999px',
},
blur: {
@ -106,8 +96,8 @@ module.exports = {
'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;',
},
transitionProperty: {
'height': 'height, max-height',
'spacing': 'margin, padding',
height: 'height, max-height',
spacing: 'margin, padding',
},
maxWidth: {
'xl-1': '39.5rem',

@ -3939,13 +3939,13 @@ __metadata:
languageName: node
linkType: hard
"@hyperlane-xyz/core@npm:5.2.1":
version: 5.2.1
resolution: "@hyperlane-xyz/core@npm:5.2.1"
"@hyperlane-xyz/core@npm:5.3.0":
version: 5.3.0
resolution: "@hyperlane-xyz/core@npm:5.3.0"
dependencies:
"@arbitrum/nitro-contracts": "npm:^1.2.1"
"@eth-optimism/contracts": "npm:^0.6.0"
"@hyperlane-xyz/utils": "npm:5.2.1"
"@hyperlane-xyz/utils": "npm:5.3.0"
"@layerzerolabs/lz-evm-oapp-v2": "npm:2.0.2"
"@openzeppelin/contracts": "npm:^4.9.3"
"@openzeppelin/contracts-upgradeable": "npm:^v4.9.3"
@ -3954,17 +3954,7 @@ __metadata:
"@ethersproject/abi": "*"
"@ethersproject/providers": "*"
"@types/sinon-chai": "*"
checksum: df515d545c3a174dbadef13132a63874f0fc1e2c9cf891bf9c874ab2d4b31cc1d2cb33d660f9e99d547cc6d508f527d4dd5e1e758fc8d141de56401f4616010d
languageName: node
linkType: hard
"@hyperlane-xyz/registry@npm:4.3.2":
version: 4.3.2
resolution: "@hyperlane-xyz/registry@npm:4.3.2"
dependencies:
yaml: "npm:2.4.5"
zod: "npm:^3.21.2"
checksum: 7b1ff07074e4499f74a4c75dbbf0b7e641b3610bfc2a67785db724748d887d7b03c9dc9738b790cb56e008d6453789432c863f3b251498f77c931f196b9dab86
checksum: f3d4ca187d59cb3f7f6c7767a7f4204b5ee17b9593b1f36272cbbaf34261b3055f5d51f55ecc590591b817b8f3a4c2aa8b63af9aee16864519df50c6faf5707a
languageName: node
linkType: hard
@ -3978,16 +3968,16 @@ __metadata:
languageName: node
linkType: hard
"@hyperlane-xyz/sdk@npm:5.2.1":
version: 5.2.1
resolution: "@hyperlane-xyz/sdk@npm:5.2.1"
"@hyperlane-xyz/sdk@npm:5.3.0":
version: 5.3.0
resolution: "@hyperlane-xyz/sdk@npm:5.3.0"
dependencies:
"@arbitrum/sdk": "npm:^4.0.0"
"@aws-sdk/client-s3": "npm:^3.74.0"
"@cosmjs/cosmwasm-stargate": "npm:^0.32.4"
"@cosmjs/stargate": "npm:^0.32.4"
"@hyperlane-xyz/core": "npm:5.2.1"
"@hyperlane-xyz/utils": "npm:5.2.1"
"@hyperlane-xyz/core": "npm:5.3.0"
"@hyperlane-xyz/utils": "npm:5.3.0"
"@safe-global/api-kit": "npm:1.3.0"
"@safe-global/protocol-kit": "npm:1.3.0"
"@safe-global/safe-deployments": "npm:1.37.8"
@ -4006,13 +3996,13 @@ __metadata:
peerDependencies:
"@ethersproject/abi": "*"
"@ethersproject/providers": "*"
checksum: 94912ab970d911d77590709f78f43139717abf2d1d1ffd4f97137d2b739a0de785517a38108e2c47e4a6090c8c7e2c63f5665aa77333ca243e5ab610b0ce2585
checksum: f72eb29ddceff027c9c6a2a85679aaca0beff94ea171cc5653bc3f57e53350e69ba5ab11484b9fff3e3f764a9cbcf51db0fa3ab71fbe92707e2dc209e61af3e6
languageName: node
linkType: hard
"@hyperlane-xyz/utils@npm:5.2.1":
version: 5.2.1
resolution: "@hyperlane-xyz/utils@npm:5.2.1"
"@hyperlane-xyz/utils@npm:5.3.0":
version: 5.3.0
resolution: "@hyperlane-xyz/utils@npm:5.3.0"
dependencies:
"@cosmjs/encoding": "npm:^0.32.4"
"@solana/web3.js": "npm:^1.78.0"
@ -4021,7 +4011,7 @@ __metadata:
lodash-es: "npm:^4.17.21"
pino: "npm:^8.19.0"
yaml: "npm:2.4.5"
checksum: 67c725cbb0581f6a8b42723974986b9c7beee69a51dcc3261efc9c4961f27493eb10108407b1d54329eb95c19c5595ca6cc581137f925773ec600eb72c761fe1
checksum: 2ae64331824f21c8741c2e94eadd1e863c5ce6f0b4d84e35b03eeae47b2473403636eda0f5aa648523a312b605de2a69fb9fff73949e26e3410e85b4c2fe0d27
languageName: node
linkType: hard
@ -4043,9 +4033,9 @@ __metadata:
"@emotion/styled": "npm:^11.13.0"
"@headlessui/react": "npm:^1.7.14"
"@hyperlane-xyz/registry": "npm:4.3.6"
"@hyperlane-xyz/sdk": "npm:5.2.1"
"@hyperlane-xyz/utils": "npm:5.2.1"
"@hyperlane-xyz/widgets": "npm:5.2.1"
"@hyperlane-xyz/sdk": "npm:5.3.0"
"@hyperlane-xyz/utils": "npm:5.3.0"
"@hyperlane-xyz/widgets": "npm:5.3.0"
"@interchain-ui/react": "npm:^1.23.28"
"@metamask/jazzicon": "https://github.com/jmrossy/jazzicon#7a8df28974b4e81129bfbe3cab76308b889032a6"
"@metamask/post-message-stream": "npm:6.1.2"
@ -4097,16 +4087,16 @@ __metadata:
languageName: unknown
linkType: soft
"@hyperlane-xyz/widgets@npm:5.2.1":
version: 5.2.1
resolution: "@hyperlane-xyz/widgets@npm:5.2.1"
"@hyperlane-xyz/widgets@npm:5.3.0":
version: 5.3.0
resolution: "@hyperlane-xyz/widgets@npm:5.3.0"
dependencies:
"@hyperlane-xyz/registry": "npm:4.3.2"
"@hyperlane-xyz/sdk": "npm:5.2.1"
"@hyperlane-xyz/registry": "npm:4.3.6"
"@hyperlane-xyz/sdk": "npm:5.3.0"
peerDependencies:
react: ^18
react-dom: ^18
checksum: 9ee820be26d51cf59285ca370c88867c02b828473a6ffb136590d9d7987a109b9b956620833945ca32df2345fda3d5b1a4352d2a3e94a519b633fb2fd6f1342f
checksum: 231d03f88451dc0b0defa1002c6f0da058fb999a75b80457d7be9e1f6b381bc6e5ba9745aab54f56d3efb3be07682eb58301fa6c61b32ba2b8920aa46b6aa5d5
languageName: node
linkType: hard

Loading…
Cancel
Save