From b880730d6d5d8d7f98bd5b42f1da5605c5a1a70b Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 21 Aug 2023 12:38:08 +0100 Subject: [PATCH 1/2] use prettier to format all code files in repo. adjust eslint rules. fix text in vyper --- .eslintrc.json | 7 +- .prettierrc.json | 3 +- apps/debugger/src/app/app.tsx | 14 +- apps/debugger/src/main.tsx | 11 +- apps/debugger/webpack.config.js | 67 +- apps/doc-gen/src/app/App.tsx | 30 +- .../doc-gen/src/app/hooks/useLocalStorage.tsx | 25 +- apps/doc-gen/src/app/views/ErrorView.tsx | 23 +- apps/doc-gen/src/main.tsx | 10 +- apps/doc-gen/webpack.config.js | 25 +- apps/doc-viewer/src/app/App.tsx | 9 +- apps/doc-viewer/src/main.tsx | 4 +- apps/doc-viewer/webpack.config.js | 32 +- apps/etherscan/src/app/AppContext.tsx | 20 +- apps/etherscan/src/app/RemixPlugin.tsx | 108 +- apps/etherscan/src/app/app.tsx | 83 +- .../src/app/components/HeaderWithSettings.tsx | 87 +- .../src/app/components/SubmitButton.tsx | 14 +- .../src/app/hooks/useLocalStorage.tsx | 2 +- apps/etherscan/src/app/layouts/Default.tsx | 4 +- apps/etherscan/src/app/routes.tsx | 18 +- .../src/app/views/CaptureKeyView.tsx | 124 +- apps/etherscan/src/app/views/ErrorView.tsx | 4 +- apps/etherscan/src/app/views/HomeView.tsx | 17 +- apps/etherscan/src/app/views/ReceiptsView.tsx | 138 +- apps/etherscan/src/app/views/VerifyView.tsx | 391 +++-- apps/etherscan/src/main.tsx | 14 +- apps/etherscan/webpack.config.js | 64 +- apps/remix-ide-e2e/nightwatch.ts | 77 +- .../src/local-plugin/src/app/app.tsx | 109 +- .../src/local-plugin/src/app/logger.tsx | 8 +- apps/remix-ide/background.js | 11 +- .../src/app/components/hidden-panel.tsx | 28 +- .../src/app/components/main-panel.tsx | 37 +- apps/remix-ide/src/app/components/preload.tsx | 255 ++- .../src/app/components/side-panel.tsx | 31 +- .../src/app/components/vertical-icons.tsx | 99 +- .../src/app/plugins/contractFlattener.tsx | 46 +- .../src/app/plugins/notification.tsx | 33 +- .../src/app/plugins/parser/code-parser.tsx | 566 ++++--- .../app/plugins/permission-handler-plugin.tsx | 87 +- .../src/app/plugins/remixd-handle.tsx | 174 +- .../src/app/plugins/solidity-script.tsx | 50 +- .../src/app/plugins/solidity-umlgen.tsx | 193 ++- .../src/app/providers/abstract-provider.tsx | 70 +- .../app/providers/custom-vm-fork-provider.tsx | 103 +- .../app/providers/external-http-provider.tsx | 52 +- .../src/app/providers/foundry-provider.tsx | 25 +- .../src/app/providers/ganache-provider.tsx | 25 +- .../app/providers/goerli-vm-fork-provider.tsx | 31 +- .../src/app/providers/hardhat-provider.tsx | 25 +- .../app/providers/injected-L2-provider.tsx | 43 +- .../injected-arbitrum-one-provider.tsx | 7 +- .../providers/injected-optimism-provider.tsx | 7 +- .../providers/injected-provider-default.tsx | 27 +- .../injected-provider-trustwallet.tsx | 10 +- .../src/app/providers/injected-provider.tsx | 86 +- .../providers/mainnet-vm-fork-provider.tsx | 34 +- .../providers/sepolia-vm-fork-provider.tsx | 31 +- .../src/app/providers/vm-provider.tsx | 131 +- apps/remix-ide/src/app/tabs/search.tsx | 12 +- apps/remix-ide/src/app/tabs/settings-tab.tsx | 46 +- apps/remix-ide/src/blockchain/blockchain.tsx | 904 ++++++++--- apps/remix-ide/src/index.tsx | 19 +- apps/remix-ide/webpack.config.js | 109 +- apps/solhint/src/app/App.tsx | 8 +- apps/solhint/webpack.config.js | 38 +- apps/solidity-compiler/src/app/app.tsx | 4 +- apps/solidity-compiler/webpack.config.js | 73 +- apps/vyper/src/app/app.tsx | 38 +- .../src/app/components/CompilerButton.tsx | 44 +- apps/vyper/src/app/components/LocalUrl.tsx | 20 +- apps/vyper/src/app/components/VyperResult.tsx | 72 +- apps/vyper/src/app/components/WarnRemote.tsx | 10 +- apps/vyper/src/app/utils/compiler.tsx | 59 +- apps/vyper/src/app/utils/remix-client.tsx | 68 +- apps/vyper/src/main.tsx | 14 +- apps/vyper/webpack.config.js | 67 +- apps/walletconnect/src/app/app.tsx | 24 +- .../walletconnect/src/app/walletConnectUI.tsx | 33 +- apps/walletconnect/src/main.tsx | 5 +- apps/walletconnect/webpack.config.js | 68 +- libs/remix-debug/test.ts | 28 +- .../remix-app/components/dragbar/dragbar.tsx | 42 +- .../components/modals/dialogViewPlugin.tsx | 10 +- .../remix-app/components/modals/dialogs.tsx | 17 +- .../remix-app/components/modals/matomo.tsx | 77 +- .../components/modals/modal-wrapper.tsx | 68 +- .../components/modals/origin-warning.tsx | 37 +- .../lib/remix-app/components/splashscreen.tsx | 31 +- .../app/src/lib/remix-app/context/context.tsx | 22 +- .../src/lib/remix-app/context/provider.tsx | 95 +- .../app/src/lib/remix-app/remix-app.tsx | 68 +- .../checkbox/src/lib/remix-ui-checkbox.tsx | 55 +- .../copy-to-clipboard/copy-to-clipboard.tsx | 44 +- .../debugger-ui/src/hooks/extract-data.tsx | 37 +- .../lib/button-navigator/button-navigator.tsx | 311 +++- .../debugger-ui/src/lib/debugger-ui.tsx | 415 +++-- .../debugger-ui/src/lib/slider/slider.tsx | 15 +- .../src/lib/step-manager/step-manager.tsx | 34 +- .../src/lib/tx-browser/tx-browser.tsx | 69 +- .../src/lib/vm-debugger/assembly-items.tsx | 92 +- .../src/lib/vm-debugger/calldata-panel.tsx | 6 +- .../src/lib/vm-debugger/callstack-panel.tsx | 6 +- .../src/lib/vm-debugger/code-list-view.tsx | 6 +- .../src/lib/vm-debugger/dropdown-panel.tsx | 211 ++- .../lib/vm-debugger/full-storages-changes.tsx | 11 +- .../src/lib/vm-debugger/function-panel.tsx | 10 +- .../src/lib/vm-debugger/global-variables.tsx | 19 +- .../src/lib/vm-debugger/memory-panel.tsx | 11 +- .../src/lib/vm-debugger/solidity-locals.tsx | 37 +- .../src/lib/vm-debugger/solidity-state.tsx | 38 +- .../src/lib/vm-debugger/stack-panel.tsx | 11 +- .../src/lib/vm-debugger/step-detail.tsx | 11 +- .../src/lib/vm-debugger/storage-panel.tsx | 10 +- .../src/lib/vm-debugger/vm-debugger-head.tsx | 186 ++- .../src/lib/vm-debugger/vm-debugger.tsx | 109 +- .../drag-n-drop/src/lib/drag-n-drop.tsx | 66 +- .../editor/src/lib/remix-ui-editor.tsx | 817 +++++++--- .../lib/components/file-decoration-icon.tsx | 60 +- .../file-decoration-custom-icon.tsx | 21 +- .../file-decoration-error-icon.tsx | 21 +- .../file-decoration-tooltip.tsx | 55 +- .../file-decoration-warning-icon.tsx | 19 +- .../file-decorators/src/lib/helper/index.tsx | 19 +- .../src/lib/components/PluginViewWrapper.tsx | 26 +- .../src/lib/components/custom-dropdown.tsx | 228 ++- .../src/lib/components/custom-tooltip.tsx | 41 +- .../helper/src/lib/components/web3Dialog.tsx | 56 +- .../helper/src/lib/helper-components.tsx | 80 +- .../src/lib/components/customNavButtons.tsx | 23 +- .../src/lib/components/homeTabFeatured.tsx | 128 +- .../lib/components/homeTabFeaturedPlugins.tsx | 111 +- .../src/lib/components/homeTabFile.tsx | 239 ++- .../src/lib/components/homeTabGetStarted.tsx | 125 +- .../src/lib/components/homeTabLearn.tsx | 176 +- .../src/lib/components/homeTabScamAlert.tsx | 46 +- .../src/lib/components/homeTabTitle.tsx | 146 +- .../src/lib/components/pluginButton.tsx | 51 +- .../src/lib/components/workspaceTemplate.tsx | 22 +- .../home-tab/src/lib/remix-ui-home-tab.tsx | 40 +- .../src/lib/remix-ui-locale-module.tsx | 26 +- .../src/lib/remix-ui-modal-dialog.tsx | 129 +- .../panel/src/lib/dragbar/dragbar.tsx | 36 +- .../panel/src/lib/main/main-panel.tsx | 23 +- .../panel/src/lib/plugins/panel-header.tsx | 134 +- .../panel/src/lib/plugins/panel-plugin.tsx | 7 +- .../panel/src/lib/plugins/remix-ui-panel.tsx | 16 +- .../src/lib/permission-dialog.tsx | 154 +- .../src/lib/components/ActivePluginCard.tsx | 84 +- .../components/ActivePluginCardContainer.tsx | 41 +- .../src/lib/components/InactivePluginCard.tsx | 80 +- .../InactivePluginCardContainer.tsx | 42 +- .../src/lib/components/LocalPluginForm.tsx | 430 +++-- .../src/lib/components/moduleHeading.tsx | 12 +- .../lib/components/permissionsSettings.tsx | 209 ++- .../src/lib/components/rootView.tsx | 23 +- .../src/lib/remix-ui-plugin-manager.tsx | 18 +- .../src/lib/publish-to-storage.tsx | 131 +- .../src/lib/publishOnSwarm.tsx | 162 +- .../src/lib/publishToIPFS.tsx | 126 +- libs/remix-ui/renderer/src/lib/renderer.tsx | 71 +- .../run-tab/src/lib/components/account.tsx | 174 +- .../src/lib/components/contractDropdownUI.tsx | 483 ++++-- .../src/lib/components/deployButton.tsx | 60 +- .../src/lib/components/deployInput.tsx | 43 +- .../src/lib/components/environment.tsx | 135 +- .../run-tab/src/lib/components/gasPrice.tsx | 22 +- .../lib/components/instanceContainerUI.tsx | 95 +- .../run-tab/src/lib/components/mainnet.tsx | 150 +- .../src/lib/components/multiDeployInput.tsx | 39 +- .../run-tab/src/lib/components/network.tsx | 11 +- .../run-tab/src/lib/components/passphrase.tsx | 21 +- .../src/lib/components/recorderCardUI.tsx | 125 +- .../run-tab/src/lib/components/scenario.tsx | 21 +- .../run-tab/src/lib/components/settingsUI.tsx | 41 +- .../src/lib/components/universalDappUI.tsx | 181 ++- .../run-tab/src/lib/components/value.tsx | 53 +- libs/remix-ui/run-tab/src/lib/run-tab.tsx | 221 ++- .../search/src/lib/components/Exclude.tsx | 22 +- .../search/src/lib/components/Find.tsx | 18 +- .../src/lib/components/FindContainer.tsx | 24 +- .../search/src/lib/components/Include.tsx | 24 +- .../src/lib/components/OverWriteCheck.tsx | 14 +- .../search/src/lib/components/Replace.tsx | 18 +- .../search/src/lib/components/Search.tsx | 17 +- .../search/src/lib/components/StopSearch.tsx | 17 +- .../search/src/lib/components/Undo.tsx | 58 +- .../lib/components/results/ResultFileName.tsx | 15 +- .../src/lib/components/results/ResultItem.tsx | 94 +- .../lib/components/results/ResultSummary.tsx | 84 +- .../src/lib/components/results/Results.tsx | 17 +- .../search/src/lib/context/context.tsx | 34 +- .../settings/src/lib/etherscan-settings.tsx | 77 +- .../settings/src/lib/github-settings.tsx | 95 +- .../settings/src/lib/remix-ui-settings.tsx | 528 ++++-- .../src/lib/compiler-container.tsx | 935 ++++++++--- .../src/lib/compilerConfiguration.tsx | 2 +- .../src/lib/contract-selection.tsx | 379 +++-- .../src/lib/solidity-compiler.tsx | 240 ++- .../src/lib/components/UmlDownload.tsx | 52 +- .../src/lib/solidity-uml-gen.tsx | 114 +- .../src/lib/solidity-unit-testing.tsx | 826 +++++++--- .../src/lib/Button/StaticAnalyserButton.tsx | 36 +- .../static-analyser/src/lib/ErrorRenderer.tsx | 46 +- .../src/lib/components/BasicTitle.tsx | 65 +- .../src/lib/remix-ui-static-analyser.tsx | 829 +++++----- libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx | 203 ++- .../src/lib/components/ChechTxStatus.tsx | 21 +- .../terminal/src/lib/components/Context.tsx | 105 +- .../src/lib/components/RenderCall.tsx | 110 +- .../components/RenderKnownTransactions.tsx | 110 +- .../components/RenderUnknownTransactions.tsx | 86 +- .../terminal/src/lib/components/Table.tsx | 91 +- .../src/lib/custom-hooks/useKeyPress.tsx | 8 +- .../terminal/src/lib/remix-ui-terminal.tsx | 821 +++++++--- .../terminal/src/lib/terminalWelcome.tsx | 69 +- .../src/lib/remix-ui-theme-module.tsx | 28 +- libs/remix-ui/toaster/src/lib/toaster.tsx | 115 +- .../tooltip-popup/src/lib/tooltip-popup.tsx | 28 +- .../tree-view/src/lib/remix-ui-tree-view.tsx | 8 +- libs/remix-ui/utils/src/lib/should-render.tsx | 6 +- .../src/lib/components/Badge.tsx | 57 +- .../src/lib/components/BasicLogo.tsx | 34 +- .../src/lib/components/Chevron.tsx | 23 +- .../src/lib/components/Home.tsx | 11 +- .../src/lib/components/Icon.tsx | 100 +- .../src/lib/components/IconList.tsx | 42 +- .../src/lib/remix-ui-vertical-icons-panel.tsx | 111 +- .../src/lib/vertical-icons-context-menu.tsx | 76 +- .../components/file-explorer-context-menu.tsx | 434 +++-- .../src/lib/components/file-label.tsx | 30 +- .../src/lib/components/upload-file.tsx | 28 +- .../components/workspace-hamburger-item.tsx | 62 +- .../lib/components/workspace-hamburger.tsx | 227 ++- .../src/lib/providers/FileSystemProvider.tsx | 158 +- .../workspace/src/lib/remix-ui-workspace.tsx | 1417 ++++++++++++----- .../remixDefault/tests/storage.test.js | 7 +- package.json | 1 + 239 files changed, 15832 insertions(+), 7763 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 1dc764a010..f4ba083cb7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -48,6 +48,11 @@ "no-empty": "off", "jsx-a11y/anchor-is-valid": "off", "@typescript-eslint/no-inferrable-types": "off", + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-explicit-any": "off", + "react-hooks/exhaustive-deps": "off", + "array-callback-return": "off", + "prefer-spread": "off", "indent": ["error", 2] } }, @@ -67,4 +72,4 @@ "globals": { "JSX": true } -} \ No newline at end of file +} diff --git a/.prettierrc.json b/.prettierrc.json index eb9e1f1f9e..d7840d1dca 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -9,6 +9,5 @@ "trailingComma": "none", "jsxBracketSameLine": false, "arrowParens": "always", - "singleAttributePerLine": false, - "ignorePath": ".prettierignore" + "singleAttributePerLine": false } diff --git a/apps/debugger/src/app/app.tsx b/apps/debugger/src/app/app.tsx index 5cee11a2d9..f6e07dc685 100644 --- a/apps/debugger/src/app/app.tsx +++ b/apps/debugger/src/app/app.tsx @@ -1,17 +1,17 @@ -import React, { useState, useEffect } from 'react'; +import React, {useState, useEffect} from 'react' -import { DebuggerUI } from '@remix-ui/debugger-ui' // eslint-disable-line +import {DebuggerUI} from '@remix-ui/debugger-ui' // eslint-disable-line -import { DebuggerClientApi } from './debugger' +import {DebuggerClientApi} from './debugger' const remix = new DebuggerClientApi() -export const App = () => { +export const App = () => { return (
- ); -}; + ) +} -export default App; +export default App diff --git a/apps/debugger/src/main.tsx b/apps/debugger/src/main.tsx index bc1579ec0f..be9ae3d572 100644 --- a/apps/debugger/src/main.tsx +++ b/apps/debugger/src/main.tsx @@ -1,9 +1,6 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; +import React from 'react' +import ReactDOM from 'react-dom' -import App from './app/app'; +import App from './app/app' -ReactDOM.render( - , - document.getElementById('root') -); +ReactDOM.render(, document.getElementById('root')) diff --git a/apps/debugger/webpack.config.js b/apps/debugger/webpack.config.js index 9feb0dc08d..4bc648f1db 100644 --- a/apps/debugger/webpack.config.js +++ b/apps/debugger/webpack.config.js @@ -1,8 +1,7 @@ -const { composePlugins, withNx } = require('@nrwl/webpack') +const {composePlugins, withNx} = require('@nrwl/webpack') const webpack = require('webpack') -const TerserPlugin = require("terser-webpack-plugin") -const CssMinimizerPlugin = require("css-minimizer-webpack-plugin") - +const TerserPlugin = require('terser-webpack-plugin') +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') // Nx plugins for webpack. module.exports = composePlugins(withNx(), (config) => { @@ -12,56 +11,52 @@ module.exports = composePlugins(withNx(), (config) => { // add fallback for node modules config.resolve.fallback = { ...config.resolve.fallback, - "crypto": require.resolve("crypto-browserify"), - "stream": require.resolve("stream-browserify"), - "path": require.resolve("path-browserify"), - "http": require.resolve("stream-http"), - "https": require.resolve("https-browserify"), - "constants": require.resolve("constants-browserify"), - "os": false, //require.resolve("os-browserify/browser"), - "timers": false, // require.resolve("timers-browserify"), - "zlib": require.resolve("browserify-zlib"), - "fs": false, - "module": false, - "tls": false, - "net": false, - "readline": false, - "child_process": false, - "buffer": require.resolve("buffer/"), - "vm": require.resolve('vm-browserify'), + crypto: require.resolve('crypto-browserify'), + stream: require.resolve('stream-browserify'), + path: require.resolve('path-browserify'), + http: require.resolve('stream-http'), + https: require.resolve('https-browserify'), + constants: require.resolve('constants-browserify'), + os: false, //require.resolve("os-browserify/browser"), + timers: false, // require.resolve("timers-browserify"), + zlib: require.resolve('browserify-zlib'), + fs: false, + module: false, + tls: false, + net: false, + readline: false, + child_process: false, + buffer: require.resolve('buffer/'), + vm: require.resolve('vm-browserify') } - // add externals config.externals = { ...config.externals, - solc: 'solc', + solc: 'solc' } // add public path config.output.publicPath = '/' - - // add copy & provide plugin config.plugins.push( new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'], url: ['url', 'URL'], - process: 'process/browser', + process: 'process/browser' }) ) // souce-map loader config.module.rules.push({ test: /\.js$/, - use: ["source-map-loader"], - enforce: "pre" + use: ['source-map-loader'], + enforce: 'pre' }) config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings - // set minimizer config.optimization.minimizer = [ new TerserPlugin({ @@ -71,17 +66,17 @@ module.exports = composePlugins(withNx(), (config) => { compress: false, mangle: false, format: { - comments: false, - }, + comments: false + } }, - extractComments: false, + extractComments: false }), - new CssMinimizerPlugin(), - ]; + new CssMinimizerPlugin() + ] config.watchOptions = { ignored: /node_modules/ } - return config; -}); + return config +}) diff --git a/apps/doc-gen/src/app/App.tsx b/apps/doc-gen/src/app/App.tsx index a11b5b99e8..08fe6f7ba2 100644 --- a/apps/doc-gen/src/app/App.tsx +++ b/apps/doc-gen/src/app/App.tsx @@ -4,13 +4,13 @@ import './App.css' import { DocGenClient } from './docgen-client' import { Build } from './docgen/site' -export const client = new DocGenClient() +export const client = new DocGenClient() const App = () => { // eslint-disable-next-line @typescript-eslint/no-unused-vars - const [themeType, setThemeType] = useState('dark'); - const [hasBuild, setHasBuild] = useState(false); - const [fileName, setFileName] = useState(''); + const [themeType, setThemeType] = useState('dark') + const [hasBuild, setHasBuild] = useState(false) + const [fileName, setFileName] = useState('') useEffect(() => { const watchThemeSwitch = async () => { @@ -21,19 +21,27 @@ const App = () => { setHasBuild(true) setFileName(fileName) }) - client.eventEmitter.on('docsGenerated', (docs: string[]) => { - }) + client.eventEmitter.on('docsGenerated', (docs: string[]) => {}) } watchThemeSwitch() }, []) return (
-
Compile a Solidity contract and generate its documentation as Markdown. (Right-click on a contract in the File Explorer and select "Generate Docs" from the context menu.).
- {fileName &&
-
File: {fileName}
-
} - {hasBuild && } +
+ Compile a Solidity contract and generate its documentation as Markdown. (Right-click on a contract in the File + Explorer and select "Generate Docs" from the context menu.). +
+ {fileName && ( +
+
File: {fileName}
+
+ )} + {hasBuild && ( + + )}
) } diff --git a/apps/doc-gen/src/app/hooks/useLocalStorage.tsx b/apps/doc-gen/src/app/hooks/useLocalStorage.tsx index d677de7813..955658bac5 100644 --- a/apps/doc-gen/src/app/hooks/useLocalStorage.tsx +++ b/apps/doc-gen/src/app/hooks/useLocalStorage.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState } from 'react' export function useLocalStorage(key: string, initialValue: any) { // State to store our value @@ -6,32 +6,31 @@ export function useLocalStorage(key: string, initialValue: any) { const [storedValue, setStoredValue] = useState(() => { try { // Get from local storage by key - const item = window.localStorage.getItem(key); + const item = window.localStorage.getItem(key) // Parse stored json or if none return initialValue - return item ? JSON.parse(item) : initialValue; + return item ? JSON.parse(item) : initialValue } catch (error) { // If error also return initialValue - console.log(error); - return initialValue; + console.log(error) + return initialValue } - }); + }) // Return a wrapped version of useState's setter function that ... // ... persists the new value to localStorage. const setValue = (value: any) => { try { // Allow value to be a function so we have same API as useState - const valueToStore = - value instanceof Function ? value(storedValue) : value; + const valueToStore = value instanceof Function ? value(storedValue) : value // Save state - setStoredValue(valueToStore); + setStoredValue(valueToStore) // Save to local storage - window.localStorage.setItem(key, JSON.stringify(valueToStore)); + window.localStorage.setItem(key, JSON.stringify(valueToStore)) } catch (error) { // A more advanced implementation would handle the error case - console.log(error); + console.log(error) } - }; + } - return [storedValue, setValue]; + return [storedValue, setValue] } diff --git a/apps/doc-gen/src/app/views/ErrorView.tsx b/apps/doc-gen/src/app/views/ErrorView.tsx index f1c4fdaf91..31a3b90a73 100644 --- a/apps/doc-gen/src/app/views/ErrorView.tsx +++ b/apps/doc-gen/src/app/views/ErrorView.tsx @@ -1,31 +1,28 @@ -import React from "react"; +import React from 'react' export const ErrorView: React.FC = () => { return (
Error page
Sorry, something unexpected happened.
- Please raise an issue:{" "} - + Please raise an issue:{' '} + Here
- ); -}; + ) +} diff --git a/apps/doc-gen/src/main.tsx b/apps/doc-gen/src/main.tsx index a6dc3b3a47..d2d29f2bb4 100644 --- a/apps/doc-gen/src/main.tsx +++ b/apps/doc-gen/src/main.tsx @@ -1,11 +1,11 @@ -import React from "react"; -import ReactDOM from "react-dom"; -import App from "./app/App"; +import React from 'react' +import ReactDOM from 'react-dom' +import App from './app/App' // import { Routes } from "./routes"; ReactDOM.render( , - document.getElementById("root") -); + document.getElementById('root'), +) diff --git a/apps/doc-gen/webpack.config.js b/apps/doc-gen/webpack.config.js index b7f8e45da0..86bcf51395 100644 --- a/apps/doc-gen/webpack.config.js +++ b/apps/doc-gen/webpack.config.js @@ -1,19 +1,19 @@ const { composePlugins, withNx } = require('@nrwl/webpack') const { withReact } = require('@nrwl/react') const webpack = require('webpack') -const TerserPlugin = require("terser-webpack-plugin") -const CssMinimizerPlugin = require("css-minimizer-webpack-plugin") +const TerserPlugin = require('terser-webpack-plugin') +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') // Nx plugins for webpack. -module.exports = composePlugins(withNx(), withReact(), (config) => { +module.exports = composePlugins(withNx(), withReact(), config => { // Update the webpack config as needed here. // e.g. `config.plugins.push(new MyPlugin())` // add fallback for node modules config.resolve.fallback = { ...config.resolve.fallback, - "path": require.resolve("path-browserify"), - "fs": false, + path: require.resolve('path-browserify'), + fs: false, } // add externals @@ -24,10 +24,9 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { config.module.rules.push({ test: /\.hbs$/, - type: 'asset/source' + type: 'asset/source', }) - // add public path config.output.publicPath = '/' @@ -38,16 +37,14 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { url: ['url', 'URL'], process: 'process/browser', }), - new webpack.DefinePlugin({ - - }), + new webpack.DefinePlugin({}), ) // souce-map loader config.module.rules.push({ test: /\.js$/, - use: ["source-map-loader"], - enforce: "pre" + use: ['source-map-loader'], + enforce: 'pre', }) config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings @@ -67,7 +64,7 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { extractComments: false, }), new CssMinimizerPlugin(), - ]; + ] - return config; + return config }) diff --git a/apps/doc-viewer/src/app/App.tsx b/apps/doc-viewer/src/app/App.tsx index cbb57460d0..5f5092eb24 100644 --- a/apps/doc-viewer/src/app/App.tsx +++ b/apps/doc-viewer/src/app/App.tsx @@ -1,5 +1,5 @@ -import React, { useEffect, useState } from "react" -import { DocViewer } from "./docviewer" +import React, {useEffect, useState} from 'react' +import {DocViewer} from './docviewer' import ReactMarkdown from 'react-markdown' import remarkGfm from 'remark-gfm' @@ -11,13 +11,12 @@ export default function App() { client.eventEmitter.on('contentsReady', (fileContents: string) => { setContents(fileContents) }) - }, []) return ( <>
- +
) -} \ No newline at end of file +} diff --git a/apps/doc-viewer/src/main.tsx b/apps/doc-viewer/src/main.tsx index 7b8dd49ee6..b8ec0b96a0 100644 --- a/apps/doc-viewer/src/main.tsx +++ b/apps/doc-viewer/src/main.tsx @@ -6,5 +6,5 @@ ReactDOM.render( , - document.getElementById("root") -); + document.getElementById('root') +) diff --git a/apps/doc-viewer/webpack.config.js b/apps/doc-viewer/webpack.config.js index 1a460e3da0..b21898ae87 100644 --- a/apps/doc-viewer/webpack.config.js +++ b/apps/doc-viewer/webpack.config.js @@ -1,8 +1,8 @@ -const { composePlugins, withNx } = require('@nrwl/webpack') -const { withReact } = require('@nrwl/react') +const {composePlugins, withNx} = require('@nrwl/webpack') +const {withReact} = require('@nrwl/react') const webpack = require('webpack') -const TerserPlugin = require("terser-webpack-plugin") -const CssMinimizerPlugin = require("css-minimizer-webpack-plugin") +const TerserPlugin = require('terser-webpack-plugin') +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') // Nx plugins for webpack. module.exports = composePlugins(withNx(), withReact(), (config) => { @@ -12,7 +12,7 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { // add externals config.externals = { ...config.externals, - solc: 'solc', + solc: 'solc' } // add public path @@ -23,18 +23,16 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'], url: ['url', 'URL'], - process: 'process/browser', - }), - new webpack.DefinePlugin({ - + process: 'process/browser' }), + new webpack.DefinePlugin({}) ) // souce-map loader config.module.rules.push({ test: /\.js$/, - use: ["source-map-loader"], - enforce: "pre" + use: ['source-map-loader'], + enforce: 'pre' }) config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings @@ -48,13 +46,13 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { compress: false, mangle: false, format: { - comments: false, - }, + comments: false + } }, - extractComments: false, + extractComments: false }), - new CssMinimizerPlugin(), - ]; + new CssMinimizerPlugin() + ] - return config; + return config }) diff --git a/apps/etherscan/src/app/AppContext.tsx b/apps/etherscan/src/app/AppContext.tsx index 52b0c1fda8..f121406a67 100644 --- a/apps/etherscan/src/app/AppContext.tsx +++ b/apps/etherscan/src/app/AppContext.tsx @@ -1,24 +1,24 @@ -import React from "react" -import { PluginClient } from "@remixproject/plugin" +import React from 'react' +import {PluginClient} from '@remixproject/plugin' -import { Receipt, ThemeType } from "./types" +import {Receipt, ThemeType} from './types' export const AppContext = React.createContext({ - apiKey: "", + apiKey: '', setAPIKey: (value: string) => { - console.log("Set API Key from Context") + console.log('Set API Key from Context') }, clientInstance: {} as PluginClient, receipts: [] as Receipt[], setReceipts: (receipts: Receipt[]) => { - console.log("Calling Set Receipts") + console.log('Calling Set Receipts') }, contracts: [] as string[], setContracts: (contracts: string[]) => { - console.log("Calling Set Contract Names") + console.log('Calling Set Contract Names') }, - themeType: "dark" as ThemeType, + themeType: 'dark' as ThemeType, setThemeType: (themeType: ThemeType) => { - console.log("Calling Set Theme Type") - }, + console.log('Calling Set Theme Type') + } }) diff --git a/apps/etherscan/src/app/RemixPlugin.tsx b/apps/etherscan/src/app/RemixPlugin.tsx index 979f2c967d..6c02917229 100644 --- a/apps/etherscan/src/app/RemixPlugin.tsx +++ b/apps/etherscan/src/app/RemixPlugin.tsx @@ -1,40 +1,80 @@ -import { PluginClient } from '@remixproject/plugin'; -import { verify, EtherScanReturn } from './utils/verify'; -import { getReceiptStatus, getEtherScanApi, getNetworkName, getProxyContractReceiptStatus } from './utils'; +import {PluginClient} from '@remixproject/plugin' +import {verify, EtherScanReturn} from './utils/verify' +import { + getReceiptStatus, + getEtherScanApi, + getNetworkName, + getProxyContractReceiptStatus +} from './utils' export class RemixClient extends PluginClient { + loaded() { + return this.onload() + } - loaded() { - return this.onload() - } - - async verify (apiKey: string, contractAddress: string, contractArguments: string, contractName: string, compilationResultParam: any, chainRef?: number | string, isProxyContract?: boolean, expectedImplAddress?: string) { - const result = await verify(apiKey, contractAddress, contractArguments, contractName, compilationResultParam, chainRef, isProxyContract, expectedImplAddress, this, - (value: EtherScanReturn) => {}, (value: string) => {}) - return result - } + async verify( + apiKey: string, + contractAddress: string, + contractArguments: string, + contractName: string, + compilationResultParam: any, + chainRef?: number | string, + isProxyContract?: boolean, + expectedImplAddress?: string + ) { + const result = await verify( + apiKey, + contractAddress, + contractArguments, + contractName, + compilationResultParam, + chainRef, + isProxyContract, + expectedImplAddress, + this, + (value: EtherScanReturn) => {}, + (value: string) => {} + ) + return result + } + + async receiptStatus( + receiptGuid: string, + apiKey: string, + isProxyContract: boolean + ) { + try { + const {network, networkId} = await getNetworkName(this) + if (network === 'vm') { + throw new Error( + 'Cannot check the receipt status in the selected network' + ) + } + const etherscanApi = getEtherScanApi(networkId) + let receiptStatus - async receiptStatus (receiptGuid: string, apiKey: string, isProxyContract: boolean) { - try { - const { network, networkId } = await getNetworkName(this) - if (network === "vm") { - throw new Error("Cannot check the receipt status in the selected network") - } - const etherscanApi = getEtherScanApi(networkId) - let receiptStatus - - if (isProxyContract) receiptStatus = await getProxyContractReceiptStatus(receiptGuid, apiKey, etherscanApi) - else receiptStatus = await getReceiptStatus(receiptGuid, apiKey, etherscanApi) - return { - message: receiptStatus.result, - succeed: receiptStatus.status === '0' ? false : true - } - } catch (e: any){ - return { - status: 'error', - message: e.message, - succeed: false - } - } + if (isProxyContract) + receiptStatus = await getProxyContractReceiptStatus( + receiptGuid, + apiKey, + etherscanApi + ) + else + receiptStatus = await getReceiptStatus( + receiptGuid, + apiKey, + etherscanApi + ) + return { + message: receiptStatus.result, + succeed: receiptStatus.status === '0' ? false : true + } + } catch (e: any) { + return { + status: 'error', + message: e.message, + succeed: false + } } + } } diff --git a/apps/etherscan/src/app/app.tsx b/apps/etherscan/src/app/app.tsx index 501e3620ae..baaa452278 100644 --- a/apps/etherscan/src/app/app.tsx +++ b/apps/etherscan/src/app/app.tsx @@ -1,22 +1,27 @@ -import React, { useState, useEffect, useRef } from "react" +import React, {useState, useEffect, useRef} from 'react' import { CompilationFileSources, - CompilationResult, -} from "@remixproject/plugin-api" + CompilationResult +} from '@remixproject/plugin-api' -import { RemixClient } from "./RemixPlugin"; -import { createClient } from "@remixproject/plugin-webview"; +import {RemixClient} from './RemixPlugin' +import {createClient} from '@remixproject/plugin-webview' -import { AppContext } from "./AppContext" -import { DisplayRoutes } from "./routes" +import {AppContext} from './AppContext' +import {DisplayRoutes} from './routes' -import { useLocalStorage } from "./hooks/useLocalStorage" +import {useLocalStorage} from './hooks/useLocalStorage' -import { getReceiptStatus, getEtherScanApi, getNetworkName, getProxyContractReceiptStatus } from "./utils" -import { Receipt, ThemeType } from "./types" +import { + getReceiptStatus, + getEtherScanApi, + getNetworkName, + getProxyContractReceiptStatus +} from './utils' +import {Receipt, ThemeType} from './types' -import "./App.css" +import './App.css' export const getNewContractNames = (compilationResult: CompilationResult) => { const compiledContracts = compilationResult.contracts @@ -31,11 +36,11 @@ export const getNewContractNames = (compilationResult: CompilationResult) => { } const App = () => { - const [apiKey, setAPIKey] = useLocalStorage("apiKey", "") + const [apiKey, setAPIKey] = useLocalStorage('apiKey', '') const [clientInstance, setClientInstance] = useState(undefined as any) - const [receipts, setReceipts] = useLocalStorage("receipts", []) + const [receipts, setReceipts] = useLocalStorage('receipts', []) const [contracts, setContracts] = useState([] as string[]) - const [themeType, setThemeType] = useState("dark" as ThemeType) + const [themeType, setThemeType] = useState('dark' as ThemeType) const timer = useRef(null) const clientInstanceRef = useRef(clientInstance) @@ -49,8 +54,9 @@ const App = () => { const loadClient = async () => { await client.onload() setClientInstance(client) - client.on("solidity", - "compilationFinished", + client.on( + 'solidity', + 'compilationFinished', ( fileName: string, source: CompilationFileSources, @@ -61,7 +67,7 @@ const App = () => { const newContractsToSave: string[] = [ ...contractsRef.current, - ...newContractsNames, + ...newContractsNames ] const uniqueContracts: string[] = [...new Set(newContractsToSave)] @@ -82,7 +88,10 @@ const App = () => { useEffect(() => { let receiptsNotVerified: Receipt[] = receipts.filter((item: Receipt) => { - return item.status === "Pending in queue" || item.status === "Max rate limit reached" + return ( + item.status === 'Pending in queue' || + item.status === 'Max rate limit reached' + ) }) if (receiptsNotVerified.length > 0) { @@ -91,17 +100,19 @@ const App = () => { timer.current = null } timer.current = setInterval(async () => { - const { network, networkId } = await getNetworkName(clientInstanceRef.current) + const {network, networkId} = await getNetworkName( + clientInstanceRef.current + ) if (!clientInstanceRef.current) { return } - - if (network === "vm") { + + if (network === 'vm') { return } let newReceipts = receipts - for (const item of receiptsNotVerified) { - await new Promise(r => setTimeout(r, 500)) // avoid api rate limit exceed. + for (const item of receiptsNotVerified) { + await new Promise((r) => setTimeout(r, 500)) // avoid api rate limit exceed. let status if (item.isProxyContract) { status = await getProxyContractReceiptStatus( @@ -113,29 +124,35 @@ const App = () => { status.message = status.result status.result = 'Successfully Updated' } - } else + } else status = await getReceiptStatus( item.guid, apiKey, getEtherScanApi(networkId) ) - if (status.result === "Pass - Verified" || status.result === "Already Verified" || - status.result === "Successfully Updated") { + if ( + status.result === 'Pass - Verified' || + status.result === 'Already Verified' || + status.result === 'Successfully Updated' + ) { newReceipts = newReceipts.map((currentReceipt: Receipt) => { if (currentReceipt.guid === item.guid) { - let res = { + const res = { ...currentReceipt, - status: status.result, + status: status.result } if (currentReceipt.isProxyContract) res.message = status.message return res } return currentReceipt - }) - } + }) + } } receiptsNotVerified = newReceipts.filter((item: Receipt) => { - return item.status === "Pending in queue" || item.status === "Max rate limit reached" + return ( + item.status === 'Pending in queue' || + item.status === 'Max rate limit reached' + ) }) if (timer.current && receiptsNotVerified.length === 0) { clearInterval(timer.current) @@ -157,7 +174,7 @@ const App = () => { contracts, setContracts, themeType, - setThemeType, + setThemeType }} > @@ -165,4 +182,4 @@ const App = () => { ) } -export default App \ No newline at end of file +export default App diff --git a/apps/etherscan/src/app/components/HeaderWithSettings.tsx b/apps/etherscan/src/app/components/HeaderWithSettings.tsx index 7eb1827fef..e321287114 100644 --- a/apps/etherscan/src/app/components/HeaderWithSettings.tsx +++ b/apps/etherscan/src/app/components/HeaderWithSettings.tsx @@ -1,8 +1,8 @@ -import React from "react" +import React from 'react' -import { NavLink } from "react-router-dom" -import { CustomTooltip } from '@remix-ui/helper' -import { AppContext } from "../AppContext" +import {NavLink} from 'react-router-dom' +import {CustomTooltip} from '@remix-ui/helper' +import {AppContext} from '../AppContext' interface Props { title?: string @@ -13,21 +13,29 @@ interface IconProps { from: string } -const HomeIcon: React.FC = ({ from }: IconProps) => { +const HomeIcon: React.FC = ({from}: IconProps) => { return ( isActive ? "border border-secondary shadow-none btn p-1 m-0" : "border-0 shadow-none btn p-1 m-0"} - style={ ({ isActive }) => !isActive ? { width: "1.8rem", filter: "contrast(0.5)"} : {width: "1.8rem"}} - state={ from } + className={({isActive}) => + isActive + ? 'border border-secondary shadow-none btn p-1 m-0' + : 'border-0 shadow-none btn p-1 m-0' + } + style={({isActive}) => + !isActive + ? {width: '1.8rem', filter: 'contrast(0.5)'} + : {width: '1.8rem'} + } + state={from} > @@ -35,21 +43,29 @@ const HomeIcon: React.FC = ({ from }: IconProps) => { ) } -const ReceiptsIcon: React.FC = ({ from }: IconProps) => { +const ReceiptsIcon: React.FC = ({from}: IconProps) => { return ( - isActive ? "border border-secondary shadow-none btn p-1 m-0" : "border-0 shadow-none btn p-1 m-0"} - style={ ({ isActive }) => !isActive ? { width: "1.8rem", filter: "contrast(0.5)"} : {width: "1.8rem"}} - state={ from } + className={({isActive}) => + isActive + ? 'border border-secondary shadow-none btn p-1 m-0' + : 'border-0 shadow-none btn p-1 m-0' + } + style={({isActive}) => + !isActive + ? {width: '1.8rem', filter: 'contrast(0.5)'} + : {width: '1.8rem'} + } + state={from} > @@ -57,21 +73,29 @@ const ReceiptsIcon: React.FC = ({ from }: IconProps) => { ) } -const SettingsIcon: React.FC = ({ from }: IconProps) => { +const SettingsIcon: React.FC = ({from}: IconProps) => { return ( isActive ? "border border-secondary shadow-none btn p-1 m-0" : "border-0 shadow-none btn p-1 m-0"} - style={ ({ isActive }) => !isActive ? { width: "1.8rem", filter: "contrast(0.5)"} : {width: "1.8rem"}} - state= {from} + className={({isActive}) => + isActive + ? 'border border-secondary shadow-none btn p-1 m-0' + : 'border-0 shadow-none btn p-1 m-0' + } + style={({isActive}) => + !isActive + ? {width: '1.8rem', filter: 'contrast(0.5)'} + : {width: '1.8rem'} + } + state={from} > @@ -79,10 +103,7 @@ const SettingsIcon: React.FC = ({ from }: IconProps) => { ) } -export const HeaderWithSettings: React.FC = ({ - title = "", - from, -}) => { +export const HeaderWithSettings: React.FC = ({title = '', from}) => { return ( {() => ( diff --git a/apps/etherscan/src/app/components/SubmitButton.tsx b/apps/etherscan/src/app/components/SubmitButton.tsx index 83a080ca6a..2364168935 100644 --- a/apps/etherscan/src/app/components/SubmitButton.tsx +++ b/apps/etherscan/src/app/components/SubmitButton.tsx @@ -1,5 +1,5 @@ -import React from "react" -import { CustomTooltip } from '@remix-ui/helper' +import React from 'react' +import {CustomTooltip} from '@remix-ui/helper' interface Props { text: string @@ -23,10 +23,14 @@ export const SubmitButton: React.FC = ({ disabled={disable} >
{!isSubmitting && text} diff --git a/apps/etherscan/src/app/hooks/useLocalStorage.tsx b/apps/etherscan/src/app/hooks/useLocalStorage.tsx index dbef5378a8..c4c1b78eae 100644 --- a/apps/etherscan/src/app/hooks/useLocalStorage.tsx +++ b/apps/etherscan/src/app/hooks/useLocalStorage.tsx @@ -1,4 +1,4 @@ -import { useState } from "react" +import {useState} from 'react' export function useLocalStorage(key: string, initialValue: any) { // State to store our value diff --git a/apps/etherscan/src/app/layouts/Default.tsx b/apps/etherscan/src/app/layouts/Default.tsx index 18ac232f0e..86bf995b28 100644 --- a/apps/etherscan/src/app/layouts/Default.tsx +++ b/apps/etherscan/src/app/layouts/Default.tsx @@ -1,6 +1,6 @@ -import React, { PropsWithChildren } from "react" +import React, {PropsWithChildren} from 'react' -import { HeaderWithSettings } from "../components" +import {HeaderWithSettings} from '../components' interface Props { from: string diff --git a/apps/etherscan/src/app/routes.tsx b/apps/etherscan/src/app/routes.tsx index defe35cf2d..426583ed53 100644 --- a/apps/etherscan/src/app/routes.tsx +++ b/apps/etherscan/src/app/routes.tsx @@ -1,13 +1,8 @@ -import React from "react" -import { - HashRouter as Router, - Route, - Routes, - RouteProps, -} from "react-router-dom" +import React from 'react' +import {HashRouter as Router, Route, Routes, RouteProps} from 'react-router-dom' -import { ErrorView, HomeView, ReceiptsView, CaptureKeyView } from "./views" -import { DefaultLayout } from "./layouts" +import {ErrorView, HomeView, ReceiptsView, CaptureKeyView} from './views' +import {DefaultLayout} from './layouts' interface Props extends RouteProps { component: any // TODO: new (props: any) => React.Component @@ -16,7 +11,7 @@ interface Props extends RouteProps { export const DisplayRoutes = () => ( - + ( } /> - } /> + } /> { const location = useLocation() const navigate = useNavigate() - const [msg, setMsg] = useState("") + const [msg, setMsg] = useState('') return ( - {({ apiKey, clientInstance, setAPIKey }) => { + {({apiKey, clientInstance, setAPIKey}) => { if (!apiKey) setMsg('Please provide a 34-character API key to continue') return ( -
- { - const errors = {} as any - if (!values.apiKey) { - errors.apiKey = "Required" - } else if (values.apiKey.length !== 34) { - errors.apiKey = "API key should be 34 characters long" - } - return errors - }} - onSubmit={(values) => { - const apiKey = values.apiKey - if (apiKey.length === 34) { - setAPIKey(values.apiKey) - navigate((location && location.state ? location.state : '/')) - } - }} - > - {({ errors, touched, handleSubmit }) => ( -
-
- - - -
+
+ { + const errors = {} as any + if (!values.apiKey) { + errors.apiKey = 'Required' + } else if (values.apiKey.length !== 34) { + errors.apiKey = 'API key should be 34 characters long' + } + return errors + }} + onSubmit={(values) => { + const apiKey = values.apiKey + if (apiKey.length === 34) { + setAPIKey(values.apiKey) + navigate(location && location.state ? location.state : '/') + } + }} + > + {({errors, touched, handleSubmit}) => ( + +
+ + + +
-
- -
- - )} -
+
+ +
+ + )} + -
-
+
+
) }} diff --git a/apps/etherscan/src/app/views/ErrorView.tsx b/apps/etherscan/src/app/views/ErrorView.tsx index e5fdcd7138..56ec1cfdd6 100644 --- a/apps/etherscan/src/app/views/ErrorView.tsx +++ b/apps/etherscan/src/app/views/ErrorView.tsx @@ -1,4 +1,4 @@ -import React from "react" +import React from 'react' export const ErrorView: React.FC = () => { return ( @@ -11,7 +11,7 @@ export const ErrorView: React.FC = () => { />
Sorry, something unexpected happened.
- Please raise an issue:{" "} + Please raise an issue:{' '} { return ( - {({ apiKey, clientInstance, setReceipts, receipts, contracts }) => { + {({apiKey, clientInstance, setReceipts, receipts, contracts}) => { return !apiKey ? ( ) : ( @@ -28,8 +28,7 @@ export const HomeView: React.FC = () => { }} /> ) - } - } + }} ) } diff --git a/apps/etherscan/src/app/views/ReceiptsView.tsx b/apps/etherscan/src/app/views/ReceiptsView.tsx index 862e72684e..755161de91 100644 --- a/apps/etherscan/src/app/views/ReceiptsView.tsx +++ b/apps/etherscan/src/app/views/ReceiptsView.tsx @@ -1,13 +1,18 @@ -import React, { useState } from "react" +import React, {useState} from 'react' -import { Formik, ErrorMessage, Field } from "formik" -import { getEtherScanApi, getNetworkName, getReceiptStatus, getProxyContractReceiptStatus } from "../utils" -import { Receipt } from "../types" -import { AppContext } from "../AppContext" -import { SubmitButton } from "../components" -import { Navigate } from "react-router-dom" -import { Button } from "react-bootstrap" -import { CustomTooltip } from '@remix-ui/helper' +import {Formik, ErrorMessage, Field} from 'formik' +import { + getEtherScanApi, + getNetworkName, + getReceiptStatus, + getProxyContractReceiptStatus +} from '../utils' +import {Receipt} from '../types' +import {AppContext} from '../AppContext' +import {SubmitButton} from '../components' +import {Navigate} from 'react-router-dom' +import {Button} from 'react-bootstrap' +import {CustomTooltip} from '@remix-ui/helper' interface FormValues { receiptGuid: string @@ -23,11 +28,11 @@ export const ReceiptsView: React.FC = () => { apiKey: string ) => { try { - const { network, networkId } = await getNetworkName(clientInstance) - if (network === "vm") { + const {network, networkId} = await getNetworkName(clientInstance) + if (network === 'vm') { setResults({ succeed: false, - message: "Cannot verify in the selected network" + message: 'Cannot verify in the selected network' }) return } @@ -51,7 +56,9 @@ export const ReceiptsView: React.FC = () => { ) setResults({ succeed: result.status === '1' ? true : false, - message: result.result || (result.status === '0' ? 'Verification failed' : result.message) + message: + result.result || + (result.status === '0' ? 'Verification failed' : result.message) }) } catch (error: any) { setResults({ @@ -63,21 +70,21 @@ export const ReceiptsView: React.FC = () => { return ( - {({ apiKey, clientInstance, receipts, setReceipts }) => { + {({apiKey, clientInstance, receipts, setReceipts}) => { return !apiKey ? ( ) : (
{ const errors = {} as any if (!values.receiptGuid) { - errors.receiptGuid = "Required" + errors.receiptGuid = 'Required' } return errors }} @@ -85,15 +92,15 @@ export const ReceiptsView: React.FC = () => { onGetReceiptStatus(values, clientInstance, apiKey) } > - {({ errors, touched, handleSubmit, handleChange }) => ( + {({errors, touched, handleSubmit, handleChange}) => (
{ handleChange(e) if (e.target.checked) setIsProxyContractReceipt(true) else setIsProxyContractReceipt(false) - }} + }} /> - +
- + )}
-
+ +
- +
) - } - } + }} ) } -const ReceiptsTable: React.FC<{ receipts: Receipt[] }> = ({ receipts }) => { +const ReceiptsTable: React.FC<{receipts: Receipt[]}> = ({receipts}) => { return (
Receipts
@@ -162,20 +195,35 @@ const ReceiptsTable: React.FC<{ receipts: Receipt[] }> = ({ receipts }) => { receipts.map((item: Receipt, index) => { return ( - - {item.status} - {item.status === 'Successfully Updated' && - - + + {item.status} + {item.status === 'Successfully Updated' && ( + + + + )} {item.guid} diff --git a/apps/etherscan/src/app/views/VerifyView.tsx b/apps/etherscan/src/app/views/VerifyView.tsx index 57e6c6f97a..a1f4e3461e 100644 --- a/apps/etherscan/src/app/views/VerifyView.tsx +++ b/apps/etherscan/src/app/views/VerifyView.tsx @@ -1,16 +1,14 @@ -import React, { useEffect, useRef, useState } from "react" +import React, {useEffect, useRef, useState} from 'react' import Web3 from 'web3' -import { - PluginClient, -} from "@remixproject/plugin" -import { CustomTooltip } from '@remix-ui/helper' -import { Formik, ErrorMessage, Field } from "formik" +import {PluginClient} from '@remixproject/plugin' +import {CustomTooltip} from '@remix-ui/helper' +import {Formik, ErrorMessage, Field} from 'formik' -import { SubmitButton } from "../components" -import { Receipt } from "../types" -import { verify } from "../utils/verify" -import { etherscanScripts } from "@remix-project/remix-ws-templates" +import {SubmitButton} from '../components' +import {Receipt} from '../types' +import {verify} from '../utils/verify' +import {etherscanScripts} from '@remix-project/remix-ws-templates' interface Props { client: PluginClient @@ -29,11 +27,11 @@ export const VerifyView: React.FC = ({ apiKey, client, contracts, - onVerifiedContract, + onVerifiedContract }) => { - const [results, setResults] = useState("") - const [networkName, setNetworkName] = useState("Loading...") - const [selectedContract, setSelectedContract] = useState("") + const [results, setResults] = useState('') + const [networkName, setNetworkName] = useState('Loading...') + const [selectedContract, setSelectedContract] = useState('') const [showConstructorArgs, setShowConstructorArgs] = useState(false) const [isProxyContract, setIsProxyContract] = useState(false) const [constructorInputs, setConstructorInputs] = useState([]) @@ -41,13 +39,19 @@ export const VerifyView: React.FC = ({ useEffect(() => { if (client && client.on) { - client.on("blockchain" as any, 'networkStatus', (result) => { - setNetworkName(`${result.network.name} ${result.network.id !== '-' ? `(Chain id: ${result.network.id})` : '(Not supported)'}`) + client.on('blockchain' as any, 'networkStatus', (result) => { + setNetworkName( + `${result.network.name} ${ + result.network.id !== '-' + ? `(Chain id: ${result.network.id})` + : '(Not supported)' + }` + ) }) } return () => { // To fix memory leak - if (client && client.off) client.off("blockchain" as any, 'networkStatus') + if (client && client.off) client.off('blockchain' as any, 'networkStatus') } }, [client]) @@ -56,36 +60,53 @@ export const VerifyView: React.FC = ({ }, [contracts]) const updateConsFields = (contractName) => { - client.call("compilerArtefacts" as any, "getArtefactsByContractName", contractName).then((result) => { - const { artefact } = result - if (artefact && artefact.abi && artefact.abi[0] && artefact.abi[0].type && artefact.abi[0].type === 'constructor' && artefact.abi[0].inputs.length > 0) { - setConstructorInputs(artefact.abi[0].inputs) - setShowConstructorArgs(true) - } else { - setConstructorInputs([]) - setShowConstructorArgs(false) - } - }) + client + .call( + 'compilerArtefacts' as any, + 'getArtefactsByContractName', + contractName + ) + .then((result) => { + const {artefact} = result + if ( + artefact && + artefact.abi && + artefact.abi[0] && + artefact.abi[0].type && + artefact.abi[0].type === 'constructor' && + artefact.abi[0].inputs.length > 0 + ) { + setConstructorInputs(artefact.abi[0].inputs) + setShowConstructorArgs(true) + } else { + setConstructorInputs([]) + setShowConstructorArgs(false) + } + }) } const onVerifyContract = async (values: FormValues) => { const compilationResult = (await client.call( - "solidity", - "getCompilationResult" + 'solidity', + 'getCompilationResult' )) as any if (!compilationResult) { - throw new Error("no compilation result available") + throw new Error('no compilation result available') } const constructorValues = [] for (const key in values) { - if (key.startsWith('contractArgValue')) constructorValues.push(values[key]) + if (key.startsWith('contractArgValue')) + constructorValues.push(values[key]) } const web3 = new Web3() - const constructorTypes = constructorInputs.map(e => e.type) - let contractArguments = web3.eth.abi.encodeParameters(constructorTypes, constructorValues) - contractArguments = contractArguments.replace("0x", "") + const constructorTypes = constructorInputs.map((e) => e.type) + let contractArguments = web3.eth.abi.encodeParameters( + constructorTypes, + constructorValues + ) + contractArguments = contractArguments.replace('0x', '') verificationResult.current = await verify( apiKey, @@ -98,7 +119,7 @@ export const VerifyView: React.FC = ({ values.expectedImplAddress, client, onVerifiedContract, - setResults, + setResults ) setResults(verificationResult.current['message']) } @@ -107,76 +128,90 @@ export const VerifyView: React.FC = ({
{ const errors = {} as any if (!values.contractName) { - errors.contractName = "Required" + errors.contractName = 'Required' } if (!values.contractAddress) { - errors.contractAddress = "Required" + errors.contractAddress = 'Required' } - if (values.contractAddress.trim() === "" || !values.contractAddress.startsWith('0x') - || values.contractAddress.length !== 42) { - errors.contractAddress = "Please enter a valid contract address" + if ( + values.contractAddress.trim() === '' || + !values.contractAddress.startsWith('0x') || + values.contractAddress.length !== 42 + ) { + errors.contractAddress = 'Please enter a valid contract address' } return errors }} onSubmit={(values) => onVerifyContract(values)} > - {({ errors, touched, handleSubmit, handleChange, isSubmitting }) => { - return (
-
- - + {({errors, touched, handleSubmit, handleChange, isSubmitting}) => { + return ( + +
+ + + + +
+
+ - -
-
- - { + handleChange(e) + setSelectedContract(e.target.value) + updateConsFields(e.target.value) + }} + > + + {contracts.map((item) => ( + + ))} + + +
+
{ - handleChange(e) - setSelectedContract(e.target.value) - updateConsFields(e.target.value) - }} > - - {contracts.map((item) => ( - - ))} - - -
-
- + {constructorInputs.map((item, index) => { return (
@@ -191,7 +226,7 @@ export const VerifyView: React.FC = ({ = ({ />
- )} - )} - -
-
- - - -
+ ) + })} +
+
+ { - handleChange(e) - if (e.target.checked) setIsProxyContract(true) - else setIsProxyContract(false) - }} + className={ + errors.contractAddress && touched.contractAddress + ? 'form-control is-invalid' + : 'form-control' + } + type="text" + name="contractAddress" + placeholder="e.g. 0x11b79afc03baf25c631dd70169bb6a3160b2706e" + /> + - +
+ { + handleChange(e) + if (e.target.checked) setIsProxyContract(true) + else setIsProxyContract(false) + }} + /> + +
-
-
- +
+ + + + + + +
+ +
- - - - -
- -
- - - ) + + ) }}
{/*
View Receipts diff --git a/apps/etherscan/src/main.tsx b/apps/etherscan/src/main.tsx index 353ad43f6d..5f17c9ab24 100644 --- a/apps/etherscan/src/main.tsx +++ b/apps/etherscan/src/main.tsx @@ -1,7 +1,11 @@ -import { StrictMode } from 'react'; -import * as ReactDOM from 'react-dom'; +import {StrictMode} from 'react' +import * as ReactDOM from 'react-dom' +import App from './app/app' -import App from './app/app'; - -ReactDOM.render(, document.getElementById('root')); +ReactDOM.render( + + + , + document.getElementById('root') +) diff --git a/apps/etherscan/webpack.config.js b/apps/etherscan/webpack.config.js index e28638e84e..5564f25b94 100644 --- a/apps/etherscan/webpack.config.js +++ b/apps/etherscan/webpack.config.js @@ -1,7 +1,7 @@ -const { composePlugins, withNx } = require('@nrwl/webpack') +const {composePlugins, withNx} = require('@nrwl/webpack') const webpack = require('webpack') -const TerserPlugin = require("terser-webpack-plugin") -const CssMinimizerPlugin = require("css-minimizer-webpack-plugin") +const TerserPlugin = require('terser-webpack-plugin') +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') const versionData = { timestamp: Date.now(), @@ -15,29 +15,29 @@ module.exports = composePlugins(withNx(), (config) => { // add fallback for node modules config.resolve.fallback = { ...config.resolve.fallback, - "crypto": require.resolve("crypto-browserify"), - "stream": require.resolve("stream-browserify"), - "path": require.resolve("path-browserify"), - "http": require.resolve("stream-http"), - "https": require.resolve("https-browserify"), - "constants": require.resolve("constants-browserify"), - "os": false, //require.resolve("os-browserify/browser"), - "timers": false, // require.resolve("timers-browserify"), - "zlib": require.resolve("browserify-zlib"), - "fs": false, - "module": false, - "tls": false, - "net": false, - "readline": false, - "child_process": false, - "buffer": require.resolve("buffer/"), - "vm": require.resolve('vm-browserify'), + crypto: require.resolve('crypto-browserify'), + stream: require.resolve('stream-browserify'), + path: require.resolve('path-browserify'), + http: require.resolve('stream-http'), + https: require.resolve('https-browserify'), + constants: require.resolve('constants-browserify'), + os: false, //require.resolve("os-browserify/browser"), + timers: false, // require.resolve("timers-browserify"), + zlib: require.resolve('browserify-zlib'), + fs: false, + module: false, + tls: false, + net: false, + readline: false, + child_process: false, + buffer: require.resolve('buffer/'), + vm: require.resolve('vm-browserify') } // add externals config.externals = { ...config.externals, - solc: 'solc', + solc: 'solc' } // add public path @@ -47,26 +47,24 @@ module.exports = composePlugins(withNx(), (config) => { config.output.filename = `[name].plugin-etherscan.${versionData.timestamp}.js` config.output.chunkFilename = `[name].plugin-etherscan.${versionData.timestamp}.js` - // add copy & provide plugin config.plugins.push( new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'], url: ['url', 'URL'], - process: 'process/browser', + process: 'process/browser' }) ) // souce-map loader config.module.rules.push({ test: /\.js$/, - use: ["source-map-loader"], - enforce: "pre" + use: ['source-map-loader'], + enforce: 'pre' }) config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings - // set minimizer config.optimization.minimizer = [ new TerserPlugin({ @@ -76,17 +74,17 @@ module.exports = composePlugins(withNx(), (config) => { compress: false, mangle: false, format: { - comments: false, - }, + comments: false + } }, - extractComments: false, + extractComments: false }), - new CssMinimizerPlugin(), - ]; + new CssMinimizerPlugin() + ] config.watchOptions = { ignored: /node_modules/ } - return config; -}); + return config +}) diff --git a/apps/remix-ide-e2e/nightwatch.ts b/apps/remix-ide-e2e/nightwatch.ts index 3f59c1549e..09cf5f9c5a 100644 --- a/apps/remix-ide-e2e/nightwatch.ts +++ b/apps/remix-ide-e2e/nightwatch.ts @@ -7,7 +7,7 @@ module.exports = { globals_path: '', test_settings: { - default: { + 'default': { selenium_port: 4444, selenium_host: 'localhost', globals: { @@ -20,31 +20,35 @@ module.exports = { on_failure: true, on_error: true }, - exclude: ['dist/apps/remix-ide-e2e/src/tests/runAndDeploy.test.js', 'dist/apps/remix-ide-e2e/src/tests/pluginManager.test.ts'] + exclude: [ + 'dist/apps/remix-ide-e2e/src/tests/runAndDeploy.test.js', + 'dist/apps/remix-ide-e2e/src/tests/pluginManager.test.ts' + ] }, - chrome: { + 'chrome': { desiredCapabilities: { - browserName: 'chrome', - javascriptEnabled: true, - acceptSslCerts: true, + 'browserName': 'chrome', + 'javascriptEnabled': true, + 'acceptSslCerts': true, 'goog:chromeOptions': { - args: ['window-size=2560,1440', - 'start-fullscreen', - '--no-sandbox', - '--headless', - '--verbose', - "--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36", + args: [ + 'window-size=2560,1440', + 'start-fullscreen', + '--no-sandbox', + '--headless', + '--verbose', + '--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36' ] } } }, - chromeDesktop: { + 'chromeDesktop': { desiredCapabilities: { - browserName: 'chrome', - javascriptEnabled: true, - acceptSslCerts: true, + 'browserName': 'chrome', + 'javascriptEnabled': true, + 'acceptSslCerts': true, 'goog:chromeOptions': { args: ['window-size=2560,1440', 'start-fullscreen', '--no-sandbox'] } @@ -53,40 +57,39 @@ module.exports = { 'chrome-runAndDeploy': { desiredCapabilities: { - browserName: 'chrome', - javascriptEnabled: true, - acceptSslCerts: true, + 'browserName': 'chrome', + 'javascriptEnabled': true, + 'acceptSslCerts': true, 'goog:chromeOptions': { - args: ['window-size=2560,1440', 'start-fullscreen', '--no-sandbox', '--headless', '--verbose'] + args: [ + 'window-size=2560,1440', + 'start-fullscreen', + '--no-sandbox', + '--headless', + '--verbose' + ] } } }, - firefoxDesktop: { + 'firefoxDesktop': { desiredCapabilities: { - browserName: 'firefox', - javascriptEnabled: true, - acceptSslCerts: true, + 'browserName': 'firefox', + 'javascriptEnabled': true, + 'acceptSslCerts': true, 'moz:firefoxOptions': { - args: [ - '-width=2560', - '-height=1440' - ] + args: ['-width=2560', '-height=1440'] } } }, - firefox: { + 'firefox': { desiredCapabilities: { - browserName: 'firefox', - javascriptEnabled: true, - acceptSslCerts: true, + 'browserName': 'firefox', + 'javascriptEnabled': true, + 'acceptSslCerts': true, 'moz:firefoxOptions': { - args: [ - '-headless', - '-width=2560', - '-height=1440' - ] + args: ['-headless', '-width=2560', '-height=1440'] } } } diff --git a/apps/remix-ide-e2e/src/local-plugin/src/app/app.tsx b/apps/remix-ide-e2e/src/local-plugin/src/app/app.tsx index bc599077f4..efc199eee4 100644 --- a/apps/remix-ide-e2e/src/local-plugin/src/app/app.tsx +++ b/apps/remix-ide-e2e/src/local-plugin/src/app/app.tsx @@ -1,38 +1,55 @@ - -import React, { useEffect, useState } from 'react' -import { RemixPlugin } from './Client' -import { Logger } from './logger' -import { filePanelProfile } from '@remixproject/plugin-api' -import { filSystemProfile } from '@remixproject/plugin-api' -import { dGitProfile } from '@remixproject/plugin-api' -import { editorProfile } from '@remixproject/plugin-api' -import { settingsProfile } from '@remixproject/plugin-api' -import { networkProfile } from '@remixproject/plugin-api' -import { udappProfile } from '@remixproject/plugin-api' -import { compilerProfile } from '@remixproject/plugin-api' -import { contentImportProfile } from '@remixproject/plugin-api' -import { windowProfile } from '@remixproject/plugin-api' -import { pluginManagerProfile } from '@remixproject/plugin-api' -import { Profile } from '@remixproject/plugin-utils' +import React, {useEffect, useState} from 'react' +import {RemixPlugin} from './Client' +import {Logger} from './logger' +import {filePanelProfile} from '@remixproject/plugin-api' +import {filSystemProfile} from '@remixproject/plugin-api' +import {dGitProfile} from '@remixproject/plugin-api' +import {editorProfile} from '@remixproject/plugin-api' +import {settingsProfile} from '@remixproject/plugin-api' +import {networkProfile} from '@remixproject/plugin-api' +import {udappProfile} from '@remixproject/plugin-api' +import {compilerProfile} from '@remixproject/plugin-api' +import {contentImportProfile} from '@remixproject/plugin-api' +import {windowProfile} from '@remixproject/plugin-api' +import {pluginManagerProfile} from '@remixproject/plugin-api' +import {Profile} from '@remixproject/plugin-utils' import './app.css' const client = new RemixPlugin() -function App () { +function App() { const [payload, setPayload] = useState('') const [log, setLog] = useState() const [started, setStarted] = useState(false) const [events, setEvents] = useState() - const [profiles, setProfiles] = useState([pluginManagerProfile, filePanelProfile, filSystemProfile, dGitProfile, networkProfile, settingsProfile, editorProfile, compilerProfile, udappProfile, contentImportProfile, windowProfile]) + const [profiles, setProfiles] = useState([ + pluginManagerProfile, + filePanelProfile, + filSystemProfile, + dGitProfile, + networkProfile, + settingsProfile, + editorProfile, + compilerProfile, + udappProfile, + contentImportProfile, + windowProfile + ]) - const handleChange = ({ target }: any) => { + const handleChange = ({target}: any) => { setPayload(target.value) } useEffect(() => { client.onload(async () => { - const customProfiles = ['menuicons', 'tabs', 'solidityUnitTesting', 'hardhat-provider', 'notification'] + const customProfiles = [ + 'menuicons', + 'tabs', + 'solidityUnitTesting', + 'hardhat-provider', + 'notification' + ] client.testCommand = async (data: any) => { console.log(data) @@ -44,7 +61,7 @@ function App () { const p = await client.call('manager', 'getProfile', name) addProfiles = [...addProfiles, p] } - setProfiles(profiles => [...profiles, ...addProfiles]) + setProfiles((profiles) => [...profiles, ...addProfiles]) profiles.map((profile: Profile) => { if (profile.events) { @@ -77,8 +94,10 @@ function App () { let ob: any = null try { ob = JSON.parse(payload) - if (ob && !Array.isArray(ob)) { ob = [ob] } - } catch (e) { } + if (ob && !Array.isArray(ob)) { + ob = [ob] + } + } catch (e) {} const args = ob || [payload] setStarted(true) setLog('') @@ -97,13 +116,14 @@ function App () { return (
PLUGIN API TESTER
-

+ +

- + - + {profiles.map((profile: Profile) => { const methods = profile.methods.map((method: string) => { - return + return ( + + ) }) - const events = profile.events ? profile.events.map((event: string) => { - return - }) : null - return


{methods}

{events ? : null}{events}
+ const events = profile.events + ? profile.events.map((event: string) => { + return ( + + ) + }) + : null + return ( +
+ +

+ {methods} +

+ {events ? : null} + {events} +
+ ) })} -
) } diff --git a/apps/remix-ide-e2e/src/local-plugin/src/app/logger.tsx b/apps/remix-ide-e2e/src/local-plugin/src/app/logger.tsx index 92033e264b..4273c609d2 100644 --- a/apps/remix-ide-e2e/src/local-plugin/src/app/logger.tsx +++ b/apps/remix-ide-e2e/src/local-plugin/src/app/logger.tsx @@ -1,9 +1,13 @@ import React from 'react' interface loggerProps { - log: any, + log: any id: string } export const Logger: React.FC = (props) => { - return (
{props.log}
) + return ( +
+ {props.log} +
+ ) } diff --git a/apps/remix-ide/background.js b/apps/remix-ide/background.js index 8b9269f940..40f75068b2 100644 --- a/apps/remix-ide/background.js +++ b/apps/remix-ide/background.js @@ -2,9 +2,12 @@ 'use strict' chrome.browserAction.onClicked.addListener(function (tab) { - chrome.storage.sync.set({ 'chrome-app-sync': true }) + chrome.storage.sync.set({'chrome-app-sync': true}) - chrome.tabs.create({ 'url': chrome.extension.getURL('index.html') }, function (tab) { - // tab opened - }) + chrome.tabs.create( + {url: chrome.extension.getURL('index.html')}, + function (tab) { + // tab opened + } + ) }) diff --git a/apps/remix-ide/src/app/components/hidden-panel.tsx b/apps/remix-ide/src/app/components/hidden-panel.tsx index 6aa78a4052..88b095b625 100644 --- a/apps/remix-ide/src/app/components/hidden-panel.tsx +++ b/apps/remix-ide/src/app/components/hidden-panel.tsx @@ -1,9 +1,9 @@ // eslint-disable-next-line no-use-before-define import React from 'react' -import { AbstractPanel } from './panel' +import {AbstractPanel} from './panel' import * as packageJson from '../../../../../package.json' -import { RemixPluginPanel } from '@remix-ui/panel' -import { PluginViewWrapper } from '@remix-ui/helper' +import {RemixPluginPanel} from '@remix-ui/panel' +import {PluginViewWrapper} from '@remix-ui/helper' const profile = { name: 'hiddenPanel', @@ -16,35 +16,37 @@ const profile = { export class HiddenPanel extends AbstractPanel { el: HTMLElement dispatch: React.Dispatch = () => {} - constructor () { + constructor() { super(profile) this.el = document.createElement('div') this.el.setAttribute('class', 'pluginsContainer') } - addView (profile: any, view: any): void { + addView(profile: any, view: any): void { super.removeView(profile) super.addView(profile, view) this.renderComponent() } - updateComponent (state: any) { - return } plugins={state.plugins}/> + updateComponent(state: any) { + return } plugins={state.plugins} /> } - setDispatch (dispatch: React.Dispatch) { + setDispatch(dispatch: React.Dispatch) { this.dispatch = dispatch } - render() { + render() { return ( -
- ); +
+ +
+ ) } - renderComponent () { + renderComponent() { this.dispatch({ - plugins: this.plugins, + plugins: this.plugins }) } } diff --git a/apps/remix-ide/src/app/components/main-panel.tsx b/apps/remix-ide/src/app/components/main-panel.tsx index 0eb7487b94..ed4a4b637e 100644 --- a/apps/remix-ide/src/app/components/main-panel.tsx +++ b/apps/remix-ide/src/app/components/main-panel.tsx @@ -1,8 +1,8 @@ import React from 'react' // eslint-disable-line -import { AbstractPanel } from './panel' -import { RemixPluginPanel } from '@remix-ui/panel' +import {AbstractPanel} from './panel' +import {RemixPluginPanel} from '@remix-ui/panel' import packageJson from '../../../../../package.json' -import { PluginViewWrapper } from '@remix-ui/helper' +import {PluginViewWrapper} from '@remix-ui/helper' const profile = { name: 'mainPanel', @@ -15,7 +15,7 @@ const profile = { export class MainPanel extends AbstractPanel { element: HTMLDivElement dispatch: React.Dispatch = () => {} - constructor (config) { + constructor(config) { super(profile) this.element = document.createElement('div') this.element.setAttribute('data-id', 'mainPanelPluginsContainer') @@ -23,46 +23,53 @@ export class MainPanel extends AbstractPanel { // this.config = config } - setDispatch (dispatch: React.Dispatch) { + setDispatch(dispatch: React.Dispatch) { this.dispatch = dispatch } - onActivation () { + onActivation() { this.renderComponent() } - focus (name) { + focus(name) { this.emit('focusChanged', name) super.focus(name) this.renderComponent() } - addView (profile, view) { + addView(profile, view) { super.addView(profile, view) this.renderComponent() } - removeView (profile) { + removeView(profile) { super.removeView(profile) this.renderComponent() } - async showContent (name) { + async showContent(name) { super.showContent(name) this.renderComponent() } - renderComponent () { + renderComponent() { this.dispatch({ plugins: this.plugins }) } - render() { - return
+ render() { + return ( +
+ +
+ ) } - updateComponent (state: any) { - return } plugins={state.plugins}/> + updateComponent(state: any) { + return } plugins={state.plugins} /> } } diff --git a/apps/remix-ide/src/app/components/preload.tsx b/apps/remix-ide/src/app/components/preload.tsx index 4cca83a00a..a3d7180283 100644 --- a/apps/remix-ide/src/app/components/preload.tsx +++ b/apps/remix-ide/src/app/components/preload.tsx @@ -1,16 +1,18 @@ -import { RemixApp } from '@remix-ui/app' -import React, { useEffect, useRef, useState } from 'react' -import { render } from 'react-dom' +import {RemixApp} from '@remix-ui/app' +import React, {useEffect, useRef, useState} from 'react' +import {render} from 'react-dom' import * as packageJson from '../../../../../package.json' -import { fileSystem, fileSystems } from '../files/fileSystem' -import { indexedDBFileSystem } from '../files/filesystems/indexedDB' -import { localStorageFS } from '../files/filesystems/localStorage' -import { fileSystemUtility, migrationTestData } from '../files/filesystems/fileSystemUtility' +import {fileSystem, fileSystems} from '../files/fileSystem' +import {indexedDBFileSystem} from '../files/filesystems/indexedDB' +import {localStorageFS} from '../files/filesystems/localStorage' +import { + fileSystemUtility, + migrationTestData +} from '../files/filesystems/fileSystemUtility' import './styles/preload.css' -const _paq = window._paq = window._paq || [] +const _paq = (window._paq = window._paq || []) export const Preload = () => { - const [supported, setSupported] = useState(true) const [error, setError] = useState(false) const [showDownloader, setShowDownloader] = useState(false) @@ -18,45 +20,74 @@ export const Preload = () => { const remixIndexedDB = useRef(new indexedDBFileSystem()) const localStorageFileSystem = useRef(new localStorageFS()) // url parameters to e2e test the fallbacks and error warnings - const testmigrationFallback = useRef(window.location.hash.includes('e2e_testmigration_fallback=true') && window.location.host === '127.0.0.1:8080' && window.location.protocol === 'http:') - const testmigrationResult = useRef(window.location.hash.includes('e2e_testmigration=true') && window.location.host === '127.0.0.1:8080' && window.location.protocol === 'http:') - const testBlockStorage = useRef(window.location.hash.includes('e2e_testblock_storage=true') && window.location.host === '127.0.0.1:8080' && window.location.protocol === 'http:') + const testmigrationFallback = useRef( + window.location.hash.includes('e2e_testmigration_fallback=true') && + window.location.host === '127.0.0.1:8080' && + window.location.protocol === 'http:' + ) + const testmigrationResult = useRef( + window.location.hash.includes('e2e_testmigration=true') && + window.location.host === '127.0.0.1:8080' && + window.location.protocol === 'http:' + ) + const testBlockStorage = useRef( + window.location.hash.includes('e2e_testblock_storage=true') && + window.location.host === '127.0.0.1:8080' && + window.location.protocol === 'http:' + ) function loadAppComponent() { - import('../../app').then((AppComponent) => { - const appComponent = new AppComponent.default() - appComponent.run().then(() => { - render( - <> - - , - document.getElementById('root') - ) + import('../../app') + .then((AppComponent) => { + const appComponent = new AppComponent.default() + appComponent.run().then(() => { + render( + <> + + , + document.getElementById('root') + ) + }) + }) + .catch((err) => { + _paq.push(['trackEvent', 'Preload', 'error', err && err.message]) + console.error('Error loading Remix:', err) + setError(true) }) - }).catch(err => { - _paq.push(['trackEvent', 'Preload', 'error', err && err.message]) - console.error('Error loading Remix:', err) - setError(true) - }) } const downloadBackup = async () => { setShowDownloader(false) const fsUtility = new fileSystemUtility() - await fsUtility.downloadBackup(remixFileSystems.current.fileSystems['localstorage']) + await fsUtility.downloadBackup( + remixFileSystems.current.fileSystems['localstorage'] + ) await migrateAndLoad() } const migrateAndLoad = async () => { setShowDownloader(false) const fsUtility = new fileSystemUtility() - const migrationResult = await fsUtility.migrate(localStorageFileSystem.current, remixIndexedDB.current) - _paq.push(['trackEvent', 'Migrate', 'result', migrationResult?'success' : 'fail']) + const migrationResult = await fsUtility.migrate( + localStorageFileSystem.current, + remixIndexedDB.current + ) + _paq.push([ + 'trackEvent', + 'Migrate', + 'result', + migrationResult ? 'success' : 'fail' + ]) await setFileSystems() } - const setFileSystems = async() => { - const fsLoaded = await remixFileSystems.current.setFileSystem([(testmigrationFallback.current || testBlockStorage.current)? null: remixIndexedDB.current, testBlockStorage.current? null:localStorageFileSystem.current]) + const setFileSystems = async () => { + const fsLoaded = await remixFileSystems.current.setFileSystem([ + testmigrationFallback.current || testBlockStorage.current + ? null + : remixIndexedDB.current, + testBlockStorage.current ? null : localStorageFileSystem.current + ]) if (fsLoaded) { console.log(fsLoaded.name + ' activated') _paq.push(['trackEvent', 'Storage', 'activate', fsLoaded.name]) @@ -67,78 +98,126 @@ export const Preload = () => { } } - const testmigration = async() => { + const testmigration = async () => { if (testmigrationResult.current) { const fsUtility = new fileSystemUtility() - fsUtility.populateWorkspace(migrationTestData, remixFileSystems.current.fileSystems['localstorage'].fs) + fsUtility.populateWorkspace( + migrationTestData, + remixFileSystems.current.fileSystems['localstorage'].fs + ) } } useEffect(() => { async function loadStorage() { - await remixFileSystems.current.addFileSystem(remixIndexedDB.current) || _paq.push(['trackEvent', 'Storage', 'error', 'indexedDB not supported']) - await remixFileSystems.current.addFileSystem(localStorageFileSystem.current) || _paq.push(['trackEvent', 'Storage', 'error', 'localstorage not supported']) + ;(await remixFileSystems.current.addFileSystem(remixIndexedDB.current)) || + _paq.push(['trackEvent', 'Storage', 'error', 'indexedDB not supported']) + ;(await remixFileSystems.current.addFileSystem( + localStorageFileSystem.current + )) || + _paq.push([ + 'trackEvent', + 'Storage', + 'error', + 'localstorage not supported' + ]) await testmigration() - remixIndexedDB.current.loaded && await remixIndexedDB.current.checkWorkspaces() - localStorageFileSystem.current.loaded && await localStorageFileSystem.current.checkWorkspaces() - remixIndexedDB.current.loaded && ( (remixIndexedDB.current.hasWorkSpaces || !localStorageFileSystem.current.hasWorkSpaces)? await setFileSystems():setShowDownloader(true)) - !remixIndexedDB.current.loaded && await setFileSystems() + remixIndexedDB.current.loaded && + (await remixIndexedDB.current.checkWorkspaces()) + localStorageFileSystem.current.loaded && + (await localStorageFileSystem.current.checkWorkspaces()) + remixIndexedDB.current.loaded && + (remixIndexedDB.current.hasWorkSpaces || + !localStorageFileSystem.current.hasWorkSpaces + ? await setFileSystems() + : setShowDownloader(true)) + !remixIndexedDB.current.loaded && (await setFileSystems()) } loadStorage() }, []) - return <> -
-
- {logo} -
- REMIX IDE -
- v{packageJson.version} + return ( + <> +
+
+ {logo} +
+ REMIX IDE +
+ v{packageJson.version} +
-
- {!supported ? -
- Your browser does not support any of the filesystems required by Remix. - Either change the settings in your browser or use a supported browser. -
: null} - {error ? -
- An unknown error has occurred while loading the application.

- Doing a hard refresh might fix this issue:

-
- Windows:

- - Chrome: CTRL + F5 or CTRL + Reload Button

- - Firefox: CTRL + SHIFT + R or CTRL + F5

+ {!supported ? ( +
+ Your browser does not support any of the filesystems required by + Remix. Either change the settings in your browser or use a supported + browser.
-
- MacOS:

- - Chrome & FireFox: CMD + SHIFT + R or SHIFT + Reload Button

+ ) : null} + {error ? ( +
+ An unknown error has occurred while loading the application. +

+ Doing a hard refresh might fix this issue:

+
+ Windows:

- Chrome: CTRL + F5 or CTRL + Reload Button +

- Firefox: CTRL + SHIFT + R or CTRL + F5

+
+
+ MacOS:

- Chrome & FireFox: CMD + SHIFT + R or SHIFT + + Reload Button

+
+
+ Linux:

- Chrome & FireFox: CTRL + SHIFT + R

+
-
- Linux:

- - Chrome & FireFox: CTRL + SHIFT + R

+ ) : null} + {showDownloader ? ( +
+ This app will be updated now. Please download a backup of your files + now to make sure you don't lose your work. +

+ You don't need to do anything else, your files will be available + when the app loads. +
{ + await downloadBackup() + }} + data-id="downloadbackup-btn" + className="btn btn-primary mt-1" + > + download backup +
+
{ + await migrateAndLoad() + }} + data-id="skipbackup-btn" + className="btn btn-primary mt-1" + > + skip backup +
-
: null} - {showDownloader ? -
- This app will be updated now. Please download a backup of your files now to make sure you don't lose your work. -

- You don't need to do anything else, your files will be available when the app loads. -
{ await downloadBackup() }} data-id='downloadbackup-btn' className='btn btn-primary mt-1'>download backup
-
{ await migrateAndLoad() }} data-id='skipbackup-btn' className='btn btn-primary mt-1'>skip backup
-
: null} - {(supported && !error && !showDownloader) ? -
- -
: null} -
- + ) : null} + {supported && !error && !showDownloader ? ( +
+ +
+ ) : null} +
+ + ) } - -const logo = - - - - +const logo = ( + + + + + +) diff --git a/apps/remix-ide/src/app/components/side-panel.tsx b/apps/remix-ide/src/app/components/side-panel.tsx index 8b58171492..50e1dac0dc 100644 --- a/apps/remix-ide/src/app/components/side-panel.tsx +++ b/apps/remix-ide/src/app/components/side-panel.tsx @@ -1,10 +1,10 @@ // eslint-disable-next-line no-use-before-define import React from 'react' -import { AbstractPanel } from './panel' -import { RemixPluginPanel } from '@remix-ui/panel' +import {AbstractPanel} from './panel' +import {RemixPluginPanel} from '@remix-ui/panel' import packageJson from '../../../../../package.json' -import { RemixUIPanelHeader } from '@remix-ui/panel' -import { PluginViewWrapper } from '@remix-ui/helper' +import {RemixUIPanelHeader} from '@remix-ui/panel' +import {PluginViewWrapper} from '@remix-ui/helper' // const csjs = require('csjs-inject') const sidePanel = { @@ -56,7 +56,8 @@ export class SidePanel extends AbstractPanel { } removeView(profile) { - if (this.plugins[profile.name].active) this.call('menuicons', 'select', 'filePanel') + if (this.plugins[profile.name].active) + this.call('menuicons', 'select', 'filePanel') super.removeView(profile) this.emit('pluginDisabled', profile.name) this.call('menuicons', 'unlinkContent', profile) @@ -79,18 +80,28 @@ export class SidePanel extends AbstractPanel { this.renderComponent() } - setDispatch (dispatch: React.Dispatch) { + setDispatch(dispatch: React.Dispatch) { this.dispatch = dispatch } - render() { + render() { return ( -
- ); +
+ {' '} + +
+ ) } updateComponent(state: any) { - return } plugins={state.plugins} /> + return ( + + } + plugins={state.plugins} + /> + ) } renderComponent() { diff --git a/apps/remix-ide/src/app/components/vertical-icons.tsx b/apps/remix-ide/src/app/components/vertical-icons.tsx index 87f78ffd40..2e4b67a852 100644 --- a/apps/remix-ide/src/app/components/vertical-icons.tsx +++ b/apps/remix-ide/src/app/components/vertical-icons.tsx @@ -1,11 +1,14 @@ // eslint-disable-next-line no-use-before-define import React from 'react' import packageJson from '../../../../../package.json' -import { Plugin } from '@remixproject/engine' -import { EventEmitter } from 'events' -import { IconRecord, RemixUiVerticalIconsPanel } from '@remix-ui/vertical-icons-panel' -import { Profile } from '@remixproject/plugin-utils' -import { PluginViewWrapper } from '@remix-ui/helper' +import {Plugin} from '@remixproject/engine' +import {EventEmitter} from 'events' +import { + IconRecord, + RemixUiVerticalIconsPanel +} from '@remix-ui/vertical-icons-panel' +import {Profile} from '@remixproject/plugin-utils' +import {PluginViewWrapper} from '@remix-ui/helper' const profile = { name: 'menuicons', @@ -21,44 +24,63 @@ export class VerticalIcons extends Plugin { htmlElement: HTMLDivElement icons: Record = {} dispatch: React.Dispatch = () => {} - constructor () { + constructor() { super(profile) this.events = new EventEmitter() this.htmlElement = document.createElement('div') this.htmlElement.setAttribute('id', 'icon-panel') } - renderComponent () { - const fixedOrder = ['filePanel', 'search', 'solidity','udapp', 'debugger', 'solidityStaticAnalysis', 'solidityUnitTesting', 'pluginManager'] + renderComponent() { + const fixedOrder = [ + 'filePanel', + 'search', + 'solidity', + 'udapp', + 'debugger', + 'solidityStaticAnalysis', + 'solidityUnitTesting', + 'pluginManager' + ] - const divived = Object.values(this.icons).map((value) => { return { - ...value, - isRequired: fixedOrder.indexOf(value.profile.name) > -1 - }}).sort((a,b) => { - return a.timestamp - b.timestamp - }) + const divived = Object.values(this.icons) + .map((value) => { + return { + ...value, + isRequired: fixedOrder.indexOf(value.profile.name) > -1 + } + }) + .sort((a, b) => { + return a.timestamp - b.timestamp + }) - const required = divived.filter((value) => value.isRequired).sort((a,b) => { - return fixedOrder.indexOf(a.profile.name) - fixedOrder.indexOf(b.profile.name) - }) + const required = divived + .filter((value) => value.isRequired) + .sort((a, b) => { + return ( + fixedOrder.indexOf(a.profile.name) - + fixedOrder.indexOf(b.profile.name) + ) + }) const sorted: IconRecord[] = [ ...required, - ...divived.filter((value) => { return !value.isRequired }) + ...divived.filter((value) => { + return !value.isRequired + }) ] this.dispatch({ verticalIconsPlugin: this, icons: sorted }) - } - setDispatch (dispatch: React.Dispatch) { + setDispatch(dispatch: React.Dispatch) { this.dispatch = dispatch } - onActivation () { + onActivation() { this.renderComponent() this.on('sidePanel', 'focusChanged', (name: string) => { Object.keys(this.icons).map((o) => { @@ -69,19 +91,24 @@ export class VerticalIcons extends Plugin { }) } - async linkContent (profile: Profile) { + async linkContent(profile: Profile) { if (!profile.icon) return if (!profile.kind) profile.kind = 'none' this.icons[profile.name] = { profile: profile, active: false, - canbeDeactivated: await this.call('manager', 'canDeactivate', this.profile, profile), + canbeDeactivated: await this.call( + 'manager', + 'canDeactivate', + this.profile, + profile + ), timestamp: Date.now() } this.renderComponent() } - unlinkContent (profile: Profile) { + unlinkContent(profile: Profile) { delete this.icons[profile.name] this.renderComponent() } @@ -95,7 +122,7 @@ export class VerticalIcons extends Plugin { * Set an icon as active * @param {string} name Name of profile of the module to activate */ - select (name: string) { + select(name: string) { // TODO: Only keep `this.emit` (issue#2210) this.emit('showContent', name) this.events.emit('showContent', name) @@ -105,22 +132,26 @@ export class VerticalIcons extends Plugin { * Toggles the side panel for plugin * @param {string} name Name of profile of the module to activate */ - toggle (name: string) { + toggle(name: string) { // TODO: Only keep `this.emit` (issue#2210) this.emit('toggleContent', name) this.events.emit('toggleContent', name) } - updateComponent(state: any){ - return + updateComponent(state: any) { + return ( + + ) } - render() { + render() { return ( -
- ); +
+ +
+ ) } } diff --git a/apps/remix-ide/src/app/plugins/contractFlattener.tsx b/apps/remix-ide/src/app/plugins/contractFlattener.tsx index 4f7cad9212..18c1336e54 100644 --- a/apps/remix-ide/src/app/plugins/contractFlattener.tsx +++ b/apps/remix-ide/src/app/plugins/contractFlattener.tsx @@ -1,9 +1,13 @@ import React from 'react' -import { Plugin } from '@remixproject/engine' -import { customAction } from '@remixproject/plugin-api' -import { concatSourceFiles, getDependencyGraph, normalizeContractPath } from '@remix-ui/solidity-compiler' +import {Plugin} from '@remixproject/engine' +import {customAction} from '@remixproject/plugin-api' +import { + concatSourceFiles, + getDependencyGraph, + normalizeContractPath +} from '@remix-ui/solidity-compiler' -const _paq = window._paq = window._paq || [] +const _paq = (window._paq = window._paq || []) const profile = { name: 'contractflattener', @@ -11,25 +15,28 @@ const profile = { description: 'Flatten solidity contracts', methods: ['flattenAContract', 'flattenContract'], events: [], - maintainedBy: 'Remix', + maintainedBy: 'Remix' } export class ContractFlattener extends Plugin { - triggerFlattenContract: boolean = false constructor() { super(profile) } onActivation(): void { - this.on('solidity', 'compilationFinished', async (file, source, languageVersion, data, input, version) => { - if(data.sources && Object.keys(data.sources).length > 1) { - if(this.triggerFlattenContract) { - this.triggerFlattenContract = false - await this.flattenContract(source, file, data) + this.on( + 'solidity', + 'compilationFinished', + async (file, source, languageVersion, data, input, version) => { + if (data.sources && Object.keys(data.sources).length > 1) { + if (this.triggerFlattenContract) { + this.triggerFlattenContract = false + await this.flattenContract(source, file, data) + } } } - }) + ) _paq.push(['trackEvent', 'plugin', 'activated', 'contractFlattener']) } @@ -48,8 +55,11 @@ export class ContractFlattener extends Plugin { * Takes the flattened result, writes it to a file and returns the result. * @returns {Promise} */ - async flattenContract (source: { sources: any, target: string }, - filePath: string, data: { contracts: any, sources: any }): Promise { + async flattenContract( + source: {sources: any; target: string}, + filePath: string, + data: {contracts: any; sources: any} + ): Promise { const appendage = '_flattened.sol' const normalized = normalizeContractPath(filePath) const path = `${normalized[normalized.length - 2]}${appendage}` @@ -58,17 +68,17 @@ export class ContractFlattener extends Plugin { let sorted let result let sources - try{ + try { dependencyGraph = getDependencyGraph(ast, filePath) sorted = dependencyGraph.isEmpty() ? [filePath] : dependencyGraph.sort().reverse() sources = source.sources result = concatSourceFiles(sorted, sources) - }catch(err){ + } catch (err) { console.warn(err) } - await this.call('fileManager', 'writeFile', path , result) + await this.call('fileManager', 'writeFile', path, result) _paq.push(['trackEvent', 'plugin', 'contractFlattener', 'flattenAContract']) // clean up memory references & return result sorted = null @@ -76,4 +86,4 @@ export class ContractFlattener extends Plugin { dependencyGraph = null return result } -} \ No newline at end of file +} diff --git a/apps/remix-ide/src/app/plugins/notification.tsx b/apps/remix-ide/src/app/plugins/notification.tsx index 83754e8b38..7d790aaf68 100644 --- a/apps/remix-ide/src/app/plugins/notification.tsx +++ b/apps/remix-ide/src/app/plugins/notification.tsx @@ -1,11 +1,15 @@ -import { Plugin } from '@remixproject/engine' -import { LibraryProfile, MethodApi, StatusEvents } from '@remixproject/plugin-utils' -import { AppModal } from '@remix-ui/app' -import { AlertModal } from '@remix-ui/app' -import { dispatchModalInterface } from '@remix-ui/app' +import {Plugin} from '@remixproject/engine' +import { + LibraryProfile, + MethodApi, + StatusEvents +} from '@remixproject/plugin-utils' +import {AppModal} from '@remix-ui/app' +import {AlertModal} from '@remix-ui/app' +import {dispatchModalInterface} from '@remix-ui/app' interface INotificationApi { - events: StatusEvents, + events: StatusEvents methods: { modal: (args: AppModal) => void alert: (args: AlertModal) => void @@ -13,32 +17,35 @@ interface INotificationApi { } } -const profile:LibraryProfile = { +const profile: LibraryProfile = { name: 'notification', displayName: 'Notification', description: 'Displays notifications', methods: ['modal', 'alert', 'toast'] } -export class NotificationPlugin extends Plugin implements MethodApi { +export class NotificationPlugin + extends Plugin + implements MethodApi +{ dispatcher: dispatchModalInterface - constructor () { + constructor() { super(profile) } - setDispatcher (dispatcher: dispatchModalInterface) { + setDispatcher(dispatcher: dispatchModalInterface) { this.dispatcher = dispatcher } - async modal (args: AppModal) { + async modal(args: AppModal) { return this.dispatcher.modal(args) } - async alert (args: AlertModal) { + async alert(args: AlertModal) { return this.dispatcher.alert(args) } - async toast (message: string | JSX.Element) { + async toast(message: string | JSX.Element) { this.dispatcher.toast(message) } } diff --git a/apps/remix-ide/src/app/plugins/parser/code-parser.tsx b/apps/remix-ide/src/app/plugins/parser/code-parser.tsx index b3e0955ece..f9d46bb7bf 100644 --- a/apps/remix-ide/src/app/plugins/parser/code-parser.tsx +++ b/apps/remix-ide/src/app/plugins/parser/code-parser.tsx @@ -1,63 +1,110 @@ 'use strict' -import { Plugin } from '@remixproject/engine' -import { sourceMappingDecoder } from '@remix-project/remix-debug' -import { CompilerAbstract } from '@remix-project/remix-solidity' -import { CompilationResult } from '@remix-project/remix-solidity' +import {Plugin} from '@remixproject/engine' +import {sourceMappingDecoder} from '@remix-project/remix-debug' +import {CompilerAbstract} from '@remix-project/remix-solidity' +import {CompilationResult} from '@remix-project/remix-solidity' import CodeParserGasService from './services/code-parser-gas-service' import CodeParserCompiler from './services/code-parser-compiler' import CodeParserAntlrService from './services/code-parser-antlr-service' -import CodeParserImports, { CodeParserImportsData } from './services/code-parser-imports' +import CodeParserImports, { + CodeParserImportsData +} from './services/code-parser-imports' import React from 'react' -import { Profile } from '@remixproject/plugin-utils' -import { ContractDefinitionAstNode, EventDefinitionAstNode, FunctionCallAstNode, FunctionDefinitionAstNode, IdentifierAstNode, ImportDirectiveAstNode, ModifierDefinitionAstNode, SourceUnitAstNode, StructDefinitionAstNode, VariableDeclarationAstNode } from '@remix-project/remix-analyzer' -import { lastCompilationResult, RemixApi } from '@remixproject/plugin-api' -import { antlr } from './types' -import { ParseResult } from './types/antlr-types' +import {Profile} from '@remixproject/plugin-utils' +import { + ContractDefinitionAstNode, + EventDefinitionAstNode, + FunctionCallAstNode, + FunctionDefinitionAstNode, + IdentifierAstNode, + ImportDirectiveAstNode, + ModifierDefinitionAstNode, + SourceUnitAstNode, + StructDefinitionAstNode, + VariableDeclarationAstNode +} from '@remix-project/remix-analyzer' +import {lastCompilationResult, RemixApi} from '@remixproject/plugin-api' +import {antlr} from './types' +import {ParseResult} from './types/antlr-types' const profile: Profile = { name: 'codeParser', - methods: ['nodesAtPosition', 'getContractNodes', 'getCurrentFileNodes', 'getLineColumnOfNode', 'getLineColumnOfPosition', 'getFunctionParamaters', 'getDeclaration', 'getFunctionReturnParameters', 'getVariableDeclaration', 'getNodeDocumentation', 'getNodeLink', 'listAstNodes', 'getANTLRBlockAtPosition', 'getLastNodeInLine', 'resolveImports', 'parseSolidity', 'getNodesWithScope', 'getNodesWithName', 'getNodes', 'compile', 'getNodeById', 'getLastCompilationResult', 'positionOfDefinition', 'definitionAtPosition', 'jumpToDefinition', 'referrencesAtPosition', 'referencesOf', 'getActiveHighlights', 'gasEstimation', 'declarationOf', 'getGasEstimates', 'getImports'], + methods: [ + 'nodesAtPosition', + 'getContractNodes', + 'getCurrentFileNodes', + 'getLineColumnOfNode', + 'getLineColumnOfPosition', + 'getFunctionParamaters', + 'getDeclaration', + 'getFunctionReturnParameters', + 'getVariableDeclaration', + 'getNodeDocumentation', + 'getNodeLink', + 'listAstNodes', + 'getANTLRBlockAtPosition', + 'getLastNodeInLine', + 'resolveImports', + 'parseSolidity', + 'getNodesWithScope', + 'getNodesWithName', + 'getNodes', + 'compile', + 'getNodeById', + 'getLastCompilationResult', + 'positionOfDefinition', + 'definitionAtPosition', + 'jumpToDefinition', + 'referrencesAtPosition', + 'referencesOf', + 'getActiveHighlights', + 'gasEstimation', + 'declarationOf', + 'getGasEstimates', + 'getImports' + ], events: [], version: '0.0.1' } export function isNodeDefinition(node: genericASTNode) { - return node.nodeType === 'ContractDefinition' || - node.nodeType === 'FunctionDefinition' || - node.nodeType === 'ModifierDefinition' || - node.nodeType === 'VariableDeclaration' || - node.nodeType === 'StructDefinition' || - node.nodeType === 'EventDefinition' + return ( + node.nodeType === 'ContractDefinition' || + node.nodeType === 'FunctionDefinition' || + node.nodeType === 'ModifierDefinition' || + node.nodeType === 'VariableDeclaration' || + node.nodeType === 'StructDefinition' || + node.nodeType === 'EventDefinition' + ) } export type genericASTNode = - ContractDefinitionAstNode - | FunctionDefinitionAstNode - | ModifierDefinitionAstNode - | VariableDeclarationAstNode - | StructDefinitionAstNode - | EventDefinitionAstNode - | IdentifierAstNode - | FunctionCallAstNode - | ImportDirectiveAstNode - | SourceUnitAstNode + | ContractDefinitionAstNode + | FunctionDefinitionAstNode + | ModifierDefinitionAstNode + | VariableDeclarationAstNode + | StructDefinitionAstNode + | EventDefinitionAstNode + | IdentifierAstNode + | FunctionCallAstNode + | ImportDirectiveAstNode + | SourceUnitAstNode interface flatReferenceIndexNode { - [id: number]: genericASTNode + [id: number]: genericASTNode } interface declarationIndexNode { - [id: number]: genericASTNode[] + [id: number]: genericASTNode[] } interface codeParserIndex { - declarations: declarationIndexNode, - flatReferences: flatReferenceIndexNode, - nodesPerFile: any + declarations: declarationIndexNode + flatReferences: flatReferenceIndexNode + nodesPerFile: any } export class CodeParser extends Plugin { - compilerAbstract: CompilerAbstract currentFile: string nodeIndex: codeParserIndex @@ -80,7 +127,6 @@ export class CodeParser extends Plugin { debuggerIsOn: boolean = false - constructor(astWalker: any) { super(profile) this.astWalker = astWalker @@ -92,31 +138,52 @@ export class CodeParser extends Plugin { } async handleChangeEvents() { - const completionSettings = await this.call('config', 'getAppParameter', 'auto-completion') + const completionSettings = await this.call( + 'config', + 'getAppParameter', + 'auto-completion' + ) if (completionSettings) { this.antlrService.enableWorker() } else { this.antlrService.disableWorker() } - const showGasSettings = await this.call('config', 'getAppParameter', 'show-gas') - const showErrorSettings = await this.call('config', 'getAppParameter', 'display-errors') - if (showGasSettings || showErrorSettings || completionSettings || this.debuggerIsOn) { + const showGasSettings = await this.call( + 'config', + 'getAppParameter', + 'show-gas' + ) + const showErrorSettings = await this.call( + 'config', + 'getAppParameter', + 'display-errors' + ) + if ( + showGasSettings || + showErrorSettings || + completionSettings || + this.debuggerIsOn + ) { await this.compilerService.compile() } } async onActivation() { - this.gasService = new CodeParserGasService(this) this.compilerService = new CodeParserCompiler(this) this.antlrService = new CodeParserAntlrService(this) this.importService = new CodeParserImports(this) this.parseSolidity = this.antlrService.parseSolidity.bind(this.antlrService) - this.getLastNodeInLine = this.antlrService.getLastNodeInLine.bind(this.antlrService) + this.getLastNodeInLine = this.antlrService.getLastNodeInLine.bind( + this.antlrService + ) this.listAstNodes = this.antlrService.listAstNodes.bind(this.antlrService) - this.getANTLRBlockAtPosition = this.antlrService.getANTLRBlockAtPosition.bind(this.antlrService) - this.setCurrentFileAST = this.antlrService.setCurrentFileAST.bind(this.antlrService) + this.getANTLRBlockAtPosition = + this.antlrService.getANTLRBlockAtPosition.bind(this.antlrService) + this.setCurrentFileAST = this.antlrService.setCurrentFileAST.bind( + this.antlrService + ) this.getImports = this.importService.getImports.bind(this.importService) this.on('editor', 'didChangeFile', async (file) => { @@ -138,7 +205,11 @@ export class CodeParser extends Plugin { this.on('fileManager', 'currentFileChanged', async () => { await this.call('editor', 'discardLineTexts') - const completionSettings = await this.call('config', 'getAppParameter', 'auto-completion') + const completionSettings = await this.call( + 'config', + 'getAppParameter', + 'auto-completion' + ) if (completionSettings) { this.antlrService.setCurrentFileAST() } @@ -158,49 +229,53 @@ export class CodeParser extends Plugin { }) await this.compilerService.init() - this.on('solidity', 'compilerLoaded', async () => { + this.on('solidity', 'compilerLoaded', async () => { await this.reload() }) - this.on('debugger', 'startDebugging', async () => { + this.on('debugger', 'startDebugging', async () => { this.debuggerIsOn = true await this.reload() }) - this.on('debugger', 'stopDebugging', async () => { + this.on('debugger', 'stopDebugging', async () => { this.debuggerIsOn = false await this.reload() }) } - async reload(){ + async reload() { await this.call('editor', 'discardLineTexts') await this.call('fileDecorator', 'clearFileDecorators') await this.call('editor', 'clearErrorMarkers', [this.currentFile]) - await this.handleChangeEvents() + await this.handleChangeEvents() } /** - * - * @returns - */ + * + * @returns + */ async getLastCompilationResult() { return this.compilerAbstract } getSubNodes(node: T): number[] { - return node.nodeType == "ContractDefinition" && node.contractDependencies; + return node.nodeType == 'ContractDefinition' && node.contractDependencies } /** - * Builds a flat index and declarations of all the nodes in the compilation result - * @param compilationResult - * @param source - */ + * Builds a flat index and declarations of all the nodes in the compilation result + * @param compilationResult + * @param source + */ _buildIndex(compilationResult: CompilationResult, source) { if (compilationResult && compilationResult.sources) { const callback = (node: genericASTNode) => { - if (node && ("referencedDeclaration" in node) && node.referencedDeclaration) { + if ( + node && + 'referencedDeclaration' in node && + node.referencedDeclaration + ) { if (!this.nodeIndex.declarations[node.referencedDeclaration]) { this.nodeIndex.declarations[node.referencedDeclaration] = [] } @@ -211,9 +286,7 @@ export class CodeParser extends Plugin { for (const s in compilationResult.sources) { this.astWalker.walkFull(compilationResult.sources[s].ast, callback) } - } - } // NODE HELPERS @@ -232,16 +305,32 @@ export class CodeParser extends Plugin { return '(' + params.toString() + ')' } - - _flatNodeList(contractNode: ContractDefinitionAstNode, fileName: string, inScope: boolean, compilatioResult: any) { + _flatNodeList( + contractNode: ContractDefinitionAstNode, + fileName: string, + inScope: boolean, + compilatioResult: any + ) { const index = {} const contractName: string = contractNode.name const callback = (node) => { - if (inScope && node.scope !== contractNode.id - && !(node.nodeType === 'EnumDefinition' || node.nodeType === 'EventDefinition' || node.nodeType === 'ModifierDefinition')) + if ( + inScope && + node.scope !== contractNode.id && + !( + node.nodeType === 'EnumDefinition' || + node.nodeType === 'EventDefinition' || + node.nodeType === 'ModifierDefinition' + ) + ) return - if (inScope) node.isClassNode = true; - node.gasEstimate = this._getContractGasEstimate(node, contractName, fileName, compilatioResult) + if (inScope) node.isClassNode = true + node.gasEstimate = this._getContractGasEstimate( + node, + contractName, + fileName, + compilatioResult + ) node.functionName = node.name + this._getInputParams(node) node.contractName = contractName node.contractId = contractNode.id @@ -251,17 +340,37 @@ export class CodeParser extends Plugin { return index } - _extractFileNodes(fileName: string, compilationResult: lastCompilationResult) { - if (compilationResult && compilationResult.data.sources && compilationResult.data.sources[fileName]) { + _extractFileNodes( + fileName: string, + compilationResult: lastCompilationResult + ) { + if ( + compilationResult && + compilationResult.data.sources && + compilationResult.data.sources[fileName] + ) { const source = compilationResult.data.sources[fileName] const nodesByContract: any = {} nodesByContract.imports = {} nodesByContract.contracts = {} this.astWalker.walkFull(source.ast, async (node) => { if (node.nodeType === 'ContractDefinition') { - const flatNodes = this._flatNodeList(node, fileName, false, compilationResult) - node.gasEstimate = this._getContractGasEstimate(node, node.name, fileName, compilationResult) - nodesByContract.contracts[node.name] = { contractDefinition: node, contractNodes: flatNodes } + const flatNodes = this._flatNodeList( + node, + fileName, + false, + compilationResult + ) + node.gasEstimate = this._getContractGasEstimate( + node, + node.name, + fileName, + compilationResult + ) + nodesByContract.contracts[node.name] = { + contractDefinition: node, + contractNodes: flatNodes + } const baseNodes = {} const baseNodesWithBaseContractScope = {} if (node.linearizedBaseContracts) { @@ -271,11 +380,12 @@ export class CodeParser extends Plugin { const callback = (node) => { node.contractName = (baseContract as any).name node.contractId = (baseContract as any).id - node.isBaseNode = true; + node.isBaseNode = true baseNodes[node.id] = node - if ((node.scope && node.scope === baseContract.id) - || node.nodeType === 'EnumDefinition' - || node.nodeType === 'EventDefinition' + if ( + (node.scope && node.scope === baseContract.id) || + node.nodeType === 'EnumDefinition' || + node.nodeType === 'EventDefinition' ) { baseNodesWithBaseContractScope[node.id] = node } @@ -283,7 +393,7 @@ export class CodeParser extends Plugin { for (const member of node.members) { member.contractName = (baseContract as any).name member.contractId = (baseContract as any).id - member.isBaseNode = true; + member.isBaseNode = true } } } @@ -292,14 +402,15 @@ export class CodeParser extends Plugin { } } nodesByContract.contracts[node.name].baseNodes = baseNodes - nodesByContract.contracts[node.name].baseNodesWithBaseContractScope = baseNodesWithBaseContractScope - nodesByContract.contracts[node.name].contractScopeNodes = this._flatNodeList(node, fileName, true, compilationResult) + nodesByContract.contracts[node.name].baseNodesWithBaseContractScope = + baseNodesWithBaseContractScope + nodesByContract.contracts[node.name].contractScopeNodes = + this._flatNodeList(node, fileName, true, compilationResult) } if (node.nodeType === 'ImportDirective') { - const imported = await this.resolveImports(node, {}) - for (const importedNode of (Object.values(imported) as any)) { + for (const importedNode of Object.values(imported) as any) { if (importedNode.nodes) for (const subNode of importedNode.nodes) { nodesByContract.imports[subNode.id] = subNode @@ -311,9 +422,15 @@ export class CodeParser extends Plugin { } } - _getContractGasEstimate(node: ContractDefinitionAstNode | FunctionDefinitionAstNode, contractName: string, fileName: string, compilationResult: lastCompilationResult) { - - const contracts = compilationResult.data.contracts && compilationResult.data.contracts[this.currentFile] + _getContractGasEstimate( + node: ContractDefinitionAstNode | FunctionDefinitionAstNode, + contractName: string, + fileName: string, + compilationResult: lastCompilationResult + ) { + const contracts = + compilationResult.data.contracts && + compilationResult.data.contracts[this.currentFile] for (const name in contracts) { if (name === contractName) { const contract = contracts[name] @@ -327,15 +444,21 @@ export class CodeParser extends Plugin { const fn = fnName + this._getInputParams(node) if (visibility === 'public' || visibility === 'external') { - executionCost = estimationObj === null ? '-' : estimationObj.external[fn] + executionCost = + estimationObj === null ? '-' : estimationObj.external[fn] } else if (visibility === 'private' || visibility === 'internal') { - executionCost = estimationObj === null ? '-' : estimationObj.internal[fn] + executionCost = + estimationObj === null ? '-' : estimationObj.internal[fn] } - return { executionCost } + return {executionCost} } else { return { - creationCost: estimationObj === null ? '-' : estimationObj.creation.totalCost, - codeDepositCost: estimationObj === null ? '-' : estimationObj.creation.codeDepositCost, + creationCost: + estimationObj === null ? '-' : estimationObj.creation.totalCost, + codeDepositCost: + estimationObj === null + ? '-' + : estimationObj.creation.codeDepositCost } } } @@ -344,31 +467,53 @@ export class CodeParser extends Plugin { } /** - * Nodes at position where position is a number, offset - * @param position - * @param type - * @returns - */ - async nodesAtPosition(position: number, type = ''): Promise { + * Nodes at position where position is a number, offset + * @param position + * @param type + * @returns + */ + async nodesAtPosition( + position: number, + type = '' + ): Promise { let lastCompilationResult = this.compilerAbstract - if(this.debuggerIsOn) { - lastCompilationResult = await this.call('compilerArtefacts', 'get', '__last') + if (this.debuggerIsOn) { + lastCompilationResult = await this.call( + 'compilerArtefacts', + 'get', + '__last' + ) this.currentFile = await this.call('fileManager', 'file') } if (!lastCompilationResult) return [] - const urlFromPath = await this.call('fileManager', 'getUrlFromPath', this.currentFile) - if (lastCompilationResult && lastCompilationResult.languageversion.indexOf('soljson') === 0 && lastCompilationResult.data && lastCompilationResult.data.sources && lastCompilationResult.data.sources[this.currentFile]) { - const nodes: genericASTNode[] = sourceMappingDecoder.nodesAtPosition(type, position, lastCompilationResult.data.sources[this.currentFile] || lastCompilationResult.data.sources[urlFromPath.file]) + const urlFromPath = await this.call( + 'fileManager', + 'getUrlFromPath', + this.currentFile + ) + if ( + lastCompilationResult && + lastCompilationResult.languageversion.indexOf('soljson') === 0 && + lastCompilationResult.data && + lastCompilationResult.data.sources && + lastCompilationResult.data.sources[this.currentFile] + ) { + const nodes: genericASTNode[] = sourceMappingDecoder.nodesAtPosition( + type, + position, + lastCompilationResult.data.sources[this.currentFile] || + lastCompilationResult.data.sources[urlFromPath.file] + ) return nodes } return [] } /** - * - * @param id - * @returns - */ + * + * @param id + * @returns + */ async getNodeById(id: number) { for (const key in this.nodeIndex.flatReferences) { if (this.nodeIndex.flatReferences[key].id === id) { @@ -378,19 +523,20 @@ export class CodeParser extends Plugin { } /** - * - * @param id - * @returns - */ + * + * @param id + * @returns + */ async getDeclaration(id: number) { - if (this.nodeIndex.declarations && this.nodeIndex.declarations[id]) return this.nodeIndex.declarations[id] + if (this.nodeIndex.declarations && this.nodeIndex.declarations[id]) + return this.nodeIndex.declarations[id] } /** - * - * @param scope - * @returns - */ + * + * @param scope + * @returns + */ async getNodesWithScope(scope: number) { const nodes = [] for (const node of Object.values(this.nodeIndex.flatReferences)) { @@ -400,10 +546,10 @@ export class CodeParser extends Plugin { } /** - * - * @param name - * @returns - */ + * + * @param name + * @returns + */ async getNodesWithName(name: string) { const nodes: genericASTNode[] = [] for (const node of Object.values(this.nodeIndex.flatReferences)) { @@ -412,22 +558,22 @@ export class CodeParser extends Plugin { return nodes } /** - * - * @param node - * @returns - */ + * + * @param node + * @returns + */ declarationOf(node: T) { - if (node && ('referencedDeclaration' in node) && node.referencedDeclaration) { + if (node && 'referencedDeclaration' in node && node.referencedDeclaration) { return this.nodeIndex.flatReferences[node.referencedDeclaration] } return null } /** - * - * @param position - * @returns - */ + * + * @param position + * @returns + */ async definitionAtPosition(position: number) { const nodes = await this.nodesAtPosition(position) let nodeDefinition: any @@ -436,7 +582,7 @@ export class CodeParser extends Plugin { node = nodes[nodes.length - 1] nodeDefinition = node if (!isNodeDefinition(node)) { - nodeDefinition = await this.declarationOf(node) || node + nodeDefinition = (await this.declarationOf(node)) || node } if (node.nodeType === 'ImportDirective') { for (const key in this.nodeIndex.flatReferences) { @@ -457,39 +603,49 @@ export class CodeParser extends Plugin { if (!nodeDefinition) nodeDefinition = node } } - if (nodeDefinition && nodeDefinition.type && nodeDefinition.type === 'Identifier') { + if ( + nodeDefinition && + nodeDefinition.type && + nodeDefinition.type === 'Identifier' + ) { const nodeForIdentifier = await this.findIdentifier(nodeDefinition) if (nodeForIdentifier) nodeDefinition = nodeForIdentifier } return nodeDefinition } } - } async getContractNodes(contractName: string) { - if (this.nodeIndex.nodesPerFile - && this.nodeIndex.nodesPerFile[this.currentFile] - && this.nodeIndex.nodesPerFile[this.currentFile].contracts[contractName] - && this.nodeIndex.nodesPerFile[this.currentFile].contracts[contractName].contractNodes) { - return this.nodeIndex.nodesPerFile[this.currentFile].contracts[contractName] + if ( + this.nodeIndex.nodesPerFile && + this.nodeIndex.nodesPerFile[this.currentFile] && + this.nodeIndex.nodesPerFile[this.currentFile].contracts[contractName] && + this.nodeIndex.nodesPerFile[this.currentFile].contracts[contractName] + .contractNodes + ) { + return this.nodeIndex.nodesPerFile[this.currentFile].contracts[ + contractName + ] } return false } async getCurrentFileNodes() { - if (this.nodeIndex.nodesPerFile - && this.nodeIndex.nodesPerFile[this.currentFile]) { + if ( + this.nodeIndex.nodesPerFile && + this.nodeIndex.nodesPerFile[this.currentFile] + ) { return this.nodeIndex.nodesPerFile[this.currentFile] } return false } /** - * - * @param identifierNode - * @returns - */ + * + * @param identifierNode + * @returns + */ async findIdentifier(identifierNode: any) { const astNodes = await this.antlrService.listAstNodes() for (const node of astNodes) { @@ -500,10 +656,10 @@ export class CodeParser extends Plugin { } /** - * - * @param node - * @returns - */ + * + * @param node + * @returns + */ async positionOfDefinition(node: genericASTNode): Promise { if (node) { if (node.src) { @@ -517,11 +673,11 @@ export class CodeParser extends Plugin { } /** - * - * @param node - * @param imported - * @returns - */ + * + * @param node + * @param imported + * @returns + */ async resolveImports(node: any, imported = {}) { if (node.nodeType === 'ImportDirective' && !imported[node.sourceUnit]) { const importNode: any = await this.getNodeById(node.sourceUnit) @@ -535,13 +691,11 @@ export class CodeParser extends Plugin { return imported } - - /** - * - * @param node - * @returns - */ + * + * @param node + * @returns + */ referencesOf(node: genericASTNode) { const results: genericASTNode[] = [] const highlights = (id: number) => { @@ -553,7 +707,7 @@ export class CodeParser extends Plugin { } } } - if (node && ("referencedDeclaration" in node) && node.referencedDeclaration) { + if (node && 'referencedDeclaration' in node && node.referencedDeclaration) { highlights(node.referencedDeclaration) const current = this.nodeIndex.flatReferences[node.referencedDeclaration] results.push(current) @@ -564,10 +718,10 @@ export class CodeParser extends Plugin { } /** - * - * @param position - * @returns - */ + * + * @param position + * @returns + */ async referrencesAtPosition(position: any): Promise { const nodes = await this.nodesAtPosition(position) if (nodes && nodes.length) { @@ -579,59 +733,68 @@ export class CodeParser extends Plugin { } /** - * - * @returns - */ + * + * @returns + */ async getNodes(): Promise { return this.nodeIndex.flatReferences } - - /** - * - * @param node - * @returns - */ + * + * @param node + * @returns + */ async getNodeLink(node: genericASTNode) { const lineColumn = await this.getLineColumnOfNode(node) const position = await this.positionOfDefinition(node) if (this.compilerAbstract && this.compilerAbstract.source && position) { const fileName = this.compilerAbstract.getSourceName(position.file) - return lineColumn ? `${fileName} ${lineColumn.start.line}:${lineColumn.start.column}` : null + return lineColumn + ? `${fileName} ${lineColumn.start.line}:${lineColumn.start.column}` + : null } return '' } /* - * @param node - */ + * @param node + */ async getLineColumnOfNode(node: any) { const position = await this.positionOfDefinition(node) return this.getLineColumnOfPosition(position) } /* - * @param position - */ + * @param position + */ async getLineColumnOfPosition(position: any) { if (position) { const fileName = this.compilerAbstract.getSourceName(position.file) - const lineBreaks = sourceMappingDecoder.getLinebreakPositions(this.compilerAbstract.source.sources[fileName].content) - const lineColumn = sourceMappingDecoder.convertOffsetToLineColumn(position, lineBreaks) + const lineBreaks = sourceMappingDecoder.getLinebreakPositions( + this.compilerAbstract.source.sources[fileName].content + ) + const lineColumn = sourceMappingDecoder.convertOffsetToLineColumn( + position, + lineBreaks + ) return lineColumn } } /** - * - * @param node - * @returns - */ + * + * @param node + * @returns + */ async getNodeDocumentation(node: genericASTNode) { - if (("documentation" in node) && node.documentation && (node.documentation as any).text) { - let text = ''; - (node.documentation as any).text.split('\n').forEach(line => { + if ( + 'documentation' in node && + node.documentation && + (node.documentation as any).text + ) { + let text = '' + ;(node.documentation as any).text.split('\n').forEach((line) => { text += `${line.trim()}\n` }) return text @@ -639,35 +802,35 @@ export class CodeParser extends Plugin { } /** - * - * @param node - * @returns - */ + * + * @param node + * @returns + */ async getVariableDeclaration(node: any) { - const nodeVisibility = node.visibility && node.visibility.length ? node.visibility + ' ' : '' + const nodeVisibility = + node.visibility && node.visibility.length ? node.visibility + ' ' : '' const nodeName = node.name && node.name.length ? node.name : '' if (node.typeDescriptions && node.typeDescriptions.typeString) { return `${node.typeDescriptions.typeString} ${nodeVisibility}${nodeName}` } else { if (node.typeName && node.typeName.name) { return `${node.typeName.name} ${nodeVisibility}${nodeName}` - } - else if (node.typeName && node.typeName.namePath) { + } else if (node.typeName && node.typeName.namePath) { return `${node.typeName.namePath} ${nodeVisibility}${nodeName}` - } - else { + } else { return `${nodeName}${nodeName}` } } } /** - * - * @param node - * @returns - */ + * + * @param node + * @returns + */ async getFunctionParamaters(node: any) { - const localParam = (node.parameters && node.parameters.parameters) || (node.parameters) + const localParam = + (node.parameters && node.parameters.parameters) || node.parameters if (localParam) { const params = [] for (const param of localParam) { @@ -678,12 +841,12 @@ export class CodeParser extends Plugin { } /** - * - * @param node - * @returns - */ + * + * @param node + * @returns + */ async getFunctionReturnParameters(node: any) { - const localParam = (node.returnParameters && node.returnParameters.parameters) + const localParam = node.returnParameters && node.returnParameters.parameters if (localParam) { const params = [] for (const param of localParam) { @@ -692,7 +855,4 @@ export class CodeParser extends Plugin { return `(${params.join(', ')})` } } - - - } diff --git a/apps/remix-ide/src/app/plugins/permission-handler-plugin.tsx b/apps/remix-ide/src/app/plugins/permission-handler-plugin.tsx index c89b087eed..169388d16a 100644 --- a/apps/remix-ide/src/app/plugins/permission-handler-plugin.tsx +++ b/apps/remix-ide/src/app/plugins/permission-handler-plugin.tsx @@ -1,9 +1,12 @@ import React from 'react' // eslint-disable-line -import { FormattedMessage } from 'react-intl' -import { Plugin } from '@remixproject/engine' -import { AppModal } from '@remix-ui/app' -import { PermissionHandlerDialog, PermissionHandlerValue } from '@remix-ui/permission-handler' -import { Profile } from '@remixproject/plugin-utils' +import {FormattedMessage} from 'react-intl' +import {Plugin} from '@remixproject/engine' +import {AppModal} from '@remix-ui/app' +import { + PermissionHandlerDialog, + PermissionHandlerValue +} from '@remix-ui/permission-handler' +import {Profile} from '@remixproject/plugin-utils' const profile = { name: 'permissionhandler', @@ -46,16 +49,22 @@ export class PermissionHandlerPlugin extends Plugin { } } - switchMode (from: Profile, to: Profile, method: string, set: boolean, sensitiveCall: boolean) { + switchMode( + from: Profile, + to: Profile, + method: string, + set: boolean, + sensitiveCall: boolean + ) { if (sensitiveCall) { set - ? this.sessionPermissions[to.name][method][from.name] = {} + ? (this.sessionPermissions[to.name][method][from.name] = {}) : delete this.sessionPermissions[to.name][method][from.name] } else { set - ? this.permissions[to.name][method][from.name] = {} + ? (this.permissions[to.name][method][from.name] = {}) : delete this.permissions[to.name][method][from.name] - } + } } clear() { @@ -65,7 +74,9 @@ export class PermissionHandlerPlugin extends Plugin { } notAllowWarning(from: Profile, to: Profile, method: string) { - return `${from.displayName || from.name} is not allowed to call ${method} method of ${to.displayName || to.name}.` + return `${ + from.displayName || from.name + } is not allowed to call ${method} method of ${to.displayName || to.name}.` } async getTheme() { @@ -80,20 +91,33 @@ export class PermissionHandlerPlugin extends Plugin { * @param {string} message from the caller plugin to add more details if needed * @returns {Promise} */ - async askPermission(from: Profile, to: Profile, method: string, message: string, sensitiveCall: boolean) { + async askPermission( + from: Profile, + to: Profile, + method: string, + message: string, + sensitiveCall: boolean + ) { try { if (sensitiveCall) { - if (!this.sessionPermissions[to.name]) this.sessionPermissions[to.name] = {} - if (!this.sessionPermissions[to.name][method]) this.sessionPermissions[to.name][method] = {} - if (!this.sessionPermissions[to.name][method][from.name]) return this.openPermission(from, to, method, message, sensitiveCall) + if (!this.sessionPermissions[to.name]) + this.sessionPermissions[to.name] = {} + if (!this.sessionPermissions[to.name][method]) + this.sessionPermissions[to.name][method] = {} + if (!this.sessionPermissions[to.name][method][from.name]) + return this.openPermission(from, to, method, message, sensitiveCall) } else { this.permissions = this._getFromLocal() if (!this.permissions[to.name]) this.permissions[to.name] = {} - if (!this.permissions[to.name][method]) this.permissions[to.name][method] = {} - if (!this.permissions[to.name][method][from.name]) return this.openPermission(from, to, method, message, sensitiveCall) + if (!this.permissions[to.name][method]) + this.permissions[to.name][method] = {} + if (!this.permissions[to.name][method][from.name]) + return this.openPermission(from, to, method, message, sensitiveCall) } - const { allow, hash } = sensitiveCall ? this.sessionPermissions[to.name][method][from.name] : this.permissions[to.name][method][from.name] + const {allow, hash} = sensitiveCall + ? this.sessionPermissions[to.name][method][from.name] + : this.permissions[to.name][method][from.name] if (!allow) { const warning = this.notAllowWarning(from, to, method) this.call('notification', 'toast', warning) @@ -107,7 +131,13 @@ export class PermissionHandlerPlugin extends Plugin { } } - async openPermission(from: Profile, to: Profile, method: string, message: string, sensitiveCall: boolean) { + async openPermission( + from: Profile, + to: Profile, + method: string, + message: string, + sensitiveCall: boolean + ) { let remember if (sensitiveCall) { remember = this.sessionPermissions[to.name][method][from.name] @@ -124,10 +154,21 @@ export class PermissionHandlerPlugin extends Plugin { } const modal: AppModal = { id: 'PermissionHandler', - title: , - message: , - okLabel: , - cancelLabel: + title: ( + + ), + message: ( + + ), + okLabel: , + cancelLabel: } const result = await this.call('notification', 'modal', modal) @@ -166,7 +207,7 @@ export class PermissionHandlerPlugin extends Plugin { } this.persistPermissions() } - } + } reject(this.notAllowWarning(from, to, method)) } }) diff --git a/apps/remix-ide/src/app/plugins/remixd-handle.tsx b/apps/remix-ide/src/app/plugins/remixd-handle.tsx index a39c52c3d3..33d289b0a7 100644 --- a/apps/remix-ide/src/app/plugins/remixd-handle.tsx +++ b/apps/remix-ide/src/app/plugins/remixd-handle.tsx @@ -1,12 +1,12 @@ /* eslint-disable no-unused-vars */ -import React, { useRef, useState, useEffect } from 'react' // eslint-disable-line +import React, {useRef, useState, useEffect} from 'react' // eslint-disable-line import isElectron from 'is-electron' -import { WebsocketPlugin } from '@remixproject/engine-web' +import {WebsocketPlugin} from '@remixproject/engine-web' import * as packageJson from '../../../../../package.json' // eslint-disable-next-line @nrwl/nx/enforce-module-boundaries -import { version as remixdVersion } from '../../../../../libs/remixd/package.json' -import { PluginManager } from '@remixproject/engine' -import { AppModal, AlertModal } from '@remix-ui/app' +import {version as remixdVersion} from '../../../../../libs/remixd/package.json' +import {PluginManager} from '@remixproject/engine' +import {AppModal, AlertModal} from '@remix-ui/app' const LOCALHOST = ' - connect to localhost - ' @@ -14,15 +14,27 @@ const profile = { name: 'remixd', displayName: 'RemixD', url: 'ws://127.0.0.1:65520', - methods: ['folderIsReadOnly', 'resolveDirectory', 'get', 'exists', 'isFile', 'set', 'rename', 'remove', 'isDirectory', 'list', 'createDir'], + methods: [ + 'folderIsReadOnly', + 'resolveDirectory', + 'get', + 'exists', + 'isFile', + 'set', + 'rename', + 'remove', + 'isDirectory', + 'list', + 'createDir' + ], events: [], description: 'Using Remixd daemon, allow to access file system', kind: 'other', version: packageJson.version, - repo: "https://github.com/ethereum/remix-project/tree/master/libs/remixd", - maintainedBy: "Remix", - documentation: "https://remix-ide.readthedocs.io/en/latest/remixd.html", - authorContact: "" + repo: 'https://github.com/ethereum/remix-project/tree/master/libs/remixd', + maintainedBy: 'Remix', + documentation: 'https://remix-ide.readthedocs.io/en/latest/remixd.html', + authorContact: '' } export class RemixdHandle extends WebsocketPlugin { @@ -62,7 +74,6 @@ export class RemixdHandle extends WebsocketPlugin { } await this.appManager.deactivatePlugin('remixd') - } async callPluginMethod(key: string, payload?: any[]) { @@ -74,36 +85,44 @@ export class RemixdHandle extends WebsocketPlugin { } /** - * connect to localhost if no connection and render the explorer - * disconnect from localhost if connected and remove the explorer - * - * @param {String} txHash - hash of the transaction - */ + * connect to localhost if no connection and render the explorer + * disconnect from localhost if connected and remove the explorer + * + * @param {String} txHash - hash of the transaction + */ async connectToLocalhost() { const connection = async (error?: any) => { if (error) { console.log(error) const alert: AlertModal = { id: 'connectionAlert', - message: 'Cannot connect to the remixd daemon. Please make sure you have the remixd running in the background.' + message: + 'Cannot connect to the remixd daemon. Please make sure you have the remixd running in the background.' } this.call('notification', 'alert', alert) this.canceled() } else { const intervalId = setInterval(() => { - if (!this.socket || (this.socket && this.socket.readyState === 3)) { // 3 means connection closed + if (!this.socket || (this.socket && this.socket.readyState === 3)) { + // 3 means connection closed clearInterval(intervalId) const alert: AlertModal = { id: 'connectionAlert', - message: 'Connection to remixd terminated. Please make sure remixd is still running in the background.' + message: + 'Connection to remixd terminated. Please make sure remixd is still running in the background.' } this.call('notification', 'alert', alert) this.canceled() } }, 3000) this.localhostProvider.init(() => { - this.call('filePanel', 'setWorkspace', { name: LOCALHOST, isLocalhost: true }, true) - }); + this.call( + 'filePanel', + 'setWorkspace', + {name: LOCALHOST, isLocalhost: true}, + true + ) + }) for (const plugin of this.dependentPlugins) { await this.appManager.activatePlugin(plugin) } @@ -118,7 +137,7 @@ export class RemixdHandle extends WebsocketPlugin { title: 'Access file system using remixd', message: remixdDialog(), okLabel: 'Connect', - cancelLabel: 'Cancel', + cancelLabel: 'Cancel' } const result = await this.call('notification', 'modal', mod) if (result) { @@ -126,7 +145,8 @@ export class RemixdHandle extends WebsocketPlugin { this.localhostProvider.preInit() super.activate() setTimeout(() => { - if (!this.socket || (this.socket && this.socket.readyState === 3)) { // 3 means connection closed + if (!this.socket || (this.socket && this.socket.readyState === 3)) { + // 3 means connection closed connection(new Error('Connection with daemon failed.')) } else { connection() @@ -135,14 +155,15 @@ export class RemixdHandle extends WebsocketPlugin { } catch (error) { connection(error) } - } - else { + } else { await this.canceled() } } else { try { super.activate() - setTimeout(() => { connection() }, 2000) + setTimeout(() => { + connection() + }, 2000) } catch (error) { connection(error) } @@ -152,38 +173,73 @@ export class RemixdHandle extends WebsocketPlugin { function remixdDialog() { const commandText = 'remixd' - const fullCommandText = 'remixd -s -u ' - return (<> -
-
- Access your local file system from Remix IDE using Remixd NPM package. -
-
-
- The remixd command is: -
{commandText} -
-
- The remixd command without options uses the terminal's current directory as the shared directory and the shared Remix domain can only be https://remix.ethereum.org, https://remix-alpha.ethereum.org, or https://remix-beta.ethereum.org -
-
- Example command with flags:
- {fullCommandText} -
-
- For info about ports, see Remixd ports usage -
-
- This feature is still in Alpha. We recommend to keep a backup of the shared folder. -
-
-
- Before using, make sure remixd version is latest i.e. v{remixdVersion} -

Read here how to update it -
+ const fullCommandText = + 'remixd -s -u ' + return ( + <> +
+
+ Access your local file system from Remix IDE using{' '} + + Remixd NPM package + + . +
+
+ Remixd{' '} + + documentation + + . +
+
+ The remixd command is: +
+ {commandText} +
+
+ The remixd command without options uses the terminal's current + directory as the shared directory and the shared Remix domain can only + be https://remix.ethereum.org, https://remix-alpha.ethereum.org, or + https://remix-beta.ethereum.org +
+
+ Example command with flags:
+ {fullCommandText} +
+
+ For info about ports, see{' '} + + Remixd ports usage + +
+
+ This feature is still in Alpha. We recommend to keep a backup of the + shared folder. +
+
+
+ Before using, make sure remixd version is latest i.e.{' '} + v{remixdVersion} +

+ + Read here how to update it + +
+
-
- ) + + ) } diff --git a/apps/remix-ide/src/app/plugins/solidity-script.tsx b/apps/remix-ide/src/app/plugins/solidity-script.tsx index 88c3b1e962..dccc59c6c5 100644 --- a/apps/remix-ide/src/app/plugins/solidity-script.tsx +++ b/apps/remix-ide/src/app/plugins/solidity-script.tsx @@ -1,9 +1,9 @@ import React from 'react' // eslint-disable-line -import { format } from 'util' -import { Plugin } from '@remixproject/engine' -import { compile } from '@remix-project/remix-solidity' -import { TransactionConfig } from 'web3-core' -const _paq = window._paq = window._paq || [] //eslint-disable-line +import {format} from 'util' +import {Plugin} from '@remixproject/engine' +import {compile} from '@remix-project/remix-solidity' +import {TransactionConfig} from 'web3-core' +const _paq = (window._paq = window._paq || []) //eslint-disable-line const profile = { name: 'solidity-script', @@ -13,17 +13,20 @@ const profile = { } export class SolidityScript extends Plugin { - constructor () { + constructor() { super(profile) } - async execute (path: string, functionName: string = 'run') { + async execute(path: string, functionName: string = 'run') { _paq.push(['trackEvent', 'SolidityScript', 'execute', 'script']) - this.call('terminal', 'log', `Running free function '${functionName}' from ${path}...`) + this.call( + 'terminal', + 'log', + `Running free function '${functionName}' from ${path}...` + ) let content = await this.call('fileManager', 'readFile', path) const params = await this.call('solidity', 'getCompilerParameters') - content = ` // SPDX-License-Identifier: GPL-3.0 @@ -38,13 +41,15 @@ export class SolidityScript extends Plugin { ${functionName}(); } }` - const targets = { 'script.sol': { content } } + const targets = {'script.sol': {content}} // compile const compilation = await compile(targets, params, async (url, cb) => { - await this.call('contentImport', 'resolveAndSave', url).then((result) => cb(null, result)).catch((error) => cb(error.message)) + await this.call('contentImport', 'resolveAndSave', url) + .then((result) => cb(null, result)) + .catch((error) => cb(error.message)) }) - + if (compilation.data.error) { this.call('terminal', 'log', compilation.data.error.formattedMessage) } @@ -53,7 +58,7 @@ export class SolidityScript extends Plugin { this.call('terminal', 'log', error.formattedMessage) }) } - + // get the contract const contract = compilation.getContract('SolidityScript') if (!contract) { @@ -83,24 +88,31 @@ export class SolidityScript extends Plugin { const hhlogs = await web3.eth.getHHLogsForTx(receiptCall.transactionHash) if (hhlogs && hhlogs.length) { - const finalLogs =
console.log:
- { - hhlogs.map((log) => { + const finalLogs = ( +
+
+ console.log: +
+ {hhlogs.map((log) => { let formattedLog // Hardhat implements the same formatting options that can be found in Node.js' console.log, // which in turn uses util.format: https://nodejs.org/dist/latest-v12.x/docs/api/util.html#util_util_format_format_args // For example: console.log("Name: %s, Age: %d", remix, 6) will log 'Name: remix, Age: 6' // We check first arg to determine if 'util.format' is needed - if (typeof log[0] === 'string' && (log[0].includes('%s') || log[0].includes('%d'))) { + if ( + typeof log[0] === 'string' && + (log[0].includes('%s') || log[0].includes('%d')) + ) { formattedLog = format(log[0], ...log.slice(1)) } else { formattedLog = log.join(' ') } return
{formattedLog}
})} -
+
+ ) _paq.push(['trackEvent', 'udapp', 'hardhat', 'console.log']) this.call('terminal', 'logHtml', finalLogs) } - } + } } diff --git a/apps/remix-ide/src/app/plugins/solidity-umlgen.tsx b/apps/remix-ide/src/app/plugins/solidity-umlgen.tsx index 11ab06ddeb..fc19289c4a 100644 --- a/apps/remix-ide/src/app/plugins/solidity-umlgen.tsx +++ b/apps/remix-ide/src/app/plugins/solidity-umlgen.tsx @@ -1,27 +1,32 @@ /* eslint-disable @nrwl/nx/enforce-module-boundaries */ -import { ViewPlugin } from '@remixproject/engine-web' +import {ViewPlugin} from '@remixproject/engine-web' import React from 'react' // eslint-disable-next-line @nrwl/nx/enforce-module-boundaries -import { RemixUiSolidityUmlGen } from '@remix-ui/solidity-uml-gen' -import { ISolidityUmlGen, ThemeQualityType, ThemeSummary } from 'libs/remix-ui/solidity-uml-gen/src/types' -import { RemixAppManager } from 'libs/remix-ui/plugin-manager/src/types' -import { normalizeContractPath } from 'libs/remix-ui/solidity-compiler/src/lib/logic/flattenerUtilities' -import { convertAST2UmlClasses } from 'sol2uml/lib/converterAST2Classes' +import {RemixUiSolidityUmlGen} from '@remix-ui/solidity-uml-gen' +import { + ISolidityUmlGen, + ThemeQualityType, + ThemeSummary +} from 'libs/remix-ui/solidity-uml-gen/src/types' +import {RemixAppManager} from 'libs/remix-ui/plugin-manager/src/types' +import {normalizeContractPath} from 'libs/remix-ui/solidity-compiler/src/lib/logic/flattenerUtilities' +import {convertAST2UmlClasses} from 'sol2uml/lib/converterAST2Classes' import vizRenderStringSync from '@aduh95/viz.js/sync' -import { PluginViewWrapper } from '@remix-ui/helper' -import { customAction } from '@remixproject/plugin-api' -import { ClassOptions } from 'sol2uml/lib/converterClass2Dot' +import {PluginViewWrapper} from '@remix-ui/helper' +import {customAction} from '@remixproject/plugin-api' +import {ClassOptions} from 'sol2uml/lib/converterClass2Dot' const parser = (window as any).SolidityParser -const _paq = window._paq = window._paq || [] +const _paq = (window._paq = window._paq || []) const profile = { name: 'solidityumlgen', displayName: 'Solidity UML Generator', - description: 'Generates UML diagram in svg format from last compiled contract', + description: + 'Generates UML diagram in svg format from last compiled contract', location: 'mainPanel', methods: ['showUmlDiagram', 'generateUml', 'generateCustomAction'], - events: [], + events: [] } /** @@ -54,7 +59,6 @@ export class SolidityUmlGen extends ViewPlugin implements ISolidityUmlGen { this.currentlySelectedTheme = '' this.themeName = '' - this.activeTheme = {} as ThemeSummary this.appManager = appManager this.element = document.createElement('div') @@ -63,37 +67,54 @@ export class SolidityUmlGen extends ViewPlugin implements ISolidityUmlGen { onActivation(): void { this.handleThemeChange() - this.on('solidity', 'compilationFinished', async (file: string, source, languageVersion, data, input, version) => { - if(!this.triggerGenerateUml) return - this.triggerGenerateUml = false - const currentTheme: ThemeQualityType = await this.call('theme', 'currentTheme') - this.currentlySelectedTheme = currentTheme.quality - this.themeName = currentTheme.name - let result = '' - const normalized = normalizeContractPath(file) - this.currentFile = normalized[normalized.length - 1] - try { - if (data.sources && Object.keys(data.sources).length > 1) { // we should flatten first as there are multiple asts - result = await this.flattenContract(source, file, data) + this.on( + 'solidity', + 'compilationFinished', + async (file: string, source, languageVersion, data, input, version) => { + if (!this.triggerGenerateUml) return + this.triggerGenerateUml = false + const currentTheme: ThemeQualityType = await this.call( + 'theme', + 'currentTheme' + ) + this.currentlySelectedTheme = currentTheme.quality + this.themeName = currentTheme.name + let result = '' + const normalized = normalizeContractPath(file) + this.currentFile = normalized[normalized.length - 1] + try { + if (data.sources && Object.keys(data.sources).length > 1) { + // we should flatten first as there are multiple asts + result = await this.flattenContract(source, file, data) + } + const ast = + result.length > 1 + ? parser.parse(result) + : parser.parse(source.sources[file].content) + this.umlClasses = convertAST2UmlClasses(ast, this.currentFile) + let umlDot = '' + this.activeTheme = await this.call('theme', 'currentTheme') + umlDot = convertUmlClasses2Dot(this.umlClasses, false, { + backColor: this.activeTheme.backgroundColor, + textColor: this.activeTheme.textColor, + shapeColor: this.activeTheme.shapeColor, + fillColor: this.activeTheme.fillColor + }) + const payload = vizRenderStringSync(umlDot) + this.updatedSvg = payload + _paq.push(['trackEvent', 'solidityumlgen', 'umlgenerated']) + this.renderComponent() + await this.call('tabs', 'focus', 'solidityumlgen') + } catch (error) { + console.log('error', error) } - const ast = result.length > 1 ? parser.parse(result) : parser.parse(source.sources[file].content) - this.umlClasses = convertAST2UmlClasses(ast, this.currentFile) - let umlDot = '' - this.activeTheme = await this.call('theme', 'currentTheme') - umlDot = convertUmlClasses2Dot(this.umlClasses, false, { backColor: this.activeTheme.backgroundColor, textColor: this.activeTheme.textColor, shapeColor: this.activeTheme.shapeColor, fillColor: this.activeTheme.fillColor }) - const payload = vizRenderStringSync(umlDot) - this.updatedSvg = payload - _paq.push(['trackEvent', 'solidityumlgen', 'umlgenerated']) - this.renderComponent() - await this.call('tabs', 'focus', 'solidityumlgen') - } catch (error) { - console.log('error', error) } - }) + ) } getThemeCssVariables(cssVars: string) { - return window.getComputedStyle(document.documentElement) + return window + .getComputedStyle(document.documentElement) .getPropertyValue(cssVars) } @@ -102,7 +123,12 @@ export class SolidityUmlGen extends ViewPlugin implements ISolidityUmlGen { this.currentlySelectedTheme = theme.quality this.activeTheme = theme this.themeDark = theme.backgroundColor - const umlDot = convertUmlClasses2Dot(this.umlClasses, false, { backColor: this.activeTheme.backgroundColor, textColor: this.activeTheme.textColor, shapeColor: this.activeTheme.shapeColor, fillColor: this.activeTheme.fillColor }) + const umlDot = convertUmlClasses2Dot(this.umlClasses, false, { + backColor: this.activeTheme.backgroundColor, + textColor: this.activeTheme.textColor, + shapeColor: this.activeTheme.shapeColor, + fillColor: this.activeTheme.fillColor + }) this.updatedSvg = vizRenderStringSync(umlDot) this.renderComponent() await this.call('tabs', 'focus', 'solidityumlgen') @@ -133,13 +159,17 @@ export class SolidityUmlGen extends ViewPlugin implements ISolidityUmlGen { * and assigns to a local property * @returns {Promise} */ - async flattenContract (source: any, filePath: string, data: any) { - const result = await this.call('contractflattener', 'flattenContract', source, filePath, data) + async flattenContract(source: any, filePath: string, data: any) { + const result = await this.call( + 'contractflattener', + 'flattenContract', + source, + filePath, + data + ) return result } - - async showUmlDiagram(svgPayload: string) { this.updatedSvg = svgPayload this.renderComponent() @@ -150,18 +180,20 @@ export class SolidityUmlGen extends ViewPlugin implements ISolidityUmlGen { this.renderComponent() } - setDispatch (dispatch: React.Dispatch) { + setDispatch(dispatch: React.Dispatch) { this.dispatch = dispatch this.renderComponent() } render() { - return
- -
+ return ( +
+ +
+ ) } - renderComponent () { + renderComponent() { this.dispatch({ ...this, updatedSvg: this.updatedSvg, @@ -171,24 +203,25 @@ export class SolidityUmlGen extends ViewPlugin implements ISolidityUmlGen { themeDark: this.themeDark, fileName: this.currentFile, themeCollection: this.themeCollection, - activeTheme: this.activeTheme, + activeTheme: this.activeTheme }) } updateComponent(state: any) { - return + return ( + + ) } } - interface Sol2umlClassOptions extends ClassOptions { backColor?: string shapeColor?: string @@ -196,15 +229,15 @@ interface Sol2umlClassOptions extends ClassOptions { textColor?: string } -import { dirname } from 'path' -import { convertClass2Dot } from 'sol2uml/lib/converterClass2Dot' +import {dirname} from 'path' +import {convertClass2Dot} from 'sol2uml/lib/converterClass2Dot' import { Association, ClassStereotype, ReferenceType, - UmlClass, + UmlClass } from 'sol2uml/lib/umlClass' -import { findAssociatedClass } from 'sol2uml/lib/associations' +import {findAssociatedClass} from 'sol2uml/lib/associations' // const debug = require('debug')('sol2uml') @@ -347,20 +380,20 @@ function addAssociationToDot( // Or associations to Structs, Enums or Constants if they are hidden if ( (classOptions.hideLibraries && - (sourceUmlClass.stereotype === ClassStereotype.Library || - targetUmlClass.stereotype === ClassStereotype.Library)) || - (classOptions.hideInterfaces && - (targetUmlClass.stereotype === ClassStereotype.Interface || - sourceUmlClass.stereotype === ClassStereotype.Interface)) || - (classOptions.hideAbstracts && - (targetUmlClass.stereotype === ClassStereotype.Abstract || - sourceUmlClass.stereotype === ClassStereotype.Abstract)) || - (classOptions.hideStructs && - targetUmlClass.stereotype === ClassStereotype.Struct) || - (classOptions.hideEnums && - targetUmlClass.stereotype === ClassStereotype.Enum) || - (classOptions.hideConstants && - targetUmlClass.stereotype === ClassStereotype.Constant) + (sourceUmlClass.stereotype === ClassStereotype.Library || + targetUmlClass.stereotype === ClassStereotype.Library)) || + (classOptions.hideInterfaces && + (targetUmlClass.stereotype === ClassStereotype.Interface || + sourceUmlClass.stereotype === ClassStereotype.Interface)) || + (classOptions.hideAbstracts && + (targetUmlClass.stereotype === ClassStereotype.Abstract || + sourceUmlClass.stereotype === ClassStereotype.Abstract)) || + (classOptions.hideStructs && + targetUmlClass.stereotype === ClassStereotype.Struct) || + (classOptions.hideEnums && + targetUmlClass.stereotype === ClassStereotype.Enum) || + (classOptions.hideConstants && + targetUmlClass.stereotype === ClassStereotype.Constant) ) { return '' } @@ -369,8 +402,8 @@ function addAssociationToDot( if ( association.referenceType == ReferenceType.Memory || - (association.realization && - targetUmlClass.stereotype === ClassStereotype.Interface) + (association.realization && + targetUmlClass.stereotype === ClassStereotype.Interface) ) { dotString += 'style=dashed, ' } diff --git a/apps/remix-ide/src/app/providers/abstract-provider.tsx b/apps/remix-ide/src/app/providers/abstract-provider.tsx index 5d9df384c3..4b4272ee89 100644 --- a/apps/remix-ide/src/app/providers/abstract-provider.tsx +++ b/apps/remix-ide/src/app/providers/abstract-provider.tsx @@ -1,30 +1,30 @@ -import { Plugin } from '@remixproject/engine' -import { AppModal, AlertModal, ModalTypes } from '@remix-ui/app' -import { Blockchain } from '../../blockchain/blockchain' -import { ethers } from 'ethers' +import {Plugin} from '@remixproject/engine' +import {AppModal, AlertModal, ModalTypes} from '@remix-ui/app' +import {Blockchain} from '../../blockchain/blockchain' +import {ethers} from 'ethers' export type JsonDataRequest = { - id: number, + id: number jsonrpc: string // version - method: string, - params: Array, + method: string + params: Array } export type JsonDataResult = { - id: number, + id: number jsonrpc: string // version - result?: any, - error?: any, + result?: any + error?: any } export type RejectRequest = (error: Error) => void export type SuccessRequest = (data: JsonDataResult) => void export interface IProvider { - options: { [id: string] : any } - init(): Promise<{ [id: string] : any }> + options: {[id: string]: any} + init(): Promise<{[id: string]: any}> body(): JSX.Element - sendAsync (data: JsonDataRequest): Promise + sendAsync(data: JsonDataRequest): Promise } export abstract class AbstractProvider extends Plugin implements IProvider { @@ -33,9 +33,9 @@ export abstract class AbstractProvider extends Plugin implements IProvider { defaultUrl: string connected: boolean nodeUrl: string - options: { [id: string] : any } = {} + options: {[id: string]: any} = {} - constructor (profile, blockchain, defaultUrl) { + constructor(profile, blockchain, defaultUrl) { super(profile) this.defaultUrl = defaultUrl this.provider = null @@ -46,11 +46,11 @@ export abstract class AbstractProvider extends Plugin implements IProvider { abstract body(): JSX.Element - onDeactivation () { + onDeactivation() { this.provider = null } - async init () { + async init() { this.nodeUrl = await ((): Promise => { return new Promise((resolve, reject) => { const modalContent: AppModal = { @@ -61,16 +61,17 @@ export abstract class AbstractProvider extends Plugin implements IProvider { okLabel: 'OK', cancelLabel: 'Cancel', validationFn: (value) => { - if (!value) return { valid: false, message: "value is empty" } + if (!value) return {valid: false, message: 'value is empty'} if (value.startsWith('https://') || value.startsWith('http://')) { - return { - valid: true, + return { + valid: true, message: '' } } else { return { - valid: false, - message: 'the provided value should contain the protocol ( e.g starts with http:// or https:// )' + valid: false, + message: + 'the provided value should contain the protocol ( e.g starts with http:// or https:// )' } } }, @@ -94,7 +95,7 @@ export abstract class AbstractProvider extends Plugin implements IProvider { } } - sendAsync (data: JsonDataRequest): Promise { + sendAsync(data: JsonDataRequest): Promise { // eslint-disable-next-line no-async-promise-executor return new Promise(async (resolve, reject) => { if (!this.provider) return reject(new Error('provider node set')) @@ -102,7 +103,7 @@ export abstract class AbstractProvider extends Plugin implements IProvider { }) } - private async switchAway (showError) { + private async switchAway(showError) { if (!this.provider) return this.provider = null this.connected = false @@ -110,28 +111,37 @@ export abstract class AbstractProvider extends Plugin implements IProvider { const modalContent: AlertModal = { id: this.profile.name, title: this.profile.displayName, - message: `Error while connecting to the provider, provider not connected`, + message: `Error while connecting to the provider, provider not connected` } this.call('notification', 'alert', modalContent) } - await this.call('udapp', 'setEnvironmentMode', { context: 'vm-merge'}) + await this.call('udapp', 'setEnvironmentMode', {context: 'vm-merge'}) return } - private async sendAsyncInternal (data: JsonDataRequest, resolve: SuccessRequest, reject: RejectRequest): Promise { + private async sendAsyncInternal( + data: JsonDataRequest, + resolve: SuccessRequest, + reject: RejectRequest + ): Promise { if (this.provider) { try { const result = await this.provider.send(data.method, data.params) - resolve({ jsonrpc: '2.0', result, id: data.id }) + resolve({jsonrpc: '2.0', result, id: data.id}) } catch (error) { - if (error && error.message && error.message.includes('net_version') && error.message.includes('SERVER_ERROR')) { + if ( + error && + error.message && + error.message.includes('net_version') && + error.message.includes('SERVER_ERROR') + ) { this.switchAway(true) } reject(error) } } else { const result = data.method === 'net_listening' ? 'canceled' : [] - resolve({ jsonrpc: '2.0', result: result, id: data.id }) + resolve({jsonrpc: '2.0', result: result, id: data.id}) } } } diff --git a/apps/remix-ide/src/app/providers/custom-vm-fork-provider.tsx b/apps/remix-ide/src/app/providers/custom-vm-fork-provider.tsx index d4f9c81297..6b2e4cec91 100644 --- a/apps/remix-ide/src/app/providers/custom-vm-fork-provider.tsx +++ b/apps/remix-ide/src/app/providers/custom-vm-fork-provider.tsx @@ -1,23 +1,26 @@ -import React, { useRef } from 'react' // eslint-disable-line +import React, {useRef} from 'react' // eslint-disable-line import * as packageJson from '../../../../../package.json' -import { AppModal, ModalTypes } from '@remix-ui/app' -import { BasicVMProvider } from './vm-provider' -import { Hardfork } from '@ethereumjs/common' +import {AppModal, ModalTypes} from '@remix-ui/app' +import {BasicVMProvider} from './vm-provider' +import {Hardfork} from '@ethereumjs/common' export class CustomForkVMProvider extends BasicVMProvider { nodeUrl: string blockNumber: number | 'latest' inputs: any - constructor (blockchain) { - super({ - name: 'vm-custom-fork', - displayName: 'Custom fork - Remix VM', - kind: 'provider', - description: 'Custom fork - Remix VM', - methods: ['sendAsync', 'init'], - version: packageJson.version - }, blockchain) + constructor(blockchain) { + super( + { + name: 'vm-custom-fork', + displayName: 'Custom fork - Remix VM', + kind: 'provider', + description: 'Custom fork - Remix VM', + methods: ['sendAsync', 'init'], + version: packageJson.version + }, + blockchain + ) this.blockchain = blockchain this.fork = '' this.nodeUrl = '' @@ -25,28 +28,54 @@ export class CustomForkVMProvider extends BasicVMProvider { this.inputs = {} } - async init () { + async init() { const body = () => { - return
- Please provide information about the custom fork. If the node URL is not provided, the VM will start with an empty state. + return (
- - + + Please provide information about the custom fork. If the node URL is + not provided, the VM will start with an empty state. + +
+ + +
+
+ + +
+
+ + +
-
- - -
-
- - -
-
- } + ) + } const result = await ((): Promise => { return new Promise((resolve, reject) => { const modalContent: AppModal = { @@ -54,7 +83,7 @@ export class CustomForkVMProvider extends BasicVMProvider { title: this.profile.displayName, message: body(), validationFn: (data: any) => { - if(data.nodeUrl !== '' && !data.nodeUrl.startsWith("http")) { + if (data.nodeUrl !== '' && !data.nodeUrl.startsWith('http')) { return { valid: false, message: 'node URL should be a valid URL' @@ -96,11 +125,11 @@ export class CustomForkVMProvider extends BasicVMProvider { this.nodeUrl = undefined this.blockNumber = undefined } - + return { - 'fork': this.fork, - 'nodeUrl': this.nodeUrl, - 'blockNumber': this.blockNumber + fork: this.fork, + nodeUrl: this.nodeUrl, + blockNumber: this.blockNumber } } } diff --git a/apps/remix-ide/src/app/providers/external-http-provider.tsx b/apps/remix-ide/src/app/providers/external-http-provider.tsx index 36d864c2a1..3bb6b970d7 100644 --- a/apps/remix-ide/src/app/providers/external-http-provider.tsx +++ b/apps/remix-ide/src/app/providers/external-http-provider.tsx @@ -1,6 +1,6 @@ import * as packageJson from '../../../../../package.json' import React from 'react' // eslint-disable-line -import { AbstractProvider } from './abstract-provider' +import {AbstractProvider} from './abstract-provider' const profile = { name: 'basic-http-provider', @@ -12,25 +12,57 @@ const profile = { } export class ExternalHttpProvider extends AbstractProvider { - constructor (blockchain) { + constructor(blockchain) { super(profile, blockchain, 'http://127.0.0.1:8545') } - body (): JSX.Element { + body(): JSX.Element { const thePath = '' return ( <>
- Note: To use Geth & https://remix.ethereum.org, configure it to allow requests from Remix:(see Geth Docs on rpc server) -
geth --http --http.corsdomain https://remix.ethereum.org
+ Note: To use Geth & https://remix.ethereum.org, configure it to allow + requests from Remix:(see{' '} + + Geth Docs on rpc server + + ) +
+ geth --http --http.corsdomain https://remix.ethereum.org +

- To run Remix & a local Geth test node, use this command: (see Geth Docs on Dev mode) -
geth --http --http.corsdomain="{window.origin}" --http.api web3,eth,debug,personal,net --vmdebug --datadir {thePath} --dev console
+ To run Remix & a local Geth test node, use this command: (see{' '} + + Geth Docs on Dev mode + + ) +
+ geth --http --http.corsdomain="{window.origin}" --http.api + web3,eth,debug,personal,net --vmdebug --datadir {thePath} --dev + console +


- WARNING: It is not safe to use the --http.corsdomain flag with a wildcard: --http.corsdomain * + WARNING: It is not safe to use the --http.corsdomain flag with + a wildcard: --http.corsdomain *
-
For more info: Remix Docs on External HTTP Provider +
+ For more info:{' '} + + Remix Docs on External HTTP Provider +

External HTTP Provider Endpoint @@ -38,4 +70,4 @@ export class ExternalHttpProvider extends AbstractProvider { ) } -} \ No newline at end of file +} diff --git a/apps/remix-ide/src/app/providers/foundry-provider.tsx b/apps/remix-ide/src/app/providers/foundry-provider.tsx index 904c330b3c..3ec4ee70ec 100644 --- a/apps/remix-ide/src/app/providers/foundry-provider.tsx +++ b/apps/remix-ide/src/app/providers/foundry-provider.tsx @@ -1,6 +1,6 @@ import * as packageJson from '../../../../../package.json' import React from 'react' // eslint-disable-line -import { AbstractProvider } from './abstract-provider' +import {AbstractProvider} from './abstract-provider' const profile = { name: 'foundry-provider', @@ -12,20 +12,29 @@ const profile = { } export class FoundryProvider extends AbstractProvider { - constructor (blockchain) { + constructor(blockchain) { super(profile, blockchain, 'http://127.0.0.1:8545') } - body (): JSX.Element { + body(): JSX.Element { return ( -
Note: To run Anvil on your system, run: -
curl -L https://foundry.paradigm.xyz | bash
-
anvil
+
+ {' '} + Note: To run Anvil on your system, run: +
+ curl -L https://foundry.paradigm.xyz | bash +
+
+ anvil +
- For more info, visit: Foundry Documentation + For more info, visit:{' '} + + Foundry Documentation +
Anvil JSON-RPC Endpoint:
) } -} \ No newline at end of file +} diff --git a/apps/remix-ide/src/app/providers/ganache-provider.tsx b/apps/remix-ide/src/app/providers/ganache-provider.tsx index 132aa20957..b8cb1488b5 100644 --- a/apps/remix-ide/src/app/providers/ganache-provider.tsx +++ b/apps/remix-ide/src/app/providers/ganache-provider.tsx @@ -1,6 +1,6 @@ import * as packageJson from '../../../../../package.json' import React from 'react' // eslint-disable-line -import { AbstractProvider } from './abstract-provider' +import {AbstractProvider} from './abstract-provider' const profile = { name: 'ganache-provider', @@ -12,20 +12,29 @@ const profile = { } export class GanacheProvider extends AbstractProvider { - constructor (blockchain) { + constructor(blockchain) { super(profile, blockchain, 'http://127.0.0.1:8545') } - body (): JSX.Element { + body(): JSX.Element { return ( -
Note: To run Ganache on your system, run: -
yarn global add ganache
-
ganache
+
+ {' '} + Note: To run Ganache on your system, run: +
+ yarn global add ganache +
+
+ ganache +
- For more info, visit: Ganache Documentation + For more info, visit:{' '} + + Ganache Documentation +
Ganache JSON-RPC Endpoint:
) } -} \ No newline at end of file +} diff --git a/apps/remix-ide/src/app/providers/goerli-vm-fork-provider.tsx b/apps/remix-ide/src/app/providers/goerli-vm-fork-provider.tsx index 9327f38226..21f7845d33 100644 --- a/apps/remix-ide/src/app/providers/goerli-vm-fork-provider.tsx +++ b/apps/remix-ide/src/app/providers/goerli-vm-fork-provider.tsx @@ -1,29 +1,32 @@ import * as packageJson from '../../../../../package.json' -import { BasicVMProvider } from './vm-provider' +import {BasicVMProvider} from './vm-provider' export class GoerliForkVMProvider extends BasicVMProvider { nodeUrl: string blockNumber: number | 'latest' - constructor (blockchain) { - super({ - name: 'vm-goerli-fork', - displayName: 'Goerli fork - Remix VM (London)', - kind: 'provider', - description: 'Remix VM (London)', - methods: ['sendAsync', 'init'], - version: packageJson.version - }, blockchain) + constructor(blockchain) { + super( + { + name: 'vm-goerli-fork', + displayName: 'Goerli fork - Remix VM (London)', + kind: 'provider', + description: 'Remix VM (London)', + methods: ['sendAsync', 'init'], + version: packageJson.version + }, + blockchain + ) this.blockchain = blockchain this.fork = 'shanghai' this.nodeUrl = 'https://remix-sepolia.ethdevops.io' this.blockNumber = 'latest' } - async init () { + async init() { return { - 'fork': this.fork, - 'nodeUrl': this.nodeUrl, - 'blockNumber': this.blockNumber + fork: this.fork, + nodeUrl: this.nodeUrl, + blockNumber: this.blockNumber } } } diff --git a/apps/remix-ide/src/app/providers/hardhat-provider.tsx b/apps/remix-ide/src/app/providers/hardhat-provider.tsx index 1d579ab6c1..719b3dcb41 100644 --- a/apps/remix-ide/src/app/providers/hardhat-provider.tsx +++ b/apps/remix-ide/src/app/providers/hardhat-provider.tsx @@ -1,6 +1,6 @@ import * as packageJson from '../../../../../package.json' import React from 'react' // eslint-disable-line -import { AbstractProvider } from './abstract-provider' +import {AbstractProvider} from './abstract-provider' const profile = { name: 'hardhat-provider', @@ -12,19 +12,30 @@ const profile = { } export class HardhatProvider extends AbstractProvider { - constructor (blockchain) { + constructor(blockchain) { super(profile, blockchain, 'http://127.0.0.1:8545') } - body (): JSX.Element { + body(): JSX.Element { return ( -
Note: To run Hardhat network node on your system, go to hardhat project folder and run command: -
npx hardhat node
+
+ {' '} + Note: To run Hardhat network node on your system, go to hardhat project + folder and run command: +
+ npx hardhat node +
- For more info, visit: Hardhat Documentation + For more info, visit:{' '} + + Hardhat Documentation +
Hardhat JSON-RPC Endpoint:
) } -} \ No newline at end of file +} diff --git a/apps/remix-ide/src/app/providers/injected-L2-provider.tsx b/apps/remix-ide/src/app/providers/injected-L2-provider.tsx index afae690a39..1ab64a3775 100644 --- a/apps/remix-ide/src/app/providers/injected-L2-provider.tsx +++ b/apps/remix-ide/src/app/providers/injected-L2-provider.tsx @@ -1,32 +1,41 @@ -import { InjectedProviderDefaultBase } from './injected-provider-default' +import {InjectedProviderDefaultBase} from './injected-provider-default' -export class InjectedL2Provider extends InjectedProviderDefaultBase { +export class InjectedL2Provider extends InjectedProviderDefaultBase { chainName: string chainId: string rpcUrls: Array - constructor (profile: any, chainName: string, chainId: string, rpcUrls: Array) { + constructor( + profile: any, + chainName: string, + chainId: string, + rpcUrls: Array + ) { super(profile) this.chainName = chainName this.chainId = chainId this.rpcUrls = rpcUrls } - async init () { + async init() { await super.init() - if (this.chainName && this.rpcUrls && this.rpcUrls.length > 0) await addL2Network(this.chainName, this.chainId, this.rpcUrls) - else - throw new Error('Cannot add the L2 network to main injected provider') + if (this.chainName && this.rpcUrls && this.rpcUrls.length > 0) + await addL2Network(this.chainName, this.chainId, this.rpcUrls) + else throw new Error('Cannot add the L2 network to main injected provider') return {} } } -export const addL2Network = async (chainName: string, chainId: string, rpcUrls: Array) => { +export const addL2Network = async ( + chainName: string, + chainId: string, + rpcUrls: Array +) => { try { await (window as any).ethereum.request({ method: 'wallet_switchEthereumChain', - params: [{ chainId: chainId }], - }); + params: [{chainId: chainId}] + }) } catch (switchError) { // This error code indicates that the chain has not been added to MetaMask. if (switchError.code === 4902) { @@ -37,19 +46,19 @@ export const addL2Network = async (chainName: string, chainId: string, rpcUrls: { chainId: chainId, chainName: chainName, - rpcUrls: rpcUrls, - }, - ], - }); + rpcUrls: rpcUrls + } + ] + }) await (window as any).ethereum.request({ method: 'wallet_switchEthereumChain', - params: [{ chainId: chainId }], - }); + params: [{chainId: chainId}] + }) } catch (addError) { // handle "add" error } } // handle other "switch" errors } -} \ No newline at end of file +} diff --git a/apps/remix-ide/src/app/providers/injected-arbitrum-one-provider.tsx b/apps/remix-ide/src/app/providers/injected-arbitrum-one-provider.tsx index aaf20e9070..eb1ba39a7a 100644 --- a/apps/remix-ide/src/app/providers/injected-arbitrum-one-provider.tsx +++ b/apps/remix-ide/src/app/providers/injected-arbitrum-one-provider.tsx @@ -1,5 +1,5 @@ import * as packageJson from '../../../../../package.json' -import { InjectedL2Provider } from './injected-L2-provider' +import {InjectedL2Provider} from './injected-L2-provider' const profile = { name: 'injected-arbitrum-one-provider', @@ -11,8 +11,7 @@ const profile = { } export class InjectedArbitrumOneProvider extends InjectedL2Provider { - - constructor () { + constructor() { super(profile, 'Arbitrum One', '0xa4b1', ['https://arb1.arbitrum.io/rpc']) } -} \ No newline at end of file +} diff --git a/apps/remix-ide/src/app/providers/injected-optimism-provider.tsx b/apps/remix-ide/src/app/providers/injected-optimism-provider.tsx index 60037f415b..9c8729dd84 100644 --- a/apps/remix-ide/src/app/providers/injected-optimism-provider.tsx +++ b/apps/remix-ide/src/app/providers/injected-optimism-provider.tsx @@ -1,5 +1,5 @@ import * as packageJson from '../../../../../package.json' -import { InjectedL2Provider } from './injected-L2-provider' +import {InjectedL2Provider} from './injected-L2-provider' const profile = { name: 'injected-optimism-provider', @@ -11,8 +11,7 @@ const profile = { } export class Injected0ptimismProvider extends InjectedL2Provider { - - constructor () { + constructor() { super(profile, 'Optimism', '0xa', ['https://mainnet.optimism.io']) } -} \ No newline at end of file +} diff --git a/apps/remix-ide/src/app/providers/injected-provider-default.tsx b/apps/remix-ide/src/app/providers/injected-provider-default.tsx index 9af45e5660..84733542e1 100644 --- a/apps/remix-ide/src/app/providers/injected-provider-default.tsx +++ b/apps/remix-ide/src/app/providers/injected-provider-default.tsx @@ -1,25 +1,34 @@ /* global ethereum */ import * as packageJson from '../../../../../package.json' -import { InjectedProvider } from './injected-provider' +import {InjectedProvider} from './injected-provider' -export class InjectedProviderDefaultBase extends InjectedProvider { - constructor (profile) { +export class InjectedProviderDefaultBase extends InjectedProvider { + constructor(profile) { super(profile) } - async init () { + async init() { const injectedProvider = this.getInjectedProvider() - if (injectedProvider && injectedProvider._metamask && injectedProvider._metamask.isUnlocked) { - if (!await injectedProvider._metamask.isUnlocked()) this.call('notification', 'toast', 'Please make sure the injected provider is unlocked (e.g Metamask).') + if ( + injectedProvider && + injectedProvider._metamask && + injectedProvider._metamask.isUnlocked + ) { + if (!(await injectedProvider._metamask.isUnlocked())) + this.call( + 'notification', + 'toast', + 'Please make sure the injected provider is unlocked (e.g Metamask).' + ) } return super.init() } - getInjectedProvider () { + getInjectedProvider() { return (window as any).ethereum } - notFound () { + notFound() { return 'No injected provider found. Make sure your provider (e.g. MetaMask, ...) is active and running (when recently activated you may have to reload the page).' } } @@ -34,7 +43,7 @@ const profile = { } export class InjectedProviderDefault extends InjectedProviderDefaultBase { - constructor () { + constructor() { super(profile) } } diff --git a/apps/remix-ide/src/app/providers/injected-provider-trustwallet.tsx b/apps/remix-ide/src/app/providers/injected-provider-trustwallet.tsx index c58f6d12f8..f7f139fed8 100644 --- a/apps/remix-ide/src/app/providers/injected-provider-trustwallet.tsx +++ b/apps/remix-ide/src/app/providers/injected-provider-trustwallet.tsx @@ -1,6 +1,6 @@ /* global ethereum */ import * as packageJson from '../../../../../package.json' -import { InjectedProvider } from './injected-provider' +import {InjectedProvider} from './injected-provider' const profile = { name: 'injected-trustwallet', @@ -11,16 +11,16 @@ const profile = { version: packageJson.version } -export class InjectedProviderTrustWallet extends InjectedProvider { - constructor () { +export class InjectedProviderTrustWallet extends InjectedProvider { + constructor() { super(profile) } - getInjectedProvider () { + getInjectedProvider() { return (window as any).trustwallet } - notFound () { + notFound() { return 'Could not find Trust Wallet provider. Please make sure the Trust Wallet extension is active. Download the latest version from https://trustwallet.com/browser-extension' } } diff --git a/apps/remix-ide/src/app/providers/injected-provider.tsx b/apps/remix-ide/src/app/providers/injected-provider.tsx index 9a1f915128..ee771c70a5 100644 --- a/apps/remix-ide/src/app/providers/injected-provider.tsx +++ b/apps/remix-ide/src/app/providers/injected-provider.tsx @@ -1,15 +1,19 @@ /* global ethereum */ import React from 'react' // eslint-disable-line -import { Plugin } from '@remixproject/engine' -import { JsonDataRequest, RejectRequest, SuccessRequest } from '../providers/abstract-provider' -import { IProvider } from './abstract-provider' +import {Plugin} from '@remixproject/engine' +import { + JsonDataRequest, + RejectRequest, + SuccessRequest +} from '../providers/abstract-provider' +import {IProvider} from './abstract-provider' export abstract class InjectedProvider extends Plugin implements IProvider { - options: { [id: string] : any } = {} + options: {[id: string]: any} = {} listenerAccountsChanged: (accounts: Array) => void listenerChainChanged: (chainId: number) => void - constructor (profile) { + constructor(profile) { super(profile) this.listenerAccountsChanged = (accounts: Array) => { this.emit('accountsChanged', accounts) @@ -25,39 +29,43 @@ export abstract class InjectedProvider extends Plugin implements IProvider { onActivation(): void { try { const web3Provider = this.getInjectedProvider() - web3Provider.on('accountsChanged', this.listenerAccountsChanged); - web3Provider.on('chainChanged', this.listenerChainChanged); + web3Provider.on('accountsChanged', this.listenerAccountsChanged) + web3Provider.on('chainChanged', this.listenerChainChanged) } catch (error) { console.log('unable to listen on context changed') - } + } } onDeactivation(): void { try { const web3Provider = this.getInjectedProvider() - web3Provider.removeListener('accountsChanged', this.listenerAccountsChanged) + web3Provider.removeListener( + 'accountsChanged', + this.listenerAccountsChanged + ) web3Provider.removeListener('chainChanged', this.listenerChainChanged) } catch (error) { console.log('unable to remove listener on context changed') - } + } } - askPermission (throwIfNoInjectedProvider) { + askPermission(throwIfNoInjectedProvider) { const web3Provider = this.getInjectedProvider() - if (typeof web3Provider !== "undefined" && typeof web3Provider.request === "function") { - web3Provider.request({ method: "eth_requestAccounts" }) + if ( + typeof web3Provider !== 'undefined' && + typeof web3Provider.request === 'function' + ) { + web3Provider.request({method: 'eth_requestAccounts'}) } else if (throwIfNoInjectedProvider) { throw new Error(this.notFound()) } } - body (): JSX.Element { - return ( -
- ) + body(): JSX.Element { + return
} - async init () { + async init() { const injectedProvider = this.getInjectedProvider() if (injectedProvider === undefined) { this.call('notification', 'toast', this.notFound()) @@ -68,38 +76,60 @@ export abstract class InjectedProvider extends Plugin implements IProvider { return {} } - sendAsync (data: JsonDataRequest): Promise { + sendAsync(data: JsonDataRequest): Promise { return new Promise((resolve, reject) => { this.sendAsyncInternal(data, resolve, reject) }) } - private async sendAsyncInternal (data: JsonDataRequest, resolve: SuccessRequest, reject: RejectRequest): Promise { + private async sendAsyncInternal( + data: JsonDataRequest, + resolve: SuccessRequest, + reject: RejectRequest + ): Promise { // Check the case where current environment is VM on UI and it still sends RPC requests // This will be displayed on UI tooltip as 'cannot get account list: Environment Updated !!' const web3Provider = this.getInjectedProvider() if (!web3Provider) { - this.call('notification', 'toast', 'No injected provider (e.g Metamask) has been found.') - return resolve({ jsonrpc: '2.0', error: 'no injected provider found', id: data.id }) + this.call( + 'notification', + 'toast', + 'No injected provider (e.g Metamask) has been found.' + ) + return resolve({ + jsonrpc: '2.0', + error: 'no injected provider found', + id: data.id + }) } try { let resultData - if (web3Provider.send) resultData = await web3Provider.send(data.method, data.params) - else if (web3Provider.request) resultData = await web3Provider.request({ method: data.method, params: data.params}) + if (web3Provider.send) + resultData = await web3Provider.send(data.method, data.params) + else if (web3Provider.request) + resultData = await web3Provider.request({ + method: data.method, + params: data.params + }) else { - resolve({ jsonrpc: '2.0', error: 'provider not valid', id: data.id }) + resolve({jsonrpc: '2.0', error: 'provider not valid', id: data.id}) return } if (resultData) { if (resultData.jsonrpc && resultData.jsonrpc === '2.0') { resultData = resultData.result } - resolve({ jsonrpc: '2.0', result: resultData, id: data.id }) + resolve({jsonrpc: '2.0', result: resultData, id: data.id}) } else { - resolve({ jsonrpc: '2.0', error: 'no return data provided', id: data.id }) + resolve({jsonrpc: '2.0', error: 'no return data provided', id: data.id}) } } catch (error) { - resolve({ jsonrpc: '2.0', error: error.data && error.data.message ? error.data.message : error.message, id: data.id }) + resolve({ + jsonrpc: '2.0', + error: + error.data && error.data.message ? error.data.message : error.message, + id: data.id + }) } } } diff --git a/apps/remix-ide/src/app/providers/mainnet-vm-fork-provider.tsx b/apps/remix-ide/src/app/providers/mainnet-vm-fork-provider.tsx index 68fc03e5ba..830f3cb454 100644 --- a/apps/remix-ide/src/app/providers/mainnet-vm-fork-provider.tsx +++ b/apps/remix-ide/src/app/providers/mainnet-vm-fork-provider.tsx @@ -1,29 +1,33 @@ import * as packageJson from '../../../../../package.json' -import { BasicVMProvider } from './vm-provider' +import {BasicVMProvider} from './vm-provider' export class MainnetForkVMProvider extends BasicVMProvider { nodeUrl: string blockNumber: number | 'latest' - constructor (blockchain) { - super({ - name: 'vm-mainnet-fork', - displayName: 'Mainet fork -Remix VM (London)', - kind: 'provider', - description: 'Remix VM (London)', - methods: ['sendAsync', 'init'], - version: packageJson.version - }, blockchain) + constructor(blockchain) { + super( + { + name: 'vm-mainnet-fork', + displayName: 'Mainet fork -Remix VM (London)', + kind: 'provider', + description: 'Remix VM (London)', + methods: ['sendAsync', 'init'], + version: packageJson.version + }, + blockchain + ) this.blockchain = blockchain this.fork = 'shanghai' - this.nodeUrl = 'https://mainnet.infura.io/v3/08b2a484451e4635a28b3d8234f24332' + this.nodeUrl = + 'https://mainnet.infura.io/v3/08b2a484451e4635a28b3d8234f24332' this.blockNumber = 'latest' } - async init () { + async init() { return { - 'fork': this.fork, - 'nodeUrl': this.nodeUrl, - 'blockNumber': this.blockNumber + fork: this.fork, + nodeUrl: this.nodeUrl, + blockNumber: this.blockNumber } } } diff --git a/apps/remix-ide/src/app/providers/sepolia-vm-fork-provider.tsx b/apps/remix-ide/src/app/providers/sepolia-vm-fork-provider.tsx index 042bd0ed7c..03d7248adb 100644 --- a/apps/remix-ide/src/app/providers/sepolia-vm-fork-provider.tsx +++ b/apps/remix-ide/src/app/providers/sepolia-vm-fork-provider.tsx @@ -1,29 +1,32 @@ import * as packageJson from '../../../../../package.json' -import { BasicVMProvider } from './vm-provider' +import {BasicVMProvider} from './vm-provider' export class SepoliaForkVMProvider extends BasicVMProvider { nodeUrl: string blockNumber: number | 'latest' - constructor (blockchain) { - super({ - name: 'vm-sepolia-fork', - displayName: 'Sepolia fork - Remix VM (London)', - kind: 'provider', - description: 'Remix VM (London)', - methods: ['sendAsync', 'init'], - version: packageJson.version - }, blockchain) + constructor(blockchain) { + super( + { + name: 'vm-sepolia-fork', + displayName: 'Sepolia fork - Remix VM (London)', + kind: 'provider', + description: 'Remix VM (London)', + methods: ['sendAsync', 'init'], + version: packageJson.version + }, + blockchain + ) this.blockchain = blockchain this.fork = 'shanghai' this.nodeUrl = 'https://remix-sepolia.ethdevops.io' this.blockNumber = 'latest' } - async init () { + async init() { return { - 'fork': this.fork, - 'nodeUrl': this.nodeUrl, - 'blockNumber': this.blockNumber + fork: this.fork, + nodeUrl: this.nodeUrl, + blockNumber: this.blockNumber } } } diff --git a/apps/remix-ide/src/app/providers/vm-provider.tsx b/apps/remix-ide/src/app/providers/vm-provider.tsx index 5e66152463..9d3d64861b 100644 --- a/apps/remix-ide/src/app/providers/vm-provider.tsx +++ b/apps/remix-ide/src/app/providers/vm-provider.tsx @@ -1,41 +1,52 @@ import React from 'react' // eslint-disable-line import * as packageJson from '../../../../../package.json' -import { JsonDataRequest, RejectRequest, SuccessRequest } from '../providers/abstract-provider' -import { Plugin } from '@remixproject/engine' -import { IProvider } from './abstract-provider' +import { + JsonDataRequest, + RejectRequest, + SuccessRequest +} from '../providers/abstract-provider' +import {Plugin} from '@remixproject/engine' +import {IProvider} from './abstract-provider' export class BasicVMProvider extends Plugin implements IProvider { blockchain fork: string - options: { [id: string] : any } = {} - constructor (profile, blockchain) { + options: {[id: string]: any} = {} + constructor(profile, blockchain) { super(profile) this.blockchain = blockchain this.fork = '' } - async init (): Promise<{ [id: string] : any }> { return {} } + async init(): Promise<{[id: string]: any}> { + return {} + } - body (): JSX.Element { - return ( -
- ) + body(): JSX.Element { + return
} - sendAsync (data: JsonDataRequest): Promise { + sendAsync(data: JsonDataRequest): Promise { return new Promise((resolve, reject) => { this.sendAsyncInternal(data, resolve, reject) }) } - private async sendAsyncInternal (data: JsonDataRequest, resolve: SuccessRequest, reject: RejectRequest): Promise { + private async sendAsyncInternal( + data: JsonDataRequest, + resolve: SuccessRequest, + reject: RejectRequest + ): Promise { try { - await this.blockchain.providers.vm.provider.sendAsync(data, (error, result) => { - if (error) return reject(error) - else { - resolve({ jsonrpc: '2.0', result, id: data.id }) + await this.blockchain.providers.vm.provider.sendAsync( + data, + (error, result) => { + if (error) return reject(error) + else { + resolve({jsonrpc: '2.0', result, id: data.id}) + } } - }) + ) } catch (error) { reject(error) } @@ -43,61 +54,73 @@ export class BasicVMProvider extends Plugin implements IProvider { } export class MergeVMProvider extends BasicVMProvider { - constructor (blockchain) { - super({ - name: 'vm-merge', - displayName: 'Remix VM (Merge)', - kind: 'provider', - description: 'Remix VM (Merge)', - methods: ['sendAsync', 'init'], - version: packageJson.version - }, blockchain) + constructor(blockchain) { + super( + { + name: 'vm-merge', + displayName: 'Remix VM (Merge)', + kind: 'provider', + description: 'Remix VM (Merge)', + methods: ['sendAsync', 'init'], + version: packageJson.version + }, + blockchain + ) this.blockchain = blockchain this.fork = 'merge' } } export class LondonVMProvider extends BasicVMProvider { - constructor (blockchain) { - super({ - name: 'vm-london', - displayName: 'Remix VM (London)', - kind: 'provider', - description: 'Remix VM (London)', - methods: ['sendAsync', 'init'], - version: packageJson.version - }, blockchain) + constructor(blockchain) { + super( + { + name: 'vm-london', + displayName: 'Remix VM (London)', + kind: 'provider', + description: 'Remix VM (London)', + methods: ['sendAsync', 'init'], + version: packageJson.version + }, + blockchain + ) this.blockchain = blockchain this.fork = 'london' } } export class BerlinVMProvider extends BasicVMProvider { - constructor (blockchain) { - super({ - name: 'vm-berlin', - displayName: 'Remix VM (Berlin)', - kind: 'provider', - description: 'Remix VM (Berlin)', - methods: ['sendAsync', 'init'], - version: packageJson.version - }, blockchain) + constructor(blockchain) { + super( + { + name: 'vm-berlin', + displayName: 'Remix VM (Berlin)', + kind: 'provider', + description: 'Remix VM (Berlin)', + methods: ['sendAsync', 'init'], + version: packageJson.version + }, + blockchain + ) this.blockchain = blockchain this.fork = 'berlin' } } export class ShanghaiVMProvider extends BasicVMProvider { - constructor (blockchain) { - super({ - name: 'vm-shanghai', - displayName: 'Remix VM (Shanghai)', - kind: 'provider', - description: 'Remix VM (Shanghai)', - methods: ['sendAsync', 'init'], - version: packageJson.version - }, blockchain) + constructor(blockchain) { + super( + { + name: 'vm-shanghai', + displayName: 'Remix VM (Shanghai)', + kind: 'provider', + description: 'Remix VM (Shanghai)', + methods: ['sendAsync', 'init'], + version: packageJson.version + }, + blockchain + ) this.blockchain = blockchain this.fork = 'shanghai' } -} \ No newline at end of file +} diff --git a/apps/remix-ide/src/app/tabs/search.tsx b/apps/remix-ide/src/app/tabs/search.tsx index b809335981..780ce49bb7 100644 --- a/apps/remix-ide/src/app/tabs/search.tsx +++ b/apps/remix-ide/src/app/tabs/search.tsx @@ -1,7 +1,7 @@ -import { ViewPlugin } from '@remixproject/engine-web' +import {ViewPlugin} from '@remixproject/engine-web' import * as packageJson from '../../../../../package.json' import React from 'react' // eslint-disable-line -import { SearchTab } from '@remix-ui/search' +import {SearchTab} from '@remix-ui/search' const profile = { name: 'search', displayName: 'Search in files', @@ -17,17 +17,15 @@ const profile = { } export class SearchPlugin extends ViewPlugin { - - constructor () { + constructor() { super(profile) } render() { return ( -
+
- ); + ) } - } diff --git a/apps/remix-ide/src/app/tabs/settings-tab.tsx b/apps/remix-ide/src/app/tabs/settings-tab.tsx index b68cc0f7f0..cfc168054a 100644 --- a/apps/remix-ide/src/app/tabs/settings-tab.tsx +++ b/apps/remix-ide/src/app/tabs/settings-tab.tsx @@ -1,10 +1,10 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import React from 'react' // eslint-disable-line -import { ViewPlugin } from '@remixproject/engine-web' +import {ViewPlugin} from '@remixproject/engine-web' import * as packageJson from '../../../../../package.json' -import { RemixUiSettings } from '@remix-ui/settings' //eslint-disable-line +import {RemixUiSettings} from '@remix-ui/settings' //eslint-disable-line import Registry from '../state/registry' -import { PluginViewWrapper } from '@remix-ui/helper' +import {PluginViewWrapper} from '@remix-ui/helper' const profile = { name: 'settings', @@ -18,7 +18,7 @@ const profile = { documentation: 'https://remix-ide.readthedocs.io/en/latest/settings.html', version: packageJson.version, permission: true, - maintainedBy: "Remix" + maintainedBy: 'Remix' } module.exports = class SettingsTab extends ViewPlugin { @@ -31,7 +31,7 @@ module.exports = class SettingsTab extends ViewPlugin { element: HTMLDivElement public useMatomoAnalytics: any dispatch: React.Dispatch = () => {} - constructor (config, editor) { + constructor(config, editor) { super(profile) this.config = config this.config.events.on('configChanged', (changedConfig) => { @@ -47,37 +47,41 @@ module.exports = class SettingsTab extends ViewPlugin { this.useMatomoAnalytics = null } - setDispatch (dispatch: React.Dispatch) { + setDispatch(dispatch: React.Dispatch) { this.dispatch = dispatch this.renderComponent() } render() { - return
- -
+ return ( +
+ +
+ ) } - updateComponent(state: any){ - return + updateComponent(state: any) { + return ( + + ) } - renderComponent () { + renderComponent() { this.dispatch(this) } - get (key) { + get(key) { return this.config.get(key) } - updateMatomoAnalyticsChoice (isChecked) { + updateMatomoAnalyticsChoice(isChecked) { this.config.set('settings/matomo-analytics', isChecked) this.useMatomoAnalytics = isChecked this.dispatch({ diff --git a/apps/remix-ide/src/blockchain/blockchain.tsx b/apps/remix-ide/src/blockchain/blockchain.tsx index 61aeeb74df..4d2b69b21e 100644 --- a/apps/remix-ide/src/blockchain/blockchain.tsx +++ b/apps/remix-ide/src/blockchain/blockchain.tsx @@ -1,47 +1,68 @@ - import React from 'react' // eslint-disable-line import Web3 from 'web3' -import { Plugin } from '@remixproject/engine' -import { toBuffer, addHexPrefix } from '@ethereumjs/util' -import { EventEmitter } from 'events' -import { format } from 'util' -import { ExecutionContext } from './execution-context' +import {Plugin} from '@remixproject/engine' +import {toBuffer, addHexPrefix} from '@ethereumjs/util' +import {EventEmitter} from 'events' +import {format} from 'util' +import {ExecutionContext} from './execution-context' import Config from '../config' -import { VMProvider } from './providers/vm' -import { InjectedProvider } from './providers/injected' -import { NodeProvider } from './providers/node' -import { execution, EventManager, helpers } from '@remix-project/remix-lib' -import { etherScanLink } from './helper' -import { logBuilder, cancelUpgradeMsg, cancelProxyMsg, addressToString } from "@remix-ui/helper" -const { txFormat, txExecution, typeConversion, txListener: Txlistener, TxRunner, TxRunnerWeb3, txHelper } = execution -const { txResultHelper } = helpers -const { resultToRemixTx } = txResultHelper +import {VMProvider} from './providers/vm' +import {InjectedProvider} from './providers/injected' +import {NodeProvider} from './providers/node' +import {execution, EventManager, helpers} from '@remix-project/remix-lib' +import {etherScanLink} from './helper' +import { + logBuilder, + cancelUpgradeMsg, + cancelProxyMsg, + addressToString +} from '@remix-ui/helper' +const { + txFormat, + txExecution, + typeConversion, + txListener: Txlistener, + TxRunner, + TxRunnerWeb3, + txHelper +} = execution +const {txResultHelper} = helpers +const {resultToRemixTx} = txResultHelper import * as packageJson from '../../../../package.json' -const _paq = window._paq = window._paq || [] //eslint-disable-line +const _paq = (window._paq = window._paq || []) //eslint-disable-line const profile = { name: 'blockchain', displayName: 'Blockchain', description: 'Blockchain - Logic', - methods: ['getCode', 'getTransactionReceipt', 'addProvider', 'removeProvider', 'getCurrentFork', 'getAccounts', 'web3VM', 'getProvider'], + methods: [ + 'getCode', + 'getTransactionReceipt', + 'addProvider', + 'removeProvider', + 'getCurrentFork', + 'getAccounts', + 'web3VM', + 'getProvider' + ], version: packageJson.version } export type TransactionContextAPI = { - getAddress: (cb: (error: Error, result: string) => void) => void, - getValue: (cb: (error: Error, result: string) => void) => void, + getAddress: (cb: (error: Error, result: string) => void) => void + getValue: (cb: (error: Error, result: string) => void) => void getGasLimit: (cb: (error: Error, result: string) => void) => void } // see TxRunner.ts in remix-lib export type Transaction = { - from: string, - to: string, - value: string, - data: string, - gasLimit: number, - useCall: boolean, + from: string + to: string + value: string + data: string + gasLimit: number + useCall: boolean timestamp?: number } @@ -55,16 +76,16 @@ export class Blockchain extends Plugin { networkcallid: number networkStatus: { network: { - name: string, - id: string + name: string + id: string } error?: string } - providers: { [key: string]: VMProvider | InjectedProvider | NodeProvider } + providers: {[key: string]: VMProvider | InjectedProvider | NodeProvider} transactionContextAPI: TransactionContextAPI // NOTE: the config object will need to be refactored out in remix-lib - constructor (config: Config) { + constructor(config: Config) { super(profile) this.active = false this.event = new EventManager() @@ -72,55 +93,63 @@ export class Blockchain extends Plugin { this.events = new EventEmitter() this.config = config - const web3Runner = new TxRunnerWeb3({ - config: this.config, - detectNetwork: (cb) => { - this.executionContext.detectNetwork(cb) + const web3Runner = new TxRunnerWeb3( + { + config: this.config, + detectNetwork: (cb) => { + this.executionContext.detectNetwork(cb) + }, + isVM: () => { + return this.executionContext.isVM() + }, + personalMode: () => { + return this.getProvider() === 'web3' + ? this.config.get('settings/personal-mode') + : false + } }, - isVM: () => { return this.executionContext.isVM() }, - personalMode: () => { - return this.getProvider() === 'web3' ? this.config.get('settings/personal-mode') : false - } - }, _ => this.executionContext.web3(), _ => this.executionContext.currentblockGasLimit()) + (_) => this.executionContext.web3(), + (_) => this.executionContext.currentblockGasLimit() + ) this.txRunner = new TxRunner(web3Runner, {}) this.networkcallid = 0 - this.networkStatus = { network: { name: ' - ', id: ' - ' } } + this.networkStatus = {network: {name: ' - ', id: ' - '}} this.setupEvents() this.setupProviders() } - _triggerEvent (name, args) { + _triggerEvent(name, args) { if (!this.active) return this.event.trigger(name, args) this.emit(name, ...args) } - onActivation () { + onActivation() { this.active = true this.on('injected', 'chainChanged', () => { this.detectNetwork((error, network) => { - this.networkStatus = { network, error } + this.networkStatus = {network, error} this._triggerEvent('networkStatus', [this.networkStatus]) }) }) this.on('injected-trustwallet', 'chainChanged', () => { this.detectNetwork((error, network) => { - this.networkStatus = { network, error } + this.networkStatus = {network, error} this._triggerEvent('networkStatus', [this.networkStatus]) }) }) this.on('walletconnect', 'chainChanged', () => { this.detectNetwork((error, network) => { - this.networkStatus = { network, error } + this.networkStatus = {network, error} this._triggerEvent('networkStatus', [this.networkStatus]) }) }) } - onDeactivation () { + onDeactivation() { this.active = false this.off('injected', 'chainChanged') this.off('injected-trustwallet', 'chainChanged') @@ -128,12 +157,12 @@ export class Blockchain extends Plugin { this.off('walletconnect', 'accountsChanged') } - setupEvents () { + setupEvents() { this.executionContext.event.register('contextChanged', async (context) => { await this.resetEnvironment() this._triggerEvent('contextChanged', [context]) this.detectNetwork((error, network) => { - this.networkStatus = { network, error } + this.networkStatus = {network, error} this._triggerEvent('networkStatus', [this.networkStatus]) }) }) @@ -148,17 +177,17 @@ export class Blockchain extends Plugin { setInterval(() => { this.detectNetwork((error, network) => { - this.networkStatus = { network, error } + this.networkStatus = {network, error} this._triggerEvent('networkStatus', [this.networkStatus]) }) }, 30000) } - getCurrentNetworkStatus () { + getCurrentNetworkStatus() { return this.networkStatus } - setupProviders () { + setupProviders() { const vmProvider = new VMProvider(this.executionContext) this.providers = {} this.providers['vm'] = vmProvider @@ -166,7 +195,7 @@ export class Blockchain extends Plugin { this.providers.web3 = new NodeProvider(this.executionContext, this.config) } - getCurrentProvider () { + getCurrentProvider() { const provider = this.getProvider() if (provider && provider.startsWith('vm')) return this.providers['vm'] if (this.providers[provider]) return this.providers[provider] @@ -175,7 +204,7 @@ export class Blockchain extends Plugin { /** Return the list of accounts */ // note: the dual promise/callback is kept for now as it was before - getAccounts (cb) { + getAccounts(cb) { return new Promise((resolve, reject) => { this.getCurrentProvider().getAccounts((error, accounts) => { if (cb) { @@ -189,36 +218,89 @@ export class Blockchain extends Plugin { }) } - deployContractAndLibraries (selectedContract, args, contractMetadata, compilerContracts, callbacks, confirmationCb) { - const { continueCb, promptCb, statusCb, finalCb } = callbacks + deployContractAndLibraries( + selectedContract, + args, + contractMetadata, + compilerContracts, + callbacks, + confirmationCb + ) { + const {continueCb, promptCb, statusCb, finalCb} = callbacks const constructor = selectedContract.getConstructorInterface() - txFormat.buildData(selectedContract.name, selectedContract.object, compilerContracts, true, constructor, args, (error, data) => { - if (error) { - return statusCb(`creation of ${selectedContract.name} errored: ${error.message ? error.message : error}`) - } + txFormat.buildData( + selectedContract.name, + selectedContract.object, + compilerContracts, + true, + constructor, + args, + (error, data) => { + if (error) { + return statusCb( + `creation of ${selectedContract.name} errored: ${ + error.message ? error.message : error + }` + ) + } - statusCb(`creation of ${selectedContract.name} pending...`) - this.createContract(selectedContract, data, continueCb, promptCb, confirmationCb, finalCb) - }, statusCb, (data, runTxCallback) => { - // called for libraries deployment - this.runTx(data, confirmationCb, continueCb, promptCb, runTxCallback) - }) + statusCb(`creation of ${selectedContract.name} pending...`) + this.createContract( + selectedContract, + data, + continueCb, + promptCb, + confirmationCb, + finalCb + ) + }, + statusCb, + (data, runTxCallback) => { + // called for libraries deployment + this.runTx(data, confirmationCb, continueCb, promptCb, runTxCallback) + } + ) } - deployContractWithLibrary (selectedContract, args, contractMetadata, compilerContracts, callbacks, confirmationCb) { - const { continueCb, promptCb, statusCb, finalCb } = callbacks + deployContractWithLibrary( + selectedContract, + args, + contractMetadata, + compilerContracts, + callbacks, + confirmationCb + ) { + const {continueCb, promptCb, statusCb, finalCb} = callbacks const constructor = selectedContract.getConstructorInterface() - txFormat.encodeConstructorCallAndLinkLibraries(selectedContract.object, args, constructor, contractMetadata.linkReferences, selectedContract.bytecodeLinkReferences, (error, data) => { - if (error) { - return statusCb(`creation of ${selectedContract.name} errored: ${error.message ? error.message : error}`) - } + txFormat.encodeConstructorCallAndLinkLibraries( + selectedContract.object, + args, + constructor, + contractMetadata.linkReferences, + selectedContract.bytecodeLinkReferences, + (error, data) => { + if (error) { + return statusCb( + `creation of ${selectedContract.name} errored: ${ + error.message ? error.message : error + }` + ) + } - statusCb(`creation of ${selectedContract.name} pending...`) - this.createContract(selectedContract, data, continueCb, promptCb, confirmationCb, finalCb) - }) + statusCb(`creation of ${selectedContract.name} pending...`) + this.createContract( + selectedContract, + data, + continueCb, + promptCb, + confirmationCb, + finalCb + ) + } + ) } - async deployProxy (proxyData, implementationContractObject) { + async deployProxy(proxyData, implementationContractObject) { const proxyModal = { id: 'confirmProxyDeployment', title: 'Confirm Deploy Proxy (ERC1967)', @@ -229,44 +311,94 @@ export class Blockchain extends Plugin { cancelLabel: 'Cancel', okFn: () => { this.runProxyTx(proxyData, implementationContractObject) - _paq.push(['trackEvent', 'blockchain', 'Deploy With Proxy', 'modal ok confirmation']) + _paq.push([ + 'trackEvent', + 'blockchain', + 'Deploy With Proxy', + 'modal ok confirmation' + ]) }, cancelFn: () => { this.call('notification', 'toast', cancelProxyMsg()) - _paq.push(['trackEvent', 'blockchain', 'Deploy With Proxy', 'cancel proxy deployment']) + _paq.push([ + 'trackEvent', + 'blockchain', + 'Deploy With Proxy', + 'cancel proxy deployment' + ]) }, hideFn: () => null } this.call('notification', 'modal', proxyModal) } - async runProxyTx (proxyData, implementationContractObject) { - const args = { useCall: false, data: proxyData } + async runProxyTx(proxyData, implementationContractObject) { + const args = {useCall: false, data: proxyData} let networkInfo - const confirmationCb = (network, tx, gasEstimation, continueTxExecution, cancelCb) => { + const confirmationCb = ( + network, + tx, + gasEstimation, + continueTxExecution, + cancelCb + ) => { networkInfo = network // continue using original authorization given by user continueTxExecution(null) } - const continueCb = (error, continueTxExecution, cancelCb) => { continueTxExecution() } - const promptCb = (okCb, cancelCb) => { okCb() } + const continueCb = (error, continueTxExecution, cancelCb) => { + continueTxExecution() + } + const promptCb = (okCb, cancelCb) => { + okCb() + } const finalCb = async (error, txResult, address, returnValue) => { if (error) { const log = logBuilder(error) - - _paq.push(['trackEvent', 'blockchain', 'Deploy With Proxy', 'Proxy deployment failed: ' + error]) + + _paq.push([ + 'trackEvent', + 'blockchain', + 'Deploy With Proxy', + 'Proxy deployment failed: ' + error + ]) return this.call('terminal', 'logHtml', log) } - await this.saveDeployedContractStorageLayout(implementationContractObject, address, networkInfo) - this.events.emit('newProxyDeployment', address, new Date().toISOString(), implementationContractObject.contractName) - _paq.push(['trackEvent', 'blockchain', 'Deploy With Proxy', 'Proxy deployment successful']) - this.call('udapp', 'addInstance', addressToString(address), implementationContractObject.abi, implementationContractObject.name) + await this.saveDeployedContractStorageLayout( + implementationContractObject, + address, + networkInfo + ) + this.events.emit( + 'newProxyDeployment', + address, + new Date().toISOString(), + implementationContractObject.contractName + ) + _paq.push([ + 'trackEvent', + 'blockchain', + 'Deploy With Proxy', + 'Proxy deployment successful' + ]) + this.call( + 'udapp', + 'addInstance', + addressToString(address), + implementationContractObject.abi, + implementationContractObject.name + ) } this.runTx(args, confirmationCb, continueCb, promptCb, finalCb) } - async upgradeProxy(proxyAddress, newImplAddress, data, newImplementationContractObject) { + async upgradeProxy( + proxyAddress, + newImplAddress, + data, + newImplementationContractObject + ) { const upgradeModal = { id: 'confirmProxyDeployment', title: 'Confirm Update Proxy (ERC1967)', @@ -276,56 +408,120 @@ export class Blockchain extends Plugin { cancelLabel: 'Cancel', okFn: () => { this.runUpgradeTx(proxyAddress, data, newImplementationContractObject) - _paq.push(['trackEvent', 'blockchain', 'Upgrade With Proxy', 'proxy upgrade confirmation click']) + _paq.push([ + 'trackEvent', + 'blockchain', + 'Upgrade With Proxy', + 'proxy upgrade confirmation click' + ]) }, cancelFn: () => { this.call('notification', 'toast', cancelUpgradeMsg()) - _paq.push(['trackEvent', 'blockchain', 'Upgrade With Proxy', 'proxy upgrade cancel click']) + _paq.push([ + 'trackEvent', + 'blockchain', + 'Upgrade With Proxy', + 'proxy upgrade cancel click' + ]) }, hideFn: () => null } this.call('notification', 'modal', upgradeModal) } - async runUpgradeTx (proxyAddress, data, newImplementationContractObject) { - const args = { useCall: false, data, to: proxyAddress } + async runUpgradeTx(proxyAddress, data, newImplementationContractObject) { + const args = {useCall: false, data, to: proxyAddress} let networkInfo - const confirmationCb = (network, tx, gasEstimation, continueTxExecution, cancelCb) => { + const confirmationCb = ( + network, + tx, + gasEstimation, + continueTxExecution, + cancelCb + ) => { // continue using original authorization given by user networkInfo = network continueTxExecution(null) } - const continueCb = (error, continueTxExecution, cancelCb) => { continueTxExecution() } - const promptCb = (okCb, cancelCb) => { okCb() } + const continueCb = (error, continueTxExecution, cancelCb) => { + continueTxExecution() + } + const promptCb = (okCb, cancelCb) => { + okCb() + } const finalCb = async (error, txResult, address, returnValue) => { if (error) { const log = logBuilder(error) - _paq.push(['trackEvent', 'blockchain', 'Upgrade With Proxy', 'Upgrade failed']) + _paq.push([ + 'trackEvent', + 'blockchain', + 'Upgrade With Proxy', + 'Upgrade failed' + ]) return this.call('terminal', 'logHtml', log) } - await this.saveDeployedContractStorageLayout(newImplementationContractObject, proxyAddress, networkInfo) - _paq.push(['trackEvent', 'blockchain', 'Upgrade With Proxy', 'Upgrade Successful']) - this.call('udapp', 'addInstance', addressToString(proxyAddress), newImplementationContractObject.abi, newImplementationContractObject.name) + await this.saveDeployedContractStorageLayout( + newImplementationContractObject, + proxyAddress, + networkInfo + ) + _paq.push([ + 'trackEvent', + 'blockchain', + 'Upgrade With Proxy', + 'Upgrade Successful' + ]) + this.call( + 'udapp', + 'addInstance', + addressToString(proxyAddress), + newImplementationContractObject.abi, + newImplementationContractObject.name + ) } this.runTx(args, confirmationCb, continueCb, promptCb, finalCb) } - async saveDeployedContractStorageLayout (contractObject, proxyAddress, networkInfo) { - const { contractName, implementationAddress } = contractObject - const networkName = networkInfo.name === 'custom' ? networkInfo.name + '-' + networkInfo.id : networkInfo.name - const hasPreviousDeploys = await this.call('fileManager', 'exists', `.deploys/upgradeable-contracts/${networkName}/UUPS.json`) + async saveDeployedContractStorageLayout( + contractObject, + proxyAddress, + networkInfo + ) { + const {contractName, implementationAddress} = contractObject + const networkName = + networkInfo.name === 'custom' + ? networkInfo.name + '-' + networkInfo.id + : networkInfo.name + const hasPreviousDeploys = await this.call( + 'fileManager', + 'exists', + `.deploys/upgradeable-contracts/${networkName}/UUPS.json` + ) // TODO: make deploys folder read only. if (hasPreviousDeploys) { - const deployments = await this.call('fileManager', 'readFile', `.deploys/upgradeable-contracts/${networkName}/UUPS.json`) + const deployments = await this.call( + 'fileManager', + 'readFile', + `.deploys/upgradeable-contracts/${networkName}/UUPS.json` + ) const parsedDeployments = JSON.parse(deployments) const proxyDeployment = parsedDeployments.deployments[proxyAddress] if (proxyDeployment) { const oldImplementationAddress = proxyDeployment.implementationAddress - const hasPreviousBuild = await this.call('fileManager', 'exists', `.deploys/upgradeable-contracts/${networkName}/solc-${oldImplementationAddress}.json`) + const hasPreviousBuild = await this.call( + 'fileManager', + 'exists', + `.deploys/upgradeable-contracts/${networkName}/solc-${oldImplementationAddress}.json` + ) - if (hasPreviousBuild) await this.call('fileManager', 'remove', `.deploys/upgradeable-contracts/${networkName}/solc-${oldImplementationAddress}.json`) + if (hasPreviousBuild) + await this.call( + 'fileManager', + 'remove', + `.deploys/upgradeable-contracts/${networkName}/solc-${oldImplementationAddress}.json` + ) } parsedDeployments.deployments[proxyAddress] = { date: new Date().toISOString(), @@ -335,32 +531,64 @@ export class Blockchain extends Plugin { solcOutput: contractObject.compiler.data, solcInput: contractObject.compiler.source } - await this.call('fileManager', 'writeFile', `.deploys/upgradeable-contracts/${networkName}/solc-${implementationAddress}.json`, JSON.stringify({ - solcInput: contractObject.compiler.source, - solcOutput: contractObject.compiler.data - }, null, 2)) - await this.call('fileManager', 'writeFile', `.deploys/upgradeable-contracts/${networkName}/UUPS.json`, JSON.stringify(parsedDeployments, null, 2)) + await this.call( + 'fileManager', + 'writeFile', + `.deploys/upgradeable-contracts/${networkName}/solc-${implementationAddress}.json`, + JSON.stringify( + { + solcInput: contractObject.compiler.source, + solcOutput: contractObject.compiler.data + }, + null, + 2 + ) + ) + await this.call( + 'fileManager', + 'writeFile', + `.deploys/upgradeable-contracts/${networkName}/UUPS.json`, + JSON.stringify(parsedDeployments, null, 2) + ) } else { - await this.call('fileManager', 'writeFile', `.deploys/upgradeable-contracts/${networkName}/solc-${implementationAddress}.json`, JSON.stringify({ - solcInput: contractObject.compiler.source, - solcOutput: contractObject.compiler.data - }, null, 2)) - await this.call('fileManager', 'writeFile', `.deploys/upgradeable-contracts/${networkName}/UUPS.json`, JSON.stringify({ - id: networkInfo.id, - network: networkInfo.name, - deployments: { - [proxyAddress]: { - date: new Date().toISOString(), - contractName: contractName, - fork: networkInfo.currentFork, - implementationAddress: implementationAddress - } - } - }, null, 2)) + await this.call( + 'fileManager', + 'writeFile', + `.deploys/upgradeable-contracts/${networkName}/solc-${implementationAddress}.json`, + JSON.stringify( + { + solcInput: contractObject.compiler.source, + solcOutput: contractObject.compiler.data + }, + null, + 2 + ) + ) + await this.call( + 'fileManager', + 'writeFile', + `.deploys/upgradeable-contracts/${networkName}/UUPS.json`, + JSON.stringify( + { + id: networkInfo.id, + network: networkInfo.name, + deployments: { + [proxyAddress]: { + date: new Date().toISOString(), + contractName: contractName, + fork: networkInfo.currentFork, + implementationAddress: implementationAddress + } + } + }, + null, + 2 + ) + ) } } - async getEncodedFunctionHex (args, funABI) { + async getEncodedFunctionHex(args, funABI) { return new Promise((resolve, reject) => { txFormat.encodeFunctionCall(args, funABI, (error, data) => { if (error) return reject(error) @@ -369,7 +597,7 @@ export class Blockchain extends Plugin { }) } - async getEncodedParams (args, funABI) { + async getEncodedParams(args, funABI) { return new Promise((resolve, reject) => { txFormat.encodeParams(args, funABI, (error, encodedParams) => { if (error) return reject(error) @@ -378,31 +606,57 @@ export class Blockchain extends Plugin { }) } - createContract (selectedContract, data, continueCb, promptCb, confirmationCb, finalCb) { + createContract( + selectedContract, + data, + continueCb, + promptCb, + confirmationCb, + finalCb + ) { if (data) { data.contractName = selectedContract.name data.linkReferences = selectedContract.bytecodeLinkReferences data.contractABI = selectedContract.abi } - this.runTx({ data: data, useCall: false }, confirmationCb, continueCb, promptCb, + this.runTx( + {data: data, useCall: false}, + confirmationCb, + continueCb, + promptCb, (error, txResult, address) => { if (error) { - return finalCb(`creation of ${selectedContract.name} errored: ${error.message ? error.message : error}`) + return finalCb( + `creation of ${selectedContract.name} errored: ${ + error.message ? error.message : error + }` + ) } - if (txResult.receipt.status === false || txResult.receipt.status === '0x0' || txResult.receipt.status === 0) { - return finalCb(`creation of ${selectedContract.name} errored: transaction execution failed`) + if ( + txResult.receipt.status === false || + txResult.receipt.status === '0x0' || + txResult.receipt.status === 0 + ) { + return finalCb( + `creation of ${selectedContract.name} errored: transaction execution failed` + ) } finalCb(null, selectedContract, address) } ) } - determineGasPrice (cb) { + determineGasPrice(cb) { this.getCurrentProvider().getGasPrice((error, gasPrice) => { - const warnMessage = ' Please fix this issue before sending any transaction. ' + const warnMessage = + ' Please fix this issue before sending any transaction. ' if (error) { - return cb('Unable to retrieve the current network gas price.' + warnMessage + error) + return cb( + 'Unable to retrieve the current network gas price.' + + warnMessage + + error + ) } try { const gasPriceValue = this.fromWei(gasPrice, false, 'gwei') @@ -413,29 +667,35 @@ export class Blockchain extends Plugin { }) } - getInputs (funABI) { + getInputs(funABI) { if (!funABI.inputs) { return '' } return txHelper.inputParametersDeclarationToString(funABI.inputs) } - fromWei (value, doTypeConversion, unit) { + fromWei(value, doTypeConversion, unit) { if (doTypeConversion) { return Web3.utils.fromWei(typeConversion.toInt(value), unit || 'ether') } return Web3.utils.fromWei(value.toString(10), unit || 'ether') } - toWei (value, unit) { + toWei(value, unit) { return Web3.utils.toWei(value, unit || 'gwei') } - calculateFee (gas, gasPrice, unit?) { - return Web3.utils.toBN(gas).mul(Web3.utils.toBN(Web3.utils.toWei(gasPrice.toString(10) as string, unit || 'gwei'))) + calculateFee(gas, gasPrice, unit?) { + return Web3.utils + .toBN(gas) + .mul( + Web3.utils.toBN( + Web3.utils.toWei(gasPrice.toString(10) as string, unit || 'gwei') + ) + ) } - determineGasFees (tx) { + determineGasFees(tx) { const determineGasFeesCb = (gasPrice, cb) => { let txFeeText, priceStatus // TODO: this try catch feels like an anti pattern, can/should be @@ -445,7 +705,8 @@ export class Blockchain extends Plugin { txFeeText = ' ' + this.fromWei(fee, false, 'ether') + ' Ether' priceStatus = true } catch (e) { - txFeeText = ' Please fix this issue before sending any transaction. ' + e.message + txFeeText = + ' Please fix this issue before sending any transaction. ' + e.message priceStatus = false } cb(txFeeText, priceStatus) @@ -454,19 +715,25 @@ export class Blockchain extends Plugin { return determineGasFeesCb } - changeExecutionContext (context, confirmCb, infoCb, cb) { - return this.executionContext.executionContextChange(context, null, confirmCb, infoCb, cb) + changeExecutionContext(context, confirmCb, infoCb, cb) { + return this.executionContext.executionContextChange( + context, + null, + confirmCb, + infoCb, + cb + ) } - detectNetwork (cb) { + detectNetwork(cb) { return this.executionContext.detectNetwork(cb) } - getProvider () { + getProvider() { return this.executionContext.getProvider() } - getInjectedWeb3Address () { + getInjectedWeb3Address() { return this.executionContext.getSelectedAddress() } @@ -474,29 +741,29 @@ export class Blockchain extends Plugin { * return the fork name applied to the current envionment * @return {String} - fork name */ - getCurrentFork () { + getCurrentFork() { return this.executionContext.getCurrentFork() } - isWeb3Provider () { + isWeb3Provider() { const isVM = this.executionContext.isVM() const isInjected = this.getProvider() === 'injected' - return (!isVM && !isInjected) + return !isVM && !isInjected } - isInjectedWeb3 () { + isInjectedWeb3() { return this.getProvider() === 'injected' } - signMessage (message, account, passphrase, cb) { + signMessage(message, account, passphrase, cb) { this.getCurrentProvider().signMessage(message, account, passphrase, cb) } - web3VM () { + web3VM() { return (this.providers.vm as VMProvider).web3 } - web3 () { + web3() { // @todo(https://github.com/ethereum/remix-project/issues/431) const isVM = this.executionContext.isVM() if (isVM) { @@ -505,7 +772,7 @@ export class Blockchain extends Plugin { return this.executionContext.web3() } - getTxListener (opts) { + getTxListener(opts) { opts.event = { // udapp: this.udapp.event udapp: this.event @@ -514,85 +781,132 @@ export class Blockchain extends Plugin { return txlistener } - runOrCallContractMethod (contractName, contractAbi, funABI, contract, value, address, callType, lookupOnly, logMsg, logCallback, outputCb, confirmationCb, continueCb, promptCb) { + runOrCallContractMethod( + contractName, + contractAbi, + funABI, + contract, + value, + address, + callType, + lookupOnly, + logMsg, + logCallback, + outputCb, + confirmationCb, + continueCb, + promptCb + ) { // contractsDetails is used to resolve libraries - txFormat.buildData(contractName, contractAbi, {}, false, funABI, callType, (error, data) => { - if (error) { - return logCallback(`${logMsg} errored: ${error.message ? error.message : error}`) - } - if (!lookupOnly) { - logCallback(`${logMsg} pending ... `) - } else { - logCallback(`${logMsg}`) - } - if (funABI.type === 'fallback') data.dataHex = value - - if (data) { - data.contractName = contractName - data.contractABI = contractAbi - data.contract = contract - } - const useCall = funABI.stateMutability === 'view' || funABI.stateMutability === 'pure' - this.runTx({ to: address, data, useCall }, confirmationCb, continueCb, promptCb, (error, txResult, _address, returnValue) => { + txFormat.buildData( + contractName, + contractAbi, + {}, + false, + funABI, + callType, + (error, data) => { if (error) { - return logCallback(`${logMsg} errored: ${error.message ? error.message : error}`) + return logCallback( + `${logMsg} errored: ${error.message ? error.message : error}` + ) } - if (lookupOnly) { - outputCb(returnValue) + if (!lookupOnly) { + logCallback(`${logMsg} pending ... `) + } else { + logCallback(`${logMsg}`) } - }) - }, - (msg) => { - logCallback(msg) - }, - (data, runTxCallback) => { - // called for libraries deployment - this.runTx(data, confirmationCb, runTxCallback, promptCb, () => { /* Do nothing. */ }) - }) + if (funABI.type === 'fallback') data.dataHex = value + + if (data) { + data.contractName = contractName + data.contractABI = contractAbi + data.contract = contract + } + const useCall = + funABI.stateMutability === 'view' || funABI.stateMutability === 'pure' + this.runTx( + {to: address, data, useCall}, + confirmationCb, + continueCb, + promptCb, + (error, txResult, _address, returnValue) => { + if (error) { + return logCallback( + `${logMsg} errored: ${error.message ? error.message : error}` + ) + } + if (lookupOnly) { + outputCb(returnValue) + } + } + ) + }, + (msg) => { + logCallback(msg) + }, + (data, runTxCallback) => { + // called for libraries deployment + this.runTx(data, confirmationCb, runTxCallback, promptCb, () => { + /* Do nothing. */ + }) + } + ) } - context () { - return (this.executionContext.isVM() ? 'memory' : 'blockchain') + context() { + return this.executionContext.isVM() ? 'memory' : 'blockchain' } // NOTE: the config is only needed because exectuionContext.init does - async resetAndInit (config: Config, transactionContextAPI: TransactionContextAPI) { + async resetAndInit( + config: Config, + transactionContextAPI: TransactionContextAPI + ) { this.transactionContextAPI = transactionContextAPI this.executionContext.init(config) this.executionContext.stopListenOnLastBlock() this.executionContext.listenOnLastBlock() } - addProvider (provider) { + addProvider(provider) { this.executionContext.addProvider(provider) } - removeProvider (name) { + removeProvider(name) { this.executionContext.removeProvider(name) } // TODO : event should be triggered by Udapp instead of TxListener /** Listen on New Transaction. (Cannot be done inside constructor because txlistener doesn't exist yet) */ - startListening (txlistener) { + startListening(txlistener) { txlistener.event.register('newTransaction', (tx, receipt) => { this.events.emit('newTransaction', tx, receipt) }) } - async resetEnvironment () { + async resetEnvironment() { await this.getCurrentProvider().resetEnvironment() // TODO: most params here can be refactored away in txRunner - const web3Runner = new TxRunnerWeb3({ - config: this.config, - detectNetwork: (cb) => { - this.executionContext.detectNetwork(cb) + const web3Runner = new TxRunnerWeb3( + { + config: this.config, + detectNetwork: (cb) => { + this.executionContext.detectNetwork(cb) + }, + isVM: () => { + return this.executionContext.isVM() + }, + personalMode: () => { + return this.getProvider() === 'web3' + ? this.config.get('settings/personal-mode') + : false + } }, - isVM: () => { return this.executionContext.isVM() }, - personalMode: () => { - return this.getProvider() === 'web3' ? this.config.get('settings/personal-mode') : false - } - }, _ => this.executionContext.web3(), _ => this.executionContext.currentblockGasLimit()) - + (_) => this.executionContext.web3(), + (_) => this.executionContext.currentblockGasLimit() + ) + web3Runner.event.register('transactionBroadcasted', (txhash) => { this.executionContext.detectNetwork((error, network) => { if (error || !network) return @@ -600,10 +914,13 @@ export class Blockchain extends Plugin { const viewEtherScanLink = etherScanLink(network.name, txhash) if (viewEtherScanLink) { - this.call('terminal', 'logHtml', - ( - view on etherscan - )) + this.call( + 'terminal', + 'logHtml', + + view on etherscan + + ) } }) }) @@ -614,23 +931,25 @@ export class Blockchain extends Plugin { * Create a VM Account * @param {{privateKey: string, balance: string}} newAccount The new account to create */ - createVMAccount (newAccount) { + createVMAccount(newAccount) { if (!this.executionContext.isVM()) { - throw new Error('plugin API does not allow creating a new account through web3 connection. Only vm mode is allowed') + throw new Error( + 'plugin API does not allow creating a new account through web3 connection. Only vm mode is allowed' + ) } return (this.providers.vm as VMProvider).createVMAccount(newAccount) } - newAccount (_password, passwordPromptCb, cb) { + newAccount(_password, passwordPromptCb, cb) { return this.getCurrentProvider().newAccount(passwordPromptCb, cb) } /** Get the balance of an address, and convert wei to ether */ - getBalanceInEther (address) { + getBalanceInEther(address) { return this.getCurrentProvider().getBalanceInEther(address) } - pendingTransactionsCount () { + pendingTransactionsCount() { return Object.keys(this.txRunner.pendingTxs).length } @@ -638,7 +957,7 @@ export class Blockchain extends Plugin { return await this.web3().eth.getCode(address) } - async getTransactionReceipt (hash) { + async getTransactionReceipt(hash) { return await this.web3().eth.getTransactionReceipt(hash) } @@ -648,27 +967,41 @@ export class Blockchain extends Plugin { * * @param {Object} tx - transaction. */ - sendTransaction (tx: Transaction) { + sendTransaction(tx: Transaction) { return new Promise((resolve, reject) => { this.executionContext.detectNetwork((error, network) => { if (error) return reject(error) if (network.name === 'Main' && network.id === '1') { - return reject(new Error('It is not allowed to make this action against mainnet')) + return reject( + new Error('It is not allowed to make this action against mainnet') + ) } this.txRunner.rawRun( tx, - (network, tx, gasEstimation, continueTxExecution, cancelCb) => { continueTxExecution() }, - (error, continueTxExecution, cancelCb) => { if (error) { reject(error) } else { continueTxExecution() } }, - (okCb, cancelCb) => { okCb() }, + (network, tx, gasEstimation, continueTxExecution, cancelCb) => { + continueTxExecution() + }, + (error, continueTxExecution, cancelCb) => { + if (error) { + reject(error) + } else { + continueTxExecution() + } + }, + (okCb, cancelCb) => { + okCb() + }, async (error, result) => { if (error) return reject(error) try { if (this.executionContext.isVM()) { - const execResult = await this.web3().eth.getExecutionResultFromSimulator(result.transactionHash) + const execResult = + await this.web3().eth.getExecutionResultFromSimulator( + result.transactionHash + ) resolve(resultToRemixTx(result, execResult)) - } else - resolve(resultToRemixTx(result)) + } else resolve(resultToRemixTx(result)) } catch (e) { reject(e) } @@ -678,7 +1011,7 @@ export class Blockchain extends Plugin { }) } - async runTx (args, confirmationCb, continueCb, promptCb, cb) { + async runTx(args, confirmationCb, continueCb, promptCb, cb) { const getGasLimit = () => { return new Promise((resolve, reject) => { if (this.transactionContextAPI.getGasLimit) { @@ -712,7 +1045,10 @@ export class Blockchain extends Plugin { if (this.transactionContextAPI.getAddress) { return this.transactionContextAPI.getAddress(function (err, address) { if (err) return reject(err) - if (!address) return reject('"from" is not defined. Please make sure an account is selected. If you are using a public node, it is likely that no account will be provided. In that case, add the public node to your injected provider (type Metamask) and use injected provider in Remix.') + if (!address) + return reject( + '"from" is not defined. Please make sure an account is selected. If you are using a public node, it is likely that no account will be provided. In that case, add the public node to your injected provider (type Metamask) and use injected provider in Remix.' + ) return resolve(address) }) } @@ -721,7 +1057,10 @@ export class Blockchain extends Plugin { const address = accounts[0] if (!address) return reject('No accounts available') - if (this.executionContext.isVM() && !this.providers.vm.RemixSimulatorProvider.Accounts.accounts[address]) { + if ( + this.executionContext.isVM() && + !this.providers.vm.RemixSimulatorProvider.Accounts.accounts[address] + ) { return reject('Invalid account selected') } return resolve(address) @@ -743,46 +1082,85 @@ export class Blockchain extends Plugin { return } - const tx = { to: args.to, data: args.data.dataHex, useCall: args.useCall, from: fromAddress, value: value, gasLimit: gasLimit, timestamp: args.data.timestamp } - const payLoad = { funAbi: args.data.funAbi, funArgs: args.data.funArgs, contractBytecode: args.data.contractBytecode, contractName: args.data.contractName, contractABI: args.data.contractABI, linkReferences: args.data.linkReferences } + const tx = { + to: args.to, + data: args.data.dataHex, + useCall: args.useCall, + from: fromAddress, + value: value, + gasLimit: gasLimit, + timestamp: args.data.timestamp + } + const payLoad = { + funAbi: args.data.funAbi, + funArgs: args.data.funArgs, + contractBytecode: args.data.contractBytecode, + contractName: args.data.contractName, + contractABI: args.data.contractABI, + linkReferences: args.data.linkReferences + } if (!tx.timestamp) tx.timestamp = Date.now() const timestamp = tx.timestamp this._triggerEvent('initiatingTransaction', [timestamp, tx, payLoad]) try { - this.txRunner.rawRun(tx, confirmationCb, continueCb, promptCb, + this.txRunner.rawRun( + tx, + confirmationCb, + continueCb, + promptCb, async (error, result) => { if (error) { - if (typeof (error) !== 'string') { + if (typeof error !== 'string') { if (error.message) error = error.message else { - try { error = 'error: ' + JSON.stringify(error) } catch (e) { console.log(e) } + try { + error = 'error: ' + JSON.stringify(error) + } catch (e) { + console.log(e) + } } } return reject(error) } - + const isVM = this.executionContext.isVM() if (isVM && tx.useCall) { try { - result.transactionHash = await this.web3().eth.getHashFromTagBySimulator(timestamp) + result.transactionHash = + await this.web3().eth.getHashFromTagBySimulator(timestamp) } catch (e) { console.log('unable to retrieve back the "call" hash', e) } } - const eventName = (tx.useCall ? 'callExecuted' : 'transactionExecuted') - - this._triggerEvent(eventName, [error, tx.from, tx.to, tx.data, tx.useCall, result, timestamp, payLoad]) - return resolve({ result, tx }) + const eventName = tx.useCall + ? 'callExecuted' + : 'transactionExecuted' + + this._triggerEvent(eventName, [ + error, + tx.from, + tx.to, + tx.data, + tx.useCall, + result, + timestamp, + payLoad + ]) + return resolve({result, tx}) } ) } catch (err) { let error = err - if (error && (typeof (error) !== 'string')) { + if (error && typeof error !== 'string') { if (error.message) error = error.message else { - try { error = 'error: ' + JSON.stringify(error) } catch (e) { console.log(e) } + try { + error = 'error: ' + JSON.stringify(error) + } catch (e) { + console.log(e) + } } } return reject(error) @@ -804,49 +1182,71 @@ export class Blockchain extends Plugin { let execResult let returnValue = null if (isVM) { - const hhlogs = await this.web3().eth.getHHLogsForTx(txResult.transactionHash) + const hhlogs = await this.web3().eth.getHHLogsForTx( + txResult.transactionHash + ) if (hhlogs && hhlogs.length) { - const finalLogs =
console.log:
- { - hhlogs.map((log) => { + const finalLogs = ( +
+
+ console.log: +
+ {hhlogs.map((log) => { let formattedLog // Hardhat implements the same formatting options that can be found in Node.js' console.log, // which in turn uses util.format: https://nodejs.org/dist/latest-v12.x/docs/api/util.html#util_util_format_format_args // For example: console.log("Name: %s, Age: %d", remix, 6) will log 'Name: remix, Age: 6' // We check first arg to determine if 'util.format' is needed - if (typeof log[0] === 'string' && (log[0].includes('%s') || log[0].includes('%d'))) { + if ( + typeof log[0] === 'string' && + (log[0].includes('%s') || log[0].includes('%d')) + ) { formattedLog = format(log[0], ...log.slice(1)) } else { formattedLog = log.join(' ') } return
{formattedLog}
})} -
+
+ ) _paq.push(['trackEvent', 'udapp', 'hardhat', 'console.log']) this.call('terminal', 'logHtml', finalLogs) } - execResult = await this.web3().eth.getExecutionResultFromSimulator(txResult.transactionHash) + execResult = await this.web3().eth.getExecutionResultFromSimulator( + txResult.transactionHash + ) if (execResult) { // if it's not the VM, we don't have return value. We only have the transaction, and it does not contain the return value. - returnValue = execResult ? toBuffer(execResult.returnValue) : toBuffer(addHexPrefix(txResult.result) || '0x0000000000000000000000000000000000000000000000000000000000000000') - const compiledContracts = await this.call('compilerArtefacts', 'getAllContractDatas') - const vmError = txExecution.checkVMError(execResult, compiledContracts) + returnValue = execResult + ? toBuffer(execResult.returnValue) + : toBuffer( + addHexPrefix(txResult.result) || + '0x0000000000000000000000000000000000000000000000000000000000000000' + ) + const compiledContracts = await this.call( + 'compilerArtefacts', + 'getAllContractDatas' + ) + const vmError = txExecution.checkVMError( + execResult, + compiledContracts + ) if (vmError.error) { return cb(vmError.message) } } } - + if (!isVM && tx && tx.useCall) { returnValue = toBuffer(addHexPrefix(txResult.result)) } - + let address = null if (txResult && txResult.receipt) { address = txResult.receipt.contractAddress } - + cb(null, txResult, address, returnValue) } catch (error) { cb(error) diff --git a/apps/remix-ide/src/index.tsx b/apps/remix-ide/src/index.tsx index 92a0206003..75b6880c76 100644 --- a/apps/remix-ide/src/index.tsx +++ b/apps/remix-ide/src/index.tsx @@ -1,19 +1,18 @@ // eslint-disable-next-line no-use-before-define import React from 'react' -import { render } from 'react-dom' +import {render} from 'react-dom' import './index.css' -import { ThemeModule } from './app/tabs/theme-module' -import { Preload } from './app/components/preload' +import {ThemeModule} from './app/tabs/theme-module' +import {Preload} from './app/components/preload' import Config from './config' import Registry from './app/state/registry' -import { Storage } from '@remix-project/remix-lib' - -(async function () { +import {Storage} from '@remix-project/remix-lib' +;(async function () { try { const configStorage = new Storage('config-v0.8:') - const config = new Config(configStorage); - Registry.getInstance().put({ api: config, name: 'config' }) - } catch (e) { } + const config = new Config(configStorage) + Registry.getInstance().put({api: config, name: 'config'}) + } catch (e) {} const theme = new ThemeModule() theme.initTheme() @@ -24,5 +23,3 @@ import { Storage } from '@remix-project/remix-lib' document.getElementById('root') ) })() - - diff --git a/apps/remix-ide/webpack.config.js b/apps/remix-ide/webpack.config.js index b34b7dcb11..d8ce82562f 100644 --- a/apps/remix-ide/webpack.config.js +++ b/apps/remix-ide/webpack.config.js @@ -1,11 +1,11 @@ -const { composePlugins, withNx } = require('@nrwl/webpack') -const { withReact } = require('@nrwl/react') +const {composePlugins, withNx} = require('@nrwl/webpack') +const {withReact} = require('@nrwl/react') const webpack = require('webpack') -const CopyPlugin = require("copy-webpack-plugin") +const CopyPlugin = require('copy-webpack-plugin') const version = require('../../package.json').version const fs = require('fs') -const TerserPlugin = require("terser-webpack-plugin") -const CssMinimizerPlugin = require("css-minimizer-webpack-plugin") +const TerserPlugin = require('terser-webpack-plugin') +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') const axios = require('axios') const versionData = { @@ -16,12 +16,18 @@ const versionData = { const loadLocalSolJson = async () => { // execute apps/remix-ide/ci/downloadsoljson.sh - const child = require('child_process').execSync('bash ./apps/remix-ide/ci/downloadsoljson.sh', { encoding: 'utf8', cwd: process.cwd(), shell: true }) + const child = require('child_process').execSync( + 'bash ./apps/remix-ide/ci/downloadsoljson.sh', + {encoding: 'utf8', cwd: process.cwd(), shell: true} + ) // show output console.log(child) } -fs.writeFileSync('./apps/remix-ide/src/assets/version.json', JSON.stringify(versionData)) +fs.writeFileSync( + './apps/remix-ide/src/assets/version.json', + JSON.stringify(versionData) +) loadLocalSolJson() @@ -32,9 +38,8 @@ const implicitDependencies = JSON.parse(project).implicitDependencies const copyPatterns = implicitDependencies.map((dep) => { try { fs.statSync(__dirname + `/../../dist/apps/${dep}`).isDirectory() - return { from: `../../dist/apps/${dep}`, to: `plugins/${dep}` } - } - catch (e) { + return {from: `../../dist/apps/${dep}`, to: `plugins/${dep}`} + } catch (e) { console.log('error', e) return false } @@ -50,30 +55,29 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { // add fallback for node modules config.resolve.fallback = { ...config.resolve.fallback, - "crypto": require.resolve("crypto-browserify"), - "stream": require.resolve("stream-browserify"), - "path": require.resolve("path-browserify"), - "http": require.resolve("stream-http"), - "https": require.resolve("https-browserify"), - "constants": require.resolve("constants-browserify"), - "os": false, //require.resolve("os-browserify/browser"), - "timers": false, // require.resolve("timers-browserify"), - "zlib": require.resolve("browserify-zlib"), - "fs": false, - "module": false, - "tls": false, - "net": false, - "readline": false, - "child_process": false, - "buffer": require.resolve("buffer/"), - "vm": require.resolve('vm-browserify'), + crypto: require.resolve('crypto-browserify'), + stream: require.resolve('stream-browserify'), + path: require.resolve('path-browserify'), + http: require.resolve('stream-http'), + https: require.resolve('https-browserify'), + constants: require.resolve('constants-browserify'), + os: false, //require.resolve("os-browserify/browser"), + timers: false, // require.resolve("timers-browserify"), + zlib: require.resolve('browserify-zlib'), + fs: false, + module: false, + tls: false, + net: false, + readline: false, + child_process: false, + buffer: require.resolve('buffer/'), + vm: require.resolve('vm-browserify') } - // add externals config.externals = { ...config.externals, - solc: 'solc', + solc: 'solc' } // add public path @@ -83,12 +87,14 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { config.output.filename = `[name].${versionData.version}.${versionData.timestamp}.js` config.output.chunkFilename = `[name].${versionData.version}.${versionData.timestamp}.js` - // add copy & provide plugin config.plugins.push( new CopyPlugin({ patterns: [ - { from: '../../node_modules/monaco-editor/min/vs', to: 'assets/js/monaco-editor/min/vs' }, + { + from: '../../node_modules/monaco-editor/min/vs', + to: 'assets/js/monaco-editor/min/vs' + }, ...copyPatterns ].filter(Boolean) }), @@ -96,15 +102,15 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'], url: ['url', 'URL'], - process: 'process/browser', + process: 'process/browser' }) ) // souce-map loader config.module.rules.push({ test: /\.js$/, - use: ["source-map-loader"], - enforce: "pre" + use: ['source-map-loader'], + enforce: 'pre' }) config.ignoreWarnings = [/Failed to parse source map/, /require function/] // ignore source-map-loader warnings & AST warnings @@ -118,23 +124,23 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { compress: false, mangle: false, format: { - comments: false, - }, + comments: false + } }, - extractComments: false, + extractComments: false }), - new CssMinimizerPlugin(), - ]; + new CssMinimizerPlugin() + ] config.watchOptions = { ignored: /node_modules/ } - return config; -}); + return config +}) class CopyFileAfterBuild { - apply(compiler) { + apply(compiler) { const onEnd = async () => { try { console.log('runnning CopyFileAfterBuild') @@ -142,17 +148,20 @@ class CopyFileAfterBuild { // This is needed because by default the etherscan resources are served from the /plugins/etherscan/ folder, // but the raw-loader try to access the resources from the root folder. const files = fs.readdirSync('./dist/apps/etherscan') - files.forEach(file => { + files.forEach((file) => { if (file.includes('plugin-etherscan')) { - fs.copyFileSync('./dist/apps/etherscan/' + file, './dist/apps/remix-ide/' + file) - } + fs.copyFileSync( + './dist/apps/etherscan/' + file, + './dist/apps/remix-ide/' + file + ) + } }) } catch (e) { - console.error('running CopyFileAfterBuild failed with error: ' + e.message) - } + console.error( + 'running CopyFileAfterBuild failed with error: ' + e.message + ) + } } - compiler.hooks.afterEmit.tapPromise('FileManagerPlugin', onEnd); + compiler.hooks.afterEmit.tapPromise('FileManagerPlugin', onEnd) } } - - diff --git a/apps/solhint/src/app/App.tsx b/apps/solhint/src/app/App.tsx index ac1eae48b3..929d6c6658 100644 --- a/apps/solhint/src/app/App.tsx +++ b/apps/solhint/src/app/App.tsx @@ -1,8 +1,8 @@ -import React, { useEffect, useState } from "react"; -import { SolHint } from "./SolhintPluginClient"; +import React, {useEffect, useState} from 'react' +import {SolHint} from './SolhintPluginClient' -const client = new SolHint(); +const client = new SolHint() export default function App() { - return <>; + return <> } diff --git a/apps/solhint/webpack.config.js b/apps/solhint/webpack.config.js index 2e3893c15c..a52cc43bf1 100644 --- a/apps/solhint/webpack.config.js +++ b/apps/solhint/webpack.config.js @@ -1,18 +1,18 @@ -const { composePlugins, withNx } = require('@nrwl/webpack') -const { withReact } = require('@nrwl/react') +const {composePlugins, withNx} = require('@nrwl/webpack') +const {withReact} = require('@nrwl/react') const webpack = require('webpack') -const TerserPlugin = require("terser-webpack-plugin") -const CssMinimizerPlugin = require("css-minimizer-webpack-plugin") +const TerserPlugin = require('terser-webpack-plugin') +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') // Nx plugins for webpack. module.exports = composePlugins(withNx(), withReact(), (config) => { // Update the webpack config as needed here. config.resolve.fallback = { ...config.resolve.fallback, - "path": false, - "os": false, - "fs": false, - "module": false, + path: false, + os: false, + fs: false, + module: false } // add public path @@ -23,18 +23,18 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'], url: ['url', 'URL'], - process: 'process/browser', + process: 'process/browser' }), new webpack.DefinePlugin({ - "BROWSER": true, - }), + BROWSER: true + }) ) // souce-map loader config.module.rules.push({ test: /\.js$/, - use: ["source-map-loader"], - enforce: "pre" + use: ['source-map-loader'], + enforce: 'pre' }) config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings @@ -48,13 +48,13 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { compress: false, mangle: false, format: { - comments: false, - }, + comments: false + } }, - extractComments: false, + extractComments: false }), - new CssMinimizerPlugin(), - ]; + new CssMinimizerPlugin() + ] - return config; + return config }) diff --git a/apps/solidity-compiler/src/app/app.tsx b/apps/solidity-compiler/src/app/app.tsx index 7115b1509a..e9c636ac3d 100644 --- a/apps/solidity-compiler/src/app/app.tsx +++ b/apps/solidity-compiler/src/app/app.tsx @@ -1,9 +1,9 @@ /* eslint-disable no-use-before-define */ import React from 'react' -import { SolidityCompiler } from '@remix-ui/solidity-compiler' // eslint-disable-line +import {SolidityCompiler} from '@remix-ui/solidity-compiler' // eslint-disable-line -import { CompilerClientApi } from './compiler' +import {CompilerClientApi} from './compiler' const remix = new CompilerClientApi() diff --git a/apps/solidity-compiler/webpack.config.js b/apps/solidity-compiler/webpack.config.js index e19684ca91..39edff4cc6 100644 --- a/apps/solidity-compiler/webpack.config.js +++ b/apps/solidity-compiler/webpack.config.js @@ -1,10 +1,10 @@ -const { composePlugins, withNx } = require('@nrwl/webpack') -const { withReact } = require('@nrwl/react') +const {composePlugins, withNx} = require('@nrwl/webpack') +const {withReact} = require('@nrwl/react') const webpack = require('webpack') const version = require('../../package.json').version const fs = require('fs') -const TerserPlugin = require("terser-webpack-plugin") -const CssMinimizerPlugin = require("css-minimizer-webpack-plugin") +const TerserPlugin = require('terser-webpack-plugin') +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') const versionData = { version: version, @@ -12,7 +12,10 @@ const versionData = { mode: process.env.NODE_ENV === 'production' ? 'production' : 'development' } -fs.writeFileSync('./apps/remix-ide/src/assets/version.json', JSON.stringify(versionData)) +fs.writeFileSync( + './apps/remix-ide/src/assets/version.json', + JSON.stringify(versionData) +) // Nx plugins for webpack. module.exports = composePlugins(withNx(), withReact(), (config) => { @@ -22,56 +25,52 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { // add fallback for node modules config.resolve.fallback = { ...config.resolve.fallback, - "crypto": require.resolve("crypto-browserify"), - "stream": require.resolve("stream-browserify"), - "path": require.resolve("path-browserify"), - "http": require.resolve("stream-http"), - "https": require.resolve("https-browserify"), - "constants": require.resolve("constants-browserify"), - "os": false, //require.resolve("os-browserify/browser"), - "timers": false, // require.resolve("timers-browserify"), - "zlib": require.resolve("browserify-zlib"), - "fs": false, - "module": false, - "tls": false, - "net": false, - "readline": false, - "child_process": false, - "buffer": require.resolve("buffer/"), - "vm": require.resolve('vm-browserify'), + crypto: require.resolve('crypto-browserify'), + stream: require.resolve('stream-browserify'), + path: require.resolve('path-browserify'), + http: require.resolve('stream-http'), + https: require.resolve('https-browserify'), + constants: require.resolve('constants-browserify'), + os: false, //require.resolve("os-browserify/browser"), + timers: false, // require.resolve("timers-browserify"), + zlib: require.resolve('browserify-zlib'), + fs: false, + module: false, + tls: false, + net: false, + readline: false, + child_process: false, + buffer: require.resolve('buffer/'), + vm: require.resolve('vm-browserify') } - // add externals config.externals = { ...config.externals, - solc: 'solc', + solc: 'solc' } // add public path config.output.publicPath = '/' - - // add copy & provide plugin config.plugins.push( new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'], url: ['url', 'URL'], - process: 'process/browser', + process: 'process/browser' }) ) // souce-map loader config.module.rules.push({ test: /\.js$/, - use: ["source-map-loader"], - enforce: "pre" + use: ['source-map-loader'], + enforce: 'pre' }) config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings - // set minimizer config.optimization.minimizer = [ new TerserPlugin({ @@ -81,17 +80,17 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { compress: false, mangle: false, format: { - comments: false, - }, + comments: false + } }, - extractComments: false, + extractComments: false }), - new CssMinimizerPlugin(), - ]; + new CssMinimizerPlugin() + ] config.watchOptions = { ignored: /node_modules/ } - return config; -}); + return config +}) diff --git a/apps/vyper/src/app/app.tsx b/apps/vyper/src/app/app.tsx index e5f9d80159..a3ce721b0b 100644 --- a/apps/vyper/src/app/app.tsx +++ b/apps/vyper/src/app/app.tsx @@ -1,7 +1,7 @@ -import React, { useState, useEffect } from 'react' +import React, {useState, useEffect} from 'react' -import { VyperCompilationOutput, remixClient } from './utils' -import { CompilationResult } from '@remixproject/plugin-api' +import {VyperCompilationOutput, remixClient} from './utils' +import {CompilationResult} from '@remixproject/plugin-api' // Components import CompilerButton from './components/CompilerButton' @@ -38,7 +38,7 @@ const App: React.FC = () => { async function start() { try { await remixClient.loaded() - remixClient.onFileChange(name => setContract(name)) + remixClient.onFileChange((name) => setContract(name)) remixClient.onNoFileSelected(() => setContract('')) } catch (err) { console.log(err) @@ -53,11 +53,11 @@ const App: React.FC = () => { /** Update the environment state value */ function setEnvironment(environment: 'local' | 'remote') { - setState({ ...state, environment }) + setState({...state, environment}) } function setLocalUrl(url: string) { - setState({ ...state, localUrl: url }) + setState({...state, localUrl: url}) } function compilerUrl() { @@ -78,12 +78,16 @@ const App: React.FC = () => { href="https://github.com/ethereum/remix-project/tree/master/apps/vyper" target="_blank" > - +
-
@@ -93,10 +97,20 @@ const App: React.FC = () => { type="radio" value={state.environment} > - + Remote Compiler v0.2.16 - + Local Compiler @@ -110,9 +124,7 @@ const App: React.FC = () => { - setOutput({ ...output, [name]: update }) - } + setOutput={(name, update) => setOutput({...output, [name]: update})} />
diff --git a/apps/vyper/src/app/components/CompilerButton.tsx b/apps/vyper/src/app/components/CompilerButton.tsx index fba082575b..fd4687d5a1 100644 --- a/apps/vyper/src/app/components/CompilerButton.tsx +++ b/apps/vyper/src/app/components/CompilerButton.tsx @@ -11,12 +11,11 @@ import Button from 'react-bootstrap/Button' interface Props { compilerUrl: string - contract?: string, + contract?: string setOutput: (name: string, output: VyperCompilationOutput) => void } -function CompilerButton({ contract, setOutput, compilerUrl }: Props) { - +function CompilerButton({contract, setOutput, compilerUrl}: Props) { if (!contract || !contract) { return } @@ -33,9 +32,9 @@ function CompilerButton({ contract, setOutput, compilerUrl }: Props) { try { _contract = await remixClient.getContract() } catch (e: any) { - setOutput('', { status: 'failed', message: e.message}) + setOutput('', {status: 'failed', message: e.message}) return - } + } remixClient.changeStatus({ key: 'loading', type: 'info', @@ -45,17 +44,17 @@ function CompilerButton({ contract, setOutput, compilerUrl }: Props) { try { output = await compile(compilerUrl, _contract) } catch (e: any) { - setOutput(_contract.name, { status: 'failed', message: e.message}) + setOutput(_contract.name, {status: 'failed', message: e.message}) return - } + } setOutput(_contract.name, output) // ERROR if (isCompilationError(output)) { const line = output.line if (line) { const lineColumnPos = { - start: { line: line - 1, column: 10 }, - end: { line: line - 1, column: 10 } + start: {line: line - 1, column: 10}, + end: {line: line - 1, column: 10} } remixClient.highlight(lineColumnPos as any, _contract.name, '#e0b4b4') } else { @@ -69,15 +68,20 @@ function CompilerButton({ contract, setOutput, compilerUrl }: Props) { errorIndex = errorIndex + 4 if (message && message.split('\n\n').length > 0) { try { - message = message.split('\n\n')[message.split('\n\n').length - 1] - } catch (e) {} + message = + message.split('\n\n')[message.split('\n\n').length - 1] + } catch (e) {} } if (location.length > 0) { const lineColumnPos = { - start: { line: parseInt(location[0]) - 1, column: 10 }, - end: { line: parseInt(location[0]) - 1, column: 10 } + start: {line: parseInt(location[0]) - 1, column: 10}, + end: {line: parseInt(location[0]) - 1, column: 10} } - remixClient.highlight(lineColumnPos as any, _contract.name, message) + remixClient.highlight( + lineColumnPos as any, + _contract.name, + message + ) } }) } @@ -103,9 +107,17 @@ function CompilerButton({ contract, setOutput, compilerUrl }: Props) { } return ( - ) } diff --git a/apps/vyper/src/app/components/LocalUrl.tsx b/apps/vyper/src/app/components/LocalUrl.tsx index 47acde9dad..18275b1714 100644 --- a/apps/vyper/src/app/components/LocalUrl.tsx +++ b/apps/vyper/src/app/components/LocalUrl.tsx @@ -3,12 +3,11 @@ import Form from 'react-bootstrap/Form' interface Props { url: string - setUrl: (url: string) => void, + setUrl: (url: string) => void environment: 'remote' | 'local' } -function LocalUrlInput({ url, setUrl, environment }: Props) { - +function LocalUrlInput({url, setUrl, environment}: Props) { if (environment === 'remote') { return <> } @@ -20,17 +19,20 @@ function LocalUrlInput({ url, setUrl, environment }: Props) { return (
- Currently we support vyper version > 0.2.16 + + {'Currently we support vyper version > 0.2.16'} + Local Compiler Url - - - + placeholder="eg http://localhost:8000/compile" + /> +
) } -export default LocalUrlInput; +export default LocalUrlInput diff --git a/apps/vyper/src/app/components/VyperResult.tsx b/apps/vyper/src/app/components/VyperResult.tsx index 44ccba7b7f..b91487e65d 100644 --- a/apps/vyper/src/app/components/VyperResult.tsx +++ b/apps/vyper/src/app/components/VyperResult.tsx @@ -1,75 +1,93 @@ -import React, { useState } from 'react'; +import React, {useState} from 'react' import { VyperCompilationResult, VyperCompilationOutput, - isCompilationError, -} from '../utils'; + isCompilationError +} from '../utils' import Tabs from 'react-bootstrap/Tabs' import Tab from 'react-bootstrap/Tab' -import Button from 'react-bootstrap/Button'; +import Button from 'react-bootstrap/Button' import JSONTree from 'react-json-view' -import { CopyToClipboard } from '@remix-ui/clipboard' +import {CopyToClipboard} from '@remix-ui/clipboard' interface VyperResultProps { - output?: VyperCompilationOutput; + output?: VyperCompilationOutput } export type ExampleContract = { - name: string, + name: string address: string } -function VyperResult({ output }: VyperResultProps) { - const [ active, setActive ] = useState('abi') +function VyperResult({output}: VyperResultProps) { + const [active, setActive] = useState('abi') - if (!output) return ( - -
-

No contract compiled yet.

-
- ) + if (!output) + return ( +
+

No contract compiled yet.

+
+ ) if (isCompilationError(output)) { return (
-
{output.message}
+
+          {output.message}
+        
) } return ( - setActive(key)}> + setActive(key)} + > JSON.stringify(output.abi)}> - + output.bytecode}> - + output.bytecode_runtime}> - + output.ir}> - + - ); + ) } -export default VyperResult; \ No newline at end of file +export default VyperResult diff --git a/apps/vyper/src/app/components/WarnRemote.tsx b/apps/vyper/src/app/components/WarnRemote.tsx index 107ab13335..fbdb60db81 100644 --- a/apps/vyper/src/app/components/WarnRemote.tsx +++ b/apps/vyper/src/app/components/WarnRemote.tsx @@ -4,15 +4,17 @@ interface Props { environment: 'remote' | 'local' } -function WarnRemoteLabel({ environment }: Props) { - +function WarnRemoteLabel({environment}: Props) { if (environment === 'local') { return <> } return ( - The remote compiler should only be used for testing NOT for production environments. For production, use a local compiler. + + The remote compiler should only be used for testing NOT for production + environments. For production, use a local compiler. + ) } -export default WarnRemoteLabel; \ No newline at end of file +export default WarnRemoteLabel diff --git a/apps/vyper/src/app/utils/compiler.tsx b/apps/vyper/src/app/utils/compiler.tsx index 0b65c65a1a..013f126bf6 100644 --- a/apps/vyper/src/app/utils/compiler.tsx +++ b/apps/vyper/src/app/utils/compiler.tsx @@ -1,16 +1,16 @@ -import { CompilationResult, ABIDescription } from "@remixproject/plugin-api"; +import {CompilationResult, ABIDescription} from '@remixproject/plugin-api' export interface Contract { - name: string; - content: string; + name: string + content: string } export interface VyperCompilationResult { - status: 'success', - bytecode: string, - bytecode_runtime: string, - abi: ABIDescription[], - ir: string, + status: 'success' + bytecode: string + bytecode_runtime: string + abi: ABIDescription[] + ir: string method_identifiers: { [method: string]: string } @@ -23,19 +23,26 @@ export interface VyperCompilationError { message: string } -export type VyperCompilationOutput = VyperCompilationResult | VyperCompilationError +export type VyperCompilationOutput = + | VyperCompilationResult + | VyperCompilationError /** Check if the output is an error */ -export function isCompilationError(output: VyperCompilationOutput): output is VyperCompilationError { +export function isCompilationError( + output: VyperCompilationOutput +): output is VyperCompilationError { return output.status === 'failed' } /** * Compile the a contract - * @param url The url of the compiler + * @param url The url of the compiler * @param contract The name and content of the contract */ -export async function compile(url: string, contract: Contract): Promise { +export async function compile( + url: string, + contract: Contract +): Promise { if (!contract.name) { throw new Error('Set your Vyper contract file.') } @@ -45,8 +52,8 @@ export async function compile(url: string, contract: Contract): Promise>(this); + private client = createClient>(this) loaded() { return this.client.onload() @@ -14,9 +18,13 @@ export class RemixClient extends PluginClient { /** Emit an event when file changed */ async onFileChange(cb: (contract: string) => any) { - this.client.on('fileManager', 'currentFileChanged', async (name: string) => { - cb(name) - }) + this.client.on( + 'fileManager', + 'currentFileChanged', + async (name: string) => { + cb(name) + } + ) } /** Emit an event when file changed */ @@ -29,8 +37,17 @@ export class RemixClient extends PluginClient { /** Load Ballot contract example into the file manager */ async loadContract({name, address}: ExampleContract) { try { - const content = await this.client.call('contentImport', 'resolve', address) - await this.client.call('fileManager', 'setFile', content.cleanUrl, content.content) + const content = await this.client.call( + 'contentImport', + 'resolve', + address + ) + await this.client.call( + 'fileManager', + 'setFile', + content.cleanUrl, + content.content + ) await this.client.call('fileManager', 'switchFile', content.cleanUrl) } catch (err) { console.log(err) @@ -43,9 +60,18 @@ export class RemixClient extends PluginClient { this.call('notification', 'toast', 'cloning Vyper repository...') await this.call('manager', 'activatePlugin', 'dGitProvider') // @ts-ignore - await this.call('dGitProvider', 'clone', { url: 'https://github.com/vyperlang/vyper', token: null }, 'vyper-lang') + await this.call( + 'dGitProvider', + 'clone', + {url: 'https://github.com/vyperlang/vyper', token: null}, + 'vyper-lang' + ) // @ts-ignore - this.call('notification', 'toast', 'Vyper repository cloned, the workspace Vyper has been created.') + this.call( + 'notification', + 'toast', + 'Vyper repository cloned, the workspace Vyper has been created.' + ) } catch (e) { // @ts-ignore this.call('notification', 'toast', e.message) @@ -54,11 +80,15 @@ export class RemixClient extends PluginClient { /** Update the status of the plugin in remix */ changeStatus(status: Status) { - this.client.emit('statusChanged', status); + this.client.emit('statusChanged', status) } /** Highlight a part of the editor */ - async highlight(lineColumnPos: HighlightPosition, name: string, message: string) { + async highlight( + lineColumnPos: HighlightPosition, + name: string, + message: string + ) { await this.client.call('editor', 'highlight', lineColumnPos, name) /* column: -1 @@ -94,15 +124,15 @@ export class RemixClient extends PluginClient { const content = await this.client.call('fileManager', 'getFile', name) return { name, - content, + content } } /** Emit an event to Remix with compilation result */ compilationFinish(title: string, content: string, data: CompilationResult) { - this.client.emit('compilationFinished', title, content, 'vyper', data); + this.client.emit('compilationFinished', title, content, 'vyper', data) } } export const remixClient = new RemixClient() -// export const RemixClientContext = React.createContext(new RemixClient()) \ No newline at end of file +// export const RemixClientContext = React.createContext(new RemixClient()) diff --git a/apps/vyper/src/main.tsx b/apps/vyper/src/main.tsx index 353ad43f6d..5f17c9ab24 100644 --- a/apps/vyper/src/main.tsx +++ b/apps/vyper/src/main.tsx @@ -1,7 +1,11 @@ -import { StrictMode } from 'react'; -import * as ReactDOM from 'react-dom'; +import {StrictMode} from 'react' +import * as ReactDOM from 'react-dom' +import App from './app/app' -import App from './app/app'; - -ReactDOM.render(, document.getElementById('root')); +ReactDOM.render( + + + , + document.getElementById('root') +) diff --git a/apps/vyper/webpack.config.js b/apps/vyper/webpack.config.js index 9feb0dc08d..4bc648f1db 100644 --- a/apps/vyper/webpack.config.js +++ b/apps/vyper/webpack.config.js @@ -1,8 +1,7 @@ -const { composePlugins, withNx } = require('@nrwl/webpack') +const {composePlugins, withNx} = require('@nrwl/webpack') const webpack = require('webpack') -const TerserPlugin = require("terser-webpack-plugin") -const CssMinimizerPlugin = require("css-minimizer-webpack-plugin") - +const TerserPlugin = require('terser-webpack-plugin') +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') // Nx plugins for webpack. module.exports = composePlugins(withNx(), (config) => { @@ -12,56 +11,52 @@ module.exports = composePlugins(withNx(), (config) => { // add fallback for node modules config.resolve.fallback = { ...config.resolve.fallback, - "crypto": require.resolve("crypto-browserify"), - "stream": require.resolve("stream-browserify"), - "path": require.resolve("path-browserify"), - "http": require.resolve("stream-http"), - "https": require.resolve("https-browserify"), - "constants": require.resolve("constants-browserify"), - "os": false, //require.resolve("os-browserify/browser"), - "timers": false, // require.resolve("timers-browserify"), - "zlib": require.resolve("browserify-zlib"), - "fs": false, - "module": false, - "tls": false, - "net": false, - "readline": false, - "child_process": false, - "buffer": require.resolve("buffer/"), - "vm": require.resolve('vm-browserify'), + crypto: require.resolve('crypto-browserify'), + stream: require.resolve('stream-browserify'), + path: require.resolve('path-browserify'), + http: require.resolve('stream-http'), + https: require.resolve('https-browserify'), + constants: require.resolve('constants-browserify'), + os: false, //require.resolve("os-browserify/browser"), + timers: false, // require.resolve("timers-browserify"), + zlib: require.resolve('browserify-zlib'), + fs: false, + module: false, + tls: false, + net: false, + readline: false, + child_process: false, + buffer: require.resolve('buffer/'), + vm: require.resolve('vm-browserify') } - // add externals config.externals = { ...config.externals, - solc: 'solc', + solc: 'solc' } // add public path config.output.publicPath = '/' - - // add copy & provide plugin config.plugins.push( new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'], url: ['url', 'URL'], - process: 'process/browser', + process: 'process/browser' }) ) // souce-map loader config.module.rules.push({ test: /\.js$/, - use: ["source-map-loader"], - enforce: "pre" + use: ['source-map-loader'], + enforce: 'pre' }) config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings - // set minimizer config.optimization.minimizer = [ new TerserPlugin({ @@ -71,17 +66,17 @@ module.exports = composePlugins(withNx(), (config) => { compress: false, mangle: false, format: { - comments: false, - }, + comments: false + } }, - extractComments: false, + extractComments: false }), - new CssMinimizerPlugin(), - ]; + new CssMinimizerPlugin() + ] config.watchOptions = { ignored: /node_modules/ } - return config; -}); + return config +}) diff --git a/apps/walletconnect/src/app/app.tsx b/apps/walletconnect/src/app/app.tsx index 7cecd906c5..30cb43cd94 100644 --- a/apps/walletconnect/src/app/app.tsx +++ b/apps/walletconnect/src/app/app.tsx @@ -1,9 +1,9 @@ -import React, { useEffect, useState } from 'react' +import React, {useEffect, useState} from 'react' import '../css/app.css' import '@fortawesome/fontawesome-free/css/all.css' -import type { EthereumClient } from '@web3modal/ethereum' -import { WalletConnectRemixClient } from '../services/WalletConnectRemixClient' -import { WalletConnectUI } from './walletConnectUI' +import type {EthereumClient} from '@web3modal/ethereum' +import {WalletConnectRemixClient} from '../services/WalletConnectRemixClient' +import {WalletConnectUI} from './walletConnectUI' const remix = new WalletConnectRemixClient() @@ -13,12 +13,12 @@ function App() { const [theme, setTheme] = useState('dark') useEffect(() => { - (async () => { + ;(async () => { await remix.initClient() remix.internalEvents.on('themeChanged', (theme: string) => { setTheme(theme) }) - + setWagmiConfig(remix.wagmiConfig) setEthereumClient(remix.ethereumClient) })() @@ -26,10 +26,16 @@ function App() { return (
-

WalletConnect

- { ethereumClient && wagmiConfig && } +

WalletConnect

+ {ethereumClient && wagmiConfig && ( + + )}
) } -export default App \ No newline at end of file +export default App diff --git a/apps/walletconnect/src/app/walletConnectUI.tsx b/apps/walletconnect/src/app/walletConnectUI.tsx index 471f2de6b0..ec3f44a535 100644 --- a/apps/walletconnect/src/app/walletConnectUI.tsx +++ b/apps/walletconnect/src/app/walletConnectUI.tsx @@ -1,17 +1,20 @@ -import { Web3Button, Web3Modal } from "@web3modal/react" -import { WagmiConfig } from "wagmi" -import { PROJECT_ID } from "../services/constant" +import {Web3Button, Web3Modal} from '@web3modal/react' +import {WagmiConfig} from 'wagmi' +import {PROJECT_ID} from '../services/constant' -export function WalletConnectUI ({ ethereumClient, wagmiConfig, theme }) { - - return ( -
-
- - - -
- -
- ) +export function WalletConnectUI({ethereumClient, wagmiConfig, theme}) { + return ( +
+
+ + + +
+ +
+ ) } diff --git a/apps/walletconnect/src/main.tsx b/apps/walletconnect/src/main.tsx index b63438d846..818cf01a94 100644 --- a/apps/walletconnect/src/main.tsx +++ b/apps/walletconnect/src/main.tsx @@ -2,7 +2,4 @@ import React from 'react' import ReactDOM from 'react-dom' import App from './app/app' -ReactDOM.render( - , - document.getElementById('root') -) \ No newline at end of file +ReactDOM.render(, document.getElementById('root')) diff --git a/apps/walletconnect/webpack.config.js b/apps/walletconnect/webpack.config.js index 51de9dd815..80c3c94308 100644 --- a/apps/walletconnect/webpack.config.js +++ b/apps/walletconnect/webpack.config.js @@ -1,7 +1,7 @@ -const { composePlugins, withNx } = require('@nrwl/webpack') +const {composePlugins, withNx} = require('@nrwl/webpack') const webpack = require('webpack') -const TerserPlugin = require("terser-webpack-plugin") -const CssMinimizerPlugin = require("css-minimizer-webpack-plugin") +const TerserPlugin = require('terser-webpack-plugin') +const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') // Nx plugins for webpack. module.exports = composePlugins(withNx(), (config) => { @@ -10,30 +10,29 @@ module.exports = composePlugins(withNx(), (config) => { // add fallback for node modules config.resolve.fallback = { ...config.resolve.fallback, - "crypto": require.resolve("crypto-browserify"), - "stream": require.resolve("stream-browserify"), - "path": require.resolve("path-browserify"), - "http": require.resolve("stream-http"), - "https": require.resolve("https-browserify"), - "constants": require.resolve("constants-browserify"), - "os": false, //require.resolve("os-browserify/browser"), - "timers": false, // require.resolve("timers-browserify"), - "zlib": require.resolve("browserify-zlib"), - "fs": false, - "module": false, - "tls": false, - "net": false, - "readline": false, - "child_process": false, - "buffer": require.resolve("buffer/"), - "vm": require.resolve('vm-browserify'), + crypto: require.resolve('crypto-browserify'), + stream: require.resolve('stream-browserify'), + path: require.resolve('path-browserify'), + http: require.resolve('stream-http'), + https: require.resolve('https-browserify'), + constants: require.resolve('constants-browserify'), + os: false, //require.resolve("os-browserify/browser"), + timers: false, // require.resolve("timers-browserify"), + zlib: require.resolve('browserify-zlib'), + fs: false, + module: false, + tls: false, + net: false, + readline: false, + child_process: false, + buffer: require.resolve('buffer/'), + vm: require.resolve('vm-browserify') } - // add externals config.externals = { ...config.externals, - solc: 'solc', + solc: 'solc' } // add public path @@ -44,27 +43,28 @@ module.exports = composePlugins(withNx(), (config) => { new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'], url: ['url', 'URL'], - process: 'process/browser', + process: 'process/browser' }) ) // set the define plugin to load the WALLET_CONNECT_PROJECT_ID config.plugins.push( new webpack.DefinePlugin({ - WALLET_CONNECT_PROJECT_ID: JSON.stringify(process.env.WALLET_CONNECT_PROJECT_ID), + WALLET_CONNECT_PROJECT_ID: JSON.stringify( + process.env.WALLET_CONNECT_PROJECT_ID + ) }) ) // souce-map loader config.module.rules.push({ test: /\.js$/, - use: ["source-map-loader"], - enforce: "pre" + use: ['source-map-loader'], + enforce: 'pre' }) config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings - // set minimizer config.optimization.minimizer = [ new TerserPlugin({ @@ -74,17 +74,17 @@ module.exports = composePlugins(withNx(), (config) => { compress: false, mangle: false, format: { - comments: false, - }, + comments: false + } }, - extractComments: false, + extractComments: false }), - new CssMinimizerPlugin(), - ]; + new CssMinimizerPlugin() + ] config.watchOptions = { ignored: /node_modules/ } - return config; -}); + return config +}) diff --git a/libs/remix-debug/test.ts b/libs/remix-debug/test.ts index 95a5a44c4c..917b3fb61c 100644 --- a/libs/remix-debug/test.ts +++ b/libs/remix-debug/test.ts @@ -10,8 +10,7 @@ const shortFilename = 'simple_storage.sol' const inputJson = { language: 'Solidity', - sources: { - }, + sources: {}, settings: { optimizer: { enabled: true, @@ -19,24 +18,38 @@ const inputJson = { }, outputSelection: { '*': { - '': [ 'ast' ], - '*': [ 'abi', 'metadata', 'devdoc', 'userdoc', 'evm.legacyAssembly', 'evm.bytecode', 'evm.deployedBytecode', 'evm.methodIdentifiers', 'evm.gasEstimates' ] + '': ['ast'], + '*': [ + 'abi', + 'metadata', + 'devdoc', + 'userdoc', + 'evm.legacyAssembly', + 'evm.bytecode', + 'evm.deployedBytecode', + 'evm.methodIdentifiers', + 'evm.gasEstimates' + ] } } } } -inputJson.sources[shortFilename] = {content: fs.readFileSync(filename).toString()} +inputJson.sources[shortFilename] = { + content: fs.readFileSync(filename).toString() +} console.dir(inputJson) console.log('compiling...') -const compilationData = JSON.parse(solc.compileStandardWrapper(JSON.stringify(inputJson))) +const compilationData = JSON.parse( + solc.compileStandardWrapper(JSON.stringify(inputJson)) +) console.dir(Object.keys(compilationData)) const compilation = {} compilation['data'] = compilationData -compilation['source'] = { sources: inputJson.sources } +compilation['source'] = {sources: inputJson.sources} console.dir(compilation) console.dir(compilation['data'].errors) @@ -106,4 +119,3 @@ repl.start({ }) module.exports = cmdLine - diff --git a/libs/remix-ui/app/src/lib/remix-app/components/dragbar/dragbar.tsx b/libs/remix-ui/app/src/lib/remix-app/components/dragbar/dragbar.tsx index 1671e1bcc8..c9d34471be 100644 --- a/libs/remix-ui/app/src/lib/remix-app/components/dragbar/dragbar.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/components/dragbar/dragbar.tsx @@ -1,10 +1,10 @@ -import React, { useEffect, useState, useRef } from 'react' +import React, {useEffect, useState, useRef} from 'react' import Draggable from 'react-draggable' import './dragbar.css' interface IRemixDragBarUi { - refObject: React.MutableRefObject; - setHideStatus: (hide: boolean) => void; + refObject: React.MutableRefObject + setHideStatus: (hide: boolean) => void hidden: boolean minWidth: number maximiseTrigger: number @@ -19,7 +19,9 @@ const DragBar = (props: IRemixDragBarUi) => { const nodeRef = React.useRef(null) // fix for strictmode useEffect(() => { - setDragBarPosX(offset + (props.hidden ? 0 : props.refObject.current.offsetWidth)) + setDragBarPosX( + offset + (props.hidden ? 0 : props.refObject.current.offsetWidth) + ) }, [props.hidden, offset]) useEffect(() => { @@ -47,14 +49,15 @@ const DragBar = (props: IRemixDragBarUi) => { const handleResize = () => { if (!props.refObject.current) return setOffSet(props.refObject.current.offsetLeft) - setDragBarPosX(props.refObject.current.offsetLeft + props.refObject.current.offsetWidth) + setDragBarPosX( + props.refObject.current.offsetLeft + props.refObject.current.offsetWidth + ) } useEffect(() => { window.addEventListener('resize', handleResize) // TODO: not a good way to wait on the ref doms element to be rendered of course - setTimeout(() => - handleResize(), 2000) + setTimeout(() => handleResize(), 2000) return () => window.removeEventListener('resize', handleResize) }, []) @@ -64,7 +67,7 @@ const DragBar = (props: IRemixDragBarUi) => { setDragBarPosX(offset) props.setHideStatus(true) } else { - props.refObject.current.style.width = (data.x - offset) + 'px' + props.refObject.current.style.width = data.x - offset + 'px' setTimeout(() => { props.setHideStatus(false) setDragBarPosX(offset + props.refObject.current.offsetWidth) @@ -75,12 +78,23 @@ const DragBar = (props: IRemixDragBarUi) => { function startDrag() { setDragState(true) } - return <> -
- -
-
- + return ( + <> +
+ +
+
+ + ) } export default DragBar diff --git a/libs/remix-ui/app/src/lib/remix-app/components/modals/dialogViewPlugin.tsx b/libs/remix-ui/app/src/lib/remix-app/components/modals/dialogViewPlugin.tsx index d5610de56c..091795a900 100644 --- a/libs/remix-ui/app/src/lib/remix-app/components/modals/dialogViewPlugin.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/components/modals/dialogViewPlugin.tsx @@ -1,13 +1,13 @@ -import React, { useContext, useEffect } from 'react' -import { AppContext } from '../../context/context' -import { useDialogDispatchers } from '../../context/provider' +import React, {useContext, useEffect} from 'react' +import {AppContext} from '../../context/context' +import {useDialogDispatchers} from '../../context/provider' const DialogViewPlugin = () => { - const { modal, alert, toast } = useDialogDispatchers() + const {modal, alert, toast} = useDialogDispatchers() const app = useContext(AppContext) useEffect(() => { - app.modal.setDispatcher({ modal, alert, toast }) + app.modal.setDispatcher({modal, alert, toast}) }, []) return <> } diff --git a/libs/remix-ui/app/src/lib/remix-app/components/modals/dialogs.tsx b/libs/remix-ui/app/src/lib/remix-app/components/modals/dialogs.tsx index 90bd71a05d..4dcfa322e8 100644 --- a/libs/remix-ui/app/src/lib/remix-app/components/modals/dialogs.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/components/modals/dialogs.tsx @@ -1,16 +1,21 @@ import React from 'react' -import { useDialogDispatchers, useDialogs } from '../../context/provider' -import { Toaster } from '@remix-ui/toaster' +import {useDialogDispatchers, useDialogs} from '../../context/provider' +import {Toaster} from '@remix-ui/toaster' import ModalWrapper from './modal-wrapper' const AppDialogs = () => { - const { handleHideModal, handleToaster } = useDialogDispatchers() - const { focusModal, focusToaster } = useDialogs() + const {handleHideModal, handleToaster} = useDialogDispatchers() + const {focusModal, focusToaster} = useDialogs() return ( <> - - ) + + + ) } export default AppDialogs diff --git a/libs/remix-ui/app/src/lib/remix-app/components/modals/matomo.tsx b/libs/remix-ui/app/src/lib/remix-app/components/modals/matomo.tsx index 276a3ee47b..8b2f00d4fc 100644 --- a/libs/remix-ui/app/src/lib/remix-app/components/modals/matomo.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/components/modals/matomo.tsx @@ -1,30 +1,76 @@ -import React, { useContext, useEffect, useState } from 'react' -import { AppContext } from '../../context/context' -import { useDialogDispatchers } from '../../context/provider' +import React, {useContext, useEffect, useState} from 'react' +import {AppContext} from '../../context/context' +import {useDialogDispatchers} from '../../context/provider' declare global { interface Window { _paq: any } } -const _paq = window._paq = window._paq || [] +const _paq = (window._paq = window._paq || []) const MatomoDialog = (props) => { - const { settings, showMatamo, appManager } = useContext(AppContext) - const { modal } = useDialogDispatchers() + const {settings, showMatamo, appManager} = useContext(AppContext) + const {modal} = useDialogDispatchers() const [visible, setVisible] = useState(props.hide) const message = () => { - return (<>

An Opt-in version of Matomo, an open source data analytics platform is being used to improve Remix IDE.

-

We realize that our users have sensitive information in their code and that their privacy - your privacy - must be protected.

-

All data collected through Matomo is stored on our own server - no data is ever given to third parties. Our analytics reports are public: take a look.

-

We do not collect nor store any personally identifiable information (PII).

-

For more info, see: Matomo Analyitcs on Remix iDE.

-

You can change your choice in the Settings panel anytime.

) + return ( + <> +

+ An Opt-in version of{' '} + + Matomo + + , an open source data analytics platform is being used to improve + Remix IDE. +

+

+ We realize that our users have sensitive information in their code and + that their privacy - your privacy - must be protected. +

+

+ All data collected through Matomo is stored on our own server - no + data is ever given to third parties. Our analytics reports are public:{' '} + + take a look + + . +

+

+ We do not collect nor store any personally identifiable information + (PII). +

+

+ For more info, see:{' '} + + Matomo Analyitcs on Remix iDE + + . +

+

You can change your choice in the Settings panel anytime.

+ + ) } useEffect(() => { if (visible && showMatamo) { - modal({ id: 'matomoModal', title: 'Help us to improve Remix IDE', message: message(), okLabel: 'Accept', okFn: handleModalOkClick, cancelLabel: 'Decline', cancelFn: declineModal }) + modal({ + id: 'matomoModal', + title: 'Help us to improve Remix IDE', + message: message(), + okLabel: 'Accept', + okFn: handleModalOkClick, + cancelLabel: 'Decline', + cancelFn: declineModal + }) } }, [visible]) @@ -38,13 +84,14 @@ const MatomoDialog = (props) => { const handleModalOkClick = async () => { _paq.push(['forgetUserOptOut']) // @TODO remove next line when https://github.com/matomo-org/matomo/commit/9e10a150585522ca30ecdd275007a882a70c6df5 is used - document.cookie = 'mtm_consent_removed=; expires=Thu, 01 Jan 1970 00:00:01 GMT;' + document.cookie = + 'mtm_consent_removed=; expires=Thu, 01 Jan 1970 00:00:01 GMT;' settings.updateMatomoAnalyticsChoice(true) appManager.call('walkthrough', 'start') setVisible(false) } - return (<>) + return <> } export default MatomoDialog diff --git a/libs/remix-ui/app/src/lib/remix-app/components/modals/modal-wrapper.tsx b/libs/remix-ui/app/src/lib/remix-app/components/modals/modal-wrapper.tsx index 38c8d8579e..69e0901c30 100644 --- a/libs/remix-ui/app/src/lib/remix-app/components/modals/modal-wrapper.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/components/modals/modal-wrapper.tsx @@ -1,6 +1,10 @@ -import React, { useEffect, useRef, useState } from 'react' -import { ModalDialog, ModalDialogProps, ValidationResult } from '@remix-ui/modal-dialog' -import { ModalTypes } from '../../types' +import React, {useEffect, useRef, useState} from 'react' +import { + ModalDialog, + ModalDialogProps, + ValidationResult +} from '@remix-ui/modal-dialog' +import {ModalTypes} from '../../types' interface ModalWrapperProps extends ModalDialogProps { modalType?: ModalTypes @@ -28,36 +32,54 @@ const ModalWrapper = (props: ModalWrapperProps) => { if (ref.current === undefined && formRef.current === undefined) { onOkFn() } else if (formRef.current) { - (props.okFn) ? props.okFn(getFormData()) : props.resolve(getFormData()) - } else if(ref.current) { + props.okFn ? props.okFn(getFormData()) : props.resolve(getFormData()) + } else if (ref.current) { // @ts-ignore: Object is possibly 'null'. - (props.okFn) ? props.okFn(ref.current.value) : props.resolve(ref.current.value) + props.okFn + ? props.okFn(ref.current.value) + : props.resolve(ref.current.value) } } const onOkFn = async () => { - (props.okFn) ? props.okFn(data.current) : props.resolve(data.current || true) + props.okFn ? props.okFn(data.current) : props.resolve(data.current || true) } const onCancelFn = async () => { - (props.cancelFn) ? props.cancelFn() : props.resolve(false) + props.cancelFn ? props.cancelFn() : props.resolve(false) } const onInputChanged = (event) => { if (props.validationFn) { const validation = props.validationFn(event.target.value) - setState(prevState => { - return { ...prevState, message: createModalMessage(props.defaultValue, validation), validation } + setState((prevState) => { + return { + ...prevState, + message: createModalMessage(props.defaultValue, validation), + validation + } }) } } - const createModalMessage = (defaultValue: string, validation: ValidationResult) => { + const createModalMessage = ( + defaultValue: string, + validation: ValidationResult + ) => { return ( <> {props.message} - - {validation && !validation.valid && {validation.message}} + + {validation && !validation.valid && ( + {validation.message} + )} ) } @@ -65,8 +87,8 @@ const ModalWrapper = (props: ModalWrapperProps) => { const onFormChanged = () => { if (props.validationFn) { const validation = props.validationFn(getFormData()) - setState(prevState => { - return { ...prevState, message: createForm(validation), validation } + setState((prevState) => { + return {...prevState, message: createForm(validation), validation} }) } } @@ -77,7 +99,9 @@ const ModalWrapper = (props: ModalWrapperProps) => {
{props.message}
- {validation && !validation.valid && {validation.message}} + {validation && !validation.valid && ( + {validation.message} + )} ) } @@ -92,7 +116,7 @@ const ModalWrapper = (props: ModalWrapperProps) => { ...props, okFn: onFinishPrompt, cancelFn: onCancelFn, - message: createModalMessage(props.defaultValue, { valid: true }) + message: createModalMessage(props.defaultValue, {valid: true}) }) break case ModalTypes.form: @@ -100,7 +124,7 @@ const ModalWrapper = (props: ModalWrapperProps) => { ...props, okFn: onFinishPrompt, cancelFn: onCancelFn, - message: createForm({ valid: true }) + message: createForm({valid: true}) }) break default: @@ -122,14 +146,12 @@ const ModalWrapper = (props: ModalWrapperProps) => { // reset the message and input if any, so when the modal is shown again it doesn't show the previous value. const handleHide = () => { - setState(prevState => { - return { ...prevState, message: '' } + setState((prevState) => { + return {...prevState, message: ''} }) props.handleHide() } - return ( - - ) + return } export default ModalWrapper diff --git a/libs/remix-ui/app/src/lib/remix-app/components/modals/origin-warning.tsx b/libs/remix-ui/app/src/lib/remix-app/components/modals/origin-warning.tsx index 61d25db2f6..e5f34d3971 100644 --- a/libs/remix-ui/app/src/lib/remix-app/components/modals/origin-warning.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/components/modals/origin-warning.tsx @@ -1,22 +1,31 @@ -import React, { useEffect, useState } from 'react' -import { ModalDialog } from '@remix-ui/modal-dialog' -import { useDialogDispatchers } from '../../context/provider' +import React, {useEffect, useState} from 'react' +import {ModalDialog} from '@remix-ui/modal-dialog' +import {useDialogDispatchers} from '../../context/provider' const OriginWarning = () => { - const { alert } = useDialogDispatchers() + const {alert} = useDialogDispatchers() const [content, setContent] = useState(null) useEffect(() => { // check the origin and warn message if (window.location.hostname === 'yann300.github.io') { - setContent('This UNSTABLE ALPHA branch of Remix has been moved to http://ethereum.github.io/remix-live-alpha.') - } else if (window.location.hostname === 'remix-alpha.ethereum.org' || - (window.location.hostname === 'ethereum.github.io' && window.location.pathname.indexOf('/remix-live-alpha') === 0)) { - setContent('Welcome to the Remix alpha instance. Please use it to try out latest features. But use preferably https://remix.ethereum.org for any production work.') - } else if (window.location.protocol.indexOf('http') === 0 && - window.location.hostname !== 'remix.ethereum.org' && - window.location.hostname !== 'localhost' && - window.location.hostname !== '127.0.0.1') { + setContent( + 'This UNSTABLE ALPHA branch of Remix has been moved to http://ethereum.github.io/remix-live-alpha.' + ) + } else if ( + window.location.hostname === 'remix-alpha.ethereum.org' || + (window.location.hostname === 'ethereum.github.io' && + window.location.pathname.indexOf('/remix-live-alpha') === 0) + ) { + setContent( + 'Welcome to the Remix alpha instance. Please use it to try out latest features. But use preferably https://remix.ethereum.org for any production work.' + ) + } else if ( + window.location.protocol.indexOf('http') === 0 && + window.location.hostname !== 'remix.ethereum.org' && + window.location.hostname !== 'localhost' && + window.location.hostname !== '127.0.0.1' + ) { setContent(`The Remix IDE has moved to http://remix.ethereum.org.\n This instance of Remix you are visiting WILL NOT BE UPDATED.\n Please make a backup of your contracts and start using http://remix.ethereum.org`) @@ -25,11 +34,11 @@ const OriginWarning = () => { useEffect(() => { if (content) { - alert({ id: 'warningOriging', title: null, message: content }) + alert({id: 'warningOriging', title: null, message: content}) } }, [content]) - return (<>) + return <> } export default OriginWarning diff --git a/libs/remix-ui/app/src/lib/remix-app/components/splashscreen.tsx b/libs/remix-ui/app/src/lib/remix-app/components/splashscreen.tsx index 44e55a4db4..ed382ec8ab 100644 --- a/libs/remix-ui/app/src/lib/remix-app/components/splashscreen.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/components/splashscreen.tsx @@ -1,16 +1,27 @@ import React from 'react' const RemixSplashScreen = (props) => { - return (<>
- - - - - -
- REMIX IDE -
-
) + return ( + <> + {' '} +
+ + + + + +
REMIX IDE
+
+ + ) } export default RemixSplashScreen diff --git a/libs/remix-ui/app/src/lib/remix-app/context/context.tsx b/libs/remix-ui/app/src/lib/remix-app/context/context.tsx index ca69771f80..ec0f105b51 100644 --- a/libs/remix-ui/app/src/lib/remix-app/context/context.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/context/context.tsx @@ -1,6 +1,6 @@ import React from 'react' -import { AlertModal, AppModal } from '../interface' -import { ModalInitialState } from '../state/modals' +import {AlertModal, AppModal} from '../interface' +import {ModalInitialState} from '../state/modals' export const AppContext = React.createContext(null) @@ -8,16 +8,18 @@ export interface dispatchModalInterface { modal: (data: AppModal) => void toast: (message: string | JSX.Element) => void alert: (data: AlertModal) => void - handleHideModal: () => void, + handleHideModal: () => void handleToaster: () => void } -export const dispatchModalContext = React.createContext({ - modal: (data: AppModal) => { }, - toast: (message: string | JSX.Element) => {}, - alert: (data: AlertModal) => {}, - handleHideModal: () => {}, - handleToaster: () => {} -}) +export const dispatchModalContext = React.createContext( + { + modal: (data: AppModal) => {}, + toast: (message: string | JSX.Element) => {}, + alert: (data: AlertModal) => {}, + handleHideModal: () => {}, + handleToaster: () => {} + } +) export const modalContext = React.createContext(ModalInitialState) diff --git a/libs/remix-ui/app/src/lib/remix-app/context/provider.tsx b/libs/remix-ui/app/src/lib/remix-app/context/provider.tsx index 635500a8b3..7e04805a87 100644 --- a/libs/remix-ui/app/src/lib/remix-app/context/provider.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/context/provider.tsx @@ -1,13 +1,20 @@ -import React, { useReducer } from 'react' -import { modalActionTypes } from '../actions/modals' -import { AlertModal, AppModal } from '../interface' -import { modalReducer } from '../reducer/modals' -import { ModalInitialState } from '../state/modals' -import { ModalTypes } from '../types' -import { AppContext, dispatchModalContext, modalContext } from './context' +import React, {useReducer} from 'react' +import {modalActionTypes} from '../actions/modals' +import {AlertModal, AppModal} from '../interface' +import {modalReducer} from '../reducer/modals' +import {ModalInitialState} from '../state/modals' +import {ModalTypes} from '../types' +import {AppContext, dispatchModalContext, modalContext} from './context' -export const ModalProvider = ({ children = [], reducer = modalReducer, initialState = ModalInitialState } = {}) => { - const [{ modals, toasters, focusModal, focusToaster }, dispatch] = useReducer(reducer, initialState) +export const ModalProvider = ({ + children = [], + reducer = modalReducer, + initialState = ModalInitialState +} = {}) => { + const [{modals, toasters, focusModal, focusToaster}, dispatch] = useReducer( + reducer, + initialState + ) const onNextFn = async () => { dispatch({ @@ -16,17 +23,53 @@ export const ModalProvider = ({ children = [], reducer = modalReducer, initialSt } const modal = (modalData: AppModal) => { - const { id, title, message, validationFn, okLabel, okFn, cancelLabel, cancelFn, modalType, defaultValue, hideFn, data } = modalData + const { + id, + title, + message, + validationFn, + okLabel, + okFn, + cancelLabel, + cancelFn, + modalType, + defaultValue, + hideFn, + data + } = modalData return new Promise((resolve, reject) => { dispatch({ type: modalActionTypes.setModal, - payload: { id, title, message, okLabel, validationFn, okFn, cancelLabel, cancelFn, modalType: modalType || ModalTypes.default, defaultValue: defaultValue, hideFn, resolve, next: onNextFn, data } + payload: { + id, + title, + message, + okLabel, + validationFn, + okFn, + cancelLabel, + cancelFn, + modalType: modalType || ModalTypes.default, + defaultValue: defaultValue, + hideFn, + resolve, + next: onNextFn, + data + } }) }) } const alert = (modalData: AlertModal) => { - return modal({ id: modalData.id, title: modalData.title || 'Alert', message: modalData.message || modalData.title, okLabel: 'OK', okFn: (value?:any) => {}, cancelLabel: '', cancelFn: () => {} }) + return modal({ + id: modalData.id, + title: modalData.title || 'Alert', + message: modalData.message || modalData.title, + okLabel: 'OK', + okFn: (value?: any) => {}, + cancelLabel: '', + cancelFn: () => {} + }) } const handleHideModal = () => { @@ -39,7 +82,7 @@ export const ModalProvider = ({ children = [], reducer = modalReducer, initialSt const toast = (message: string | JSX.Element) => { dispatch({ type: modalActionTypes.setToast, - payload: { message, timestamp: Date.now() } + payload: {message, timestamp: Date.now()} }) } @@ -50,17 +93,25 @@ export const ModalProvider = ({ children = [], reducer = modalReducer, initialSt }) } - return ( - - {children} - - ) + return ( + + + {children} + + + ) } -export const AppProvider = ({ children = [], value = {} } = {}) => { - return - {children} - +export const AppProvider = ({children = [], value = {}} = {}) => { + return ( + + {children} + + ) } export const useDialogs = () => { diff --git a/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx b/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx index 31cbe3dc79..ee608d91aa 100644 --- a/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx +++ b/libs/remix-ui/app/src/lib/remix-app/remix-app.tsx @@ -1,15 +1,15 @@ -import React, { useEffect, useRef, useState } from 'react' +import React, {useEffect, useRef, useState} from 'react' import './style/remix-app.css' -import { RemixUIMainPanel } from '@remix-ui/panel' +import {RemixUIMainPanel} from '@remix-ui/panel' import MatomoDialog from './components/modals/matomo' import OriginWarning from './components/modals/origin-warning' import DragBar from './components/dragbar/dragbar' -import { AppProvider } from './context/provider' +import {AppProvider} from './context/provider' import AppDialogs from './components/modals/dialogs' import DialogViewPlugin from './components/modals/dialogViewPlugin' -import { AppContext } from './context/context' -import { IntlProvider } from 'react-intl' -import { CustomTooltip } from '@remix-ui/helper'; +import {AppContext} from './context/context' +import {IntlProvider} from 'react-intl' +import {CustomTooltip} from '@remix-ui/helper' interface IRemixAppUi { app: any @@ -20,11 +20,14 @@ const RemixApp = (props: IRemixAppUi) => { const [hideSidePanel, setHideSidePanel] = useState(false) const [maximiseTrigger, setMaximiseTrigger] = useState(0) const [resetTrigger, setResetTrigger] = useState(0) - const [locale, setLocale] = useState<{ code:string; messages:any }>({ code:'en', messages:{} }); + const [locale, setLocale] = useState<{code: string; messages: any}>({ + code: 'en', + messages: {} + }) const sidePanelRef = useRef(null) useEffect(() => { - async function activateApp () { + async function activateApp() { props.app.themeModule.initTheme(() => { setAppReady(true) props.app.activate() @@ -37,9 +40,9 @@ const RemixApp = (props: IRemixAppUi) => { } }, []) - function setListeners () { + function setListeners() { props.app.sidePanel.events.on('toggle', () => { - setHideSidePanel(prev => { + setHideSidePanel((prev) => { return !prev }) }) @@ -55,13 +58,13 @@ const RemixApp = (props: IRemixAppUi) => { }) props.app.layout.event.on('maximisesidepanel', () => { - setMaximiseTrigger(prev => { + setMaximiseTrigger((prev) => { return prev + 1 }) }) props.app.layout.event.on('resetsidepanel', () => { - setResetTrigger(prev => { + setResetTrigger((prev) => { return prev + 1 }) }) @@ -84,18 +87,47 @@ const RemixApp = (props: IRemixAppUi) => { -
-
{props.app.menuicons.render()}
-
{props.app.sidePanel.render()}
- -
+
+
+ {props.app.menuicons.render()} +
+
+ {props.app.sidePanel.render()} +
+ +
-
+
diff --git a/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx b/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx index faf4dc8f39..d47d566726 100644 --- a/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx +++ b/libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx @@ -1,8 +1,7 @@ -import { CustomTooltip } from '@remix-ui/helper'; -import React, { CSSProperties } from 'react' //eslint-disable-line +import {CustomTooltip} from '@remix-ui/helper' +import React, {CSSProperties} from 'react' //eslint-disable-line import './remix-ui-checkbox.css' -type Placement = import('react-overlays/usePopper').Placement; - +type Placement = import('react-overlays/usePopper').Placement /* eslint-disable-next-line */ export interface RemixUiCheckboxProps { @@ -38,27 +37,41 @@ export const RemixUiCheckbox = ({ optionalClassName = '', display = 'flex', disabled, - tooltipPlacement = 'right', + tooltipPlacement = 'right' }: RemixUiCheckboxProps) => { - const childJSXWithTooltip = ( -
+
-