diff --git a/apps/debugger/webpack.config.js b/apps/debugger/webpack.config.js index fa6f5e3b06..9feb0dc08d 100644 --- a/apps/debugger/webpack.config.js +++ b/apps/debugger/webpack.config.js @@ -79,5 +79,9 @@ module.exports = composePlugins(withNx(), (config) => { new CssMinimizerPlugin(), ]; + config.watchOptions = { + ignored: /node_modules/ + } + return config; }); diff --git a/apps/etherscan/webpack.config.js b/apps/etherscan/webpack.config.js index 45c7c5dd14..9d72c43a6c 100644 --- a/apps/etherscan/webpack.config.js +++ b/apps/etherscan/webpack.config.js @@ -78,5 +78,9 @@ module.exports = composePlugins(withNx(), (config) => { new CssMinimizerPlugin(), ]; + config.watchOptions = { + ignored: /node_modules/ + } + return config; }); diff --git a/apps/remix-ide-e2e/src/commands/verifyContracts.ts b/apps/remix-ide-e2e/src/commands/verifyContracts.ts index f29c3e42c6..718b3a84e2 100644 --- a/apps/remix-ide-e2e/src/commands/verifyContracts.ts +++ b/apps/remix-ide-e2e/src/commands/verifyContracts.ts @@ -31,7 +31,7 @@ function verifyContracts (browser: NightwatchBrowser, compiledContractNames: str .click('*[data-id="treeViewDivtreeViewItemcompiler"]') .waitForElementVisible('*[data-id="treeViewLiversion"]') .assert.containsText('*[data-id="treeViewLiversion"]', `${opts.version}`) - .click('[data-id="workspacesModalDialog-modal-footer-ok-react"]') + .click('[data-id="workspacesModalDialog-modal-footer-cancel-react"]') .perform(() => { done() callback() @@ -49,7 +49,7 @@ function verifyContracts (browser: NightwatchBrowser, compiledContractNames: str .click('*[data-id="treeViewDivtreeViewItemoptimizer"]') .waitForElementVisible('*[data-id="treeViewDivruns"]') .assert.containsText('*[data-id="treeViewDivruns"]', `${opts.runs}`) - .click('[data-id="workspacesModalDialog-modal-footer-ok-react"]') + .click('[data-id="workspacesModalDialog-modal-footer-cancel-react"]') .perform(() => { done() callback() diff --git a/apps/remix-ide-e2e/src/local-plugin/webpack.config.js b/apps/remix-ide-e2e/src/local-plugin/webpack.config.js index a98229d072..25932a1054 100644 --- a/apps/remix-ide-e2e/src/local-plugin/webpack.config.js +++ b/apps/remix-ide-e2e/src/local-plugin/webpack.config.js @@ -17,5 +17,9 @@ module.exports = composePlugins(withNx(), (config) => { config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings + config.watchOptions = { + ignored: /node_modules/ + } + return config; }); diff --git a/apps/remix-ide-e2e/src/tests/editorHoverContext.test.ts b/apps/remix-ide-e2e/src/tests/editorHoverContext.test.ts index f9f5eef0c4..db86224b11 100644 --- a/apps/remix-ide-e2e/src/tests/editorHoverContext.test.ts +++ b/apps/remix-ide-e2e/src/tests/editorHoverContext.test.ts @@ -18,14 +18,6 @@ module.exports = { init(browser, done, 'http://127.0.0.1:8080', false) }, - 'Should enable settings': function (browser: NightwatchBrowser) { - browser - .clickLaunchIcon('settings') - .click('[data-id="settingsAutoCompleteLabel"]') - .click('[data-id="settingsShowGasLabel"]') - .click('[data-id="displayErrorsLabel"]') - }, - 'Should load the test file': function (browser: NightwatchBrowser) { browser.openFile('contracts') .openFile('contracts/3_Ballot.sol') diff --git a/apps/remix-ide-e2e/src/tests/editorReferences.test.ts b/apps/remix-ide-e2e/src/tests/editorReferences.test.ts index f63837233e..86856a9822 100644 --- a/apps/remix-ide-e2e/src/tests/editorReferences.test.ts +++ b/apps/remix-ide-e2e/src/tests/editorReferences.test.ts @@ -20,13 +20,6 @@ module.exports = { init(browser, done, 'http://127.0.0.1:8080', false) }, - 'Should enable settings': function (browser: NightwatchBrowser) { - browser - .clickLaunchIcon('settings') - .click('[data-id="settingsAutoCompleteLabel"]') - .click('[data-id="settingsShowGasLabel"]') - .click('[data-id="displayErrorsLabel"]') - }, 'Should load the test file': function (browser: NightwatchBrowser) { browser.openFile('contracts') .openFile('contracts/3_Ballot.sol') diff --git a/apps/remix-ide-e2e/src/tests/editor_error_marker.test.ts b/apps/remix-ide-e2e/src/tests/editor_error_marker.test.ts index daa5456982..f762d605b7 100644 --- a/apps/remix-ide-e2e/src/tests/editor_error_marker.test.ts +++ b/apps/remix-ide-e2e/src/tests/editor_error_marker.test.ts @@ -8,13 +8,7 @@ module.exports = { before: function (browser: NightwatchBrowser, done: VoidFunction) { init(browser, done, 'http://127.0.0.1:8080', true) }, - 'Should enable settings': function (browser: NightwatchBrowser) { - browser - .clickLaunchIcon('settings') - .click('[data-id="settingsAutoCompleteLabel"]') - .click('[data-id="settingsShowGasLabel"]') - .click('[data-id="displayErrorsLabel"]') - }, + 'Should add error marker': function (browser: NightwatchBrowser) { browser .openFile('contracts') diff --git a/apps/remix-ide-e2e/src/tests/editor_line_text.test.ts b/apps/remix-ide-e2e/src/tests/editor_line_text.test.ts index 24eb0540e1..1a0e925770 100644 --- a/apps/remix-ide-e2e/src/tests/editor_line_text.test.ts +++ b/apps/remix-ide-e2e/src/tests/editor_line_text.test.ts @@ -8,13 +8,7 @@ module.exports = { before: function (browser: NightwatchBrowser, done: VoidFunction) { init(browser, done, 'http://127.0.0.1:8080', true) }, - 'Should enable settings': function (browser: NightwatchBrowser) { - browser - .clickLaunchIcon('settings') - .click('[data-id="settingsAutoCompleteLabel"]') - .click('[data-id="settingsShowGasLabel"]') - .click('[data-id="displayErrorsLabel"]') - }, + 'Should add line texts': function (browser: NightwatchBrowser) { browser .openFile('contracts') diff --git a/apps/remix-ide-e2e/src/tests/workspace.test.ts b/apps/remix-ide-e2e/src/tests/workspace.test.ts index 7cda455c74..84536cf037 100644 --- a/apps/remix-ide-e2e/src/tests/workspace.test.ts +++ b/apps/remix-ide-e2e/src/tests/workspace.test.ts @@ -408,14 +408,10 @@ module.exports = { 'Should rename a workspace #group1': function (browser: NightwatchBrowser) { browser - .useXpath() - .waitForElementPresent({ - selector: '//i[@data-id="workspaceDropdownMenuIcon"]', - locateStrategy: 'xpath', - }) - .click('//*[@id="workspacesMenuDropdown"]/span/i') - .waitForElementVisible('//*[@id="workspacesMenuDropdown"]/div/ul') - .click('//*[@id="workspacesMenuDropdown"]/div/ul/a[4]') // rename workspace_name + .waitForElementPresent('*[data-id="workspaceDropdownMenuIcon"]') + .click('*[data-id="workspaceDropdownMenuIcon"]') + .waitForElementVisible('*[data-id="wsdropdownMenu"]') + .click('*[data-id="workspacerename"]') // rename workspace_name .useCss() .waitForElementVisible('*[data-id="treeViewLitreeViewItemtests"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextRename"]') @@ -437,15 +433,14 @@ module.exports = { 'Should delete a workspace #group1': function (browser: NightwatchBrowser) { browser - .switchWorkspace('workspace_name_1')//*[@id="workspacesMenuDropdown"]/span - .useXpath() - .click('//*[@id="workspacesMenuDropdown"]/span/i') - .click('//*[@id="workspacesMenuDropdown"]/div/ul/a[2]') // delete workspace_name_1 - .waitForElementVisible('//*[@id="fileExplorerView"]/div[2]/div/div/div[2]') - .click('//*[@id="fileExplorerView"]/div[2]/div/div/div[3]/button') - .waitForElementVisible('//*[@id="workspacesSelect"]') - .click('//*[@id="workspacesSelect"]') - .useCss() + .switchWorkspace('workspace_name_1') + .click('*[data-id="workspaceDropdownMenuIcon"]') + .waitForElementVisible('*[data-id="wsdropdownMenu"]') + .click('*[data-id="workspacedelete"]') // delete workspace_name_1 + .waitForElementVisible('*[data-id="fileSystemModalDialogModalFooter-react"]') + .click('*[data-id="fileSystem-modal-footer-ok-react"]') + .waitForElementVisible('*[data-id="workspacesSelect"]') + .click('*[data-id="workspacesSelect"]') .waitForElementNotPresent(`[data-id="dropdown-item-workspace_name_1"]`) .end() }, diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index cca71d7632..8155a709ab 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -36,7 +36,8 @@ import { HardhatProvider } from './app/providers/hardhat-provider' import { GanacheProvider } from './app/providers/ganache-provider' import { FoundryProvider } from './app/providers/foundry-provider' import { ExternalHttpProvider } from './app/providers/external-http-provider' -import { BasicInjectedProvider } from './app/providers/basic-injected-provider' +import { InjectedProviderDefault } from './app/providers/injected-provider-default' +import { InjectedProviderTrustWallet } from './app/providers/injected-provider-trustwallet' import { Injected0ptimismProvider } from './app/providers/injected-optimism-provider' import { InjectedArbitrumOneProvider } from './app/providers/injected-arbitrum-one-provider' import { FileDecorator } from './app/plugins/file-decorator' @@ -216,7 +217,8 @@ class AppComponent { const ganacheProvider = new GanacheProvider(blockchain) const foundryProvider = new FoundryProvider(blockchain) const externalHttpProvider = new ExternalHttpProvider(blockchain) - const basicInjectedProvider = new BasicInjectedProvider() + const trustWalletInjectedProvider = new InjectedProviderTrustWallet() + const defaultInjectedProvider = new InjectedProviderDefault const injected0ptimismProvider = new Injected0ptimismProvider() const injectedArbitrumOneProvider = new InjectedArbitrumOneProvider() // ----------------- convert offset to line/column service ----------- @@ -289,7 +291,8 @@ class AppComponent { ganacheProvider, foundryProvider, externalHttpProvider, - basicInjectedProvider, + defaultInjectedProvider, + trustWalletInjectedProvider, injected0ptimismProvider, injectedArbitrumOneProvider, this.walkthroughService, diff --git a/apps/remix-ide/src/app/providers/basic-injected-provider.tsx b/apps/remix-ide/src/app/providers/basic-injected-provider.tsx deleted file mode 100644 index 95895a9dca..0000000000 --- a/apps/remix-ide/src/app/providers/basic-injected-provider.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import * as packageJson from '../../../../../package.json' -import { InjectedProvider } from './injected-provider' - -const profile = { - name: 'injected', - displayName: 'Injected Provider', - kind: 'provider', - description: 'injected Provider', - methods: ['sendAsync', 'init'], - version: packageJson.version -} - -export class BasicInjectedProvider extends InjectedProvider { - - constructor () { - super(profile) - } -} \ 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 3aa3ab770f..afae690a39 100644 --- a/apps/remix-ide/src/app/providers/injected-L2-provider.tsx +++ b/apps/remix-ide/src/app/providers/injected-L2-provider.tsx @@ -1,6 +1,6 @@ -import { InjectedProvider } from './injected-provider' +import { InjectedProviderDefaultBase } from './injected-provider-default' -export class InjectedL2Provider extends InjectedProvider { +export class InjectedL2Provider extends InjectedProviderDefaultBase { chainName: string chainId: string rpcUrls: Array diff --git a/apps/remix-ide/src/app/providers/injected-provider-default.tsx b/apps/remix-ide/src/app/providers/injected-provider-default.tsx new file mode 100644 index 0000000000..9af45e5660 --- /dev/null +++ b/apps/remix-ide/src/app/providers/injected-provider-default.tsx @@ -0,0 +1,40 @@ +/* global ethereum */ +import * as packageJson from '../../../../../package.json' +import { InjectedProvider } from './injected-provider' + +export class InjectedProviderDefaultBase extends InjectedProvider { + constructor (profile) { + super(profile) + } + + 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).') + } + return super.init() + } + + getInjectedProvider () { + return (window as any).ethereum + } + + 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).' + } +} + +const profile = { + name: 'injected', + displayName: 'Injected Provider', + kind: 'provider', + description: 'injected Provider', + methods: ['sendAsync', 'init'], + version: packageJson.version +} + +export class InjectedProviderDefault extends InjectedProviderDefaultBase { + 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 new file mode 100644 index 0000000000..c58f6d12f8 --- /dev/null +++ b/apps/remix-ide/src/app/providers/injected-provider-trustwallet.tsx @@ -0,0 +1,26 @@ +/* global ethereum */ +import * as packageJson from '../../../../../package.json' +import { InjectedProvider } from './injected-provider' + +const profile = { + name: 'injected-trustwallet', + displayName: 'Trust wallet', + kind: 'provider', + description: 'Trust wallet', + methods: ['sendAsync', 'init'], + version: packageJson.version +} + +export class InjectedProviderTrustWallet extends InjectedProvider { + constructor () { + super(profile) + } + + getInjectedProvider () { + return (window as any).trustwallet + } + + 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 1ca363800b..4de903c0c8 100644 --- a/apps/remix-ide/src/app/providers/injected-provider.tsx +++ b/apps/remix-ide/src/app/providers/injected-provider.tsx @@ -2,27 +2,52 @@ import React from 'react' // eslint-disable-line import { Plugin } from '@remixproject/engine' import { JsonDataRequest, RejectRequest, SuccessRequest } from '../providers/abstract-provider' -import Web3 from 'web3' import { IProvider } from './abstract-provider' -const noInjectedProviderMsg = '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).' - -export class InjectedProvider extends Plugin implements IProvider { - provider: any +export abstract class InjectedProvider extends Plugin implements IProvider { options: { [id: string] : any } = {} + listenerAccountsChanged: (accounts: Array) => void + listenerChainChanged: (chainId: number) => void constructor (profile) { super(profile) - if ((window as any).ethereum) { - this.provider = new Web3((window as any).ethereum) + this.listenerAccountsChanged = (accounts: Array) => { + this.emit('accountsChanged', accounts) + } + this.listenerChainChanged = (chainId: number) => { + this.emit('chainChanged', chainId) } } + abstract getInjectedProvider(): any + abstract notFound(): string + + onActivation(): void { + try { + const web3Provider = this.getInjectedProvider() + 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('chainChanged', this.listenerChainChanged) + } catch (error) { + console.log('unable to remove listener on context changed') + } + } + askPermission (throwIfNoInjectedProvider) { - if ((typeof (window as any).ethereum) !== "undefined" && (typeof (window as any).ethereum.request) === "function") { - (window as any).ethereum.request({ method: "eth_requestAccounts" }) + const web3Provider = this.getInjectedProvider() + if (typeof web3Provider !== "undefined" && typeof web3Provider.request === "function") { + web3Provider.request({ method: "eth_requestAccounts" }) } else if (throwIfNoInjectedProvider) { - throw new Error(noInjectedProviderMsg) + throw new Error(this.notFound()) } } @@ -33,14 +58,11 @@ export class InjectedProvider extends Plugin implements IProvider { } async init () { - const injectedProvider = (window as any).ethereum + const injectedProvider = this.getInjectedProvider() if (injectedProvider === undefined) { - this.call('notification', 'toast', noInjectedProviderMsg) - throw new Error(noInjectedProviderMsg) + this.call('notification', 'toast', this.notFound()) + throw new Error(this.notFound()) } else { - 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).') - } this.askPermission(true) } return {} @@ -55,12 +77,19 @@ export class InjectedProvider extends Plugin implements IProvider { 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 !!' - if (!this.provider) { + 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 }) } try { - let resultData = await this.provider.currentProvider.send(data.method, data.params) + 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}) + else { + resolve({ jsonrpc: '2.0', error: 'provider not valid', id: data.id }) + return + } if (resultData) { if (resultData.jsonrpc && resultData.jsonrpc === '2.0') { resultData = resultData.result diff --git a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json index 8e4d6eaa07..6c1091bd63 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json +++ b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json @@ -10,12 +10,14 @@ "filePanel.workspace.rename": "Rename Workspace", "filePanel.workspace.delete": "Delete Workspace", "filePanel.workspace.deleteConfirm": "Are you sure to delete the current workspace?", + "filePanel.workspace.download": "Download Workspace", + "filePanel.workspace.downloadConfirm": "This will download current workspace in a zip file. Do you want to continue?", "filePanel.workspace.deleteAll": "Delete All Workspaces", "filePanel.workspace.deleteAllConfirm1": "Are you absolutely sure you want to delete all your workspaces?", "filePanel.workspace.deleteAllConfirm2": "Deleted workspaces can not be restored in any manner.", "filePanel.workspace.name": "Workspace name", "filePanel.workspace.chooseTemplate": "Choose a template", - "filePanel.workspace.backup": "Backup Workspaces", + "filePanel.workspace.backup": "Backup All Workspaces", "filePanel.workspace.restore": "Restore Workspaces from the Backup", "filePanel.workspace.clone": "Clone Git Repository", "filePanel.workspace.cloneMessage": "Please provide a valid git repository url.", diff --git a/apps/remix-ide/src/app/udapp/run-tab.js b/apps/remix-ide/src/app/udapp/run-tab.js index f833cc29e5..8bec995ca8 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.js +++ b/apps/remix-ide/src/app/udapp/run-tab.js @@ -132,11 +132,20 @@ export class RunTab extends ViewPlugin { } // basic injected - const displayNameInjected = `Injected Provider${(window && window.ethereum && !(window.ethereum.providers && !window.ethereum.selectedProvider)) ? - window.ethereum.isCoinbaseWallet || window.ethereum.selectedProvider?.isCoinbaseWallet ? ' - Coinbase' : - window.ethereum.isBraveWallet || window.ethereum.selectedProvider?.isBraveWallet ? ' - Brave' : - window.ethereum.isMetaMask || window.ethereum.selectedProvider?.isMetaMask ? ' - MetaMask' : '' : ''}` - await addProvider('injected', displayNameInjected, true, false) + // if it's the trust wallet provider, we have a specific provider for that, see below + if (window && window.ethereum && !(window.ethereum.isTrustWallet || window.ethereum.selectedProvider?.isTrustWallet)) { + const displayNameInjected = `Injected Provider${(window && window.ethereum && !(window.ethereum.providers && !window.ethereum.selectedProvider)) ? + window.ethereum.isCoinbaseWallet || window.ethereum.selectedProvider?.isCoinbaseWallet ? ' - Coinbase' : + window.ethereum.isBraveWallet || window.ethereum.selectedProvider?.isBraveWallet ? ' - Brave' : + window.ethereum.isMetaMask || window.ethereum.selectedProvider?.isMetaMask ? ' - MetaMask' : '' : ''}` + await addProvider('injected', displayNameInjected, true, false) + } + + if (window && window.trustwallet) { + const displayNameInjected = `Injected Provider - TrustWallet` + await addProvider('injected-trustwallet', displayNameInjected, true, false) + } + // VM const titleVM = 'Execution environment is local to Remix. Data is only saved to browser memory and will vanish upon reload.' await addProvider('vm-merge', 'Remix VM (Merge)', false, true, 'merge', 'settingsVMMergeMode', titleVM) diff --git a/apps/remix-ide/src/blockchain/blockchain.js b/apps/remix-ide/src/blockchain/blockchain.js index 0047b786f9..49367096ab 100644 --- a/apps/remix-ide/src/blockchain/blockchain.js +++ b/apps/remix-ide/src/blockchain/blockchain.js @@ -23,7 +23,7 @@ const profile = { name: 'blockchain', displayName: 'Blockchain', description: 'Blockchain - Logic', - methods: ['getCode', 'getTransactionReceipt', 'addProvider', 'removeProvider', 'getCurrentFork', 'web3VM'], + methods: ['getCode', 'getTransactionReceipt', 'addProvider', 'removeProvider', 'getCurrentFork', 'web3VM', 'getProvider'], version: packageJson.version } @@ -48,33 +48,62 @@ export class Blockchain extends Plugin { }, _ => this.executionContext.web3(), _ => this.executionContext.currentblockGasLimit()) this.txRunner = new TxRunner(web3Runner, { runAsync: true }) - this.executionContext.event.register('contextChanged', this.resetEnvironment.bind(this)) - this.networkcallid = 0 - this.networkStatus = { name: ' - ', id: ' - ' } + this.networkStatus = { network: { name: ' - ', id: ' - ' } } this.setupEvents() this.setupProviders() } + _triggerEvent (name, args) { + this.event.trigger(name, args) + this.emit(name, ...args) + } + + onActivation () { + this.on('injected', 'chainChanged', () => { + this.detectNetwork((error, network) => { + this.networkStatus = { network, error } + this._triggerEvent('networkStatus', [this.networkStatus]) + }) + }) + + this.on('injected-trustwallet', 'chainChanged', () => { + this.detectNetwork((error, network) => { + this.networkStatus = { network, error } + this._triggerEvent('networkStatus', [this.networkStatus]) + }) + }) + } + + onDeactivation () { + this.off('injected', 'chainChanged') + this.off('injected-trustwallet', 'chainChanged') + } + setupEvents () { - this.executionContext.event.register('contextChanged', (context, silent) => { - this.event.trigger('contextChanged', [context, silent]) + this.executionContext.event.register('contextChanged', async (context) => { + await this.resetEnvironment() + this._triggerEvent('contextChanged', [context]) + this.detectNetwork((error, network) => { + this.networkStatus = { network, error } + this._triggerEvent('networkStatus', [this.networkStatus]) + }) }) this.executionContext.event.register('addProvider', (network) => { - this.event.trigger('addProvider', [network]) + this._triggerEvent('addProvider', [network]) }) this.executionContext.event.register('removeProvider', (name) => { - this.event.trigger('removeProvider', [name]) + this._triggerEvent('removeProvider', [name]) }) setInterval(() => { this.detectNetwork((error, network) => { this.networkStatus = { network, error } - this.event.trigger('networkStatus', [this.networkStatus]) + this._triggerEvent('networkStatus', [this.networkStatus]) }) - }, 1000) + }, 30000) } getCurrentNetworkStatus () { @@ -479,13 +508,11 @@ export class Blockchain extends Plugin { } // NOTE: the config is only needed because exectuionContext.init does - // if config.get('settings/always-use-vm'), we can simplify this later - resetAndInit (config, transactionContextAPI) { + async resetAndInit (config, transactionContextAPI) { this.transactionContextAPI = transactionContextAPI this.executionContext.init(config) this.executionContext.stopListenOnLastBlock() this.executionContext.listenOnLastBlock() - this.resetEnvironment() } addProvider (provider) { @@ -504,8 +531,8 @@ export class Blockchain extends Plugin { }) } - resetEnvironment () { - this.getCurrentProvider().resetEnvironment() + async resetEnvironment () { + await this.getCurrentProvider().resetEnvironment() // TODO: most params here can be refactored away in txRunner const web3Runner = new TxRunnerWeb3({ config: this.config, @@ -551,8 +578,8 @@ export class Blockchain extends Plugin { } /** Get the balance of an address, and convert wei to ether */ - getBalanceInEther (address, cb) { - this.getCurrentProvider().getBalanceInEther(address, cb) + getBalanceInEther (address) { + return this.getCurrentProvider().getBalanceInEther(address) } pendingTransactionsCount () { @@ -674,7 +701,7 @@ export class Blockchain extends Plugin { if (!tx.timestamp) tx.timestamp = Date.now() const timestamp = tx.timestamp - this.event.trigger('initiatingTransaction', [timestamp, tx, payLoad]) + this._triggerEvent('initiatingTransaction', [timestamp, tx, payLoad]) try { this.txRunner.rawRun(tx, confirmationCb, continueCb, promptCb, async (error, result) => { @@ -698,7 +725,7 @@ export class Blockchain extends Plugin { } const eventName = (tx.useCall ? 'callExecuted' : 'transactionExecuted') - this.event.trigger(eventName, [error, tx.from, tx.to, tx.data, tx.useCall, result, timestamp, payLoad]) + this._triggerEvent(eventName, [error, tx.from, tx.to, tx.data, tx.useCall, result, timestamp, payLoad]) return resolve({ result, tx }) } ) diff --git a/apps/remix-ide/src/blockchain/execution-context.js b/apps/remix-ide/src/blockchain/execution-context.js index b762f91484..3f7ecf6b6b 100644 --- a/apps/remix-ide/src/blockchain/execution-context.js +++ b/apps/remix-ide/src/blockchain/execution-context.js @@ -34,9 +34,8 @@ export class ExecutionContext { } init (config) { - if (config.get('settings/always-use-vm')) { - this.executionContext = 'vm-merge' - } + this.executionContext = 'vm-merge' + this.event.trigger('contextChanged', [this.executionContext]) } getProvider () { diff --git a/apps/remix-ide/src/blockchain/providers/injected.js b/apps/remix-ide/src/blockchain/providers/injected.js index 6e994b9a00..dbfc53f9de 100644 --- a/apps/remix-ide/src/blockchain/providers/injected.js +++ b/apps/remix-ide/src/blockchain/providers/injected.js @@ -16,17 +16,13 @@ class InjectedProvider { }) } - resetEnvironment () { + async resetEnvironment () { /* Do nothing. */ } - getBalanceInEther (address, cb) { - this.executionContext.web3().eth.getBalance(address, (err, res) => { - if (err) { - return cb(err) - } - cb(null, Web3.utils.fromWei(res.toString(10), 'ether')) - }) + async getBalanceInEther (address) { + const balance = await this.executionContext.web3().eth.getBalance(address) + return Web3.utils.fromWei(balance.toString(10), 'ether') } getGasPrice (cb) { diff --git a/apps/remix-ide/src/blockchain/providers/node.js b/apps/remix-ide/src/blockchain/providers/node.js index b5ebd6ecc0..14350a45f7 100644 --- a/apps/remix-ide/src/blockchain/providers/node.js +++ b/apps/remix-ide/src/blockchain/providers/node.js @@ -24,17 +24,13 @@ class NodeProvider { }) } - resetEnvironment () { + async resetEnvironment () { /* Do nothing. */ } - getBalanceInEther (address, cb) { - this.executionContext.web3().eth.getBalance(address, (err, res) => { - if (err) { - return cb(err) - } - cb(null, Web3.utils.fromWei(res.toString(10), 'ether')) - }) + async getBalanceInEther (address) { + const balance = await this.executionContext.web3().eth.getBalance(address) + return Web3.utils.fromWei(balance.toString(10), 'ether') } getGasPrice (cb) { diff --git a/apps/remix-ide/src/blockchain/providers/vm.js b/apps/remix-ide/src/blockchain/providers/vm.js index 2f9322deef..6a6a862bca 100644 --- a/apps/remix-ide/src/blockchain/providers/vm.js +++ b/apps/remix-ide/src/blockchain/providers/vm.js @@ -19,7 +19,7 @@ class VMProvider { }) } - resetEnvironment () { + async resetEnvironment () { if (this.worker) this.worker.terminate() this.accounts = {} this.worker = new Worker(new URL('./worker-vm', import.meta.url)) @@ -27,23 +27,29 @@ class VMProvider { let incr = 0 const stamps = {} - this.worker.addEventListener('message', (msg) => { - if (msg.data.cmd === 'sendAsyncResult' && stamps[msg.data.stamp]) { - stamps[msg.data.stamp](msg.data.error, msg.data.result) - } else if (msg.data.cmd === 'initiateResult') { - if (!msg.data.error) { - this.provider = { - sendAsync: (query, callback) => { - const stamp = Date.now() + incr - incr++ - stamps[stamp] = callback - this.worker.postMessage({ cmd: 'sendAsync', query, stamp }) + + return new Promise((resolve, reject) => { + this.worker.addEventListener('message', (msg) => { + if (msg.data.cmd === 'sendAsyncResult' && stamps[msg.data.stamp]) { + stamps[msg.data.stamp](msg.data.error, msg.data.result) + } else if (msg.data.cmd === 'initiateResult') { + if (!msg.data.error) { + this.provider = { + sendAsync: (query, callback) => { + const stamp = Date.now() + incr + incr++ + stamps[stamp] = callback + this.worker.postMessage({ cmd: 'sendAsync', query, stamp }) + } } + this.web3 = new Web3(this.provider) + extend(this.web3) + this.accounts = {} + this.executionContext.setWeb3(this.executionContext.getProvider(), this.web3) + resolve({}) + } else { + reject(new Error(msg.data.error)) } - this.web3 = new Web3(this.provider) - extend(this.web3) - this.accounts = {} - this.executionContext.setWeb3(this.executionContext.getProvider(), this.web3) } } else if (msg.data.cmd === 'newAccountResult') { if (this.newAccountCallback[msg.data.stamp]) { @@ -52,7 +58,6 @@ class VMProvider { } } }) - this.worker.postMessage({ cmd: 'init', fork: this.executionContext.getCurrentFork(), nodeUrl: provider?.options['nodeUrl'], blockNumber: provider?.options['blockNumber']}) } @@ -71,13 +76,9 @@ class VMProvider { this.worker.postMessage({ cmd: 'newAccount', stamp }) } - getBalanceInEther (address, cb) { - this.web3.eth.getBalance(address, (err, res) => { - if (err) { - return cb(err) - } - cb(null, Web3.utils.fromWei(new BN(res).toString(10), 'ether')) - }) + async getBalanceInEther (address) { + const balance = await this.web3.eth.getBalance(address) + return Web3.utils.fromWei(new BN(balance).toString(10), 'ether') } getGasPrice (cb) { diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index db5e5370df..2a4d7f4671 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -10,7 +10,7 @@ const requiredModules = [ // services + layout views + system views 'fileManager', 'contentImport', 'blockchain', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons', 'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity', 'solidity-logic', 'gistHandler', 'layout', 'notification', 'permissionhandler', 'walkthrough', 'storage', 'restorebackupzip', 'link-libraries', 'deploy-libraries', 'openzeppelin-proxy', - 'hardhat-provider', 'ganache-provider', 'foundry-provider', 'basic-http-provider', 'injected', 'injected-optimism-provider', 'injected-arbitrum-one-provider', 'vm-custom-fork', 'vm-goerli-fork', 'vm-mainnet-fork', 'vm-sepolia-fork', 'vm-merge', 'vm-london', 'vm-berlin', + 'hardhat-provider', 'ganache-provider', 'foundry-provider', 'basic-http-provider', 'injected', 'injected-trustwallet', 'injected-optimism-provider', 'injected-arbitrum-one-provider', 'vm-custom-fork', 'vm-goerli-fork', 'vm-mainnet-fork', 'vm-sepolia-fork', 'vm-merge', 'vm-london', 'vm-berlin', 'compileAndRun', 'search', 'recorder', 'fileDecorator', 'codeParser', 'codeFormatter', 'solidityumlgen', 'contractflattener'] // dependentModules shouldn't be manually activated (e.g hardhat is activated by remixd) diff --git a/apps/remix-ide/webpack.config.js b/apps/remix-ide/webpack.config.js index 8b08e62145..1705f29d32 100644 --- a/apps/remix-ide/webpack.config.js +++ b/apps/remix-ide/webpack.config.js @@ -77,7 +77,7 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { enforce: "pre" }) - config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings + config.ignoreWarnings = [/Failed to parse source map/, /require function/ ] // ignore source-map-loader warnings & AST warnings // set minimizer config.optimization.minimizer = [ @@ -96,5 +96,9 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { new CssMinimizerPlugin(), ]; + config.watchOptions = { + ignored: /node_modules/ + } + return config; }); diff --git a/apps/solidity-compiler/webpack.config.js b/apps/solidity-compiler/webpack.config.js index ad6144a8dc..e19684ca91 100644 --- a/apps/solidity-compiler/webpack.config.js +++ b/apps/solidity-compiler/webpack.config.js @@ -89,5 +89,9 @@ module.exports = composePlugins(withNx(), withReact(), (config) => { new CssMinimizerPlugin(), ]; + config.watchOptions = { + ignored: /node_modules/ + } + return config; }); diff --git a/apps/vyper/webpack.config.js b/apps/vyper/webpack.config.js index fa6f5e3b06..9feb0dc08d 100644 --- a/apps/vyper/webpack.config.js +++ b/apps/vyper/webpack.config.js @@ -79,5 +79,9 @@ module.exports = composePlugins(withNx(), (config) => { new CssMinimizerPlugin(), ]; + config.watchOptions = { + ignored: /node_modules/ + } + return config; }); diff --git a/libs/ghaction-helper/package.json b/libs/ghaction-helper/package.json index e307cac4b1..3da2205e87 100644 --- a/libs/ghaction-helper/package.json +++ b/libs/ghaction-helper/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/ghaction-helper", - "version": "0.1.7-alpha.10", + "version": "0.1.7-alpha.17", "description": "Solidity Tests GitHub Action Helper", "main": "src/index.js", "scripts": { @@ -19,17 +19,17 @@ }, "homepage": "https://github.com/ethereum/remix-project#readme", "devDependencies": { - "@remix-project/remix-solidity": "^0.5.11-alpha.10", + "@remix-project/remix-solidity": "^0.5.11-alpha.17", "@types/chai": "^4.3.4", "typescript": "^4.9.3" }, "dependencies": { "@ethereum-waffle/chai": "^3.4.4", - "@remix-project/remix-simulator": "^0.2.25-alpha.10", + "@remix-project/remix-simulator": "^0.2.25-alpha.17", "chai": "^4.3.7", "ethers": "^5.7.2", "web3": "^1.5.3" }, "types": "./src/index.d.ts", - "gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c" + "gitHead": "4806543bb099b558872793ca7a215468e0bffc81" } \ No newline at end of file diff --git a/libs/ghaction-helper/src/methods.ts b/libs/ghaction-helper/src/methods.ts index fe82378018..8bea9f5532 100644 --- a/libs/ghaction-helper/src/methods.ts +++ b/libs/ghaction-helper/src/methods.ts @@ -5,20 +5,18 @@ import { getArtifactsByContractName } from './artifacts-helper' import { SignerWithAddress } from './signer' import Web3 from "web3" -(async () => { - const providerConfig = { - fork: global.fork || null, - nodeUrl: global.nodeUrl || null, - blockNumber: global.blockNumber || null - } +const providerConfig = { + fork: global.fork || null, + nodeUrl: global.nodeUrl || null, + blockNumber: global.blockNumber || null +} - global.remixProvider = new Provider(providerConfig) - await global.remixProvider.init() - global.web3Provider = new ethers.providers.Web3Provider(global.remixProvider) - global.provider = global.web3Provider - global.ethereum = global.web3Provider - global.web3 = new Web3(global.web3Provider) -})() +global.remixProvider = new Provider(providerConfig) +global.remixProvider.init() +global.web3Provider = new ethers.providers.Web3Provider(global.remixProvider) +global.provider = global.web3Provider +global.ethereum = global.web3Provider +global.web3 = new Web3(global.web3Provider) const isFactoryOptions = (signerOrOptions: any) => { if (!signerOrOptions || signerOrOptions === undefined || signerOrOptions instanceof ethers.Signer) return false diff --git a/libs/remix-analyzer/package.json b/libs/remix-analyzer/package.json index 6fdd00e1e8..7bfa11b8cd 100644 --- a/libs/remix-analyzer/package.json +++ b/libs/remix-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-analyzer", - "version": "0.5.34-alpha.10", + "version": "0.5.34-alpha.17", "description": "Tool to perform static analysis on Solidity smart contracts", "scripts": { "test": "./../../node_modules/.bin/ts-node --project ../../tsconfig.base.json --require tsconfig-paths/register ./../../node_modules/.bin/tape ./test/tests.ts" @@ -25,8 +25,8 @@ "@ethereumjs/tx": "^4.0.2", "@ethereumjs/util": "^8.0.3", "@ethereumjs/vm": "^6.3.0", - "@remix-project/remix-astwalker": "^0.0.55-alpha.10", - "@remix-project/remix-lib": "^0.5.25-alpha.10", + "@remix-project/remix-astwalker": "^0.0.55-alpha.17", + "@remix-project/remix-lib": "^0.5.25-alpha.17", "async": "^2.6.2", "ethers": "^5.4.2", "ethjs-util": "^0.1.6", @@ -50,6 +50,6 @@ "typescript": "^3.7.5" }, "typings": "src/index.d.ts", - "gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c", + "gitHead": "4806543bb099b558872793ca7a215468e0bffc81", "main": "./src/index.js" } \ No newline at end of file diff --git a/libs/remix-astwalker/package.json b/libs/remix-astwalker/package.json index 0546e8aa05..4935c4698c 100644 --- a/libs/remix-astwalker/package.json +++ b/libs/remix-astwalker/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-astwalker", - "version": "0.0.55-alpha.10", + "version": "0.0.55-alpha.17", "description": "Tool to walk through Solidity AST", "main": "src/index.js", "scripts": { @@ -37,7 +37,7 @@ "@ethereumjs/tx": "^4.0.2", "@ethereumjs/util": "^8.0.3", "@ethereumjs/vm": "^6.3.0", - "@remix-project/remix-lib": "^0.5.25-alpha.10", + "@remix-project/remix-lib": "^0.5.25-alpha.17", "@types/tape": "^4.2.33", "async": "^2.6.2", "ethers": "^5.4.2", @@ -53,6 +53,6 @@ "tap-spec": "^5.0.0" }, "typings": "src/index.d.ts", - "gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c", + "gitHead": "4806543bb099b558872793ca7a215468e0bffc81", "types": "./src/index.d.ts" } \ No newline at end of file diff --git a/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts b/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts index 810faadd2c..3030321f93 100644 --- a/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts +++ b/libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts @@ -134,7 +134,18 @@ export class FetchAndCompile extends Plugin { if (!data) { setTimeout(_ => this.emit('notFound', contractAddress), 0) this.unresolvedAddresses.push(contractAddress) - return localCompilation() + const compilation = await localCompilation() + if (compilation) { + let found = false + compilation.visitContracts((contract) => { + found = util.compareByteCode(codeAtAddress, '0x' + contract.object.evm.deployedBytecode.object) + return found + }) + if (found) { + await this.call('compilerArtefacts', 'addResolvedContract', contractAddress, compilation) + return compilation + } + } } const { settings, compilationTargets } = data diff --git a/libs/remix-debug/package.json b/libs/remix-debug/package.json index 7da35447cf..bd3640f4a6 100644 --- a/libs/remix-debug/package.json +++ b/libs/remix-debug/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-debug", - "version": "0.5.25-alpha.10", + "version": "0.5.25-alpha.17", "description": "Tool to debug Ethereum transactions", "contributors": [ { @@ -26,10 +26,10 @@ "@ethereumjs/tx": "^4.0.2", "@ethereumjs/util": "^8.0.3", "@ethereumjs/vm": "^6.3.0", - "@remix-project/remix-astwalker": "^0.0.55-alpha.10", - "@remix-project/remix-lib": "^0.5.25-alpha.10", - "@remix-project/remix-simulator": "^0.2.25-alpha.10", - "@remix-project/remix-solidity": "^0.5.11-alpha.10", + "@remix-project/remix-astwalker": "^0.0.55-alpha.17", + "@remix-project/remix-lib": "^0.5.25-alpha.17", + "@remix-project/remix-simulator": "^0.2.25-alpha.17", + "@remix-project/remix-solidity": "^0.5.11-alpha.17", "ansi-gray": "^0.1.1", "async": "^2.6.2", "color-support": "^1.1.3", @@ -69,6 +69,6 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-debug#readme", "typings": "src/index.d.ts", - "gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c", + "gitHead": "4806543bb099b558872793ca7a215468e0bffc81", "types": "./src/index.d.ts" } \ No newline at end of file diff --git a/libs/remix-lib/package.json b/libs/remix-lib/package.json index 5230b21bcb..5b07a0760a 100644 --- a/libs/remix-lib/package.json +++ b/libs/remix-lib/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-lib", - "version": "0.5.25-alpha.10", + "version": "0.5.25-alpha.17", "description": "Library to various Remix tools", "contributors": [ { @@ -51,6 +51,6 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-lib#readme", "typings": "src/index.d.ts", - "gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c", + "gitHead": "4806543bb099b558872793ca7a215468e0bffc81", "types": "./src/index.d.ts" } \ No newline at end of file diff --git a/libs/remix-simulator/package.json b/libs/remix-simulator/package.json index 07c815e95e..d4f83939b4 100644 --- a/libs/remix-simulator/package.json +++ b/libs/remix-simulator/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-simulator", - "version": "0.2.25-alpha.10", + "version": "0.2.25-alpha.17", "description": "Ethereum IDE and tools for the web", "contributors": [ { @@ -22,7 +22,7 @@ "@ethereumjs/tx": "^4.0.2", "@ethereumjs/util": "^8.0.3", "@ethereumjs/vm": "^6.3.0", - "@remix-project/remix-lib": "^0.5.25-alpha.10", + "@remix-project/remix-lib": "^0.5.25-alpha.17", "ansi-gray": "^0.1.1", "async": "^3.1.0", "body-parser": "^1.18.2", @@ -67,6 +67,6 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-simulator#readme", "typings": "src/index.d.ts", - "gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c", + "gitHead": "4806543bb099b558872793ca7a215468e0bffc81", "types": "./src/index.d.ts" } \ No newline at end of file diff --git a/libs/remix-simulator/src/provider.ts b/libs/remix-simulator/src/provider.ts index 264a9f7b4c..03b2840943 100644 --- a/libs/remix-simulator/src/provider.ts +++ b/libs/remix-simulator/src/provider.ts @@ -18,7 +18,9 @@ export class Provider { Accounts Transactions methods - connected: boolean; + connected: boolean + initialized: boolean + pendingRequests: Array constructor (options: Record = {}) { this.options = options @@ -39,15 +41,27 @@ export class Provider { } async init () { + this.initialized = false + this.pendingRequests = [] await this.vmContext.init() await generateBlock(this.vmContext) await this.Accounts.resetAccounts() this.Transactions.init(this.Accounts.accounts) + this.initialized = true + if (this.pendingRequests.length > 0) { + this.pendingRequests.map((req) => { + this.sendAsync(req.payload, req.callback) + }) + this.pendingRequests = [] + } } sendAsync (payload, callback) { // log.info('payload method is ', payload.method) // commented because, this floods the IDE console - + if (!this.initialized) { + this.pendingRequests.push({ payload, callback }) + return + } const method = this.methods[payload.method] if (this.options.logDetails) { info(payload) diff --git a/libs/remix-solidity/package.json b/libs/remix-solidity/package.json index 42ee0db087..10e2076bec 100644 --- a/libs/remix-solidity/package.json +++ b/libs/remix-solidity/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-solidity", - "version": "0.5.11-alpha.10", + "version": "0.5.11-alpha.17", "description": "Tool to load and run Solidity compiler", "main": "src/index.js", "types": "src/index.d.ts", @@ -19,7 +19,7 @@ "@ethereumjs/tx": "^4.0.2", "@ethereumjs/util": "^8.0.3", "@ethereumjs/vm": "^6.3.0", - "@remix-project/remix-lib": "^0.5.25-alpha.10", + "@remix-project/remix-lib": "^0.5.25-alpha.17", "async": "^2.6.2", "eslint-scope": "^5.0.0", "ethers": "^5.4.2", @@ -57,5 +57,5 @@ }, "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-solidity#readme", "typings": "src/index.d.ts", - "gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c" + "gitHead": "4806543bb099b558872793ca7a215468e0bffc81" } \ No newline at end of file diff --git a/libs/remix-tests/package.json b/libs/remix-tests/package.json index 849bb6ee00..cd92586fb8 100644 --- a/libs/remix-tests/package.json +++ b/libs/remix-tests/package.json @@ -1,6 +1,6 @@ { "name": "@remix-project/remix-tests", - "version": "0.2.25-alpha.10", + "version": "0.2.25-alpha.17", "description": "Tool to test Solidity smart contracts", "main": "src/index.js", "types": "./src/index.d.ts", @@ -41,9 +41,9 @@ "@ethereumjs/tx": "^4.0.2", "@ethereumjs/util": "^8.0.3", "@ethereumjs/vm": "^6.3.0", - "@remix-project/remix-lib": "^0.5.25-alpha.10", - "@remix-project/remix-simulator": "^0.2.25-alpha.10", - "@remix-project/remix-solidity": "^0.5.11-alpha.10", + "@remix-project/remix-lib": "^0.5.25-alpha.17", + "@remix-project/remix-simulator": "^0.2.25-alpha.17", + "@remix-project/remix-solidity": "^0.5.11-alpha.17", "@remix-project/remix-url-resolver": "^0.0.42", "ansi-gray": "^0.1.1", "async": "^2.6.0", @@ -78,5 +78,5 @@ "typescript": "^3.3.1" }, "typings": "src/index.d.ts", - "gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c" + "gitHead": "4806543bb099b558872793ca7a215468e0bffc81" } \ No newline at end of file diff --git a/libs/remix-tests/src/run.ts b/libs/remix-tests/src/run.ts index ada8ab2ea8..116da1cb28 100644 --- a/libs/remix-tests/src/run.ts +++ b/libs/remix-tests/src/run.ts @@ -55,6 +55,7 @@ commander .option('-f, --fork ', 'set hard fork (e.g: istanbul, berlin etc. See full list of hard forks here: https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/common/src/hardforks)') .option('-n, --nodeUrl ', 'set node url (e.g: https://mainnet.infura.io/v3/your-api-key)') .option('-b, --blockNumber ', 'set block number (e.g: 123456)') + .option('-k, --killProcess ', 'kill process when tests fail') .argument('file_path', 'path to test file or directory') .action(async (file_path) => { const options = commander.opts(); @@ -131,8 +132,9 @@ commander await provider.init() web3.setProvider(provider) extend(web3) - runTestFiles(path.resolve(file_path), isDirectory, web3, compilerConfig, (error) => { + runTestFiles(path.resolve(file_path), isDirectory, web3, compilerConfig, (error, totalPassing, totalFailing) => { if (error) process.exit(1) + if (totalFailing > 0 && options.killProcess) process.exit(1) }) }) @@ -140,5 +142,4 @@ if (!process.argv.slice(2).length) { log.error('Please specify a file or directory path') process.exit(1) } - commander.parse(process.argv) diff --git a/libs/remix-tests/src/runTestFiles.ts b/libs/remix-tests/src/runTestFiles.ts index 143f38e45c..a811f9b441 100644 --- a/libs/remix-tests/src/runTestFiles.ts +++ b/libs/remix-tests/src/runTestFiles.ts @@ -173,8 +173,7 @@ export function runTestFiles (filepath: string, isDirectory: boolean, web3: Web3 } console.log(colors.white('Time Taken: ' + totalTime + 's')) console.log('') - - next() + next(null, totalPassing, totalFailing) }) } ], finalCallback) diff --git a/libs/remix-tests/tests/testRunner.cli.spec.ts b/libs/remix-tests/tests/testRunner.cli.spec.ts index 16bd565cce..c4824c9b8b 100644 --- a/libs/remix-tests/tests/testRunner.cli.spec.ts +++ b/libs/remix-tests/tests/testRunner.cli.spec.ts @@ -49,6 +49,7 @@ Options: -n, --nodeUrl set node url (e.g: https://mainnet.infura.io/v3/your-api-key) -b, --blockNumber set block number (e.g: 123456) + -k, --killProcess kill process when tests fail -h, --help display help for command Commands: diff --git a/libs/remix-ui/editor/src/lib/providers/completionProvider.ts b/libs/remix-ui/editor/src/lib/providers/completionProvider.ts index f387bdcd15..5e28da8d44 100644 --- a/libs/remix-ui/editor/src/lib/providers/completionProvider.ts +++ b/libs/remix-ui/editor/src/lib/providers/completionProvider.ts @@ -119,7 +119,7 @@ export class RemixCompletionProvider implements monacoTypes.languages.Completion // truncate for performance if (filteredNodes.length > this.maximumItemsForContractCompletion) { - await this.props.plugin.call('notification', 'toast', `Too many completion items. Only ${this.maximumItemsForContractCompletion} items will be shown.`) + // await this.props.plugin.call('notification', 'toast', `Too many completion items. Only ${this.maximumItemsForContractCompletion} items will be shown.`) filteredNodes = filteredNodes.slice(0, this.maximumItemsForContractCompletion) } diff --git a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx index 3df0397c03..0097e05f66 100644 --- a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx +++ b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx @@ -12,8 +12,6 @@ import { monacoTypes } from '@remix-ui/editor'; import './remix-ui-editor.css' import { loadTypes } from './web-types' - - import { RemixHoverProvider } from './providers/hoverProvider' import { RemixReferenceProvider } from './providers/referenceProvider' import { RemixCompletionProvider } from './providers/completionProvider' @@ -262,6 +260,7 @@ export const EditorUI = (props: EditorUIProps) => { { token: 'keyword.continue', foreground: warningColor }, { token: 'keyword.while', foreground: warningColor }, { token: 'keyword.do', foreground: warningColor }, + { token: 'keyword.delete', foreground: warningColor }, { token: 'keyword.if', foreground: yellowColor }, { token: 'keyword.else', foreground: yellowColor }, diff --git a/libs/remix-ui/editor/src/lib/syntaxes/solidity.ts b/libs/remix-ui/editor/src/lib/syntaxes/solidity.ts index dfb388fda4..fda352456e 100644 --- a/libs/remix-ui/editor/src/lib/syntaxes/solidity.ts +++ b/libs/remix-ui/editor/src/lib/syntaxes/solidity.ts @@ -1266,6 +1266,7 @@ export const solidityTokensProvider = { 'constant', 'fallback', 'receive', + 'delete', 'if', 'else', 'for', diff --git a/libs/remix-ui/helper/src/lib/components/custom-dropdown.tsx b/libs/remix-ui/helper/src/lib/components/custom-dropdown.tsx index 5322b4c61a..c6f9462bc2 100644 --- a/libs/remix-ui/helper/src/lib/components/custom-dropdown.tsx +++ b/libs/remix-ui/helper/src/lib/components/custom-dropdown.tsx @@ -37,7 +37,7 @@ export const CustomIconsToggle = React.forwardRef(({ onClick, icon, className = // forwardRef again here! // Dropdown needs access to the DOM of the Menu to measure it export const CustomMenu = React.forwardRef( - ({ children, style, className, 'aria-labelledby': labeledBy }: { children: React.ReactNode, style?: React.CSSProperties, className: string, 'aria-labelledby'?: string }, ref: Ref) => { + ({ children, style, 'data-id': dataId, className, 'aria-labelledby': labeledBy }: { children: React.ReactNode, style?: React.CSSProperties, 'data-id'?: string, className: string, 'aria-labelledby'?: string }, ref: Ref) => { const height = window.innerHeight * 0.6 return (
    { diff --git a/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx b/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx index f60309c24e..66330349b0 100644 --- a/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx +++ b/libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx @@ -103,7 +103,8 @@ export const ModalDialog = (props: ModalDialogProps) => { onClick={() => { if (props.validation && !props.validation.valid) return if (props.okFn) props.okFn() - handleHide() + if (props.donotHideOnOkClick) calledHideFunctionOnce.current = false + else handleHide() }} > {props.okLabel ? props.okLabel : 'OK'} diff --git a/libs/remix-ui/modal-dialog/src/lib/types/index.ts b/libs/remix-ui/modal-dialog/src/lib/types/index.ts index e469bffc61..0c96017bac 100644 --- a/libs/remix-ui/modal-dialog/src/lib/types/index.ts +++ b/libs/remix-ui/modal-dialog/src/lib/types/index.ts @@ -13,6 +13,7 @@ export interface ModalDialogProps { message?: string | JSX.Element, okLabel?: string | JSX.Element, okFn?: (value?:any) => void, + donotHideOnOkClick?: boolean, cancelLabel?: string | JSX.Element, cancelFn?: () => void, modalClass?: string, diff --git a/libs/remix-ui/renderer/src/lib/renderer.css b/libs/remix-ui/renderer/src/lib/renderer.css index 26b05fc019..e03e68502c 100644 --- a/libs/remix-ui/renderer/src/lib/renderer.css +++ b/libs/remix-ui/renderer/src/lib/renderer.css @@ -1,48 +1,46 @@ .remixui_sol.success, .remixui_sol.error, .remixui_sol.warning { - white-space: pre-line; - word-wrap: break-word; - cursor: pointer; - position: relative; - margin: 0.5em 0 1em 0; - border-radius: 5px; - line-height: 20px; - padding: 8px 15px; + white-space: pre-line; + word-wrap: break-word; + cursor: pointer; + position: relative; + margin: 0.5em 0 1em 0; + border-radius: 5px; + line-height: 20px; + padding: 8px 15px; } .remixui_sol.success pre, .remixui_sol.error pre, .remixui_sol.warning pre { - white-space: pre-line; - overflow-y: hidden; - background-color: transparent; - margin: 0; - font-size: 12px; - border: 0 none; - padding: 0; - border-radius: 0; + white-space: pre-line; + overflow-y: hidden; + background-color: transparent; + margin: 0; + font-size: 12px; + border: 0 none; + padding: 0; + border-radius: 0; } .remixui_sol.success .close, .remixui_sol.error .close, .remixui_sol.warning .close { - visibility: hidden; - white-space: pre-line; - font-weight: bold; - position: absolute; - color: hsl(0, 0%, 0%); /* black in style-guide.js */ - top: 0; - right: 0; - padding: 0.5em; + visibility: hidden; + white-space: pre-line; + font-weight: bold; + position: absolute; + color: hsl(0, 0%, 0%); /* black in style-guide.js */ + top: 0; + right: 0; + padding: 0.5em; } -.remixui_sol.error { -} - -.remixui_sol.warning { -} - -.remixui_sol.success { - /* background-color: // styles.rightPanel.message_Success_BackgroundColor; */ +.remixui_sol.success a, +.remixui_sol.error a, +.remixui_sol.warning a { + position: absolute; + bottom: 0; + right: 0; } diff --git a/libs/remix-ui/renderer/src/lib/renderer.tsx b/libs/remix-ui/renderer/src/lib/renderer.tsx index 679d26c490..9873b84c07 100644 --- a/libs/remix-ui/renderer/src/lib/renderer.tsx +++ b/libs/remix-ui/renderer/src/lib/renderer.tsx @@ -1,4 +1,5 @@ import React, { useEffect, useState } from 'react' //eslint-disable-line +import { CopyToClipboard } from '@remix-ui/clipboard' import { helper } from '@remix-project/remix-solidity' import './renderer.css' interface RendererProps { @@ -77,7 +78,9 @@ export const Renderer = ({ message, opt = {}, plugin }: RendererProps) => {
    -
) + + + ) } ) diff --git a/libs/remix-ui/run-tab/src/lib/actions/account.ts b/libs/remix-ui/run-tab/src/lib/actions/account.ts index 461f928d43..060de8bf62 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/account.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/account.ts @@ -3,17 +3,14 @@ import { RunTab } from "../types/run-tab" import { clearInstances, setAccount, setExecEnv } from "./actions" import { displayNotification, displayPopUp, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, setExternalEndpoint, setMatchPassphrase, setPassphrase } from "./payload" -export const updateAccountBalances = (plugin: RunTab, dispatch: React.Dispatch) => { +export const updateAccountBalances = async (plugin: RunTab, dispatch: React.Dispatch) => { const accounts = plugin.REACT_API.accounts.loadedAccounts - Object.keys(accounts).map((value) => { - plugin.blockchain.getBalanceInEther(value, (err, balance) => { - if (err) return - const updated = shortenAddress(value, balance) - - accounts[value] = updated - }) - }) + for (const account of Object.keys(accounts)) { + const balance = await plugin.blockchain.getBalanceInEther(account) + const updated = shortenAddress(account, balance) + accounts[account] = updated + } dispatch(fetchAccountsListSuccess(accounts)) } @@ -31,17 +28,10 @@ export const fillAccountsList = async (plugin: RunTab, dispatch: React.Dispatch< // - all the promises resolve // - at least one reject // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all - await (Promise as any).all(accounts.map((account) => { - return new Promise((resolve, reject) => { - plugin.blockchain.getBalanceInEther(account, (err, balance) => { - if (err) return reject(err) - const updated = shortenAddress(account, balance) - - loadedAccounts[account] = updated - resolve(account) - }) - }) - })) + for (const account of accounts) { + const balance = await plugin.blockchain.getBalanceInEther(account) + loadedAccounts[account] = shortenAddress(account, balance) + } const provider = plugin.blockchain.getProvider() if (provider === 'injected') { @@ -59,6 +49,7 @@ export const fillAccountsList = async (plugin: RunTab, dispatch: React.Dispatch< } export const setFinalContext = (plugin: RunTab, dispatch: React.Dispatch) => { + dispatch(fetchAccountsListRequest()) // set the final context. Cause it is possible that this is not the one we've originaly selected const value = _getProviderDropdownValue(plugin) diff --git a/libs/remix-ui/run-tab/src/lib/actions/deploy.ts b/libs/remix-ui/run-tab/src/lib/actions/deploy.ts index 7b6a4807f9..d2efbe71c1 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/deploy.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/deploy.ts @@ -6,7 +6,7 @@ import { SolcInput, SolcOutput } from "@openzeppelin/upgrades-core" // Used direct path to UpgradeableContract class to fix cyclic dependency error from @openzeppelin/upgrades-core library import { UpgradeableContract } from '../../../../../../node_modules/@openzeppelin/upgrades-core/dist/standalone' import { DeployMode, MainnetPrompt } from "../types" -import { displayNotification, displayPopUp, fetchProxyDeploymentsSuccess, setDecodedResponse } from "./payload" +import { displayNotification, displayPopUp, fetchProxyDeploymentsSuccess, setDecodedResponse, updateInstancesBalance } from "./payload" import { addInstance } from "./actions" import { addressToString, logBuilder } from "@remix-ui/helper" import Web3 from "web3" @@ -318,14 +318,15 @@ export const getFuncABIInputs = (plugin: RunTab, funcABI: FuncABI) => { return plugin.blockchain.getInputs(funcABI) } -export const updateInstanceBalance = (plugin: RunTab) => { +export const updateInstanceBalance = async (plugin: RunTab, dispatch: React.Dispatch) => { if (plugin.REACT_API?.instances?.instanceList?.length) { - for (const instance of plugin.REACT_API.instances.instanceList) { - plugin.blockchain.getBalanceInEther(instance.address, (err, balInEth) => { - if (!err) instance.balance = balInEth - }) + const instances = plugin.REACT_API?.instances?.instanceList + for (const instance of instances) { + const balInEth = await plugin.blockchain.getBalanceInEther(instance.address) + instance.balance = balInEth } - } + dispatch(updateInstanceBalance(instances, dispatch)) + } } export const isValidContractAddress = async (plugin: RunTab, address: string) => { diff --git a/libs/remix-ui/run-tab/src/lib/actions/events.ts b/libs/remix-ui/run-tab/src/lib/actions/events.ts index ed686bb887..5fd49279d2 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/events.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/events.ts @@ -1,13 +1,15 @@ import { envChangeNotification } from "@remix-ui/helper" import { RunTab } from "../types/run-tab" -import { setExecutionContext, setFinalContext, updateAccountBalances } from "./account" +import { setExecutionContext, setFinalContext, updateAccountBalances, fillAccountsList } from "./account" import { addExternalProvider, addInstance, addNewProxyDeployment, removeExternalProvider, setNetworkNameFromProvider } from "./actions" -import { addDeployOption, clearAllInstances, clearRecorderCount, fetchContractListSuccess, resetProxyDeployments, resetUdapp, setCurrentContract, setCurrentFile, setLoadType, setRecorderCount, setRemixDActivated, setSendValue } from "./payload" +import { addDeployOption, clearAllInstances, clearRecorderCount, fetchContractListSuccess, resetProxyDeployments, resetUdapp, setCurrentContract, setCurrentFile, setLoadType, setRecorderCount, setRemixDActivated, setSendValue, fetchAccountsListSuccess } from "./payload" +import { updateInstanceBalance } from './deploy' import { CompilerAbstract } from '@remix-project/remix-solidity' import BN from 'bn.js' import Web3 from 'web3' import { Plugin } from "@remixproject/engine" import { getNetworkProxyAddresses } from "./deploy" +import { shortenAddress } from "@remix-ui/helper" const _paq = window._paq = window._paq || [] @@ -20,12 +22,15 @@ export const setupEvents = (plugin: RunTab, dispatch: React.Dispatch) => { if (!lookupOnly) dispatch(setSendValue('0')) if (error) return updateAccountBalances(plugin, dispatch) + updateInstanceBalance(plugin, dispatch) }) - plugin.blockchain.event.register('contextChanged', (context, silent) => { + plugin.blockchain.event.register('contextChanged', (context) => { dispatch(resetProxyDeployments()) if (!context.startsWith('vm')) getNetworkProxyAddresses(plugin, dispatch) setFinalContext(plugin, dispatch) + fillAccountsList(plugin, dispatch) + updateAccountBalances(plugin, dispatch) }) plugin.blockchain.event.register('networkStatus', ({ error, network }) => { @@ -117,6 +122,23 @@ export const setupEvents = (plugin: RunTab, dispatch: React.Dispatch) => { plugin.event.register('cleared', () => { dispatch(clearRecorderCount()) }) + + plugin.on('injected', 'accountsChanged', (accounts: Array) => { + const accountsMap = {} + accounts.map(account => { accountsMap[account] = shortenAddress(account, '0')}) + dispatch(fetchAccountsListSuccess(accountsMap)) + }) + + plugin.on('injected-trustwallet', 'accountsChanged', (accounts: Array) => { + const accountsMap = {} + accounts.map(account => { accountsMap[account] = shortenAddress(account, '0')}) + dispatch(fetchAccountsListSuccess(accountsMap)) + }) + + setInterval(() => { + fillAccountsList(plugin, dispatch) + updateInstanceBalance(plugin, dispatch) + }, 30000) } const broadcastCompilationResult = async (compilerName: string, plugin: RunTab, dispatch: React.Dispatch, file, source, languageVersion, data, input?) => { diff --git a/libs/remix-ui/run-tab/src/lib/actions/index.ts b/libs/remix-ui/run-tab/src/lib/actions/index.ts index 6b6447c566..d13c9d0bfd 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/index.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/index.ts @@ -2,7 +2,7 @@ import React from 'react' import { RunTab } from '../types/run-tab' import { resetAndInit, setupEvents } from './events' -import { createNewBlockchainAccount, fillAccountsList, setExecutionContext, signMessageWithAddress } from './account' +import { createNewBlockchainAccount, setExecutionContext, signMessageWithAddress } from './account' import { clearInstances, clearPopUp, removeInstance, setAccount, setGasFee, setMatchPassphrasePrompt, setNetworkNameFromProvider, setPassphrasePrompt, setSelectedContract, setSendTransactionValue, setUnit, updateBaseFeePerGas, updateConfirmSettings, updateGasPrice, updateGasPriceStatus, updateMaxFee, updateMaxPriorityFee, updateScenarioPath } from './actions' @@ -25,12 +25,8 @@ let plugin: RunTab, dispatch: React.Dispatch export const initRunTab = (udapp: RunTab) => async (reducerDispatch: React.Dispatch) => { plugin = udapp dispatch = reducerDispatch + setupEvents(plugin, dispatch) resetAndInit(plugin) - setupEvents(plugin, dispatch) - setInterval(() => { - fillAccountsList(plugin, dispatch) - updateInstanceBalance(plugin) - }, 1000) } export const setAccountAddress = (account: string) => setAccount(dispatch, account) diff --git a/libs/remix-ui/run-tab/src/lib/actions/payload.ts b/libs/remix-ui/run-tab/src/lib/actions/payload.ts index 98189d529a..c8bee7af2e 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/payload.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/payload.ts @@ -1,5 +1,5 @@ import { ContractData } from '@remix-project/core-plugin' -import { ADD_DEPLOY_OPTION, ADD_INSTANCE, ADD_PROVIDER, CLEAR_INSTANCES, CLEAR_RECORDER_COUNT, DISPLAY_NOTIFICATION, DISPLAY_POPUP_MESSAGE, FETCH_ACCOUNTS_LIST_FAILED, FETCH_ACCOUNTS_LIST_REQUEST, FETCH_ACCOUNTS_LIST_SUCCESS, FETCH_CONTRACT_LIST_FAILED, FETCH_CONTRACT_LIST_REQUEST, FETCH_CONTRACT_LIST_SUCCESS, HIDE_NOTIFICATION, HIDE_POPUP_MESSAGE, REMOVE_DEPLOY_OPTION, REMOVE_INSTANCE, REMOVE_PROVIDER, RESET_STATE, SET_BASE_FEE_PER_GAS, SET_CONFIRM_SETTINGS, SET_CURRENT_CONTRACT, SET_CURRENT_FILE, SET_DECODED_RESPONSE, SET_DEPLOY_OPTIONS, SET_EXECUTION_ENVIRONMENT, SET_EXTERNAL_WEB3_ENDPOINT, SET_GAS_LIMIT, SET_GAS_PRICE, SET_GAS_PRICE_STATUS, SET_IPFS_CHECKED_STATE, SET_LOAD_TYPE, SET_MATCH_PASSPHRASE, SET_MAX_FEE, SET_MAX_PRIORITY_FEE, SET_NETWORK_NAME, SET_PASSPHRASE, SET_PATH_TO_SCENARIO, SET_PERSONAL_MODE, SET_RECORDER_COUNT, SET_SELECTED_ACCOUNT, SET_SEND_UNIT, SET_SEND_VALUE, SET_REMIXD_ACTIVATED, FETCH_PROXY_DEPLOYMENTS, NEW_PROXY_DEPLOYMENT, RESET_PROXY_DEPLOYMENTS } from '../constants' +import { ADD_DEPLOY_OPTION, ADD_INSTANCE, UPDATE_INSTANCES_BALANCE, ADD_PROVIDER, CLEAR_INSTANCES, CLEAR_RECORDER_COUNT, DISPLAY_NOTIFICATION, DISPLAY_POPUP_MESSAGE, FETCH_ACCOUNTS_LIST_FAILED, FETCH_ACCOUNTS_LIST_REQUEST, FETCH_ACCOUNTS_LIST_SUCCESS, FETCH_CONTRACT_LIST_FAILED, FETCH_CONTRACT_LIST_REQUEST, FETCH_CONTRACT_LIST_SUCCESS, HIDE_NOTIFICATION, HIDE_POPUP_MESSAGE, REMOVE_DEPLOY_OPTION, REMOVE_INSTANCE, REMOVE_PROVIDER, RESET_STATE, SET_BASE_FEE_PER_GAS, SET_CONFIRM_SETTINGS, SET_CURRENT_CONTRACT, SET_CURRENT_FILE, SET_DECODED_RESPONSE, SET_DEPLOY_OPTIONS, SET_EXECUTION_ENVIRONMENT, SET_EXTERNAL_WEB3_ENDPOINT, SET_GAS_LIMIT, SET_GAS_PRICE, SET_GAS_PRICE_STATUS, SET_IPFS_CHECKED_STATE, SET_LOAD_TYPE, SET_MATCH_PASSPHRASE, SET_MAX_FEE, SET_MAX_PRIORITY_FEE, SET_NETWORK_NAME, SET_PASSPHRASE, SET_PATH_TO_SCENARIO, SET_PERSONAL_MODE, SET_RECORDER_COUNT, SET_SELECTED_ACCOUNT, SET_SEND_UNIT, SET_SEND_VALUE, SET_REMIXD_ACTIVATED, FETCH_PROXY_DEPLOYMENTS, NEW_PROXY_DEPLOYMENT, RESET_PROXY_DEPLOYMENTS } from '../constants' import { ContractList, DeployOptions } from '../types' export const fetchAccountsListRequest = () => { @@ -216,6 +216,13 @@ export const setGasPrice = (price: string) => { } } +export const updateInstancesBalance = (instances: Array<{ contractData?: ContractData, address: string, name: string, abi?: any }>) => { + return { + type: UPDATE_INSTANCES_BALANCE, + payload: instances + } +} + export const addNewInstance = (instance: { contractData?: ContractData, address: string, name: string, abi?: any }) => { return { type: ADD_INSTANCE, diff --git a/libs/remix-ui/run-tab/src/lib/components/account.tsx b/libs/remix-ui/run-tab/src/lib/components/account.tsx index 4687927fe1..dfcdf4f9d1 100644 --- a/libs/remix-ui/run-tab/src/lib/components/account.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/account.tsx @@ -117,42 +117,38 @@ export function AccountUI (props: AccountProps) { const passphraseCreationPrompt = () => { return ( -
Please provide a Passphrase for the account creation -
- -
-
- -
+
+ Please provide a Passphrase for the account creation + +
) } const signMessagePrompt = () => { return ( -
-
- -
+
+ +
) } const signedMessagePrompt = (msgHash: string, signedData: string) => { return ( -
- :
+
+ {msgHash} -
:
+ {signedData}
) @@ -168,16 +164,17 @@ export function AccountUI (props: AccountProps) { tooltipId="remixPlusWrapperTooltip" tooltipText={plusOpt.title} > - - - + + + + { props.accounts.isRequesting && }
- { props.setAccount(e.target.value) }}> + { + accounts.map((value, index) => ) + }
}> = action.payload + + return { + ...state, + instances: { + ...state.instances, + instanceList: payload + } + } + } + case REMOVE_INSTANCE: { const payload: number = action.payload diff --git a/libs/remix-ui/run-tab/src/lib/types/blockchain.d.ts b/libs/remix-ui/run-tab/src/lib/types/blockchain.d.ts index 0575d3988c..137ff0e92c 100644 --- a/libs/remix-ui/run-tab/src/lib/types/blockchain.d.ts +++ b/libs/remix-ui/run-tab/src/lib/types/blockchain.d.ts @@ -60,7 +60,7 @@ export class Blockchain extends Plugin { removeProvider(name: any): void; /** Listen on New Transaction. (Cannot be done inside constructor because txlistener doesn't exist yet) */ startListening(txlistener: any): void; - resetEnvironment(): void; + resetEnvironment(): Promise; /** * Create a VM Account * @param {{privateKey: string, balance: string}} newAccount The new account to create @@ -71,7 +71,7 @@ export class Blockchain extends Plugin { }): any; newAccount(_password: any, passwordPromptCb: any, cb: any): any; /** Get the balance of an address, and convert wei to ether */ - getBalanceInEther(address: any, cb: any): void; + getBalanceInEther(address: any): Promise; pendingTransactionsCount(): number; /** * This function send a tx only to Remix VM or testnet, will return an error for the mainnet diff --git a/libs/remix-ui/run-tab/src/lib/types/injected.d.ts b/libs/remix-ui/run-tab/src/lib/types/injected.d.ts index c12ab88933..085faca4c5 100644 --- a/libs/remix-ui/run-tab/src/lib/types/injected.d.ts +++ b/libs/remix-ui/run-tab/src/lib/types/injected.d.ts @@ -4,8 +4,8 @@ declare class InjectedProvider { executionContext: any; getAccounts(cb: any): any; newAccount(passwordPromptCb: any, cb: any): void; - resetEnvironment(): void; - getBalanceInEther(address: any, cb: any): void; + resetEnvironment(): Promise; + getBalanceInEther(address: any): Promise; getGasPrice(cb: any): void; signMessage(message: any, account: any, _passphrase: any, cb: any): void; getProvider(): string; diff --git a/libs/remix-ui/run-tab/src/lib/types/node.d.ts b/libs/remix-ui/run-tab/src/lib/types/node.d.ts index 8979746943..365c95a2cb 100644 --- a/libs/remix-ui/run-tab/src/lib/types/node.d.ts +++ b/libs/remix-ui/run-tab/src/lib/types/node.d.ts @@ -5,8 +5,8 @@ declare class NodeProvider { config: any; getAccounts(cb: any): any; newAccount(passwordPromptCb: any, cb: any): any; - resetEnvironment(): void; - getBalanceInEther(address: any, cb: any): void; + resetEnvironment(): Promise; + getBalanceInEther(address: any): Promise; getGasPrice(cb: any): void; signMessage(message: any, account: any, passphrase: any, cb: any): void; getProvider(): any; diff --git a/libs/remix-ui/run-tab/src/lib/types/vm.d.ts b/libs/remix-ui/run-tab/src/lib/types/vm.d.ts index 95fe2ea803..5b94d5315d 100644 --- a/libs/remix-ui/run-tab/src/lib/types/vm.d.ts +++ b/libs/remix-ui/run-tab/src/lib/types/vm.d.ts @@ -3,13 +3,13 @@ declare class VMProvider { constructor(executionContext: any); executionContext: any; getAccounts(cb: any): void; - resetEnvironment(): void; + resetEnvironment(): Promise; accounts: any; RemixSimulatorProvider: any; web3: any; createVMAccount(newAccount: any): string; newAccount(_passwordPromptCb: any, cb: any): void; - getBalanceInEther(address: any, cb: any): void; + getBalanceInEther(address: any): Promise; getGasPrice(cb: any): void; signMessage(message: any, account: any, _passphrase: any, cb: any): void; getProvider(): string; diff --git a/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx index f08d6279c7..90cd1682be 100644 --- a/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx +++ b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx @@ -3,7 +3,7 @@ import React, { useState, useReducer, useEffect, useCallback } from 'react' // e import { labels, textDark, textSecondary } from './constants' import './remix-ui-settings.css' -import { ethereumVM, generateContractMetadat, personal, textWrapEventAction, useMatomoAnalytics, saveTokenToast, removeTokenToast, saveSwarmSettingsToast, saveIpfsSettingsToast, useAutoCompletion, useShowGasInEditor, useDisplayErrors } from './settingsAction' +import { generateContractMetadat, personal, textWrapEventAction, useMatomoAnalytics, saveTokenToast, removeTokenToast, saveSwarmSettingsToast, saveIpfsSettingsToast, useAutoCompletion, useShowGasInEditor, useDisplayErrors } from './settingsAction' import { initialState, toastInitialState, toastReducer, settingReducer } from './settingsReducer' import { Toaster } from '@remix-ui/toaster'// eslint-disable-line import { RemixUiThemeModule, ThemeModule} from '@remix-ui/theme-module' @@ -41,17 +41,14 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { const metadataConfig = props.config.get('settings/generate-contract-metadata') if (metadataConfig === undefined || metadataConfig === null) generateContractMetadat(props.config, true, dispatch) - const javascriptVM = props.config.get('settings/always-use-vm') - if (javascriptVM === null || javascriptVM === undefined) ethereumVM(props.config, true, dispatch) - const useAutoComplete = props.config.get('settings/auto-completion') - if (useAutoComplete === null || useAutoComplete === undefined) useAutoCompletion(props.config, false, dispatch) + if (useAutoComplete === null || useAutoComplete === undefined) useAutoCompletion(props.config, true, dispatch) const displayErrors = props.config.get('settings/display-errors') - if (displayErrors === null || displayErrors === undefined) useDisplayErrors(props.config, false, dispatch) + if (displayErrors === null || displayErrors === undefined) useDisplayErrors(props.config, true, dispatch) const useShowGas = props.config.get('settings/show-gas') - if (useShowGas === null || useShowGas === undefined) useShowGasInEditor(props.config, false, dispatch) + if (useShowGas === null || useShowGas === undefined) useShowGasInEditor(props.config, true, dispatch) } useEffect(() => initValue(), [resetState, props.config]) useEffect(() => initValue(), []) @@ -110,10 +107,6 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { generateContractMetadat(props.config, event.target.checked, dispatch) } - const onchangeOption = (event) => { - ethereumVM(props.config, event.target.checked, dispatch) - } - const textWrapEvent = (event) => { textWrapEventAction(props.config, props.editor, event.target.checked, dispatch) } @@ -148,7 +141,6 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { const generalConfig = () => { const isMetadataChecked = props.config.get('settings/generate-contract-metadata') || false - const isEthereumVMChecked = props.config.get('settings/always-use-vm') || false const isEditorWrapChecked = props.config.get('settings/text-wrap') || false const isPersonalChecked = props.config.get('settings/personal-mode') || false const isMatomoChecked = props.config.get('settings/matomo-analytics') || false @@ -192,12 +184,6 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
-
- - -
- - modal(selectedContract, log, 'Close', null) + const downloadFn = () => { + _paq.push(['trackEvent', 'compiler', 'compilerDetails', 'download']) + saveAs(new Blob([JSON.stringify(contractProperties, null, '\t')]), `${selectedContract}_compData.json`) + } + modal(selectedContract, log, 'Download', downloadFn, true, 'Close', null) } const copyBytecode = () => { diff --git a/libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx b/libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx index 328797acf3..6277443121 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx +++ b/libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx @@ -27,6 +27,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => { message: null, okLabel: '', okFn: () => { }, + donotHideOnOkClick: false, cancelLabel: '', cancelFn: () => { }, handleHide: null @@ -131,7 +132,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => { api.setCompilerParameters({ version: value }) } - const modal = async (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => { + const modal = async (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, donotHideOnOkClick: boolean, cancelLabel?: string, cancelFn?: () => void) => { await setState(prevState => { return { ...prevState, @@ -142,6 +143,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => { title, okLabel, okFn, + donotHideOnOkClick, cancelLabel, cancelFn } @@ -190,7 +192,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => { <> {compileErrors[currentFile].error && } - {compileErrors[currentFile].error && (compileErrors[currentFile].error.mode === 'panic') && modal('Error', panicMessage(compileErrors[currentFile].error.formattedMessage), 'Close', null)} + {compileErrors[currentFile].error && (compileErrors[currentFile].error.mode === 'panic') && modal('Error', panicMessage(compileErrors[currentFile].error.formattedMessage), 'Close', null, false)} {compileErrors[currentFile].errors && compileErrors[currentFile].errors.length && compileErrors[currentFile].errors.map((err, index) => { if (hideWarnings) { if (err.severity !== 'warning') { @@ -212,6 +214,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => { hide={state.modal.hide} okLabel={state.modal.okLabel} okFn={state.modal.okFn} + donotHideOnOkClick={state.modal.donotHideOnOkClick} cancelLabel={state.modal.cancelLabel} cancelFn={state.modal.cancelFn} handleHide={handleHideModal}> diff --git a/libs/remix-ui/solidity-compiler/src/lib/types/index.ts b/libs/remix-ui/solidity-compiler/src/lib/types/index.ts index 7e14b71973..848596f5e0 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/types/index.ts +++ b/libs/remix-ui/solidity-compiler/src/lib/types/index.ts @@ -14,7 +14,7 @@ export interface CompilerContainerProps { isFoundryProject: boolean, workspaceName: string, tooltip: (message: string | JSX.Element) => void, - modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void, + modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, donotHideOnOkClick?: boolean, cancelLabel?: string, cancelFn?: () => void) => void, compiledFileName: string, updateCurrentVersion: any, configurationSettings: ConfigurationSettings, @@ -26,7 +26,7 @@ export interface ContractSelectionProps { compiledFileName: string, contractList: { file: string, name: string }[], compilerInput: Record - modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void, + modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, donotHideOnOkClick?: boolean, cancelLabel?: string, cancelFn?: () => void) => void, contractsDetails: Record } diff --git a/libs/remix-ui/workspace/src/lib/actions/index.ts b/libs/remix-ui/workspace/src/lib/actions/index.ts index 67f9c83f82..424daf41d9 100644 --- a/libs/remix-ui/workspace/src/lib/actions/index.ts +++ b/libs/remix-ui/workspace/src/lib/actions/index.ts @@ -376,6 +376,21 @@ export const handleDownloadFiles = async () => { } } +export const handleDownloadWorkspace = async () => { + try { + const zip = new JSZip() + const workspaceProvider = plugin.fileProviders.workspace + await workspaceProvider.copyFolderToJson('/', ({ path, content }) => { + zip.file(path, content) + }) + const blob = await zip.generateAsync({ type: 'blob' }) + saveAs(blob, `${workspaceProvider.workspace}.zip`) + } catch (e) { + console.error(e) + plugin.call('notification', 'toast', e.message) + } +} + export const restoreBackupZip = async () => { await plugin.appManager.activatePlugin(['restorebackupzip']) await plugin.call('mainPanel', 'showContent', 'restorebackupzip') diff --git a/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx b/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx index 523f9b1287..9941dee29a 100644 --- a/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx +++ b/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx @@ -4,9 +4,10 @@ import { HamburgerMenuItem } from './workspace-hamburger-item' export interface HamburgerMenuProps { createWorkspace: () => void, + renameCurrentWorkspace: () => void, + downloadCurrentWorkspace: () => void, deleteCurrentWorkspace: () => void, deleteAllWorkspaces: () => void, - renameCurrentWorkspace: () => void, cloneGitRepository: () => void, downloadWorkspaces: () => void, restoreBackup: () => void, @@ -27,24 +28,27 @@ export function HamburgerMenu (props: HamburgerMenuProps) { props.createWorkspace() props.hideIconsMenu(!showIconsMenu) }}> - { - props.deleteCurrentWorkspace() - props.hideIconsMenu(!showIconsMenu) - }}> - { - props.deleteAllWorkspaces() + { + props.cloneGitRepository() props.hideIconsMenu(!showIconsMenu) }}> { props.renameCurrentWorkspace() props.hideIconsMenu(!showIconsMenu) }}> + { + props.downloadCurrentWorkspace() + props.hideIconsMenu(!showIconsMenu) + }}> + { + props.deleteCurrentWorkspace() + props.hideIconsMenu(!showIconsMenu) + }}> - { - props.cloneGitRepository() + { + props.deleteAllWorkspaces() props.hideIconsMenu(!showIconsMenu) }}> - { props.downloadWorkspaces() props.hideIconsMenu(!showIconsMenu) diff --git a/libs/remix-ui/workspace/src/lib/contexts/index.ts b/libs/remix-ui/workspace/src/lib/contexts/index.ts index 04e91602ef..44783948be 100644 --- a/libs/remix-ui/workspace/src/lib/contexts/index.ts +++ b/libs/remix-ui/workspace/src/lib/contexts/index.ts @@ -33,6 +33,7 @@ export const FileSystemContext = createContext<{ dispatchHandleClickFile: (path: string, type: 'file' | 'folder' | 'gist') => Promise dispatchHandleExpandPath: (paths: string[]) => Promise, dispatchHandleDownloadFiles: () => Promise, + dispatchHandleDownloadWorkspace: () => Promise, dispatchHandleRestoreBackup: () => Promise dispatchCloneRepository: (url: string) => Promise, dispatchMoveFile: (src: string, dest: string) => Promise, diff --git a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx index e05e92a7d2..ae038142a7 100644 --- a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx +++ b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx @@ -7,7 +7,7 @@ import { FileSystemContext } from '../contexts' import { browserReducer, browserInitialState } from '../reducers/workspace' import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, deleteAllWorkspaces, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder, deletePath, renamePath, downloadPath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace, - fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, uploadFolder, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder, + fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, uploadFolder, handleDownloadWorkspace, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder, showAllBranches, switchBranch, createNewBranch, checkoutRemoteBranch, createSolidityGithubAction, createTsSolGithubAction, createSlitherGithubAction } from '../actions' import { Modal, WorkspaceProps, WorkspaceTemplate } from '../types' @@ -135,6 +135,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => { await handleDownloadFiles() } + const dispatchHandleDownloadWorkspace = async () => { + await handleDownloadWorkspace() + } + const dispatchHandleRestoreBackup = async () => { await restoreBackupZip() } @@ -284,6 +288,7 @@ export const FileSystemProvider = (props: WorkspaceProps) => { dispatchHandleClickFile, dispatchHandleExpandPath, dispatchHandleDownloadFiles, + dispatchHandleDownloadWorkspace, dispatchHandleRestoreBackup, dispatchCloneRepository, dispatchMoveFile, diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index 43fefe1b2e..5b73874993 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -76,6 +76,9 @@ export function Workspace () { global.modal(intl.formatMessage({ id: 'filePanel.workspace.rename' }), renameModalMessage(), intl.formatMessage({ id: 'filePanel.ok' }), onFinishRenameWorkspace, intl.formatMessage({ id: 'filePanel.cancel' })) } + const downloadCurrentWorkspace = () => { + global.modal(intl.formatMessage({ id: 'filePanel.workspace.download' }), intl.formatMessage({ id: 'filePanel.workspace.downloadConfirm' }), intl.formatMessage({ id: 'filePanel.ok' }), onFinishDownloadWorkspace, intl.formatMessage({ id: 'filePanel.cancel' })) + } const createWorkspace = () => { global.modal(intl.formatMessage({ id: 'filePanel.workspace.create' }), createModalMessage(), intl.formatMessage({ id: 'filePanel.ok' }), onFinishCreateWorkspace, intl.formatMessage({ id: 'filePanel.cancel' })) } @@ -156,6 +159,15 @@ export function Workspace () { } } + const onFinishDownloadWorkspace = async () => { + try { + await global.dispatchHandleDownloadWorkspace() + } catch (e) { + global.modal(intl.formatMessage({ id: 'filePanel.workspace.download' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' })) + console.error(e) + } + } + const onFinishCreateWorkspace = async () => { if (workspaceCreateInput.current === undefined) return // @ts-ignore: Object is possibly 'null'. @@ -453,9 +465,10 @@ export function Workspace () { = 1.43.0 < 2": - version "1.51.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" - integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== - mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-db@~1.26.0: - version "1.26.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.26.0.tgz#eaffcd0e4fc6935cf8134da246e2e6c35305adff" - integrity sha1-6v/NDk/Gk1z4E02iRuLmw1MFrf8= - -mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.34" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" - integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== - dependencies: - mime-db "1.51.0" +"mime-db@>= 1.43.0 < 2": + version "1.51.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== -mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@^2.1.16, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34, mime-types@~2.1.7: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" -mime-types@~2.1.7: - version "2.1.14" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.14.tgz#f7ef7d97583fcaf3b7d282b6f8b5679dab1e94ee" - integrity sha1-9+99l1g/yvO30oK2+LVnnaselO4= - dependencies: - mime-db "~1.26.0" - mime@1.6.0, mime@^1.4.1, mime@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" @@ -19177,11 +19124,6 @@ node-notifier@^4.2.3: shellwords "^0.1.0" which "^1.0.5" -node-releases@^1.1.77: - version "1.1.77" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.77.tgz#50b0cfede855dd374e7585bf228ff34e57c1c32e" - integrity sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ== - node-releases@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" @@ -20712,11 +20654,6 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -picocolors@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" - integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== - picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -26267,9 +26204,9 @@ webpack-subresource-integrity@^5.1.0: typed-assert "^1.0.8" webpack@^5.75.0: - version "5.75.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.75.0.tgz#1e440468647b2505860e94c9ff3e44d5b582c152" - integrity sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ== + version "5.76.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c" + integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51"