mirror of
https://github.com/Instadapp/chains.git
synced 2024-07-29 22:37:19 +00:00
Squashed 'website/' content from commit 363240a
git-subtree-dir: website git-subtree-split: 363240aff0185a5593cb828a19cd6dfaceb8bc6c
This commit is contained in:
commit
78c6e74dfb
17
.github/workflows/auto-deploy.yml
vendored
Normal file
17
.github/workflows/auto-deploy.yml
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
name: Auto Deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Check if deployment is needed
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
BUILD_HOOK: ${{ secrets.NETLIFY_BUILD_HOOK }}
|
||||||
|
run: ./scripts/check-deploy.sh
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
node_modules/
|
||||||
|
.cache/
|
||||||
|
public
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 Frederik Bolding
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
30
README.md
Normal file
30
README.md
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# Chainlist
|
||||||
|
A list of EVM-based chains that also allows you to add chains to your favorite Web3 wallet. An alternative to the closing chainlist.org.
|
||||||
|
|
||||||
|
Uses the data from https://github.com/ethereum-lists/chains
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Development
|
||||||
|
|
||||||
|
To start a development server, run the following command
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn run start
|
||||||
|
```
|
||||||
|
|
||||||
|
The server will be accessible on `localhost:8000`.
|
||||||
|
|
||||||
|
### Production
|
||||||
|
|
||||||
|
To build a static version of the site for production, run the following command
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn run build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributions
|
||||||
|
Contributions are very welcome! Feel free to open issues and PRs for missing features or potential bugs!
|
||||||
|
|
||||||
|
## License
|
||||||
|
This project is [MIT licensed](./LICENSE).
|
41
gatsby-config.js
Normal file
41
gatsby-config.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/** @type {import('gatsby').GatsbyConfig} */
|
||||||
|
module.exports = {
|
||||||
|
siteMetadata: {
|
||||||
|
title: `Chainlist`,
|
||||||
|
siteUrl: `https://evm-chainlist.netlify.app/`,
|
||||||
|
author: "@frederikbolding",
|
||||||
|
description:
|
||||||
|
"A list of EVM-based chains that also allows you to add chains to your favorite Web3 wallet.",
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
"gatsby-plugin-emotion",
|
||||||
|
"gatsby-plugin-react-helmet",
|
||||||
|
"gatsby-plugin-netlify",
|
||||||
|
{
|
||||||
|
// For `gatsby-transformer-json` to work, `gatsby-source-filesystem` needs to be loaded. This
|
||||||
|
// plugin requires a specific folder to be set however, so here we just specify the pages
|
||||||
|
// folder as a dummy folder.
|
||||||
|
resolve: 'gatsby-source-filesystem',
|
||||||
|
options: {
|
||||||
|
name: 'pages',
|
||||||
|
path: 'src/pages'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gatsby-transformer-json",
|
||||||
|
{
|
||||||
|
resolve: "@chakra-ui/gatsby-plugin",
|
||||||
|
options: {
|
||||||
|
/**
|
||||||
|
* @property {boolean} [resetCSS=true]
|
||||||
|
* if false, this plugin will not use `<CSSReset />
|
||||||
|
*/
|
||||||
|
resetCSS: true,
|
||||||
|
/**
|
||||||
|
* @property {boolean} [isUsingColorMode=true]
|
||||||
|
* if false, this plugin will not use <ColorModeProvider />
|
||||||
|
*/
|
||||||
|
isUsingColorMode: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
50
gatsby-node.ts
Normal file
50
gatsby-node.ts
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import { GatsbyNode } from "gatsby";
|
||||||
|
import path from "path";
|
||||||
|
import webpack from "webpack";
|
||||||
|
import { createRemoteFileNode } from "gatsby-source-filesystem";
|
||||||
|
|
||||||
|
export const sourceNodes: GatsbyNode['sourceNodes'] = async ({
|
||||||
|
actions,
|
||||||
|
createNodeId,
|
||||||
|
store,
|
||||||
|
cache,
|
||||||
|
reporter
|
||||||
|
}) => {
|
||||||
|
const { createNode } = actions;
|
||||||
|
|
||||||
|
await createRemoteFileNode({
|
||||||
|
url: "https://chainid.network/chains.json",
|
||||||
|
createNode,
|
||||||
|
createNodeId,
|
||||||
|
store,
|
||||||
|
cache,
|
||||||
|
reporter,
|
||||||
|
name: "chains",
|
||||||
|
ext: ".json"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://github.com/WalletConnect/walletconnect-monorepo/issues/584
|
||||||
|
export const onCreateWebpackConfig: GatsbyNode["onCreateWebpackConfig"] = ({
|
||||||
|
actions,
|
||||||
|
}) => {
|
||||||
|
actions.setWebpackConfig({
|
||||||
|
plugins: [
|
||||||
|
new webpack.ProvidePlugin({
|
||||||
|
Buffer: ["buffer", "Buffer"],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
fallback: {
|
||||||
|
util: path.resolve(`./node_modules/util/`),
|
||||||
|
url: path.resolve(`./node_modules/url/`),
|
||||||
|
assert: path.resolve(`./node_modules/assert/`),
|
||||||
|
crypto: path.resolve(`./node_modules/crypto-browserify`),
|
||||||
|
os: path.resolve(`./node_modules/os-browserify/browser`),
|
||||||
|
https: path.resolve(`./node_modules/https-browserify`),
|
||||||
|
http: path.resolve(`./node_modules/stream-http`),
|
||||||
|
stream: path.resolve(`./node_modules/stream-browserify`),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
54
package.json
Normal file
54
package.json
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
"name": "chainlist",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"description": "chainlist",
|
||||||
|
"author": "Frederik Bolding",
|
||||||
|
"keywords": [
|
||||||
|
"gatsby"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"develop": "gatsby develop",
|
||||||
|
"start": "gatsby develop",
|
||||||
|
"build": "gatsby build",
|
||||||
|
"serve": "gatsby serve",
|
||||||
|
"clean": "gatsby clean",
|
||||||
|
"typecheck": "tsc --noEmit"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@chakra-ui/gatsby-plugin": "^2.0.4",
|
||||||
|
"@chakra-ui/icons": "^1.1.7",
|
||||||
|
"@chakra-ui/react": "^1.8.6",
|
||||||
|
"@emotion/react": "^11.8.1",
|
||||||
|
"@emotion/styled": "^11.8.1",
|
||||||
|
"@ethersproject/providers": "^5.5.3",
|
||||||
|
"@walletconnect/web3-provider": "^1.7.3",
|
||||||
|
"assert": "^2.0.0",
|
||||||
|
"crypto-browserify": "^3.12.0",
|
||||||
|
"framer-motion": "^6.2.8",
|
||||||
|
"gatsby": "^4.9.0",
|
||||||
|
"gatsby-plugin-emotion": "^7.9.0",
|
||||||
|
"gatsby-plugin-netlify": "^4.1.0",
|
||||||
|
"gatsby-plugin-react-helmet": "^5.9.0",
|
||||||
|
"https-browserify": "^1.0.0",
|
||||||
|
"os-browserify": "^0.3.0",
|
||||||
|
"react": "^17.0.1",
|
||||||
|
"react-dom": "^17.0.1",
|
||||||
|
"react-helmet": "^6.1.0",
|
||||||
|
"react-icons": "^4.3.1",
|
||||||
|
"stream-browserify": "^3.0.0",
|
||||||
|
"stream-http": "^3.2.0",
|
||||||
|
"url": "^0.11.0",
|
||||||
|
"util": "^0.12.4",
|
||||||
|
"web3modal": "^1.9.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^17.0.14",
|
||||||
|
"@types/react": "^17.0.38",
|
||||||
|
"@types/react-dom": "^17.0.11",
|
||||||
|
"@types/react-helmet": "^6.1.5",
|
||||||
|
"gatsby-source-filesystem": "^4.9.0",
|
||||||
|
"gatsby-transformer-json": "^4.9.0",
|
||||||
|
"typescript": "^4.5.5"
|
||||||
|
}
|
||||||
|
}
|
10
scripts/check-deploy.sh
Executable file
10
scripts/check-deploy.sh
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
shouldDeploy=$(curl -s https://api.github.com/repos/ethereum-lists/chains/commits/master | jq -r "((now - (.commit.author.date | fromdateiso8601) ) / (60*60*24) | trunc)")
|
||||||
|
|
||||||
|
if [ $shouldDeploy -eq 0 ]
|
||||||
|
then
|
||||||
|
echo "Deploying..."
|
||||||
|
curl -X POST -d '{}' https://api.netlify.com/build_hooks/${BUILD_HOOK}
|
||||||
|
else
|
||||||
|
echo "No deploy needed"
|
||||||
|
fi
|
8
src/@chakra-ui/gatsby-plugin/theme.js
Normal file
8
src/@chakra-ui/gatsby-plugin/theme.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import { extendTheme } from "@chakra-ui/react";
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
initialColorMode: "system",
|
||||||
|
useSystemColorMode: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default extendTheme({ config });
|
59
src/components/Chain.tsx
Normal file
59
src/components/Chain.tsx
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Center,
|
||||||
|
Flex,
|
||||||
|
Stat,
|
||||||
|
StatGroup,
|
||||||
|
StatLabel,
|
||||||
|
StatNumber,
|
||||||
|
Text,
|
||||||
|
} from "@chakra-ui/react";
|
||||||
|
import React, { useContext } from "react";
|
||||||
|
import { Web3Context } from "../context/Web3Context";
|
||||||
|
import { ChainData } from "../types/chain";
|
||||||
|
|
||||||
|
export const Chain = ({
|
||||||
|
name,
|
||||||
|
chainId,
|
||||||
|
nativeCurrency,
|
||||||
|
...rest
|
||||||
|
}: ChainData) => {
|
||||||
|
const { isConnected, handleConnect, handleAddChain } =
|
||||||
|
useContext(Web3Context);
|
||||||
|
const handleAddChainClick = () => {
|
||||||
|
handleAddChain({ name, chainId, nativeCurrency, ...rest });
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Box px="5" py="4" borderWidth="1px" rounded="md" boxShadow="base">
|
||||||
|
<Flex mb="2">
|
||||||
|
<Text
|
||||||
|
fontSize="lg"
|
||||||
|
fontWeight="semibold"
|
||||||
|
lineHeight="short"
|
||||||
|
isTruncated
|
||||||
|
verticalAlign="middle"
|
||||||
|
>
|
||||||
|
{name}
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
<StatGroup>
|
||||||
|
<Stat>
|
||||||
|
<StatLabel>Chain ID</StatLabel>
|
||||||
|
<StatNumber fontSize="md">{chainId}</StatNumber>
|
||||||
|
</Stat>
|
||||||
|
<Stat>
|
||||||
|
<StatLabel>Currency</StatLabel>
|
||||||
|
<StatNumber fontSize="md">{nativeCurrency.symbol}</StatNumber>
|
||||||
|
</Stat>
|
||||||
|
</StatGroup>
|
||||||
|
<Center mt="2">
|
||||||
|
{!isConnected ? (
|
||||||
|
<Button onClick={handleConnect}>Connect Wallet</Button>
|
||||||
|
) : (
|
||||||
|
<Button onClick={handleAddChainClick}>Add Chain</Button>
|
||||||
|
)}
|
||||||
|
</Center>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
18
src/components/ChainList.tsx
Normal file
18
src/components/ChainList.tsx
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { SimpleGrid } from "@chakra-ui/react";
|
||||||
|
import React from "react";
|
||||||
|
import { ChainData } from "../types/chain";
|
||||||
|
import { Chain } from "./Chain";
|
||||||
|
|
||||||
|
export const ChainList = ({
|
||||||
|
chains,
|
||||||
|
}: {
|
||||||
|
chains: (ChainData & { id: string })[];
|
||||||
|
}) => (
|
||||||
|
<>
|
||||||
|
<SimpleGrid minChildWidth="300px" spacing={4}>
|
||||||
|
{chains.map((c) => (
|
||||||
|
<Chain key={c.id} {...c} />
|
||||||
|
))}
|
||||||
|
</SimpleGrid>
|
||||||
|
</>
|
||||||
|
);
|
15
src/components/DarkModeToggle.tsx
Normal file
15
src/components/DarkModeToggle.tsx
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import React from "react";
|
||||||
|
import { MoonIcon, SunIcon } from "@chakra-ui/icons";
|
||||||
|
import { IconButton, useColorMode } from "@chakra-ui/react";
|
||||||
|
|
||||||
|
export const DarkModeToggle = (props) => {
|
||||||
|
const { colorMode, toggleColorMode } = useColorMode();
|
||||||
|
return (
|
||||||
|
<IconButton
|
||||||
|
{...props}
|
||||||
|
aria-label="Toggle Dark Mode"
|
||||||
|
onClick={toggleColorMode}
|
||||||
|
icon={colorMode === "light" ? <MoonIcon /> : <SunIcon />}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
65
src/components/Header.tsx
Normal file
65
src/components/Header.tsx
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Heading,
|
||||||
|
Flex,
|
||||||
|
Text,
|
||||||
|
IconButton,
|
||||||
|
Link,
|
||||||
|
Tooltip,
|
||||||
|
} from "@chakra-ui/react";
|
||||||
|
import React, { useContext } from "react";
|
||||||
|
import { Web3Context } from "../context/Web3Context";
|
||||||
|
import { DarkModeToggle } from "./DarkModeToggle";
|
||||||
|
import { Search } from "./Search";
|
||||||
|
import { FaGithub } from "react-icons/fa";
|
||||||
|
import { AddIcon } from "@chakra-ui/icons";
|
||||||
|
|
||||||
|
export const Header = (props) => {
|
||||||
|
const { handleConnect, isConnected, address } = useContext(Web3Context);
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
pb="2"
|
||||||
|
flexDirection={{ base: "column", md: "row" }}
|
||||||
|
justifyContent="space-between"
|
||||||
|
>
|
||||||
|
<Heading>Chainlist</Heading>
|
||||||
|
<Search {...props} />
|
||||||
|
<Flex>
|
||||||
|
<Tooltip label="Add Network">
|
||||||
|
<Link
|
||||||
|
href="https://github.com/ethereum-lists/chains/pulls"
|
||||||
|
isExternal
|
||||||
|
>
|
||||||
|
<IconButton size="lg" aria-label="Add" icon={<AddIcon />} mr="1" />
|
||||||
|
</Link>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip label="GitHub">
|
||||||
|
<Link href="https://github.com/FrederikBolding/chainlist" isExternal>
|
||||||
|
<IconButton
|
||||||
|
size="lg"
|
||||||
|
aria-label="GitHub"
|
||||||
|
icon={<FaGithub />}
|
||||||
|
mr="1"
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
</Tooltip>
|
||||||
|
<DarkModeToggle size="lg" mr="1" />
|
||||||
|
{!isConnected ? (
|
||||||
|
<Button
|
||||||
|
w={{ base: "100%", md: "auto" }}
|
||||||
|
size="lg"
|
||||||
|
onClick={handleConnect}
|
||||||
|
>
|
||||||
|
Connect Wallet
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button size="lg" w={{ base: "100%", md: "auto" }}>
|
||||||
|
<Text fontSize="sm" isTruncated>
|
||||||
|
{address}
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
66
src/components/SEO.tsx
Normal file
66
src/components/SEO.tsx
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
import React from "react";
|
||||||
|
import { Helmet } from "react-helmet";
|
||||||
|
import { useStaticQuery, graphql } from "gatsby";
|
||||||
|
|
||||||
|
export const Seo = ({ lang = "en", meta = [] }) => {
|
||||||
|
const { site } = useStaticQuery(
|
||||||
|
graphql`
|
||||||
|
query {
|
||||||
|
site {
|
||||||
|
siteMetadata {
|
||||||
|
title
|
||||||
|
description
|
||||||
|
author
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
const metaDescription = site.siteMetadata.description;
|
||||||
|
const title = site.siteMetadata?.title;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Helmet
|
||||||
|
htmlAttributes={{
|
||||||
|
lang,
|
||||||
|
}}
|
||||||
|
title={title}
|
||||||
|
titleTemplate={`%s`}
|
||||||
|
meta={[
|
||||||
|
{
|
||||||
|
name: `description`,
|
||||||
|
content: metaDescription,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
property: `og:title`,
|
||||||
|
content: title,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
property: `og:description`,
|
||||||
|
content: metaDescription,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
property: `og:type`,
|
||||||
|
content: `website`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: `twitter:card`,
|
||||||
|
content: `summary`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: `twitter:creator`,
|
||||||
|
content: site.siteMetadata?.author || ``,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: `twitter:title`,
|
||||||
|
content: title,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: `twitter:description`,
|
||||||
|
content: metaDescription,
|
||||||
|
},
|
||||||
|
].concat(meta)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
21
src/components/Search.tsx
Normal file
21
src/components/Search.tsx
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { SearchIcon } from "@chakra-ui/icons";
|
||||||
|
import { Input, InputGroup, InputLeftElement } from "@chakra-ui/react";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export const Search = ({ setSearchQuery, searchQuery }) => {
|
||||||
|
const handleChange = (event) => setSearchQuery(event.target.value);
|
||||||
|
return (
|
||||||
|
<InputGroup size="lg" mx={{ base: 0, md: "5" }} mb={{ base: "2", md: 0}}>
|
||||||
|
<InputLeftElement
|
||||||
|
pointerEvents="none"
|
||||||
|
children={<SearchIcon color="gray.300" />}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
placeholder="Search"
|
||||||
|
value={searchQuery}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</InputGroup>
|
||||||
|
);
|
||||||
|
};
|
76
src/context/Web3Context.tsx
Normal file
76
src/context/Web3Context.tsx
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
import WalletConnectProvider from "@walletconnect/web3-provider";
|
||||||
|
import React, { createContext, useEffect, useState } from "react";
|
||||||
|
import { Web3Provider as EthersWeb3 } from "@ethersproject/providers";
|
||||||
|
import { ChainData } from "../types/chain";
|
||||||
|
|
||||||
|
// Hack to fix build
|
||||||
|
const Web3Modal = typeof window !== `undefined` ? require("web3modal") : null;
|
||||||
|
|
||||||
|
export const Web3Context = createContext({});
|
||||||
|
|
||||||
|
export const Web3Provider = ({ children }) => {
|
||||||
|
const [web3, setWeb3] = useState<any | undefined>(undefined);
|
||||||
|
const [address, setAddress] = useState(undefined);
|
||||||
|
const providerOptions = {
|
||||||
|
walletconnect: {
|
||||||
|
package: WalletConnectProvider,
|
||||||
|
options: {
|
||||||
|
infuraId: "854b581018fe44a59897b53ee6a19551",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const web3Modal =
|
||||||
|
Web3Modal &&
|
||||||
|
new Web3Modal.default({
|
||||||
|
cacheProvider: true, // optional
|
||||||
|
providerOptions, // required
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleConnect = () => {
|
||||||
|
web3Modal.connect().then(setWeb3);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isConnected = web3 !== undefined;
|
||||||
|
const provider = isConnected && new EthersWeb3(web3, "any");
|
||||||
|
const signer = provider && provider.getSigner();
|
||||||
|
|
||||||
|
const handleAddChain = (chain: ChainData) => {
|
||||||
|
provider.send("wallet_addEthereumChain", [
|
||||||
|
{
|
||||||
|
chainId: `0x${chain.chainId.toString(16)}`,
|
||||||
|
chainName: chain.name,
|
||||||
|
nativeCurrency: chain.nativeCurrency,
|
||||||
|
rpcUrls: chain.rpc,
|
||||||
|
blockExplorerUrls: chain.explorers?.map((e) => e.url),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateInfo = () => {
|
||||||
|
signer.getAddress().then((res) => setAddress(res));
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (web3) {
|
||||||
|
updateInfo();
|
||||||
|
web3.on("accountsChanged", updateInfo);
|
||||||
|
web3.on("chainChanged", updateInfo);
|
||||||
|
}
|
||||||
|
}, [web3]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Web3Context.Provider
|
||||||
|
value={{
|
||||||
|
web3,
|
||||||
|
setWeb3,
|
||||||
|
handleConnect,
|
||||||
|
isConnected,
|
||||||
|
handleAddChain,
|
||||||
|
address,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Web3Context.Provider>
|
||||||
|
);
|
||||||
|
};
|
BIN
src/images/icon.png
Normal file
BIN
src/images/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
21
src/pages/404.tsx
Normal file
21
src/pages/404.tsx
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import * as React from "react";
|
||||||
|
import { Text, Box, Container, Center, Heading } from "@chakra-ui/react";
|
||||||
|
|
||||||
|
const NotFoundPage = () => {
|
||||||
|
return (
|
||||||
|
<Box p="8" textAlign="center">
|
||||||
|
<Container>
|
||||||
|
<Center>
|
||||||
|
<Heading m="2" as="h1" size="2xl">
|
||||||
|
404
|
||||||
|
</Heading>
|
||||||
|
</Center>
|
||||||
|
<Text mt="4" opacity="0.75">
|
||||||
|
These are not the droids you are looking for.
|
||||||
|
</Text>
|
||||||
|
</Container>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NotFoundPage;
|
57
src/pages/index.tsx
Normal file
57
src/pages/index.tsx
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import { Box } from "@chakra-ui/react";
|
||||||
|
import { graphql, useStaticQuery } from "gatsby";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { ChainList } from "../components/ChainList";
|
||||||
|
import { Header } from "../components/Header";
|
||||||
|
import { Seo } from "../components/SEO";
|
||||||
|
import { Web3Provider } from "../context/Web3Context";
|
||||||
|
|
||||||
|
const IndexPage = () => {
|
||||||
|
const rawData = useStaticQuery(graphql`
|
||||||
|
query ChainsQuery {
|
||||||
|
allChainsJson {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
chain
|
||||||
|
chainId
|
||||||
|
rpc
|
||||||
|
icon
|
||||||
|
nativeCurrency {
|
||||||
|
decimals
|
||||||
|
name
|
||||||
|
symbol
|
||||||
|
}
|
||||||
|
explorers {
|
||||||
|
url
|
||||||
|
name
|
||||||
|
standard
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
const chains = rawData.allChainsJson.nodes;
|
||||||
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
|
const filteredChains =
|
||||||
|
searchQuery.length > 0
|
||||||
|
? chains.filter(
|
||||||
|
(chain) =>
|
||||||
|
chain.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||||
|
chain.chainId.toString().includes(searchQuery) ||
|
||||||
|
chain.nativeCurrency.symbol.toLowerCase().includes(searchQuery.toLowerCase())
|
||||||
|
)
|
||||||
|
: chains;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Web3Provider>
|
||||||
|
<Seo />
|
||||||
|
<Box py="4" px="8">
|
||||||
|
<Header searchQuery={searchQuery} setSearchQuery={setSearchQuery} />
|
||||||
|
<ChainList chains={filteredChains} />
|
||||||
|
</Box>
|
||||||
|
</Web3Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default IndexPage;
|
21
src/types/chain.ts
Normal file
21
src/types/chain.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
export interface ChainData {
|
||||||
|
name: string;
|
||||||
|
chain: string;
|
||||||
|
icon: string;
|
||||||
|
rpc: string[];
|
||||||
|
chainId: number;
|
||||||
|
nativeCurrency: ChainCurrency;
|
||||||
|
explorers?: BlockExplorer[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ChainCurrency {
|
||||||
|
name: string;
|
||||||
|
symbol: string;
|
||||||
|
decimals: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BlockExplorer {
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
standard: string;
|
||||||
|
}
|
102
tsconfig.json
Normal file
102
tsconfig.json
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
||||||
|
|
||||||
|
/* Projects */
|
||||||
|
// "incremental": true, /* Enable incremental compilation */
|
||||||
|
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||||
|
// "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
|
||||||
|
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
|
||||||
|
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||||
|
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||||
|
|
||||||
|
/* Language and Environment */
|
||||||
|
"target": "esnext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||||
|
"lib": ["dom", "esnext"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||||
|
"jsx": "react", /* Specify what JSX code is generated. */
|
||||||
|
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
||||||
|
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||||
|
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
|
||||||
|
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||||
|
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
|
||||||
|
// "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
|
||||||
|
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||||
|
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||||
|
|
||||||
|
/* Modules */
|
||||||
|
"module": "esnext", /* Specify what module code is generated. */
|
||||||
|
// "rootDir": "./", /* Specify the root folder within your source files. */
|
||||||
|
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||||
|
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||||
|
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||||
|
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||||
|
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
|
||||||
|
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||||
|
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||||
|
// "resolveJsonModule": true, /* Enable importing .json files */
|
||||||
|
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
|
||||||
|
|
||||||
|
/* JavaScript Support */
|
||||||
|
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
|
||||||
|
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||||
|
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
|
||||||
|
|
||||||
|
/* Emit */
|
||||||
|
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||||
|
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||||
|
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||||
|
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||||
|
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
|
||||||
|
// "outDir": "./", /* Specify an output folder for all emitted files. */
|
||||||
|
// "removeComments": true, /* Disable emitting comments. */
|
||||||
|
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||||
|
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||||
|
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
|
||||||
|
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||||
|
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||||
|
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||||
|
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||||
|
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||||
|
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||||
|
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||||
|
// "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
|
||||||
|
// "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
|
||||||
|
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||||
|
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
|
||||||
|
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||||
|
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||||
|
|
||||||
|
/* Interop Constraints */
|
||||||
|
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||||
|
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||||
|
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
|
||||||
|
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||||
|
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||||
|
|
||||||
|
/* Type Checking */
|
||||||
|
"strict": true, /* Enable all strict type-checking options. */
|
||||||
|
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
|
||||||
|
// "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
|
||||||
|
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||||
|
// "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
|
||||||
|
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||||
|
// "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
|
||||||
|
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||||
|
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||||
|
// "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
|
||||||
|
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
|
||||||
|
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||||
|
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||||
|
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||||
|
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
|
||||||
|
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||||
|
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
|
||||||
|
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||||
|
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||||
|
|
||||||
|
/* Completeness */
|
||||||
|
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||||
|
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||||
|
},
|
||||||
|
"include": ["./src/**/*"]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user