- ${displayName}
- ${versionWarning}
+
+ ${displayName}
+ ${doclink}
+ ${versionWarning}
+
${activationButton}
See the Remixd tutorial for more info. +
remixd -s absolute-path-to-the-shared-folder --remix-ide your-remix-ide-URL-instance + ${copyToClipboard(() => commandText)}
here it is: -
remixd -s absolute-path-to-the-shared-folder --remix-ide your-remix-ide-URL-instance +
To see that a connection has been made, check that there is a localhost section in the Files Explorer
Before using, make sure you have the latest remixd version.
Read here how to update it
') + val = el.children.length === 0 ? el.firstChild : el + } if (types[idx] === 'element') val = jsbeautify.html(val) return val }) diff --git a/apps/remix-ide/src/app/tabs/compile-tab.js b/apps/remix-ide/src/app/tabs/compile-tab.js index 12b93ff594..8bb5b48575 100644 --- a/apps/remix-ide/src/app/tabs/compile-tab.js +++ b/apps/remix-ide/src/app/tabs/compile-tab.js @@ -65,15 +65,10 @@ class CompileTab extends ViewPlugin { eventHandlers: {}, loading: false } + this.compileTabLogic = new CompileTabLogic(this.queryParams, this.fileManager, this.editor, this.config, this.fileProvider, this.contentImport) } onActivationInternal () { - const miscApi = { - clearAnnotations: () => { - this.call('editor', 'clearAnnotations') - } - } - this.compileTabLogic = new CompileTabLogic(this.queryParams, this.fileManager, this.editor, this.config, this.fileProvider, this.contentImport, miscApi) this.compiler = this.compileTabLogic.compiler this.compileTabLogic.init() @@ -85,11 +80,28 @@ class CompileTab extends ViewPlugin { ) } + resetResults () { + if (this._view.errorContainer) { + this._view.errorContainer.innerHTML = '' + } + this.compilerContainer.currentFile = '' + this.data.contractsDetails = {} + yo.update(this._view.contractSelection, this.contractSelection()) + this.emit('statusChanged', { key: 'none' }) + } + /************ * EVENTS */ listenToEvents () { + this.on('filePanel', 'setWorkspace', (workspace) => { + this.compileTabLogic.isHardhatProject().then((result) => { + if (result && workspace.isLocalhost) this.compilerContainer.hardhatCompilation.style.display = 'flex' + else this.compilerContainer.hardhatCompilation.style.display = 'none' + }) + }) + this.data.eventHandlers.onContentChanged = () => { this.emit('statusChanged', { key: 'edited', title: 'the content has changed, needs recompilation', type: 'info' }) } @@ -113,6 +125,9 @@ class CompileTab extends ViewPlugin { } this.emit('statusChanged', { key: 'loading', title: 'compiling...', type: 'info' }) } + + this.on('filePanel', 'setWorkspace', () => this.resetResults()) + this.compileTabLogic.event.on('startingCompilation', this.data.eventHandlers.onStartingCompilation) this.data.eventHandlers.onCurrentFileChanged = (name) => { @@ -199,7 +214,7 @@ class CompileTab extends ViewPlugin { // ctrl+s or command+s if ((e.metaKey || e.ctrlKey) && e.keyCode === 83) { e.preventDefault() - this.compileTabLogic.runCompiler() + this.compileTabLogic.runCompiler(this.compilerContainer.hhCompilation) } }) } @@ -479,6 +494,7 @@ class CompileTab extends ViewPlugin { } onActivation () { + this.call('manager', 'activatePlugin', 'solidity-logic') this.listenToEvents() } @@ -492,6 +508,7 @@ class CompileTab extends ViewPlugin { this.fileManager.events.removeListener('noFileSelected', this.data.eventHandlers.onNoFileSelected) this.compiler.event.unregister('compilationFinished', this.data.eventHandlers.onCompilationFinished) globalRegistry.get('themeModule').api.events.removeListener('themeChanged', this.data.eventHandlers.onThemeChanged) + this.call('manager', 'deactivatePlugin', 'solidity-logic') } } diff --git a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js index 79228d1663..33deec9dc7 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compileTab.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compileTab.js @@ -1,10 +1,19 @@ +import * as packageJson from '../../../../../../package.json' +import { Plugin } from '@remixproject/engine' const EventEmitter = require('events') var Compiler = require('@remix-project/remix-solidity').Compiler -class CompileTab { - constructor (queryParams, fileManager, editor, config, fileProvider, contentImport, miscApi) { +const profile = { + name: 'solidity-logic', + displayName: 'Solidity compiler logic', + description: 'Compile solidity contracts - Logic', + version: packageJson.version +} + +class CompileTab extends Plugin { + constructor (queryParams, fileManager, editor, config, fileProvider, contentImport) { + super(profile) this.event = new EventEmitter() - this.miscApi = miscApi this.queryParams = queryParams this.compilerImport = contentImport this.compiler = new Compiler((url, cb) => this.compilerImport.resolveAndSave(url).then((result) => cb(null, result)).catch((error) => cb(error.message))) @@ -78,10 +87,38 @@ class CompileTab { }) } - runCompiler () { + async isHardhatProject () { + if (this.fileManager.mode === 'localhost') { + return await this.fileManager.exists('hardhat.config.js') + } else return false + } + + runCompiler (hhCompilation) { try { + if (this.fileManager.mode === 'localhost' && hhCompilation) { + const { currentVersion, optimize, runs } = this.compiler.state + if (currentVersion) { + const fileContent = `module.exports = { + solidity: '${currentVersion.substring(0, currentVersion.indexOf('+commit'))}', + settings: { + optimizer: { + enabled: ${optimize}, + runs: ${runs} + } + } + } + ` + const configFilePath = 'remix-compiler.config.js' + this.fileManager.setFileContent(configFilePath, fileContent) + this.call('hardhat', 'compile', configFilePath).then((result) => { + this.call('terminal', 'log', { type: 'info', value: result }) + }).catch((error) => { + this.call('terminal', 'log', { type: 'error', value: error }) + }) + } + } this.fileManager.saveCurrentFile() - this.miscApi.clearAnnotations() + this.call('editor', 'clearAnnotations') var currentFile = this.config.get('currentFile') return this.compileFile(currentFile) } catch (err) { diff --git a/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js b/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js index f64cdead77..6c09d0586e 100644 --- a/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js +++ b/apps/remix-ide/src/app/tabs/compileTab/compilerContainer.js @@ -15,6 +15,7 @@ class CompilerContainer { this.editor = editor this.config = config this.queryParams = queryParams + this.hhCompilation = false this.data = { hideWarnings: config.get('hideWarnings') || false, @@ -23,7 +24,7 @@ class CompilerContainer { timeout: 300, allversions: null, selectedVersion: null, - defaultVersion: 'soljson-v0.8.1+commit.df193b15.js' // this default version is defined: in makeMockCompiler (for browser test) + defaultVersion: 'soljson-v0.8.4+commit.c7e474f2.js' // this default version is defined: in makeMockCompiler (for browser test) } } @@ -183,6 +184,10 @@ class CompilerContainer { } }) + this.hardhatCompilation = yo` ` this._view.warnCompilationSlow = yo`` this._view.compileIcon = yo`` this._view.autoCompile = yo` this.updateAutoCompile()} data-id="compilerContainerAutoCompile" id="autoCompile" type="checkbox" title="Auto compile">` @@ -299,6 +304,7 @@ class CompilerContainer {
+ For more info, visit: Hardhat Documentation +
+ Hardhat JSON-RPC Endpoint +
A checksummed address is an address that contains uppercase letters, as specified in EIP-55. +
Checksummed addresses are meant to help prevent users from sending transactions to the wrong address. + `) + address = ethJSUtil.toChecksumAddress(address) + } this.dropdownLogic.loadContractFromAddress(address, (cb) => { - modalDialogCustom.confirm(null, 'Do you really want to interact with ' + address + ' using the current ABI definition?', cb) + modalDialogCustom.confirm('At Address', `Do you really want to interact with ${address} using the current ABI definition?`, cb) }, (error, loadType, abi) => { if (error) { diff --git a/apps/remix-ide/src/app/tabs/runTab/model/dropdownlogic.js b/apps/remix-ide/src/app/tabs/runTab/model/dropdownlogic.js index 15764a6dbe..2ee225fef3 100644 --- a/apps/remix-ide/src/app/tabs/runTab/model/dropdownlogic.js +++ b/apps/remix-ide/src/app/tabs/runTab/model/dropdownlogic.js @@ -55,7 +55,7 @@ class DropdownLogic { cb(null, 'abi', abi) }) } else { - _paq.push(['trackEvent', 'udapp', 'AtAddressLoadWithInstance']) + _paq.push(['trackEvent', 'udapp', 'AtAddressLoadWithArtifacts']) cb(null, 'instance') } } diff --git a/apps/remix-ide/src/app/tabs/runTab/model/recorder.js b/apps/remix-ide/src/app/tabs/runTab/model/recorder.js index 126b354927..f9a5d9aa78 100644 --- a/apps/remix-ide/src/app/tabs/runTab/model/recorder.js +++ b/apps/remix-ide/src/app/tabs/runTab/model/recorder.js @@ -63,10 +63,10 @@ class Recorder { } }) - this.blockchain.event.register('transactionExecuted', (error, from, to, data, call, txResult, timestamp, _payload, rawAddress) => { + this.blockchain.event.register('transactionExecuted', (error, from, to, data, call, txResult, timestamp, _payload) => { if (error) return console.log(error) if (call) return - + const rawAddress = txResult.receipt.contractAddress if (!rawAddress) return // not a contract creation const address = helper.addressToString(rawAddress) // save back created addresses for the convertion from tokens to real adresses diff --git a/apps/remix-ide/src/app/tabs/runTab/settings.js b/apps/remix-ide/src/app/tabs/runTab/settings.js index c4ee816bc8..dd726c09be 100644 --- a/apps/remix-ide/src/app/tabs/runTab/settings.js +++ b/apps/remix-ide/src/app/tabs/runTab/settings.js @@ -1,3 +1,4 @@ +import { BN } from 'ethereumjs-util' const $ = require('jquery') const yo = require('yo-yo') const remixLib = require('@remix-project/remix-lib') @@ -65,14 +66,26 @@ class SettingsUI { validateValue () { const valueEl = this.el.querySelector('#value') - valueEl.value = parseInt(valueEl.value) - // assign 0 if given value is - // - empty - // - not valid (for ex 4345-54) - // - contains only '0's (for ex 0000) copy past or edit - if (!valueEl.value) valueEl.value = 0 + if (!valueEl.value) { + // assign 0 if given value is + // - empty + valueEl.value = 0 + return + } + + let v + try { + v = new BN(valueEl.value, 10) + valueEl.value = v.toString(10) + } catch (e) { + // assign 0 if given value is + // - not valid (for ex 4345-54) + // - contains only '0's (for ex 0000) copy past or edit + valueEl.value = 0 + } + // if giveen value is negative(possible with copy-pasting) set to 0 - if (valueEl.value < 0) valueEl.value = 0 + if (v.lt(0)) valueEl.value = 0 } render () { @@ -84,7 +97,7 @@ class SettingsUI { Environment