Merge branch 'master' into fix_vm_mode

pull/5370/head
Liana Husikyan 2 years ago committed by GitHub
commit 2a9cdbe630
  1. 4
      apps/debugger/webpack.config.js
  2. 4
      apps/etherscan/webpack.config.js
  3. 4
      apps/remix-ide-e2e/src/commands/verifyContracts.ts
  4. 4
      apps/remix-ide-e2e/src/local-plugin/webpack.config.js
  5. 8
      apps/remix-ide-e2e/src/tests/editorHoverContext.test.ts
  6. 7
      apps/remix-ide-e2e/src/tests/editorReferences.test.ts
  7. 8
      apps/remix-ide-e2e/src/tests/editor_error_marker.test.ts
  8. 8
      apps/remix-ide-e2e/src/tests/editor_line_text.test.ts
  9. 29
      apps/remix-ide-e2e/src/tests/workspace.test.ts
  10. 9
      apps/remix-ide/src/app.js
  11. 18
      apps/remix-ide/src/app/providers/basic-injected-provider.tsx
  12. 4
      apps/remix-ide/src/app/providers/injected-L2-provider.tsx
  13. 40
      apps/remix-ide/src/app/providers/injected-provider-default.tsx
  14. 26
      apps/remix-ide/src/app/providers/injected-provider-trustwallet.tsx
  15. 65
      apps/remix-ide/src/app/providers/injected-provider.tsx
  16. 4
      apps/remix-ide/src/app/tabs/locales/en/filePanel.json
  17. 19
      apps/remix-ide/src/app/udapp/run-tab.js
  18. 65
      apps/remix-ide/src/blockchain/blockchain.js
  19. 5
      apps/remix-ide/src/blockchain/execution-context.js
  20. 12
      apps/remix-ide/src/blockchain/providers/injected.js
  21. 12
      apps/remix-ide/src/blockchain/providers/node.js
  22. 49
      apps/remix-ide/src/blockchain/providers/vm.js
  23. 2
      apps/remix-ide/src/remixAppManager.js
  24. 6
      apps/remix-ide/webpack.config.js
  25. 4
      apps/solidity-compiler/webpack.config.js
  26. 4
      apps/vyper/webpack.config.js
  27. 8
      libs/ghaction-helper/package.json
  28. 24
      libs/ghaction-helper/src/methods.ts
  29. 8
      libs/remix-analyzer/package.json
  30. 6
      libs/remix-astwalker/package.json
  31. 13
      libs/remix-core-plugin/src/lib/compiler-fetch-and-compile.ts
  32. 12
      libs/remix-debug/package.json
  33. 4
      libs/remix-lib/package.json
  34. 6
      libs/remix-simulator/package.json
  35. 18
      libs/remix-simulator/src/provider.ts
  36. 6
      libs/remix-solidity/package.json
  37. 10
      libs/remix-tests/package.json
  38. 5
      libs/remix-tests/src/run.ts
  39. 3
      libs/remix-tests/src/runTestFiles.ts
  40. 1
      libs/remix-tests/tests/testRunner.cli.spec.ts
  41. 2
      libs/remix-ui/editor/src/lib/providers/completionProvider.ts
  42. 3
      libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
  43. 1
      libs/remix-ui/editor/src/lib/syntaxes/solidity.ts
  44. 3
      libs/remix-ui/helper/src/lib/components/custom-dropdown.tsx
  45. 3
      libs/remix-ui/modal-dialog/src/lib/remix-ui-modal-dialog.tsx
  46. 1
      libs/remix-ui/modal-dialog/src/lib/types/index.ts
  47. 62
      libs/remix-ui/renderer/src/lib/renderer.css
  48. 5
      libs/remix-ui/renderer/src/lib/renderer.tsx
  49. 31
      libs/remix-ui/run-tab/src/lib/actions/account.ts
  50. 15
      libs/remix-ui/run-tab/src/lib/actions/deploy.ts
  51. 28
      libs/remix-ui/run-tab/src/lib/actions/events.ts
  52. 8
      libs/remix-ui/run-tab/src/lib/actions/index.ts
  53. 9
      libs/remix-ui/run-tab/src/lib/actions/payload.ts
  54. 57
      libs/remix-ui/run-tab/src/lib/components/account.tsx
  55. 1
      libs/remix-ui/run-tab/src/lib/constants/index.ts
  56. 1
      libs/remix-ui/run-tab/src/lib/css/run-tab.css
  57. 14
      libs/remix-ui/run-tab/src/lib/reducers/runTab.ts
  58. 4
      libs/remix-ui/run-tab/src/lib/types/blockchain.d.ts
  59. 4
      libs/remix-ui/run-tab/src/lib/types/injected.d.ts
  60. 4
      libs/remix-ui/run-tab/src/lib/types/node.d.ts
  61. 4
      libs/remix-ui/run-tab/src/lib/types/vm.d.ts
  62. 22
      libs/remix-ui/settings/src/lib/remix-ui-settings.tsx
  63. 5
      libs/remix-ui/settings/src/lib/settingsAction.ts
  64. 2
      libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx
  65. 10
      libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx
  66. 7
      libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx
  67. 4
      libs/remix-ui/solidity-compiler/src/lib/types/index.ts
  68. 15
      libs/remix-ui/workspace/src/lib/actions/index.ts
  69. 24
      libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx
  70. 1
      libs/remix-ui/workspace/src/lib/contexts/index.ts
  71. 7
      libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx
  72. 15
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
  73. 17
      libs/remix-ui/workspace/src/lib/utils/constants.ts
  74. 4
      libs/remix-url-resolver/package.json
  75. 4
      libs/remix-ws-templates/package.json
  76. 113
      yarn.lock

@ -79,5 +79,9 @@ module.exports = composePlugins(withNx(), (config) => {
new CssMinimizerPlugin(), new CssMinimizerPlugin(),
]; ];
config.watchOptions = {
ignored: /node_modules/
}
return config; return config;
}); });

@ -78,5 +78,9 @@ module.exports = composePlugins(withNx(), (config) => {
new CssMinimizerPlugin(), new CssMinimizerPlugin(),
]; ];
config.watchOptions = {
ignored: /node_modules/
}
return config; return config;
}); });

