Merge pull request #47 from hyperlane-xyz/rebrand

Rebrand
pull/48/head
J M Rossy 1 year ago committed by GitHub
commit 3323fe7f98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. BIN
      public/android-chrome-192x192.png
  2. BIN
      public/android-chrome-512x512.png
  3. BIN
      public/apple-touch-icon.png
  4. BIN
      public/background-texture.png
  5. BIN
      public/background-texture2.png
  6. BIN
      public/background-texture3.png
  7. 2
      public/browserconfig.xml
  8. BIN
      public/favicon-16x16.png
  9. BIN
      public/favicon-32x32.png
  10. BIN
      public/favicon.ico
  11. BIN
      public/fonts/NeueHaasDisplayMedium.ttf
  12. BIN
      public/icon.png
  13. 4
      public/images/lines-bg-mid.svg
  14. 4
      public/images/lines-bg-top.svg
  15. BIN
      public/images/logo-blue.png
  16. BIN
      public/images/logo-with-text.png
  17. BIN
      public/images/logo.png
  18. 0
      public/images/logo.svg
  19. BIN
      public/logo-with-text.png
  20. BIN
      public/mstile-150x150.png
  21. 26
      public/safari-pinned-tab.svg
  22. 0
      src/components/animations/Fade.tsx
  23. 0
      src/components/animations/Spinner.module.css
  24. 0
      src/components/animations/Spinner.tsx
  25. 10
      src/components/buttons/SolidButton.tsx
  26. 83
      src/components/icons/Chevron.tsx
  27. 38
      src/components/icons/Discord.tsx
  28. 30
      src/components/icons/Github.tsx
  29. 38
      src/components/icons/HyperlaneLogo.tsx
  30. 30
      src/components/icons/LinkedIn.tsx
  31. 32
      src/components/icons/Medium.tsx
  32. 30
      src/components/icons/Twitter.tsx
  33. 80
      src/components/icons/Web.tsx
  34. 31
      src/components/icons/XIcon.tsx
  35. 2
      src/components/input/Checkbox.module.css
  36. 2
      src/components/input/SelectField.tsx
  37. 28
      src/components/layout/AppLayout.tsx
  38. 11
      src/components/layout/Card.tsx
  39. 20
      src/components/layout/ContentFrame.tsx
  40. 64
      src/components/layout/Dropdown.tsx
  41. 4
      src/components/layout/Modal.tsx
  42. 168
      src/components/nav/Footer.tsx
  43. 154
      src/components/nav/Header.tsx
  44. 6
      src/components/search/MiniSearchBar.tsx
  45. 19
      src/components/search/SearchBar.tsx
  46. 71
      src/components/search/SearchFilterBar.tsx
  47. 8
      src/components/search/SearchStates.tsx
  48. 3
      src/consts/links.ts
  49. 36
      src/features/chains/ConfigureChains.tsx
  50. 31
      src/features/messages/MessageDetails.tsx
  51. 11
      src/features/messages/MessageSearch.tsx
  52. 18
      src/features/messages/MessageTable.tsx
  53. 4
      src/features/messages/cards/ContentDetailsCard.tsx
  54. 6
      src/features/messages/cards/GasDetailsCard.tsx
  55. 4
      src/features/messages/cards/IcaDetailsCard.tsx
  56. 6
      src/features/messages/cards/IsmDetailsCard.tsx
  57. 2
      src/features/messages/cards/KeyValueRow.tsx
  58. 4
      src/features/messages/cards/TimelineCard.tsx
  59. 28
      src/features/messages/cards/TransactionCard.tsx
  60. 2
      src/features/messages/queries/useMessageQuery.ts
  61. 1
      src/global.d.ts
  62. 3
      src/images/backgrounds/footer-bg.svg
  63. 3
      src/images/backgrounds/footer-line-desktop.svg
  64. 3
      src/images/backgrounds/footer-line-mobile.svg
  65. 1
      src/images/backgrounds/footer-top-border.svg
  66. 4
      src/images/backgrounds/main-bg.svg
  67. 2
      src/images/icons/checkmark-circle.svg
  68. 2
      src/images/icons/search.svg
  69. 4
      src/images/icons/x.svg
  70. 3
      src/images/logos/github copy.svg
  71. 2
      src/images/logos/hyperlane-explorer.svg
  72. 2
      src/images/logos/hyperlane-logo.svg
  73. 2
      src/images/logos/hyperlane-name.svg
  74. 17
      src/pages/_document.tsx
  75. 20
      src/pages/api-docs.tsx
  76. 7
      src/pages/index.tsx
  77. 7
      src/pages/message/[messageId].tsx
  78. 21
      src/styles/Color.ts
  79. 7
      src/styles/fonts.css
  80. 32
      tailwind.config.js

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

@ -3,7 +3,7 @@
<msapplication>
<tile>
<square150x150logo src="/mstile-150x150.png"/>
<TileColor>#2362C1</TileColor>
<TileColor>#da532c</TileColor>
</tile>
</msapplication>
</browserconfig>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 818 B

After

Width:  |  Height:  |  Size: 760 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

@ -0,0 +1,4 @@
<svg width="1440" height="1422" viewBox="0 0 1440 1422" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M-31.5 462.274C2081.5 638.912 -628.5 757.774 1473.5 932.774" stroke="white" stroke-width="8"/>
<path d="M-34 484.774C1976.5 621.774 -688.5 763.274 1470.5 960.774" stroke="white" stroke-width="4"/>
</svg>

After

Width:  |  Height:  |  Size: 317 B

@ -0,0 +1,4 @@
<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>

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

@ -2,23 +2,23 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="2000.000000pt" height="2000.000000pt" viewBox="0 0 2000.000000 2000.000000"
width="1000.000000pt" height="1000.000000pt" viewBox="0 0 1000.000000 1000.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.14, written by Peter Selinger 2001-2017
</metadata>
<g transform="translate(0.000000,2000.000000) scale(0.100000,-0.100000)"
<g transform="translate(0.000000,1000.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M4210 16424 c-56 -24 -99 -73 -116 -131 -14 -48 -14 -58 0 -105 8
-29 508 -1400 1110 -3046 l1094 -2994 -1106 -3166 c-1009 -2887 -1107 -3172
-1107 -3229 0 -52 5 -68 30 -104 17 -23 50 -53 74 -66 l44 -23 1283 0 c1389 0
1351 -1 1499 55 153 57 312 191 400 335 29 48 259 668 890 2405 l850 2340
1514 3 c1457 2 1513 1 1509 -16 -3 -10 -386 -1109 -851 -2443 -466 -1333 -849
-2438 -853 -2455 -9 -46 13 -110 52 -154 69 -76 -34 -71 1429 -68 l1310 3 85
28 c215 72 389 216 481 399 46 90 2209 6053 2209 6088 0 31 -2132 5773 -2190
5897 -84 183 -238 329 -426 404 -152 61 -105 59 -1505 59 -1132 0 -1284 -2
-1317 -15 -75 -32 -122 -102 -122 -182 0 -39 170 -511 859 -2395 l858 -2348
-1523 0 -1523 0 -3 -21 c-2 -11 -376 982 -832 2208 -456 1225 -840 2252 -852
2280 -89 206 -283 373 -516 445 l-73 23 -1315 2 c-1160 2 -1319 1 -1350 -13z"/>
<path d="M0 5000 l0 -5000 5000 0 5000 0 0 5000 0 5000 -5000 0 -5000 0 0
-5000z m4016 2455 c67 -20 140 -70 172 -118 15 -22 185 -436 379 -921 l352
-881 630 -3 630 -2 -14 32 c-7 18 -171 437 -364 930 -316 807 -349 899 -340
926 5 16 21 34 35 41 18 8 181 11 558 11 582 0 585 0 678 -59 26 -17 60 -48
76 -70 23 -32 477 -1153 867 -2143 l66 -167 -446 -1147 c-245 -631 -455 -1164
-465 -1184 -26 -51 -110 -124 -168 -146 -43 -17 -93 -19 -600 -22 l-553 -3
-29 30 c-17 16 -30 36 -30 43 0 11 603 1636 675 1821 l15 37 -623 0 -622 0
-334 -863 c-184 -474 -344 -881 -357 -903 -30 -54 -84 -101 -154 -133 l-55
-26 -540 -3 c-297 -2 -550 0 -562 3 -29 7 -63 44 -63 68 0 11 205 568 455
1237 l455 1218 -456 1163 c-338 864 -453 1170 -449 1189 3 14 16 33 28 42 20
16 66 18 563 18 448 0 549 -3 590 -15z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -1,7 +1,7 @@
import { PropsWithChildren, ReactElement } from 'react';
interface ButtonProps {
color?: 'white' | 'blue' | 'green' | 'red'; // defaults to blue
color?: 'white' | 'blue' | 'green' | 'red' | 'pink'; // defaults to blue
type?: 'submit' | 'reset' | 'button';
onClick?: () => void;
classes?: string;
@ -18,7 +18,7 @@ export function SolidButton(props: PropsWithChildren<ButtonProps>) {
onClick,
color: _color,
classes,
bold,
bold = true,
icon,
disabled,
title,
@ -26,12 +26,16 @@ export function SolidButton(props: PropsWithChildren<ButtonProps>) {
} = props;
const color = _color ?? 'blue';
const base = 'flex items-center justify-center rounded transition-all duration-500';
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';
} else if (color === 'green') {
baseColors = 'bg-green-500 text-white';
onHover = 'hover:bg-green-600';

@ -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"
@ -51,3 +51,84 @@ function _ChevronIcon({ width, height, direction, color, classes }: Props) {
}
export const ChevronIcon = memo(_ChevronIcon);
interface Props {
width?: string | number;
height?: string | number;
direction: 'n' | 'e' | 's' | 'w';
color?: string;
classes?: string;
}
function _HyperlaneChevron({ width, height, direction, color, classes }: Props) {
let directionClass;
switch (direction) {
case 'n':
directionClass = '-rotate-90';
break;
case 'e':
directionClass = '';
break;
case 's':
directionClass = 'rotate-90';
break;
case 'w':
directionClass = 'rotate-180';
break;
default:
throw new Error(`Invalid chevron direction ${direction}`);
}
return (
<svg
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="1.2 1 139.1 322"
width={width}
height={height}
className={`${directionClass} ${classes}`}
>
<path
d="M6.3 1h61.3a20 20 0 0 1 18.7 13L140 158.3a5 5 0 0 1 0 3.4l-.3.9-53.5 147.2A20 20 0 0 1 67.4 323H6.2a5 5 0 0 1-4.7-6.6l55.2-158.1L1.7 7.7A5 5 0 0 1 6.2 1Z"
fill={color || Color.Blue}
></path>
</svg>
);
}
export const HyperlaneChevron = memo(_HyperlaneChevron);
function _HyperlaneWideChevron({ width, height, direction, color, classes }: Props) {
let directionClass;
switch (direction) {
case 'n':
directionClass = '-rotate-90';
break;
case 'e':
directionClass = '';
break;
case 's':
directionClass = 'rotate-90';
break;
case 'w':
directionClass = 'rotate-180';
break;
default:
throw new Error(`Invalid chevron direction ${direction}`);
}
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 120.3 190"
width={width}
height={height}
className={`${directionClass} ${classes}`}
fill={color || Color.Blue}
>
<path d="M4.4 0h53c7.2 0 13.7 3 16.2 7.7l46.5 85.1a2 2 0 0 1 0 2l-.2.5-46.3 87c-2.5 4.6-9 7.7-16.3 7.7h-53c-3 0-5-2-4-4L48 92.9.4 4c-1-2 1-4 4-4Z" />
</svg>
);
}
export const HyperlaneWideChevron = memo(_HyperlaneWideChevron);

@ -0,0 +1,38 @@
import { memo } from 'react';
function _Discord({
width,
height,
fill,
className = '',
}: {
width?: number | string;
height?: number | string;
fill?: string;
className?: string;
}) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
className={className}
viewBox="0 0 71 55"
fill="none"
>
<g clipPath="url(#a)">
<path
d="M60.1 4.9A58.5 58.5 0 0 0 45.4.5l-1.8 3.7a54 54 0 0 0-16.2 0 37.4 37.4 0 0 0-2-3.8A58.4 58.4 0 0 0 10.7 5 60 60 0 0 0 .4 45.6a58.9 58.9 0 0 0 18 8.8 42 42 0 0 0 3.6-5.9l-.1-.3c-2-.7-3.8-1.6-5.6-2.6a.2.2 0 0 1 0-.4 30.3 30.3 0 0 0 1.3-.9 42 42 0 0 0 36 0l1 1c.2 0 .2.2 0 .3-1.7 1-3.6 1.9-5.5 2.6a47.2 47.2 0 0 0 3.8 6.3 58.7 58.7 0 0 0 17.8-9.1A59.5 59.5 0 0 0 60 4.9ZM23.7 37.3c-3.5 0-6.4-3.2-6.4-7.1 0-4 2.9-7.2 6.4-7.2 3.6 0 6.5 3.3 6.4 7.2 0 4-2.8 7.1-6.4 7.1Zm23.6 0c-3.5 0-6.4-3.2-6.4-7.1 0-4 2.9-7.2 6.4-7.2 3.6 0 6.5 3.3 6.4 7.2 0 4-2.8 7.1-6.4 7.1Z"
fill={fill}
/>
</g>
<defs>
<clipPath id="a">
<path fill="#fff" d="M0 0h71v55H0z" />
</clipPath>
</defs>
</svg>
);
}
export const Discord = memo(_Discord);

