import React, { useEffect, useState } from "react"; import { version } from "@walletconnect/sign-client/package.json"; import Banner from "./components/Banner"; import Blockchain from "./components/Blockchain"; import Column from "./components/Column"; import Header from "./components/Header"; import Modal from "./components/Modal"; import { DEFAULT_COSMOS_METHODS, DEFAULT_EIP155_METHODS, DEFAULT_MAIN_CHAINS, DEFAULT_SOLANA_METHODS, DEFAULT_TEST_CHAINS, } from "./constants"; import { AccountAction, setLocaleStorageTestnetFlag } from "./helpers"; import Toggle from "./components/Toggle"; import RequestModal from "./modals/RequestModal"; import PairingModal from "./modals/PairingModal"; import PingModal from "./modals/PingModal"; import { SAccounts, SAccountsContainer, SButtonContainer, SConnectButton, SContent, SLanding, SLayout, SToggleContainer, } from "./components/app"; import { useWalletConnectClient } from "./contexts/ClientContext"; import { useJsonRpc } from "./contexts/JsonRpcContext"; import { useChainData } from "./contexts/ChainDataContext"; export default function App() { const [modal, setModal] = useState(""); const closeModal = () => setModal(""); const openPairingModal = () => setModal("pairing"); const openPingModal = () => setModal("ping"); const openRequestModal = () => setModal("request"); // Initialize the WalletConnect client. const { client, session, connect, disconnect, chains, accounts, balances, isFetchingBalances, isInitializing, setChains, } = useWalletConnectClient(); // Use `JsonRpcContext` to provide us with relevant RPC methods and states. const { ping, ethereumRpc, cosmosRpc, solanaRpc, isRpcRequestPending, rpcResult, isTestnet, setIsTestnet, } = useJsonRpc(); const { chainData } = useChainData(); // Close the pairing modal after a session is established. useEffect(() => { if (session && modal === "pairing") { closeModal(); } }, [session, modal]); const onConnect = () => { if (typeof client === "undefined") { throw new Error("WalletConnect is not initialized"); } // Suggest existing pairings (if any). if (client.pairing.values.length) { openPairingModal(); } else { // If no existing pairings are available, trigger `WalletConnectClient.connect`. connect(); } }; const onPing = async () => { openPingModal(); await ping(); }; const getEthereumActions = (): AccountAction[] => { const onSendTransaction = async (chainId: string, address: string) => { openRequestModal(); await ethereumRpc.testSendTransaction(chainId, address); }; const onSignTransaction = async (chainId: string, address: string) => { openRequestModal(); await ethereumRpc.testSignTransaction(chainId, address); }; const onSignPersonalMessage = async (chainId: string, address: string) => { openRequestModal(); await ethereumRpc.testSignPersonalMessage(chainId, address); }; const onEthSign = async (chainId: string, address: string) => { openRequestModal(); await ethereumRpc.testEthSign(chainId, address); }; const onSignTypedData = async (chainId: string, address: string) => { openRequestModal(); await ethereumRpc.testSignTypedData(chainId, address); }; return [ { method: DEFAULT_EIP155_METHODS.ETH_SEND_TRANSACTION, callback: onSendTransaction }, { method: DEFAULT_EIP155_METHODS.ETH_SIGN_TRANSACTION, callback: onSignTransaction }, { method: DEFAULT_EIP155_METHODS.PERSONAL_SIGN, callback: onSignPersonalMessage }, { method: DEFAULT_EIP155_METHODS.ETH_SIGN + " (standard)", callback: onEthSign }, { method: DEFAULT_EIP155_METHODS.ETH_SIGN_TYPED_DATA, callback: onSignTypedData }, ]; }; const getCosmosActions = (): AccountAction[] => { const onSignDirect = async (chainId: string, address: string) => { openRequestModal(); await cosmosRpc.testSignDirect(chainId, address); }; const onSignAmino = async (chainId: string, address: string) => { openRequestModal(); await cosmosRpc.testSignAmino(chainId, address); }; return [ { method: DEFAULT_COSMOS_METHODS.COSMOS_SIGN_DIRECT, callback: onSignDirect }, { method: DEFAULT_COSMOS_METHODS.COSMOS_SIGN_AMINO, callback: onSignAmino }, ]; }; const getSolanaActions = (): AccountAction[] => { const onSignTransaction = async (chainId: string, address: string) => { openRequestModal(); await solanaRpc.testSignTransaction(chainId, address); }; const onSignMessage = async (chainId: string, address: string) => { openRequestModal(); await solanaRpc.testSignMessage(chainId, address); }; return [ { method: DEFAULT_SOLANA_METHODS.SOL_SIGN_TRANSACTION, callback: onSignTransaction }, { method: DEFAULT_SOLANA_METHODS.SOL_SIGN_MESSAGE, callback: onSignMessage }, ]; }; const getBlockchainActions = (chainId: string) => { const [namespace] = chainId.split(":"); switch (namespace) { case "eip155": return getEthereumActions(); case "cosmos": return getCosmosActions(); case "solana": return getSolanaActions(); default: break; } }; // Toggle between displaying testnet or mainnet chains as selection options. const toggleTestnets = () => { const nextIsTestnetState = !isTestnet; setIsTestnet(nextIsTestnetState); setLocaleStorageTestnetFlag(nextIsTestnetState); }; const handleChainSelectionClick = (chainId: string) => { if (chains.includes(chainId)) { setChains(chains.filter(chain => chain !== chainId)); } else { setChains([...chains, chainId]); } }; // Renders the appropriate model for the given request that is currently in-flight. const renderModal = () => { switch (modal) { case "pairing": if (typeof client === "undefined") { throw new Error("WalletConnect is not initialized"); } return ; case "request": return ; case "ping": return ; default: return null; } }; const renderContent = () => { const chainOptions = isTestnet ? DEFAULT_TEST_CHAINS : DEFAULT_MAIN_CHAINS; return !accounts.length && !Object.keys(balances).length ? (
{`Using v${version || "2.0.0-beta"}`}
Select chains:

Testnets Only?

{chainOptions.map(chainId => ( ))} {"Connect"}
) : (

Accounts

{accounts.map(account => { const [namespace, reference, address] = account.split(":"); const chainId = `${namespace}:${reference}`; return ( ); })}
); }; return (
{isInitializing ? "Loading..." : renderContent()} {renderModal()} ); }