@ -31,7 +31,7 @@ function verifyContracts (browser: NightwatchBrowser, compiledContractNames: str
.click('*[data-id="treeViewDivtreeViewItemcompiler"]') .click('*[data-id="treeViewDivtreeViewItemcompiler"]')
.waitForElementVisible('*[data-id="treeViewLiversion"]') .waitForElementVisible('*[data-id="treeViewLiversion"]')
.assert.containsText('*[data-id="treeViewLiversion"]', `${opts.version}`) .assert.containsText('*[data-id="treeViewLiversion"]', `${opts.version}`)
.click('[data-id="workspacesModalDialog-modal-footer-ok-react"]') .click('[data-id="workspacesModalDialog-modal-footer-cancel-react"]')
.perform(() => { .perform(() => {
done() done()
callback() callback()
@ -49,7 +49,7 @@ function verifyContracts (browser: NightwatchBrowser, compiledContractNames: str
.click('*[data-id="treeViewDivtreeViewItemoptimizer"]') .click('*[data-id="treeViewDivtreeViewItemoptimizer"]')
.waitForElementVisible('*[data-id="treeViewDivruns"]') .waitForElementVisible('*[data-id="treeViewDivruns"]')
.assert.containsText('*[data-id="treeViewDivruns"]', `${opts.runs}`) .assert.containsText('*[data-id="treeViewDivruns"]', `${opts.runs}`)
.click('[data-id="workspacesModalDialog-modal-footer-ok-react"]') .click('[data-id="workspacesModalDialog-modal-footer-cancel-react"]')
.perform(() => { .perform(() => {
done() done()
callback() callback()

@ -17,5 +17,9 @@ module.exports = composePlugins(withNx(), (config) => {
config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings
config.watchOptions = {
ignored: /node_modules/
}
return config; return config;
}); });

@ -18,14 +18,6 @@ module.exports = {
init(browser, done, 'http://127.0.0.1:8080', false) 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) { 'Should load the test file': function (browser: NightwatchBrowser) {
browser.openFile('contracts') browser.openFile('contracts')
.openFile('contracts/3_Ballot.sol') .openFile('contracts/3_Ballot.sol')

@ -20,13 +20,6 @@ module.exports = {
init(browser, done, 'http://127.0.0.1:8080', false) 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) { 'Should load the test file': function (browser: NightwatchBrowser) {
browser.openFile('contracts') browser.openFile('contracts')
.openFile('contracts/3_Ballot.sol') .openFile('contracts/3_Ballot.sol')

@ -8,13 +8,7 @@ module.exports = {
before: function (browser: NightwatchBrowser, done: VoidFunction) { before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done, 'http://127.0.0.1:8080', true) 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) { 'Should add error marker': function (browser: NightwatchBrowser) {
browser browser
.openFile('contracts') .openFile('contracts')

@ -8,13 +8,7 @@ module.exports = {
before: function (browser: NightwatchBrowser, done: VoidFunction) { before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done, 'http://127.0.0.1:8080', true) 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) { 'Should add line texts': function (browser: NightwatchBrowser) {
browser browser
.openFile('contracts') .openFile('contracts')

@ -408,14 +408,10 @@ module.exports = {
'Should rename a workspace #group1': function (browser: NightwatchBrowser) { 'Should rename a workspace #group1': function (browser: NightwatchBrowser) {
browser browser
.useXpath() .waitForElementPresent('*[data-id="workspaceDropdownMenuIcon"]')
.waitForElementPresent({ .click('*[data-id="workspaceDropdownMenuIcon"]')
selector: '//i[@data-id="workspaceDropdownMenuIcon"]', .waitForElementVisible('*[data-id="wsdropdownMenu"]')
locateStrategy: 'xpath', .click('*[data-id="workspacerename"]') // rename workspace_name
})
.click('//*[@id="workspacesMenuDropdown"]/span/i')
.waitForElementVisible('//*[@id="workspacesMenuDropdown"]/div/ul')
.click('//*[@id="workspacesMenuDropdown"]/div/ul/a[4]') // rename workspace_name
.useCss() .useCss()
.waitForElementVisible('*[data-id="treeViewLitreeViewItemtests"]') .waitForElementVisible('*[data-id="treeViewLitreeViewItemtests"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextRename"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextRename"]')
@ -437,15 +433,14 @@ module.exports = {
'Should delete a workspace #group1': function (browser: NightwatchBrowser) { 'Should delete a workspace #group1': function (browser: NightwatchBrowser) {
browser browser
.switchWorkspace('workspace_name_1')//*[@id="workspacesMenuDropdown"]/span .switchWorkspace('workspace_name_1')
.useXpath() .click('*[data-id="workspaceDropdownMenuIcon"]')
.click('//*[@id="workspacesMenuDropdown"]/span/i') .waitForElementVisible('*[data-id="wsdropdownMenu"]')
.click('//*[@id="workspacesMenuDropdown"]/div/ul/a[2]') // delete workspace_name_1 .click('*[data-id="workspacedelete"]') // delete workspace_name_1
.waitForElementVisible('//*[@id="fileExplorerView"]/div[2]/div/div/div[2]') .waitForElementVisible('*[data-id="fileSystemModalDialogModalFooter-react"]')
.click('//*[@id="fileExplorerView"]/div[2]/div/div/div[3]/button') .click('*[data-id="fileSystem-modal-footer-ok-react"]')
.waitForElementVisible('//*[@id="workspacesSelect"]') .waitForElementVisible('*[data-id="workspacesSelect"]')
.click('//*[@id="workspacesSelect"]') .click('*[data-id="workspacesSelect"]')
.useCss()
.waitForElementNotPresent(`[data-id="dropdown-item-workspace_name_1"]`) .waitForElementNotPresent(`[data-id="dropdown-item-workspace_name_1"]`)
.end() .end()
}, },

@ -36,7 +36,8 @@ import { HardhatProvider } from './app/providers/hardhat-provider'
import { GanacheProvider } from './app/providers/ganache-provider' import { GanacheProvider } from './app/providers/ganache-provider'
import { FoundryProvider } from './app/providers/foundry-provider' import { FoundryProvider } from './app/providers/foundry-provider'
import { ExternalHttpProvider } from './app/providers/external-http-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 { Injected0ptimismProvider } from './app/providers/injected-optimism-provider'
import { InjectedArbitrumOneProvider } from './app/providers/injected-arbitrum-one-provider' import { InjectedArbitrumOneProvider } from './app/providers/injected-arbitrum-one-provider'
import { FileDecorator } from './app/plugins/file-decorator' import { FileDecorator } from './app/plugins/file-decorator'
@ -216,7 +217,8 @@ class AppComponent {
const ganacheProvider = new GanacheProvider(blockchain) const ganacheProvider = new GanacheProvider(blockchain)
const foundryProvider = new FoundryProvider(blockchain) const foundryProvider = new FoundryProvider(blockchain)
const externalHttpProvider = new ExternalHttpProvider(blockchain) const externalHttpProvider = new ExternalHttpProvider(blockchain)
const basicInjectedProvider = new BasicInjectedProvider() const trustWalletInjectedProvider = new InjectedProviderTrustWallet()
const defaultInjectedProvider = new InjectedProviderDefault
const injected0ptimismProvider = new Injected0ptimismProvider() const injected0ptimismProvider = new Injected0ptimismProvider()
const injectedArbitrumOneProvider = new InjectedArbitrumOneProvider() const injectedArbitrumOneProvider = new InjectedArbitrumOneProvider()
// ----------------- convert offset to line/column service ----------- // ----------------- convert offset to line/column service -----------
@ -289,7 +291,8 @@ class AppComponent {
ganacheProvider, ganacheProvider,
foundryProvider, foundryProvider,
externalHttpProvider, externalHttpProvider,
basicInjectedProvider, defaultInjectedProvider,
trustWalletInjectedProvider,
injected0ptimismProvider, injected0ptimismProvider,
injectedArbitrumOneProvider, injectedArbitrumOneProvider,
this.walkthroughService, this.walkthroughService,

@ -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)
}
}

@ -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 chainName: string
chainId: string chainId: string
rpcUrls: Array<string> rpcUrls: Array<string>

@ -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)
}
}

@ -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'
}
}

@ -2,27 +2,52 @@
import React from 'react' // eslint-disable-line import React from 'react' // eslint-disable-line
import { Plugin } from '@remixproject/engine' import { Plugin } from '@remixproject/engine'
import { JsonDataRequest, RejectRequest, SuccessRequest } from '../providers/abstract-provider' import { JsonDataRequest, RejectRequest, SuccessRequest } from '../providers/abstract-provider'
import Web3 from 'web3'
import { IProvider } from './abstract-provider' 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 abstract class InjectedProvider extends Plugin implements IProvider {
export class InjectedProvider extends Plugin implements IProvider {
provider: any
options: { [id: string] : any } = {} options: { [id: string] : any } = {}
listenerAccountsChanged: (accounts: Array<string>) => void
listenerChainChanged: (chainId: number) => void
constructor (profile) { constructor (profile) {
super(profile) super(profile)
if ((window as any).ethereum) { this.listenerAccountsChanged = (accounts: Array<string>) => {
this.provider = new Web3((window as any).ethereum) 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) { askPermission (throwIfNoInjectedProvider) {
if ((typeof (window as any).ethereum) !== "undefined" && (typeof (window as any).ethereum.request) === "function") { const web3Provider = this.getInjectedProvider()
(window as any).ethereum.request({ method: "eth_requestAccounts" }) if (typeof web3Provider !== "undefined" && typeof web3Provider.request === "function") {
web3Provider.request({ method: "eth_requestAccounts" })
} else if (throwIfNoInjectedProvider) { } 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 () { async init () {
const injectedProvider = (window as any).ethereum const injectedProvider = this.getInjectedProvider()
if (injectedProvider === undefined) { if (injectedProvider === undefined) {
this.call('notification', 'toast', noInjectedProviderMsg) this.call('notification', 'toast', this.notFound())
throw new Error(noInjectedProviderMsg) throw new Error(this.notFound())
} else { } 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) this.askPermission(true)
} }
return {} return {}
@ -55,12 +77,19 @@ export class InjectedProvider extends Plugin implements IProvider {
private async sendAsyncInternal (data: JsonDataRequest, resolve: SuccessRequest, reject: RejectRequest): Promise<void> { private async sendAsyncInternal (data: JsonDataRequest, resolve: SuccessRequest, reject: RejectRequest): Promise<void> {
// Check the case where current environment is VM on UI and it still sends RPC requests // 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 !!' // 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.') 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 }) return resolve({ jsonrpc: '2.0', error: 'no injected provider found', id: data.id })
} }
try { 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) {
if (resultData.jsonrpc && resultData.jsonrpc === '2.0') { if (resultData.jsonrpc && resultData.jsonrpc === '2.0') {
resultData = resultData.result resultData = resultData.result

@ -10,12 +10,14 @@
"filePanel.workspace.rename": "Rename Workspace", "filePanel.workspace.rename": "Rename Workspace",
"filePanel.workspace.delete": "Delete Workspace", "filePanel.workspace.delete": "Delete Workspace",
"filePanel.workspace.deleteConfirm": "Are you sure to delete the current 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.deleteAll": "Delete All Workspaces",
"filePanel.workspace.deleteAllConfirm1": "Are you absolutely sure you want to delete all your 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.deleteAllConfirm2": "Deleted workspaces can not be restored in any manner.",
"filePanel.workspace.name": "Workspace name", "filePanel.workspace.name": "Workspace name",
"filePanel.workspace.chooseTemplate": "Choose a template", "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.restore": "Restore Workspaces from the Backup",
"filePanel.workspace.clone": "Clone Git Repository", "filePanel.workspace.clone": "Clone Git Repository",
"filePanel.workspace.cloneMessage": "Please provide a valid git repository url.", "filePanel.workspace.cloneMessage": "Please provide a valid git repository url.",

@ -132,11 +132,20 @@ export class RunTab extends ViewPlugin {
} }
// basic injected // basic injected
const displayNameInjected = `Injected Provider${(window && window.ethereum && !(window.ethereum.providers && !window.ethereum.selectedProvider)) ? // if it's the trust wallet provider, we have a specific provider for that, see below
window.ethereum.isCoinbaseWallet || window.ethereum.selectedProvider?.isCoinbaseWallet ? ' - Coinbase' : if (window && window.ethereum && !(window.ethereum.isTrustWallet || window.ethereum.selectedProvider?.isTrustWallet)) {
window.ethereum.isBraveWallet || window.ethereum.selectedProvider?.isBraveWallet ? ' - Brave' : const displayNameInjected = `Injected Provider${(window && window.ethereum && !(window.ethereum.providers && !window.ethereum.selectedProvider)) ?
window.ethereum.isMetaMask || window.ethereum.selectedProvider?.isMetaMask ? ' - MetaMask' : '' : ''}` window.ethereum.isCoinbaseWallet || window.ethereum.selectedProvider?.isCoinbaseWallet ? ' - Coinbase' :
await addProvider('injected', displayNameInjected, true, false) 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 // VM
const titleVM = 'Execution environment is local to Remix. Data is only saved to browser memory and will vanish upon reload.' 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) await addProvider('vm-merge', 'Remix VM (Merge)', false, true, 'merge', 'settingsVMMergeMode', titleVM)

@ -23,7 +23,7 @@ const profile = {
name: 'blockchain', name: 'blockchain',
displayName: 'Blockchain', displayName: 'Blockchain',
description: 'Blockchain - Logic', description: 'Blockchain - Logic',
methods: ['getCode', 'getTransactionReceipt', 'addProvider', 'removeProvider', 'getCurrentFork', 'web3VM'], methods: ['getCode', 'getTransactionReceipt', 'addProvider', 'removeProvider', 'getCurrentFork', 'web3VM', 'getProvider'],
version: packageJson.version version: packageJson.version
} }
@ -48,33 +48,62 @@ export class Blockchain extends Plugin {
}, _ => this.executionContext.web3(), _ => this.executionContext.currentblockGasLimit()) }, _ => this.executionContext.web3(), _ => this.executionContext.currentblockGasLimit())
this.txRunner = new TxRunner(web3Runner, { runAsync: true }) this.txRunner = new TxRunner(web3Runner, { runAsync: true })
this.executionContext.event.register('contextChanged', this.resetEnvironment.bind(this))
this.networkcallid = 0 this.networkcallid = 0
this.networkStatus = { name: ' - ', id: ' - ' } this.networkStatus = { network: { name: ' - ', id: ' - ' } }
this.setupEvents() this.setupEvents()
this.setupProviders() 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 () { setupEvents () {
this.executionContext.event.register('contextChanged', (context, silent) => { this.executionContext.event.register('contextChanged', async (context) => {
this.event.trigger('contextChanged', [context, silent]) 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.executionContext.event.register('addProvider', (network) => {
this.event.trigger('addProvider', [network]) this._triggerEvent('addProvider', [network])
}) })
this.executionContext.event.register('removeProvider', (name) => { this.executionContext.event.register('removeProvider', (name) => {
this.event.trigger('removeProvider', [name]) this._triggerEvent('removeProvider', [name])
}) })
setInterval(() => { setInterval(() => {
this.detectNetwork((error, network) => { this.detectNetwork((error, network) => {
this.networkStatus = { network, error } this.networkStatus = { network, error }
this.event.trigger('networkStatus', [this.networkStatus]) this._triggerEvent('networkStatus', [this.networkStatus])
}) })
}, 1000) }, 30000)
} }
getCurrentNetworkStatus () { getCurrentNetworkStatus () {
@ -479,13 +508,11 @@ export class Blockchain extends Plugin {
} }
// NOTE: the config is only needed because exectuionContext.init does // NOTE: the config is only needed because exectuionContext.init does
// if config.get('settings/always-use-vm'), we can simplify this later async resetAndInit (config, transactionContextAPI) {
resetAndInit (config, transactionContextAPI) {
this.transactionContextAPI = transactionContextAPI this.transactionContextAPI = transactionContextAPI
this.executionContext.init(config) this.executionContext.init(config)
this.executionContext.stopListenOnLastBlock() this.executionContext.stopListenOnLastBlock()
this.executionContext.listenOnLastBlock() this.executionContext.listenOnLastBlock()
this.resetEnvironment()
} }
addProvider (provider) { addProvider (provider) {
@ -504,8 +531,8 @@ export class Blockchain extends Plugin {
}) })
} }
resetEnvironment () { async resetEnvironment () {
this.getCurrentProvider().resetEnvironment() await this.getCurrentProvider().resetEnvironment()
// TODO: most params here can be refactored away in txRunner // TODO: most params here can be refactored away in txRunner
const web3Runner = new TxRunnerWeb3({ const web3Runner = new TxRunnerWeb3({
config: this.config, config: this.config,
@ -551,8 +578,8 @@ export class Blockchain extends Plugin {
} }
/** Get the balance of an address, and convert wei to ether */ /** Get the balance of an address, and convert wei to ether */
getBalanceInEther (address, cb) { getBalanceInEther (address) {
this.getCurrentProvider().getBalanceInEther(address, cb) return this.getCurrentProvider().getBalanceInEther(address)
} }
pendingTransactionsCount () { pendingTransactionsCount () {
@ -674,7 +701,7 @@ export class Blockchain extends Plugin {
if (!tx.timestamp) tx.timestamp = Date.now() if (!tx.timestamp) tx.timestamp = Date.now()
const timestamp = tx.timestamp const timestamp = tx.timestamp
this.event.trigger('initiatingTransaction', [timestamp, tx, payLoad]) this._triggerEvent('initiatingTransaction', [timestamp, tx, payLoad])
try { try {
this.txRunner.rawRun(tx, confirmationCb, continueCb, promptCb, this.txRunner.rawRun(tx, confirmationCb, continueCb, promptCb,
async (error, result) => { async (error, result) => {
@ -698,7 +725,7 @@ export class Blockchain extends Plugin {
} }
const eventName = (tx.useCall ? 'callExecuted' : 'transactionExecuted') 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 }) return resolve({ result, tx })
} }
) )

@ -34,9 +34,8 @@ export class ExecutionContext {
} }
init (config) { init (config) {
if (config.get('settings/always-use-vm')) { this.executionContext = 'vm-merge'
this.executionContext = 'vm-merge' this.event.trigger('contextChanged', [this.executionContext])
}
} }
getProvider () { getProvider () {

@ -16,17 +16,13 @@ class InjectedProvider {
}) })
} }
resetEnvironment () { async resetEnvironment () {
/* Do nothing. */ /* Do nothing. */
} }
getBalanceInEther (address, cb) { async getBalanceInEther (address) {
this.executionContext.web3().eth.getBalance(address, (err, res) => { const balance = await this.executionContext.web3().eth.getBalance(address)
if (err) { return Web3.utils.fromWei(balance.toString(10), 'ether')
return cb(err)
}
cb(null, Web3.utils.fromWei(res.toString(10), 'ether'))
})
} }
getGasPrice (cb) { getGasPrice (cb) {

@ -24,17 +24,13 @@ class NodeProvider {
}) })
} }
resetEnvironment () { async resetEnvironment () {
/* Do nothing. */ /* Do nothing. */
} }
getBalanceInEther (address, cb) { async getBalanceInEther (address) {
this.executionContext.web3().eth.getBalance(address, (err, res) => { const balance = await this.executionContext.web3().eth.getBalance(address)
if (err) { return Web3.utils.fromWei(balance.toString(10), 'ether')
return cb(err)
}
cb(null, Web3.utils.fromWei(res.toString(10), 'ether'))
})
} }
getGasPrice (cb) { getGasPrice (cb) {

@ -19,7 +19,7 @@ class VMProvider {
}) })
} }
resetEnvironment () { async resetEnvironment () {
if (this.worker) this.worker.terminate() if (this.worker) this.worker.terminate()
this.accounts = {} this.accounts = {}
this.worker = new Worker(new URL('./worker-vm', import.meta.url)) this.worker = new Worker(new URL('./worker-vm', import.meta.url))
@ -27,23 +27,29 @@ class VMProvider {
let incr = 0 let incr = 0
const stamps = {} const stamps = {}
this.worker.addEventListener('message', (msg) => {
if (msg.data.cmd === 'sendAsyncResult' && stamps[msg.data.stamp]) { return new Promise((resolve, reject) => {
stamps[msg.data.stamp](msg.data.error, msg.data.result) this.worker.addEventListener('message', (msg) => {
} else if (msg.data.cmd === 'initiateResult') { if (msg.data.cmd === 'sendAsyncResult' && stamps[msg.data.stamp]) {
if (!msg.data.error) { stamps[msg.data.stamp](msg.data.error, msg.data.result)
this.provider = { } else if (msg.data.cmd === 'initiateResult') {
sendAsync: (query, callback) => { if (!msg.data.error) {
const stamp = Date.now() + incr this.provider = {
incr++ sendAsync: (query, callback) => {
stamps[stamp] = callback const stamp = Date.now() + incr
this.worker.postMessage({ cmd: 'sendAsync', query, stamp }) 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') { } else if (msg.data.cmd === 'newAccountResult') {
if (this.newAccountCallback[msg.data.stamp]) { 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']}) 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 }) this.worker.postMessage({ cmd: 'newAccount', stamp })
} }
getBalanceInEther (address, cb) { async getBalanceInEther (address) {
this.web3.eth.getBalance(address, (err, res) => { const balance = await this.web3.eth.getBalance(address)
if (err) { return Web3.utils.fromWei(new BN(balance).toString(10), 'ether')
return cb(err)
}
cb(null, Web3.utils.fromWei(new BN(res).toString(10), 'ether'))
})
} }
getGasPrice (cb) { getGasPrice (cb) {

@ -10,7 +10,7 @@ const requiredModules = [ // services + layout views + system views
'fileManager', 'contentImport', 'blockchain', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons', 'fileManager', 'contentImport', 'blockchain', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons',
'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity', 'solidity-logic', 'gistHandler', 'layout', 'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity', 'solidity-logic', 'gistHandler', 'layout',
'notification', 'permissionhandler', 'walkthrough', 'storage', 'restorebackupzip', 'link-libraries', 'deploy-libraries', 'openzeppelin-proxy', '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'] 'compileAndRun', 'search', 'recorder', 'fileDecorator', 'codeParser', 'codeFormatter', 'solidityumlgen', 'contractflattener']
// dependentModules shouldn't be manually activated (e.g hardhat is activated by remixd) // dependentModules shouldn't be manually activated (e.g hardhat is activated by remixd)

@ -77,7 +77,7 @@ module.exports = composePlugins(withNx(), withReact(), (config) => {
enforce: "pre" 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 // set minimizer
config.optimization.minimizer = [ config.optimization.minimizer = [
@ -96,5 +96,9 @@ module.exports = composePlugins(withNx(), withReact(), (config) => {
new CssMinimizerPlugin(), new CssMinimizerPlugin(),
]; ];
config.watchOptions = {
ignored: /node_modules/
}
return config; return config;
}); });

@ -89,5 +89,9 @@ module.exports = composePlugins(withNx(), withReact(), (config) => {
new CssMinimizerPlugin(), new CssMinimizerPlugin(),
]; ];
config.watchOptions = {
ignored: /node_modules/
}
return config; return config;
}); });

@ -79,5 +79,9 @@ module.exports = composePlugins(withNx(), (config) => {
new CssMinimizerPlugin(), new CssMinimizerPlugin(),
]; ];
config.watchOptions = {
ignored: /node_modules/
}
return config; return config;
}); });

@ -1,6 +1,6 @@
{ {
"name": "@remix-project/ghaction-helper", "name": "@remix-project/ghaction-helper",
"version": "0.1.7-alpha.10", "version": "0.1.7-alpha.17",
"description": "Solidity Tests GitHub Action Helper", "description": "Solidity Tests GitHub Action Helper",
"main": "src/index.js", "main": "src/index.js",
"scripts": { "scripts": {
@ -19,17 +19,17 @@
}, },
"homepage": "https://github.com/ethereum/remix-project#readme", "homepage": "https://github.com/ethereum/remix-project#readme",
"devDependencies": { "devDependencies": {
"@remix-project/remix-solidity": "^0.5.11-alpha.10", "@remix-project/remix-solidity": "^0.5.11-alpha.17",
"@types/chai": "^4.3.4", "@types/chai": "^4.3.4",
"typescript": "^4.9.3" "typescript": "^4.9.3"
}, },
"dependencies": { "dependencies": {
"@ethereum-waffle/chai": "^3.4.4", "@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", "chai": "^4.3.7",
"ethers": "^5.7.2", "ethers": "^5.7.2",
"web3": "^1.5.3" "web3": "^1.5.3"
}, },
"types": "./src/index.d.ts", "types": "./src/index.d.ts",
"gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c" "gitHead": "4806543bb099b558872793ca7a215468e0bffc81"
} }

@ -5,20 +5,18 @@ import { getArtifactsByContractName } from './artifacts-helper'
import { SignerWithAddress } from './signer' import { SignerWithAddress } from './signer'
import Web3 from "web3" import Web3 from "web3"
(async () => { const providerConfig = {
const providerConfig = { fork: global.fork || null,
fork: global.fork || null, nodeUrl: global.nodeUrl || null,
nodeUrl: global.nodeUrl || null, blockNumber: global.blockNumber || null
blockNumber: global.blockNumber || null }
}
global.remixProvider = new Provider(providerConfig) global.remixProvider = new Provider(providerConfig)
await global.remixProvider.init() global.remixProvider.init()
global.web3Provider = new ethers.providers.Web3Provider(global.remixProvider) global.web3Provider = new ethers.providers.Web3Provider(global.remixProvider)
global.provider = global.web3Provider global.provider = global.web3Provider
global.ethereum = global.web3Provider global.ethereum = global.web3Provider
global.web3 = new Web3(global.web3Provider) global.web3 = new Web3(global.web3Provider)
})()
const isFactoryOptions = (signerOrOptions: any) => { const isFactoryOptions = (signerOrOptions: any) => {
if (!signerOrOptions || signerOrOptions === undefined || signerOrOptions instanceof ethers.Signer) return false if (!signerOrOptions || signerOrOptions === undefined || signerOrOptions instanceof ethers.Signer) return false

@ -1,6 +1,6 @@
{ {
"name": "@remix-project/remix-analyzer", "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", "description": "Tool to perform static analysis on Solidity smart contracts",
"scripts": { "scripts": {
"test": "./../../node_modules/.bin/ts-node --project ../../tsconfig.base.json --require tsconfig-paths/register ./../../node_modules/.bin/tape ./test/tests.ts" "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/tx": "^4.0.2",
"@ethereumjs/util": "^8.0.3", "@ethereumjs/util": "^8.0.3",
"@ethereumjs/vm": "^6.3.0", "@ethereumjs/vm": "^6.3.0",
"@remix-project/remix-astwalker": "^0.0.55-alpha.10", "@remix-project/remix-astwalker": "^0.0.55-alpha.17",
"@remix-project/remix-lib": "^0.5.25-alpha.10", "@remix-project/remix-lib": "^0.5.25-alpha.17",
"async": "^2.6.2", "async": "^2.6.2",
"ethers": "^5.4.2", "ethers": "^5.4.2",
"ethjs-util": "^0.1.6", "ethjs-util": "^0.1.6",
@ -50,6 +50,6 @@
"typescript": "^3.7.5" "typescript": "^3.7.5"
}, },
"typings": "src/index.d.ts", "typings": "src/index.d.ts",
"gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c", "gitHead": "4806543bb099b558872793ca7a215468e0bffc81",
"main": "./src/index.js" "main": "./src/index.js"
} }

@ -1,6 +1,6 @@
{ {
"name": "@remix-project/remix-astwalker", "name": "@remix-project/remix-astwalker",
"version": "0.0.55-alpha.10", "version": "0.0.55-alpha.17",
"description": "Tool to walk through Solidity AST", "description": "Tool to walk through Solidity AST",
"main": "src/index.js", "main": "src/index.js",
"scripts": { "scripts": {
@ -37,7 +37,7 @@
"@ethereumjs/tx": "^4.0.2", "@ethereumjs/tx": "^4.0.2",
"@ethereumjs/util": "^8.0.3", "@ethereumjs/util": "^8.0.3",
"@ethereumjs/vm": "^6.3.0", "@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", "@types/tape": "^4.2.33",
"async": "^2.6.2", "async": "^2.6.2",
"ethers": "^5.4.2", "ethers": "^5.4.2",
@ -53,6 +53,6 @@
"tap-spec": "^5.0.0" "tap-spec": "^5.0.0"
}, },
"typings": "src/index.d.ts", "typings": "src/index.d.ts",
"gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c", "gitHead": "4806543bb099b558872793ca7a215468e0bffc81",
"types": "./src/index.d.ts" "types": "./src/index.d.ts"
} }

@ -134,7 +134,18 @@ export class FetchAndCompile extends Plugin {
if (!data) { if (!data) {
setTimeout(_ => this.emit('notFound', contractAddress), 0) setTimeout(_ => this.emit('notFound', contractAddress), 0)
this.unresolvedAddresses.push(contractAddress) 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 const { settings, compilationTargets } = data

@ -1,6 +1,6 @@
{ {
"name": "@remix-project/remix-debug", "name": "@remix-project/remix-debug",
"version": "0.5.25-alpha.10", "version": "0.5.25-alpha.17",
"description": "Tool to debug Ethereum transactions", "description": "Tool to debug Ethereum transactions",
"contributors": [ "contributors": [
{ {
@ -26,10 +26,10 @@
"@ethereumjs/tx": "^4.0.2", "@ethereumjs/tx": "^4.0.2",
"@ethereumjs/util": "^8.0.3", "@ethereumjs/util": "^8.0.3",
"@ethereumjs/vm": "^6.3.0", "@ethereumjs/vm": "^6.3.0",
"@remix-project/remix-astwalker": "^0.0.55-alpha.10", "@remix-project/remix-astwalker": "^0.0.55-alpha.17",
"@remix-project/remix-lib": "^0.5.25-alpha.10", "@remix-project/remix-lib": "^0.5.25-alpha.17",
"@remix-project/remix-simulator": "^0.2.25-alpha.10", "@remix-project/remix-simulator": "^0.2.25-alpha.17",
"@remix-project/remix-solidity": "^0.5.11-alpha.10", "@remix-project/remix-solidity": "^0.5.11-alpha.17",
"ansi-gray": "^0.1.1", "ansi-gray": "^0.1.1",
"async": "^2.6.2", "async": "^2.6.2",
"color-support": "^1.1.3", "color-support": "^1.1.3",
@ -69,6 +69,6 @@
}, },
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-debug#readme", "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-debug#readme",
"typings": "src/index.d.ts", "typings": "src/index.d.ts",
"gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c", "gitHead": "4806543bb099b558872793ca7a215468e0bffc81",
"types": "./src/index.d.ts" "types": "./src/index.d.ts"
} }

@ -1,6 +1,6 @@
{ {
"name": "@remix-project/remix-lib", "name": "@remix-project/remix-lib",
"version": "0.5.25-alpha.10", "version": "0.5.25-alpha.17",
"description": "Library to various Remix tools", "description": "Library to various Remix tools",
"contributors": [ "contributors": [
{ {
@ -51,6 +51,6 @@
}, },
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-lib#readme", "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-lib#readme",
"typings": "src/index.d.ts", "typings": "src/index.d.ts",
"gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c", "gitHead": "4806543bb099b558872793ca7a215468e0bffc81",
"types": "./src/index.d.ts" "types": "./src/index.d.ts"
} }

@ -1,6 +1,6 @@
{ {
"name": "@remix-project/remix-simulator", "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", "description": "Ethereum IDE and tools for the web",
"contributors": [ "contributors": [
{ {
@ -22,7 +22,7 @@
"@ethereumjs/tx": "^4.0.2", "@ethereumjs/tx": "^4.0.2",
"@ethereumjs/util": "^8.0.3", "@ethereumjs/util": "^8.0.3",
"@ethereumjs/vm": "^6.3.0", "@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", "ansi-gray": "^0.1.1",
"async": "^3.1.0", "async": "^3.1.0",
"body-parser": "^1.18.2", "body-parser": "^1.18.2",
@ -67,6 +67,6 @@
}, },
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-simulator#readme", "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-simulator#readme",
"typings": "src/index.d.ts", "typings": "src/index.d.ts",
"gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c", "gitHead": "4806543bb099b558872793ca7a215468e0bffc81",
"types": "./src/index.d.ts" "types": "./src/index.d.ts"
} }

@ -18,7 +18,9 @@ export class Provider {
Accounts Accounts
Transactions Transactions
methods methods
connected: boolean; connected: boolean
initialized: boolean
pendingRequests: Array<any>
constructor (options: Record<string, string | number> = {}) { constructor (options: Record<string, string | number> = {}) {
this.options = options this.options = options
@ -39,15 +41,27 @@ export class Provider {
} }
async init () { async init () {
this.initialized = false
this.pendingRequests = []
await this.vmContext.init() await this.vmContext.init()
await generateBlock(this.vmContext) await generateBlock(this.vmContext)
await this.Accounts.resetAccounts() await this.Accounts.resetAccounts()
this.Transactions.init(this.Accounts.accounts) 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) { sendAsync (payload, callback) {
// log.info('payload method is ', payload.method) // commented because, this floods the IDE console // 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] const method = this.methods[payload.method]
if (this.options.logDetails) { if (this.options.logDetails) {
info(payload) info(payload)

@ -1,6 +1,6 @@
{ {
"name": "@remix-project/remix-solidity", "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", "description": "Tool to load and run Solidity compiler",
"main": "src/index.js", "main": "src/index.js",
"types": "src/index.d.ts", "types": "src/index.d.ts",
@ -19,7 +19,7 @@
"@ethereumjs/tx": "^4.0.2", "@ethereumjs/tx": "^4.0.2",
"@ethereumjs/util": "^8.0.3", "@ethereumjs/util": "^8.0.3",
"@ethereumjs/vm": "^6.3.0", "@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", "async": "^2.6.2",
"eslint-scope": "^5.0.0", "eslint-scope": "^5.0.0",
"ethers": "^5.4.2", "ethers": "^5.4.2",
@ -57,5 +57,5 @@
}, },
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-solidity#readme", "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-solidity#readme",
"typings": "src/index.d.ts", "typings": "src/index.d.ts",
"gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c" "gitHead": "4806543bb099b558872793ca7a215468e0bffc81"
} }

@ -1,6 +1,6 @@
{ {
"name": "@remix-project/remix-tests", "name": "@remix-project/remix-tests",
"version": "0.2.25-alpha.10", "version": "0.2.25-alpha.17",
"description": "Tool to test Solidity smart contracts", "description": "Tool to test Solidity smart contracts",
"main": "src/index.js", "main": "src/index.js",
"types": "./src/index.d.ts", "types": "./src/index.d.ts",
@ -41,9 +41,9 @@
"@ethereumjs/tx": "^4.0.2", "@ethereumjs/tx": "^4.0.2",
"@ethereumjs/util": "^8.0.3", "@ethereumjs/util": "^8.0.3",
"@ethereumjs/vm": "^6.3.0", "@ethereumjs/vm": "^6.3.0",
"@remix-project/remix-lib": "^0.5.25-alpha.10", "@remix-project/remix-lib": "^0.5.25-alpha.17",
"@remix-project/remix-simulator": "^0.2.25-alpha.10", "@remix-project/remix-simulator": "^0.2.25-alpha.17",
"@remix-project/remix-solidity": "^0.5.11-alpha.10", "@remix-project/remix-solidity": "^0.5.11-alpha.17",
"@remix-project/remix-url-resolver": "^0.0.42", "@remix-project/remix-url-resolver": "^0.0.42",
"ansi-gray": "^0.1.1", "ansi-gray": "^0.1.1",
"async": "^2.6.0", "async": "^2.6.0",
@ -78,5 +78,5 @@
"typescript": "^3.3.1" "typescript": "^3.3.1"
}, },
"typings": "src/index.d.ts", "typings": "src/index.d.ts",
"gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c" "gitHead": "4806543bb099b558872793ca7a215468e0bffc81"
} }

@ -55,6 +55,7 @@ commander
.option('-f, --fork <string>', '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('-f, --fork <string>', '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 <string>', 'set node url (e.g: https://mainnet.infura.io/v3/your-api-key)') .option('-n, --nodeUrl <string>', 'set node url (e.g: https://mainnet.infura.io/v3/your-api-key)')
.option('-b, --blockNumber <string>', 'set block number (e.g: 123456)') .option('-b, --blockNumber <string>', 'set block number (e.g: 123456)')
.option('-k, --killProcess <bool>', 'kill process when tests fail')
.argument('file_path', 'path to test file or directory') .argument('file_path', 'path to test file or directory')
.action(async (file_path) => { .action(async (file_path) => {
const options = commander.opts(); const options = commander.opts();
@ -131,8 +132,9 @@ commander
await provider.init() await provider.init()
web3.setProvider(provider) web3.setProvider(provider)
extend(web3) 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 (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') log.error('Please specify a file or directory path')
process.exit(1) process.exit(1)
} }
commander.parse(process.argv) commander.parse(process.argv)

@ -173,8 +173,7 @@ export function runTestFiles (filepath: string, isDirectory: boolean, web3: Web3
} }
console.log(colors.white('Time Taken: ' + totalTime + 's')) console.log(colors.white('Time Taken: ' + totalTime + 's'))
console.log('') console.log('')
next(null, totalPassing, totalFailing)
next()
}) })
} }
], finalCallback) ], finalCallback)

@ -49,6 +49,7 @@ Options:
-n, --nodeUrl <string> set node url (e.g: -n, --nodeUrl <string> set node url (e.g:
https://mainnet.infura.io/v3/your-api-key) https://mainnet.infura.io/v3/your-api-key)
-b, --blockNumber <string> set block number (e.g: 123456) -b, --blockNumber <string> set block number (e.g: 123456)
-k, --killProcess <bool> kill process when tests fail
-h, --help display help for command -h, --help display help for command
Commands: Commands:

@ -119,7 +119,7 @@ export class RemixCompletionProvider implements monacoTypes.languages.Completion
// truncate for performance // truncate for performance
if (filteredNodes.length > this.maximumItemsForContractCompletion) { 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) filteredNodes = filteredNodes.slice(0, this.maximumItemsForContractCompletion)
} }

@ -12,8 +12,6 @@ import { monacoTypes } from '@remix-ui/editor';
import './remix-ui-editor.css' import './remix-ui-editor.css'
import { loadTypes } from './web-types' import { loadTypes } from './web-types'
import { RemixHoverProvider } from './providers/hoverProvider' import { RemixHoverProvider } from './providers/hoverProvider'
import { RemixReferenceProvider } from './providers/referenceProvider' import { RemixReferenceProvider } from './providers/referenceProvider'
import { RemixCompletionProvider } from './providers/completionProvider' import { RemixCompletionProvider } from './providers/completionProvider'
@ -262,6 +260,7 @@ export const EditorUI = (props: EditorUIProps) => {
{ token: 'keyword.continue', foreground: warningColor }, { token: 'keyword.continue', foreground: warningColor },
{ token: 'keyword.while', foreground: warningColor }, { token: 'keyword.while', foreground: warningColor },
{ token: 'keyword.do', foreground: warningColor }, { token: 'keyword.do', foreground: warningColor },
{ token: 'keyword.delete', foreground: warningColor },
{ token: 'keyword.if', foreground: yellowColor }, { token: 'keyword.if', foreground: yellowColor },
{ token: 'keyword.else', foreground: yellowColor }, { token: 'keyword.else', foreground: yellowColor },

@ -1266,6 +1266,7 @@ export const solidityTokensProvider = {
'constant', 'constant',
'fallback', 'fallback',
'receive', 'receive',
'delete',
'if', 'if',
'else', 'else',
'for', 'for',

@ -37,7 +37,7 @@ export const CustomIconsToggle = React.forwardRef(({ onClick, icon, className =
// forwardRef again here! // forwardRef again here!
// Dropdown needs access to the DOM of the Menu to measure it // Dropdown needs access to the DOM of the Menu to measure it
export const CustomMenu = React.forwardRef( export const CustomMenu = React.forwardRef(
({ children, style, className, 'aria-labelledby': labeledBy }: { children: React.ReactNode, style?: React.CSSProperties, className: string, 'aria-labelledby'?: string }, ref: Ref<HTMLDivElement>) => { ({ 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<HTMLDivElement>) => {
const height = window.innerHeight * 0.6 const height = window.innerHeight * 0.6
return ( return (
<div <div
@ -45,6 +45,7 @@ export const CustomMenu = React.forwardRef(
style={style} style={style}
className={className} className={className}
aria-labelledby={labeledBy} aria-labelledby={labeledBy}
data-id={dataId}
> >
<ul className="overflow-auto list-unstyled mb-0" style={{ maxHeight: height+'px' }}> <ul className="overflow-auto list-unstyled mb-0" style={{ maxHeight: height+'px' }}>
{ {

@ -103,7 +103,8 @@ export const ModalDialog = (props: ModalDialogProps) => {
onClick={() => { onClick={() => {
if (props.validation && !props.validation.valid) return if (props.validation && !props.validation.valid) return
if (props.okFn) props.okFn() if (props.okFn) props.okFn()
handleHide() if (props.donotHideOnOkClick) calledHideFunctionOnce.current = false
else handleHide()
}} }}
> >
{props.okLabel ? props.okLabel : 'OK'} {props.okLabel ? props.okLabel : 'OK'}

@ -13,6 +13,7 @@ export interface ModalDialogProps {
message?: string | JSX.Element, message?: string | JSX.Element,
okLabel?: string | JSX.Element, okLabel?: string | JSX.Element,
okFn?: (value?:any) => void, okFn?: (value?:any) => void,
donotHideOnOkClick?: boolean,
cancelLabel?: string | JSX.Element, cancelLabel?: string | JSX.Element,
cancelFn?: () => void, cancelFn?: () => void,
modalClass?: string, modalClass?: string,

@ -1,48 +1,46 @@
.remixui_sol.success, .remixui_sol.success,
.remixui_sol.error, .remixui_sol.error,
.remixui_sol.warning { .remixui_sol.warning {
white-space: pre-line; white-space: pre-line;
word-wrap: break-word; word-wrap: break-word;
cursor: pointer; cursor: pointer;
position: relative; position: relative;
margin: 0.5em 0 1em 0; margin: 0.5em 0 1em 0;
border-radius: 5px; border-radius: 5px;
line-height: 20px; line-height: 20px;
padding: 8px 15px; padding: 8px 15px;
} }
.remixui_sol.success pre, .remixui_sol.success pre,
.remixui_sol.error pre, .remixui_sol.error pre,
.remixui_sol.warning pre { .remixui_sol.warning pre {
white-space: pre-line; white-space: pre-line;
overflow-y: hidden; overflow-y: hidden;
background-color: transparent; background-color: transparent;
margin: 0; margin: 0;
font-size: 12px; font-size: 12px;
border: 0 none; border: 0 none;
padding: 0; padding: 0;
border-radius: 0; border-radius: 0;
} }
.remixui_sol.success .close, .remixui_sol.success .close,
.remixui_sol.error .close, .remixui_sol.error .close,
.remixui_sol.warning .close { .remixui_sol.warning .close {
visibility: hidden; visibility: hidden;
white-space: pre-line; white-space: pre-line;
font-weight: bold; font-weight: bold;
position: absolute; position: absolute;
color: hsl(0, 0%, 0%); /* black in style-guide.js */ color: hsl(0, 0%, 0%); /* black in style-guide.js */
top: 0; top: 0;
right: 0; right: 0;
padding: 0.5em; padding: 0.5em;
} }
.remixui_sol.error { .remixui_sol.success a,
} .remixui_sol.error a,
.remixui_sol.warning a {
.remixui_sol.warning { position: absolute;
} bottom: 0;
right: 0;
.remixui_sol.success {
/* background-color: // styles.rightPanel.message_Success_BackgroundColor; */
} }

@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react' //eslint-disable-line import React, { useEffect, useState } from 'react' //eslint-disable-line
import { CopyToClipboard } from '@remix-ui/clipboard'
import { helper } from '@remix-project/remix-solidity' import { helper } from '@remix-project/remix-solidity'
import './renderer.css' import './renderer.css'
interface RendererProps { interface RendererProps {
@ -77,7 +78,9 @@ export const Renderer = ({ message, opt = {}, plugin }: RendererProps) => {
<div className="close" data-id="renderer" onClick={handleClose}> <div className="close" data-id="renderer" onClick={handleClose}>
<i className="fas fa-times"></i> <i className="fas fa-times"></i>
</div> </div>
</div>) <CopyToClipboard content={messageText} className={` p-0 m-0 far fa-copy ${classList}`} direction={"top"} />
</div>
)
} }
</> </>
) )

@ -3,17 +3,14 @@ import { RunTab } from "../types/run-tab"
import { clearInstances, setAccount, setExecEnv } from "./actions" import { clearInstances, setAccount, setExecEnv } from "./actions"
import { displayNotification, displayPopUp, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, setExternalEndpoint, setMatchPassphrase, setPassphrase } from "./payload" import { displayNotification, displayPopUp, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, setExternalEndpoint, setMatchPassphrase, setPassphrase } from "./payload"
export const updateAccountBalances = (plugin: RunTab, dispatch: React.Dispatch<any>) => { export const updateAccountBalances = async (plugin: RunTab, dispatch: React.Dispatch<any>) => {
const accounts = plugin.REACT_API.accounts.loadedAccounts const accounts = plugin.REACT_API.accounts.loadedAccounts
Object.keys(accounts).map((value) => { for (const account of Object.keys(accounts)) {
plugin.blockchain.getBalanceInEther(value, (err, balance) => { const balance = await plugin.blockchain.getBalanceInEther(account)
if (err) return const updated = shortenAddress(account, balance)
const updated = shortenAddress(value, balance) accounts[account] = updated
}
accounts[value] = updated
})
})
dispatch(fetchAccountsListSuccess(accounts)) dispatch(fetchAccountsListSuccess(accounts))
} }
@ -31,17 +28,10 @@ export const fillAccountsList = async (plugin: RunTab, dispatch: React.Dispatch<
// - all the promises resolve // - all the promises resolve
// - at least one reject // - at least one reject
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
await (Promise as any).all(accounts.map((account) => { for (const account of accounts) {
return new Promise((resolve, reject) => { const balance = await plugin.blockchain.getBalanceInEther(account)
plugin.blockchain.getBalanceInEther(account, (err, balance) => { loadedAccounts[account] = shortenAddress(account, balance)
if (err) return reject(err) }
const updated = shortenAddress(account, balance)
loadedAccounts[account] = updated
resolve(account)
})
})
}))
const provider = plugin.blockchain.getProvider() const provider = plugin.blockchain.getProvider()
if (provider === 'injected') { if (provider === 'injected') {
@ -59,6 +49,7 @@ export const fillAccountsList = async (plugin: RunTab, dispatch: React.Dispatch<
} }
export const setFinalContext = (plugin: RunTab, dispatch: React.Dispatch<any>) => { export const setFinalContext = (plugin: RunTab, dispatch: React.Dispatch<any>) => {
dispatch(fetchAccountsListRequest())
// set the final context. Cause it is possible that this is not the one we've originaly selected // set the final context. Cause it is possible that this is not the one we've originaly selected
const value = _getProviderDropdownValue(plugin) const value = _getProviderDropdownValue(plugin)

@ -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 // 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 { UpgradeableContract } from '../../../../../../node_modules/@openzeppelin/upgrades-core/dist/standalone'
import { DeployMode, MainnetPrompt } from "../types" 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 { addInstance } from "./actions"
import { addressToString, logBuilder } from "@remix-ui/helper" import { addressToString, logBuilder } from "@remix-ui/helper"
import Web3 from "web3" import Web3 from "web3"
@ -318,14 +318,15 @@ export const getFuncABIInputs = (plugin: RunTab, funcABI: FuncABI) => {
return plugin.blockchain.getInputs(funcABI) return plugin.blockchain.getInputs(funcABI)
} }
export const updateInstanceBalance = (plugin: RunTab) => { export const updateInstanceBalance = async (plugin: RunTab, dispatch: React.Dispatch<any>) => {
if (plugin.REACT_API?.instances?.instanceList?.length) { if (plugin.REACT_API?.instances?.instanceList?.length) {
for (const instance of plugin.REACT_API.instances.instanceList) { const instances = plugin.REACT_API?.instances?.instanceList
plugin.blockchain.getBalanceInEther(instance.address, (err, balInEth) => { for (const instance of instances) {
if (!err) instance.balance = balInEth const balInEth = await plugin.blockchain.getBalanceInEther(instance.address)
}) instance.balance = balInEth
} }
} dispatch(updateInstanceBalance(instances, dispatch))
}
} }
export const isValidContractAddress = async (plugin: RunTab, address: string) => { export const isValidContractAddress = async (plugin: RunTab, address: string) => {

@ -1,13 +1,15 @@
import { envChangeNotification } from "@remix-ui/helper" import { envChangeNotification } from "@remix-ui/helper"
import { RunTab } from "../types/run-tab" 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 { 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 { CompilerAbstract } from '@remix-project/remix-solidity'
import BN from 'bn.js' import BN from 'bn.js'
import Web3 from 'web3' import Web3 from 'web3'
import { Plugin } from "@remixproject/engine" import { Plugin } from "@remixproject/engine"
import { getNetworkProxyAddresses } from "./deploy" import { getNetworkProxyAddresses } from "./deploy"
import { shortenAddress } from "@remix-ui/helper"
const _paq = window._paq = window._paq || [] const _paq = window._paq = window._paq || []
@ -20,12 +22,15 @@ export const setupEvents = (plugin: RunTab, dispatch: React.Dispatch<any>) => {
if (!lookupOnly) dispatch(setSendValue('0')) if (!lookupOnly) dispatch(setSendValue('0'))
if (error) return if (error) return
updateAccountBalances(plugin, dispatch) updateAccountBalances(plugin, dispatch)
updateInstanceBalance(plugin, dispatch)
}) })
plugin.blockchain.event.register('contextChanged', (context, silent) => { plugin.blockchain.event.register('contextChanged', (context) => {
dispatch(resetProxyDeployments()) dispatch(resetProxyDeployments())
if (!context.startsWith('vm')) getNetworkProxyAddresses(plugin, dispatch) if (!context.startsWith('vm')) getNetworkProxyAddresses(plugin, dispatch)
setFinalContext(plugin, dispatch) setFinalContext(plugin, dispatch)
fillAccountsList(plugin, dispatch)
updateAccountBalances(plugin, dispatch)
}) })
plugin.blockchain.event.register('networkStatus', ({ error, network }) => { plugin.blockchain.event.register('networkStatus', ({ error, network }) => {
@ -117,6 +122,23 @@ export const setupEvents = (plugin: RunTab, dispatch: React.Dispatch<any>) => {
plugin.event.register('cleared', () => { plugin.event.register('cleared', () => {
dispatch(clearRecorderCount()) dispatch(clearRecorderCount())
}) })
plugin.on('injected', 'accountsChanged', (accounts: Array<string>) => {
const accountsMap = {}
accounts.map(account => { accountsMap[account] = shortenAddress(account, '0')})
dispatch(fetchAccountsListSuccess(accountsMap))
})
plugin.on('injected-trustwallet', 'accountsChanged', (accounts: Array<string>) => {
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<any>, file, source, languageVersion, data, input?) => { const broadcastCompilationResult = async (compilerName: string, plugin: RunTab, dispatch: React.Dispatch<any>, file, source, languageVersion, data, input?) => {

@ -2,7 +2,7 @@
import React from 'react' import React from 'react'
import { RunTab } from '../types/run-tab' import { RunTab } from '../types/run-tab'
import { resetAndInit, setupEvents } from './events' 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, import { clearInstances, clearPopUp, removeInstance, setAccount, setGasFee, setMatchPassphrasePrompt,
setNetworkNameFromProvider, setPassphrasePrompt, setSelectedContract, setSendTransactionValue, setUnit, setNetworkNameFromProvider, setPassphrasePrompt, setSelectedContract, setSendTransactionValue, setUnit,
updateBaseFeePerGas, updateConfirmSettings, updateGasPrice, updateGasPriceStatus, updateMaxFee, updateMaxPriorityFee, updateScenarioPath } from './actions' updateBaseFeePerGas, updateConfirmSettings, updateGasPrice, updateGasPriceStatus, updateMaxFee, updateMaxPriorityFee, updateScenarioPath } from './actions'
@ -25,12 +25,8 @@ let plugin: RunTab, dispatch: React.Dispatch<any>
export const initRunTab = (udapp: RunTab) => async (reducerDispatch: React.Dispatch<any>) => { export const initRunTab = (udapp: RunTab) => async (reducerDispatch: React.Dispatch<any>) => {
plugin = udapp plugin = udapp
dispatch = reducerDispatch dispatch = reducerDispatch
setupEvents(plugin, dispatch)
resetAndInit(plugin) resetAndInit(plugin)
setupEvents(plugin, dispatch)
setInterval(() => {
fillAccountsList(plugin, dispatch)
updateInstanceBalance(plugin)
}, 1000)
} }
export const setAccountAddress = (account: string) => setAccount(dispatch, account) export const setAccountAddress = (account: string) => setAccount(dispatch, account)

@ -1,5 +1,5 @@
import { ContractData } from '@remix-project/core-plugin' 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' import { ContractList, DeployOptions } from '../types'
export const fetchAccountsListRequest = () => { 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 }) => { export const addNewInstance = (instance: { contractData?: ContractData, address: string, name: string, abi?: any }) => {
return { return {
type: ADD_INSTANCE, type: ADD_INSTANCE,

@ -117,42 +117,38 @@ export function AccountUI (props: AccountProps) {
const passphraseCreationPrompt = () => { const passphraseCreationPrompt = () => {
return ( return (
<div> Please provide a Passphrase for the account creation <div className='d-flex flex-column'>
<div> Please provide a Passphrase for the account creation
<input id="prompt1" type="password" name='prompt_text' style={{ width: '100%' }} onInput={handlePassphrase} /> <input id="prompt1" type="password" name='prompt_text' className='w-100 py-2' onInput={handlePassphrase} />
<br /> <input id="prompt2" type="password" name='prompt_text' className='w-100' onInput={handleMatchPassphrase} />
<br />
<input id="prompt2" type="password" name='prompt_text' style={{ width: '100%' }} onInput={handleMatchPassphrase} />
</div>
</div> </div>
) )
} }
const signMessagePrompt = () => { const signMessagePrompt = () => {
return ( return (
<div> <FormattedMessage id='udapp.enterAMessageToSign' /> <div>
<div> <FormattedMessage id='udapp.enterAMessageToSign' />
<textarea <textarea
id="prompt_text" id="prompt_text"
className='bg-light' className='bg-light text-light'
data-id="signMessageTextarea" data-id="signMessageTextarea"
style={{ width: '100%' }} style={{ width: '100%' }}
rows={4} rows={4}
cols={50} cols={50}
onInput={handleMessageInput} onInput={handleMessageInput}
defaultValue={messageRef.current} defaultValue={messageRef.current}
></textarea> ></textarea>
</div>
</div> </div>
) )
} }
const signedMessagePrompt = (msgHash: string, signedData: string) => { const signedMessagePrompt = (msgHash: string, signedData: string) => {
return ( return (
<div> <div className="d-flex flex-column">
<b><FormattedMessage id='udapp.hash' />:</b><br /> <label className='text-uppercase'><FormattedMessage id='udapp.hash' /></label>
<span id="remixRunSignMsgHash" data-id="settingsRemixRunSignMsgHash">{msgHash}</span> <span id="remixRunSignMsgHash" data-id="settingsRemixRunSignMsgHash">{msgHash}</span>
<br /><b><FormattedMessage id='udapp.signature' />:</b><br /> <label className='pt-2 text-uppercase'><FormattedMessage id='udapp.signature' /></label>
<span id="remixRunSignMsgSignature" data-id="settingsRemixRunSignMsgSignature">{signedData}</span> <span id="remixRunSignMsgSignature" data-id="settingsRemixRunSignMsgSignature">{signedData}</span>
</div> </div>
) )
@ -168,16 +164,17 @@ export function AccountUI (props: AccountProps) {
tooltipId="remixPlusWrapperTooltip" tooltipId="remixPlusWrapperTooltip"
tooltipText={plusOpt.title} tooltipText={plusOpt.title}
> >
<span id="remixRunPlusWraper"> <span id="remixRunPlusWraper">
<i id="remixRunPlus" className={`fas fa-plus-circle udapp_icon ${plusOpt.classList}`} aria-hidden="true" onClick={newAccount}></i> <i id="remixRunPlus" className={`fas fa-plus-circle udapp_icon ${plusOpt.classList}`} aria-hidden="true" onClick={newAccount}></i>
</span> </span>
</CustomTooltip> </CustomTooltip>
{ props.accounts.isRequesting && <i className="fa fa-spinner fa-pulse ml-2" aria-hidden="true"></i> }
</label> </label>
<div className="udapp_account"> <div className="udapp_account">
<select id="txorigin" data-id="runTabSelectAccount" name="txorigin" className="form-control udapp_select custom-select pr-4" value={selectedAccount} onChange={(e) => { props.setAccount(e.target.value) }}> <select id="txorigin" data-id="runTabSelectAccount" name="txorigin" className="form-control udapp_select custom-select pr-4" value={selectedAccount||""} onChange={(e) => { props.setAccount(e.target.value) }}>
{ {
accounts.map((value, index) => <option value={value} key={index}>{ loadedAccounts[value] }</option>) accounts.map((value, index) => <option value={value} key={index}>{ loadedAccounts[value] }</option>)
} }
</select> </select>
<div style={{ marginLeft: -5 }}><CopyToClipboard tip='Copy account to clipboard' content={selectedAccount} direction='top' /></div> <div style={{ marginLeft: -5 }}><CopyToClipboard tip='Copy account to clipboard' content={selectedAccount} direction='top' /></div>
<CustomTooltip <CustomTooltip

@ -33,6 +33,7 @@ export const SET_MAX_PRIORITY_FEE = 'SET_MAX_PRIORITY_FEE'
export const SET_BASE_FEE_PER_GAS = 'SET_BASE_FEE_PER_GAS' export const SET_BASE_FEE_PER_GAS = 'SET_BASE_FEE_PER_GAS'
export const SET_GAS_PRICE = 'SET_GAS_PRICE' export const SET_GAS_PRICE = 'SET_GAS_PRICE'
export const ADD_INSTANCE = 'ADD_INSTANCE' export const ADD_INSTANCE = 'ADD_INSTANCE'
export const UPDATE_INSTANCES_BALANCE = 'UPDATE_INSTANCES_BALANCE'
export const REMOVE_INSTANCE = 'REMOVE_INSTANCE' export const REMOVE_INSTANCE = 'REMOVE_INSTANCE'
export const CLEAR_INSTANCES = 'CLEAR_INSTANCES' export const CLEAR_INSTANCES = 'CLEAR_INSTANCES'
export const SET_DECODED_RESPONSE = 'SET_DECODED_RESPONSE' export const SET_DECODED_RESPONSE = 'SET_DECODED_RESPONSE'

@ -170,7 +170,6 @@
} }
.udapp_icon:hover { .udapp_icon:hover {
font-size: 12px; font-size: 12px;
color: var(--warning);
} }
.udapp_errorIcon { .udapp_errorIcon {
color: var(--warning); color: var(--warning);

@ -1,6 +1,6 @@
import { ContractData } from '@remix-project/core-plugin' import { ContractData } from '@remix-project/core-plugin'
import { ContractList, DeployOptions, RunTabState } from '../types' import { ContractList, DeployOptions, RunTabState } from '../types'
import { 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, FETCH_PROVIDER_LIST_FAILED, FETCH_PROVIDER_LIST_REQUEST, FETCH_PROVIDER_LIST_SUCCESS, HIDE_NOTIFICATION, HIDE_POPUP_MESSAGE, 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, ADD_DEPLOY_OPTION, REMOVE_DEPLOY_OPTION, SET_REMIXD_ACTIVATED, FETCH_PROXY_DEPLOYMENTS, NEW_PROXY_DEPLOYMENT, RESET_PROXY_DEPLOYMENTS } from '../constants' import { 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, FETCH_PROVIDER_LIST_FAILED, FETCH_PROVIDER_LIST_REQUEST, FETCH_PROVIDER_LIST_SUCCESS, HIDE_NOTIFICATION, HIDE_POPUP_MESSAGE, 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, ADD_DEPLOY_OPTION, REMOVE_DEPLOY_OPTION, SET_REMIXD_ACTIVATED, FETCH_PROXY_DEPLOYMENTS, NEW_PROXY_DEPLOYMENT, RESET_PROXY_DEPLOYMENTS } from '../constants'
declare const window: any declare const window: any
interface Action { interface Action {
@ -487,6 +487,18 @@ export const runTabReducer = (state: RunTabState = runTabInitialState, action: A
} }
} }
case UPDATE_INSTANCES_BALANCE: {
const payload: Array<{ contractData: ContractData, address: string, balance: number, name: string, abi?: any, decodedResponse?: Record<number, any> }> = action.payload
return {
...state,
instances: {
...state.instances,
instanceList: payload
}
}
}
case REMOVE_INSTANCE: { case REMOVE_INSTANCE: {
const payload: number = action.payload const payload: number = action.payload

@ -60,7 +60,7 @@ export class Blockchain extends Plugin<any, any> {
removeProvider(name: any): void; removeProvider(name: any): void;
/** Listen on New Transaction. (Cannot be done inside constructor because txlistener doesn't exist yet) */ /** Listen on New Transaction. (Cannot be done inside constructor because txlistener doesn't exist yet) */
startListening(txlistener: any): void; startListening(txlistener: any): void;
resetEnvironment(): void; resetEnvironment(): Promise<void>;
/** /**
* Create a VM Account * Create a VM Account
* @param {{privateKey: string, balance: string}} newAccount The new account to create * @param {{privateKey: string, balance: string}} newAccount The new account to create
@ -71,7 +71,7 @@ export class Blockchain extends Plugin<any, any> {
}): any; }): any;
newAccount(_password: any, passwordPromptCb: any, cb: any): any; newAccount(_password: any, passwordPromptCb: any, cb: any): any;
/** Get the balance of an address, and convert wei to ether */ /** Get the balance of an address, and convert wei to ether */
getBalanceInEther(address: any, cb: any): void; getBalanceInEther(address: any): Promise<string>;
pendingTransactionsCount(): number; pendingTransactionsCount(): number;
/** /**
* This function send a tx only to Remix VM or testnet, will return an error for the mainnet * This function send a tx only to Remix VM or testnet, will return an error for the mainnet

@ -4,8 +4,8 @@ declare class InjectedProvider {
executionContext: any; executionContext: any;
getAccounts(cb: any): any; getAccounts(cb: any): any;
newAccount(passwordPromptCb: any, cb: any): void; newAccount(passwordPromptCb: any, cb: any): void;
resetEnvironment(): void; resetEnvironment(): Promise<void>;
getBalanceInEther(address: any, cb: any): void; getBalanceInEther(address: any): Promise<string>;
getGasPrice(cb: any): void; getGasPrice(cb: any): void;
signMessage(message: any, account: any, _passphrase: any, cb: any): void; signMessage(message: any, account: any, _passphrase: any, cb: any): void;
getProvider(): string; getProvider(): string;

@ -5,8 +5,8 @@ declare class NodeProvider {
config: any; config: any;
getAccounts(cb: any): any; getAccounts(cb: any): any;
newAccount(passwordPromptCb: any, cb: any): any; newAccount(passwordPromptCb: any, cb: any): any;
resetEnvironment(): void; resetEnvironment(): Promise<void>;
getBalanceInEther(address: any, cb: any): void; getBalanceInEther(address: any): Promise<string>;
getGasPrice(cb: any): void; getGasPrice(cb: any): void;
signMessage(message: any, account: any, passphrase: any, cb: any): void; signMessage(message: any, account: any, passphrase: any, cb: any): void;
getProvider(): any; getProvider(): any;

@ -3,13 +3,13 @@ declare class VMProvider {
constructor(executionContext: any); constructor(executionContext: any);
executionContext: any; executionContext: any;
getAccounts(cb: any): void; getAccounts(cb: any): void;
resetEnvironment(): void; resetEnvironment(): Promise<void>;
accounts: any; accounts: any;
RemixSimulatorProvider: any; RemixSimulatorProvider: any;
web3: any; web3: any;
createVMAccount(newAccount: any): string; createVMAccount(newAccount: any): string;
newAccount(_passwordPromptCb: any, cb: any): void; newAccount(_passwordPromptCb: any, cb: any): void;
getBalanceInEther(address: any, cb: any): void; getBalanceInEther(address: any): Promise<string>;
getGasPrice(cb: any): void; getGasPrice(cb: any): void;
signMessage(message: any, account: any, _passphrase: any, cb: any): void; signMessage(message: any, account: any, _passphrase: any, cb: any): void;
getProvider(): string; getProvider(): string;

@ -3,7 +3,7 @@ import React, { useState, useReducer, useEffect, useCallback } from 'react' // e
import { labels, textDark, textSecondary } from './constants' import { labels, textDark, textSecondary } from './constants'
import './remix-ui-settings.css' 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 { initialState, toastInitialState, toastReducer, settingReducer } from './settingsReducer'
import { Toaster } from '@remix-ui/toaster'// eslint-disable-line import { Toaster } from '@remix-ui/toaster'// eslint-disable-line
import { RemixUiThemeModule, ThemeModule} from '@remix-ui/theme-module' 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') const metadataConfig = props.config.get('settings/generate-contract-metadata')
if (metadataConfig === undefined || metadataConfig === null) generateContractMetadat(props.config, true, dispatch) 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') 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') 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') 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(), [resetState, props.config])
useEffect(() => initValue(), []) useEffect(() => initValue(), [])
@ -110,10 +107,6 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
generateContractMetadat(props.config, event.target.checked, dispatch) generateContractMetadat(props.config, event.target.checked, dispatch)
} }
const onchangeOption = (event) => {
ethereumVM(props.config, event.target.checked, dispatch)
}
const textWrapEvent = (event) => { const textWrapEvent = (event) => {
textWrapEventAction(props.config, props.editor, event.target.checked, dispatch) textWrapEventAction(props.config, props.editor, event.target.checked, dispatch)
} }
@ -148,7 +141,6 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
const generalConfig = () => { const generalConfig = () => {
const isMetadataChecked = props.config.get('settings/generate-contract-metadata') || false 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 isEditorWrapChecked = props.config.get('settings/text-wrap') || false
const isPersonalChecked = props.config.get('settings/personal-mode') || false const isPersonalChecked = props.config.get('settings/personal-mode') || false
const isMatomoChecked = props.config.get('settings/matomo-analytics') || false const isMatomoChecked = props.config.get('settings/matomo-analytics') || false
@ -192,12 +184,6 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
<FormattedMessage id='settings.generateContractMetadataText' /> <FormattedMessage id='settings.generateContractMetadataText' />
</label> </label>
</div> </div>
<div className="fmt-2 custom-control custom-checkbox mb-1">
<input onChange={onchangeOption} className="custom-control-input" id="alwaysUseVM" data-id="settingsTabAlwaysUseVM" type="checkbox" name="ethereumVM" checked={isEthereumVMChecked} />
<label className={`form-check-label custom-control-label align-middle ${getTextClass('settings/always-use-vm')}`} htmlFor="alwaysUseVM">
<FormattedMessage id='settings.ethereunVMText' />
</label>
</div>
<div className="mt-2 custom-control custom-checkbox mb-1"> <div className="mt-2 custom-control custom-checkbox mb-1">
<input id="editorWrap" className="custom-control-input" type="checkbox" onChange={textWrapEvent} checked={isEditorWrapChecked} /> <input id="editorWrap" className="custom-control-input" type="checkbox" onChange={textWrapEvent} checked={isEditorWrapChecked} />
<label className={`form-check-label custom-control-label align-middle ${getTextClass('settings/text-wrap')}`} htmlFor="editorWrap"> <label className={`form-check-label custom-control-label align-middle ${getTextClass('settings/text-wrap')}`} htmlFor="editorWrap">

@ -13,11 +13,6 @@ export const generateContractMetadat = (config, checked, dispatch) => {
dispatch({ type: 'contractMetadata', payload: { isChecked: checked, textClass: checked ? textDark : textSecondary } }) dispatch({ type: 'contractMetadata', payload: { isChecked: checked, textClass: checked ? textDark : textSecondary } })
} }
export const ethereumVM = (config, checked: boolean, dispatch) => {
config.set('settings/always-use-vm', checked)
dispatch({ type: 'ethereumVM', payload: { isChecked: checked, textClass: checked ? textDark : textSecondary } })
}
export const textWrapEventAction = (config, editor, checked, dispatch) => { export const textWrapEventAction = (config, editor, checked, dispatch) => {
config.set('settings/text-wrap', checked) config.set('settings/text-wrap', checked)
editor.resize(checked) editor.resize(checked)

@ -281,6 +281,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
'New configuration file', `The file "${configFilePathInput.current.value}" you entered does not exist. Do you want to create a new one?`, 'New configuration file', `The file "${configFilePathInput.current.value}" you entered does not exist. Do you want to create a new one?`,
'Create', 'Create',
async () => await createNewConfigFile(), async () => await createNewConfigFile(),
false,
'Cancel', 'Cancel',
() => { () => {
setShowFilePathInput(false) setShowFilePathInput(false)
@ -580,6 +581,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
promptMessage('URL'), promptMessage('URL'),
'OK', 'OK',
addCustomCompiler, addCustomCompiler,
false,
'Cancel', 'Cancel',
() => {} () => {}
) )

@ -4,9 +4,11 @@ import { ContractSelectionProps } from './types'
import { PublishToStorage } from '@remix-ui/publish-to-storage' // eslint-disable-line import { PublishToStorage } from '@remix-ui/publish-to-storage' // eslint-disable-line
import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line
import { CopyToClipboard } from '@remix-ui/clipboard' // eslint-disable-line import { CopyToClipboard } from '@remix-ui/clipboard' // eslint-disable-line
import { saveAs } from 'file-saver'
import './css/style.css' import './css/style.css'
import { CustomTooltip } from '@remix-ui/helper' import { CustomTooltip } from '@remix-ui/helper'
const _paq = window._paq = window._paq || []
export const ContractSelection = (props: ContractSelectionProps) => { export const ContractSelection = (props: ContractSelectionProps) => {
const { api, compiledFileName, contractsDetails, contractList, compilerInput, modal } = props const { api, compiledFileName, contractsDetails, contractList, compilerInput, modal } = props
@ -141,6 +143,7 @@ export const ContractSelection = (props: ContractSelectionProps) => {
} }
const details = () => { const details = () => {
_paq.push(['trackEvent', 'compiler', 'compilerDetails', 'display'])
if (!selectedContract) throw new Error('No contract compiled yet') if (!selectedContract) throw new Error('No contract compiled yet')
const help = { const help = {
@ -183,8 +186,11 @@ export const ContractSelection = (props: ContractSelectionProps) => {
} }
</TreeView> </TreeView>
</div> </div>
const downloadFn = () => {
modal(selectedContract, log, 'Close', null) _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 = () => { const copyBytecode = () => {

@ -27,6 +27,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
message: null, message: null,
okLabel: '', okLabel: '',
okFn: () => { }, okFn: () => { },
donotHideOnOkClick: false,
cancelLabel: '', cancelLabel: '',
cancelFn: () => { }, cancelFn: () => { },
handleHide: null handleHide: null
@ -131,7 +132,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
api.setCompilerParameters({ version: value }) 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 => { await setState(prevState => {
return { return {
...prevState, ...prevState,
@ -142,6 +143,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
title, title,
okLabel, okLabel,
okFn, okFn,
donotHideOnOkClick,
cancelLabel, cancelLabel,
cancelFn cancelFn
} }
@ -190,7 +192,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
<> <>
<span data-id={`compilationFinishedWith_${currentVersion}`}></span> <span data-id={`compilationFinishedWith_${currentVersion}`}></span>
{compileErrors[currentFile].error && <Renderer message={compileErrors[currentFile].error.formattedMessage || compileErrors[currentFile].error} plugin={api} opt={{ type: compileErrors[currentFile].error.severity || 'error', errorType: compileErrors[currentFile].error.type }} />} {compileErrors[currentFile].error && <Renderer message={compileErrors[currentFile].error.formattedMessage || compileErrors[currentFile].error} plugin={api} opt={{ type: compileErrors[currentFile].error.severity || 'error', errorType: compileErrors[currentFile].error.type }} />}
{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) => { {compileErrors[currentFile].errors && compileErrors[currentFile].errors.length && compileErrors[currentFile].errors.map((err, index) => {
if (hideWarnings) { if (hideWarnings) {
if (err.severity !== 'warning') { if (err.severity !== 'warning') {
@ -212,6 +214,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
hide={state.modal.hide} hide={state.modal.hide}
okLabel={state.modal.okLabel} okLabel={state.modal.okLabel}
okFn={state.modal.okFn} okFn={state.modal.okFn}
donotHideOnOkClick={state.modal.donotHideOnOkClick}
cancelLabel={state.modal.cancelLabel} cancelLabel={state.modal.cancelLabel}
cancelFn={state.modal.cancelFn} cancelFn={state.modal.cancelFn}
handleHide={handleHideModal}> handleHide={handleHideModal}>

@ -14,7 +14,7 @@ export interface CompilerContainerProps {
isFoundryProject: boolean, isFoundryProject: boolean,
workspaceName: string, workspaceName: string,
tooltip: (message: string | JSX.Element) => void, 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, compiledFileName: string,
updateCurrentVersion: any, updateCurrentVersion: any,
configurationSettings: ConfigurationSettings, configurationSettings: ConfigurationSettings,
@ -26,7 +26,7 @@ export interface ContractSelectionProps {
compiledFileName: string, compiledFileName: string,
contractList: { file: string, name: string }[], contractList: { file: string, name: string }[],
compilerInput: Record<string, any> compilerInput: Record<string, any>
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<string, any> contractsDetails: Record<string, any>
} }

@ -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 () => { export const restoreBackupZip = async () => {
await plugin.appManager.activatePlugin(['restorebackupzip']) await plugin.appManager.activatePlugin(['restorebackupzip'])
await plugin.call('mainPanel', 'showContent', 'restorebackupzip') await plugin.call('mainPanel', 'showContent', 'restorebackupzip')

@ -4,9 +4,10 @@ import { HamburgerMenuItem } from './workspace-hamburger-item'
export interface HamburgerMenuProps { export interface HamburgerMenuProps {
createWorkspace: () => void, createWorkspace: () => void,
renameCurrentWorkspace: () => void,
downloadCurrentWorkspace: () => void,
deleteCurrentWorkspace: () => void, deleteCurrentWorkspace: () => void,
deleteAllWorkspaces: () => void, deleteAllWorkspaces: () => void,
renameCurrentWorkspace: () => void,
cloneGitRepository: () => void, cloneGitRepository: () => void,
downloadWorkspaces: () => void, downloadWorkspaces: () => void,
restoreBackup: () => void, restoreBackup: () => void,
@ -27,24 +28,27 @@ export function HamburgerMenu (props: HamburgerMenuProps) {
props.createWorkspace() props.createWorkspace()
props.hideIconsMenu(!showIconsMenu) props.hideIconsMenu(!showIconsMenu)
}}></HamburgerMenuItem> }}></HamburgerMenuItem>
<HamburgerMenuItem kind='delete' fa='far fa-trash' hideOption={hideWorkspaceOptions || hideLocalhostOptions} actionOnClick={() => { <HamburgerMenuItem kind='clone' fa='fab fa-github' hideOption={hideWorkspaceOptions} actionOnClick={() => {
props.deleteCurrentWorkspace() props.cloneGitRepository()
props.hideIconsMenu(!showIconsMenu)
}}></HamburgerMenuItem>
<HamburgerMenuItem kind='deleteAll' fa='far fa-trash-alt' hideOption={hideWorkspaceOptions || hideLocalhostOptions} actionOnClick={() => {
props.deleteAllWorkspaces()
props.hideIconsMenu(!showIconsMenu) props.hideIconsMenu(!showIconsMenu)
}}></HamburgerMenuItem> }}></HamburgerMenuItem>
<HamburgerMenuItem kind='rename' fa='far fa-edit' hideOption={hideWorkspaceOptions || hideLocalhostOptions} actionOnClick={() => { <HamburgerMenuItem kind='rename' fa='far fa-edit' hideOption={hideWorkspaceOptions || hideLocalhostOptions} actionOnClick={() => {
props.renameCurrentWorkspace() props.renameCurrentWorkspace()
props.hideIconsMenu(!showIconsMenu) props.hideIconsMenu(!showIconsMenu)
}}></HamburgerMenuItem> }}></HamburgerMenuItem>
<HamburgerMenuItem kind='download' fa='far fa-arrow-alt-down' hideOption={hideWorkspaceOptions || hideLocalhostOptions} actionOnClick={() => {
props.downloadCurrentWorkspace()
props.hideIconsMenu(!showIconsMenu)
}}></HamburgerMenuItem>
<HamburgerMenuItem kind='delete' fa='far fa-trash' hideOption={hideWorkspaceOptions || hideLocalhostOptions} actionOnClick={() => {
props.deleteCurrentWorkspace()
props.hideIconsMenu(!showIconsMenu)
}}></HamburgerMenuItem>
<Dropdown.Divider className="border mb-0 mt-0 remixui_menuhr" style={{ pointerEvents: 'none' }} /> <Dropdown.Divider className="border mb-0 mt-0 remixui_menuhr" style={{ pointerEvents: 'none' }} />
<HamburgerMenuItem kind='clone' fa='fab fa-github' hideOption={hideWorkspaceOptions} actionOnClick={() => { <HamburgerMenuItem kind='deleteAll' fa='far fa-trash-alt' hideOption={hideWorkspaceOptions || hideLocalhostOptions} actionOnClick={() => {
props.cloneGitRepository() props.deleteAllWorkspaces()
props.hideIconsMenu(!showIconsMenu) props.hideIconsMenu(!showIconsMenu)
}}></HamburgerMenuItem> }}></HamburgerMenuItem>
<Dropdown.Divider className="border mt-0 mb-0 remixui_menuhr" style={{ pointerEvents: 'none' }}/>
<HamburgerMenuItem kind='backup' fa='far fa-download' hideOption={hideWorkspaceOptions || hideLocalhostOptions} actionOnClick={() => { <HamburgerMenuItem kind='backup' fa='far fa-download' hideOption={hideWorkspaceOptions || hideLocalhostOptions} actionOnClick={() => {
props.downloadWorkspaces() props.downloadWorkspaces()
props.hideIconsMenu(!showIconsMenu) props.hideIconsMenu(!showIconsMenu)

@ -33,6 +33,7 @@ export const FileSystemContext = createContext<{
dispatchHandleClickFile: (path: string, type: 'file' | 'folder' | 'gist') => Promise<void> dispatchHandleClickFile: (path: string, type: 'file' | 'folder' | 'gist') => Promise<void>
dispatchHandleExpandPath: (paths: string[]) => Promise<void>, dispatchHandleExpandPath: (paths: string[]) => Promise<void>,
dispatchHandleDownloadFiles: () => Promise<void>, dispatchHandleDownloadFiles: () => Promise<void>,
dispatchHandleDownloadWorkspace: () => Promise<void>,
dispatchHandleRestoreBackup: () => Promise<void> dispatchHandleRestoreBackup: () => Promise<void>
dispatchCloneRepository: (url: string) => Promise<void>, dispatchCloneRepository: (url: string) => Promise<void>,
dispatchMoveFile: (src: string, dest: string) => Promise<void>, dispatchMoveFile: (src: string, dest: string) => Promise<void>,

@ -7,7 +7,7 @@ import { FileSystemContext } from '../contexts'
import { browserReducer, browserInitialState } from '../reducers/workspace' import { browserReducer, browserInitialState } from '../reducers/workspace'
import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, deleteAllWorkspaces, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder, import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, deleteAllWorkspaces, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder,
deletePath, renamePath, downloadPath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace, 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 showAllBranches, switchBranch, createNewBranch, checkoutRemoteBranch, createSolidityGithubAction, createTsSolGithubAction, createSlitherGithubAction
} from '../actions' } from '../actions'
import { Modal, WorkspaceProps, WorkspaceTemplate } from '../types' import { Modal, WorkspaceProps, WorkspaceTemplate } from '../types'
@ -135,6 +135,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
await handleDownloadFiles() await handleDownloadFiles()
} }
const dispatchHandleDownloadWorkspace = async () => {
await handleDownloadWorkspace()
}
const dispatchHandleRestoreBackup = async () => { const dispatchHandleRestoreBackup = async () => {
await restoreBackupZip() await restoreBackupZip()
} }
@ -284,6 +288,7 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
dispatchHandleClickFile, dispatchHandleClickFile,
dispatchHandleExpandPath, dispatchHandleExpandPath,
dispatchHandleDownloadFiles, dispatchHandleDownloadFiles,
dispatchHandleDownloadWorkspace,
dispatchHandleRestoreBackup, dispatchHandleRestoreBackup,
dispatchCloneRepository, dispatchCloneRepository,
dispatchMoveFile, dispatchMoveFile,

@ -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' })) 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 = () => { const createWorkspace = () => {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.create' }), createModalMessage(), intl.formatMessage({ id: 'filePanel.ok' }), onFinishCreateWorkspace, intl.formatMessage({ id: 'filePanel.cancel' })) 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 () => { const onFinishCreateWorkspace = async () => {
if (workspaceCreateInput.current === undefined) return if (workspaceCreateInput.current === undefined) return
// @ts-ignore: Object is possibly 'null'. // @ts-ignore: Object is possibly 'null'.
@ -453,9 +465,10 @@ export function Workspace () {
<Dropdown.Menu as={CustomMenu} data-id="wsdropdownMenu" className='custom-dropdown-items remixui_menuwidth' rootCloseEvent="click"> <Dropdown.Menu as={CustomMenu} data-id="wsdropdownMenu" className='custom-dropdown-items remixui_menuwidth' rootCloseEvent="click">
<HamburgerMenu <HamburgerMenu
createWorkspace={createWorkspace} createWorkspace={createWorkspace}
renameCurrentWorkspace={renameCurrentWorkspace}
downloadCurrentWorkspace={downloadCurrentWorkspace}
deleteCurrentWorkspace={deleteCurrentWorkspace} deleteCurrentWorkspace={deleteCurrentWorkspace}
deleteAllWorkspaces={deleteAllWorkspaces} deleteAllWorkspaces={deleteAllWorkspaces}
renameCurrentWorkspace={renameCurrentWorkspace}
cloneGitRepository={cloneGitRepository} cloneGitRepository={cloneGitRepository}
downloadWorkspaces={downloadWorkspaces} downloadWorkspaces={downloadWorkspaces}
restoreBackup={restoreBackup} restoreBackup={restoreBackup}

@ -11,10 +11,17 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Run SUT Action - name: Run SUT Action
uses: EthereumRemix/sol-test@v1 uses: EthereumRemix/sol-test@v1.1
with: with:
test-path: 'tests' test-path: 'tests'
compiler-version: '0.8.15' compiler-version: '0.8.15'
// evm-version: 'paris'
// optimize: true
// optimizer-runs: 200
// node-url: 'https://mainnet.infura.io/v3/08b2a484451e4635a28b3d8234f24332'
// block-number: 'latest'
// hard-fork: 'merge'
` `
export const tsSolTestYml = ` export const tsSolTestYml = `
name: Running Mocha Chai Solidity Unit Tests name: Running Mocha Chai Solidity Unit Tests
@ -28,11 +35,17 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Run Mocha Chai Unit Test Action - name: Run Mocha Chai Unit Test Action
uses: EthereumRemix/ts-sol-test@v1.2 uses: EthereumRemix/ts-sol-test@v1.3.1
with: with:
test-path: 'tests' test-path: 'tests'
contract-path: 'contracts' contract-path: 'contracts'
compiler-version: '0.8.7' compiler-version: '0.8.7'
// evm-version: 'paris'
// optimize: true
// optimizer-runs: 200
// node-url: 'https://mainnet.infura.io/v3/08b2a484451e4635a28b3d8234f24332'
// block-number: 'latest'
// hard-fork: 'merge'
` `
export const slitherYml = ` export const slitherYml = `
name: Slither Analysis name: Slither Analysis

@ -1,6 +1,6 @@
{ {
"name": "@remix-project/remix-url-resolver", "name": "@remix-project/remix-url-resolver",
"version": "0.0.47-alpha.10", "version": "0.0.47-alpha.17",
"description": "Solidity import url resolver engine", "description": "Solidity import url resolver engine",
"main": "src/index.js", "main": "src/index.js",
"types": "src/index.d.ts", "types": "src/index.d.ts",
@ -40,5 +40,5 @@
"typescript": "^3.1.6" "typescript": "^3.1.6"
}, },
"typings": "src/index.d.ts", "typings": "src/index.d.ts",
"gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c" "gitHead": "4806543bb099b558872793ca7a215468e0bffc81"
} }

@ -1,6 +1,6 @@
{ {
"name": "@remix-project/remix-ws-templates", "name": "@remix-project/remix-ws-templates",
"version": "1.0.12-alpha.10", "version": "1.0.12-alpha.17",
"description": "Create a Remix IDE workspace using different templates", "description": "Create a Remix IDE workspace using different templates",
"main": "src/index.js", "main": "src/index.js",
"types": "src/index.d.ts", "types": "src/index.d.ts",
@ -24,5 +24,5 @@
"ethers": "^5.4.2", "ethers": "^5.4.2",
"web3": "^1.5.1" "web3": "^1.5.1"
}, },
"gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c" "gitHead": "4806543bb099b558872793ca7a215468e0bffc81"
} }

@ -5936,16 +5936,16 @@
"@types/estree" "*" "@types/estree" "*"
"@types/json-schema" "*" "@types/json-schema" "*"
"@types/estree@*", "@types/estree@0.0.39": "@types/estree@*", "@types/estree@^0.0.51":
version "0.0.39"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
"@types/estree@^0.0.51":
version "0.0.51" version "0.0.51"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40"
integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==
"@types/estree@0.0.39":
version "0.0.39"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18":
version "4.17.31" version "4.17.31"
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz#a1139efeab4e7323834bb0226e62ac019f474b2f" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz#a1139efeab4e7323834bb0226e62ac019f474b2f"
@ -6822,16 +6822,11 @@ acorn@^7.0.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
acorn@^8.0.4: acorn@^8.0.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0:
version "8.8.1" version "8.8.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73"
integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==
acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0:
version "8.8.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8"
integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==
adm-zip@^0.4.16: adm-zip@^0.4.16:
version "0.4.16" version "0.4.16"
resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365"
@ -8865,18 +8860,7 @@ browserslist@^3.2.6:
caniuse-lite "^1.0.30000844" caniuse-lite "^1.0.30000844"
electron-to-chromium "^1.3.47" electron-to-chromium "^1.3.47"
browserslist@^4.0.0, browserslist@^4.16.6: browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.20.3, browserslist@^4.21.3, browserslist@^4.21.4:
version "4.17.3"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.3.tgz#2844cd6eebe14d12384b0122d217550160d2d624"
integrity sha512-59IqHJV5VGdcJZ+GZ2hU5n4Kv3YiASzW6Xk5g9tf5a/MAzGeFwgGWU39fVzNIOVcgB3+Gp+kiQu0HEfTVU/3VQ==
dependencies:
caniuse-lite "^1.0.30001264"
electron-to-chromium "^1.3.857"
escalade "^3.1.1"
node-releases "^1.1.77"
picocolors "^0.2.1"
browserslist@^4.14.5, browserslist@^4.20.3, browserslist@^4.21.3, browserslist@^4.21.4:
version "4.21.4" version "4.21.4"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987"
integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==
@ -9266,7 +9250,7 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2" lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0" lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001264, caniuse-lite@^1.0.30001407: caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001407:
version "1.0.30001426" version "1.0.30001426"
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001426.tgz" resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001426.tgz"
integrity sha512-n7cosrHLl8AWt0wwZw/PJZgUg3lV0gk9LMI7ikGJwhyhgsd2Nb65vKvmSexCqq/J7rbH3mFG6yZZiPR5dLPW5A== integrity sha512-n7cosrHLl8AWt0wwZw/PJZgUg3lV0gk9LMI7ikGJwhyhgsd2Nb65vKvmSexCqq/J7rbH3mFG6yZZiPR5dLPW5A==
@ -11666,11 +11650,6 @@ electron-to-chromium@^1.3.47:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.308.tgz#39e7047579867c59973eec5168d8bf440780cb7a" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.308.tgz#39e7047579867c59973eec5168d8bf440780cb7a"
integrity sha512-qyTx2aDFjEni4UnRWEME9ubd2Xc9c0zerTUl/ZinvD4QPsF0S7kJTV/Es/lPCTkNX6smyYar+z/n8Cl6pFr8yQ== integrity sha512-qyTx2aDFjEni4UnRWEME9ubd2Xc9c0zerTUl/ZinvD4QPsF0S7kJTV/Es/lPCTkNX6smyYar+z/n8Cl6pFr8yQ==
electron-to-chromium@^1.3.857:
version "1.3.866"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.866.tgz#d446338f5ad6948b27a50739760e7b0b5cc5032f"
integrity sha512-iYze6TpDXWxk+sfcpUUdTs6Pv/3kG45Pnjer2DxEeFw0N08bZeNLuz97s2lMgy8yObon48o0WHY2Bkg3xuAPOA==
electron-to-chromium@^1.4.251: electron-to-chromium@^1.4.251:
version "1.4.264" version "1.4.264"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.264.tgz#2f68a062c38b7a04bf57f3e6954b868672fbdcd3" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.264.tgz#2f68a062c38b7a04bf57f3e6954b868672fbdcd3"
@ -11750,15 +11729,7 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1:
dependencies: dependencies:
once "^1.4.0" once "^1.4.0"
enhanced-resolve@^5.0.0: enhanced-resolve@^5.0.0, enhanced-resolve@^5.10.0, enhanced-resolve@^5.7.0:
version "5.8.3"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0"
integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==
dependencies:
graceful-fs "^4.2.4"
tapable "^2.2.0"
enhanced-resolve@^5.10.0, enhanced-resolve@^5.7.0:
version "5.10.0" version "5.10.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6"
integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==
@ -12529,7 +12500,7 @@ eventemitter3@^4.0.0, eventemitter3@^4.0.4:
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
events@3.2.0, events@^3.0.0: events@3.2.0:
version "3.2.0" version "3.2.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379"
integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==
@ -12539,7 +12510,7 @@ events@^2.0.0:
resolved "https://registry.yarnpkg.com/events/-/events-2.1.0.tgz#2a9a1e18e6106e0e812aa9ebd4a819b3c29c0ba5" resolved "https://registry.yarnpkg.com/events/-/events-2.1.0.tgz#2a9a1e18e6106e0e812aa9ebd4a819b3c29c0ba5"
integrity sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg== integrity sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==
events@^3.2.0: events@^3.0.0, events@^3.2.0:
version "3.3.0" version "3.3.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
@ -14342,21 +14313,16 @@ got@^9.6.0:
to-readable-stream "^1.0.0" to-readable-stream "^1.0.0"
url-parse-lax "^3.0.0" url-parse-lax "^3.0.0"
graceful-fs@^4.0.0, graceful-fs@^4.1.15, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.4: graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
version "4.2.8" version "4.2.10"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@~4.1.11: graceful-fs@~4.1.11:
version "4.1.11" version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=
graceful-fs@^4.2.6, graceful-fs@^4.2.9:
version "4.2.10"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
grapheme-splitter@^1.0.4: grapheme-splitter@^1.0.4:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
@ -18200,42 +18166,23 @@ miller-rabin@^4.0.0:
bn.js "^4.0.0" bn.js "^4.0.0"
brorand "^1.0.1" brorand "^1.0.1"
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-db@1.52.0: mime-db@1.52.0:
version "1.52.0" version "1.52.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-db@~1.26.0: "mime-db@>= 1.43.0 < 2":
version "1.26.0" version "1.51.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.26.0.tgz#eaffcd0e4fc6935cf8134da246e2e6c35305adff" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c"
integrity sha1-6v/NDk/Gk1z4E02iRuLmw1MFrf8= integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==
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-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" version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies: dependencies:
mime-db "1.52.0" 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: mime@1.6.0, mime@^1.4.1, mime@^1.6.0:
version "1.6.0" version "1.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" 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" shellwords "^0.1.0"
which "^1.0.5" 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: node-releases@^2.0.6:
version "2.0.6" version "2.0.6"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" 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" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= 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: picocolors@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" 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" typed-assert "^1.0.8"
webpack@^5.75.0: webpack@^5.75.0:
version "5.75.0" version "5.76.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.75.0.tgz#1e440468647b2505860e94c9ff3e44d5b582c152" resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c"
integrity sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ== integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==
dependencies: dependencies:
"@types/eslint-scope" "^3.7.3" "@types/eslint-scope" "^3.7.3"
"@types/estree" "^0.0.51" "@types/estree" "^0.0.51"

Loading…
Cancel
Save