From c3a9e47a33deb484e9d8051a0cde07610f81ffa1 Mon Sep 17 00:00:00 2001
From: TrofimovAnton85 <98453427+TrofimovAnton85@users.noreply.github.com>
Date: Wed, 10 Jul 2024 10:18:25 +0200
Subject: [PATCH] feat(reference): act-1327 - added support eip-6963 (#1389)
* feat(reference): act-1327 - added support eip-6963
* feat(reference): remove selecte wallets
---
.../ParserOpenRPC/AuthBox/index.tsx | 36 ++++++++++++--
.../ParserOpenRPC/AuthBox/styles.module.css | 34 +++++++++++++
src/components/ParserOpenRPC/index.tsx | 31 +++++++++---
src/hooks/store.ts | 49 +++++++++++++++++++
src/hooks/useSyncProviders.ts | 4 ++
wallet/reference/new-reference.mdx | 2 +-
6 files changed, 144 insertions(+), 12 deletions(-)
create mode 100644 src/hooks/store.ts
create mode 100644 src/hooks/useSyncProviders.ts
diff --git a/src/components/ParserOpenRPC/AuthBox/index.tsx b/src/components/ParserOpenRPC/AuthBox/index.tsx
index 37ed0492e3b..fd0eebde152 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 > 0) {
+ 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 7cd7d9f61a8..20bf5c87c40 100644
--- a/src/components/ParserOpenRPC/index.tsx
+++ b/src/components/ParserOpenRPC/index.tsx
@@ -17,6 +17,7 @@ import {
trackInputChangeForSegment
} from "@site/src/lib/segmentAnalytics";
import { useLocation } from "@docusaurus/router";
+import { useSyncProviders } from "@site/src/hooks/useSyncProviders.ts"
interface ParserProps {
network: NETWORK_NAMES;
@@ -34,7 +35,6 @@ export const ParserOpenRPCContext = createContext {
+ setSelectedWallet(i);
+ }
+
useEffect(() => {
- const installed = !!(window as any)?.ethereum;
- setMetamaskInstalled(installed);
trackPageViewForSegment({
name: "Reference page",
path: location.pathname,
@@ -100,6 +105,15 @@ export default function ParserOpenRPC({ network, method }: ParserProps) {
})
}, []);
+ const metamaskProviders = useMemo(() => {
+ const isMetamasks = providers.filter(pr => pr?.info?.name?.includes("MetaMask"));
+ if (isMetamasks.length > 1) {
+ const indexWallet = isMetamasks.findIndex(item => item.info.name === "MetaMask");
+ setSelectedWallet(indexWallet);
+ }
+ return isMetamasks;
+ }, [providers]);
+
const onParamsChangeHandle = (data) => {
if (typeof data !== 'object' || data === null || Object.keys(data).length === 0) {
setParamsData([]);
@@ -112,8 +126,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
})
@@ -188,9 +203,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