From 77ccee713d27095e6f72a54c0a781587f1e90327 Mon Sep 17 00:00:00 2001 From: Arnau Espin <43625217+aspnxdd@users.noreply.github.com> Date: Mon, 1 Aug 2022 10:28:09 +0200 Subject: [PATCH] feat/network switch (#26) * feat: add network config * feat: add connection context to app * feat: network selector * feat: add sass and primer css * fix: fix wallet styles * feat: add tokens filter * feat: send network to api * feat: add fallback rpc * refactor: refactor network selector * fix: merge error * fix: merge error * trigger deployment * fix: make sure connection is not undefined * fix * feat: add network to mongodb * feat: remove mongo from mainnet * style: fix header * fix: add connection to getTokenBalance * fix: fix connection context to have null default value --- components/Layout/NetworkSelector.tsx | 141 +++++++++++++------------- components/Layout/index.ts | 2 +- components/Table/HeaderTable.tsx | 19 +++- components/Table/Row.tsx | 16 +-- contexts/ConnectionContext.ts | 4 +- contexts/index.ts | 1 + db/lib.ts | 3 +- hooks/useCreateToken.ts | 18 ++-- hooks/useFetchTokens.ts | 6 +- hooks/useMintAndTransfer.ts | 5 +- lib/create-token.ts | 6 +- lib/spl.ts | 1 - pages/_app.tsx | 2 +- pages/api/mint.ts | 1 + pages/api/mongo-get.ts | 2 +- types.ts | 1 + 16 files changed, 122 insertions(+), 106 deletions(-) diff --git a/components/Layout/NetworkSelector.tsx b/components/Layout/NetworkSelector.tsx index dcbd940..8a9d37c 100644 --- a/components/Layout/NetworkSelector.tsx +++ b/components/Layout/NetworkSelector.tsx @@ -1,81 +1,80 @@ -import { FC, useEffect, useRef } from 'react' -import { WalletAdapterNetwork } from '@solana/wallet-adapter-base' -import { clusterApiUrl, Connection } from '@solana/web3.js' -import { Network, useConnection } from 'contexts' +import { FC, useEffect, useRef } from "react"; +import { WalletAdapterNetwork } from "@solana/wallet-adapter-base"; +import { clusterApiUrl, Connection } from "@solana/web3.js"; +import { Network, useConnection } from "contexts"; -const RPC_API_DEVNET = process.env.NEXT_PUBLIC_RPC_API_DEVNET || clusterApiUrl('devnet') -const RPC_API_MAINNET = process.env.NEXT_PUBLIC_RPC_API_MAINNET || clusterApiUrl('mainnet-beta') +const RPC_API_DEVNET = + process.env.NEXT_PUBLIC_RPC_API_DEVNET || clusterApiUrl("devnet"); +const RPC_API_MAINNET = + process.env.NEXT_PUBLIC_RPC_API_MAINNET || clusterApiUrl("mainnet-beta"); function getUrl(network: Network): string { - switch (network) { - case 'Devnet': - return RPC_API_DEVNET - case 'Mainnet': - return RPC_API_MAINNET - default: - throw new Error(`Unknown network: ${network}`) - } + switch (network) { + case "Devnet": + return RPC_API_DEVNET; + case "Mainnet": + return RPC_API_MAINNET; + default: + throw new Error(`Unknown network: ${network}`); + } } const NetworkSelector: FC = () => { - const { setConnection, network, setNetwork, setUrl } = useConnection() - const detailsRef = useRef(null) - function hideUl() { - detailsRef.current!.removeAttribute('open') - } + const { setConnection, network, setNetwork, setUrl } = useConnection(); + const detailsRef = useRef(null); - useEffect(() => { - const _network = window.localStorage.getItem('network-fontana') as Network | null - if (_network === 'Devnet' || _network === 'Mainnet' || _network === 'Testnet') { - setNetwork(_network) - setConnection(new Connection(getUrl(_network))) - setUrl(getUrl(_network)) - window.localStorage.setItem('network-fontana', _network) - } - if (!_network) { - setNetwork('Devnet') - setConnection(new Connection(getUrl('Devnet'))) - setUrl(getUrl('Devnet')) - window.localStorage.setItem('network-fontana', 'Devnet') - } - }, []) - function changeNetwork(_network: Network) { - setNetwork(_network) - setConnection(new Connection(getUrl(_network))) - setUrl(getUrl(_network)) - hideUl() - window.localStorage.setItem('network-fontana', _network) + function hideUl() { + detailsRef.current!.removeAttribute("open"); + } + + function changeNetwork(_network: Network) { + setNetwork(_network); + setConnection(new Connection(getUrl(_network))); + setUrl(getUrl(_network)); + localStorage.setItem("network-fontana", _network); + } + + useEffect(() => { + const _network = localStorage.getItem("network-fontana") as Network | null; + if (_network === "Devnet" || _network === "Mainnet" || _network === "Testnet") { + changeNetwork(_network); + return; } + changeNetwork("Devnet"); + }, []); - return ( -
-
- - {network || 'Select Network'} - - - { -
    - {Object.keys(WalletAdapterNetwork) - .filter((e) => e !== 'Testnet') - .map((_network) => ( -
  • changeNetwork(_network as Network)} - > - {_network} -
  • - ))} -
- } -
-
- ) -} + return ( +
+
+ + {network || "Select Network"} + + + { +
    + {Object.keys(WalletAdapterNetwork) + .filter((e) => e !== "Testnet") + .map((_network) => ( +
  • { + changeNetwork(_network as Network); + hideUl(); + }} + > + {_network} +
  • + ))} +
+ } +
+
+ ); +}; -export default NetworkSelector \ No newline at end of file +export default NetworkSelector; diff --git a/components/Layout/index.ts b/components/Layout/index.ts index 07e1458..448adc8 100644 --- a/components/Layout/index.ts +++ b/components/Layout/index.ts @@ -1,5 +1,5 @@ export { default as Wallet } from "./Wallet"; export { default as Header } from "./Header"; export { default as FontanaSVG } from "./FontanaSVG"; -export { default as Toast } from "./Flash"; export { default as NetworkSelector } from "./NetworkSelector"; +export { default as Toast } from "./Flash"; diff --git a/components/Table/HeaderTable.tsx b/components/Table/HeaderTable.tsx index f0361cc..2a626f7 100644 --- a/components/Table/HeaderTable.tsx +++ b/components/Table/HeaderTable.tsx @@ -2,7 +2,7 @@ import { Header, Text, Button, Box, StyledOcticon } from "@primer/react"; import { CheckIcon, SyncIcon } from "@primer/octicons-react"; import { useWallet } from "@solana/wallet-adapter-react"; -import { useHasMongoUri } from "contexts"; +import { useHasMongoUri, useConnection } from "contexts"; import { HourglassIcon } from "@primer/octicons-react"; import { useCreateToken } from "hooks"; @@ -11,8 +11,15 @@ const HeaderTable: React.FC<{ tokensAmount: number }> = ({ }) => { const { publicKey } = useWallet(); const { hasMongoUri } = useHasMongoUri(); + const { network } = useConnection(); const { createToken, minting, triggerRefresh } = useCreateToken(); + const canCreateToken = () => { + if (publicKey) return true; + if (!publicKey && hasMongoUri && network === "Devnet") return true; + return false; + }; + return (
= ({ > - +

{tokensAmount} SPL Tokens available - +

= ({ position: "relative", }} > - {(hasMongoUri || publicKey) && ( + {canCreateToken() && (