pull/4877/head
Your Name 5 months ago
commit ccd38c444a
  1. 10
      apps/remix-ide-e2e/src/tests/etherscan_api.test.ts
  2. 17
      apps/remix-ide-e2e/src/tests/runAndDeploy_injected.test.ts
  3. 169
      apps/remix-ide-e2e/src/tests/terminal.test.ts
  4. 3
      apps/remix-ide/src/app/tabs/locales/en/filePanel.json
  5. 8
      libs/ghaction-helper/package.json
  6. 8
      libs/remix-analyzer/package.json
  7. 6
      libs/remix-astwalker/package.json
  8. 12
      libs/remix-debug/package.json
  9. 4
      libs/remix-lib/package.json
  10. 7
      libs/remix-simulator/package.json
  11. 6
      libs/remix-solidity/package.json
  12. 10
      libs/remix-tests/package.json
  13. 18
      libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts
  14. 15
      libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
  15. 2
      libs/remix-ui/helper/src/lib/components/custom-dropdown.tsx
  16. 2
      libs/remix-ui/home-tab/src/lib/components/homeTabFeatured.tsx
  17. 4
      libs/remix-ui/workspace/src/lib/css/remix-ui-workspace.css
  18. 201
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
  19. 4
      libs/remix-url-resolver/package.json
  20. 4
      libs/remix-ws-templates/package.json
  21. 4
      libs/remixd/package.json