@ -0,0 +1,30 @@
import { memo } from 'react';
function _Github({
width,
height,
fill,
className = '',
}: {
width?: number | string;
height?: number | string;
fill?: string;
className?: string;
}) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
className={className}
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"
fill={fill}
/>
</svg>
);
}
export const Github = memo(_Github);

@ -0,0 +1,38 @@
import { memo } from 'react';
function _HyperlaneLogo({
width,
height,
fill,
className = '',
}: {
width?: number | string;
height?: number | string;
fill?: string;
className?: string;
}) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
className={className}
viewBox="0 0 117 118"
>
<path
d="M64.4787 0H88.4134C91.6788 0 94.6004 1.89614 95.7403 4.7553L116.749 57.4498C116.911 57.8563 116.913 58.3035 116.754 58.7112L116.637 59.014L116.635 59.017L95.7152 112.81C94.5921 115.698 91.6551 117.62 88.3666 117.62H64.4355C63.0897 117.62 62.1465 116.379 62.59 115.192L84.1615 57.4498L62.6428 2.45353C62.1766 1.26188 63.1208 0 64.4787 0Z"
fill={fill}
/>
<path
d="M1.99945 0H25.9342C29.1996 0 32.1211 1.89614 33.261 4.7553L54.2696 57.4498C54.4316 57.8563 54.4336 58.3035 54.275 58.7112L54.1573 59.014L54.1561 59.017L33.236 112.81C32.1129 115.698 29.1759 117.62 25.8874 117.62H1.95626C0.610483 117.62 -0.332722 116.379 0.110804 115.192L21.6823 57.4498L0.163626 2.45353C-0.302638 1.26188 0.641544 0 1.99945 0Z"
fill={fill}
/>
<path
d="M80.7202 46.2178H46.9324V71.7089H80.7202L86.2411 58.5992L80.7202 46.2178Z"
fill={fill}
/>
</svg>
);
}
export const HyperlaneLogo = memo(_HyperlaneLogo);

@ -0,0 +1,30 @@
import { memo } from 'react';
function _Linkedin({
width,
height,
fill,
className = '',
}: {
width?: number | string;
height?: number | string;
fill?: string;
className?: string;
}) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
className={className}
viewBox="0 0 30 30"
>
<path
d="M9 25H4V10h5v15zM6.5 8a2.5 2.5 0 1 1 0-5 2.5 2.5 0 0 1 0 5zM27 25h-4.8v-7.3c0-1.74-.04-3.98-2.5-3.98-2.5 0-2.9 1.9-2.9 3.85V25H12V9.99h4.61v2.05h.07a5.08 5.08 0 0 1 4.55-2.42c4.87 0 5.77 3.1 5.77 7.15V25z"
fill={fill}
/>
</svg>
);
}
export const Linkedin = memo(_Linkedin);

@ -0,0 +1,32 @@
import { memo } from 'react';
function _Medium({
width,
height,
fill,
className = '',
}: {
width?: number | string;
height?: number | string;
fill?: string;
className?: string;
}) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
className={className}
viewBox="0 -55 256 256"
preserveAspectRatio="xMidYMid"
fill="none"
>
<path
fill={fill}
d="M72.2 0c39.88 0 72.2 32.55 72.2 72.7 0 40.14-32.33 72.69-72.2 72.69-39.87 0-72.2-32.55-72.2-72.7C0 32.56 32.33 0 72.2 0Zm115.3 4.26c19.94 0 36.1 30.64 36.1 68.44 0 37.79-16.16 68.43-36.1 68.43-19.93 0-36.1-30.64-36.1-68.43 0-37.8 16.16-68.44 36.1-68.44Zm55.8 7.13c7.01 0 12.7 27.45 12.7 61.3 0 33.86-5.68 61.32-12.7 61.32-7.01 0-12.7-27.46-12.7-61.31 0-33.86 5.7-61.31 12.7-61.31Z"
/>
</svg>
);
}
export const Medium = memo(_Medium);

@ -0,0 +1,30 @@
import { memo } from 'react';
function _Twitter({
width,
height,
fill,
className = '',
}: {
width?: number | string;
height?: number | string;
fill?: string;
className?: string;
}) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
className={className}
viewBox="0 0 16 16"
>
<path
d="M5.026 15c6.038 0 9.341-5.003 9.341-9.334 0-.14 0-.282-.006-.422A6.685 6.685 0 0 0 16 3.542a6.658 6.658 0 0 1-1.889.518 3.301 3.301 0 0 0 1.447-1.817 6.533 6.533 0 0 1-2.087.793A3.286 3.286 0 0 0 7.875 6.03a9.325 9.325 0 0 1-6.767-3.429 3.289 3.289 0 0 0 1.018 4.382A3.323 3.323 0 0 1 .64 6.575v.045a3.288 3.288 0 0 0 2.632 3.218 3.203 3.203 0 0 1-.865.115 3.23 3.23 0 0 1-.614-.057 3.283 3.283 0 0 0 3.067 2.277A6.588 6.588 0 0 1 .78 13.58a6.32 6.32 0 0 1-.78-.045A9.344 9.344 0 0 0 5.026 15z"
fill={fill}
/>
</svg>
);
}
export const Twitter = memo(_Twitter);

@ -0,0 +1,80 @@
import { memo } from 'react';
function _Web({
width,
height,
fill,
className = '',
}: {
width?: number | string;
height?: number | string;
fill?: string;
className?: string;
}) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
className={className}
viewBox="0 0 29 29"
>
<path
fill={fill}
d="m11 18.6-.39.17a13.45 13.45 0 0 0 1.12 2.9 5.25 5.25 0 0 0 2.08 2.24c.36.18.7.26 1.03.26.95 0 2.1-.71 3.1-2.5.46-.82.85-1.8 1.13-2.9a10.3 10.3 0 0 0-8.06-.17Z"
/>
<path
fill="#02010A"
d="M20.34 19.46a11.88 11.88 0 0 1-1.88 3.99 9.63 9.63 0 0 0 3.63-2.6 10.3 10.3 0 0 0-1.75-1.4Z"
/>
<path
fill="#02010A"
d="M24.41 15.27a9.55 9.55 0 0 1-1.48 4.45l-.53-.49c-.54-.45-1.12-.86-1.74-1.22.08-.45.15-.9.2-1.38l.05-.61c.02-.25.04-.5.04-.75h3.46Z"
/>
<path
fill="#02010A"
d="M22.96 9.45a9.55 9.55 0 0 1 1.45 4.42h-3.46a19 19 0 0 0-.28-2.7c.83-.47 1.6-1.06 2.3-1.72Z"
/>
<path
fill="#02010A"
d="m22.05 8.24.07.08c-.54.54-1.14 1.01-1.78 1.42a11.84 11.84 0 0 0-1.91-4.08 9.63 9.63 0 0 1 3.62 2.58Z"
/>
<path
fill="#02010A"
d="M16.35 5.53a2.55 2.55 0 0 0-1.51-.57c-.96 0-2.11.72-3.11 2.5-.15.28-.3.57-.43.88l-.24.58c-.17.47-.33.97-.46 1.5a10.24 10.24 0 0 0 8.47 0 12.18 12.18 0 0 0-1.12-2.95 6.02 6.02 0 0 0-1.6-1.94Z"
/>
<path
fill="#02010A"
d="M7.54 8.3a9.68 9.68 0 0 1 3.7-2.63 11.9 11.9 0 0 0-1.9 4.07 10.4 10.4 0 0 1-1.8-1.44Z"
/>
<path
fill="#02010A"
d="M5.26 13.87A9.53 9.53 0 0 1 6.7 9.45c.69.67 1.46 1.25 2.3 1.73a19 19 0 0 0-.29 2.69H5.26Z"
/>
<path
fill="#02010A"
d="M6.73 19.72a9.53 9.53 0 0 1-1.47-4.45h3.46c.03.95.14 1.87.3 2.74a11.33 11.33 0 0 0-2.29 1.7Z"
/>
<path
fill="#02010A"
d="M11.24 23.47a9.62 9.62 0 0 1-3.66-2.61c.53-.54 1.12-1.01 1.76-1.41.45 1.6 1.1 2.98 1.9 4.02Z"
/>
<path
fill="#02010A"
d="M19.55 15.27a14 14 0 0 1-.2 2.1 11.66 11.66 0 0 0-9.03 0c-.1-.67-.17-1.38-.2-2.1h9.43Z"
/>
<path
fill="#02010A"
d="M19.55 13.87h-9.43c.03-.71.1-1.4.2-2.05a11.78 11.78 0 0 0 9.04 0 18.37 18.37 0 0 1 .2 2.05Z"
/>
<path
fill="#02010A"
fill-rule="evenodd"
d="M28.84 14.57a14 14 0 1 0-14 14 14 14 0 0 0 14-14Zm-3 0a11 11 0 1 0-22 0 11 11 0 0 0 22 0Z"
clip-rule="evenodd"
/>
</svg>
);
}
export const Web = memo(_Web);

@ -1,19 +1,30 @@
import { memo } from 'react';
import X from '../../images/icons/x.svg';
import { IconButton } from '../buttons/IconButton';
function _XIcon({
onClick,
title,
size = 20,
width,
height,
fill,
className = '',
}: {
onClick: () => void;
title?: string;
size?: number;
width?: number | string;
height?: number | string;
fill?: string;
className?: string;
}) {
return (
<IconButton imgSrc={X} title={title || 'Close'} width={size} height={size} onClick={onClick} />
<svg
xmlns="http://www.w3.org/2000/svg"
width={width}
height={height}
className={className}
viewBox="20.24 19.95 56.33 56.24"
>
<path
fill={fill}
d="M27.73 76.19a7.5 7.5 0 0 1-5.3-12.8l41.34-41.34a7.5 7.5 0 0 1 10.6 10.61L33 74a7.48 7.48 0 0 1-5.27 2.19Z"
/>
<path d="M69.07 76.19a7.48 7.48 0 0 1-5.3-2.2L22.43 32.66A7.5 7.5 0 0 1 33 22.05l41.37 41.34a7.5 7.5 0 0 1-5.3 12.8Z" />
</svg>
);
}

