From e79898c2ce998532aaf49f6327ffaf3111d4e2a1 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Mon, 8 Jan 2024 00:11:26 +0100 Subject: [PATCH 1/6] Experiment with chain pages --- src/components/Chain.tsx | 89 +++++++++++---------- src/pages/chain/{Chain.chainId}.tsx | 120 ++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+), 43 deletions(-) create mode 100644 src/pages/chain/{Chain.chainId}.tsx diff --git a/src/components/Chain.tsx b/src/components/Chain.tsx index f4ee98a71..eac9cbbb5 100644 --- a/src/components/Chain.tsx +++ b/src/components/Chain.tsx @@ -12,6 +12,7 @@ import React, { useContext } from "react"; import { Web3Context } from "../context/Web3Context"; import { ChainData } from "../types/chain"; import { ChainIcon } from "./ChainIcon"; +import { Link } from "gatsby"; export const Chain = ({ name, @@ -26,51 +27,53 @@ export const Chain = ({ handleAddChain({ name, chainId, nativeCurrency, ...rest }); }; return ( - - - - - - {name} - + + + + + + + {name} + + + + + Chain ID + {chainId} + + + Currency + {nativeCurrency.symbol} + + - - - Chain ID - {chainId} - - - Currency - {nativeCurrency.symbol} - - + {icon && ( + + + + )} - {icon && ( - - - - )} +
+ {!isConnected ? ( + + ) : ( + + )} +
-
- {!isConnected ? ( - - ) : ( - - )} -
-
+ ); }; diff --git a/src/pages/chain/{Chain.chainId}.tsx b/src/pages/chain/{Chain.chainId}.tsx new file mode 100644 index 000000000..24731a25d --- /dev/null +++ b/src/pages/chain/{Chain.chainId}.tsx @@ -0,0 +1,120 @@ +import React, { useContext } from "react"; +import { + Box, + Button, + Flex, + StatGroup, + StatLabel, + Stat, + StatNumber, + Heading, + Text, +} from "@chakra-ui/react"; +import { graphql } from "gatsby"; +import { Seo } from "../../components/SEO"; +import { SearchProvider } from "../../context/SearchContext"; +import { Web3Context, Web3Provider } from "../../context/Web3Context"; +import { Header } from "../../components/Header"; +import { ChainIcon } from "../../components/ChainIcon"; +import { Layout } from "../../components/Layout"; + +const ChainPage = ({ data }) => { + const { name, chainId, nativeCurrency, icon, explorers, rpc, slip44 } = + data.chain; + + const { isConnected, handleConnect, handleAddChain } = + useContext(Web3Context); + const handleAddChainClick = () => { + handleAddChain({ name, chainId, nativeCurrency, ...rest }); + }; + + return ( + <> + + + + + + + + {icon && ( + + + + )} + + {name} + + + {!isConnected ? ( + + ) : ( + + )} + + + + Chain ID + {chainId} + + + Currency + {nativeCurrency.symbol} + + + SLIP44 + {slip44} + + + + RPC URLs + + {rpc.map((rpcUrl) => ( + {rpcUrl} + ))} + + Explorers + + {explorers.map((explorer) => ( + {explorer.url} + ))} + + + + + + ); +}; + +export const query = graphql` + query ($id: String) { + chain(id: { eq: $id }) { + id + name + chain + chainId + rpc + icon { + publicURL + childImageSharp { + gatsbyImageData(width: 40, placeholder: NONE) + } + } + nativeCurrency { + decimals + name + symbol + } + explorers { + url + name + standard + } + status + faucets + slip44 + } + } +`; + +export default ChainPage; From 11cf8cbb8b3a95124b8035cce8a35cc9ea6b7767 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Wed, 17 Jul 2024 00:23:43 +0200 Subject: [PATCH 2/6] More progress on chain pages --- gatsby-node.js | 2 + src/components/ChainIcon.tsx | 4 +- src/components/ExternalLink.tsx | 9 ++++ src/components/Header.tsx | 5 +- src/components/RpcTable.tsx | 45 ++++++++++++++++ src/pages/chain/{Chain.chainId}.tsx | 80 +++++++++++++++++++---------- 6 files changed, 116 insertions(+), 29 deletions(-) create mode 100644 src/components/ExternalLink.tsx create mode 100644 src/components/RpcTable.tsx diff --git a/gatsby-node.js b/gatsby-node.js index 4cb348aed..fb0c0c126 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -65,6 +65,8 @@ exports.sourceNodes = async ({ }, Promise.resolve({})); chains + // Filter out non HTTP(S) RPC URLs + .map((chain) => ({ ...chain, rpc: chain.rpc.filter(rpc => rpc.startsWith('http://') || rpc.startsWith('https://'))})) .filter((chain) => chain.rpc.length > 0) .forEach((chain) => { const icon = chain.icon; diff --git a/src/components/ChainIcon.tsx b/src/components/ChainIcon.tsx index dc85ff24c..3ad80074b 100644 --- a/src/components/ChainIcon.tsx +++ b/src/components/ChainIcon.tsx @@ -3,7 +3,7 @@ import { GatsbyImage } from "gatsby-plugin-image"; import { ChainData } from "../types/chain"; import { Image } from "@chakra-ui/react"; -export const ChainIcon = ({ icon, name }: Pick) => +export const ChainIcon = ({ icon, name, width = "40px" }: Pick & { width?: string; }) => icon.childImageSharp ? ( ) => alt={name} /> ) : ( - + ); diff --git a/src/components/ExternalLink.tsx b/src/components/ExternalLink.tsx new file mode 100644 index 000000000..667b220e1 --- /dev/null +++ b/src/components/ExternalLink.tsx @@ -0,0 +1,9 @@ +import React from "react"; +import { ExternalLinkIcon } from "@chakra-ui/icons"; +import { Link } from "@chakra-ui/react"; + +export const ExternalLink = ({ href, children }) => ( + + {children} + +); diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 7573c1610..da73bf3e9 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -14,6 +14,7 @@ import { Search } from "./Search"; import { FaGithub } from "react-icons/fa"; import { AddIcon } from "@chakra-ui/icons"; import { Filters } from "./Filters"; +import { Link as GatsbyLink } from "gatsby"; export const Header = ({ showSearch = true, showFilters = true }) => { const { handleConnect, isConnected, address } = useContext(Web3Context); @@ -33,7 +34,9 @@ export const Header = ({ showSearch = true, showFilters = true }) => { width="100%" zIndex="sticky" > - Chainlist + + Chainlist + {showSearch && } {showFilters && } diff --git a/src/components/RpcTable.tsx b/src/components/RpcTable.tsx new file mode 100644 index 000000000..235b974b0 --- /dev/null +++ b/src/components/RpcTable.tsx @@ -0,0 +1,45 @@ +import React, { useContext } from "react"; +import { + Button, + Table, + TableContainer, + Tbody, + Td, + Th, + Thead, + Tr, +} from "@chakra-ui/react"; +import { Web3Context } from "../context/Web3Context"; + +export const RpcTable = ({ rpcs, handleRpcClick }) => { + const { isConnected, handleConnect } = useContext(Web3Context); + + return ( + + + + + + + + + + {rpcs.map((rpcUrl) => ( + + + + + ))} + +
RPC URL
{rpcUrl} + {!isConnected ? ( + + ) : ( + + )} +
+
+ ); +}; diff --git a/src/pages/chain/{Chain.chainId}.tsx b/src/pages/chain/{Chain.chainId}.tsx index 24731a25d..980a6ab65 100644 --- a/src/pages/chain/{Chain.chainId}.tsx +++ b/src/pages/chain/{Chain.chainId}.tsx @@ -9,23 +9,39 @@ import { StatNumber, Heading, Text, + Divider, } from "@chakra-ui/react"; import { graphql } from "gatsby"; import { Seo } from "../../components/SEO"; import { SearchProvider } from "../../context/SearchContext"; import { Web3Context, Web3Provider } from "../../context/Web3Context"; -import { Header } from "../../components/Header"; import { ChainIcon } from "../../components/ChainIcon"; import { Layout } from "../../components/Layout"; +import { ExternalLink } from "../../components/ExternalLink"; +import { RpcTable } from "../../components/RpcTable"; const ChainPage = ({ data }) => { - const { name, chainId, nativeCurrency, icon, explorers, rpc, slip44 } = - data.chain; + const { + name, + chainId, + nativeCurrency, + icon, + explorers, + rpc, + slip44, + infoURL, + status, + } = data.chain; const { isConnected, handleConnect, handleAddChain } = useContext(Web3Context); + const handleAddChainClick = () => { - handleAddChain({ name, chainId, nativeCurrency, ...rest }); + handleAddChain({ name, chainId, nativeCurrency, rpc, explorers }); + }; + + const handleRpcClick = (rpc) => { + handleAddChain({ name, chainId, nativeCurrency, rpc: [rpc], explorers }); }; return ( @@ -34,17 +50,15 @@ const ChainPage = ({ data }) => { - - + + {icon && ( - - + + )} - - {name} - + {name} {!isConnected ? ( @@ -52,6 +66,7 @@ const ChainPage = ({ data }) => { )} + Chain ID @@ -62,22 +77,34 @@ const ChainPage = ({ data }) => { {nativeCurrency.symbol} - SLIP44 - {slip44} + Status + + {status ?? "Active"} + + {infoURL && ( + + Info + + {infoURL} + + + )} + {explorers && ( + + Explorers + + {explorers.map((explorer) => ( + + {explorer.url} + + ))} + + + )} - - RPC URLs - - {rpc.map((rpcUrl) => ( - {rpcUrl} - ))} - - Explorers - - {explorers.map((explorer) => ( - {explorer.url} - ))} + + @@ -97,7 +124,7 @@ export const query = graphql` icon { publicURL childImageSharp { - gatsbyImageData(width: 40, placeholder: NONE) + gatsbyImageData(width: 60, placeholder: NONE) } } nativeCurrency { @@ -113,6 +140,7 @@ export const query = graphql` status faucets slip44 + infoURL } } `; From 0d9905d05f1ca1b802d0923fa7f87bdd06035e16 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Thu, 18 Jul 2024 00:03:48 +0200 Subject: [PATCH 3/6] Move providers to root --- gatsby-browser.jsx | 9 +++ src/pages/chain/{Chain.chainId}.tsx | 116 ++++++++++++++-------------- src/pages/index.tsx | 13 +--- 3 files changed, 68 insertions(+), 70 deletions(-) create mode 100644 gatsby-browser.jsx diff --git a/gatsby-browser.jsx b/gatsby-browser.jsx new file mode 100644 index 000000000..5789734d5 --- /dev/null +++ b/gatsby-browser.jsx @@ -0,0 +1,9 @@ +import React from "react"; +import { Web3Provider } from "./src/context/Web3Context"; +import { SearchProvider } from "./src/context/SearchContext"; + +export const wrapRootElement = ({ element }) => ( + + {element} + +); diff --git a/src/pages/chain/{Chain.chainId}.tsx b/src/pages/chain/{Chain.chainId}.tsx index 980a6ab65..94302596a 100644 --- a/src/pages/chain/{Chain.chainId}.tsx +++ b/src/pages/chain/{Chain.chainId}.tsx @@ -47,68 +47,64 @@ const ChainPage = ({ data }) => { return ( <> - - - - - - - {icon && ( - - - - )} - {name} + + + + + {icon && ( + + - {!isConnected ? ( - - ) : ( - - )} - - - - - Chain ID - {chainId} - - - Currency - {nativeCurrency.symbol} - - - Status - - {status ?? "Active"} - - - {infoURL && ( - - Info - - {infoURL} - - - )} - {explorers && ( - - Explorers - - {explorers.map((explorer) => ( - - {explorer.url} - - ))} - - - )} - - - + )} + {name} - - - + {!isConnected ? ( + + ) : ( + + )} +
+ + + + Chain ID + {chainId} + + + Currency + {nativeCurrency.symbol} + + + Status + + {status ?? "Active"} + + + {infoURL && ( + + Info + + {infoURL} + + + )} + {explorers && ( + + Explorers + + {explorers.map((explorer) => ( + + {explorer.url} + + ))} + + + )} + + + +
+ ); }; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 051a31179..8ce559e50 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,21 +1,14 @@ -import { graphql, useStaticQuery } from "gatsby"; import React from "react"; import { ChainList } from "../components/ChainList"; import { Seo } from "../components/SEO"; -import { Web3Provider } from "../context/Web3Context"; -import { SearchProvider } from "../context/SearchContext"; import { Layout } from "../components/Layout"; const IndexPage = () => ( <> - - - - - - - + + + ); From 12fc5276267c6a1fe17ba340c054dc01b5bf9bbc Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Thu, 25 Jul 2024 17:23:06 +0200 Subject: [PATCH 4/6] Add flags and improve styling --- src/components/RedFlagBadge.tsx | 20 +++++++++++++ src/components/StatValue.tsx | 8 +++++ src/components/StatusBadge.tsx | 13 ++++++++ src/pages/chain/{Chain.chainId}.tsx | 46 ++++++++++++++++------------- src/types/chain.ts | 3 ++ 5 files changed, 70 insertions(+), 20 deletions(-) create mode 100644 src/components/RedFlagBadge.tsx create mode 100644 src/components/StatValue.tsx create mode 100644 src/components/StatusBadge.tsx diff --git a/src/components/RedFlagBadge.tsx b/src/components/RedFlagBadge.tsx new file mode 100644 index 000000000..9dc2bb51d --- /dev/null +++ b/src/components/RedFlagBadge.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import { Badge, Tooltip } from "@chakra-ui/react"; +import { ChainData } from "../types/chain"; + +export const RedFlagBadge = ({ redFlags }: Pick) => { + if (!redFlags || redFlags.length === 0) { + return null; + } + const flagLabel = + redFlags[0] === "reusedChainId" + ? "Flagged for reusing chain ID" + : "Flagged for unknown reasons"; + return ( + + + Flagged + + + ); +}; diff --git a/src/components/StatValue.tsx b/src/components/StatValue.tsx new file mode 100644 index 000000000..477e0dd15 --- /dev/null +++ b/src/components/StatValue.tsx @@ -0,0 +1,8 @@ +import React from "react"; +import { VStack } from "@chakra-ui/react"; + +export const StatValue = ({ children }: { children: React.ReactNode }) => ( + + {children} + +); diff --git a/src/components/StatusBadge.tsx b/src/components/StatusBadge.tsx new file mode 100644 index 000000000..02526e805 --- /dev/null +++ b/src/components/StatusBadge.tsx @@ -0,0 +1,13 @@ +import React from "react"; +import { Badge } from "@chakra-ui/react"; +import { ChainData } from "../types/chain"; + +export const StatusBadge = ({ status }: Pick) => { + const actualStatus = status ?? "Active"; + const colorScheme = status === "deprecated" ? "yellow" : undefined; + return ( + + {actualStatus} + + ); +}; diff --git a/src/pages/chain/{Chain.chainId}.tsx b/src/pages/chain/{Chain.chainId}.tsx index 94302596a..2076b2b9b 100644 --- a/src/pages/chain/{Chain.chainId}.tsx +++ b/src/pages/chain/{Chain.chainId}.tsx @@ -1,26 +1,27 @@ import React, { useContext } from "react"; import { - Box, Button, Flex, StatGroup, StatLabel, Stat, - StatNumber, Heading, - Text, Divider, + Text, } from "@chakra-ui/react"; import { graphql } from "gatsby"; import { Seo } from "../../components/SEO"; -import { SearchProvider } from "../../context/SearchContext"; -import { Web3Context, Web3Provider } from "../../context/Web3Context"; +import { Web3Context } from "../../context/Web3Context"; import { ChainIcon } from "../../components/ChainIcon"; import { Layout } from "../../components/Layout"; import { ExternalLink } from "../../components/ExternalLink"; import { RpcTable } from "../../components/RpcTable"; +import { RedFlagBadge } from "../../components/RedFlagBadge"; +import { StatusBadge } from "../../components/StatusBadge"; +import { StatValue } from "../../components/StatValue"; +import { ChainData } from "../../types/chain"; -const ChainPage = ({ data }) => { +const ChainPage = ({ data }: { data: { chain: ChainData } }) => { const { name, chainId, @@ -28,7 +29,7 @@ const ChainPage = ({ data }) => { icon, explorers, rpc, - slip44, + redFlags, infoURL, status, } = data.chain; @@ -40,7 +41,7 @@ const ChainPage = ({ data }) => { handleAddChain({ name, chainId, nativeCurrency, rpc, explorers }); }; - const handleRpcClick = (rpc) => { + const handleRpcClick = (rpc: string) => { handleAddChain({ name, chainId, nativeCurrency, rpc: [rpc], explorers }); }; @@ -65,39 +66,44 @@ const ChainPage = ({ data }) => { )}
- + Chain ID - {chainId} + + {chainId} + Currency - {nativeCurrency.symbol} + + {nativeCurrency.symbol} + - Status - - {status ?? "Active"} - + Status + + + + {infoURL && ( Info - + {infoURL} - + )} {explorers && ( Explorers - + {explorers.map((explorer) => ( {explorer.url} ))} - + )} @@ -135,7 +141,7 @@ export const query = graphql` } status faucets - slip44 + redFlags infoURL } } diff --git a/src/types/chain.ts b/src/types/chain.ts index 5ca376aac..42100bcfc 100644 --- a/src/types/chain.ts +++ b/src/types/chain.ts @@ -11,6 +11,9 @@ export interface ChainData { chainId: number; nativeCurrency: ChainCurrency; explorers?: BlockExplorer[]; + status?: string; + redFlags?: string[]; + infoURL?: string; } export interface ChainCurrency { From 08f7483c953b9b265e74e2f6bbb5982eb226c545 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Thu, 25 Jul 2024 17:32:07 +0200 Subject: [PATCH 5/6] Add gatsby-ssr --- gatsby-ssr.jsx | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 gatsby-ssr.jsx diff --git a/gatsby-ssr.jsx b/gatsby-ssr.jsx new file mode 100644 index 000000000..5789734d5 --- /dev/null +++ b/gatsby-ssr.jsx @@ -0,0 +1,9 @@ +import React from "react"; +import { Web3Provider } from "./src/context/Web3Context"; +import { SearchProvider } from "./src/context/SearchContext"; + +export const wrapRootElement = ({ element }) => ( + + {element} + +); From 43b670aee13bba5f072cc78b2bac00eea2e85c70 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Thu, 25 Jul 2024 22:39:28 +0200 Subject: [PATCH 6/6] More responsiveness and fixes --- src/components/Chain.tsx | 12 ++++++++++-- src/components/Header.tsx | 2 +- src/components/Layout.tsx | 9 ++++++++- src/components/RpcTable.tsx | 2 +- src/pages/chain/{Chain.chainId}.tsx | 19 ++++++++++++++----- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/components/Chain.tsx b/src/components/Chain.tsx index eac9cbbb5..1ed2fb8c7 100644 --- a/src/components/Chain.tsx +++ b/src/components/Chain.tsx @@ -23,9 +23,17 @@ export const Chain = ({ }: ChainData) => { const { isConnected, handleConnect, handleAddChain } = useContext(Web3Context); - const handleAddChainClick = () => { + + const handleConnectClick = (event: React.MouseEvent) => { + event.preventDefault(); + handleConnect(); + }; + + const handleAddChainClick = (event: React.MouseEvent) => { + event.preventDefault(); handleAddChain({ name, chainId, nativeCurrency, ...rest }); }; + return (
{!isConnected ? ( - + ) : ( )} diff --git a/src/components/Header.tsx b/src/components/Header.tsx index da73bf3e9..84a6858d1 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -65,7 +65,7 @@ export const Header = ({ showSearch = true, showFilters = true }) => { size="lg" onClick={handleConnect} > - Connect Wallet + Connect ) : ( + ) : ( + ) : ( )}