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(),
];
config.watchOptions = {
ignored: /node_modules/
}
return config;
});

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

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

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

@ -18,14 +18,6 @@ module.exports = {
init(browser, done, 'http://127.0.0.1:8080', false)
},
'Should enable settings': function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('settings')
.click('[data-id="settingsAutoCompleteLabel"]')
.click('[data-id="settingsShowGasLabel"]')
.click('[data-id="displayErrorsLabel"]')
},
'Should load the test file': function (browser: NightwatchBrowser) {
browser.openFile('contracts')
.openFile('contracts/3_Ballot.sol')

@ -20,13 +20,6 @@ module.exports = {
init(browser, done, 'http://127.0.0.1:8080', false)
},
'Should enable settings': function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('settings')
.click('[data-id="settingsAutoCompleteLabel"]')
.click('[data-id="settingsShowGasLabel"]')
.click('[data-id="displayErrorsLabel"]')
},
'Should load the test file': function (browser: NightwatchBrowser) {
browser.openFile('contracts')
.openFile('contracts/3_Ballot.sol')

@ -8,13 +8,7 @@ module.exports = {
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done, 'http://127.0.0.1:8080', true)
},
'Should enable settings': function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('settings')
.click('[data-id="settingsAutoCompleteLabel"]')
.click('[data-id="settingsShowGasLabel"]')
.click('[data-id="displayErrorsLabel"]')
},
'Should add error marker': function (browser: NightwatchBrowser) {
browser
.openFile('contracts')

@ -8,13 +8,7 @@ module.exports = {
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done, 'http://127.0.0.1:8080', true)
},
'Should enable settings': function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('settings')
.click('[data-id="settingsAutoCompleteLabel"]')
.click('[data-id="settingsShowGasLabel"]')
.click('[data-id="displayErrorsLabel"]')
},
'Should add line texts': function (browser: NightwatchBrowser) {
browser
.openFile('contracts')

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

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

@ -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
chainId: 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 { Plugin } from '@remixproject/engine'
import { JsonDataRequest, RejectRequest, SuccessRequest } from '../providers/abstract-provider'
import Web3 from 'web3'
import { IProvider } from './abstract-provider'
const noInjectedProviderMsg = 'No injected provider found. Make sure your provider (e.g. MetaMask) is active and running (when recently activated you may have to reload the page).'
export class InjectedProvider extends Plugin implements IProvider {
provider: any
export abstract class InjectedProvider extends Plugin implements IProvider {
options: { [id: string] : any } = {}
listenerAccountsChanged: (accounts: Array<string>) => void
listenerChainChanged: (chainId: number) => void
constructor (profile) {
super(profile)
if ((window as any).ethereum) {
this.provider = new Web3((window as any).ethereum)
this.listenerAccountsChanged = (accounts: Array<string>) => {
this.emit('accountsChanged', accounts)
}
this.listenerChainChanged = (chainId: number) => {
this.emit('chainChanged', chainId)
}
}
abstract getInjectedProvider(): any
abstract notFound(): string
onActivation(): void {
try {
const web3Provider = this.getInjectedProvider()
web3Provider.on('accountsChanged', this.listenerAccountsChanged);
web3Provider.on('chainChanged', this.listenerChainChanged);
} catch (error) {
console.log('unable to listen on context changed')
}
}
onDeactivation(): void {
try {
const web3Provider = this.getInjectedProvider()
web3Provider.removeListener('accountsChanged', this.listenerAccountsChanged)
web3Provider.removeListener('chainChanged', this.listenerChainChanged)
} catch (error) {
console.log('unable to remove listener on context changed')
}
}
askPermission (throwIfNoInjectedProvider) {
if ((typeof (window as any).ethereum) !== "undefined" && (typeof (window as any).ethereum.request) === "function") {
(window as any).ethereum.request({ method: "eth_requestAccounts" })
const web3Provider = this.getInjectedProvider()
if (typeof web3Provider !== "undefined" && typeof web3Provider.request === "function") {
web3Provider.request({ method: "eth_requestAccounts" })
} else if (throwIfNoInjectedProvider) {
throw new Error(noInjectedProviderMsg)
throw new Error(this.notFound())
}
}
@ -33,14 +58,11 @@ export class InjectedProvider extends Plugin implements IProvider {
}
async init () {
const injectedProvider = (window as any).ethereum
const injectedProvider = this.getInjectedProvider()
if (injectedProvider === undefined) {
this.call('notification', 'toast', noInjectedProviderMsg)
throw new Error(noInjectedProviderMsg)
this.call('notification', 'toast', this.notFound())
throw new Error(this.notFound())
} else {
if (injectedProvider && injectedProvider._metamask && injectedProvider._metamask.isUnlocked) {
if (!await injectedProvider._metamask.isUnlocked()) this.call('notification', 'toast', 'Please make sure the injected provider is unlocked (e.g Metamask).')
}
this.askPermission(true)
}
return {}
@ -55,12 +77,19 @@ export class InjectedProvider extends Plugin implements IProvider {
private async sendAsyncInternal (data: JsonDataRequest, resolve: SuccessRequest, reject: RejectRequest): Promise<void> {
// Check the case where current environment is VM on UI and it still sends RPC requests
// This will be displayed on UI tooltip as 'cannot get account list: Environment Updated !!'
if (!this.provider) {
const web3Provider = this.getInjectedProvider()
if (!web3Provider) {
this.call('notification', 'toast', 'No injected provider (e.g Metamask) has been found.')
return resolve({ jsonrpc: '2.0', error: 'no injected provider found', id: data.id })
}
try {
let resultData = await this.provider.currentProvider.send(data.method, data.params)
let resultData
if (web3Provider.send) resultData = await web3Provider.send(data.method, data.params)
else if (web3Provider.request) resultData = await web3Provider.request({ method: data.method, params: data.params})
else {
resolve({ jsonrpc: '2.0', error: 'provider not valid', id: data.id })
return
}
if (resultData) {
if (resultData.jsonrpc && resultData.jsonrpc === '2.0') {
resultData = resultData.result

@ -10,12 +10,14 @@
"filePanel.workspace.rename": "Rename Workspace",
"filePanel.workspace.delete": "Delete Workspace",
"filePanel.workspace.deleteConfirm": "Are you sure to delete the current workspace?",
"filePanel.workspace.download": "Download Workspace",
"filePanel.workspace.downloadConfirm": "This will download current workspace in a zip file. Do you want to continue?",
"filePanel.workspace.deleteAll": "Delete All Workspaces",
"filePanel.workspace.deleteAllConfirm1": "Are you absolutely sure you want to delete all your workspaces?",
"filePanel.workspace.deleteAllConfirm2": "Deleted workspaces can not be restored in any manner.",
"filePanel.workspace.name": "Workspace name",
"filePanel.workspace.chooseTemplate": "Choose a template",
"filePanel.workspace.backup": "Backup Workspaces",
"filePanel.workspace.backup": "Backup All Workspaces",
"filePanel.workspace.restore": "Restore Workspaces from the Backup",
"filePanel.workspace.clone": "Clone Git Repository",
"filePanel.workspace.cloneMessage": "Please provide a valid git repository url.",

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

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

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

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

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

@ -19,7 +19,7 @@ class VMProvider {
})
}
resetEnvironment () {
async resetEnvironment () {
if (this.worker) this.worker.terminate()
this.accounts = {}
this.worker = new Worker(new URL('./worker-vm', import.meta.url))
@ -27,23 +27,29 @@ class VMProvider {
let incr = 0
const stamps = {}
this.worker.addEventListener('message', (msg) => {
if (msg.data.cmd === 'sendAsyncResult' && stamps[msg.data.stamp]) {
stamps[msg.data.stamp](msg.data.error, msg.data.result)
} else if (msg.data.cmd === 'initiateResult') {
if (!msg.data.error) {
this.provider = {
sendAsync: (query, callback) => {
const stamp = Date.now() + incr
incr++
stamps[stamp] = callback
this.worker.postMessage({ cmd: 'sendAsync', query, stamp })
return new Promise((resolve, reject) => {
this.worker.addEventListener('message', (msg) => {
if (msg.data.cmd === 'sendAsyncResult' && stamps[msg.data.stamp]) {
stamps[msg.data.stamp](msg.data.error, msg.data.result)
} else if (msg.data.cmd === 'initiateResult') {
if (!msg.data.error) {
this.provider = {
sendAsync: (query, callback) => {
const stamp = Date.now() + incr
incr++
stamps[stamp] = callback
this.worker.postMessage({ cmd: 'sendAsync', query, stamp })
}
}
this.web3 = new Web3(this.provider)
extend(this.web3)
this.accounts = {}
this.executionContext.setWeb3(this.executionContext.getProvider(), this.web3)
resolve({})
} else {
reject(new Error(msg.data.error))
}
this.web3 = new Web3(this.provider)
extend(this.web3)
this.accounts = {}
this.executionContext.setWeb3(this.executionContext.getProvider(), this.web3)
}
} else if (msg.data.cmd === 'newAccountResult') {
if (this.newAccountCallback[msg.data.stamp]) {
@ -52,7 +58,6 @@ class VMProvider {
}
}
})
this.worker.postMessage({ cmd: 'init', fork: this.executionContext.getCurrentFork(), nodeUrl: provider?.options['nodeUrl'], blockNumber: provider?.options['blockNumber']})
}
@ -71,13 +76,9 @@ class VMProvider {
this.worker.postMessage({ cmd: 'newAccount', stamp })
}
getBalanceInEther (address, cb) {
this.web3.eth.getBalance(address, (err, res) => {
if (err) {
return cb(err)
}
cb(null, Web3.utils.fromWei(new BN(res).toString(10), 'ether'))
})
async getBalanceInEther (address) {
const balance = await this.web3.eth.getBalance(address)
return Web3.utils.fromWei(new BN(balance).toString(10), 'ether')
}
getGasPrice (cb) {

@ -10,7 +10,7 @@ const requiredModules = [ // services + layout views + system views
'fileManager', 'contentImport', 'blockchain', 'web3Provider', 'scriptRunner', 'fetchAndCompile', 'mainPanel', 'hiddenPanel', 'sidePanel', 'menuicons',
'filePanel', 'terminal', 'settings', 'pluginManager', 'tabs', 'udapp', 'dGitProvider', 'solidity', 'solidity-logic', 'gistHandler', 'layout',
'notification', 'permissionhandler', 'walkthrough', 'storage', 'restorebackupzip', 'link-libraries', 'deploy-libraries', 'openzeppelin-proxy',
'hardhat-provider', 'ganache-provider', 'foundry-provider', 'basic-http-provider', 'injected', 'injected-optimism-provider', 'injected-arbitrum-one-provider', 'vm-custom-fork', 'vm-goerli-fork', 'vm-mainnet-fork', 'vm-sepolia-fork', 'vm-merge', 'vm-london', 'vm-berlin',
'hardhat-provider', 'ganache-provider', 'foundry-provider', 'basic-http-provider', 'injected', 'injected-trustwallet', 'injected-optimism-provider', 'injected-arbitrum-one-provider', 'vm-custom-fork', 'vm-goerli-fork', 'vm-mainnet-fork', 'vm-sepolia-fork', 'vm-merge', 'vm-london', 'vm-berlin',
'compileAndRun', 'search', 'recorder', 'fileDecorator', 'codeParser', 'codeFormatter', 'solidityumlgen', 'contractflattener']
// dependentModules shouldn't be manually activated (e.g hardhat is activated by remixd)

@ -77,7 +77,7 @@ module.exports = composePlugins(withNx(), withReact(), (config) => {
enforce: "pre"
})
config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings
config.ignoreWarnings = [/Failed to parse source map/, /require function/ ] // ignore source-map-loader warnings & AST warnings
// set minimizer
config.optimization.minimizer = [
@ -96,5 +96,9 @@ module.exports = composePlugins(withNx(), withReact(), (config) => {
new CssMinimizerPlugin(),
];
config.watchOptions = {
ignored: /node_modules/
}
return config;
});

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

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

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

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

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

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

@ -134,7 +134,18 @@ export class FetchAndCompile extends Plugin {
if (!data) {
setTimeout(_ => this.emit('notFound', contractAddress), 0)
this.unresolvedAddresses.push(contractAddress)
return localCompilation()
const compilation = await localCompilation()
if (compilation) {
let found = false
compilation.visitContracts((contract) => {
found = util.compareByteCode(codeAtAddress, '0x' + contract.object.evm.deployedBytecode.object)
return found
})
if (found) {
await this.call('compilerArtefacts', 'addResolvedContract', contractAddress, compilation)
return compilation
}
}
}
const { settings, compilationTargets } = data

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

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

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

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

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

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

@ -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('-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('-k, --killProcess <bool>', 'kill process when tests fail')
.argument('file_path', 'path to test file or directory')
.action(async (file_path) => {
const options = commander.opts();
@ -131,8 +132,9 @@ commander
await provider.init()
web3.setProvider(provider)
extend(web3)
runTestFiles(path.resolve(file_path), isDirectory, web3, compilerConfig, (error) => {
runTestFiles(path.resolve(file_path), isDirectory, web3, compilerConfig, (error, totalPassing, totalFailing) => {
if (error) process.exit(1)
if (totalFailing > 0 && options.killProcess) process.exit(1)
})
})
@ -140,5 +142,4 @@ if (!process.argv.slice(2).length) {
log.error('Please specify a file or directory path')
process.exit(1)
}
commander.parse(process.argv)

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

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

@ -119,7 +119,7 @@ export class RemixCompletionProvider implements monacoTypes.languages.Completion
// truncate for performance
if (filteredNodes.length > this.maximumItemsForContractCompletion) {
await this.props.plugin.call('notification', 'toast', `Too many completion items. Only ${this.maximumItemsForContractCompletion} items will be shown.`)
// await this.props.plugin.call('notification', 'toast', `Too many completion items. Only ${this.maximumItemsForContractCompletion} items will be shown.`)
filteredNodes = filteredNodes.slice(0, this.maximumItemsForContractCompletion)
}

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

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

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

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

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

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

@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react' //eslint-disable-line
import { CopyToClipboard } from '@remix-ui/clipboard'
import { helper } from '@remix-project/remix-solidity'
import './renderer.css'
interface RendererProps {
@ -77,7 +78,9 @@ export const Renderer = ({ message, opt = {}, plugin }: RendererProps) => {
<div className="close" data-id="renderer" onClick={handleClose}>
<i className="fas fa-times"></i>
</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 { 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
Object.keys(accounts).map((value) => {
plugin.blockchain.getBalanceInEther(value, (err, balance) => {
if (err) return
const updated = shortenAddress(value, balance)
accounts[value] = updated
})
})
for (const account of Object.keys(accounts)) {
const balance = await plugin.blockchain.getBalanceInEther(account)
const updated = shortenAddress(account, balance)
accounts[account] = updated
}
dispatch(fetchAccountsListSuccess(accounts))
}
@ -31,17 +28,10 @@ export const fillAccountsList = async (plugin: RunTab, dispatch: React.Dispatch<
// - all the promises resolve
// - at least one reject
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
await (Promise as any).all(accounts.map((account) => {
return new Promise((resolve, reject) => {
plugin.blockchain.getBalanceInEther(account, (err, balance) => {
if (err) return reject(err)
const updated = shortenAddress(account, balance)
loadedAccounts[account] = updated
resolve(account)
})
})
}))
for (const account of accounts) {
const balance = await plugin.blockchain.getBalanceInEther(account)
loadedAccounts[account] = shortenAddress(account, balance)
}
const provider = plugin.blockchain.getProvider()
if (provider === 'injected') {
@ -59,6 +49,7 @@ export const fillAccountsList = async (plugin: RunTab, dispatch: React.Dispatch<
}
export const setFinalContext = (plugin: RunTab, dispatch: React.Dispatch<any>) => {
dispatch(fetchAccountsListRequest())
// set the final context. Cause it is possible that this is not the one we've originaly selected
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
import { UpgradeableContract } from '../../../../../../node_modules/@openzeppelin/upgrades-core/dist/standalone'
import { DeployMode, MainnetPrompt } from "../types"
import { displayNotification, displayPopUp, fetchProxyDeploymentsSuccess, setDecodedResponse } from "./payload"
import { displayNotification, displayPopUp, fetchProxyDeploymentsSuccess, setDecodedResponse, updateInstancesBalance } from "./payload"
import { addInstance } from "./actions"
import { addressToString, logBuilder } from "@remix-ui/helper"
import Web3 from "web3"
@ -318,14 +318,15 @@ export const getFuncABIInputs = (plugin: RunTab, funcABI: FuncABI) => {
return plugin.blockchain.getInputs(funcABI)
}
export const updateInstanceBalance = (plugin: RunTab) => {
export const updateInstanceBalance = async (plugin: RunTab, dispatch: React.Dispatch<any>) => {
if (plugin.REACT_API?.instances?.instanceList?.length) {
for (const instance of plugin.REACT_API.instances.instanceList) {
plugin.blockchain.getBalanceInEther(instance.address, (err, balInEth) => {
if (!err) instance.balance = balInEth
})
const instances = plugin.REACT_API?.instances?.instanceList
for (const instance of instances) {
const balInEth = await plugin.blockchain.getBalanceInEther(instance.address)
instance.balance = balInEth
}
}
dispatch(updateInstanceBalance(instances, dispatch))
}
}
export const isValidContractAddress = async (plugin: RunTab, address: string) => {

@ -1,13 +1,15 @@
import { envChangeNotification } from "@remix-ui/helper"
import { RunTab } from "../types/run-tab"
import { setExecutionContext, setFinalContext, updateAccountBalances } from "./account"
import { setExecutionContext, setFinalContext, updateAccountBalances, fillAccountsList } from "./account"
import { addExternalProvider, addInstance, addNewProxyDeployment, removeExternalProvider, setNetworkNameFromProvider } from "./actions"
import { addDeployOption, clearAllInstances, clearRecorderCount, fetchContractListSuccess, resetProxyDeployments, resetUdapp, setCurrentContract, setCurrentFile, setLoadType, setRecorderCount, setRemixDActivated, setSendValue } from "./payload"
import { addDeployOption, clearAllInstances, clearRecorderCount, fetchContractListSuccess, resetProxyDeployments, resetUdapp, setCurrentContract, setCurrentFile, setLoadType, setRecorderCount, setRemixDActivated, setSendValue, fetchAccountsListSuccess } from "./payload"
import { updateInstanceBalance } from './deploy'
import { CompilerAbstract } from '@remix-project/remix-solidity'
import BN from 'bn.js'
import Web3 from 'web3'
import { Plugin } from "@remixproject/engine"
import { getNetworkProxyAddresses } from "./deploy"
import { shortenAddress } from "@remix-ui/helper"
const _paq = window._paq = window._paq || []
@ -20,12 +22,15 @@ export const setupEvents = (plugin: RunTab, dispatch: React.Dispatch<any>) => {
if (!lookupOnly) dispatch(setSendValue('0'))
if (error) return
updateAccountBalances(plugin, dispatch)
updateInstanceBalance(plugin, dispatch)
})
plugin.blockchain.event.register('contextChanged', (context, silent) => {
plugin.blockchain.event.register('contextChanged', (context) => {
dispatch(resetProxyDeployments())
if (!context.startsWith('vm')) getNetworkProxyAddresses(plugin, dispatch)
setFinalContext(plugin, dispatch)
fillAccountsList(plugin, dispatch)
updateAccountBalances(plugin, dispatch)
})
plugin.blockchain.event.register('networkStatus', ({ error, network }) => {
@ -117,6 +122,23 @@ export const setupEvents = (plugin: RunTab, dispatch: React.Dispatch<any>) => {
plugin.event.register('cleared', () => {
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?) => {

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

@ -1,5 +1,5 @@
import { ContractData } from '@remix-project/core-plugin'
import { ADD_DEPLOY_OPTION, ADD_INSTANCE, ADD_PROVIDER, CLEAR_INSTANCES, CLEAR_RECORDER_COUNT, DISPLAY_NOTIFICATION, DISPLAY_POPUP_MESSAGE, FETCH_ACCOUNTS_LIST_FAILED, FETCH_ACCOUNTS_LIST_REQUEST, FETCH_ACCOUNTS_LIST_SUCCESS, FETCH_CONTRACT_LIST_FAILED, FETCH_CONTRACT_LIST_REQUEST, FETCH_CONTRACT_LIST_SUCCESS, HIDE_NOTIFICATION, HIDE_POPUP_MESSAGE, REMOVE_DEPLOY_OPTION, REMOVE_INSTANCE, REMOVE_PROVIDER, RESET_STATE, SET_BASE_FEE_PER_GAS, SET_CONFIRM_SETTINGS, SET_CURRENT_CONTRACT, SET_CURRENT_FILE, SET_DECODED_RESPONSE, SET_DEPLOY_OPTIONS, SET_EXECUTION_ENVIRONMENT, SET_EXTERNAL_WEB3_ENDPOINT, SET_GAS_LIMIT, SET_GAS_PRICE, SET_GAS_PRICE_STATUS, SET_IPFS_CHECKED_STATE, SET_LOAD_TYPE, SET_MATCH_PASSPHRASE, SET_MAX_FEE, SET_MAX_PRIORITY_FEE, SET_NETWORK_NAME, SET_PASSPHRASE, SET_PATH_TO_SCENARIO, SET_PERSONAL_MODE, SET_RECORDER_COUNT, SET_SELECTED_ACCOUNT, SET_SEND_UNIT, SET_SEND_VALUE, SET_REMIXD_ACTIVATED, FETCH_PROXY_DEPLOYMENTS, NEW_PROXY_DEPLOYMENT, RESET_PROXY_DEPLOYMENTS } from '../constants'
import { ADD_DEPLOY_OPTION, ADD_INSTANCE, UPDATE_INSTANCES_BALANCE, ADD_PROVIDER, CLEAR_INSTANCES, CLEAR_RECORDER_COUNT, DISPLAY_NOTIFICATION, DISPLAY_POPUP_MESSAGE, FETCH_ACCOUNTS_LIST_FAILED, FETCH_ACCOUNTS_LIST_REQUEST, FETCH_ACCOUNTS_LIST_SUCCESS, FETCH_CONTRACT_LIST_FAILED, FETCH_CONTRACT_LIST_REQUEST, FETCH_CONTRACT_LIST_SUCCESS, HIDE_NOTIFICATION, HIDE_POPUP_MESSAGE, REMOVE_DEPLOY_OPTION, REMOVE_INSTANCE, REMOVE_PROVIDER, RESET_STATE, SET_BASE_FEE_PER_GAS, SET_CONFIRM_SETTINGS, SET_CURRENT_CONTRACT, SET_CURRENT_FILE, SET_DECODED_RESPONSE, SET_DEPLOY_OPTIONS, SET_EXECUTION_ENVIRONMENT, SET_EXTERNAL_WEB3_ENDPOINT, SET_GAS_LIMIT, SET_GAS_PRICE, SET_GAS_PRICE_STATUS, SET_IPFS_CHECKED_STATE, SET_LOAD_TYPE, SET_MATCH_PASSPHRASE, SET_MAX_FEE, SET_MAX_PRIORITY_FEE, SET_NETWORK_NAME, SET_PASSPHRASE, SET_PATH_TO_SCENARIO, SET_PERSONAL_MODE, SET_RECORDER_COUNT, SET_SELECTED_ACCOUNT, SET_SEND_UNIT, SET_SEND_VALUE, SET_REMIXD_ACTIVATED, FETCH_PROXY_DEPLOYMENTS, NEW_PROXY_DEPLOYMENT, RESET_PROXY_DEPLOYMENTS } from '../constants'
import { ContractList, DeployOptions } from '../types'
export const fetchAccountsListRequest = () => {
@ -216,6 +216,13 @@ export const setGasPrice = (price: string) => {
}
}
export const updateInstancesBalance = (instances: Array<{ contractData?: ContractData, address: string, name: string, abi?: any }>) => {
return {
type: UPDATE_INSTANCES_BALANCE,
payload: instances
}
}
export const addNewInstance = (instance: { contractData?: ContractData, address: string, name: string, abi?: any }) => {
return {
type: ADD_INSTANCE,

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

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

@ -1,6 +1,6 @@
import { ContractData } from '@remix-project/core-plugin'
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
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: {
const payload: number = action.payload

@ -60,7 +60,7 @@ export class Blockchain extends Plugin<any, any> {
removeProvider(name: any): void;
/** Listen on New Transaction. (Cannot be done inside constructor because txlistener doesn't exist yet) */
startListening(txlistener: any): void;
resetEnvironment(): void;
resetEnvironment(): Promise<void>;
/**
* Create a VM Account
* @param {{privateKey: string, balance: string}} newAccount The new account to create
@ -71,7 +71,7 @@ export class Blockchain extends Plugin<any, any> {
}): any;
newAccount(_password: any, passwordPromptCb: any, cb: any): any;
/** Get the balance of an address, and convert wei to ether */
getBalanceInEther(address: any, cb: any): void;
getBalanceInEther(address: any): Promise<string>;
pendingTransactionsCount(): number;
/**
* 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;
getAccounts(cb: any): any;
newAccount(passwordPromptCb: any, cb: any): void;
resetEnvironment(): void;
getBalanceInEther(address: any, cb: any): void;
resetEnvironment(): Promise<void>;
getBalanceInEther(address: any): Promise<string>;
getGasPrice(cb: any): void;
signMessage(message: any, account: any, _passphrase: any, cb: any): void;
getProvider(): string;

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

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

@ -3,7 +3,7 @@ import React, { useState, useReducer, useEffect, useCallback } from 'react' // e
import { labels, textDark, textSecondary } from './constants'
import './remix-ui-settings.css'
import { ethereumVM, generateContractMetadat, personal, textWrapEventAction, useMatomoAnalytics, saveTokenToast, removeTokenToast, saveSwarmSettingsToast, saveIpfsSettingsToast, useAutoCompletion, useShowGasInEditor, useDisplayErrors } from './settingsAction'
import { generateContractMetadat, personal, textWrapEventAction, useMatomoAnalytics, saveTokenToast, removeTokenToast, saveSwarmSettingsToast, saveIpfsSettingsToast, useAutoCompletion, useShowGasInEditor, useDisplayErrors } from './settingsAction'
import { initialState, toastInitialState, toastReducer, settingReducer } from './settingsReducer'
import { Toaster } from '@remix-ui/toaster'// eslint-disable-line
import { RemixUiThemeModule, ThemeModule} from '@remix-ui/theme-module'
@ -41,17 +41,14 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
const metadataConfig = props.config.get('settings/generate-contract-metadata')
if (metadataConfig === undefined || metadataConfig === null) generateContractMetadat(props.config, true, dispatch)
const javascriptVM = props.config.get('settings/always-use-vm')
if (javascriptVM === null || javascriptVM === undefined) ethereumVM(props.config, true, dispatch)
const useAutoComplete = props.config.get('settings/auto-completion')
if (useAutoComplete === null || useAutoComplete === undefined) useAutoCompletion(props.config, false, dispatch)
if (useAutoComplete === null || useAutoComplete === undefined) useAutoCompletion(props.config, true, dispatch)
const displayErrors = props.config.get('settings/display-errors')
if (displayErrors === null || displayErrors === undefined) useDisplayErrors(props.config, false, dispatch)
if (displayErrors === null || displayErrors === undefined) useDisplayErrors(props.config, true, dispatch)
const useShowGas = props.config.get('settings/show-gas')
if (useShowGas === null || useShowGas === undefined) useShowGasInEditor(props.config, false, dispatch)
if (useShowGas === null || useShowGas === undefined) useShowGasInEditor(props.config, true, dispatch)
}
useEffect(() => initValue(), [resetState, props.config])
useEffect(() => initValue(), [])
@ -110,10 +107,6 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
generateContractMetadat(props.config, event.target.checked, dispatch)
}
const onchangeOption = (event) => {
ethereumVM(props.config, event.target.checked, dispatch)
}
const textWrapEvent = (event) => {
textWrapEventAction(props.config, props.editor, event.target.checked, dispatch)
}
@ -148,7 +141,6 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
const generalConfig = () => {
const isMetadataChecked = props.config.get('settings/generate-contract-metadata') || false
const isEthereumVMChecked = props.config.get('settings/always-use-vm') || false
const isEditorWrapChecked = props.config.get('settings/text-wrap') || false
const isPersonalChecked = props.config.get('settings/personal-mode') || false
const isMatomoChecked = props.config.get('settings/matomo-analytics') || false
@ -192,12 +184,6 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
<FormattedMessage id='settings.generateContractMetadataText' />
</label>
</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">
<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">

@ -13,11 +13,6 @@ export const generateContractMetadat = (config, checked, dispatch) => {
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) => {
config.set('settings/text-wrap', 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?`,
'Create',
async () => await createNewConfigFile(),
false,
'Cancel',
() => {
setShowFilePathInput(false)
@ -580,6 +581,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
promptMessage('URL'),
'OK',
addCustomCompiler,
false,
'Cancel',
() => {}
)

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

@ -27,6 +27,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
message: null,
okLabel: '',
okFn: () => { },
donotHideOnOkClick: false,
cancelLabel: '',
cancelFn: () => { },
handleHide: null
@ -131,7 +132,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
api.setCompilerParameters({ version: value })
}
const modal = async (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => {
const modal = async (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, donotHideOnOkClick: boolean, cancelLabel?: string, cancelFn?: () => void) => {
await setState(prevState => {
return {
...prevState,
@ -142,6 +143,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
title,
okLabel,
okFn,
donotHideOnOkClick,
cancelLabel,
cancelFn
}
@ -190,7 +192,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
<>
<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 && (compileErrors[currentFile].error.mode === 'panic') && modal('Error', panicMessage(compileErrors[currentFile].error.formattedMessage), 'Close', null)}
{compileErrors[currentFile].error && (compileErrors[currentFile].error.mode === 'panic') && modal('Error', panicMessage(compileErrors[currentFile].error.formattedMessage), 'Close', null, false)}
{compileErrors[currentFile].errors && compileErrors[currentFile].errors.length && compileErrors[currentFile].errors.map((err, index) => {
if (hideWarnings) {
if (err.severity !== 'warning') {
@ -212,6 +214,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
hide={state.modal.hide}
okLabel={state.modal.okLabel}
okFn={state.modal.okFn}
donotHideOnOkClick={state.modal.donotHideOnOkClick}
cancelLabel={state.modal.cancelLabel}
cancelFn={state.modal.cancelFn}
handleHide={handleHideModal}>

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

@ -376,6 +376,21 @@ export const handleDownloadFiles = async () => {
}
}
export const handleDownloadWorkspace = async () => {
try {
const zip = new JSZip()
const workspaceProvider = plugin.fileProviders.workspace
await workspaceProvider.copyFolderToJson('/', ({ path, content }) => {
zip.file(path, content)
})
const blob = await zip.generateAsync({ type: 'blob' })
saveAs(blob, `${workspaceProvider.workspace}.zip`)
} catch (e) {
console.error(e)
plugin.call('notification', 'toast', e.message)
}
}
export const restoreBackupZip = async () => {
await plugin.appManager.activatePlugin(['restorebackupzip'])
await plugin.call('mainPanel', 'showContent', 'restorebackupzip')

@ -4,9 +4,10 @@ import { HamburgerMenuItem } from './workspace-hamburger-item'
export interface HamburgerMenuProps {
createWorkspace: () => void,
renameCurrentWorkspace: () => void,
downloadCurrentWorkspace: () => void,
deleteCurrentWorkspace: () => void,
deleteAllWorkspaces: () => void,
renameCurrentWorkspace: () => void,
cloneGitRepository: () => void,
downloadWorkspaces: () => void,
restoreBackup: () => void,
@ -27,24 +28,27 @@ export function HamburgerMenu (props: HamburgerMenuProps) {
props.createWorkspace()
props.hideIconsMenu(!showIconsMenu)
}}></HamburgerMenuItem>
<HamburgerMenuItem kind='delete' fa='far fa-trash' hideOption={hideWorkspaceOptions || hideLocalhostOptions} actionOnClick={() => {
props.deleteCurrentWorkspace()
props.hideIconsMenu(!showIconsMenu)
}}></HamburgerMenuItem>
<HamburgerMenuItem kind='deleteAll' fa='far fa-trash-alt' hideOption={hideWorkspaceOptions || hideLocalhostOptions} actionOnClick={() => {
props.deleteAllWorkspaces()
<HamburgerMenuItem kind='clone' fa='fab fa-github' hideOption={hideWorkspaceOptions} actionOnClick={() => {
props.cloneGitRepository()
props.hideIconsMenu(!showIconsMenu)
}}></HamburgerMenuItem>
<HamburgerMenuItem kind='rename' fa='far fa-edit' hideOption={hideWorkspaceOptions || hideLocalhostOptions} actionOnClick={() => {
props.renameCurrentWorkspace()
props.hideIconsMenu(!showIconsMenu)
}}></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' }} />
<HamburgerMenuItem kind='clone' fa='fab fa-github' hideOption={hideWorkspaceOptions} actionOnClick={() => {
props.cloneGitRepository()
<HamburgerMenuItem kind='deleteAll' fa='far fa-trash-alt' hideOption={hideWorkspaceOptions || hideLocalhostOptions} actionOnClick={() => {
props.deleteAllWorkspaces()
props.hideIconsMenu(!showIconsMenu)
}}></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={() => {
props.downloadWorkspaces()
props.hideIconsMenu(!showIconsMenu)

@ -33,6 +33,7 @@ export const FileSystemContext = createContext<{
dispatchHandleClickFile: (path: string, type: 'file' | 'folder' | 'gist') => Promise<void>
dispatchHandleExpandPath: (paths: string[]) => Promise<void>,
dispatchHandleDownloadFiles: () => Promise<void>,
dispatchHandleDownloadWorkspace: () => Promise<void>,
dispatchHandleRestoreBackup: () => Promise<void>
dispatchCloneRepository: (url: 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 { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, deleteAllWorkspaces, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder,
deletePath, renamePath, downloadPath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace,
fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, uploadFolder, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder,
fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, uploadFolder, handleDownloadWorkspace, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder,
showAllBranches, switchBranch, createNewBranch, checkoutRemoteBranch, createSolidityGithubAction, createTsSolGithubAction, createSlitherGithubAction
} from '../actions'
import { Modal, WorkspaceProps, WorkspaceTemplate } from '../types'
@ -135,6 +135,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
await handleDownloadFiles()
}
const dispatchHandleDownloadWorkspace = async () => {
await handleDownloadWorkspace()
}
const dispatchHandleRestoreBackup = async () => {
await restoreBackupZip()
}
@ -284,6 +288,7 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
dispatchHandleClickFile,
dispatchHandleExpandPath,
dispatchHandleDownloadFiles,
dispatchHandleDownloadWorkspace,
dispatchHandleRestoreBackup,
dispatchCloneRepository,
dispatchMoveFile,

@ -76,6 +76,9 @@ export function Workspace () {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.rename' }), renameModalMessage(), intl.formatMessage({ id: 'filePanel.ok' }), onFinishRenameWorkspace, intl.formatMessage({ id: 'filePanel.cancel' }))
}
const downloadCurrentWorkspace = () => {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.download' }), intl.formatMessage({ id: 'filePanel.workspace.downloadConfirm' }), intl.formatMessage({ id: 'filePanel.ok' }), onFinishDownloadWorkspace, intl.formatMessage({ id: 'filePanel.cancel' }))
}
const createWorkspace = () => {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.create' }), createModalMessage(), intl.formatMessage({ id: 'filePanel.ok' }), onFinishCreateWorkspace, intl.formatMessage({ id: 'filePanel.cancel' }))
}
@ -156,6 +159,15 @@ export function Workspace () {
}
}
const onFinishDownloadWorkspace = async () => {
try {
await global.dispatchHandleDownloadWorkspace()
} catch (e) {
global.modal(intl.formatMessage({ id: 'filePanel.workspace.download' }), e.message, intl.formatMessage({ id: 'filePanel.ok' }), () => {}, intl.formatMessage({ id: 'filePanel.cancel' }))
console.error(e)
}
}
const onFinishCreateWorkspace = async () => {
if (workspaceCreateInput.current === undefined) return
// @ts-ignore: Object is possibly 'null'.
@ -453,9 +465,10 @@ export function Workspace () {
<Dropdown.Menu as={CustomMenu} data-id="wsdropdownMenu" className='custom-dropdown-items remixui_menuwidth' rootCloseEvent="click">
<HamburgerMenu
createWorkspace={createWorkspace}
renameCurrentWorkspace={renameCurrentWorkspace}
downloadCurrentWorkspace={downloadCurrentWorkspace}
deleteCurrentWorkspace={deleteCurrentWorkspace}
deleteAllWorkspaces={deleteAllWorkspaces}
renameCurrentWorkspace={renameCurrentWorkspace}
cloneGitRepository={cloneGitRepository}
downloadWorkspaces={downloadWorkspaces}
restoreBackup={restoreBackup}

@ -11,10 +11,17 @@ jobs:
- name: Checkout
uses: actions/checkout@v2
- name: Run SUT Action
uses: EthereumRemix/sol-test@v1
uses: EthereumRemix/sol-test@v1.1
with:
test-path: 'tests'
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 = `
name: Running Mocha Chai Solidity Unit Tests
@ -28,11 +35,17 @@ jobs:
- name: Checkout
uses: actions/checkout@v2
- name: Run Mocha Chai Unit Test Action
uses: EthereumRemix/ts-sol-test@v1.2
uses: EthereumRemix/ts-sol-test@v1.3.1
with:
test-path: 'tests'
contract-path: 'contracts'
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 = `
name: Slither Analysis

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

@ -1,6 +1,6 @@
{
"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",
"main": "src/index.js",
"types": "src/index.d.ts",
@ -24,5 +24,5 @@
"ethers": "^5.4.2",
"web3": "^1.5.1"
},
"gitHead": "4ea0d9afb03f04df480fdc57a60b8f85b771ed7c"
"gitHead": "4806543bb099b558872793ca7a215468e0bffc81"
}

@ -5936,16 +5936,16 @@
"@types/estree" "*"
"@types/json-schema" "*"
"@types/estree@*", "@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/estree@^0.0.51":
"@types/estree@*", "@types/estree@^0.0.51":
version "0.0.51"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40"
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":
version "4.17.31"
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"
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"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73"
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:
version "0.4.16"
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"
electron-to-chromium "^1.3.47"
browserslist@^4.0.0, browserslist@^4.16.6:
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:
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.21.4"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987"
integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==
@ -9266,7 +9250,7 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2"
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"
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001426.tgz"
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"
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:
version "1.4.264"
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:
once "^1.4.0"
enhanced-resolve@^5.0.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:
enhanced-resolve@^5.0.0, enhanced-resolve@^5.10.0, enhanced-resolve@^5.7.0:
version "5.10.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6"
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"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
events@3.2.0, events@^3.0.0:
events@3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379"
integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==
@ -12539,7 +12510,7 @@ events@^2.0.0:
resolved "https://registry.yarnpkg.com/events/-/events-2.1.0.tgz#2a9a1e18e6106e0e812aa9ebd4a819b3c29c0ba5"
integrity sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==
events@^3.2.0:
events@^3.0.0, events@^3.2.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
@ -14342,21 +14313,16 @@ got@^9.6.0:
to-readable-stream "^1.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:
version "4.2.8"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
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.10"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
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"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
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:
version "1.0.4"
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"
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:
version "1.52.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-db@~1.26.0:
version "1.26.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.26.0.tgz#eaffcd0e4fc6935cf8134da246e2e6c35305adff"
integrity sha1-6v/NDk/Gk1z4E02iRuLmw1MFrf8=
mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24:
version "2.1.34"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24"
integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==
dependencies:
mime-db "1.51.0"
"mime-db@>= 1.43.0 < 2":
version "1.51.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c"
integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==
mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.34:
mime-types@^2.1.12, mime-types@^2.1.16, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34, mime-types@~2.1.7:
version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
mime-types@~2.1.7:
version "2.1.14"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.14.tgz#f7ef7d97583fcaf3b7d282b6f8b5679dab1e94ee"
integrity sha1-9+99l1g/yvO30oK2+LVnnaselO4=
dependencies:
mime-db "~1.26.0"
mime@1.6.0, mime@^1.4.1, mime@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
@ -19177,11 +19124,6 @@ node-notifier@^4.2.3:
shellwords "^0.1.0"
which "^1.0.5"
node-releases@^1.1.77:
version "1.1.77"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.77.tgz#50b0cfede855dd374e7585bf228ff34e57c1c32e"
integrity sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==
node-releases@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503"
@ -20712,11 +20654,6 @@ performance-now@^2.1.0:
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
picocolors@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f"
integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==
picocolors@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
@ -26267,9 +26204,9 @@ webpack-subresource-integrity@^5.1.0:
typed-assert "^1.0.8"
webpack@^5.75.0:
version "5.75.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.75.0.tgz#1e440468647b2505860e94c9ff3e44d5b582c152"
integrity sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==
version "5.76.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c"
integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==
dependencies:
"@types/eslint-scope" "^3.7.3"
"@types/estree" "^0.0.51"

Loading…
Cancel
Save