@ -20,7 +20,7 @@
border-radius: 0.2rem;
transform: scale(0);
transition: 200ms all ease-in-out;
background-color: #2362c1;
background-color: #2362c0;
}
.checkbox:checked::before {

@ -19,7 +19,7 @@ export function SelectField(props: Props) {
return (
<select
className={`px-2 py-1 text-sm border border-gray-400 rounded bg-transparent invalid:text-gray-400 ${
className={`px-2 py-1 text-sm font-light border border-gray-400 rounded bg-transparent invalid:text-gray-400 ${
classes || ''
}`}
{...passThruProps}

@ -17,13 +17,19 @@ export function AppLayout({ pathName, children }: PropsWithChildren<Props>) {
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{`Hyperlane Explorer | ${getHeadTitle(pathName)}`}</title>
</Head>
<div id="app-content" className="h-full min-h-screen w-full min-w-screen">
<div
style={styles.container}
id="app-content"
className="relative w-full min-w-screen h-full min-h-screen flex flex-col justify-between bg-blue-500"
>
{/* <InfoBanner /> */}
<div className="max-w-5xl mx-auto flex flex-col justify-between min-h-screen">
<Header pathName={pathName} />
<main className="w-full grow">{children}</main>
<Footer />
<Header pathName={pathName} />
<div className="max-w-5xl mx-auto grow">
<main style={styles.main} className="relative min-h-full pt-3 z-20">
{children}
</main>
</div>
<Footer />
</div>
</>
);
@ -34,3 +40,15 @@ function getHeadTitle(pathName: string) {
if (segments.length <= 1 || !segments[1]) return 'Home';
else return toTitleCase(segments[1]);
}
const styles = {
container: {
backgroundImage: 'url(/images/lines-bg-top.svg)',
backgroundSize: '94vw',
backgroundRepeat: 'no-repeat',
backgroundPosition: 'center 80px',
},
main: {
width: 'min(900px,96vw)',
},
};

@ -1,11 +1,16 @@
import { PropsWithChildren } from 'react';
interface Props {
classes?: string;
className?: string;
padding?: string;
}
export function Card({ classes, children }: PropsWithChildren<Props>) {
export function Card({ className, padding = 'p-4 sm:p-5', children }: PropsWithChildren<Props>) {
return (
<div className={`p-4 bg-white shadow border rounded overflow-auto ${classes}`}>{children}</div>
<div
className={`bg-white ring ring-blue-300 rounded-3xl overflow-auto ${padding} ${className}`}
>
{children}
</div>
);
}

@ -1,20 +0,0 @@
import { PropsWithChildren } from 'react';
import { BackgroundBanner } from './BackgroundBanner';
export function ContentFrame(props: PropsWithChildren) {
return (
<div className="flex flex-col justify-center items-center min-h-full">
<div style={styles.container} className="relative overflow-visible mt-7 mb-8">
<BackgroundBanner />
<div className="relative z-20 mt-1">{props.children}</div>
</div>
</div>
);
}
const styles = {
container: {
width: 'min(900px,96vw)',
},
};

@ -1,44 +1,40 @@
import { Menu, Popover, Transition } from '@headlessui/react';
import { Fragment, ReactElement, ReactNode } from 'react';
import { Fragment, PropsWithChildren, ReactElement, ReactNode } from 'react';
interface MenuProps {
buttonContent: ReactNode;
ButtonContent: (p: { isOpen: boolean }) => ReactElement;
buttonClasses?: string;
buttonTitle?: string;
menuItems: ReactNode[];
menuItems: Array<(close: () => void) => ReactElement>;
menuClasses?: string;
isFullscreen?: boolean;
}
// Uses Headless menu, which auto-closes on any item click
export function DropdownMenu({
buttonContent,
ButtonContent,
buttonClasses,
buttonTitle,
menuItems,
menuClasses,
isFullscreen,
}: MenuProps) {
const menuItemsClass = isFullscreen
? `z-50 fixed left-0 right-0 top-20 bottom-0 w-screen bg-blue-500 focus:outline-none ${menuClasses}`
: `z-50 absolute -right-1.5 mt-3 origin-top-right rounded-md bg-white shadow-md drop-shadow-md focus:outline-none ${menuClasses}`;
return (
<Menu as="div" className="relative">
<Menu.Button title={buttonTitle} className={`flex ${buttonClasses}`}>
{buttonContent}
{({ open }) => <ButtonContent isOpen={open} />}
</Menu.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-100"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items
className={`z-50 absolute -right-1.5 mt-3 origin-top-right rounded-md bg-white shadow-md drop-shadow-md ring-1 ring-black ring-opacity-5 focus:outline-none ${menuClasses}`}
>
<DropdownTransition>
<Menu.Items className={menuItemsClass}>
{menuItems.map((mi, i) => (
<Menu.Item key={`menu-item-${i}`}>{mi}</Menu.Item>
<Menu.Item key={`menu-item-${i}`}>{({ close }) => mi(close)}</Menu.Item>
))}
</Menu.Items>
</Transition>
</DropdownTransition>
</Menu>
);
}
@ -64,21 +60,29 @@ export function DropdownModal({
<Popover.Button title={buttonTitle} className={`flex ${buttonClasses}`}>
{buttonContent}
</Popover.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-100"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<DropdownTransition>
<Popover.Panel
className={`z-50 absolute mt-3 origin-top-right rounded-md bg-white shadow-md drop-shadow-md ring-1 ring-black ring-opacity-5 focus:outline-none ${modalClasses}`}
className={`z-50 absolute mt-3 origin-top-right rounded-md bg-white shadow-md drop-shadow-md focus:outline-none ${modalClasses}`}
>
{({ close }) => modalContent(close)}
</Popover.Panel>
</Transition>
</DropdownTransition>
</Popover>
);
}
function DropdownTransition({ children }: PropsWithChildren<unknown>) {
return (
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-100"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
{children}
</Transition>
);
}

@ -40,9 +40,9 @@ export function Modal({
<Dialog.Panel
className={`w-full ${
maxWidth || 'max-w-xs'
} max-h-[90vh] transform overflow-auto rounded-md bg-white px-4 py-4 text-left shadow-lg transition-all`}
} max-h-[90vh] transform overflow-auto rounded-xl bg-white px-4 py-4 text-left shadow-lg transition-all`}
>
<Dialog.Title as="h3" className="text text-gray-700">
<Dialog.Title as="h3" className="font-medium text-blue-500">
{title}
</Dialog.Title>
{children}

@ -1,79 +1,117 @@
// Partly copied from https://github.com/hyperlane-xyz/hyperlane-website/blob/main/src/components/nav/Footer.tsx
import Image from 'next/image';
import Link from 'next/link';
import { links } from '../../consts/links';
import Discord from '../../images/logos/discord.svg';
import Github from '../../images/logos/github.svg';
import Hyperlane from '../../images/logos/hyperlane-logo.svg';
import Medium from '../../images/logos/medium.svg';
import Twitter from '../../images/logos/twitter.svg';
// import FooterLine from '../../images/backgrounds/footer-line-desktop.svg';
// import FooterLineMobile from '../../images/backgrounds/footer-line-mobile.svg';
import FooterBg from '../../images/backgrounds/footer-bg.svg';
import FooterTopBorder from '../../images/backgrounds/footer-top-border.svg';
import { Color } from '../../styles/Color';
import { Discord } from '../icons/Discord';
import { Github } from '../icons/Github';
import { HyperlaneLogo } from '../icons/HyperlaneLogo';
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: 'Chains', url: links.chains, external: true },
];
const footerLinks2 = [
{ title: 'Crew', url: `${links.home}/crew`, external: true },
{ title: 'Bounty', url: `${links.home}/bounty`, external: true },
{ title: 'Brand', url: links.brand, external: true },
];
const footerLinks3 = [
{ 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" /> },
{ title: 'Blog', url: links.blog, external: true, icon: <Medium fill="#fff" /> },
];
export function Footer() {
return (
<footer className="px-4 pt-5 pb-7 sm:px-10 opacity-80">
<div className="flex justify-between items-center gap-6 sm:gap-0">
<div className="flex items-center">
<div className="flex scale-90 sm:scale-100">
<Image src={Hyperlane} width={50} height={50} alt="" />
</div>
<div className="hidden sm:flex flex-col ml-3">
<p className="text-sm font-light leading-5">
<span className="text-base font-medium">Hyperlane</span> is the platform
<br />
for developers building
<br />
the interchain universe.
</p>
</div>
</div>
<div className="flex">
<div className="flex flex-col">
<FooterLink href={links.home} text="About" />
<FooterLink href={links.docs} text="Docs" />
<FooterLink href={links.chains} text="Chains" />
<FooterLink href={links.jobs} text="Jobs" />
</div>
<div className="flex flex-col ml-16">
<FooterIconLink href={links.twitter} imgSrc={Twitter} text="Twitter" />
<FooterIconLink href={links.discord} imgSrc={Discord} text="Discord" />
<FooterIconLink href={links.github} imgSrc={Github} text="Github" />
<FooterIconLink href={links.blog} imgSrc={Medium} text="Blog" />
<footer className="text-white ">
<div className="relative">
<Image className="relative z-0 w-full" src={FooterBg} alt="background" />
<Image
className="absolute z-10 bottom-[1.5rem] w-full h-auto"
src={FooterTopBorder}
alt="border"
/>
</div>
<div className="px-8 py-5 bg-pink-500">
<div className="flex flex-col sm:flex-row gap-10 items-center justify-between">
<div className="flex items-center justify-center">
<div className="ml-2 w-16 sm:w-20 h-16 sm:h-20">
<HyperlaneLogo fill={Color.White} />
</div>
<div className="text-xl sm:text-2xl font-medium ml-6 space-y-1 ">
<div>Go Interchain</div>
<div>With Hyperlane</div>
</div>
{/* <div className="absolute">
<div className="hidden sm:block">
<Image src={FooterLine} alt="" />
</div>
<div className="sm:hidden">
<Image src={FooterLineMobile} alt="" />
</div>
</div> */}
</div>
<nav className="flex text-lg font-medium">
<ul className={`${styles.linkCol} mr-14`}>
{footerLinks1.map((item) => (
<li className="" key={item.title}>
<Link
className={styles.linkItem}
target={item.external ? '_blank' : '_self'}
href={item.url}
>
<div className="">{item.title}</div>
</Link>
</li>
))}
</ul>
<ul className={`${styles.linkCol} mr-14`}>
{footerLinks2.map((item) => (
<li key={item.title}>
<Link
className={styles.linkItem}
target={item.external ? '_blank' : '_self'}
href={item.url}
>
<div className="">{item.title}</div>
</Link>
</li>
))}
</ul>
<ul className={`${styles.linkCol}`}>
{footerLinks3.map((item) => (
<li key={item.title}>
<Link
className={styles.linkItem}
target={item.external ? '_blank' : '_self'}
href={item.url}
>
{item?.icon && <div className="mr-4 w-6">{item?.icon}</div>}
<div className="">{item.title}</div>
</Link>
</li>
))}
</ul>
</nav>
</div>
</div>
</footer>
);
}
function FooterLink({ href, text }: { href: string; text: string }) {
const aClasses =
'mt-1.5 text-sm hover:underline underline-offset-4 hover:opacity-70 transition-all';
if (href[0] === '/') {
return (
<Link href={href} className={aClasses}>
{text}
</Link>
);
} else {
return (
<a href={href} target="_blank" rel="noopener noreferrer" className={aClasses}>
{text}
</a>
);
}
}
function FooterIconLink({ href, imgSrc, text }: { href: string; imgSrc: any; text: string }) {
return (
<a
href={href}
target="_blank"
rel="noopener noreferrer"
className="mt-1.5 flex items-center hover:underline underline-offset-4 hover:opacity-70 transition-all"
>
<Image src={imgSrc} width={18} height={18} alt="" />
<span className="ml-2.5 text-sm">{text}</span>
</a>
);
}
const styles = {
linkCol: 'flex flex-col gap-3',
linkItem: 'flex items-center capitalize text-decoration-none hover:underline underline-offset-2',
};

@ -1,37 +1,54 @@
import Image from 'next/image';
import Link from 'next/link';
import { PropsWithChildren, useEffect, useState } from 'react';
import { links } from '../../consts/links';
import BookIcon from '../../images/icons/book.svg';
import DatabaseIcon from '../../images/icons/database.svg';
import GearIcon from '../../images/icons/gear.svg';
import HamburgerIcon from '../../images/icons/hamburger.svg';
import HouseIcon from '../../images/icons/house.svg';
import InfoIcon from '../../images/icons/info-circle.svg';
import Explorer from '../../images/logos/hyperlane-explorer.svg';
import Logo from '../../images/logos/hyperlane-logo.svg';
import Name from '../../images/logos/hyperlane-name.svg';
import { Color } from '../../styles/Color';
import { HyperlaneWideChevron } from '../icons/Chevron';
import { DropdownMenu } from '../layout/Dropdown';
import { MiniSearchBar } from '../search/MiniSearchBar';
const PAGES_EXCLUDING_SEARCH = ['/', '/debugger'];
export function Header({ pathName }: { pathName: string }) {
// For dynamic sizing on scroll
const [animateHeader, setAnimateHeader] = useState(false);
useEffect(() => {
const listener = () => {
if (window.scrollY > 100) {
setAnimateHeader(true);
} else setAnimateHeader(false);
};
window.addEventListener('scroll', listener);
return () => {
window.removeEventListener('scroll', listener);
};
}, []);
const showSearch = !PAGES_EXCLUDING_SEARCH.includes(pathName);
const navLinkClass = (path?: string) =>
path && pathName === path
? styles.navLink + ' text-blue-500'
: styles.navLink + ' text-gray-600';
path && pathName === path ? styles.navLink + ' underline' : styles.navLink;
return (
<header className="px-2 pt-4 pb-3 sm:pt-5 sm:px-6 lg:pr-14 w-full">
<header
className={`z-30 sticky top-0 px-2 sm:px-6 lg:px-12 w-full bg-blue-500 transition-all ease-in-out duration-500 ${
animateHeader ? 'py-1 border-b border-white' : 'py-4 sm:py-5'
}`}
>
<div className="flex items-center justify-between">
<Link href="/" className="flex items-center">
<div className="flex items-center scale-90 sm:scale-100">
<Image src={Logo} width={22} alt="" />
<Image src={Name} width={110} alt="Hyperlane" className="mt-0.5 ml-2" />
<Image src={Explorer} width={108} alt="Explorer" className="mt-0.5 ml-2" />
<div
className={`flex items-center ${
animateHeader && 'scale-90'
} transition-all ease-in-out duration-500`}
>
<Image src={Logo} alt="" className="h-8 sm:h-10 w-auto" />
<Image src={Name} alt="Hyperlane" className="hidden sm:block h-8 w-auto mt-1 ml-3" />
<Image src={Explorer} alt="Explorer" className="h-7 sm:h-8 w-auto mt-1 ml-2.5" />
</div>
</Link>
<nav
@ -59,39 +76,38 @@ export function Header({ pathName }: { pathName: string }) {
{/* Dropdown menu, used on mobile */}
<div className="relative flex item-center sm:hidden mr-2">
<DropdownMenu
buttonContent={<Image src={HamburgerIcon} width={22} height={22} alt="..." />}
ButtonContent={DropdownButton}
buttonClasses="hover:opacity-80 active:opacity-70 transition-all"
buttonTitle="Options"
menuItems={[
<Link href="/" className={styles.dropdownOption} key="dropdown-item-home">
<DropdownItemContent icon={HouseIcon} text="Home" />
</Link>,
<Link href="/settings" className={styles.dropdownOption} key="dropdown-item-home">
<DropdownItemContent icon={GearIcon} text="Settings" />
</Link>,
<Link href="/api-docs" className={styles.dropdownOption} key="dropdown-item-api">
<DropdownItemContent icon={DatabaseIcon} text="API" />
</Link>,
<a
className={styles.dropdownOption}
target="_blank"
href={links.docs}
rel="noopener noreferrer"
key="dropdown-item-docs"
>
<DropdownItemContent icon={BookIcon} text="Docs" />
</a>,
<a
className={styles.dropdownOption}
target="_blank"
href={links.home}
rel="noopener noreferrer"
key="dropdown-item-about"
>
<DropdownItemContent icon={InfoIcon} text="About" />
</a>,
(c: Fn) => (
<MobileNavLink href="/" closeDropdown={c} key="Home">
Home
</MobileNavLink>
),
(c: Fn) => (
<MobileNavLink href="/settings" closeDropdown={c} key="Settings">
Settings
</MobileNavLink>
),
(c: Fn) => (
<MobileNavLink href="/api" closeDropdown={c} key="API">
API
</MobileNavLink>
),
(c: Fn) => (
<MobileNavLink href={links.docs} closeDropdown={c} key="Docs">
Docs
</MobileNavLink>
),
(c: Fn) => (
<MobileNavLink href={links.home} closeDropdown={c} key="About">
About
</MobileNavLink>
),
]}
menuClasses="p-2 w-32 right-0"
menuClasses="pt-8 px-8"
isFullscreen={true}
/>
</div>
</div>
@ -99,18 +115,56 @@ export function Header({ pathName }: { pathName: string }) {
);
}
function DropdownItemContent({ icon, text }: { icon: any; text: string }) {
function DropdownButton({ isOpen }: { isOpen: boolean }) {
return (
<div className="px-4 py-1 flex flex-col items-center border border-white bg-pink-500 rounded-lg">
<HyperlaneWideChevron
width={10}
height={14}
direction={isOpen ? 'n' : 's'}
color={Color.White}
classes="transition-all"
/>
<HyperlaneWideChevron
width={10}
height={14}
direction={isOpen ? 'n' : 's'}
color={Color.White}
classes="-mt-1 transition-all"
/>
<HyperlaneWideChevron
width={10}
height={14}
direction={isOpen ? 'n' : 's'}
color={Color.White}
classes="-mt-1 transition-all"
/>
</div>
);
}
function MobileNavLink({
href,
closeDropdown,
children,
}: PropsWithChildren<{ href: string; closeDropdown?: () => void }>) {
const isExternal = href.startsWith('http');
return (
<>
<Image src={icon} width={18} height={18} className="opacity-70 mr-2.5" alt="" />
<span>{text}</span>
</>
<Link
href={href}
className="py-4 pl-3 flex items-center cursor-pointer hover:underline active:opacity-80 decoration-4 decoration-pink-500 underline-offset-[2px] transition-all"
onClick={closeDropdown}
rel={isExternal ? 'noopener noreferrer' : undefined}
target={isExternal ? '_blank' : undefined}
>
<span className="text-2xl font-medium text-white capitalize">{children}</span>
</Link>
);
}
const styles = {
navLink:
'pt-px flex items-center tracking-wide text-[0.95rem] hover:underline hover:opacity-80 active:opacity-70 decoration-2 underline-offset-[6px] transition-all',
'flex items-center font-medium text-white tracking-wide hover:underline active:opacity-80 decoration-4 decoration-pink-500 underline-offset-[2px] transition-all',
dropdownOption:
'flex items-center cursor-pointer p-2 mt-1 rounded text-gray-600 hover:underline decoration-2 underline-offset-4 transition-all',
'flex items-center cursor-pointer p-2 mt-1 rounded text-blue-500 font-medium hover:underline decoration-2 underline-offset-4 transition-all',
};

@ -22,15 +22,15 @@ export function MiniSearchBar() {
return (
<Formik<FormValues> initialValues={initialValues} onSubmit={onSubmit}>
<Form>
<div className="flex items-center bg-white rounded shadow">
<div className="p-1 flex items-center bg-white ring ring-blue-400 hover:ring-blue-200 rounded-full transition-all">
<Field
id="search"
name="search"
type="search"
placeholder="Hash or address"
className="w-32 focus:w-64 py-2 px-2.5 h-8 text-sm rounded placeholder:text-gray-500 focus:outline-none transition-[width] ease-in-out duration-500"
className="w-32 focus:w-64 py-2 px-2.5 h-8 text-sm font-light placeholder:text-gray-600 rounded-full focus:outline-none transition-[width] ease-in-out duration-500"
/>
<div className="h-8 w-8 flex items-center justify-center rounded bg-gray-200">
<div className="h-8 w-8 flex items-center justify-center rounded-full bg-pink-500">
<IconButton
type="submit"
imgSrc={SearchIcon}

@ -3,7 +3,7 @@ import { ChangeEvent } from 'react';
import SearchIcon from '../../images/icons/search.svg';
import XIcon from '../../images/icons/x.svg';
import { Spinner } from '../animation/Spinner';
import { Spinner } from '../animations/Spinner';
import { IconButton } from '../buttons/IconButton';
interface Props {
@ -20,24 +20,29 @@ export function SearchBar({ value, placeholder, onChangeValue, isFetching }: Pro
};
return (
<div className="flex items-center bg-white w-full rounded shadow-md border border-blue-50">
<div className="p-1 flex items-center bg-white w-full rounded-full ring ring-blue-400 hover:ring-blue-200 transition-all duration-500">
<input
value={value}
onChange={onChange}
type="search"
placeholder={placeholder}
className="p-2 sm:px-4 md:px-5 flex-1 h-10 sm:h-12 rounded placeholder:text-gray-500 focus:outline-none"
className="p-1 sm:px-4 md:px-5 flex-1 h-10 sm:h-12 font-light rounded-full placeholder:text-gray-600 focus:outline-none"
/>
<div className="h-10 sm:h-12 w-10 sm:w-12 flex items-center justify-center rounded bg-gray-200">
{isFetching && <Spinner classes="scale-[30%] mr-2.5" />}
<div className="h-10 sm:h-12 w-10 sm:w-12 flex items-center justify-center rounded-full bg-pink-500">
{isFetching && (
<div className="scale-[30%] sm:scale-[35%]">
<Spinner classes="invert" />
</div>
)}
{!isFetching && !value && <Image src={SearchIcon} width={20} height={20} alt="" />}
{!isFetching && value && (
<IconButton
imgSrc={XIcon}
title="Clear search"
width={28}
height={28}
width={16}
height={16}
onClick={() => onChange(null)}
classes="invert"
/>
)}
</div>

@ -7,8 +7,9 @@ import { ChainMetadata, mainnetChainsMetadata, testnetChainsMetadata } from '@hy
import { getChainDisplayName } from '../../features/chains/utils';
import { useMultiProvider } from '../../features/providers/multiProvider';
import GearIcon from '../../images/icons/gear.svg';
import { Color } from '../../styles/Color';
import { arrayToObject } from '../../utils/objects';
import { BorderedButton } from '../buttons/BorderedButton';
import { SolidButton } from '../buttons/SolidButton';
import { TextButton } from '../buttons/TextButton';
import { ChainLogo } from '../icons/ChainLogo';
import { ChevronIcon } from '../icons/Chevron';
@ -61,15 +62,10 @@ export function SearchFilterBar({
endValue={endTimestamp}
onChangeEndValue={onChangeEndTimestamp}
/>
<div className="w-px h-8 bg-gray-200"></div>
<Link href="/settings" title="View explorer settings">
<Image
src={GearIcon}
width={24}
height={24}
className="opacity-40 hover:opacity-30 active:opacity-20 hover:rotate-90 transition-all"
alt=""
/>
<div className="p-1.5 bg-pink-500 rounded-full active:opacity-90 hover:rotate-90 transition-all">
<Image src={GearIcon} width={16} height={16} className="invert" alt="Settings" />
</div>
</Link>
</div>
);
@ -151,23 +147,26 @@ function ChainMultiSelector({
<DropdownModal
buttonContent={
<>
<span className="text-gray-700 py-px">{text}</span>
<ChevronIcon direction="s" width={9} height={5} classes="ml-2 opacity-80" />
<span className="text-white font-medium py-px">{text}</span>
<ChevronIcon
direction="s"
width={9}
height={5}
classes="ml-2 opacity-80"
color={Color.White}
/>
</>
}
buttonClasses="text-sm sm:min-w-[5.8rem] px-1 sm:px-2.5 py-0.5 flex items-center justify-center rounded border border-gray-500 hover:opacity-70 active:opacity-60 transition-all"
buttonClasses="text-sm sm:min-w-[5.8rem] px-1 sm:px-2.5 py-0.5 flex items-center justify-center rounded-full bg-pink-500 hover:opacity-80 active:opacity-70 transition-all"
modalContent={(closeDropdown) => (
<div className="p-4">
<div className="flex items-center justify-between">
<h3 className="text-gray-700 text-lg">{header}</h3>
<h3 className="font-medium text-blue-500">{header}</h3>
<div className="flex mr-4">
<TextButton classes="text-sm underline underline-offset-2" onClick={onToggleAll}>
<TextButton classes="text-sm font-medium text-pink-500" onClick={onToggleAll}>
All
</TextButton>
<TextButton
classes="ml-3.5 text-sm underline underline-offset-2"
onClick={onToggleNone}
>
<TextButton classes="ml-3.5 text-sm font-medium text-pink-500" onClick={onToggleNone}>
None
</TextButton>
</div>
@ -180,7 +179,7 @@ function ChainMultiSelector({
onToggle={onToggleSection(mainnetChainsMetadata)}
name="mainnet-chains"
>
<h4 className="ml-2 text-gray-700">Mainnet Chains</h4>
<h4 className="ml-2 text-gray-800">Mainnet Chains</h4>
</CheckBox>
</div>
{mainnetChainsMetadata.map((c) => (
@ -191,7 +190,7 @@ function ChainMultiSelector({
name={c.name}
>
<div className="py-0.5 ml-2 text-sm flex items-center">
<span className="mr-2">
<span className="mr-2 font-light">
{getChainDisplayName(multiProvider, c.chainId, true)}
</span>
<ChainLogo chainId={c.chainId} size={12} color={false} background={false} />
@ -207,7 +206,7 @@ function ChainMultiSelector({
onToggle={onToggleSection(testnetChainsMetadata)}
name="testnet-chains"
>
<h4 className="ml-2 text-gray-700">Testnet Chains</h4>
<h4 className="ml-2 text-gray-800">Testnet Chains</h4>
</CheckBox>
</div>
{testnetChainsMetadata.map((c) => (
@ -218,7 +217,7 @@ function ChainMultiSelector({
name={c.name}
>
<div className="py-0.5 ml-2 text-sm flex items-center">
<span className="mr-2">
<span className="mr-2 font-light">
{getChainDisplayName(multiProvider, c.chainId, true)}
</span>
<ChainLogo chainId={c.chainId} size={12} color={false} background={false} />
@ -227,12 +226,12 @@ function ChainMultiSelector({
))}
</div>
</div>
<BorderedButton
<SolidButton
classes="mt-2.5 text-sm px-2 py-1 w-full"
onClick={() => onClickApply(closeDropdown)}
>
Apply
</BorderedButton>
</SolidButton>
</div>
)}
modalClasses={`w-88 ${position || 'right-0'}`}
@ -270,33 +269,39 @@ function DatetimeSelector({
<DropdownModal
buttonContent={
<>
<span className="text-gray-700 py-px px-2">Time</span>
<ChevronIcon direction="s" width={9} height={5} classes="ml-2 opacity-80" />
<span className="text-white font-medium py-px px-2">Time</span>
<ChevronIcon
direction="s"
width={9}
height={5}
classes="ml-2 opacity-80"
color={Color.White}
/>
</>
}
buttonClasses="text-sm px-1 sm:px-2.5 py-0.5 flex items-center justify-center rounded border border-gray-500 hover:opacity-70 active:opacity-60 transition-all"
buttonClasses="text-sm px-1 sm:px-2.5 py-0.5 flex items-center justify-center rounded-full bg-pink-500 hover:opacity-80 active:opacity-70 transition-all"
modalContent={(closeDropdown) => (
<div className="p-4" key="date-time-selector">
<div className="flex items-center justify-between">
<h3 className="text-gray-700 text-lg">Time Range</h3>
<h3 className="text-blue-500 font-medium">Time Range</h3>
<div className="flex pt-1">
<TextButton classes="text-sm underline underline-offset-2" onClick={onClickClear}>
<TextButton classes="text-sm font-medium text-pink-500" onClick={onClickClear}>
Clear
</TextButton>
</div>
</div>
<div className="flex flex-col">
<h4 className="mt-3 mb-1 text-gray-700">Start Time</h4>
<h4 className="mt-3 mb-1 text-gray-500 text-sm font-medium">Start Time</h4>
<DatetimeField timestamp={startTime} onChange={setStartTime} />
<h4 className="mt-3 mb-1 text-gray-700">End Time</h4>
<h4 className="mt-3 mb-1 text-gray-500 text-sm font-medium">End Time</h4>
<DatetimeField timestamp={endTime} onChange={setEndTime} />
</div>
<BorderedButton
<SolidButton
classes="mt-4 text-sm px-2 py-1 w-full"
onClick={() => onClickApply(closeDropdown)}
>
Apply
</BorderedButton>
</SolidButton>
</div>
)}
modalClasses="w-60 -right-8"

@ -4,8 +4,8 @@ import BugIcon from '../../images/icons/bug.svg';
import ErrorIcon from '../../images/icons/error-circle.svg';
import SearchOffIcon from '../../images/icons/search-off.svg';
import ShrugIcon from '../../images/icons/shrug.svg';
import { Fade } from '../animation/Fade';
import { Spinner } from '../animation/Spinner';
import { Fade } from '../animations/Fade';
import { Spinner } from '../animations/Spinner';
export function SearchFetching({ show, isPiFetching }: { show: boolean; isPiFetching?: boolean }) {
return (
@ -17,7 +17,7 @@ export function SearchFetching({ show, isPiFetching }: { show: boolean; isPiFetc
<div className="flex items-center justify-center scale-90">
<Spinner />
</div>
<div className="mt-4 text-center leading-loose text-gray-700">
<div className="mt-4 text-center font-light leading-loose text-gray-700">
{isPiFetching ? 'Searching custom chains for messages' : 'Searching for messages'}
</div>
</div>
@ -45,7 +45,7 @@ export function SearchError({
<div className="flex justify-center my-10">
<div className="flex flex-col items-center justify-center max-w-md px-3 py-5">
<Image src={imgSrc} width={imgWidth} className="opacity-80" alt="" />
<div className="mt-4 text-center leading-loose text-gray-700">{text}</div>
<div className="mt-4 text-center font-light leading-loose text-gray-700">{text}</div>
</div>
</div>
</Fade>

@ -1,4 +1,5 @@
export const links = {
baseUrl: 'https://www.hyperlane.xyz',
home: 'https://www.hyperlane.xyz',
discord: 'https://discord.gg/VK9ZUy3aTV',
github: 'https://github.com/hyperlane-xyz',
@ -9,4 +10,6 @@ export const links = {
blog: 'https://medium.com/hyperlane',
tenderlySimDocs:
'https://docs.tenderly.co/simulations-and-forks/how-to-simulate-a-transaction/using-simulation-ui',
brand:
'https://www.figma.com/file/jC5NORmNDCl6WZgjIRwKX5/Hyperlane-Brand-Assets-%5BExternal%5D?type=design&node-id=0-1&t=6eez9F8gttV7L6VG-0',
};

@ -57,8 +57,8 @@ export function ConfigureChains() {
return (
<Card>
<h2 className="mt-1 text-xl text-blue-500">Chain Settings</h2>
<p className="mt-3">
<h2 className="mt-1 text-lg text-blue-500 font-medium">Chain Settings</h2>
<p className="mt-3 font-light">
Hyperlane can be deployed to any chain using{' '}
<a
href={`${links.docs}/docs/deploy/permissionless-interoperability`}
@ -70,31 +70,35 @@ export function ConfigureChains() {
</a>
. This explorer can be configured to search for messages on any PI chain.
</p>
<h3 className="mt-4 text-lg text-blue-500">Default Chains</h3>
<h3 className="mt-6 text-lg text-blue-500 font-medium">Default Chains</h3>
<div className="mt-4 flex">
<h4 className="text-gray-600">Mainnets:</h4>
<h4 className="text-gray-600 font-medium text-sm">Mainnets:</h4>
<div className="ml-3 flex gap-3.5 flex-wrap">
{mainnetChainsMetadata.map((c) => (
<div className="shrink-0 text-sm flex items-center" key={c.name}>
<ChainLogo chainId={c.chainId} size={15} color={true} background={false} />
<span className="ml-1.5">{getChainDisplayName(multiProvider, c.chainId, true)}</span>
<span className="ml-1.5 font-light">
{getChainDisplayName(multiProvider, c.chainId, true)}
</span>
</div>
))}
</div>
</div>
<div className="mt-4 flex">
<h4 className="text-gray-600">Testnets:</h4>
<div className="mt-5 flex">
<h4 className="text-gray-600 font-medium text-sm">Testnets:</h4>
<div className="ml-3 flex gap-3.5 flex-wrap">
{testnetChainsMetadata.map((c) => (
<div className="shrink-0 text-sm flex items-center" key={c.name}>
<ChainLogo chainId={c.chainId} size={15} color={true} background={false} />
<div className="ml-1.5">{getChainDisplayName(multiProvider, c.chainId, true)}</div>
<div className="ml-1.5 font-light">
{getChainDisplayName(multiProvider, c.chainId, true)}
</div>
</div>
))}
</div>
</div>
<h3 className="mt-4 text-lg text-blue-500">Custom Chains</h3>
<table className="mt-4 w-full">
<h3 className="mt-6 text-lg text-blue-500 font-medium">Custom Chains</h3>
<table className="mt-2 w-full">
<thead>
<tr>
<th className={styles.header}>Chain</th>
@ -141,7 +145,7 @@ export function ConfigureChains() {
title="Add Custom Chain"
maxWidth="max-w-xl"
>
<p className="mt-2">
<p className="mt-2 font-light">
Input a chain metadata config including core contract addresses to enable exploration of
that chain. See{' '}
<a
@ -156,7 +160,7 @@ export function ConfigureChains() {
</p>
<div className="relative mt-4">
<textarea
className="w-full min-h-[20rem] p-2 border border-gray-400 rounded text-sm focus:outline-none"
className="w-full min-h-[20rem] p-2 border border-gray-400 rounded-xl text-sm font-light focus:outline-none"
placeholder={customChainTextareaPlaceholder}
value={customChainInput}
onChange={onCustomChainInputChange}
@ -165,7 +169,7 @@ export function ConfigureChains() {
copyValue={customChainInput || customChainTextareaPlaceholder}
width={16}
height={16}
classes="absolute top-2 right-2"
classes="absolute top-3 right-3"
/>
</div>
{chainInputErr && <div className="mt-2 text-red-600 text-sm">{chainInputErr}</div>}
@ -197,7 +201,7 @@ const customChainTextareaPlaceholder = `{
`;
const styles = {
header: 'text-sm text-gray-700 font-normal pt-2 pb-1 text-left',
value: 'py-4 text-sm px-1',
valueTruncated: 'py-4 text-sm truncate',
header: 'pt-2 pb-1 text-sm text-gray-700 font-normal text-left',
value: 'py-4 px-1 text-sm font-light',
valueTruncated: 'py-4 text-sm font-light truncate',
};

@ -2,12 +2,13 @@ import Image from 'next/image';
import { useEffect, useState } from 'react';
import { toast } from 'react-toastify';
import { Spinner } from '../../components/animation/Spinner';
import { Spinner } from '../../components/animations/Spinner';
import { Card } from '../../components/layout/Card';
import CheckmarkIcon from '../../images/icons/checkmark-circle.svg';
import { useStore } from '../../store';
import { Message, MessageStatus } from '../../types';
import { logger } from '../../utils/logger';
import { toTitleCase } from '../../utils/string';
import { toTitleCase, trimToLength } from '../../utils/string';
import { getChainDisplayName } from '../chains/utils';
import { useMessageDeliveryStatus } from '../deliveryStatus/useMessageDeliveryStatus';
import { useMultiProvider } from '../providers/multiProvider';
@ -75,7 +76,14 @@ export function MessageDetails({ messageId, message: messageFromUrlParams }: Pro
pause: !isMessageFound,
});
const { status, originChainId, destinationChainId: destChainId, origin, destination } = message;
const {
msgId,
status,
originChainId,
destinationChainId: destChainId,
origin,
destination,
} = message;
// Mark delivery found to prevent pause queries
useEffect(() => {
@ -87,18 +95,21 @@ export function MessageDetails({ messageId, message: messageFromUrlParams }: Pro
return (
<>
<div className="flex items-center justify-between px-1">
<h2 className="text-white text-lg">{`${
<Card className="flex items-center justify-between px-1 rounded-full">
<h2 className="text-blue-500 font-medium">{`${
isIcaMsg ? 'ICA ' : ''
} Message to ${getChainDisplayName(multiProvider, destChainId)}`}</h2>
} Message ${trimToLength(msgId, 6)} to ${getChainDisplayName(
multiProvider,
destChainId,
)}`}</h2>
<StatusHeader
messageStatus={status}
isMessageFound={isMessageFound}
isFetching={isFetching}
isError={isError}
/>
</div>
<div className="flex flex-wrap items-stretch justify-between mt-5 gap-3">
</Card>
<div className="flex flex-wrap items-stretch justify-between mt-3 md:mt-4 gap-3 md:gap-4">
<OriginTransactionCard chainId={originChainId} transaction={origin} blur={blur} />
<DestinationTransactionCard
chainId={destChainId}
@ -150,7 +161,7 @@ function StatusHeader({
icon = (
<div className="w-7 h-7 overflow-hidden flex items-center justify-center">
<div className="scale-[35%]">
<Spinner white={true} />
<Spinner />
</div>
</div>
);
@ -163,7 +174,7 @@ function StatusHeader({
return (
<div className="flex items-center">
<h3 className="text-white text-lg mr-3">{text}</h3>
<h3 className="text-blue-500 font-medium lg mr-3">{text}</h3>
{icon}
</div>
);

@ -1,6 +1,7 @@
import { useState } from 'react';
import { Fade } from '../../components/animation/Fade';
import { Fade } from '../../components/animations/Fade';
import { Card } from '../../components/layout/Card';
import { SearchBar } from '../../components/search/SearchBar';
import { SearchFilterBar } from '../../components/search/SearchFilterBar';
import {
@ -75,9 +76,9 @@ export function MessageSearch() {
isFetching={isAnyFetching}
placeholder="Search by address, hash, or message id"
/>
<div className="w-full min-h-[38rem] mt-5 bg-white shadow-md border rounded overflow-auto relative">
<div className="px-2 py-3 sm:px-4 md:px-5 flex items-center justify-between">
<h2 className="w-min sm:w-fit pl-0.5 text-gray-700">
<Card className="relative w-full min-h-[38rem] mt-4" padding="">
<div className="px-2 pt-3.5 pb-3 sm:px-4 md:px-5 flex items-center justify-between">
<h2 className="w-min sm:w-fit pl-0.5 text-blue-500 font-medium">
{!hasInput ? 'Latest Messages' : 'Search Results'}
</h2>
<SearchFilterBar
@ -105,7 +106,7 @@ export function MessageSearch() {
/>
<SearchUnknownError show={isAnyError && isValidInput} />
<SearchInvalidError show={!isValidInput} allowAddress={true} />
</div>
</Card>
</>
);
}

@ -38,7 +38,7 @@ export function MessageTable({
{messageList.map((m) => (
<tr
key={`message-${m.id}`}
className={`cursor-pointer hover:bg-gray-100 active:bg-gray-200 border-b border-gray-100 last:border-0 ${
className={`cursor-pointer hover:bg-pink-50 active:bg-pink-100 border-b border-blue-50 last:border-0 ${
isFetching && 'blur-xs'
} transition-all duration-500`}
>
@ -62,10 +62,10 @@ export function MessageSummaryRow({ message, mp }: { message: MessageStub; mp: M
destination,
} = message;
let statusColor = 'bg-beige-500';
let statusColor = 'bg-blue-50 text-gray-700';
let statusText = 'Pending';
if (status === MessageStatus.Delivered) {
statusColor = 'bg-green-400 text-white';
statusColor = 'bg-[#14825d] text-white';
statusText = 'Delivered';
} else if (status === MessageStatus.Failing) {
statusColor = 'bg-red-500 text-white';
@ -107,7 +107,9 @@ export function MessageSummaryRow({ message, mp }: { message: MessageStub; mp: M
: '-'}
</LinkCell>
<LinkCell id={msgId} base64={base64} aClasses="flex items-center justify-center">
<div className={`text-center w-20 md:w-[5.25rem] py-1.5 text-sm rounded ${statusColor}`}>
<div
className={`text-center w-20 md:w-[5.25rem] py-1.5 text-sm rounded-full ${statusColor}`}
>
{statusText}
</div>
</LinkCell>
@ -134,8 +136,8 @@ function LinkCell({
}
const styles = {
header: 'text-sm text-gray-700 font-normal pt-2 pb-3 text-center',
value: 'py-3.5 flex items-center justify-center text-sm text-center px-1',
valueTruncated: 'py-3.5 flex items-center justify-center text-sm text-center truncate',
chainName: 'text-sm ml-2',
header: 'text-sm text-blue-500 font-medium pt-2 pb-3 text-center',
value: 'py-3.5 flex items-center justify-center text-sm text-center font-light px-1',
valueTruncated: 'py-3.5 flex items-center justify-center text-sm text-center font-light truncate',
chainName: 'text-sm font-light ml-2',
};

@ -67,11 +67,11 @@ export function ContentDetailsCard({
}, [nonce, originDomainId, sender, destinationDomainId, recipient, body]);
return (
<Card classes="w-full space-y-4">
<Card className="w-full space-y-4">
<div className="flex items-center justify-between">
<Image src={EnvelopeInfo} width={28} height={28} alt="" className="opacity-80" />
<div className="flex items-center pb-1">
<h3 className="text-gray-500 font-medium text-md mr-2">Message Details</h3>
<h3 className="text-blue-500 font-medium text-md mr-2">Message Details</h3>
<HelpIcon
size={16}
text="Immutable information about the message itself such as its contents."

@ -69,18 +69,18 @@ export function GasDetailsCard({ message, blur, igpPayments = {} }: Props) {
}, [unit, message, igpPayments]);
return (
<Card classes="w-full space-y-4 relative">
<Card className="w-full space-y-4 relative">
<div className="flex items-center justify-between">
<Image src={FuelPump} width={24} height={24} alt="" className="opacity-80" />
<div className="flex items-center pb-1">
<h3 className="text-gray-500 font-medium text-md mr-2">Interchain Gas Payments</h3>
<h3 className="text-blue-500 font-medium text-md mr-2">Interchain Gas Payments</h3>
<HelpIcon
size={16}
text="Amounts paid to the Interchain Gas Paymaster for message delivery."
/>
</div>
</div>
<p className="text-sm">
<p className="text-sm font-light">
Interchain gas payments are required to fund message delivery on the destination chain.{' '}
<a
href={`${links.docs}/docs/protocol/interchain-gas-payments`}

@ -24,13 +24,13 @@ export function IcaDetailsCard({ message: { originDomainId, body }, blur }: Prop
} = useIcaAddress(originDomainId, decodeResult?.sender);
return (
<Card classes="w-full space-y-4">
<Card className="w-full space-y-4">
<div className="flex items-center justify-between">
<div className="relative -top-px -left-0.5">
<Image src={AccountStar} width={28} height={28} alt="" className="opacity-80" />
</div>
<div className="flex items-center pb-1">
<h3 className="text-gray-500 font-medium text-md mr-2">ICA Details</h3>
<h3 className="text-blue-500 font-medium text-md mr-2">ICA Details</h3>
<HelpIcon size={16} text="Extra information for messages from/to Interchain Accounts." />
</div>
</div>

@ -16,18 +16,18 @@ interface Props {
export function IsmDetailsCard({ ismDetails, blur }: Props) {
return (
<Card classes="w-full space-y-4 relative">
<Card className="w-full space-y-4 relative">
<div className="flex items-center justify-between">
<Image src={ShieldLock} width={24} height={24} alt="" className="opacity-80" />
<div className="flex items-center pb-1">
<h3 className="text-gray-500 font-medium text-md mr-2">Interchain Security Modules</h3>
<h3 className="text-blue-500 font-medium text-md mr-2">Interchain Security Modules</h3>
<HelpIcon
size={16}
text="Details about the Interchain Security Modules (ISM) that must verify this message."
/>
</div>
</div>
<p className="text-sm">
<p className="text-sm font-light">
Interchain Security Modules define the rules for verifying messages before delivery.{' '}
<a
href={`${links.docs}/docs/protocol/sovereign-consensus`}

@ -26,7 +26,7 @@ export function KeyValueRow({
}: Props) {
const useFallbackVal = isZeroish(display) && !allowZeroish;
return (
<div className={`flex items-center pl-px ${classes}`}>
<div className={`flex items-center pl-px font-light ${classes}`}>
<label className={`text-sm text-gray-500 ${labelWidth}`}>{label}</label>
<div className={`text-sm ml-1 truncate ${displayWidth || ''} ${blurValue && 'blur-xs'}`}>
<span>{!useFallbackVal ? display : 'Unknown'}</span>

@ -12,12 +12,12 @@ export function TimelineCard({ message, blur }: Props) {
const { stage, timings } = useMessageStage({ message });
return (
<Card classes="w-full">
<Card className="w-full">
{/* <div className="flex items-center justify-end">
<h3 className="text-gray-500 font-medium text-md mr-2">Delivery Timeline</h3>
<HelpIcon size={16} text="A breakdown of the stages for delivering a message" />
</div> */}
<div className={`-mx-2 sm:mx-0 -my-2 ${blur && 'blur-xs'}`}>
<div className={`-mx-2 sm:mx-0 -my-2 font-light ${blur && 'blur-xs'}`}>
<MessageTimeline status={message.status} stage={stage} timings={timings} />
</div>
</Card>

@ -1,6 +1,6 @@
import { PropsWithChildren, ReactNode, useState } from 'react';
import { Spinner } from '../../../components/animation/Spinner';
import { Spinner } from '../../../components/animations/Spinner';
import { ChainLogo } from '../../../components/icons/ChainLogo';
import { HelpIcon } from '../../../components/icons/HelpIcon';
import { Card } from '../../../components/layout/Card';
@ -76,14 +76,16 @@ export function DestinationTransactionCard({
} else if (status === MessageStatus.Pending) {
content = (
<DeliveryStatus>
<div>Delivery to destination chain still in progress.</div>
{isPiMsg && (
<div className="mt-2 text-gray-700 text-sm max-w-xs">
Please ensure a relayer is running for this chain.
</div>
)}
<Spinner classes="mt-4 scale-75" />
<CallDataModal debugResult={debugResult} />
<div className="flex flex-col items-center">
<div>Delivery to destination chain still in progress.</div>
{isPiMsg && (
<div className="mt-2 text-gray-700 text-sm max-w-xs">
Please ensure a relayer is running for this chain.
</div>
)}
<Spinner classes="my-4 scale-75" />
<CallDataModal debugResult={debugResult} />
</div>
</DeliveryStatus>
);
} else {
@ -116,13 +118,13 @@ function TransactionCard({
children,
}: PropsWithChildren<{ chainId: ChainId; title: string; helpText: string }>) {
return (
<Card classes="flex flex-col flex-1 min-w-fit space-y-3">
<Card className="flex flex-col flex-1 min-w-fit space-y-3">
<div className="flex items-center justify-between">
<div className="relative -top-px -left-0.5">
<ChainLogo chainId={chainId} />
</div>
<div className="flex items-center pb-1">
<h3 className="text-gray-500 font-medium text-md mr-2">{title}</h3>
<h3 className="text-blue-500 font-medium text-md mr-2">{title}</h3>
<HelpIcon size={16} text={helpText} />
</div>
</div>
@ -199,7 +201,7 @@ function TransactionDetails({
function DeliveryStatus({ children }: PropsWithChildren<unknown>) {
return (
<div className="pb-2 flex-1 flex flex-col items-center justify-center text-gray-500 text-center">
<div className="pb-2 flex-1 flex flex-col items-center justify-center text-gray-500 font-light text-center">
<div className="max-w-sm">{children}</div>
</div>
);
@ -221,7 +223,7 @@ function CallDataModal({ debugResult }: { debugResult?: MessageDebugResult }) {
maxWidth="max-w-sm sm:max-w-md"
>
<div className="mt-2 flex flex-col space-y-3.5">
<p className="text-sm">
<p className="text-sm font-light">
{`The last step of message delivery is the recipient contract's 'handle' function. If the handle reverting, try debugging it with `}
<a
className={`${styles.textLink} any:text-blue-500`}

@ -15,7 +15,7 @@ import { parseMessageQueryResult, parseMessageStubResult } from '../queries/pars
const SEARCH_AUTO_REFRESH_DELAY = 15000;
const MSG_AUTO_REFRESH_DELAY = 10000;
const LATEST_QUERY_LIMIT = 30;
const LATEST_QUERY_LIMIT = 20;
const SEARCH_QUERY_LIMIT = 50;
export function isValidSearchQuery(input: string, allowAddress?: boolean) {

1
src/global.d.ts vendored

@ -3,3 +3,4 @@ declare type HexString = string;
declare type ChainId = number;
declare type DomainId = number;
declare type AddressTo<T> = Record<Address, T>;
declare type Fn = () => void;

@ -0,0 +1,3 @@
<svg viewBox="0 0 1440 231" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0L83.5 49.5L211 104.5L351.5 150.5L541.5 189.5L726.5 203H845.5L957 195L1102 174.5L1241 143.5L1378 100L1441.5 75H1457.5L1463 744H0V0Z" fill="#D631B9"/>
</svg>

After

Width:  |  Height:  |  Size: 245 B

@ -0,0 +1,3 @@
<svg width="493" height="104" viewBox="0 0 493 104" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M-2.5 11.5C-2.5 11.5 849.5 -42 311.5 112.5" stroke="white" stroke-width="5"/>
</svg>

After

Width:  |  Height:  |  Size: 194 B

@ -0,0 +1,3 @@
<svg width="341" height="118" viewBox="0 0 341 118" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M-5 7.43544C-5 7.43544 774.5 -34.0002 -14 116.5" stroke="white" stroke-width="3"/>
</svg>

After

Width:  |  Height:  |  Size: 199 B

@ -0,0 +1 @@
<svg width="1440" height="252" viewBox="0 0 1440 252" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1466 2C892.94 292.699 474.5 309.5 -0.5 45" stroke="white" stroke-width="4" opacity="1" pathLength="1" stroke-dashoffset="0px" stroke-dasharray="1px 1px"></path><path d="M1531.5 78.5C966.144 351.535 306.5 263.612 -24 28" stroke="white" stroke-width="8" opacity="1" pathLength="1" stroke-dashoffset="0px" stroke-dasharray="1px 1px"></path></svg>

After

Width:  |  Height:  |  Size: 454 B

@ -0,0 +1,4 @@
<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>

After

Width:  |  Height:  |  Size: 290 B

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="#FFFFFF" class="bi bi-check2-circle" viewBox="0 0 16 16">
<svg xmlns="http://www.w3.org/2000/svg" fill="#2362C1" class="bi bi-check2-circle" viewBox="0 0 16 16">
<path d="M2.5 8a5.5 5.5 0 0 1 8.25-4.764.5.5 0 0 0 .5-.866A6.5 6.5 0 1 0 14.5 8a.5.5 0 0 0-1 0 5.5 5.5 0 1 1-11 0z"/>
<path d="M15.354 3.354a.5.5 0 0 0-.708-.708L8 9.293 5.354 6.646a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l7-7z"/>
</svg>

Before

Width:  |  Height:  |  Size: 346 B

After

Width:  |  Height:  |  Size: 346 B

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48" viewBox="6 5.949999809265137 36 36"><path d="M39.8 41.95 26.65 28.8q-1.5 1.3-3.5 2.025-2 .725-4.25.725-5.4 0-9.15-3.75T6 18.75q0-5.3 3.75-9.05 3.75-3.75 9.1-3.75 5.3 0 9.025 3.75 3.725 3.75 3.725 9.05 0 2.15-.7 4.15-.7 2-2.1 3.75L42 39.75Zm-20.95-13.4q4.05 0 6.9-2.875Q28.6 22.8 28.6 18.75t-2.85-6.925Q22.9 8.95 18.85 8.95q-4.1 0-6.975 2.875T9 18.75q0 4.05 2.875 6.925t6.975 2.875Z"></path></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="37" height="37" fill="none"><path fill="#fff" d="m35.86 31.55-7.95-7.95a15.12 15.12 0 0 0-1.94-18.98 15.12 15.12 0 0 0-21.35 0 15.12 15.12 0 0 0 0 21.35 15.09 15.09 0 0 0 18.98 1.94l7.95 7.95a3.04 3.04 0 0 0 4.31 0 3.05 3.05 0 0 0 0-4.3ZM8.93 21.66A9.02 9.02 0 0 1 21.66 8.93a9.02 9.02 0 0 1 0 12.73 9.02 9.02 0 0 1-12.73 0Z"/></svg>

Before

Width:  |  Height:  |  Size: 459 B

After

Width:  |  Height:  |  Size: 380 B

@ -1,3 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#2E3338" viewBox="0 0 16 16">
<path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="20.24 19.95 56.33 56.24"><path d="M27.73 76.19a7.5 7.5 0 0 1-5.3-12.8l41.34-41.34a7.5 7.5 0 0 1 10.6 10.61L33 74a7.48 7.48 0 0 1-5.27 2.19Z"/><path d="M69.07 76.19a7.48 7.48 0 0 1-5.3-2.2L22.43 32.66A7.5 7.5 0 0 1 33 22.05l41.37 41.34a7.5 7.5 0 0 1-5.3 12.8Z"/></svg>

Before

Width:  |  Height:  |  Size: 311 B

After

Width:  |  Height:  |  Size: 316 B

@ -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

@ -1 +1 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 122 32"><path d="M.97 22.92h2.74V4.15H.98V3.08h17.68v5.96h-1.07c-.04-.75-.1-1.42-.19-2-.08-.6-.25-1.1-.52-1.51-.53-.84-1.6-1.3-3.23-1.38H7.4v8.58h3.41a3.5 3.5 0 0 0 1.78-.36c.42-.26.68-.7.77-1.33l.04-.58.05-.61h1.15v7.05h-1.15a37.27 37.27 0 0 1-.1-1.4c-.08-.63-.34-1.07-.77-1.32a3.4 3.4 0 0 0-1.77-.38H7.4v9.13h5.85c2.4 0 3.85-1.1 4.36-3.32.15-.64.24-1.3.29-1.97h1.06V24H.97v-1.08Z" fill="#2362C1"/><path d="M21.1 22.93H23l4.28-5.08-5.07-6.77h-1.36v-1.07h7.3v1.07H26.2l3.23 4.27 3.51-4.27h-1.9v-1.07h4.98v1.07h-1.56l-4.34 5.18 5.08 6.67h1.38V24h-7.24v-1.07h1.75L28 18.76l-3.45 4.17h1.82V24H21.1v-1.07Z" fill="#2362C1"/><path d="M42.66 11.5c1.05-1.14 2.67-1.72 4.84-1.72a6.38 6.38 0 0 1 4.29 1.73c1.28 1.28 1.91 3.07 1.91 5.38 0 2.3-.66 4.12-1.98 5.43a6.63 6.63 0 0 1-4.84 1.95 7.61 7.61 0 0 1-3.38-.75 4.6 4.6 0 0 1-.84-.52v7.59h2.47v1.07h-8.08v-1.07h2.05V11.11h-2.18V10h5.74v1.5Zm3.65 11.6c2.38 0 3.57-2 3.57-6.02 0-2.98-.65-4.86-1.93-5.63a3.15 3.15 0 0 0-1.71-.4 4 4 0 0 0-2.01.6 4.7 4.7 0 0 0-1.57 1.5v8.39a4.9 4.9 0 0 0 2.7 1.45c.32.07.64.1.95.1Z" fill="#2362C1"/><path d="M55.17 22.93h2.13V2.06h-2.23V.98h5.85v21.95h2.3V24h-8.05v-1.07Z" fill="#2362C1"/><path d="M64.12 17c0-2.15.69-3.9 2.05-5.22a7.1 7.1 0 0 1 5.16-2c2.08 0 3.79.67 5.13 2A6.98 6.98 0 0 1 78.48 17c0 2.15-.67 3.9-2.01 5.25a6.89 6.89 0 0 1-5.13 2.02 7.07 7.07 0 0 1-5.18-2.02A7.08 7.08 0 0 1 64.12 17Zm7.18 6.14c1.84 0 2.92-1.25 3.24-3.76.1-.75.14-1.55.14-2.4 0-1.93-.22-3.37-.66-4.33a2.79 2.79 0 0 0-2.72-1.72c-1.84 0-2.92 1.21-3.24 3.64-.09.73-.14 1.54-.14 2.4 0 1.93.22 3.4.66 4.38a2.8 2.8 0 0 0 2.72 1.79Z" fill="#2362C1"/><path d="M85.71 11.9a6.76 6.76 0 0 1 4.76-2.12c.55 0 1.03.18 1.45.55.42.36.63.83.63 1.4s-.18 1.03-.54 1.39c-.35.35-.78.53-1.3.53a1.8 1.8 0 0 1-1.3-.52 1.8 1.8 0 0 1-.51-1.31c0-.21.03-.43.1-.64a7.2 7.2 0 0 0-3.29 2.03v9.74h3V24h-8.62v-1.05h2.04V11.08h-2.05v-1.07h5.63v1.89Z" fill="#2362C1"/><path d="M107 21.6c-1.43 1.78-3.47 2.67-6.11 2.67a7.6 7.6 0 0 1-5.16-2.07 7.05 7.05 0 0 1-2.06-5.23c0-2.12.7-3.85 2.08-5.18a7.3 7.3 0 0 1 5.28-2c3.13 0 5.1 1.32 5.91 3.94.27.84.4 1.78.4 2.83h-9.9v.41c0 2.82.8 4.67 2.4 5.55.53.3 1.18.45 1.92.45 1.66 0 3.17-.67 4.52-2.02l.72.66Zm-3.34-6.16a7.15 7.15 0 0 0-.67-3.33c-.42-.78-1.13-1.17-2.1-1.17-1.98 0-3.1 1.5-3.38 4.5h6.15Z" fill="#2362C1"/><path d="M114.92 11.9a6.76 6.76 0 0 1 4.75-2.12c.55 0 1.03.18 1.45.55.42.36.63.83.63 1.4s-.18 1.03-.53 1.39c-.36.35-.79.53-1.3.53s-.94-.17-1.3-.52c-.34-.35-.52-.8-.52-1.31 0-.21.04-.43.11-.64a7.2 7.2 0 0 0-3.3 2.03v9.74h3V24h-8.61v-1.05h2.03V11.08h-2.05v-1.07h5.64v1.89Z" fill="#2362C1"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="2.64 13.68 182.04 42.38"><path fill="#D631B9" d="M2.64 48V13.68h25.25v5.86H9.6v7.68h16.03v5.7H9.6v9.27h18.43V48H2.64Zm27.46 0 8.98-13.06-8.02-11.56h7.44l4.37 7.05h.1l4.12-7.05h6.77L46.23 34.9 55.01 48h-7.77l-4.56-8.16h-.1L37.25 48H30.1Zm27.42 8.06V23.38h6.29v3.07h.14a8.55 8.55 0 0 1 7.25-3.75 9.5 9.5 0 0 1 7.77 3.6c1.96 2.4 2.93 5.54 2.93 9.41 0 3.97-.97 7.14-2.93 9.5a9.57 9.57 0 0 1-7.72 3.51c-3.2 0-5.57-1.17-7.1-3.5h-.1v10.84h-6.53ZM69.85 43.3c1.67 0 2.98-.66 3.94-1.97 1-1.31 1.49-3.12 1.49-5.43 0-2.46-.47-4.4-1.4-5.8-.92-1.41-2.35-2.12-4.27-2.12-1.95 0-3.39.74-4.32 2.21-.92 1.44-1.39 3.35-1.39 5.71 0 2.28.51 4.08 1.54 5.43a5.27 5.27 0 0 0 4.41 1.97ZM85.04 48V13.68h6.52V48h-6.52Zm31.75-2.98c-2.4 2.47-5.49 3.7-9.26 3.7-3.78 0-6.87-1.23-9.27-3.7a12.9 12.9 0 0 1-3.6-9.3c0-3.72 1.2-6.8 3.6-9.27 2.4-2.5 5.49-3.75 9.27-3.75 3.77 0 6.86 1.25 9.26 3.75 2.4 2.46 3.6 5.55 3.6 9.26s-1.2 6.82-3.6 9.31Zm-9.26-1.3c1.95 0 3.47-.71 4.56-2.15 1.12-1.47 1.68-3.43 1.68-5.86s-.56-4.38-1.68-5.85a5.35 5.35 0 0 0-4.56-2.21 5.4 5.4 0 0 0-4.61 2.2c-1.09 1.45-1.63 3.4-1.63 5.86 0 2.43.54 4.39 1.63 5.86a5.44 5.44 0 0 0 4.6 2.16Zm22.18-20.34v3.93h.15a9.12 9.12 0 0 1 2.54-3.17c.93-.7 2.1-1.05 3.5-1.05.68 0 1.19.06 1.54.19v5.71h-.14c-2.21-.22-3.99.26-5.33 1.44-1.34 1.19-2.02 3.04-2.02 5.57v12h-6.52V23.38h6.28Zm21.4 25.34c-3.96 0-7.08-1.22-9.35-3.65-2.27-2.46-3.41-5.6-3.41-9.4 0-3.69 1.14-6.76 3.4-9.22a11.28 11.28 0 0 1 8.74-3.75c3.88 0 6.87 1.35 8.98 4.04 2.11 2.68 3.17 6.28 3.17 10.8h-17.86a7.8 7.8 0 0 0 1.97 4.56 5.84 5.84 0 0 0 4.32 1.58c2.4 0 3.98-1 4.75-3.02h6.43a9.67 9.67 0 0 1-3.64 5.76c-1.96 1.53-4.45 2.3-7.5 2.3Zm-.52-20.98c-3.17 0-5.07 1.76-5.71 5.28h10.94a5.64 5.64 0 0 0-1.58-3.79 4.86 4.86 0 0 0-3.65-1.49Zm21.36-4.36v3.93h.14a9.12 9.12 0 0 1 2.54-3.17c.93-.7 2.1-1.05 3.5-1.05.68 0 1.2.06 1.55.19v5.71h-.15c-2.2-.22-3.98.26-5.33 1.44-1.34 1.19-2.01 3.04-2.01 5.57v12h-6.53V23.38h6.29Z"/><path fill="#fff" d="M7.64 48V13.68h25.25v5.86H14.6v7.68h16.03v5.7H14.6v9.27h18.43V48H7.64Zm27.46 0 8.98-13.06-8.02-11.56h7.44l4.37 7.05h.1l4.12-7.05h6.77L51.23 34.9 60.01 48h-7.77l-4.56-8.16h-.1L42.25 48H35.1Zm27.42 8.06V23.38h6.29v3.07h.14a8.55 8.55 0 0 1 7.25-3.75 9.5 9.5 0 0 1 7.77 3.6c1.96 2.4 2.93 5.54 2.93 9.41 0 3.97-.97 7.14-2.93 9.5a9.57 9.57 0 0 1-7.72 3.51c-3.2 0-5.57-1.17-7.1-3.5h-.1v10.84h-6.53ZM74.85 43.3c1.67 0 2.98-.66 3.94-1.97 1-1.31 1.49-3.12 1.49-5.43 0-2.46-.47-4.4-1.4-5.8-.92-1.41-2.35-2.12-4.27-2.12-1.95 0-3.39.74-4.32 2.21-.92 1.44-1.39 3.35-1.39 5.71 0 2.28.51 4.08 1.54 5.43a5.27 5.27 0 0 0 4.41 1.97ZM90.04 48V13.68h6.52V48h-6.52Zm31.75-2.98c-2.4 2.47-5.49 3.7-9.26 3.7-3.78 0-6.87-1.23-9.27-3.7a12.9 12.9 0 0 1-3.6-9.3c0-3.72 1.2-6.8 3.6-9.27 2.4-2.5 5.49-3.75 9.27-3.75 3.77 0 6.86 1.25 9.26 3.75 2.4 2.46 3.6 5.55 3.6 9.26s-1.2 6.82-3.6 9.31Zm-9.26-1.3c1.95 0 3.47-.71 4.56-2.15 1.12-1.47 1.68-3.43 1.68-5.86s-.56-4.38-1.68-5.85a5.35 5.35 0 0 0-4.56-2.21 5.4 5.4 0 0 0-4.61 2.2c-1.09 1.45-1.63 3.4-1.63 5.86 0 2.43.54 4.39 1.63 5.86a5.44 5.44 0 0 0 4.6 2.16Zm22.18-20.34v3.93h.15a9.12 9.12 0 0 1 2.54-3.17c.93-.7 2.1-1.05 3.5-1.05.68 0 1.19.06 1.54.19v5.71h-.14c-2.21-.22-3.99.26-5.33 1.44-1.34 1.19-2.02 3.04-2.02 5.57v12h-6.52V23.38h6.28Zm21.4 25.34c-3.96 0-7.08-1.22-9.35-3.65-2.27-2.46-3.41-5.6-3.41-9.4 0-3.69 1.14-6.76 3.4-9.22a11.28 11.28 0 0 1 8.74-3.75c3.88 0 6.87 1.35 8.98 4.04 2.11 2.68 3.17 6.28 3.17 10.8h-17.86a7.8 7.8 0 0 0 1.97 4.56 5.84 5.84 0 0 0 4.32 1.58c2.4 0 3.98-1 4.75-3.02h6.43a9.67 9.67 0 0 1-3.64 5.76c-1.96 1.53-4.45 2.3-7.5 2.3Zm-.52-20.98c-3.17 0-5.07 1.76-5.71 5.28h10.94a5.64 5.64 0 0 0-1.58-3.79 4.86 4.86 0 0 0-3.65-1.49Zm21.36-4.36v3.93h.14a9.12 9.12 0 0 1 2.54-3.17c.93-.7 2.1-1.05 3.5-1.05.68 0 1.2.06 1.55.19v5.71h-.15c-2.2-.22-3.98.26-5.33 1.44-1.34 1.19-2.01 3.04-2.01 5.57v12h-6.53V23.38h6.29Z"/></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

@ -1 +1 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 301 324"><path d="M166.2 1h61.2A20 20 0 0 1 246 14L300 158.3a5 5 0 0 1 0 3.4l-.3.9L246 309.8a20 20 0 0 1-18.8 13.2H166a5 5 0 0 1-4.7-6.6l55.2-158.1-55-150.6a5 5 0 0 1 4.7-6.7Z" fill="#010101"/><path d="M6.3 1h61.3a20 20 0 0 1 18.7 13L140 158.3a5 5 0 0 1 0 3.4l-.3.9-53.5 147.2A20 20 0 0 1 67.4 323H6.2a5 5 0 0 1-4.7-6.6l55.2-158.1L1.7 7.7A5 5 0 0 1 6.2 1Z" fill="#010101"/><path d="m216.5 158.3-55-150.6a5 5 0 0 1 4.7-6.7h61.2A20 20 0 0 1 246 14L300 158.3a5 5 0 0 1 0 3.4L246 309.8a20 20 0 0 1-18.8 13.2H166a5 5 0 0 1-4.7-6.6l26.4-75.8 28.8-82.3Zm0 0-55 158a5 5 0 0 0 4.7 6.7h61m-10.7-164.7-55-150.5a5 5 0 0 1 4.7-6.8h61.2m-10.9 157.3-55.2 158a5 5 0 0 0 4.7 6.7h61.3m-10.8-164.7-55-150.6a5 5 0 0 1 4.7-6.7h61.2m0 0A20 20 0 0 1 246 14L300 158.3m0 0a5 5 0 0 1 0 3.4m0-3.4v2.5a5 5 0 0 1-.3 1.8m.3-.9L246 309.8m53.8-148-.3.8M246 309.8a20 20 0 0 1-18.8 13.2m18.8-13.2 53.5-147.2m-243-4.3-55.1 158a5 5 0 0 0 4.7 6.7h61.2a20 20 0 0 0 18.8-13.2l53.5-147.2.4-.9a5 5 0 0 0 0-3.4L86.2 14A20 20 0 0 0 67.6 1H6.3a5 5 0 0 0-4.7 6.7l55 150.6Z" stroke="#010101"/><path d="M204.5 124.5H128v70h76.5l12.5-36-12.5-34Z" fill="#010101" stroke="#010101"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="550" height="494" fill="none"><path fill="#D631B9" d="M270.65 0h100.47c13.7 0 25.97 7.96 30.75 19.96l88.19 221.19a7.2 7.2 0 0 1 .02 5.3l-.5 1.26v.02l-87.81 225.8c-4.72 12.12-17.04 20.19-30.85 20.19H270.47c-5.65 0-9.6-5.21-7.75-10.2l90.55-242.37L262.95 10.3c-1.96-5 2-10.3 7.7-10.3Z"/><path fill="#D631B9" d="M8.4 0h100.46c13.7 0 25.97 7.96 30.75 19.96l88.19 221.19a7.2 7.2 0 0 1 .02 5.3l-.5 1.26v.02l-87.81 225.8c-4.72 12.12-17.04 20.19-30.85 20.19H8.21c-5.65 0-9.6-5.21-7.74-10.2L91 241.15.7 10.3c-1.96-5 2-10.3 7.7-10.3Z"/><path fill="#D631B9" d="M338.83 194H197v107h141.83L362 245.97 338.83 194Z"/><path fill="#fff" d="M328.65 0h100.47c13.7 0 25.97 7.96 30.75 19.96l88.19 221.19a7.2 7.2 0 0 1 .02 5.3l-.5 1.26v.02l-87.81 225.8c-4.72 12.12-17.04 20.19-30.85 20.19H328.47c-5.65 0-9.6-5.21-7.75-10.2l90.55-242.37L320.95 10.3c-1.96-5 2-10.3 7.7-10.3Z"/><path fill="#fff" d="M66.4 0h100.46c13.7 0 25.97 7.96 30.75 19.96l88.19 221.19a7.2 7.2 0 0 1 .02 5.3l-.5 1.26v.02l-87.81 225.8c-4.72 12.12-17.04 20.19-30.85 20.19H66.21c-5.65 0-9.6-5.21-7.74-10.2L149 241.15 58.7 10.3c-1.96-5 2-10.3 7.7-10.3Z"/><path fill="#fff" d="M396.83 194H255v107h141.83L420 245.97 396.83 194Z"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

@ -1,8 +1,10 @@
import { Head, Html, Main, NextScript } from 'next/document';
import { links } from '../consts/links';
export default function Document() {
return (
<Html>
<Html lang="en">
<Head>
<meta charSet="utf-8" />
@ -16,23 +18,26 @@ export default function Document() {
<meta name="theme-color" content="#ffffff" />
<meta name="application-name" content="Hyperlane Explorer" />
<meta name="keywords" content="Hyperlane Explorer Scan Interchain App" />
<meta
name="keywords"
content="Hyperlane Explorer Scan Interchain Permissionless Interoperability Network Blockchain"
/>
<meta
name="description"
content="An interchain explorer for the Hyperlane protocol and network"
content="The official interchain explorer for the Hyperlane protocol and network."
/>
<meta name="HandheldFriendly" content="true" />
<meta name="apple-mobile-web-app-title" content="Hyperlane Explorer" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta property="og:url" content="https://explorer.hyperlane.xyz" />
<meta property="og:url" content={links.baseUrl} />
<meta property="og:title" content="Hyperlane Explorer" />
<meta property="og:type" content="website" />
<meta property="og:image" content="https://explorer.hyperlane.xyz/icon.png" />
<meta property="og:image" content={links.baseUrl + '/images/logo.png'} />
<meta
property="og:description"
content="An interchain explorer for the Hyperlane protocol and network"
content="The official interchain explorer for the Hyperlane protocol and network."
/>
</Head>
<body className="text-black">

@ -6,28 +6,30 @@ const ApiDocs: NextPage = () => {
return (
<div className="mt-4 mb-2 px-2 sm:px-6 lg:pr-14 w-full">
<Card>
<h2 className="mt-1 text-xl text-blue-500">Explorer APIs - Overview and documentation</h2>
<p className="mt-3">
<h2 className="mt-1 text-lg text-blue-500 font-medium">
Explorer APIs - Overview and documentation
</h2>
<p className="mt-3 font-light">
The Explorer REST API provides endpoints to retrieve data about messages.
</p>
<p className="mt-1">
<p className="mt-1 font-light">
The APIs are currently available free of charge and without authentication required.
</p>
<h3 className="mt-4 text-lg text-blue-500">Example Request</h3>
<div className="mt-2 bg-gray-50 rounded p-2.5 text-sm overflow-auto">
<h3 className="mt-5 text-blue-500 font-medium">Example Request</h3>
<div className="mt-2 bg-gray-50 rounded-xl p-2.5 text-sm overflow-auto">
<pre>
<code>{exampleRequest}</code>
</pre>
</div>
<h3 className="mt-4 text-lg text-blue-500">Example Response</h3>
<div className="mt-2 bg-gray-50 rounded p-2.5 text-sm overflow-auto">
<h3 className="mt-5 text-blue-500 font-medium">Example Response</h3>
<div className="mt-2 bg-gray-50 rounded-xl p-2.5 text-sm overflow-auto">
<pre>
<code>{exampleResponse}</code>
</pre>
</div>
<h3 className="mt-4 text-lg text-blue-500">API Reference</h3>
<h3 className="mt-4 font-medium text-blue-500">API Reference</h3>
<h4 className="mt-2 text-gray-600">
Module:<code className="ml-2">message</code>
</h4>
@ -76,7 +78,7 @@ function ParamItem({ name, desc }: { name: string; desc: string }) {
return (
<li>
<code className="mr-2">{name + ':'}</code>
{desc}
<span className="font-light">{desc}</span>
</li>
);
}

@ -1,14 +1,9 @@
import type { NextPage } from 'next';
import { ContentFrame } from '../components/layout/ContentFrame';
import { MessageSearch } from '../features/messages/MessageSearch';
const HomePage: NextPage = () => {
return (
<ContentFrame>
<MessageSearch />
</ContentFrame>
);
return <MessageSearch />;
};
// Required for dynamic routing to work by disabling Automatic Static Optimization

@ -2,7 +2,6 @@ import type { NextPage } from 'next';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
import { ContentFrame } from '../../components/layout/ContentFrame';
import { MessageDetails } from '../../features/messages/MessageDetails';
import { deserializeMessage } from '../../features/messages/utils';
import { Message } from '../../types';
@ -20,11 +19,7 @@ const MessagePage: NextPage = () => {
const message = data ? deserializeMessage<Message>(data) : undefined;
return (
<ContentFrame>
<MessageDetails messageId={messageId} message={message} />
</ContentFrame>
);
return <MessageDetails messageId={messageId} message={message} />;
};
// Required for dynamic routing to work by disabling Automatic Static Optimization

@ -1,11 +1,12 @@
// Should match tailwind.config.js
export enum Color {
primaryBlack = '#010101',
primaryWhite = '#FFFFFF',
primaryGray = '#6B7280',
primaryBlue = '#2362C1',
primaryBeige = '#F1EDE9',
primaryRed = '#BF1B15',
Black = '#010101',
White = '#FFFFFF',
Gray = '#6B7280',
Blue = '#2362C1',
Pink = '#D631B9',
Beige = '#F1EDE9',
Red = '#BF1B15',
}
// Useful for cases when using class names isn't convenient
@ -13,11 +14,13 @@ export enum Color {
export function classNameToColor(className) {
switch (className) {
case 'bg-blue-500':
return Color.primaryBlue;
return Color.Blue;
case 'bg-pink-500':
return Color.Pink;
case 'bg-red-500':
return Color.primaryRed;
return Color.Red;
case 'bg-gray-500':
return Color.primaryGray;
return Color.Gray;
default:
throw new Error('Missing color for className: ' + className);
}

@ -34,6 +34,13 @@
font-family: 'Neue Haas Grotesk';
font-style: normal;
font-weight: 600;
src: url('/fonts/NeueHaasDisplayMedium.ttf');
}
@font-face {
font-family: 'Neue Haas Grotesk';
font-style: normal;
font-weight: 700;
src: url('/fonts/NeueHaasDisplayBold.woff2') format('woff2'),
url('/fonts/NeueHaasDisplayBold.woff') format('woff');
}

@ -20,16 +20,16 @@ module.exports = {
black: '#010101',
white: '#ffffff',
blue: {
50: '#C7D9F5',
100: '#A6C3EF',
200: '#85ADE9',
300: '#6396E3',
400: '#4280DD',
500: '#2362C1',
600: '#205AB0',
700: '#1A498F',
800: '#14386E',
900: '#0E274D',
50: '#E6EDF9',
100: '#CDDCF4',
200: '#A7C2EC',
300: '#82A8E4',
400: '#5385D2',
500: '#2362C0',
600: '#1D4685',
700: '#162A4A',
800: '#11213B',
900: '#0D192C',
},
beige: {
100: '#F6F4F1',
@ -42,6 +42,18 @@ module.exports = {
800: '#A8A5A3',
900: '#908E8B',
},
pink: {
50: '#FCF2FA',
100: '#F2C1EA',
200: '#EA98DC',
300: '#E26ECE',
400: '#DA45C0',
500: '#D631B9',
600: '#C02CA6',
700: '#952281',
800: '#6B185C',
900: '#400E37',
},
red: {
100: '#EBBAB8',
200: '#DF8D8A',

Loading…
Cancel
Save