diff --git a/src/components/ParserOpenRPC/AuthBox/index.tsx b/src/components/ParserOpenRPC/AuthBox/index.tsx index 37ed0492e3b..49a4b8f8c56 100644 --- a/src/components/ParserOpenRPC/AuthBox/index.tsx +++ b/src/components/ParserOpenRPC/AuthBox/index.tsx @@ -2,9 +2,12 @@ import React from "react"; import Link from "@docusaurus/Link"; import styles from "./styles.module.css"; import global from "../global.module.css"; +import { EIP6963ProviderDetail } from "@site/src/hooks/store.ts" interface AuthBoxProps { - isMetamaskInstalled: boolean; + metamaskProviders: any; + handleConnect: (i) => void; + selectedProvider?: number; } const MetamaskInstallMessage = () => ( @@ -15,10 +18,33 @@ const MetamaskInstallMessage = () => ( ); -export const AuthBox = ({ isMetamaskInstalled }: AuthBoxProps) => { +export const AuthBox = ({ metamaskProviders = [], selectedProvider, handleConnect }: AuthBoxProps) => { + if (metamaskProviders.length === 0) { + return + } + + if (metamaskProviders.length === 1) { + return null + } + return ( - <> - {!isMetamaskInstalled ? : null} - +
+

Select a MetaMask provider to use interactive features:

+
+ {metamaskProviders.map((provider: EIP6963ProviderDetail, i) => ( +
+ +
+ ))} +
+
); }; diff --git a/src/components/ParserOpenRPC/AuthBox/styles.module.css b/src/components/ParserOpenRPC/AuthBox/styles.module.css index c8562f6d322..d7d2a8e8eff 100644 --- a/src/components/ParserOpenRPC/AuthBox/styles.module.css +++ b/src/components/ParserOpenRPC/AuthBox/styles.module.css @@ -17,3 +17,37 @@ font-size: 14px; line-height: 22px; } + +.mmBtnRow { + display: flex; + flex-wrap: wrap; +} + +.mmBtnCol { + width: 100%; + margin-bottom: 10px; +} + +.mmBtn { + position: relative; + display: flex; + align-items: center; + padding: 16px 30px 16px 20px; + width: 100%; + background: none; + border-radius: 10px; + outline: none; + font-size: 16px; + font-weight: 500; + line-height: 22px; + border: 1px solid rgba(3, 118, 201, 1); + color: rgba(3, 118, 201, 1); +} + +.mmBtnCheck { + position: absolute; + top: 50%; + transform: translateY(-50%); + right: 15px; + font-size: 16px; +} diff --git a/src/components/ParserOpenRPC/index.tsx b/src/components/ParserOpenRPC/index.tsx index 7bcdad5729b..0b3d258ce8b 100644 --- a/src/components/ParserOpenRPC/index.tsx +++ b/src/components/ParserOpenRPC/index.tsx @@ -11,6 +11,7 @@ import global from "./global.module.css"; import modalDrawerStyles from "./ModalDrawer/styles.module.css"; import clsx from "clsx"; import { useColorMode } from "@docusaurus/theme-common"; +import { useSyncProviders } from "@site/src/hooks/useSyncProviders.ts" interface ParserProps { network: NETWORK_NAMES; @@ -28,7 +29,6 @@ export const ParserOpenRPCContext = createContext { + setSelectedWallet(i); + } + useEffect(() => { - const installed = !!(window as any)?.ethereum; - setMetamaskInstalled(installed); - }, []); + const isMetamaskProviders = providers.filter(pr => pr?.info?.name?.includes("MetaMask")); + setMetamaskProviders([...isMetamaskProviders]); + }, [providers]); const onParamsChangeHandle = (data) => { if (typeof data !== 'object' || data === null || Object.keys(data).length === 0) { @@ -88,8 +96,9 @@ export default function ParserOpenRPC({ network, method }: ParserProps) { } const onSubmitRequestHandle = async () => { + if (metamaskProviders.length === 0) return try { - const response = await (window as any).ethereum.request({ + const response = await metamaskProviders[selectedWallet].provider.request({ method: method, params: paramsData }) @@ -158,9 +167,13 @@ export default function ParserOpenRPC({ network, method }: ParserProps) {
- + 0} method={method} params={currentMethodData.params} paramsData={paramsData} diff --git a/src/hooks/store.ts b/src/hooks/store.ts new file mode 100644 index 00000000000..2556b9d107b --- /dev/null +++ b/src/hooks/store.ts @@ -0,0 +1,49 @@ +declare global{ + interface WindowEventMap { + "eip6963:announceProvider": CustomEvent + } +} + +export interface EIP6963ProviderInfo { + walletId: string; + uuid: string; + name: string; + icon: string; +} + +export interface EIP1193Provider { + isStatus?: boolean; + host?: string; + path?: string; + sendAsync?: (request: { method: string, params?: Array }, callback: (error: Error | null, response: unknown) => void) => void; + send?: (request: { method: string, params?: Array }, callback: (error: Error | null, response: unknown) => void) => void; + request: (request: { method: string, params?: Array }) => Promise; +} + +export interface EIP6963ProviderDetail { + info: EIP6963ProviderInfo; + provider: EIP1193Provider; +} + +type EIP6963AnnounceProviderEvent = { + detail: { + info: EIP6963ProviderInfo; + provider: EIP1193Provider; + } +} + +let providers: EIP6963ProviderDetail[] = [] +export const store = { + value: ()=> providers, + subscribe: (callback: ()=> void) => { + function onAnnouncement(event: EIP6963AnnounceProviderEvent){ + if(providers.map(p => p.info.uuid).includes(event.detail.info.uuid)) return + providers = [...providers, event.detail] + callback() + } + window.addEventListener("eip6963:announceProvider", onAnnouncement); + window.dispatchEvent(new Event("eip6963:requestProvider")); + + return () => window.removeEventListener("eip6963:announceProvider", onAnnouncement) + } +} \ No newline at end of file diff --git a/src/hooks/useSyncProviders.ts b/src/hooks/useSyncProviders.ts new file mode 100644 index 00000000000..b9db3eff98f --- /dev/null +++ b/src/hooks/useSyncProviders.ts @@ -0,0 +1,4 @@ +import { useSyncExternalStore } from "react"; +import { store } from "./store"; + +export const useSyncProviders = ()=> useSyncExternalStore(store.subscribe, store.value, store.value) \ No newline at end of file diff --git a/wallet/reference/new-reference.mdx b/wallet/reference/new-reference.mdx index cbbf4f7a0c6..5d209868a06 100644 --- a/wallet/reference/new-reference.mdx +++ b/wallet/reference/new-reference.mdx @@ -8,4 +8,4 @@ sidebar_class_name: "hidden" import ParserOpenRPC from "@site/src/components/ParserOpenRPC"; import { NETWORK_NAMES } from "@site/src/plugins/plugin-json-rpc"; - \ No newline at end of file + \ No newline at end of file