From d7ba5f09fd2b69808bd3b4f19337de3acf250b12 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 24 Oct 2021 23:04:04 -0300 Subject: [PATCH 1/6] Extract ABI parent component --- src/address/ContractABI.tsx | 19 +++++++++++++++++++ src/address/Contracts.tsx | 11 ++--------- src/address/{ABI.tsx => RawABI.tsx} | 6 +++--- 3 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 src/address/ContractABI.tsx rename src/address/{ABI.tsx => RawABI.tsx} (74%) diff --git a/src/address/ContractABI.tsx b/src/address/ContractABI.tsx new file mode 100644 index 0000000..2f079de --- /dev/null +++ b/src/address/ContractABI.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import Copy from "../components/Copy"; +import RawABI from "./RawABI"; + +type ContractABIProps = { + abi: any[]; +}; + +const ContractABI: React.FC = ({ abi }) => ( +
+
+ ABI + +
+ +
+); + +export default React.memo(ContractABI); diff --git a/src/address/Contracts.tsx b/src/address/Contracts.tsx index 0745d73..dbaaf83 100644 --- a/src/address/Contracts.tsx +++ b/src/address/Contracts.tsx @@ -5,13 +5,12 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faChevronDown } from "@fortawesome/free-solid-svg-icons/faChevronDown"; import ContentFrame from "../ContentFrame"; import InfoRow from "../components/InfoRow"; -import Copy from "../components/Copy"; -import ABI from "./ABI"; import Contract from "./Contract"; import { RuntimeContext } from "../useRuntime"; import { Metadata } from "../useSourcify"; import ExternalLink from "../components/ExternalLink"; import { openInRemixURL } from "../url"; +import ContractABI from "./ContractABI"; type ContractsProps = { checksummedAddress: string; @@ -70,13 +69,7 @@ const Contracts: React.FC = ({ {rawMetadata !== undefined && rawMetadata !== null && ( <> {rawMetadata.output.abi && ( -
-
- ABI - -
- -
+ )}
diff --git a/src/address/ABI.tsx b/src/address/RawABI.tsx similarity index 74% rename from src/address/ABI.tsx rename to src/address/RawABI.tsx index a714367..bc07e81 100644 --- a/src/address/ABI.tsx +++ b/src/address/RawABI.tsx @@ -1,11 +1,11 @@ import React from "react"; import { SyntaxHighlighter, docco } from "../highlight-init"; -type ABIProps = { +type RawABIProps = { abi: any[]; }; -const ABI: React.FC = ({ abi }) => ( +const RawABI: React.FC = ({ abi }) => ( = ({ abi }) => ( ); -export default React.memo(ABI); +export default React.memo(RawABI); From 02261f264abd36bb9d3ca78c1eec7f79e8d06e43 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 25 Oct 2021 01:29:50 -0300 Subject: [PATCH 2/6] First parsed ABI UI prototype --- src/address/ContractABI.tsx | 26 ++++++++++++--- src/address/DecodedABI.tsx | 20 ++++++++++++ src/address/DecodedFragment.tsx | 57 +++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 src/address/DecodedABI.tsx create mode 100644 src/address/DecodedFragment.tsx diff --git a/src/address/ContractABI.tsx b/src/address/ContractABI.tsx index 2f079de..086d92c 100644 --- a/src/address/ContractABI.tsx +++ b/src/address/ContractABI.tsx @@ -1,5 +1,8 @@ import React from "react"; +import { Tab } from "@headlessui/react"; +import ModeTab from "../components/ModeTab"; import Copy from "../components/Copy"; +import DecodedABI from "./DecodedABI"; import RawABI from "./RawABI"; type ContractABIProps = { @@ -8,11 +11,24 @@ type ContractABIProps = { const ContractABI: React.FC = ({ abi }) => (
-
- ABI - -
- + + + Decoded + Raw + + + + + + +
+ ABI + +
+ +
+
+
); diff --git a/src/address/DecodedABI.tsx b/src/address/DecodedABI.tsx new file mode 100644 index 0000000..1de994d --- /dev/null +++ b/src/address/DecodedABI.tsx @@ -0,0 +1,20 @@ +import { Interface } from "@ethersproject/abi"; +import React from "react"; +import DecodedFragment from "./DecodedFragment"; + +type DecodedABIProps = { + abi: any[]; +}; + +const DecodedABI: React.FC = ({ abi }) => { + const intf = new Interface(abi); + return ( +
+ {intf.fragments.map((f, i) => ( + + ))} +
+ ); +}; + +export default React.memo(DecodedABI); diff --git a/src/address/DecodedFragment.tsx b/src/address/DecodedFragment.tsx new file mode 100644 index 0000000..33e694c --- /dev/null +++ b/src/address/DecodedFragment.tsx @@ -0,0 +1,57 @@ +import React from "react"; +import { + ConstructorFragment, + EventFragment, + Fragment, + FunctionFragment, + Interface, +} from "@ethersproject/abi"; + +type DecodedFragmentProps = { + intf: Interface; + fragment: Fragment; +}; + +const DecodedFragment: React.FC = ({ + intf, + fragment, +}) => { + let sig: string | undefined; + let letter: string | undefined; + let letterBg: string | undefined; + + if (FunctionFragment.isFunctionFragment(fragment)) { + sig = intf.getSighash(fragment); + letter = "F"; + letterBg = "bg-purple-500"; + } else if (EventFragment.isEventFragment(fragment)) { + sig = intf.getEventTopic(fragment); + letter = "E"; + letterBg = "bg-green-300"; + } else if (ConstructorFragment.isConstructorFragment(fragment)) { + letter = "C"; + letterBg = "bg-blue-500"; + } + + return ( +
+ {letter && ( + + {letter} + + )} + + {fragment.format("full")} + + {sig && ( + + {sig} + + )} +
+ ); +}; + +export default React.memo(DecodedFragment); From 4acc8be926bd5150d40952d42c63ce8c81b229ee Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 25 Oct 2021 01:44:24 -0300 Subject: [PATCH 3/6] UI tweaks --- src/address/ContractABI.tsx | 10 +++++----- src/address/DecodedABI.tsx | 2 +- src/address/DecodedFragment.tsx | 7 ++++++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/address/ContractABI.tsx b/src/address/ContractABI.tsx index 086d92c..edd713c 100644 --- a/src/address/ContractABI.tsx +++ b/src/address/ContractABI.tsx @@ -12,7 +12,11 @@ type ContractABIProps = { const ContractABI: React.FC = ({ abi }) => (
- + +
+ ABI + +
Decoded Raw
@@ -21,10 +25,6 @@ const ContractABI: React.FC = ({ abi }) => ( -
- ABI - -
diff --git a/src/address/DecodedABI.tsx b/src/address/DecodedABI.tsx index 1de994d..587538a 100644 --- a/src/address/DecodedABI.tsx +++ b/src/address/DecodedABI.tsx @@ -9,7 +9,7 @@ type DecodedABIProps = { const DecodedABI: React.FC = ({ abi }) => { const intf = new Interface(abi); return ( -
+
{intf.fragments.map((f, i) => ( ))} diff --git a/src/address/DecodedFragment.tsx b/src/address/DecodedFragment.tsx index 33e694c..991865a 100644 --- a/src/address/DecodedFragment.tsx +++ b/src/address/DecodedFragment.tsx @@ -6,6 +6,8 @@ import { FunctionFragment, Interface, } from "@ethersproject/abi"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faCaretRight } from "@fortawesome/free-solid-svg-icons/faCaretRight"; type DecodedFragmentProps = { intf: Interface; @@ -34,7 +36,10 @@ const DecodedFragment: React.FC = ({ } return ( -
+
+ + + {letter && ( Date: Mon, 25 Oct 2021 14:43:41 -0300 Subject: [PATCH 4/6] Color topic hashes/method selectors --- src/address/DecodedFragment.tsx | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/address/DecodedFragment.tsx b/src/address/DecodedFragment.tsx index 991865a..211d67c 100644 --- a/src/address/DecodedFragment.tsx +++ b/src/address/DecodedFragment.tsx @@ -18,19 +18,26 @@ const DecodedFragment: React.FC = ({ intf, fragment, }) => { + let fragmentType: "constructor" | "event" | "function" | undefined; let sig: string | undefined; let letter: string | undefined; let letterBg: string | undefined; + let hashBg: string | undefined; if (FunctionFragment.isFunctionFragment(fragment)) { + fragmentType = "function"; sig = intf.getSighash(fragment); letter = "F"; letterBg = "bg-purple-500"; + hashBg = "bg-purple-50"; } else if (EventFragment.isEventFragment(fragment)) { + fragmentType = "event"; sig = intf.getEventTopic(fragment); letter = "E"; letterBg = "bg-green-300"; + hashBg = "bg-green-50"; } else if (ConstructorFragment.isConstructorFragment(fragment)) { + fragmentType = "constructor"; letter = "C"; letterBg = "bg-blue-500"; } @@ -51,7 +58,16 @@ const DecodedFragment: React.FC = ({ {fragment.format("full")} {sig && ( - + {sig} )} From 0228a6b6aeced9a08b2b09e009d41f1a0eabd473 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 25 Oct 2021 14:49:17 -0300 Subject: [PATCH 5/6] Fix overflow --- src/address/DecodedABI.tsx | 2 +- src/address/DecodedFragment.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/address/DecodedABI.tsx b/src/address/DecodedABI.tsx index 587538a..83faabc 100644 --- a/src/address/DecodedABI.tsx +++ b/src/address/DecodedABI.tsx @@ -9,7 +9,7 @@ type DecodedABIProps = { const DecodedABI: React.FC = ({ abi }) => { const intf = new Interface(abi); return ( -
+
{intf.fragments.map((f, i) => ( ))} diff --git a/src/address/DecodedFragment.tsx b/src/address/DecodedFragment.tsx index 211d67c..ac06a16 100644 --- a/src/address/DecodedFragment.tsx +++ b/src/address/DecodedFragment.tsx @@ -43,7 +43,7 @@ const DecodedFragment: React.FC = ({ } return ( -
+
From b8e081996cb784e30e2e018a70dc43a8b44fc29d Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 25 Oct 2021 15:14:01 -0300 Subject: [PATCH 6/6] Replace deprecated react-helmet --- package-lock.json | 92 +++++++++++++++++++++++------------------------ package.json | 3 +- src/index.tsx | 24 +++++++------ 3 files changed, 59 insertions(+), 60 deletions(-) diff --git a/package-lock.json b/package-lock.json index 465caa4..ac44d74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,6 @@ "@types/react": "^17.0.31", "@types/react-blockies": "^1.4.1", "@types/react-dom": "^17.0.10", - "@types/react-helmet": "^6.1.4", "@types/react-highlight": "^0.12.5", "@types/react-router-dom": "^5.3.1", "@types/react-syntax-highlighter": "^13.5.2", @@ -43,7 +42,7 @@ "react-chartjs-2": "^3.2.0", "react-dom": "^17.0.2", "react-error-boundary": "^3.1.3", - "react-helmet": "^6.1.0", + "react-helmet-async": "^1.1.2", "react-image": "^4.0.3", "react-router-dom": "^5.3.0", "react-scripts": "4.0.3", @@ -3119,14 +3118,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-helmet": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@types/react-helmet/-/react-helmet-6.1.4.tgz", - "integrity": "sha512-jyx50RNZXVaTGHY3MsoRPNpeiVk8b0XTPgD/O6KHF6COTDnG/+lRjPYvTK5nfWtR3xDOux0w6bHLAsaHo2ZLTA==", - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/react-highlight": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/@types/react-highlight/-/react-highlight-0.12.5.tgz", @@ -9839,6 +9830,14 @@ "node": ">= 0.4" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/ip": { "version": "1.1.5", "license": "MIT" @@ -14588,18 +14587,20 @@ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" }, - "node_modules/react-helmet": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", - "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==", + "node_modules/react-helmet-async": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.1.2.tgz", + "integrity": "sha512-LTTzDDkyIleT/JJ6T/uqx7Y8qi1EuPPSiJawQY/nHHz0h7SPDT6HxP1YDDQx/fzcVxCqpWEEMS3QdrSrNkJYhg==", "dependencies": { - "object-assign": "^4.1.1", + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", "prop-types": "^15.7.2", - "react-fast-compare": "^3.1.1", - "react-side-effect": "^2.1.0" + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" }, "peerDependencies": { - "react": ">=16.3.0" + "react": "^16.6.0 || ^17.0.0", + "react-dom": "^16.6.0 || ^17.0.0" } }, "node_modules/react-image": { @@ -14949,14 +14950,6 @@ "node": ">=0.10.0" } }, - "node_modules/react-side-effect": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.1.tgz", - "integrity": "sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ==", - "peerDependencies": { - "react": "^16.3.0 || ^17.0.0" - } - }, "node_modules/react-syntax-highlighter": { "version": "15.4.4", "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.4.4.tgz", @@ -16314,6 +16307,11 @@ "sha.js": "bin.js" } }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "node_modules/shebang-command": { "version": "2.0.0", "license": "MIT", @@ -21703,14 +21701,6 @@ "@types/react": "*" } }, - "@types/react-helmet": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@types/react-helmet/-/react-helmet-6.1.4.tgz", - "integrity": "sha512-jyx50RNZXVaTGHY3MsoRPNpeiVk8b0XTPgD/O6KHF6COTDnG/+lRjPYvTK5nfWtR3xDOux0w6bHLAsaHo2ZLTA==", - "requires": { - "@types/react": "*" - } - }, "@types/react-highlight": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/@types/react-highlight/-/react-highlight-0.12.5.tgz", @@ -26271,6 +26261,14 @@ "side-channel": "^1.0.4" } }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, "ip": { "version": "1.1.5" }, @@ -29420,15 +29418,16 @@ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" }, - "react-helmet": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", - "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==", + "react-helmet-async": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.1.2.tgz", + "integrity": "sha512-LTTzDDkyIleT/JJ6T/uqx7Y8qi1EuPPSiJawQY/nHHz0h7SPDT6HxP1YDDQx/fzcVxCqpWEEMS3QdrSrNkJYhg==", "requires": { - "object-assign": "^4.1.1", + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", "prop-types": "^15.7.2", - "react-fast-compare": "^3.1.1", - "react-side-effect": "^2.1.0" + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" } }, "react-image": { @@ -29675,12 +29674,6 @@ } } }, - "react-side-effect": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.1.tgz", - "integrity": "sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ==", - "requires": {} - }, "react-syntax-highlighter": { "version": "15.4.4", "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.4.4.tgz", @@ -30615,6 +30608,11 @@ "safe-buffer": "^5.0.1" } }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "shebang-command": { "version": "2.0.0", "requires": { diff --git a/package.json b/package.json index 0369b84..79b4887 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ "@types/react": "^17.0.31", "@types/react-blockies": "^1.4.1", "@types/react-dom": "^17.0.10", - "@types/react-helmet": "^6.1.4", "@types/react-highlight": "^0.12.5", "@types/react-router-dom": "^5.3.1", "@types/react-syntax-highlighter": "^13.5.2", @@ -38,7 +37,7 @@ "react-chartjs-2": "^3.2.0", "react-dom": "^17.0.2", "react-error-boundary": "^3.1.3", - "react-helmet": "^6.1.0", + "react-helmet-async": "^1.1.2", "react-image": "^4.0.3", "react-router-dom": "^5.3.0", "react-scripts": "4.0.3", diff --git a/src/index.tsx b/src/index.tsx index 29ad212..11695da 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,6 +1,6 @@ import React from "react"; import ReactDOM from "react-dom"; -import { Helmet } from "react-helmet"; +import { HelmetProvider, Helmet } from "react-helmet-async"; import "@fontsource/space-grotesk/index.css"; import "@fontsource/roboto/index.css"; import "@fontsource/roboto-mono/index.css"; @@ -11,16 +11,18 @@ import reportWebVitals from "./reportWebVitals"; ReactDOM.render( - - - - + + + + + + , document.getElementById("root") );