@ -6,7 +6,7 @@ declare global {
interface Window { testplugin: { name: string, url: string }; }
}
module.exports = {
const tests = {
'@disabled': true,
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done, null)
@ -58,6 +58,14 @@ module.exports = {
}
}
const branch = process.env.CIRCLE_BRANCH;
const isMasterBranch = branch === 'master';
module.exports = {
...(branch ? (isMasterBranch ? tests : {}) : tests),
};
const verifiedContract = `
// SPDX-License-Identifier: GPL-3.0

@ -25,7 +25,7 @@ const checkAlerts = function (browser: NightwatchBrowser){
})
}
module.exports = {
const tests = {
'@disabled': true,
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done)
@ -50,10 +50,10 @@ module.exports = {
.pause(5000)
.switchBrowserWindow(extension_url, 'MetaMask', (browser) => {
browser
.waitForElementVisible('*[data-testid="page-container-footer-next"]')
.waitForElementVisible('*[data-testid="page-container-footer-next"]', 60000)
.click('*[data-testid="page-container-footer-next"]') // this connects the metamask account to remix
.pause(2000)
.waitForElementVisible('*[data-testid="page-container-footer-next"]')
.waitForElementVisible('*[data-testid="page-container-footer-next"]', 60000)
.click('*[data-testid="page-container-footer-next"]')
// .waitForElementVisible('*[data-testid="popover-close"]')
// .click('*[data-testid="popover-close"]')
@ -162,7 +162,7 @@ module.exports = {
.perform((done) => {
browser.switchBrowserWindow(extension_url, 'MetaMask', (browser) => {
browser
.waitForElementPresent('[data-testid="page-container-footer-next"]')
.waitForElementPresent('[data-testid="page-container-footer-next"]', 60000)
.click('[data-testid="page-container-footer-next"]') // approve the tx
.switchBrowserTab(0) // back to remix
.waitForElementContainsText('*[data-id="terminalJournal"]', 'view on etherscan', 60000)
@ -177,7 +177,7 @@ module.exports = {
.perform((done) => { // call delegate
browser.switchBrowserWindow(extension_url, 'MetaMask', (browser) => {
browser
.waitForElementPresent('[data-testid="page-container-footer-next"]')
.waitForElementPresent('[data-testid="page-container-footer-next"]', 60000)
.click('[data-testid="page-container-footer-next"]') // approve the tx
.switchBrowserTab(0) // back to remix
.waitForElementContainsText('*[data-id="terminalJournal"]', 'view on etherscan', 60000)
@ -232,6 +232,13 @@ module.exports = {
}
}
const branch = process.env.CIRCLE_BRANCH;
const isMasterBranch = branch === 'master';
module.exports = {
...(branch ? (isMasterBranch ? tests : {}) : tests),
};
const localsCheck = {
to: {
value: '0x4B0897B0513FDC7C541B6D9D7E929C4E5364D2DB',

@ -2,6 +2,10 @@
import { NightwatchBrowser } from 'nightwatch'
import init from '../helpers/init'
const branch = process.env.CIRCLE_BRANCH;
const isMasterBranch = branch === 'master';
const runMasterTests: boolean = (branch ? (isMasterBranch ? true : false) : true)
module.exports = {
'@disabled': true,
before: function (browser: NightwatchBrowser, done: VoidFunction) {
@ -209,26 +213,27 @@ module.exports = {
},
'Should run a script which log transaction and block using web3.js and ethers #group7': function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('udapp')
.switchEnvironment('basic-http-provider')
.waitForElementPresent('[data-id="basic-http-provider-modal-footer-ok-react"]')
.execute(() => {
(document.querySelector('*[data-id="basic-http-providerModalDialogContainer-react"] input[data-id="modalDialogCustomPromp"]') as any).focus()
}, [], () => { })
.setValue('[data-id="modalDialogCustomPromp"]', 'https://go.getblock.io/ee42d0a88f314707be11dd799b122cb9')
.modalFooterOKClick('basic-http-provider')
.clickLaunchIcon('filePanel')
.openFile('README.txt')
.addFile('scripts/log_tx_block.js', { content: scriptBlockAndTransaction })
.pause(1000)
.executeScriptInTerminal('remix.execute(\'scripts/log_tx_block.js\')')
// check if the input of the transaction is being logged (web3 call)
.waitForElementContainsText('*[data-id="terminalJournal"]', '0x2b0006fa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e9e0000000000000000000000000000000000000000000000000000000000004ea373ded44d6900b8b479935bee9c82176261653e334586e0fd282f569357c0777bd9d084474837ac94bf96f2e26590222a2b8e46545657c7cf06ce2833d267bd6f131b5b3fd36cb1ca3e07cf422224df0766d1a677bbdb7ee4cc0d634efa5367a302a94dac422a16b9b8d5c10fe0555924f8189f6b498bef507b1d32e7915bd4df184f51e6d79ae6a1b11d5745ce7d625cecc3bd0dc50af4f999ffb927225f5e5c019b499f5e1fdcbc70c45df61df76013d1b0d45cdf6a267dac1b4620c0db2efd251f6548509c9c69f5bd9d1ee38ac0df0c73be2774f7d2e1fb7ef5129010f29d091e3c48aed0f035fc29804c99927d33ff2a19ff526979355ac50b2542bc5d8f2d41e4f850d5981e0420807469e828b03173b96b757fbaeacda335e11b3ab8b02a48456fab35d41ca26abde751d5fca8ef5e7ba5295278b6e46ce2aab6c10b3d185a6137d3e5c28bb8dd3a797feaf35520fcb949ea074e1869e0011ef01f8162135e44bb797d3d6215ff74ffbee972c97264fc15d11c840e6a7e796dc1a418572f6dbcc842594a558e1a9e3cb7a159284e16fec758bbc303d13edc28fb6d8bb110c3a398e4ded1748da9854eb84679ad0c99bc59bea7956b521db3ed0a9057510cc11365858704989690f0d891af81b213b1f2e91e41e4998a467656eac87e7025ac2840c17f2b106df7d32a0139036bdf5d87344ca37e9ce770e0dbeb5e021d03a7d496a6695eb06d3de9258b43f3883ce155767962b52083504b19d6d609090a2f96e9724902bf1adbf57359ac1dda48a8ffe596b8d95cac1429378769a6ec2ff1c8a9c0bc343b0a6468f36696bfb202cde9f6cd5241b814096d777751b44f0cc2ac9e7ba142227e8d5f2dd8da62573953540da1abce82c59287b2f7a87a111851758c2505d8c1ded6c42a49fc5577451ee56126d2275da490baa645c3bcac0c31dabee7aa35e6cdffb56ac0d952c2583c6f50f906dfb96f5a98c49a5919031cff880bffbe371a50162a7bd0fa0398a5898eaf6ad6db868a7d807846a3592325bb4207d67ad96bac76435368962ba8944d0201c2f620fb29373a6f35c815d101af98111e9b4cc61e8ae77fc63ce375068328ec8d05b49486666fb0f756f99d2fe747c95b2a553965f304a324879393897315d310841f0a200cd156f6ca4ed2', 120000)
// check if the logsBloom is being logged (web3 call)
.waitForElementContainsText('*[data-id="terminalJournal"]', '0x0fbbd94c448fe6949f848380a1d145a974f386624b4b10aa40f9afb212b3ddeb', 120000) // hash of 4757766
// check if the logsBloom is being logged (ethers.js call)
.waitForElementContainsText('*[data-id="terminalJournal"]', '0x9db899cb75888a630ba50a1644c243b83d2eb38525eb828a06a5e8bb5663c0b0', 120000) // hash of 4757767
if (runMasterTests)
browser
.clickLaunchIcon('udapp')
.switchEnvironment('basic-http-provider')
.waitForElementPresent('[data-id="basic-http-provider-modal-footer-ok-react"]')
.execute(() => {
(document.querySelector('*[data-id="basic-http-providerModalDialogContainer-react"] input[data-id="modalDialogCustomPromp"]') as any).focus()
}, [], () => { })
.setValue('[data-id="modalDialogCustomPromp"]', 'https://go.getblock.io/ee42d0a88f314707be11dd799b122cb9')
.modalFooterOKClick('basic-http-provider')
.clickLaunchIcon('filePanel')
.openFile('README.txt')
.addFile('scripts/log_tx_block.js', { content: scriptBlockAndTransaction })
.pause(1000)
.executeScriptInTerminal('remix.execute(\'scripts/log_tx_block.js\')')
// check if the input of the transaction is being logged (web3 call)
.waitForElementContainsText('*[data-id="terminalJournal"]', '0x2b0006fa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e9e0000000000000000000000000000000000000000000000000000000000004ea373ded44d6900b8b479935bee9c82176261653e334586e0fd282f569357c0777bd9d084474837ac94bf96f2e26590222a2b8e46545657c7cf06ce2833d267bd6f131b5b3fd36cb1ca3e07cf422224df0766d1a677bbdb7ee4cc0d634efa5367a302a94dac422a16b9b8d5c10fe0555924f8189f6b498bef507b1d32e7915bd4df184f51e6d79ae6a1b11d5745ce7d625cecc3bd0dc50af4f999ffb927225f5e5c019b499f5e1fdcbc70c45df61df76013d1b0d45cdf6a267dac1b4620c0db2efd251f6548509c9c69f5bd9d1ee38ac0df0c73be2774f7d2e1fb7ef5129010f29d091e3c48aed0f035fc29804c99927d33ff2a19ff526979355ac50b2542bc5d8f2d41e4f850d5981e0420807469e828b03173b96b757fbaeacda335e11b3ab8b02a48456fab35d41ca26abde751d5fca8ef5e7ba5295278b6e46ce2aab6c10b3d185a6137d3e5c28bb8dd3a797feaf35520fcb949ea074e1869e0011ef01f8162135e44bb797d3d6215ff74ffbee972c97264fc15d11c840e6a7e796dc1a418572f6dbcc842594a558e1a9e3cb7a159284e16fec758bbc303d13edc28fb6d8bb110c3a398e4ded1748da9854eb84679ad0c99bc59bea7956b521db3ed0a9057510cc11365858704989690f0d891af81b213b1f2e91e41e4998a467656eac87e7025ac2840c17f2b106df7d32a0139036bdf5d87344ca37e9ce770e0dbeb5e021d03a7d496a6695eb06d3de9258b43f3883ce155767962b52083504b19d6d609090a2f96e9724902bf1adbf57359ac1dda48a8ffe596b8d95cac1429378769a6ec2ff1c8a9c0bc343b0a6468f36696bfb202cde9f6cd5241b814096d777751b44f0cc2ac9e7ba142227e8d5f2dd8da62573953540da1abce82c59287b2f7a87a111851758c2505d8c1ded6c42a49fc5577451ee56126d2275da490baa645c3bcac0c31dabee7aa35e6cdffb56ac0d952c2583c6f50f906dfb96f5a98c49a5919031cff880bffbe371a50162a7bd0fa0398a5898eaf6ad6db868a7d807846a3592325bb4207d67ad96bac76435368962ba8944d0201c2f620fb29373a6f35c815d101af98111e9b4cc61e8ae77fc63ce375068328ec8d05b49486666fb0f756f99d2fe747c95b2a553965f304a324879393897315d310841f0a200cd156f6ca4ed2', 120000)
// check if the logsBloom is being logged (web3 call)
.waitForElementContainsText('*[data-id="terminalJournal"]', '0x0fbbd94c448fe6949f848380a1d145a974f386624b4b10aa40f9afb212b3ddeb', 120000) // hash of 4757766
// check if the logsBloom is being logged (ethers.js call)
.waitForElementContainsText('*[data-id="terminalJournal"]', '0x9db899cb75888a630ba50a1644c243b83d2eb38525eb828a06a5e8bb5663c0b0', 120000) // hash of 4757767
},
'Should listen on all transactions #group8': function (browser: NightwatchBrowser) {
@ -291,46 +296,48 @@ module.exports = {
},
'Should connect to mainnet fork and run web3.eth.getCode in the terminal #group9': function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('udapp')
.switchEnvironment('vm-mainnet-fork')
.waitForElementPresent({
locateStrategy: 'css selector',
selector: 'select[data-id="runTabSelectAccount"] option[value="0xdD870fA1b7C4700F2BD7f44238821C26f7392148"]',
timeout: 240000
})
.executeScriptInTerminal(`web3.eth.getCode('0x180587b00c8642e2c7ac3a758712d97e6f7bdcc7')`) // mainnet contract
.waitForElementContainsText('*[data-id="terminalJournal"]', '0x608060405260043610601f5760003560e01c80635c60da1b14603157602b565b36602b576029605f565b005b6029605f565b348015603c57600080fd5b5060436097565b6040516001600160a01b03909116815260200160405180910390f35b609560917f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b60d1565b565b600060c97f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b90565b3660008037600080366000845af43d6000803e80801560ef573d6000f35b3d6000fdfea2646970667358221220969dbb4b1d8aec2bb348e26488dc1a33b6bcf0190f567d161312ab7ca9193d8d64736f6c63430008110033', 120000)
.click('*[data-id="terminalClearConsole"]')
if (runMasterTests)
browser
.clickLaunchIcon('udapp')
.switchEnvironment('vm-mainnet-fork')
.waitForElementPresent({
locateStrategy: 'css selector',
selector: 'select[data-id="runTabSelectAccount"] option[value="0xdD870fA1b7C4700F2BD7f44238821C26f7392148"]',
timeout: 240000
})
.executeScriptInTerminal(`web3.eth.getCode('0x180587b00c8642e2c7ac3a758712d97e6f7bdcc7')`) // mainnet contract
.waitForElementContainsText('*[data-id="terminalJournal"]', '0x608060405260043610601f5760003560e01c80635c60da1b14603157602b565b36602b576029605f565b005b6029605f565b348015603c57600080fd5b5060436097565b6040516001600160a01b03909116815260200160405180910390f35b609560917f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b60d1565b565b600060c97f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b90565b3660008037600080366000845af43d6000803e80801560ef573d6000f35b3d6000fdfea2646970667358221220969dbb4b1d8aec2bb348e26488dc1a33b6bcf0190f567d161312ab7ca9193d8d64736f6c63430008110033', 120000)
.click('*[data-id="terminalClearConsole"]')
},
'Should connect to the sepolia fork and run web3.eth.getCode in the terminal #group9': function (browser: NightwatchBrowser) {
browser
.switchEnvironment('vm-custom-fork')
.waitForElementVisible('[data-id="vm-custom-fork-modal-footer-ok-react"]')
.execute(() => {
(document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkNodeUrl"]') as any).focus()
}, [], () => { })
.clearValue('*[data-id="CustomForkNodeUrl"]').pause(1000).setValue('*[data-id="CustomForkNodeUrl"]', 'https://go.getblock.io/ee42d0a88f314707be11dd799b122cb9')
.execute(() => {
(document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkBlockNumber"]') as any).focus()
}, [], () => { })
.clearValue('*[data-id="CustomForkBlockNumber"]').setValue('*[data-id="CustomForkBlockNumber"]', 'latest')
.execute(() => {
(document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkEvmType"]') as any).focus()
}, [], () => { })
.click('*[data-id="CustomForkEvmType"] [value="cancun"]')
.pause(5000)
.modalFooterOKClick('vm-custom-fork')
.waitForElementPresent({
locateStrategy: 'css selector',
selector: 'select[data-id="runTabSelectAccount"] option[value="0xdD870fA1b7C4700F2BD7f44238821C26f7392148"]',
timeout: 240000
})
.pause(5000)
.executeScriptInTerminal(`web3.eth.getCode('0x75F509A4eDA030470272DfBAf99A47D587E76709')`) // sepolia contract
.waitForElementContainsText('*[data-id="terminalJournal"]', byteCodeInSepolia, 120000)
.click('*[data-id="terminalClearConsole"]')
if (runMasterTests)
browser
.switchEnvironment('vm-custom-fork')
.waitForElementVisible('[data-id="vm-custom-fork-modal-footer-ok-react"]')
.execute(() => {
(document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkNodeUrl"]') as any).focus()
}, [], () => { })
.clearValue('*[data-id="CustomForkNodeUrl"]').pause(1000).setValue('*[data-id="CustomForkNodeUrl"]', 'https://go.getblock.io/ee42d0a88f314707be11dd799b122cb9')
.execute(() => {
(document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkBlockNumber"]') as any).focus()
}, [], () => { })
.clearValue('*[data-id="CustomForkBlockNumber"]').setValue('*[data-id="CustomForkBlockNumber"]', 'latest')
.execute(() => {
(document.querySelector('*[data-id="vm-custom-forkModalDialogContainer-react"] input[data-id="CustomForkEvmType"]') as any).focus()
}, [], () => { })
.click('*[data-id="CustomForkEvmType"] [value="cancun"]')
.pause(5000)
.modalFooterOKClick('vm-custom-fork')
.waitForElementPresent({
locateStrategy: 'css selector',
selector: 'select[data-id="runTabSelectAccount"] option[value="0xdD870fA1b7C4700F2BD7f44238821C26f7392148"]',
timeout: 240000
})
.pause(5000)
.executeScriptInTerminal(`web3.eth.getCode('0x75F509A4eDA030470272DfBAf99A47D587E76709')`) // sepolia contract
.waitForElementContainsText('*[data-id="terminalJournal"]', byteCodeInSepolia, 120000)
.click('*[data-id="terminalClearConsole"]')
},
'Should run a free function while being connected to mainnet #group9': function (browser: NightwatchBrowser) {
@ -354,29 +361,31 @@ module.exports = {
console.log(resolver.addr(node));
}
`
browser
// .clickLaunchIcon('udapp')
.switchEnvironment('vm-mainnet-fork')
.clickLaunchIcon('filePanel')
.addFile('test_mainnet.sol', { content: script })
const path = "//*[@class='view-line' and contains(.,'resolveENS') and contains(.,'view')]//span//span[contains(.,'(')]"
const pathRunFunction = `//li//*[@aria-label='Run the free function "resolveENS"']`
browser.waitForElementVisible('#editorView')
//.waitForElementPresent(pathRunFunction)
.pause(10000) // the parser need to parse the code
.useXpath()
.scrollToLine(16)
.click(path)
.perform(function () {
const actions = this.actions({ async: true });
return actions
.keyDown(this.Keys.SHIFT)
.keyDown(this.Keys.ALT)
.sendKeys('r')
})
.useCss()
.waitForElementContainsText('*[data-id="terminalJournal"]', '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', 120000)
if (runMasterTests) {
browser
// .clickLaunchIcon('udapp')
.switchEnvironment('vm-mainnet-fork')
.clickLaunchIcon('filePanel')
.addFile('test_mainnet.sol', { content: script })
const path = "//*[@class='view-line' and contains(.,'resolveENS') and contains(.,'view')]//span//span[contains(.,'(')]"
const pathRunFunction = `//li//*[@aria-label='Run the free function "resolveENS"']`
browser.waitForElementVisible('#editorView')
//.waitForElementPresent(pathRunFunction)
.pause(10000) // the parser need to parse the code
.useXpath()
.scrollToLine(16)
.click(path)
.perform(function () {
const actions = this.actions({ async: true });
return actions
.keyDown(this.Keys.SHIFT)
.keyDown(this.Keys.ALT)
.sendKeys('r')
})
.useCss()
.waitForElementContainsText('*[data-id="terminalJournal"]', '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', 120000)
}
},
'Should run free function which logs in the terminal #group10': function (browser: NightwatchBrowser) {

@ -141,5 +141,6 @@
"filePanel.movingFolderFailed": "Moving Folder Failed",
"filePanel.movingFolderFailedMsg": "Unexpected error while moving folder: {src}",
"filePanel.workspaceActions": "Workspace actions",
"filePanel.saveCodeSample": "This code-sample workspace will not be persisted. Click here to save it."
"filePanel.saveCodeSample": "This code-sample workspace will not be persisted. Click here to save it.",
"filePanel.updateSubmodules": "Update all submodules of repository. Click to pull dependencies."
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/ghaction-helper",
"version": "0.1.30",
"version": "0.1.32",
"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.36",
"@remix-project/remix-solidity": "^0.5.38",
"@types/chai": "^4.3.4",
"typescript": "^4.9.3"
},
"dependencies": {
"@ethereum-waffle/chai": "^3.4.4",
"@remix-project/remix-simulator": "^0.2.50",
"@remix-project/remix-simulator": "^0.2.52",
"chai": "^4.3.7",
"ethers": "^5.7.2",
"web3": "^4.1.1"
},
"types": "./src/index.d.ts",
"gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986"
"gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-analyzer",
"version": "0.5.59",
"version": "0.5.61",
"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": "5.3.0",
"@ethereumjs/util": "9.0.3",
"@ethereumjs/vm": "8.0.0",
"@remix-project/remix-astwalker": "^0.0.80",
"@remix-project/remix-lib": "^0.5.57",
"@remix-project/remix-astwalker": "^0.0.82",
"@remix-project/remix-lib": "^0.5.59",
"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": "326585ffcef3a8846f2a1badf10beab1f73ee986",
"gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55",
"main": "./src/index.js"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-astwalker",
"version": "0.0.80",
"version": "0.0.82",
"description": "Tool to walk through Solidity AST",
"main": "src/index.js",
"scripts": {
@ -37,7 +37,7 @@
"@ethereumjs/tx": "5.3.0",
"@ethereumjs/util": "9.0.3",
"@ethereumjs/vm": "8.0.0",
"@remix-project/remix-lib": "^0.5.57",
"@remix-project/remix-lib": "^0.5.59",
"@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": "326585ffcef3a8846f2a1badf10beab1f73ee986",
"gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55",
"types": "./src/index.d.ts"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-debug",
"version": "0.5.50",
"version": "0.5.52",
"description": "Tool to debug Ethereum transactions",
"contributors": [
{
@ -26,10 +26,10 @@
"@ethereumjs/tx": "5.3.0",
"@ethereumjs/util": "9.0.3",
"@ethereumjs/vm": "8.0.0",
"@remix-project/remix-astwalker": "^0.0.80",
"@remix-project/remix-lib": "^0.5.57",
"@remix-project/remix-simulator": "^0.2.50",
"@remix-project/remix-solidity": "^0.5.36",
"@remix-project/remix-astwalker": "^0.0.82",
"@remix-project/remix-lib": "^0.5.59",
"@remix-project/remix-simulator": "^0.2.52",
"@remix-project/remix-solidity": "^0.5.38",
"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": "326585ffcef3a8846f2a1badf10beab1f73ee986",
"gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55",
"types": "./src/index.d.ts"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-lib",
"version": "0.5.57",
"version": "0.5.59",
"description": "Library to various Remix tools",
"contributors": [
{
@ -55,6 +55,6 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-lib#readme",
"typings": "src/index.d.ts",
"gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986",
"gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55",
"types": "./src/index.d.ts"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-simulator",
"version": "0.2.50",
"version": "0.2.52",
"description": "Ethereum IDE and tools for the web",
"contributors": [
{
@ -22,7 +22,8 @@
"@ethereumjs/tx": "5.3.0",
"@ethereumjs/util": "9.0.3",
"@ethereumjs/vm": "8.0.0",
"@remix-project/remix-lib": "^0.5.57",
"@metamask/eth-sig-util": "^7.0.2",
"@remix-project/remix-lib": "^0.5.59",
"ansi-gray": "^0.1.1",
"async": "^3.1.0",
"body-parser": "^1.18.2",
@ -70,6 +71,6 @@
},
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-simulator#readme",
"typings": "src/index.d.ts",
"gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986",
"gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55",
"types": "./src/index.d.ts"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-solidity",
"version": "0.5.36",
"version": "0.5.38",
"description": "Tool to load and run Solidity compiler",
"main": "src/index.js",
"types": "src/index.d.ts",
@ -19,7 +19,7 @@
"@ethereumjs/tx": "5.3.0",
"@ethereumjs/util": "9.0.3",
"@ethereumjs/vm": "8.0.0",
"@remix-project/remix-lib": "^0.5.57",
"@remix-project/remix-lib": "^0.5.59",
"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": "326585ffcef3a8846f2a1badf10beab1f73ee986"
"gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-tests",
"version": "0.2.50",
"version": "0.2.52",
"description": "Tool to test Solidity smart contracts",
"main": "src/index.js",
"types": "./src/index.d.ts",
@ -41,9 +41,9 @@
"@ethereumjs/tx": "5.3.0",
"@ethereumjs/util": "9.0.3",
"@ethereumjs/vm": "8.0.0",
"@remix-project/remix-lib": "^0.5.57",
"@remix-project/remix-simulator": "^0.2.50",
"@remix-project/remix-solidity": "^0.5.36",
"@remix-project/remix-lib": "^0.5.59",
"@remix-project/remix-simulator": "^0.2.52",
"@remix-project/remix-solidity": "^0.5.38",
"@remix-project/remix-url-resolver": "^0.0.42",
"ansi-gray": "^0.1.1",
"async": "^2.6.0",
@ -89,5 +89,5 @@
"@ethereumjs/trie": "6.2.0"
},
"typings": "src/index.d.ts",
"gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986"
"gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55"
}

@ -4,6 +4,7 @@ import { CompletionTimer } from './completionTimer';
import axios, { AxiosResponse } from 'axios'
import { slice } from 'lodash';
import { activateService } from '@remixproject/plugin-utils';
const _paq = (window._paq = window._paq || [])
const controller = new AbortController();
@ -14,6 +15,9 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
props: EditorUIProps
monaco: any
completionEnabled: boolean
task: string
currentCompletion
constructor(props: any, monaco: any) {
this.props = props
this.monaco = monaco
@ -28,6 +32,7 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
const lineRange = model.getFullModelRange().setStartPosition(lineNumber, 1).setEndPosition(lineNumber + 1, 1);
return model.getValueInRange(lineRange);
}
// get text before the position of the completion
const word = model.getValueInRange({
startLineNumber: 1,
@ -65,6 +70,7 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
// use the code generation model, only take max 1000 word as context
this.props.plugin.call('terminal', 'log', { type: 'aitypewriterwarning', value: 'Solcoder - generating code for following comment: ' + ask.replace('///', '') })
this.task = 'code_generation'
const data = await this.props.plugin.call('solcoder', 'code_generation', word)
const parsedData = data[0].trimStart() //JSON.parse(data).trimStart()
@ -103,15 +109,15 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
if (word.replace(/ +$/, '').endsWith('\n')){
// Code insertion
try {
this.task = 'code_insertion'
const output = await this.props.plugin.call('solcoder', 'code_insertion', word, word_after)
const generatedText = output[0] // no need to clean it. should already be
const item: monacoTypes.languages.InlineCompletion = {
insertText: generatedText
};
this.completionEnabled = false
const handleCompletionTimer = new CompletionTimer(5000, () => { this.completionEnabled = true });
const handleCompletionTimer = new CompletionTimer(1000, () => { this.completionEnabled = true });
handleCompletionTimer.start()
return {
@ -127,6 +133,7 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
let result
try {
// Code completion
this.task = 'code_completion'
const output = await this.props.plugin.call('solcoder', 'code_completion', word)
const generatedText = output[0]
let clean = generatedText
@ -168,14 +175,15 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
}
handleItemDidShow?(completions: monacoTypes.languages.InlineCompletions<monacoTypes.languages.InlineCompletion>, item: monacoTypes.languages.InlineCompletion, updatedInsertText: string): void {
this.currentCompletion = { 'item':item, 'task':this.task }
_paq.push(['trackEvent', 'ai', 'solcoder', this.task + '_did_show'])
}
handlePartialAccept?(completions: monacoTypes.languages.InlineCompletions<monacoTypes.languages.InlineCompletion>, item: monacoTypes.languages.InlineCompletion, acceptedCharacters: number): void {
_paq.push(['trackEvent', 'ai', 'solcoder', this.task + '_partial_accept'])
}
freeInlineCompletions(completions: monacoTypes.languages.InlineCompletions<monacoTypes.languages.InlineCompletion>): void {
}
groupId?: string;
yieldsToGroupIds?: string[];
toString?(): string {

@ -368,6 +368,8 @@ export const EditorUI = (props: EditorUIProps) => {
}
}, [props.currentFile, props.isDiff])
const inlineCompletionProvider = new RemixInLineCompletionProvider(props, monacoRef.current)
const convertToMonacoDecoration = (decoration: lineText | sourceAnnotation | sourceMarker, typeOfDecoration: string) => {
if (typeOfDecoration === 'sourceAnnotationsPerFile') {
decoration = decoration as sourceAnnotation
@ -700,6 +702,17 @@ export const EditorUI = (props: EditorUIProps) => {
}
})
editor.onDidChangeModelContent((e) => {
if (inlineCompletionProvider.currentCompletion) {
const changes = e.changes;
// Check if the change matches the current completion
if (changes.some(change => change.text === inlineCompletionProvider.currentCompletion.item.insertText)) {
_paq.push(['trackEvent', 'ai', 'solcoder', inlineCompletionProvider.currentCompletion.task + '_accepted'])
inlineCompletionProvider.currentCompletion = null;
}
}
});
// add context menu items
const zoominAction = {
id: 'zoomIn',
@ -1003,7 +1016,7 @@ export const EditorUI = (props: EditorUIProps) => {
monacoRef.current.languages.registerReferenceProvider('remix-solidity', new RemixReferenceProvider(props, monaco))
monacoRef.current.languages.registerHoverProvider('remix-solidity', new RemixHoverProvider(props, monaco))
monacoRef.current.languages.registerCompletionItemProvider('remix-solidity', new RemixCompletionProvider(props, monaco))
monacoRef.current.languages.registerInlineCompletionsProvider('remix-solidity', new RemixInLineCompletionProvider(props, monaco))
monacoRef.current.languages.registerInlineCompletionsProvider('remix-solidity', inlineCompletionProvider)
monaco.languages.registerCodeActionProvider('remix-solidity', new RemixCodeActionProvider(props, monaco))
loadTypes(monacoRef.current)

@ -29,7 +29,7 @@ export const CustomToggle = React.forwardRef(
className={className.replace('dropdown-toggle', '')}
>
<div className="d-flex">
<div className="mr-auto text-nowrap overflow-hidden">{children}</div>
<div className="mr-auto text-nowrap text-truncate overflow-hidden">{children}</div>
{icon && (
<div className="pr-1">
<i className={`${icon} pr-1`}></i>

@ -12,7 +12,7 @@ function HomeTabFeatured() {
const themeFilter = useContext(ThemeContext)
return (
<div className="pt-1 pl-2 h-100" id="hTFeaturedeSection">
<div className="pt-1 pl-2" id="hTFeaturedeSection">
<div className="mb-2 remix_ui-carousel-container">
<div className="w-100 d-flex flex-column rounded-3 remix_ui-carouselbox">
<ThemeContext.Provider value={themeFilter}>

@ -77,6 +77,10 @@
background: var(--custom-select);
}
.branches-dropdown {
max-width: 16rem;
}
.custom-dropdown-items a {
border-radius: .25rem;
text-transform: none;

@ -1345,102 +1345,119 @@ export function Workspace() {
</div>
</div>
</div>
{selectedWorkspace && (
{ selectedWorkspace && (
<div className={`bg-light border-top ${selectedWorkspace.isGitRepo && currentBranch ? 'd-block' : 'd-none'}`} data-id="workspaceGitPanel">
<div className="d-flex justify-space-between p-1">
<div className="mr-auto text-uppercase text-dark pt-2 px-1">GIT</div>
{selectedWorkspace.hasGitSubmodules?
<div className="pt-1 mr-1">
{global.fs.browser.isRequestingCloning ? <div style={{ height: 30, minWidth: 165 }} className='btn btn-sm border text-muted small'><i className="fad fa-spinner fa-spin"></i> updating submodules</div> :
<div style={{ height: 30, minWidth: 165 }} onClick={updateSubModules} data-id='updatesubmodules' className={`btn btn-sm border small ${highlightUpdateSubmodules ? 'text-warning' : 'text-muted'}`}>update submodules</div>}
</div>
: null}
<div className="pt-1 mr-1" data-id="workspaceGitBranchesDropdown">
<Dropdown style={{ height: 30, minWidth: 80 }} onToggle={toggleBranches} show={showBranches} drop={'up'}>
<Dropdown.Toggle
as={CustomToggle}
id="dropdown-custom-components"
className="btn btn-light btn-block w-100 d-inline-block border border-dark form-control h-100 p-0 pl-2 pr-2 text-dark"
icon={null}
>
{global.fs.browser.isRequestingCloning ? <i className="fad fa-spinner fa-spin"></i> : (currentBranch && currentBranch.name) || '-none-'}
</Dropdown.Toggle>
<Dropdown.Menu as={CustomMenu} className="custom-dropdown-items branches-dropdown">
<div data-id="custom-dropdown-menu">
<div className="d-flex text-dark" style={{ fontSize: 14, fontWeight: 'bold' }}>
<span className="mt-2 ml-2 mr-auto">
<FormattedMessage id="filePanel.switchBranches" />
</span>
<div
className="pt-2 pr-2"
onClick={() => {
toggleBranches(false)
}}
>
<i className="fa fa-close"></i>
<div className="d-flex justify-content-between p-1">
<div className="text-uppercase text-dark pt-1 px-1">GIT</div>
{ selectedWorkspace.hasGitSubmodules?
<CustomTooltip
placement="top"
tooltipId="updateSubmodules"
tooltipClasses="text-nowrap"
tooltipText={<FormattedMessage id="filePanel.updateSubmodules" />}
>
<div className="pr-1">
{ global.fs.browser.isRequestingCloning ? <button style={{ height: 30, minWidth: "9rem" }} className='btn btn-sm border text-dark'>
<i className="fad fa-spinner fa-spin"></i>
Updating submodules
</button> :
<button style={{ height: 30, minWidth: "9rem" }} onClick={updateSubModules} data-id='updatesubmodules' className={`btn btn-sm border ${highlightUpdateSubmodules ? 'text-warning' : 'text-dark'}`}>
Update submodules
</button> }
</div>
</CustomTooltip>
: null
}
<CustomTooltip
placement="right"
tooltipId="branchesDropdown"
tooltipClasses="text-nowrap"
tooltipText={'Current branch: ' + currentBranch || 'Branches'}
>
<div className="pt-0 mr-2" data-id="workspaceGitBranchesDropdown">
<Dropdown style={{ height: 30, maxWidth: "6rem", minWidth: "6rem" }} onToggle={toggleBranches} show={showBranches} drop={'up'}>
<Dropdown.Toggle
as={CustomToggle}
id="dropdown-custom-components"
className="btn btn-sm btn-light d-inline-block border border-dark form-control h-100 p-0 pl-2 pr-2 text-dark"
icon={null}
>
{global.fs.browser.isRequestingCloning ? <i className="fad fa-spinner fa-spin"></i> : currentBranch.name || '-none-'}
</Dropdown.Toggle>
<Dropdown.Menu as={CustomMenu} className="custom-dropdown-items branches-dropdown">
<div data-id="custom-dropdown-menu">
<div className="d-flex text-dark" style={{ fontSize: 14, fontWeight: 'bold' }}>
<span className="mt-2 ml-2 mr-auto">
<FormattedMessage id="filePanel.switchBranches" />
</span>
<div
className="pt-2 pr-2"
onClick={() => {
toggleBranches(false)
}}
>
<i className="fa fa-close"></i>
</div>
</div>
</div>
<div className="border-top py-2">
<input
className="form-control border checkout-input bg-light"
placeholder={intl.formatMessage({
id: 'filePanel.findOrCreateABranch'
})}
style={{ minWidth: 225 }}
onChange={handleBranchFilterChange}
data-id="workspaceGitInput"
/>
</div>
<div className="border-top" style={{ maxHeight: 120, overflowY: 'scroll' }} data-id="custom-dropdown-items">
{filteredBranches.length > 0 ? (
filteredBranches.map((branch, index) => {
return (
<Dropdown.Item
key={index}
onClick={() => {
switchToBranch(branch)
}}
title={intl.formatMessage({ id: `filePanel.switchToBranch${branch.remote ? 'Title1' : 'Title2'}` })}
>
<div data-id={`workspaceGit-${branch.remote ? `${branch.remote.name}/${branch.name}` : branch.name}`}>
{currentBranch && currentBranch.name === branch.name && !branch.remote ? (
<span>
&#10003; <i className="far fa-code-branch"></i>
<span className="pl-1">{branch.name}</span>
</span>
) : (
<span className="pl-3">
<i className={`far ${branch.remote ? 'fa-cloud' : 'fa-code-branch'}`}></i>
<span className="pl-1">{branch.remote ? `${branch.remote.name}/${branch.name}` : branch.name}</span>
</span>
)}
</div>
</Dropdown.Item>
)
})
) : (
<Dropdown.Item onClick={switchToNewBranch}>
<div className="pl-1 pr-1" data-id="workspaceGitCreateNewBranch">
<i className="fas fa-code-branch pr-2"></i>
<span>
<FormattedMessage id="filePanel.createBranch" />: {branchFilter} from '{currentBranch && currentBranch.name}'
</span>
</div>
</Dropdown.Item>
<div className="border-top py-2">
<input
className="form-control border checkout-input bg-light"
placeholder={intl.formatMessage({
id: 'filePanel.findOrCreateABranch'
})}
style={{ minWidth: 225 }}
onChange={handleBranchFilterChange}
data-id="workspaceGitInput"
/>
</div>
<div className="border-top" style={{ maxHeight: 120, overflowY: 'scroll' }} data-id="custom-dropdown-items">
{filteredBranches.length > 0 ? (
filteredBranches.map((branch, index) => {
return (
<Dropdown.Item
key={index}
onClick={() => {
switchToBranch(branch)
}}
title={intl.formatMessage({ id: `filePanel.switchToBranch${branch.remote ? 'Title1' : 'Title2'}` })}
>
<div data-id={`workspaceGit-${branch.remote ? `${branch.remote}/${branch.name}` : branch.name}`}>
{currentBranch.name === branch.name && !branch.remote ? (
<span>
&#10003; <i className="far fa-code-branch"></i>
<span className="pl-1">{branch.name}</span>
</span>
) : (
<span className="pl-3">
<i className={`far ${branch.remote ? 'fa-cloud' : 'fa-code-branch'}`}></i>
<span className="pl-1">{branch.remote ? `${branch.remote}/${branch.name}` : branch.name}</span>
</span>
)}
</div>
</Dropdown.Item>
)
})
) : (
<Dropdown.Item onClick={switchToNewBranch}>
<div className="pl-1 pr-1" data-id="workspaceGitCreateNewBranch">
<i className="fas fa-code-branch pr-2"></i>
<span>
<FormattedMessage id="filePanel.createBranch" />: {branchFilter} from '{currentBranch.name}'
</span>
</div>
</Dropdown.Item>
)}
</div>
{(selectedWorkspace.branches || []).length > 4 && (
<button className="btn btn-sm w-100" style={{ cursor: "pointer" }} onClick={showAllBranches}>
<FormattedMessage id="filePanel.viewAllBranches" />
</button>
)}
</div>
{(selectedWorkspace.branches || []).length > 4 && (
<div className="text-center border-top pt-2">
<label style={{ fontSize: 12, cursor: 'pointer' }} onClick={showAllBranches}>
<FormattedMessage id="filePanel.viewAllBranches" />
</label>
</div>
)}
</div>
</Dropdown.Menu>
</Dropdown>
</div>
</Dropdown.Menu>
</Dropdown>
</div>
</CustomTooltip>
</div>
</div>
)}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-url-resolver",
"version": "0.0.79",
"version": "0.0.81",
"description": "Solidity import url resolver engine",
"main": "src/index.js",
"types": "src/index.d.ts",
@ -41,5 +41,5 @@
"typescript": "^3.1.6"
},
"typings": "src/index.d.ts",
"gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986"
"gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remix-ws-templates",
"version": "1.0.44",
"version": "1.0.46",
"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": "^4.1.1"
},
"gitHead": "326585ffcef3a8846f2a1badf10beab1f73ee986"
"gitHead": "35e1469e94bb370f5427d4ab230fcbd47c665e55"
}

@ -1,6 +1,6 @@
{
"name": "@remix-project/remixd",
"version": "0.6.33",
"version": "0.6.34",
"description": "remix server: allow accessing file system from remix.ethereum.org and start a dev environment (see help section)",
"main": "index.js",
"types": "./index.d.ts",
@ -27,11 +27,11 @@
},
"homepage": "https://github.com/ethereum/remix-project#readme",
"dependencies": {
"@remix-project/remix-solidity": "^0.5.36",
"@remixproject/plugin": "0.3.33",
"@remixproject/plugin-api": "0.3.33",
"@remixproject/plugin-utils": "0.3.33",
"@remixproject/plugin-ws": "0.3.33",
"@remix-project/remix-solidity": "^0.5.36",
"axios": "1.6.0",
"chokidar": "^2.1.8",
"commander": "^9.4.1",

Loading…
Cancel
Save