fix other targets

1spacelint
bunsenstraat 1 year ago
parent 2248c5d2da
commit c37fa3d924
  1. 2
      libs/ghaction-helper/src/methods.ts
  2. 82
      libs/ghaction-helper/src/signer.ts
  3. 32
      libs/remix-analyzer/src/solidity-analyzer/modules/lowLevelCalls.ts
  4. 30
      libs/remix-analyzer/test/analysis/staticAnalysisCommon-test.ts
  5. 12
      libs/remix-analyzer/test/analysis/staticAnalysisIntegration-test-0.5.0.ts
  6. 2
      libs/remix-core-plugin/src/lib/compiler-artefacts.ts
  7. 4
      libs/remix-core-plugin/src/lib/compiler-content-imports.ts
  8. 8
      libs/remix-core-plugin/src/lib/compiler-metadata.ts
  9. 156
      libs/remix-core-plugin/src/lib/constants/uups.ts
  10. 4
      libs/remix-core-plugin/src/types/contract.ts
  11. 2
      libs/remix-debug/test.ts
  12. 16
      libs/remix-debug/test/decoder/localsTests/helper.ts
  13. 102
      libs/remix-debug/test/decoder/stateTests/mapping.ts
  14. 252
      libs/remix-debug/test/resources/ast.ts
  15. 26
      libs/remix-lib/src/execution/txFormat.ts
  16. 32
      libs/remix-lib/src/hash.ts
  17. 2
      libs/remix-lib/src/util.ts
  18. 4
      libs/remix-lib/test/txFormat.ts
  19. 66
      libs/remix-simulator/src/methods/blocks.ts
  20. 92
      libs/remix-solidity/src/compiler/compiler-abstract.ts
  21. 40
      libs/remix-solidity/src/compiler/compiler.ts
  22. 2
      libs/remix-solidity/src/compiler/types.ts
  23. 66
      libs/remix-solidity/src/lib/es-web-worker/compiler-worker.ts
  24. 12
      libs/remix-solidity/src/lib/es-web-worker/es-web-worker-handler.ts
  25. 44
      libs/remix-tests/src/logger.ts
  26. 54
      libs/remix-tests/tests/testRunner.cli.spec.ts
  27. 832
      libs/remix-tests/tests/testRunner.spec.ts
  28. 54
      libs/remix-ui/app/src/lib/remix-app/components/modals/modal-wrapper.tsx
  29. 134
      libs/remix-ui/app/src/lib/remix-app/reducer/modals.ts
  30. 36
      libs/remix-ui/checkbox/src/lib/remix-ui-checkbox.tsx
  31. 4
      libs/remix-ui/clipboard/src/lib/copy-to-clipboard/copy-to-clipboard.tsx
  32. 20
      libs/remix-ui/debugger-ui/src/lib/api/debugger-api.ts
  33. 134
      libs/remix-ui/debugger-ui/src/lib/button-navigator/button-navigator.tsx
  34. 2
      libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx
  35. 22
      libs/remix-ui/debugger-ui/src/lib/tx-browser/tx-browser.tsx
  36. 88
      libs/remix-ui/debugger-ui/src/reducers/assembly-items.ts
  37. 88
      libs/remix-ui/debugger-ui/src/reducers/calldata.ts
  38. 38
      libs/remix-ui/drag-n-drop/src/lib/drag-n-drop.tsx
  39. 152
      libs/remix-ui/editor/src/lib/actions/editor.ts
  40. 18
      libs/remix-ui/editor/src/lib/helpers/retrieveNodesAtPosition.ts
  41. 1378
      libs/remix-ui/editor/src/lib/providers/completion/completionGlobals.ts
  42. 744
      libs/remix-ui/editor/src/lib/providers/completionProvider.ts
  43. 138
      libs/remix-ui/editor/src/lib/providers/definitionProvider.ts
  44. 56
      libs/remix-ui/editor/src/lib/providers/highlightProvider.ts
  45. 362
      libs/remix-ui/editor/src/lib/providers/hoverProvider.ts
  46. 66
      libs/remix-ui/editor/src/lib/providers/referenceProvider.ts
  47. 4
      libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
  48. 456
      libs/remix-ui/editor/src/lib/web-types.ts
  49. 18
      libs/remix-ui/file-decorators/src/lib/components/file-decoration-icon.tsx
  50. 6
      libs/remix-ui/file-decorators/src/lib/components/filedecorationicons/file-decoration-custom-icon.tsx
  51. 6
      libs/remix-ui/file-decorators/src/lib/components/filedecorationicons/file-decoration-error-icon.tsx
  52. 2
      libs/remix-ui/file-decorators/src/lib/components/filedecorationicons/file-decoration-tooltip.tsx
  53. 2
      libs/remix-ui/file-decorators/src/lib/components/filedecorationicons/file-decoration-warning-icon.tsx
  54. 12
      libs/remix-ui/file-decorators/src/lib/helper/index.tsx
  55. 4
      libs/remix-ui/file-decorators/src/lib/types/index.ts
  56. 24
      libs/remix-ui/helper/src/lib/components/PluginViewWrapper.tsx
  57. 2
      libs/remix-ui/helper/src/lib/components/custom-dropdown.tsx
  58. 4
      libs/remix-ui/helper/src/lib/helper-components.tsx
  59. 4
      libs/remix-ui/helper/src/lib/remix-ui-helper.ts
  60. 26
      libs/remix-ui/home-tab/src/lib/components/homeTabFile.tsx
  61. 40
      libs/remix-ui/home-tab/src/lib/components/homeTabGetStarted.tsx
  62. 10
      libs/remix-ui/home-tab/src/lib/components/homeTabLearn.tsx
  63. 50
      libs/remix-ui/locale-module/src/lib/remix-ui-locale-module.tsx
  64. 2
      libs/remix-ui/panel/src/lib/plugins/panel-header.tsx
  65. 6
      libs/remix-ui/permission-handler/src/lib/permission-dialog.tsx
  66. 8
      libs/remix-ui/plugin-manager/src/lib/reducers/pluginManagerReducer.ts
  67. 30
      libs/remix-ui/plugin-manager/src/types.d.ts
  68. 64
      libs/remix-ui/run-tab/src/lib/actions/deploy.ts
  69. 102
      libs/remix-ui/run-tab/src/lib/components/account.tsx
  70. 22
      libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx
  71. 144
      libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx
  72. 60
      libs/remix-ui/run-tab/src/lib/components/deployButton.tsx
  73. 6
      libs/remix-ui/run-tab/src/lib/components/environment.tsx
  74. 6
      libs/remix-ui/run-tab/src/lib/components/instanceContainerUI.tsx
  75. 12
      libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx
  76. 2
      libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx
  77. 30
      libs/remix-ui/run-tab/src/lib/components/value.tsx
  78. 808
      libs/remix-ui/run-tab/src/lib/reducers/runTab.ts
  79. 106
      libs/remix-ui/run-tab/src/lib/types/blockchain.d.ts
  80. 64
      libs/remix-ui/run-tab/src/lib/types/execution-context.d.ts
  81. 18
      libs/remix-ui/run-tab/src/lib/types/injected.d.ts
  82. 20
      libs/remix-ui/run-tab/src/lib/types/node.d.ts
  83. 76
      libs/remix-ui/run-tab/src/lib/types/run-tab.d.ts
  84. 26
      libs/remix-ui/run-tab/src/lib/types/vm.d.ts
  85. 2
      libs/remix-ui/search/src/lib/components/FindContainer.tsx
  86. 2
      libs/remix-ui/search/src/lib/components/Replace.tsx
  87. 14
      libs/remix-ui/search/src/lib/components/StopSearch.tsx
  88. 34
      libs/remix-ui/search/src/lib/components/Undo.tsx
  89. 4
      libs/remix-ui/search/src/lib/components/results/ResultItem.tsx
  90. 52
      libs/remix-ui/search/src/lib/components/results/ResultSummary.tsx
  91. 2
      libs/remix-ui/search/src/lib/components/results/Results.tsx
  92. 154
      libs/remix-ui/search/src/lib/components/results/SearchHelper.ts
  93. 334
      libs/remix-ui/search/src/lib/reducers/Reducer.ts
  94. 42
      libs/remix-ui/search/src/lib/types/index.ts
  95. 16
      libs/remix-ui/settings/src/lib/constants.ts
  96. 4
      libs/remix-ui/settings/src/lib/etherscan-settings.tsx
  97. 52
      libs/remix-ui/settings/src/lib/remix-ui-settings.tsx
  98. 162
      libs/remix-ui/settings/src/lib/settingsReducer.ts
  99. 86
      libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx
  100. 2
      libs/remix-ui/solidity-compiler/src/lib/logic/compileTabLogic.ts
  101. Some files were not shown because too many files have changed in this diff Show More

@ -198,7 +198,7 @@ const getContractAt = async (contractNameOrABI: ethers.ContractInterface, addres
if (result) { if (result) {
return new ethers.Contract(address, result.abi, signer || provider.getSigner()) return new ethers.Contract(address, result.abi, signer || provider.getSigner())
} else { } else {
throw new Error('Contract artifacts not found') throw new Error('Contract artifacts not found')
} }
} else { } else {
return new ethers.Contract(address, contractNameOrABI, signer || provider.getSigner()) return new ethers.Contract(address, contractNameOrABI, signer || provider.getSigner())

@ -2,8 +2,8 @@
import { ethers } from "ethers" import { ethers } from "ethers"
export class SignerWithAddress extends ethers.Signer { export class SignerWithAddress extends ethers.Signer {
address: string address: string
_signer: { _signer: {
provider: any provider: any
signTransaction: (transaction: any) => any, signTransaction: (transaction: any) => any,
signMessage: (message: string) => any, signMessage: (message: string) => any,
@ -11,43 +11,43 @@ export class SignerWithAddress extends ethers.Signer {
connect: (provider: any) => any, connect: (provider: any) => any,
_signTypedData: (...params: any) => any _signTypedData: (...params: any) => any
} }
provider: any provider: any
static async create(signer: any) { static async create(signer: any) {
return new SignerWithAddress(await signer.getAddress(), signer) return new SignerWithAddress(await signer.getAddress(), signer)
} }
constructor(address: string, _signer: any) { constructor(address: string, _signer: any) {
super() super()
this.address = address this.address = address
this._signer = _signer this._signer = _signer
this.provider = _signer.provider this.provider = _signer.provider
} }
async getAddress() { async getAddress() {
return this.address return this.address
} }
signMessage(message: string){ signMessage(message: string){
return this._signer.signMessage(message) return this._signer.signMessage(message)
} }
signTransaction(transaction: any) { signTransaction(transaction: any) {
return this._signer.signTransaction(transaction) return this._signer.signTransaction(transaction)
} }
sendTransaction(transaction: any) { sendTransaction(transaction: any) {
return this._signer.sendTransaction(transaction) return this._signer.sendTransaction(transaction)
} }
connect(provider: any) { connect(provider: any) {
return new SignerWithAddress(this.address, this._signer.connect(provider)) return new SignerWithAddress(this.address, this._signer.connect(provider))
} }
_signTypedData(...params: any) { _signTypedData(...params: any) {
return this._signer._signTypedData(...params) return this._signer._signTypedData(...params)
} }
toJSON() { toJSON() {
return `<SignerWithAddress ${this.address}>` return `<SignerWithAddress ${this.address}>`
} }
} }

@ -43,31 +43,31 @@ export default class lowLevelCalls implements AnalyzerModule {
let text = '' let text = ''
let morehref = '' let morehref = ''
switch (item.type) { switch (item.type) {
case lowLevelCallTypes.CALL: case lowLevelCallTypes.CALL:
text = `Use of "call": should be avoided whenever possible. text = `Use of "call": should be avoided whenever possible.
It can lead to unexpected behavior if return value is not handled properly. It can lead to unexpected behavior if return value is not handled properly.
Please use Direct Calls via specifying the called contract's interface.` Please use Direct Calls via specifying the called contract's interface.`
morehref = `https://solidity.readthedocs.io/en/${version}/control-structures.html?#external-function-calls` morehref = `https://solidity.readthedocs.io/en/${version}/control-structures.html?#external-function-calls`
break break
case lowLevelCallTypes.CALLCODE: case lowLevelCallTypes.CALLCODE:
text = `Use of "callcode": should be avoided whenever possible. text = `Use of "callcode": should be avoided whenever possible.
External code, that is called can change the state of the calling contract and send ether from the caller's balance. External code, that is called can change the state of the calling contract and send ether from the caller's balance.
If this is wanted behaviour, use the Solidity library feature if possible.` If this is wanted behaviour, use the Solidity library feature if possible.`
morehref = `https://solidity.readthedocs.io/en/${version}/contracts.html#libraries` morehref = `https://solidity.readthedocs.io/en/${version}/contracts.html#libraries`
break break
case lowLevelCallTypes.DELEGATECALL: case lowLevelCallTypes.DELEGATECALL:
text = `Use of "delegatecall": should be avoided whenever possible. text = `Use of "delegatecall": should be avoided whenever possible.
External code, that is called can change the state of the calling contract and send ether from the caller's balance. External code, that is called can change the state of the calling contract and send ether from the caller's balance.
If this is wanted behaviour, use the Solidity library feature if possible.` If this is wanted behaviour, use the Solidity library feature if possible.`
morehref = `https://solidity.readthedocs.io/en/${version}/contracts.html#libraries` morehref = `https://solidity.readthedocs.io/en/${version}/contracts.html#libraries`
break break
case lowLevelCallTypes.SEND: case lowLevelCallTypes.SEND:
text = `Use of "send": "send" does not throw an exception when not successful, make sure you deal with the failure case accordingly. text = `Use of "send": "send" does not throw an exception when not successful, make sure you deal with the failure case accordingly.
Use "transfer" whenever failure of the ether transfer should rollback the whole transaction. Use "transfer" whenever failure of the ether transfer should rollback the whole transaction.
Note: if you "send/transfer" ether to a contract the fallback function is called, the callees fallback function is very limited due to the limited amount of gas provided by "send/transfer". Note: if you "send/transfer" ether to a contract the fallback function is called, the callees fallback function is very limited due to the limited amount of gas provided by "send/transfer".
No state changes are possible but the callee can log the event or revert the transfer. "send/transfer" is syntactic sugar for a "call" to the fallback function with 2300 gas and a specified ether value.` No state changes are possible but the callee can log the event or revert the transfer. "send/transfer" is syntactic sugar for a "call" to the fallback function with 2300 gas and a specified ether value.`
morehref = `https://solidity.readthedocs.io/en/${version}/security-considerations.html#sending-and-receiving-ether` morehref = `https://solidity.readthedocs.io/en/${version}/security-considerations.html#sending-and-receiving-ether`
break break
} }
return { warning: text, more: morehref, location: item.node.src } return { warning: text, more: morehref, location: item.node.src }
}) })

@ -1,10 +1,10 @@
import { default as test} from "tape" import { default as test} from "tape"
import * as common from '../../src/solidity-analyzer/modules/staticAnalysisCommon' import * as common from '../../src/solidity-analyzer/modules/staticAnalysisCommon'
const { localCall, thisLocalCall, libCall, externalDirect, superLocal, assignment, abiNamespaceCallNodes, const { localCall, thisLocalCall, libCall, externalDirect, superLocal, assignment, abiNamespaceCallNodes,
inlineAssembly, unaryOperation, nowAst, blockTimestamp, stateVariableContractNode, inlineAssembly, unaryOperation, nowAst, blockTimestamp, stateVariableContractNode,
functionDefinition, requireCall, selfdestruct, storageVariableNodes, dynamicDeleteUnaryOp, functionDefinition, requireCall, selfdestruct, storageVariableNodes, dynamicDeleteUnaryOp,
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
lowlevelCall, parameterFunction, parameterFunctionCall, inheritance, blockHashAccess, contractDefinition, funcDefForComplexParams } = require('./astBlocks') lowlevelCall, parameterFunction, parameterFunctionCall, inheritance, blockHashAccess, contractDefinition, funcDefForComplexParams } = require('./astBlocks')
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
@ -40,11 +40,11 @@ test('staticAnalysisCommon.helpers.buildFunctionSignature', function (t) {
'function (bytes memory) payable returns (bool,bytes memory)', 'function (bytes memory) payable returns (bool,bytes memory)',
'check fixed call type') 'check fixed call type')
t.equal(common.lowLevelCallTypes['CALL-0.4'].type, t.equal(common.lowLevelCallTypes['CALL-0.4'].type,
'function () payable returns (bool)', 'function () payable returns (bool)',
'check fixed call type for versions before 0.5.0') 'check fixed call type for versions before 0.5.0')
t.equal(common.lowLevelCallTypes.CALLCODE.type, t.equal(common.lowLevelCallTypes.CALLCODE.type,
'function () payable returns (bool)', 'function () payable returns (bool)',
'check fixed callcode type') 'check fixed callcode type')
@ -56,7 +56,7 @@ t.equal(common.lowLevelCallTypes.CALLCODE.type,
'function (bytes memory) returns (bool,bytes memory)', 'function (bytes memory) returns (bool,bytes memory)',
'check fixed delegatecall type') 'check fixed delegatecall type')
t.equal(common.lowLevelCallTypes['DELEGATECALL-0.4'].type, t.equal(common.lowLevelCallTypes['DELEGATECALL-0.4'].type,
'function () returns (bool)', 'function () returns (bool)',
'check fixed delegatecall type for version before 0.5.0') 'check fixed delegatecall type for version before 0.5.0')
}) })
@ -141,18 +141,18 @@ test('staticAnalysisCommon.helpers.expressionTypeDescription', function (t) {
test('staticAnalysisCommon.getType', function (t) { test('staticAnalysisCommon.getType', function (t) {
t.plan(3) t.plan(3)
const node = { "argumentTypes": null, const node = { "argumentTypes": null,
"id": 3, "id": 3,
"name": "a", "name": "a",
"nodeType": "Identifier", "nodeType": "Identifier",
"overloadedDeclarations": [], "overloadedDeclarations": [],
"referencedDeclaration": 22, "referencedDeclaration": 22,
"src": "52:1:0", "src": "52:1:0",
"typeDescriptions": "typeDescriptions":
{ {
"typeIdentifier": "t_uint256", "typeIdentifier": "t_uint256",
"typeString": "uint256" "typeString": "uint256"
} }
} }
t.ok(common.getType(blockHashAccess) === 'bytes32', 'gettype should work for different nodes') t.ok(common.getType(blockHashAccess) === 'bytes32', 'gettype should work for different nodes')
t.ok(common.getType(node) === 'uint256', 'gettype should work for different nodes') t.ok(common.getType(node) === 'uint256', 'gettype should work for different nodes')
t.ok(common.getType(assignment) === 'uint256', 'gettype should work for different nodes') t.ok(common.getType(assignment) === 'uint256', 'gettype should work for different nodes')

@ -816,11 +816,11 @@ test('Integration test forLoopIteratesOverDynamicArray module', function (t: tes
function runModuleOnFiles (Module: any, t: test.Test, cb: ((fname: string, report: AnalysisReportObj[]) => void)): void { function runModuleOnFiles (Module: any, t: test.Test, cb: ((fname: string, report: AnalysisReportObj[]) => void)): void {
const statRunner: StatRunner = new StatRunner() const statRunner: StatRunner = new StatRunner()
testFiles.forEach((fileName: string) => { testFiles.forEach((fileName: string) => {
const reports = statRunner.runWithModuleList(compilationResults[fileName], [{ name: new Module().name, mod: new Module() }]) const reports = statRunner.runWithModuleList(compilationResults[fileName], [{ name: new Module().name, mod: new Module() }])
const report: AnalysisReportObj[] = reports[0].report const report: AnalysisReportObj[] = reports[0].report
if (report.some((x: AnalysisReportObj) => x['warning'].includes('INTERNAL ERROR'))) { if (report.some((x: AnalysisReportObj) => x['warning'].includes('INTERNAL ERROR'))) {
t.comment('Error while executing Module: ' + JSON.stringify(report)) t.comment('Error while executing Module: ' + JSON.stringify(report))
} }
cb(fileName, report) cb(fileName, report)
}) })
} }

@ -95,7 +95,7 @@ export class CompilerArtefacts extends Plugin {
* filter compilation output for contracts compiled during a session of Remix IDE * filter compilation output for contracts compiled during a session of Remix IDE
* @returns compilatin output * @returns compilatin output
*/ */
filterAllContractDatas (filter) { filterAllContractDatas (filter) {
const contractsData = {} const contractsData = {}
Object.keys(this.compilersArtefactsPerFile).map((targetFile) => { Object.keys(this.compilersArtefactsPerFile).map((targetFile) => {
const artefact = this.compilersArtefactsPerFile[targetFile] const artefact = this.compilersArtefactsPerFile[targetFile]

@ -167,8 +167,8 @@ export class CompilerImports extends Plugin {
Doesn't make sense to try to resolve "localhost/node_modules/localhost/node_modules/<path>" and we'll end in an infinite loop. Doesn't make sense to try to resolve "localhost/node_modules/localhost/node_modules/<path>" and we'll end in an infinite loop.
*/ */
if (!exist && (url === 'remix_tests.sol' || url === 'remix_accounts.sol')) { if (!exist && (url === 'remix_tests.sol' || url === 'remix_accounts.sol')) {
await this.call('solidityUnitTesting', 'createTestLibs') await this.call('solidityUnitTesting', 'createTestLibs')
exist = await provider.exists(url) exist = await provider.exists(url)
} }
if (!exist && url.startsWith('browser/')) throw new Error(`not found ${url}`) if (!exist && url.startsWith('browser/')) throw new Error(`not found ${url}`)
if (!exist && url.startsWith('localhost/')) throw new Error(`not found ${url}`) if (!exist && url.startsWith('localhost/')) throw new Error(`not found ${url}`)

@ -88,10 +88,10 @@ export class CompilerMetadata extends Plugin {
const buildData = {id, _format: format, solcVersion, solcLongVersion, input, output} const buildData = {id, _format: format, solcVersion, solcLongVersion, input, output}
await this.call('fileManager', 'writeFile', buildFilename, JSON.stringify(buildData, null, '\t')) await this.call('fileManager', 'writeFile', buildFilename, JSON.stringify(buildData, null, '\t'))
} else if (this.buildInfoNames[filePath] && this.buildInfoNames[filePath] !== buildFilename) { } else if (this.buildInfoNames[filePath] && this.buildInfoNames[filePath] !== buildFilename) {
await this.call('fileManager', 'remove', this.buildInfoNames[filePath]) await this.call('fileManager', 'remove', this.buildInfoNames[filePath])
this.buildInfoNames[filePath] = buildFilename this.buildInfoNames[filePath] = buildFilename
const buildData = {id, _format: format, solcVersion, solcLongVersion, input, output} const buildData = {id, _format: format, solcVersion, solcLongVersion, input, output}
await this.call('fileManager', 'writeFile', buildFilename, JSON.stringify(buildData, null, '\t')) await this.call('fileManager', 'writeFile', buildFilename, JSON.stringify(buildData, null, '\t'))
} }
} }

@ -10,88 +10,88 @@ export const UUPSRuns = 0
export const UUPSEvmVersion = null export const UUPSEvmVersion = null
export const UUPSABI = [ export const UUPSABI = [
{ {
"inputs": [ "inputs": [
{ {
"internalType": "address", "internalType": "address",
"name": "_logic", "name": "_logic",
"type": "address" "type": "address"
}, },
{ {
"internalType": "bytes", "internalType": "bytes",
"name": "_data", "name": "_data",
"type": "bytes" "type": "bytes"
} }
], ],
"stateMutability": "payable", "stateMutability": "payable",
"type": "constructor" "type": "constructor"
}, },
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
{ {
"indexed": false, "indexed": false,
"internalType": "address", "internalType": "address",
"name": "previousAdmin", "name": "previousAdmin",
"type": "address" "type": "address"
}, },
{ {
"indexed": false, "indexed": false,
"internalType": "address", "internalType": "address",
"name": "newAdmin", "name": "newAdmin",
"type": "address" "type": "address"
} }
], ],
"name": "AdminChanged", "name": "AdminChanged",
"type": "event" "type": "event"
}, },
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
{ {
"indexed": true, "indexed": true,
"internalType": "address", "internalType": "address",
"name": "beacon", "name": "beacon",
"type": "address" "type": "address"
} }
], ],
"name": "BeaconUpgraded", "name": "BeaconUpgraded",
"type": "event" "type": "event"
}, },
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
{ {
"indexed": true, "indexed": true,
"internalType": "address", "internalType": "address",
"name": "implementation", "name": "implementation",
"type": "address" "type": "address"
} }
], ],
"name": "Upgraded", "name": "Upgraded",
"type": "event" "type": "event"
}, },
{ {
"stateMutability": "payable", "stateMutability": "payable",
"type": "fallback" "type": "fallback"
}, },
{ {
"stateMutability": "payable", "stateMutability": "payable",
"type": "receive" "type": "receive"
} }
] ]
export const UUPSfunAbi = { export const UUPSfunAbi = {
name: "", name: "",
inputs: [ inputs: [
{ {
"internalType": "address", "internalType": "address",
"name": "_logic", "name": "_logic",
"type": "address" "type": "address"
}, },
{ {
"internalType": "bytes", "internalType": "bytes",
"name": "_data", "name": "_data",
"type": "bytes" "type": "bytes"
} }
], ],
type: "constructor", type: "constructor",
outputs: [], outputs: [],
@ -99,17 +99,17 @@ export const UUPSfunAbi = {
} }
export const UUPSupgradeAbi = { export const UUPSupgradeAbi = {
"inputs": [ "inputs": [
{ {
"internalType": "address", "internalType": "address",
"name": "newImplementation", "name": "newImplementation",
"type": "address" "type": "address"
} }
], ],
"name": "upgradeTo", "name": "upgradeTo",
"outputs": [], "outputs": [],
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "type": "function"
} }
export const EnableProxyURLParam = 'deployProxy' export const EnableProxyURLParam = 'deployProxy'
export const EnableUpgradeURLParam = 'upgradeProxy' export const EnableUpgradeURLParam = 'upgradeProxy'

@ -191,7 +191,7 @@ export interface ContractSources {
} }
} }
export interface NetworkDeploymentFile { export interface NetworkDeploymentFile {
id: string, id: string,
network: string, network: string,
deployments: { deployments: {
@ -204,7 +204,7 @@ export interface ContractSources {
}[] }[]
} }
export interface SolcBuildFile { export interface SolcBuildFile {
solcInput: SolcInput, solcInput: SolcInput,
solcOutput: SolcOutput solcOutput: SolcOutput
} }

@ -67,7 +67,7 @@ cmdLine.startDebug(tx, shortFilename)
cmdLine.events.on('source', () => { cmdLine.events.on('source', () => {
cmdLine.getSource().forEach(console.dir) cmdLine.getSource().forEach(console.dir)
}) })
// }) // })
// }) // })
const repl = require('repl') const repl = require('repl')

@ -31,15 +31,15 @@ export function decodeLocals (st, index, traceManager, callTree, verifier) {
callback(error) callback(error)
} }
}], }],
index, index,
function (error, result) { function (error, result) {
if (error) { if (error) {
return st.fail(error) return st.fail(error)
} }
solidityLocals(index, callTree, result[0].value, result[1].value, {}, result[2].value, { start: 5000 }, null).then((locals) => { solidityLocals(index, callTree, result[0].value, result[1].value, {}, result[2].value, { start: 5000 }, null).then((locals) => {
verifier(locals) verifier(locals)
})
}) })
})
} catch (e) { } catch (e) {
st.fail(e.message) st.fail(e.message)
} }

@ -46,63 +46,63 @@ module.exports = async function testMappingStorage (st, cb) {
function testMapping (st, privateKey, contractAddress, output, compilationResults, web3, cb) { function testMapping (st, privateKey, contractAddress, output, compilationResults, web3, cb) {
(vmCall as any).sendTx(web3, {nonce: 1, privateKey: privateKey}, contractAddress, 0, '2fd0a83a00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001074686973206973206120737472696e6700000000000000000000000000000000', (vmCall as any).sendTx(web3, {nonce: 1, privateKey: privateKey}, contractAddress, 0, '2fd0a83a00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001074686973206973206120737472696e6700000000000000000000000000000000',
function (error, hash) { function (error, hash) {
if (error) {
console.log(error)
st.end(error)
} else {
web3.eth.getTransaction(hash, (error, tx) => {
if (error) { if (error) {
console.log(error) console.log(error)
st.end(error) st.end(error)
} else { } else {
web3.eth.getTransaction(hash, (error, tx) => { const traceManager = new TraceManager({ web3 })
if (error) { const codeManager = new CodeManager(traceManager)
console.log(error) codeManager.clear()
st.end(error) console.log(compilationResults)
} else { const solidityProxy = new SolidityProxy({
const traceManager = new TraceManager({ web3 }) getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager),
const codeManager = new CodeManager(traceManager) getCode: codeManager.getCode.bind(codeManager),
codeManager.clear() compilationResult: () => compilationResults
console.log(compilationResults) })
const solidityProxy = new SolidityProxy({ const debuggerEvent = new EventManager()
getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), const callTree = new InternalCallTree(debuggerEvent, traceManager, solidityProxy, codeManager, { includeLocalVariables: true })
getCode: codeManager.getCode.bind(codeManager), callTree.event.register('callTreeBuildFailed', (error) => {
compilationResult: () => compilationResults st.fail(error)
}) })
const debuggerEvent = new EventManager() callTree.event.register('callTreeNotReady', (reason) => {
const callTree = new InternalCallTree(debuggerEvent, traceManager, solidityProxy, codeManager, { includeLocalVariables: true }) st.fail(reason)
callTree.event.register('callTreeBuildFailed', (error) => { })
st.fail(error) callTree.event.register('callTreeReady', (scopes, scopeStarts) => {
}) const storageViewer = new StorageViewer({
callTree.event.register('callTreeNotReady', (reason) => { stepIndex: 268,
st.fail(reason) tx: tx,
}) address: contractAddress
callTree.event.register('callTreeReady', (scopes, scopeStarts) => { }, new StorageResolver({web3}), traceManager)
const storageViewer = new StorageViewer({ const stateVars = stateDecoder.extractStateVariables('SimpleMappingState', output.sources)
stepIndex: 268, stateDecoder.decodeState(stateVars, storageViewer).then((result) => {
tx: tx, st.equal(result['_num'].value, '1')
address: contractAddress st.equal(result['_num'].type, 'uint256')
}, new StorageResolver({web3}), traceManager) st.equal(result['_iBreakSolidityState'].type, 'mapping(string => uint256)')
const stateVars = stateDecoder.extractStateVariables('SimpleMappingState', output.sources) st.equal(result['_iBreakSolidityState'].value['74686973206973206120737472696e67'].value, '1')
stateDecoder.decodeState(stateVars, storageViewer).then((result) => { st.equal(result['_iBreakSolidityState'].value['74686973206973206120737472696e67'].type, 'uint256')
st.equal(result['_num'].value, '1') st.equal(result['_iBreakSolidityStateInt'].type, 'mapping(uint256 => uint256)')
st.equal(result['_num'].type, 'uint256') st.equal(result['_iBreakSolidityStateInt'].value['0000000000000000000000000000000000000000000000000000000000000001'].value, '1')
st.equal(result['_iBreakSolidityState'].type, 'mapping(string => uint256)') st.equal(result['_iBreakSolidityStateInt'].value['0000000000000000000000000000000000000000000000000000000000000001'].type, 'uint256')
st.equal(result['_iBreakSolidityState'].value['74686973206973206120737472696e67'].value, '1') cb()
st.equal(result['_iBreakSolidityState'].value['74686973206973206120737472696e67'].type, 'uint256') }, (reason) => {
st.equal(result['_iBreakSolidityStateInt'].type, 'mapping(uint256 => uint256)') console.log('fail')
st.equal(result['_iBreakSolidityStateInt'].value['0000000000000000000000000000000000000000000000000000000000000001'].value, '1') st.end(reason)
st.equal(result['_iBreakSolidityStateInt'].value['0000000000000000000000000000000000000000000000000000000000000001'].type, 'uint256') })
cb() })
}, (reason) => {
console.log('fail')
st.end(reason)
})
})
traceManager.resolveTrace(tx).then(() => { traceManager.resolveTrace(tx).then(() => {
debuggerEvent.trigger('newTraceLoaded', [traceManager.trace]) debuggerEvent.trigger('newTraceLoaded', [traceManager.trace])
}).catch((error) => { }).catch((error) => {
st.fail(error) st.fail(error)
})
}
}) })
} }
}) })
}
})
} }

@ -3,64 +3,64 @@ const node = {}
node['ast'] = {"legacyAST":{"children":[{"attributes":{"fullyImplemented":true,"isLibrary":false,"linearizedBaseContracts":[5640396],"name":"test"},"children":[{"attributes":{"name":"x","type":"int256"},"children":[{"attributes":{"name":"int"},"id":5657860,"name":"ElementaryTypeName","src":"21:3:11"}],"id":5658100,"name":"VariableDeclaration","src":"21:5:11"},{"attributes":{"name":"y","type":"int256"},"children":[{"attributes":{"name":"int"},"id":5658180,"name":"ElementaryTypeName","src":"38:3:11"}],"id":5658268,"name":"VariableDeclaration","src":"38:5:11"},{"attributes":{"constant":false,"name":"set","public":true},"children":[{"children":[{"attributes":{"name":"_x","type":"int256"},"children":[{"attributes":{"name":"int"},"id":5658404,"name":"ElementaryTypeName","src":"68:3:11"}],"id":5658492,"name":"VariableDeclaration","src":"68:6:11"}],"id":5658572,"name":"ParameterList","src":"67:8:11"},{"children":[{"attributes":{"name":"_r","type":"int256"},"children":[{"attributes":{"name":"int"},"id":5658628,"name":"ElementaryTypeName","src":"85:3:11"}],"id":5658716,"name":"VariableDeclaration","src":"85:6:11"}],"id":5658796,"name":"ParameterList","src":"84:8:11"},{"children":[{"children":[{"attributes":{"operator":"=","type":"int256"},"children":[{"attributes":{"type":"int256","value":"x"},"id":5658900,"name":"Identifier","src":"108:1:11"},{"attributes":{"type":"int256","value":"_x"},"id":5658980,"name":"Identifier","src":"112:2:11"}],"id":5657492,"name":"Assignment","src":"108:6:11"}],"id":5659028,"name":"ExpressionStatement","src":"108:6:11"},{"children":[{"attributes":{"operator":"=","type":"int256"},"children":[{"attributes":{"type":"int256","value":"y"},"id":5659116,"name":"Identifier","src":"125:1:11"},{"attributes":{"string":null,"type":"int_const 10","value":"10"},"id":5659196,"name":"Literal","src":"129:2:11"}],"id":5659252,"name":"Assignment","src":"125:6:11"}],"id":5659316,"name":"ExpressionStatement","src":"125:6:11"},{"children":[{"attributes":{"operator":"=","type":"int256"},"children":[{"attributes":{"type":"int256","value":"_r"},"id":5659428,"name":"Identifier","src":"141:2:11"},{"attributes":{"type":"int256","value":"x"},"id":5639308,"name":"Identifier","src":"146:1:11"}],"id":5639356,"name":"Assignment","src":"141:6:11"}],"id":5639420,"name":"ExpressionStatement","src":"141:6:11"}],"id":5639516,"name":"Block","src":"97:57:11"}],"id":5639612,"name":"FunctionDefinition","src":"55:99:11"},{"attributes":{"constant":false,"name":"get","public":true},"children":[{"children":[],"id":5639764,"name":"ParameterList","src":"179:2:11"},{"children":[{"attributes":{"name":"x","type":"uint256"},"children":[{"attributes":{"name":"uint"},"id":5639820,"name":"ElementaryTypeName","src":"191:4:11"}],"id":5639908,"name":"VariableDeclaration","src":"191:6:11"},{"attributes":{"name":"y","type":"uint256"},"children":[{"attributes":{"name":"uint"},"id":5639988,"name":"ElementaryTypeName","src":"199:4:11"}],"id":5640076,"name":"VariableDeclaration","src":"199:6:11"}],"id":5640156,"name":"ParameterList","src":"190:16:11"},{"children":[],"id":5640212,"name":"Block","src":"212:17:11"}],"id":5640276,"name":"FunctionDefinition","src":"167:62:11"}],"id":5640396,"name":"ContractDefinition","src":"0:231:11"}],"name":"SourceUnit"}} node['ast'] = {"legacyAST":{"children":[{"attributes":{"fullyImplemented":true,"isLibrary":false,"linearizedBaseContracts":[5640396],"name":"test"},"children":[{"attributes":{"name":"x","type":"int256"},"children":[{"attributes":{"name":"int"},"id":5657860,"name":"ElementaryTypeName","src":"21:3:11"}],"id":5658100,"name":"VariableDeclaration","src":"21:5:11"},{"attributes":{"name":"y","type":"int256"},"children":[{"attributes":{"name":"int"},"id":5658180,"name":"ElementaryTypeName","src":"38:3:11"}],"id":5658268,"name":"VariableDeclaration","src":"38:5:11"},{"attributes":{"constant":false,"name":"set","public":true},"children":[{"children":[{"attributes":{"name":"_x","type":"int256"},"children":[{"attributes":{"name":"int"},"id":5658404,"name":"ElementaryTypeName","src":"68:3:11"}],"id":5658492,"name":"VariableDeclaration","src":"68:6:11"}],"id":5658572,"name":"ParameterList","src":"67:8:11"},{"children":[{"attributes":{"name":"_r","type":"int256"},"children":[{"attributes":{"name":"int"},"id":5658628,"name":"ElementaryTypeName","src":"85:3:11"}],"id":5658716,"name":"VariableDeclaration","src":"85:6:11"}],"id":5658796,"name":"ParameterList","src":"84:8:11"},{"children":[{"children":[{"attributes":{"operator":"=","type":"int256"},"children":[{"attributes":{"type":"int256","value":"x"},"id":5658900,"name":"Identifier","src":"108:1:11"},{"attributes":{"type":"int256","value":"_x"},"id":5658980,"name":"Identifier","src":"112:2:11"}],"id":5657492,"name":"Assignment","src":"108:6:11"}],"id":5659028,"name":"ExpressionStatement","src":"108:6:11"},{"children":[{"attributes":{"operator":"=","type":"int256"},"children":[{"attributes":{"type":"int256","value":"y"},"id":5659116,"name":"Identifier","src":"125:1:11"},{"attributes":{"string":null,"type":"int_const 10","value":"10"},"id":5659196,"name":"Literal","src":"129:2:11"}],"id":5659252,"name":"Assignment","src":"125:6:11"}],"id":5659316,"name":"ExpressionStatement","src":"125:6:11"},{"children":[{"attributes":{"operator":"=","type":"int256"},"children":[{"attributes":{"type":"int256","value":"_r"},"id":5659428,"name":"Identifier","src":"141:2:11"},{"attributes":{"type":"int256","value":"x"},"id":5639308,"name":"Identifier","src":"146:1:11"}],"id":5639356,"name":"Assignment","src":"141:6:11"}],"id":5639420,"name":"ExpressionStatement","src":"141:6:11"}],"id":5639516,"name":"Block","src":"97:57:11"}],"id":5639612,"name":"FunctionDefinition","src":"55:99:11"},{"attributes":{"constant":false,"name":"get","public":true},"children":[{"children":[],"id":5639764,"name":"ParameterList","src":"179:2:11"},{"children":[{"attributes":{"name":"x","type":"uint256"},"children":[{"attributes":{"name":"uint"},"id":5639820,"name":"ElementaryTypeName","src":"191:4:11"}],"id":5639908,"name":"VariableDeclaration","src":"191:6:11"},{"attributes":{"name":"y","type":"uint256"},"children":[{"attributes":{"name":"uint"},"id":5639988,"name":"ElementaryTypeName","src":"199:4:11"}],"id":5640076,"name":"VariableDeclaration","src":"199:6:11"}],"id":5640156,"name":"ParameterList","src":"190:16:11"},{"children":[],"id":5640212,"name":"Block","src":"212:17:11"}],"id":5640276,"name":"FunctionDefinition","src":"167:62:11"}],"id":5640396,"name":"ContractDefinition","src":"0:231:11"}],"name":"SourceUnit"}}
node['ast'].ast = { node['ast'].ast = {
absolutePath: 'sample.sol', absolutePath: 'sample.sol',
exportedSymbols: { test: [ 33 ] }, exportedSymbols: { test: [ 33 ] },
id: 34, id: 34,
nodeType: 'SourceUnit', nodeType: 'SourceUnit',
nodes: nodes:
[ { [ {
abstract: false, abstract: false,
baseContracts: [], baseContracts: [],
contractDependencies: [], contractDependencies: [],
contractKind: 'contract', contractKind: 'contract',
documentation: null, documentation: null,
fullyImplemented: true, fullyImplemented: true,
id: 33, id: 33,
linearizedBaseContracts: [ 33 ], linearizedBaseContracts: [ 33 ],
name: 'test', name: 'test',
nodeType: 'ContractDefinition', nodeType: 'ContractDefinition',
nodes: nodes:
[ { constant: false, [ { constant: false,
id: 2, id: 2,
name: 'x', name: 'x',
nodeType: 'VariableDeclaration', nodeType: 'VariableDeclaration',
overrides: null, overrides: null,
scope: 33, scope: 33,
src: '20:5:0', src: '20:5:0',
stateVariable: true, stateVariable: true,
storageLocation: 'default', storageLocation: 'default',
typeDescriptions: { typeIdentifier: 't_int256', typeString: 'int256' }, typeDescriptions: { typeIdentifier: 't_int256', typeString: 'int256' },
typeName: { typeName: {
id: 1, id: 1,
name: 'int', name: 'int',
nodeType: 'ElementaryTypeName', nodeType: 'ElementaryTypeName',
src: '20:3:0', src: '20:3:0',
typeDescriptions: [Object] typeDescriptions: [Object]
}, },
value: null, value: null,
visibility: 'internal' }, visibility: 'internal' },
{ constant: false, { constant: false,
id: 4, id: 4,
name: 'y', name: 'y',
nodeType: 'VariableDeclaration', nodeType: 'VariableDeclaration',
overrides: null, overrides: null,
scope: 33, scope: 33,
src: '31:5:0', src: '31:5:0',
stateVariable: true, stateVariable: true,
storageLocation: 'default', storageLocation: 'default',
typeDescriptions: { typeIdentifier: 't_int256', typeString: 'int256' }, typeDescriptions: { typeIdentifier: 't_int256', typeString: 'int256' },
typeName: typeName:
{ id: 3, { id: 3,
name: 'int', name: 'int',
nodeType: 'ElementaryTypeName', nodeType: 'ElementaryTypeName',
src: '31:3:0', src: '31:3:0',
typeDescriptions: [Object] }, typeDescriptions: [Object] },
value: null, value: null,
visibility: 'internal' }, visibility: 'internal' },
{ body: { id: 23, { body: { id: 23,
nodeType: 'Block', nodeType: 'Block',
src: '96:55:0', src: '96:55:0',
statements: statements:
[ { expression: [ { expression:
{ argumentTypes: null, { argumentTypes: null,
id: 13, id: 13,
@ -70,31 +70,31 @@ node['ast'].ast = {
lValueRequested: false, lValueRequested: false,
leftHandSide: leftHandSide:
{ argumentTypes: null, { argumentTypes: null,
id: 11, id: 11,
name: 'x', name: 'x',
nodeType: 'Identifier', nodeType: 'Identifier',
overloadedDeclarations: [], overloadedDeclarations: [],
referencedDeclaration: 2, referencedDeclaration: 2,
src: '106:1:0', src: '106:1:0',
typeDescriptions: { typeIdentifier: 't_int256', typeString: 'int256' } }, typeDescriptions: { typeIdentifier: 't_int256', typeString: 'int256' } },
nodeType: 'Assignment', nodeType: 'Assignment',
operator: '=', operator: '=',
rightHandSide: rightHandSide:
{ argumentTypes: null, { argumentTypes: null,
id: 12, id: 12,
name: '_x', name: '_x',
nodeType: 'Identifier', nodeType: 'Identifier',
overloadedDeclarations: [], overloadedDeclarations: [],
referencedDeclaration: 6, referencedDeclaration: 6,
src: '110:2:0', src: '110:2:0',
typeDescriptions: { typeIdentifier: 't_int256', typeString: 'int256' } }, typeDescriptions: { typeIdentifier: 't_int256', typeString: 'int256' } },
src: '106:6:0', src: '106:6:0',
typeDescriptions: { typeIdentifier: 't_int256', typeString: 'int256' } typeDescriptions: { typeIdentifier: 't_int256', typeString: 'int256' }
}, },
id: 14, id: 14,
nodeType: 'ExpressionStatement', nodeType: 'ExpressionStatement',
src: '106:6:0' }, src: '106:6:0' },
{ expression: { expression:
{ argumentTypes: null, { argumentTypes: null,
id: 17, id: 17,
isConstant: false, isConstant: false,
@ -107,10 +107,10 @@ node['ast'].ast = {
rightHandSide: [Object], rightHandSide: [Object],
src: '122:6:0', src: '122:6:0',
typeDescriptions: [Object] }, typeDescriptions: [Object] },
id: 18, id: 18,
nodeType: 'ExpressionStatement', nodeType: 'ExpressionStatement',
src: '122:6:0' }, src: '122:6:0' },
{ expression: { expression:
{ argumentTypes: null, { argumentTypes: null,
id: 21, id: 21,
isConstant: false, isConstant: false,
@ -123,61 +123,61 @@ node['ast'].ast = {
rightHandSide: [Object], rightHandSide: [Object],
src: '138:6:0', src: '138:6:0',
typeDescriptions: [Object] }, typeDescriptions: [Object] },
id: 22, id: 22,
nodeType: 'ExpressionStatement', nodeType: 'ExpressionStatement',
src: '138:6:0' } ] src: '138:6:0' } ]
}, },
documentation: null, documentation: null,
functionSelector: 'e5c19b2d', functionSelector: 'e5c19b2d',
id: 24, id: 24,
implemented: true, implemented: true,
kind: 'function', kind: 'function',
modifiers: [], modifiers: [],
name: 'set', name: 'set',
nodeType: 'FunctionDefinition', nodeType: 'FunctionDefinition',
overrides: null, overrides: null,
parameters: { id: 7, parameters: { id: 7,
nodeType: 'ParameterList', nodeType: 'ParameterList',
parameters: [Array], parameters: [Array],
src: '59:8:0' }, src: '59:8:0' },
returnParameters: { id: 10, returnParameters: { id: 10,
nodeType: 'ParameterList', nodeType: 'ParameterList',
parameters: [Array], parameters: [Array],
src: '83:8:0' }, src: '83:8:0' },
scope: 33, scope: 33,
src: '47:104:0', src: '47:104:0',
stateMutability: 'nonpayable', stateMutability: 'nonpayable',
virtual: false, virtual: false,
visibility: 'public' }, visibility: 'public' },
{ body: { id: 31, nodeType: 'Block', src: '214:17:0', statements: [] }, { body: { id: 31, nodeType: 'Block', src: '214:17:0', statements: [] },
documentation: null, documentation: null,
functionSelector: '6d4ce63c', functionSelector: '6d4ce63c',
id: 32, id: 32,
implemented: true, implemented: true,
kind: 'function', kind: 'function',
modifiers: [], modifiers: [],
name: 'get', name: 'get',
nodeType: 'FunctionDefinition', nodeType: 'FunctionDefinition',
overrides: null, overrides: null,
parameters: parameters:
{ id: 25, { id: 25,
nodeType: 'ParameterList', nodeType: 'ParameterList',
parameters: [], parameters: [],
src: '175:2:0' }, src: '175:2:0' },
returnParameters: returnParameters:
{ id: 30, { id: 30,
nodeType: 'ParameterList', nodeType: 'ParameterList',
parameters: [Array], parameters: [Array],
src: '193:16:0' }, src: '193:16:0' },
scope: 33, scope: 33,
src: '163:68:0', src: '163:68:0',
stateMutability: 'nonpayable', stateMutability: 'nonpayable',
virtual: false, virtual: false,
visibility: 'public' } ], visibility: 'public' } ],
scope: 34, scope: 34,
src: '0:233:0' src: '0:233:0'
} ], } ],
src: '0:233:0' src: '0:233:0'
} }

@ -134,21 +134,21 @@ export function encodeConstructorCallAndLinkLibraries (contract, params, funAbi,
*/ */
export function linkLibraries (contract, linkLibraries, linkReferences, callback) { export function linkLibraries (contract, linkLibraries, linkReferences, callback) {
let bytecodeToDeploy = contract.evm.bytecode.object let bytecodeToDeploy = contract.evm.bytecode.object
if (bytecodeToDeploy.indexOf('_') >= 0) { if (bytecodeToDeploy.indexOf('_') >= 0) {
if (linkLibraries && linkReferences) { if (linkLibraries && linkReferences) {
for (const libFile in linkLibraries) { for (const libFile in linkLibraries) {
for (const lib in linkLibraries[libFile]) { for (const lib in linkLibraries[libFile]) {
const address = linkLibraries[libFile][lib] const address = linkLibraries[libFile][lib]
if (!isValidAddress(address)) return callback(address + ' is not a valid address. Please check the provided address is valid.') if (!isValidAddress(address)) return callback(address + ' is not a valid address. Please check the provided address is valid.')
bytecodeToDeploy = linkLibraryStandardFromlinkReferences(lib, address.replace('0x', ''), bytecodeToDeploy, linkReferences) bytecodeToDeploy = linkLibraryStandardFromlinkReferences(lib, address.replace('0x', ''), bytecodeToDeploy, linkReferences)
}
} }
} }
} }
if (bytecodeToDeploy.indexOf('_') >= 0) { }
return callback('Failed to link some libraries') if (bytecodeToDeploy.indexOf('_') >= 0) {
} return callback('Failed to link some libraries')
return callback(null, bytecodeToDeploy) }
return callback(null, bytecodeToDeploy)
} }
/** /**
@ -459,7 +459,7 @@ export function parseFunctionParams (params) {
args.push(parseFunctionParams(params.substring(i + 1, j))) args.push(parseFunctionParams(params.substring(i + 1, j)))
i = j - 1 i = j - 1
} else if (params.charAt(i) === ',' || i === params.length - 1) { // , or end of string } else if (params.charAt(i) === ',' || i === params.length - 1) { // , or end of string
// if startIndex >= 0, it means a parameter was being parsed, it can be first or other parameter // if startIndex >= 0, it means a parameter was being parsed, it can be first or other parameter
if (startIndex >= 0) { if (startIndex >= 0) {
let param = params.substring(startIndex, i === params.length - 1 ? undefined : i) let param = params.substring(startIndex, i === params.length - 1 ? undefined : i)
param = normalizeParam(param) param = normalizeParam(param)

@ -10,22 +10,22 @@ import { toBuffer, setLengthLeft, isHexString } from '@ethereumjs/util'
*/ */
export const keccak = function(a: Buffer, bits: number = 256): Buffer { export const keccak = function(a: Buffer, bits: number = 256): Buffer {
assertIsBuffer(a) assertIsBuffer(a)
switch (bits) { switch (bits) {
case 224: { case 224: {
return toBuffer(keccak224(a)) return toBuffer(keccak224(a))
} }
case 256: { case 256: {
return toBuffer(k256(a)) return toBuffer(k256(a))
} }
case 384: { case 384: {
return toBuffer(keccak384(a)) return toBuffer(keccak384(a))
} }
case 512: { case 512: {
return toBuffer(keccak512(a)) return toBuffer(keccak512(a))
} }
default: { default: {
throw new Error(`Invald algorithm: keccak${bits}`) throw new Error(`Invald algorithm: keccak${bits}`)
} }
} }
} }

@ -222,7 +222,7 @@ export function getinputParameters (value) {
if (regex && regex[1]) { if (regex && regex[1]) {
return regex[1] return regex[1]
} else } else
return '' return ''
} }
/** /**

@ -183,7 +183,7 @@ tape('ContractParameters - (TxFormat.buildData) - link Libraries', function (t)
function testLinkLibrary (st, fakeDeployedContracts, callbackDeployLibraries) { function testLinkLibrary (st, fakeDeployedContracts, callbackDeployLibraries) {
const deployMsg = ['creation of library test.sol:lib1 pending...', const deployMsg = ['creation of library test.sol:lib1 pending...',
'creation of library test.sol:lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2 pending...'] 'creation of library test.sol:lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2 pending...']
txFormat.buildData('testContractLinkLibrary', context.contract, context.output.contracts, true, context.contract.abi[0], '', (error, data) => { txFormat.buildData('testContractLinkLibrary', context.contract, context.output.contracts, true, context.contract.abi[0], '', (error, data) => {
if (error) { return st.fail(error) } if (error) { return st.fail(error) }
console.log(data) console.log(data)
@ -212,7 +212,7 @@ function testLinkLibrary2 (st, callbackDeployLibraries) {
const data = '608060405234801561001057600080fd5b506101e2806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636d4ce63c14610030575b600080fd5b61003861003a565b005b73f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff1660e01b815260040160006040518083038186803b15801561007e57600080fd5b505af4158015610092573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff1660e01b815260040160006040518083038186803b1580156100da57600080fd5b505af41580156100ee573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff1660e01b815260040160006040518083038186803b15801561013657600080fd5b505af415801561014a573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff1660e01b815260040160006040518083038186803b15801561019257600080fd5b505af41580156101a6573d6000803e3d6000fd5b5050505056fea264697066735822122007784c53df7f324243100f6642d889a08a88831c3811dd13eebe3163b7eb2e5464736f6c63430006000033' const data = '608060405234801561001057600080fd5b506101e2806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636d4ce63c14610030575b600080fd5b61003861003a565b005b73f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff1660e01b815260040160006040518083038186803b15801561007e57600080fd5b505af4158015610092573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff1660e01b815260040160006040518083038186803b1580156100da57600080fd5b505af41580156100ee573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e336344733ae16040518163ffffffff1660e01b815260040160006040518083038186803b15801561013657600080fd5b505af415801561014a573d6000803e3d6000fd5b5050505073f7a10e525d4b168f45f74db1b61f63d3e7619e116344733ae16040518163ffffffff1660e01b815260040160006040518083038186803b15801561019257600080fd5b505af41580156101a6573d6000803e3d6000fd5b5050505056fea264697066735822122007784c53df7f324243100f6642d889a08a88831c3811dd13eebe3163b7eb2e5464736f6c63430006000033'
const deployMsg = ['creation of library test.sol:lib1 pending...', const deployMsg = ['creation of library test.sol:lib1 pending...',
'creation of library test.sol:lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2 pending...'] 'creation of library test.sol:lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2 pending...']
txFormat.encodeConstructorCallAndLinkLibraries(context.contract, '', context.contract.abi[0], librariesReference, context.contract.evm.bytecode.linkReferences, (error, result) => { txFormat.encodeConstructorCallAndLinkLibraries(context.contract, '', context.contract.abi[0], librariesReference, context.contract.evm.bytecode.linkReferences, (error, result) => {
console.log(error, result) console.log(error, result)
st.equal(data, result.dataHex) st.equal(data, result.dataHex)

@ -43,25 +43,25 @@ export class Blocks {
} }
const transactions = block.transactions.map((t) => { const transactions = block.transactions.map((t) => {
const hash = '0x' + t.hash().toString('hex') const hash = '0x' + t.hash().toString('hex')
const tx = this.vmContext.txByHash[hash] const tx = this.vmContext.txByHash[hash]
const receipt = this.vmContext.currentVm.web3vm.txsReceipt[hash] const receipt = this.vmContext.currentVm.web3vm.txsReceipt[hash]
if (receipt) { if (receipt) {
return { return {
blockHash: '0x' + block.hash().toString('hex'), blockHash: '0x' + block.hash().toString('hex'),
blockNumber: bigIntToHex(block.header.number), blockNumber: bigIntToHex(block.header.number),
from: receipt.from, from: receipt.from,
gas: bigIntToHex(receipt.gas), gas: bigIntToHex(receipt.gas),
chainId: '0xd05', chainId: '0xd05',
gasPrice: '0x4a817c800', // 20000000000 gasPrice: '0x4a817c800', // 20000000000
hash: receipt.transactionHash, hash: receipt.transactionHash,
input: receipt.input, input: receipt.input,
nonce: bigIntToHex(tx.nonce), nonce: bigIntToHex(tx.nonce),
transactionIndex: this.TX_INDEX, transactionIndex: this.TX_INDEX,
value: bigIntToHex(tx.value), value: bigIntToHex(tx.value),
to: receipt.to ? receipt.to : null to: receipt.to ? receipt.to : null
}
} }
}
}) })
const b = { const b = {
baseFeePerGas: '0x01', baseFeePerGas: '0x01',
@ -101,22 +101,22 @@ export class Blocks {
const tx = this.vmContext.txByHash[hash] const tx = this.vmContext.txByHash[hash]
const receipt = this.vmContext.currentVm.web3vm.txsReceipt[hash] const receipt = this.vmContext.currentVm.web3vm.txsReceipt[hash]
if (receipt) { if (receipt) {
return { return {
blockHash: '0x' + block.hash().toString('hex'), blockHash: '0x' + block.hash().toString('hex'),
blockNumber: bigIntToHex(block.header.number), blockNumber: bigIntToHex(block.header.number),
from: receipt.from, from: receipt.from,
gas: toHex(receipt.gas), gas: toHex(receipt.gas),
chainId: '0xd05', chainId: '0xd05',
gasPrice: '0x4a817c800', // 20000000000 gasPrice: '0x4a817c800', // 20000000000
hash: receipt.transactionHash, hash: receipt.transactionHash,
input: receipt.input, input: receipt.input,
nonce: bigIntToHex(tx.nonce), nonce: bigIntToHex(tx.nonce),
transactionIndex: this.TX_INDEX, transactionIndex: this.TX_INDEX,
value: bigIntToHex(tx.value), value: bigIntToHex(tx.value),
to: receipt.to ? receipt.to : null to: receipt.to ? receipt.to : null
} }
} }
}) })
const b = { const b = {
baseFeePerGas: '0x01', baseFeePerGas: '0x01',
number: bigIntToHex(block.header.number), number: bigIntToHex(block.header.number),

@ -3,53 +3,53 @@ import helper from './helper'
import { CompilationResult, CompilerInput, CompilationSourceCode } from './types' import { CompilationResult, CompilerInput, CompilationSourceCode } from './types'
export class CompilerAbstract { export class CompilerAbstract {
languageversion: string languageversion: string
data: CompilationResult data: CompilationResult
source: CompilationSourceCode source: CompilationSourceCode
input: CompilerInput input: CompilerInput
constructor (languageversion: string, data: CompilationResult, source: CompilationSourceCode, input?: CompilerInput) { constructor (languageversion: string, data: CompilationResult, source: CompilationSourceCode, input?: CompilerInput) {
this.languageversion = languageversion this.languageversion = languageversion
this.data = data this.data = data
this.source = source // source code this.source = source // source code
this.input = input this.input = input
} }
getContracts () { getContracts () {
return this.data.contracts || {} return this.data.contracts || {}
} }
getContract (name) { getContract (name) {
return helper.getContract(name, this.data.contracts) return helper.getContract(name, this.data.contracts)
} }
visitContracts (calllback) { visitContracts (calllback) {
return helper.visitContracts(this.data.contracts, calllback) return helper.visitContracts(this.data.contracts, calllback)
} }
getData () { getData () {
return this.data return this.data
} }
getInput () { getInput () {
return this.input return this.input
} }
getAsts () { getAsts () {
return this.data.sources // ast return this.data.sources // ast
} }
getSourceName (fileIndex) { getSourceName (fileIndex) {
if (this.data && this.data.sources) { if (this.data && this.data.sources) {
return Object.keys(this.data.sources)[fileIndex] return Object.keys(this.data.sources)[fileIndex]
} else if (Object.keys(this.source.sources).length === 1) { } else if (Object.keys(this.source.sources).length === 1) {
// if we don't have ast, we return the only one filename present. // if we don't have ast, we return the only one filename present.
const sourcesArray = Object.keys(this.source.sources) const sourcesArray = Object.keys(this.source.sources)
return sourcesArray[0] return sourcesArray[0]
}
return null
} }
return null
}
getSourceCode () { getSourceCode () {
return this.source return this.source
} }
} }

@ -295,27 +295,27 @@ export class Compiler {
return return
} }
switch (data.cmd) { switch (data.cmd) {
case 'versionLoaded': case 'versionLoaded':
if (data.data) this.onCompilerLoaded(data.data, data.license) if (data.data) this.onCompilerLoaded(data.data, data.license)
break break
case 'compiled': case 'compiled':
{ {
let result: CompilationResult let result: CompilationResult
if (data.data && data.job !== undefined && data.job >= 0) { if (data.data && data.job !== undefined && data.job >= 0) {
try { try {
result = JSON.parse(data.data) result = JSON.parse(data.data)
} catch (exception) { } catch (exception) {
result = { error: { formattedMessage: 'Invalid JSON output from the compiler: ' + exception } } result = { error: { formattedMessage: 'Invalid JSON output from the compiler: ' + exception } }
} }
let sources: SourceWithTarget = {} let sources: SourceWithTarget = {}
if (data.job in jobs !== undefined) { if (data.job in jobs !== undefined) {
sources = jobs[data.job].sources sources = jobs[data.job].sources
delete jobs[data.job] delete jobs[data.job]
}
this.onCompilationFinished(result, data.missingInputs, sources, data.input, this.state.currentVersion)
}
break
} }
this.onCompilationFinished(result, data.missingInputs, sources, data.input, this.state.currentVersion)
}
break
}
} }
}) })

@ -502,6 +502,6 @@ export interface BytecodeObject {
} }
} }
export interface EsWebWorkerHandlerInterface { export interface EsWebWorkerHandlerInterface {
getWorker(): Worker getWorker(): Worker
} }

@ -6,42 +6,42 @@ const missingInputs: string[] = []
self.onmessage = (e: MessageEvent) => { self.onmessage = (e: MessageEvent) => {
const data: MessageToWorker = e.data const data: MessageToWorker = e.data
switch (data.cmd) { switch (data.cmd) {
case 'loadVersion': case 'loadVersion':
{ {
(self as any).importScripts(data.data) (self as any).importScripts(data.data)
const compiler = setupMethods(self) const compiler = setupMethods(self)
compileJSON = (input) => { compileJSON = (input) => {
try { try {
const missingInputsCallback = (path) => { const missingInputsCallback = (path) => {
missingInputs.push(path) missingInputs.push(path)
return { error: 'Deferred import' } return { error: 'Deferred import' }
}
return compiler.compile(input, { import: missingInputsCallback })
} catch (exception) {
return JSON.stringify({ error: 'Uncaught JavaScript exception:\n' + exception })
}
} }
self.postMessage({ return compiler.compile(input, { import: missingInputsCallback })
cmd: 'versionLoaded', } catch (exception) {
data: compiler.version(), return JSON.stringify({ error: 'Uncaught JavaScript exception:\n' + exception })
license: compiler.license()
})
break
} }
}
self.postMessage({
cmd: 'versionLoaded',
data: compiler.version(),
license: compiler.license()
})
break
}
case 'compile': case 'compile':
missingInputs.length = 0 missingInputs.length = 0
if (data.input && compileJSON) { if (data.input && compileJSON) {
self.postMessage({ self.postMessage({
cmd: 'compiled', cmd: 'compiled',
job: data.job, job: data.job,
timestamp: data.timestamp, timestamp: data.timestamp,
data: compileJSON(data.input), data: compileJSON(data.input),
input: data.input, input: data.input,
missingInputs: missingInputs missingInputs: missingInputs
}) })
} }
break break
} }
} }

@ -1,12 +1,12 @@
class ESWebWorkerHandler { class ESWebWorkerHandler {
constructor() { constructor() {
} }
getWorker () { getWorker () {
// @ts-ignore // @ts-ignore
return new Worker(new URL('./compiler-worker', import.meta.url)) return new Worker(new URL('./compiler-worker', import.meta.url))
} }
} }
export default ESWebWorkerHandler export default ESWebWorkerHandler

@ -31,28 +31,28 @@ const logFmt = winston.format.printf((info) => {
}) })
class Log { class Log {
logger: Logger; logger: Logger;
constructor () { constructor () {
this.logger = winston.createLogger({ this.logger = winston.createLogger({
level: 'info', level: 'info',
transports: [new winston.transports.Console()], transports: [new winston.transports.Console()],
format: winston.format.combine( format: winston.format.combine(
winston.format.colorize({ all: true }), winston.format.colorize({ all: true }),
logFmt logFmt
) )
}) })
} }
setVerbosity (v: LoggerOptions['level']): void { setVerbosity (v: LoggerOptions['level']): void {
this.logger.configure({ this.logger.configure({
level: v, level: v,
transports: [new winston.transports.Console()], transports: [new winston.transports.Console()],
format: winston.format.combine( format: winston.format.combine(
winston.format.colorize({ all: true }), winston.format.colorize({ all: true }),
logFmt logFmt
) )
}) })
} }
} }
export default Log export default Log

@ -3,35 +3,35 @@ import { resolve } from 'path'
import { expect } from 'chai'; import { expect } from 'chai';
describe('testRunner: remix-tests CLI', function(){ describe('testRunner: remix-tests CLI', function(){
this.timeout(120000) this.timeout(120000)
// remix-tests binary, after build, is used as executable // remix-tests binary, after build, is used as executable
const executablePath = resolve(__dirname + '/../../../dist/libs/remix-tests/bin/remix-tests') const executablePath = resolve(__dirname + '/../../../dist/libs/remix-tests/bin/remix-tests')
const result = spawnSync('ls', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) const result = spawnSync('ls', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') })
if(result) { if(result) {
const dirContent = result.stdout.toString() const dirContent = result.stdout.toString()
// Install dependencies if 'node_modules' is not already present // Install dependencies if 'node_modules' is not already present
if(!dirContent.includes('node_modules')) { if(!dirContent.includes('node_modules')) {
execSync('yarn add @remix-project/remix-lib ../../libs/remix-lib', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) execSync('yarn add @remix-project/remix-lib ../../libs/remix-lib', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') })
execSync('yarn add @remix-project/remix-url-resolver ../../libs/remix-url-resolver', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) execSync('yarn add @remix-project/remix-url-resolver ../../libs/remix-url-resolver', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') })
execSync('yarn add @remix-project/remix-solidity ../../libs/remix-solidity', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) execSync('yarn add @remix-project/remix-solidity ../../libs/remix-solidity', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') })
execSync('yarn add @remix-project/remix-simulator ../../libs/remix-simulator', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) execSync('yarn add @remix-project/remix-simulator ../../libs/remix-simulator', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') })
execSync('yarn install', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') }) execSync('yarn install', { cwd: resolve(__dirname + '/../../../dist/libs/remix-tests') })
}
} }
}
describe('test various CLI options', function() { describe('test various CLI options', function() {
it('remix-tests version', () => { it('remix-tests version', () => {
const res = spawnSync(executablePath, ['-V']) const res = spawnSync(executablePath, ['-V'])
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
expect(res.stdout.toString().trim()).to.equal(require('../package.json').version) expect(res.stdout.toString().trim()).to.equal(require('../package.json').version)
}) })
it('remix-tests help', () => { it('remix-tests help', () => {
const res = spawnSync(executablePath, ['-h']) const res = spawnSync(executablePath, ['-h'])
const expectedHelp = `Usage: remix-tests [options] [command] <file_path> const expectedHelp = `Usage: remix-tests [options] [command] <file_path>
Arguments: Arguments:
file_path path to test file or directory file_path path to test file or directory
@ -55,8 +55,8 @@ Options:
Commands: Commands:
version output the version number version output the version number
help output usage information` help output usage information`
expect(res.stdout.toString().trim()).to.equal(expectedHelp) expect(res.stdout.toString().trim()).to.equal(expectedHelp)
}) })
it('remix-tests running a test file', function() { it('remix-tests running a test file', function() {
const res = spawnSync(executablePath, [resolve(__dirname + '/examples_0/assert_ok_test.sol')]) const res = spawnSync(executablePath, [resolve(__dirname + '/examples_0/assert_ok_test.sol')])

@ -14,476 +14,476 @@ import { ResultsInterface, TestCbInterface, ResultCbInterface } from '../src/ind
// In this specific test, we'll use this helper to exclude `time` keys. // In this specific test, we'll use this helper to exclude `time` keys.
// Assertions for the existance of these will be made at the correct places. // Assertions for the existance of these will be made at the correct places.
function deepEqualExcluding(a: any, b: any, excludedKeys: string[]) { function deepEqualExcluding(a: any, b: any, excludedKeys: string[]) {
function removeKeysFromObject(obj: any, excludedKeys: string[]) { function removeKeysFromObject(obj: any, excludedKeys: string[]) {
if (obj !== Object(obj)) { if (obj !== Object(obj)) {
return obj return obj
} }
if (Object.prototype.toString.call(obj) !== '[object Array]') {
obj = Object.assign({}, obj)
for (const key of excludedKeys) {
delete obj[key]
}
return obj if (Object.prototype.toString.call(obj) !== '[object Array]') {
} obj = Object.assign({}, obj)
for (const key of excludedKeys) {
delete obj[key]
}
const newObj = [] return obj
for (const idx in obj) { }
newObj[idx] = removeKeysFromObject(obj[idx], excludedKeys);
}
return newObj const newObj = []
for (const idx in obj) {
newObj[idx] = removeKeysFromObject(obj[idx], excludedKeys);
} }
const aStripped: any = removeKeysFromObject(a, excludedKeys); return newObj
const bStripped: any = removeKeysFromObject(b, excludedKeys); }
assert.deepEqual(aStripped, bStripped)
const aStripped: any = removeKeysFromObject(a, excludedKeys);
const bStripped: any = removeKeysFromObject(b, excludedKeys);
assert.deepEqual(aStripped, bStripped)
} }
let accounts: string[] let accounts: string[]
const provider: any = new Provider() const provider: any = new Provider()
async function compileAndDeploy(filename: string, callback: any) { async function compileAndDeploy(filename: string, callback: any) {
const web3: Web3 = new Web3() const web3: Web3 = new Web3()
const sourceASTs: any = {} const sourceASTs: any = {}
await provider.init() await provider.init()
web3.setProvider(provider) web3.setProvider(provider)
extend(web3) extend(web3)
let compilationData: any let compilationData: any
async.waterfall([ async.waterfall([
function getAccountList(next: any): void { function getAccountList(next: any): void {
web3.eth.getAccounts((_err: Error | null | undefined, _accounts: string[]) => { web3.eth.getAccounts((_err: Error | null | undefined, _accounts: string[]) => {
accounts = _accounts accounts = _accounts
web3.eth.defaultAccount = accounts[0] web3.eth.defaultAccount = accounts[0]
next(_err) next(_err)
}) })
}, },
function compile(next: any): void { function compile(next: any): void {
compileFileOrFiles(filename, false, { accounts }, null, next) compileFileOrFiles(filename, false, { accounts }, null, next)
}, },
function deployAllContracts(compilationResult: compilationInterface, asts, next: any): void { function deployAllContracts(compilationResult: compilationInterface, asts, next: any): void {
for (const filename in asts) { for (const filename in asts) {
if (filename.endsWith('_test.sol')) if (filename.endsWith('_test.sol'))
sourceASTs[filename] = asts[filename].ast sourceASTs[filename] = asts[filename].ast
} }
// eslint-disable-next-line no-useless-catch // eslint-disable-next-line no-useless-catch
try { try {
compilationData = compilationResult compilationData = compilationResult
deployAll(compilationResult, web3, accounts, false, null, next) deployAll(compilationResult, web3, accounts, false, null, next)
} catch (e) { } catch (e) {
throw e throw e
} }
} }
], function (_err: Error | null | undefined, contracts: any): void { ], function (_err: Error | null | undefined, contracts: any): void {
callback(null, compilationData, contracts, sourceASTs, accounts, web3) callback(null, compilationData, contracts, sourceASTs, accounts, web3)
}) })
} }
describe('testRunner', function () { describe('testRunner', function () {
let tests: any[] = [], results: ResultsInterface; let tests: any[] = [], results: ResultsInterface;
const testCallback: TestCbInterface = (err, test) => { const testCallback: TestCbInterface = (err, test) => {
if (err) { throw err } if (err) { throw err }
if (test.type === 'testPass' || test.type === 'testFailure') { if (test.type === 'testPass' || test.type === 'testFailure') {
assert.ok(test.time, 'test time not reported') assert.ok(test.time, 'test time not reported')
assert.ok(!Number.isInteger(test.time || 0), 'test time should not be an integer') assert.ok(!Number.isInteger(test.time || 0), 'test time should not be an integer')
}
tests.push(test)
} }
const resultsCallback = (done) => { tests.push(test)
return (err, _results) => { }
if (err) { throw err }
results = _results const resultsCallback = (done) => {
done() return (err, _results) => {
} if (err) { throw err }
results = _results
done()
} }
}
describe('#runTest', function () { describe('#runTest', function () {
this.timeout(10000) this.timeout(10000)
describe('assert library OK method tests', () => { describe('assert library OK method tests', () => {
const filename: string = __dirname + '/examples_0/assert_ok_test.sol' const filename: string = __dirname + '/examples_0/assert_ok_test.sol'
before((done) => {
compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) => {
runTest('AssertOkTest', contracts.AssertOkTest, compilationData[filename]['AssertOkTest'], asts[filename], { accounts, web3 }, testCallback, resultsCallback(done))
})
})
after(() => { tests = [] })
it('should have 1 passing test', () => {
assert.equal(results.passingNum, 1)
})
it('should have 1 failing test', () => {
assert.equal(results.failureNum, 1)
})
const hhLogs1 = [["AssertOkTest", "okPassTest"]]
const hhLogs2 = [["AssertOkTest", "okFailTest"]]
it('should return', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'AssertOkTest', filename: __dirname + '/examples_0/assert_ok_test.sol' },
{ type: 'testPass', debugTxHash: '0x5b665752a4faf83229259b9b2811d3295be0af633b0051d4b90042283ef55707', value: 'Ok pass test', filename: __dirname + '/examples_0/assert_ok_test.sol', context: 'AssertOkTest', hhLogs: hhLogs1 },
{ type: 'testFailure', debugTxHash: '0xa0a30ad042a7fc3495f72be7ba788d705888ffbbec7173f60bb27e07721510f2', value: 'Ok fail test', filename: __dirname + '/examples_0/assert_ok_test.sol', errMsg: 'okFailTest fails', context: 'AssertOkTest', hhLogs: hhLogs2, assertMethod: 'ok', location: '366:36:0', expected: 'true', returned: 'false' },
], ['time', 'web3'])
})
})
describe('assert library EQUAL method tests', function () { before((done) => {
const filename: string = __dirname + '/examples_0/assert_equal_test.sol' compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) => {
runTest('AssertOkTest', contracts.AssertOkTest, compilationData[filename]['AssertOkTest'], asts[filename], { accounts, web3 }, testCallback, resultsCallback(done))
before((done) => {
compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) => {
runTest('AssertEqualTest', contracts.AssertEqualTest, compilationData[filename]['AssertEqualTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
})
})
after(() => { tests = [] })
it('should have 6 passing test', () => {
assert.equal(results.passingNum, 6)
})
it('should have 6 failing test', () => {
assert.equal(results.failureNum, 6)
})
it('should return', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'AssertEqualTest', filename: __dirname + '/examples_0/assert_equal_test.sol' },
{ type: 'testPass', debugTxHash: '0x233b8d91f0fa068b1a4deae1141178bc3eb79c3d2a6786160595a358363a157c', value: 'Equal uint pass test', filename: __dirname + '/examples_0/assert_equal_test.sol', context: 'AssertEqualTest' },
{ type: 'testFailure', debugTxHash: '0xa5e39c78663c2e5071c08467047ba5b2650d16081b50369700d46d7f90c4d94b', value: 'Equal uint fail test', filename: __dirname + '/examples_0/assert_equal_test.sol', errMsg: 'equalUintFailTest fails', context: 'AssertEqualTest', assertMethod: 'equal', location: '273:57:0', expected: '2', returned: '1' },
{ type: 'testPass', debugTxHash: '0x57af51c2c19db390a4ccf72fa3d32347fb3d998e70820909c7876bd8ccebf8a3', value: 'Equal int pass test', filename: __dirname + '/examples_0/assert_equal_test.sol', context: 'AssertEqualTest' },
{ type: 'testFailure', debugTxHash: '0x710f3a54a561c009fcf0277273b8fe337b2c493e9e83e0ae02786d487339ca7b', value: 'Equal int fail test', filename: __dirname + '/examples_0/assert_equal_test.sol', errMsg: 'equalIntFailTest fails', context: 'AssertEqualTest', assertMethod: 'equal', location: '493:45:0', expected: '2', returned: '-1' },
{ type: 'testPass', debugTxHash: '0x10c1ed8651110ad5de6adcad8e1284aa5c1fd3a998a1e863bbecc0ec855fcd7b', value: 'Equal bool pass test', filename: __dirname + '/examples_0/assert_equal_test.sol', context: 'AssertEqualTest' },
{ type: 'testFailure', debugTxHash: '0x004871a82968f43e02278eab9dd3d7eb0bbe88b64d459efa50065e5996fe5fad', value: 'Equal bool fail test', filename: __dirname + '/examples_0/assert_equal_test.sol', errMsg: 'equalBoolFailTest fails', context: 'AssertEqualTest', assertMethod: 'equal', location: '708:52:0', expected: false, returned: true },
{ type: 'testPass', debugTxHash: '0x64a4d4853ab7907712912cf2120ac2bfd2e08b4767b375250f0e907757546454', value: 'Equal address pass test', filename: __dirname + '/examples_0/assert_equal_test.sol', context: 'AssertEqualTest' },
{ type: 'testFailure', debugTxHash: '0xcf62fb76e3b2eb95d92aa2671a9e81e30fefb944f55e2fb8b97096c45fc74a38', value: 'Equal address fail test', filename: __dirname + '/examples_0/assert_equal_test.sol', errMsg: 'equalAddressFailTest fails', context: 'AssertEqualTest', assertMethod: 'equal', location: '1015:130:0', expected: '0x1c6637567229159d1eFD45f95A6675e77727E013', returned: '0x7994f14563F39875a2F934Ce42cAbF48a93FdDA9' },
{ type: 'testPass', debugTxHash: '0x18ef613acc128a21282e09cf920b32ef3be648bb35c0299471ddbbbeeb0faf8c', value: 'Equal bytes32 pass test', filename: __dirname + '/examples_0/assert_equal_test.sol', context: 'AssertEqualTest' },
{ type: 'testFailure', debugTxHash: '0x86fbf2f14e13d228f80a87a947841270d8c55073adddf78e8d4e2ba05d724ec6', value: 'Equal bytes32 fail test', filename: __dirname + '/examples_0/assert_equal_test.sol', errMsg: 'equalBytes32FailTest fails', context: 'AssertEqualTest', assertMethod: 'equal', location: '1670:48:0', expected: '0x72656d6978000000000000000000000000000000000000000000000000000000', returned: '0x72656d6979000000000000000000000000000000000000000000000000000000' },
{ type: 'testPass', debugTxHash: '0x80b3465f2504b74359790baa009237ba066685b24afa65a31814f1ad1bc4f99f', value: 'Equal string pass test', filename: __dirname + '/examples_0/assert_equal_test.sol', context: 'AssertEqualTest' },
{ type: 'testFailure', debugTxHash: '0x88b035a85c5f87f54a805334817f3e4599b4190d98f25947fe14d7804facd8b7', value: 'Equal string fail test', filename: __dirname + '/examples_0/assert_equal_test.sol', errMsg: 'equalStringFailTest fails', context: 'AssertEqualTest', assertMethod: 'equal', location: '1916:81:0', expected: 'remix-tests', returned: 'remix' }
], ['time', 'web3'])
})
}) })
})
after(() => { tests = [] })
it('should have 1 passing test', () => {
assert.equal(results.passingNum, 1)
})
it('should have 1 failing test', () => {
assert.equal(results.failureNum, 1)
})
const hhLogs1 = [["AssertOkTest", "okPassTest"]]
const hhLogs2 = [["AssertOkTest", "okFailTest"]]
it('should return', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'AssertOkTest', filename: __dirname + '/examples_0/assert_ok_test.sol' },
{ type: 'testPass', debugTxHash: '0x5b665752a4faf83229259b9b2811d3295be0af633b0051d4b90042283ef55707', value: 'Ok pass test', filename: __dirname + '/examples_0/assert_ok_test.sol', context: 'AssertOkTest', hhLogs: hhLogs1 },
{ type: 'testFailure', debugTxHash: '0xa0a30ad042a7fc3495f72be7ba788d705888ffbbec7173f60bb27e07721510f2', value: 'Ok fail test', filename: __dirname + '/examples_0/assert_ok_test.sol', errMsg: 'okFailTest fails', context: 'AssertOkTest', hhLogs: hhLogs2, assertMethod: 'ok', location: '366:36:0', expected: 'true', returned: 'false' },
describe('assert library NOTEQUAL method tests', function () { ], ['time', 'web3'])
const filename: string = __dirname + '/examples_0/assert_notEqual_test.sol' })
})
before((done) => {
compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) => { describe('assert library EQUAL method tests', function () {
runTest('AssertNotEqualTest', contracts.AssertNotEqualTest, compilationData[filename]['AssertNotEqualTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) const filename: string = __dirname + '/examples_0/assert_equal_test.sol'
})
}) before((done) => {
compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) => {
after(() => { tests = [] }) runTest('AssertEqualTest', contracts.AssertEqualTest, compilationData[filename]['AssertEqualTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
it('should have 6 passing test', () => {
assert.equal(results.passingNum, 6)
})
it('should have 6 failing test', () => {
assert.equal(results.failureNum, 6)
})
it('should return', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'AssertNotEqualTest', filename: __dirname + '/examples_0/assert_notEqual_test.sol' },
{ type: 'testPass', debugTxHash: '0xdef34ec7fbc6a3e6c6ef619b424bf8ebf16db16ed3f74500d56d8170d3aeca66', value: 'Not equal uint pass test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', context: 'AssertNotEqualTest' },
{ type: 'testFailure', debugTxHash: '0xfcbd35bc5f460e22e885951d560171d687cf90ccdffc41fb5de1beb7075fe4e9', value: 'Not equal uint fail test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', errMsg: 'notEqualUintFailTest fails', context: 'AssertNotEqualTest', assertMethod: 'notEqual', location: '288:63:0', expected: '1', returned: '1' },
{ type: 'testPass', debugTxHash: '0x7f269855c3fc5c677eca416eb85665b8f10df00d3b7ec5dcc00cbf8e6364cba4', value: 'Not equal int pass test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', context: 'AssertNotEqualTest' },
{ type: 'testFailure', debugTxHash: '0x76555e218571d4ad69496d7d10ae46d30149c4bfd8c6e15ff2a58668ab6fba62', value: 'Not equal int fail test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', errMsg: 'notEqualIntFailTest fails', context: 'AssertNotEqualTest', assertMethod: 'notEqual', location: '525:52:0', expected: '-2', returned: '-2' },
{ type: 'testPass', debugTxHash: '0x5fe790b3f32b9580c1d5f9a2dbb0e10ddcb62846037d3f5800d47a51bb67cc91', value: 'Not equal bool pass test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', context: 'AssertNotEqualTest' },
{ type: 'testFailure', debugTxHash: '0x660d0a73395e6855aea8f6d3450e63640437dc15071842b417c39f40e1d7ae61', value: 'Not equal bool fail test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', errMsg: 'notEqualBoolFailTest fails', context: 'AssertNotEqualTest', assertMethod: 'notEqual', location: '760:57:0', expected: true, returned: true },
{ type: 'testPass', debugTxHash: '0x6fddce5573bd6723acf5a3e4137d698ff78f695873a228939276c4323ddfb132', value: 'Not equal address pass test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', context: 'AssertNotEqualTest' },
// eslint-disable-next-line @typescript-eslint/no-loss-of-precision
{ type: 'testFailure', debugTxHash: '0x51479e46db802fb598c61ca0dd630345b9d70cc58667b5a80aa79e8119fa7787', value: 'Not equal address fail test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', errMsg: 'notEqualAddressFailTest fails', context: 'AssertNotEqualTest', assertMethod: 'notEqual', location: '1084:136:0', expected: 0x7994f14563F39875a2F934Ce42cAbF48a93FdDA9, returned: 0x7994f14563F39875a2F934Ce42cAbF48a93FdDA9 },
{ type: 'testPass', debugTxHash: '0xbcaf6d8977b655fdedb280e0e9221d728706d41e85e0973d00c8da1d128022c7', value: 'Not equal bytes32 pass test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', context: 'AssertNotEqualTest' },
{ type: 'testFailure', debugTxHash: '0x34008ef0ea908fedbf80471424d801f5069e6e46221f8ee4a2ee16776a6eeef6', value: 'Not equal bytes32 fail test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', errMsg: 'notEqualBytes32FailTest fails', context: 'AssertNotEqualTest', assertMethod: 'notEqual', location: '1756:54:0', expected: '0x72656d6978000000000000000000000000000000000000000000000000000000', returned: '0x72656d6978000000000000000000000000000000000000000000000000000000' },
{ type: 'testPass', debugTxHash: '0x8e0bc9dedea6e088ca7bd82b1e9fab516be5a52f7716a26ccca8197236aae105', value: 'Not equal string pass test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', context: 'AssertNotEqualTest' },
{ type: 'testFailure', debugTxHash: '0x13c6d270c3609ef858dd6d0c79433ca0b43e47b485b2e40ffe363f18f2868ea8', value: 'Not equal string fail test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', errMsg: 'notEqualStringFailTest fails', context: 'AssertNotEqualTest', assertMethod: 'notEqual', location: '2026:81:0', expected: 'remix', returned: 'remix' },
], ['time', 'web3'])
})
}) })
})
after(() => { tests = [] })
it('should have 6 passing test', () => {
assert.equal(results.passingNum, 6)
})
it('should have 6 failing test', () => {
assert.equal(results.failureNum, 6)
})
it('should return', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'AssertEqualTest', filename: __dirname + '/examples_0/assert_equal_test.sol' },
{ type: 'testPass', debugTxHash: '0x233b8d91f0fa068b1a4deae1141178bc3eb79c3d2a6786160595a358363a157c', value: 'Equal uint pass test', filename: __dirname + '/examples_0/assert_equal_test.sol', context: 'AssertEqualTest' },
{ type: 'testFailure', debugTxHash: '0xa5e39c78663c2e5071c08467047ba5b2650d16081b50369700d46d7f90c4d94b', value: 'Equal uint fail test', filename: __dirname + '/examples_0/assert_equal_test.sol', errMsg: 'equalUintFailTest fails', context: 'AssertEqualTest', assertMethod: 'equal', location: '273:57:0', expected: '2', returned: '1' },
{ type: 'testPass', debugTxHash: '0x57af51c2c19db390a4ccf72fa3d32347fb3d998e70820909c7876bd8ccebf8a3', value: 'Equal int pass test', filename: __dirname + '/examples_0/assert_equal_test.sol', context: 'AssertEqualTest' },
{ type: 'testFailure', debugTxHash: '0x710f3a54a561c009fcf0277273b8fe337b2c493e9e83e0ae02786d487339ca7b', value: 'Equal int fail test', filename: __dirname + '/examples_0/assert_equal_test.sol', errMsg: 'equalIntFailTest fails', context: 'AssertEqualTest', assertMethod: 'equal', location: '493:45:0', expected: '2', returned: '-1' },
{ type: 'testPass', debugTxHash: '0x10c1ed8651110ad5de6adcad8e1284aa5c1fd3a998a1e863bbecc0ec855fcd7b', value: 'Equal bool pass test', filename: __dirname + '/examples_0/assert_equal_test.sol', context: 'AssertEqualTest' },
{ type: 'testFailure', debugTxHash: '0x004871a82968f43e02278eab9dd3d7eb0bbe88b64d459efa50065e5996fe5fad', value: 'Equal bool fail test', filename: __dirname + '/examples_0/assert_equal_test.sol', errMsg: 'equalBoolFailTest fails', context: 'AssertEqualTest', assertMethod: 'equal', location: '708:52:0', expected: false, returned: true },
{ type: 'testPass', debugTxHash: '0x64a4d4853ab7907712912cf2120ac2bfd2e08b4767b375250f0e907757546454', value: 'Equal address pass test', filename: __dirname + '/examples_0/assert_equal_test.sol', context: 'AssertEqualTest' },
{ type: 'testFailure', debugTxHash: '0xcf62fb76e3b2eb95d92aa2671a9e81e30fefb944f55e2fb8b97096c45fc74a38', value: 'Equal address fail test', filename: __dirname + '/examples_0/assert_equal_test.sol', errMsg: 'equalAddressFailTest fails', context: 'AssertEqualTest', assertMethod: 'equal', location: '1015:130:0', expected: '0x1c6637567229159d1eFD45f95A6675e77727E013', returned: '0x7994f14563F39875a2F934Ce42cAbF48a93FdDA9' },
{ type: 'testPass', debugTxHash: '0x18ef613acc128a21282e09cf920b32ef3be648bb35c0299471ddbbbeeb0faf8c', value: 'Equal bytes32 pass test', filename: __dirname + '/examples_0/assert_equal_test.sol', context: 'AssertEqualTest' },
{ type: 'testFailure', debugTxHash: '0x86fbf2f14e13d228f80a87a947841270d8c55073adddf78e8d4e2ba05d724ec6', value: 'Equal bytes32 fail test', filename: __dirname + '/examples_0/assert_equal_test.sol', errMsg: 'equalBytes32FailTest fails', context: 'AssertEqualTest', assertMethod: 'equal', location: '1670:48:0', expected: '0x72656d6978000000000000000000000000000000000000000000000000000000', returned: '0x72656d6979000000000000000000000000000000000000000000000000000000' },
{ type: 'testPass', debugTxHash: '0x80b3465f2504b74359790baa009237ba066685b24afa65a31814f1ad1bc4f99f', value: 'Equal string pass test', filename: __dirname + '/examples_0/assert_equal_test.sol', context: 'AssertEqualTest' },
{ type: 'testFailure', debugTxHash: '0x88b035a85c5f87f54a805334817f3e4599b4190d98f25947fe14d7804facd8b7', value: 'Equal string fail test', filename: __dirname + '/examples_0/assert_equal_test.sol', errMsg: 'equalStringFailTest fails', context: 'AssertEqualTest', assertMethod: 'equal', location: '1916:81:0', expected: 'remix-tests', returned: 'remix' }
], ['time', 'web3'])
})
})
describe('assert library GREATERTHAN method tests', function () { describe('assert library NOTEQUAL method tests', function () {
const filename: string = __dirname + '/examples_0/assert_greaterThan_test.sol' const filename: string = __dirname + '/examples_0/assert_notEqual_test.sol'
before((done) => { before((done) => {
compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) => { compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) => {
runTest('AssertGreaterThanTest', contracts.AssertGreaterThanTest, compilationData[filename]['AssertGreaterThanTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('AssertNotEqualTest', contracts.AssertNotEqualTest, compilationData[filename]['AssertNotEqualTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
})
})
after(() => { tests = [] })
it('should have 4 passing test', () => {
assert.equal(results.passingNum, 4)
})
it('should have 4 failing test', () => {
assert.equal(results.failureNum, 4)
})
it('should return', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'AssertGreaterThanTest', filename: __dirname + '/examples_0/assert_greaterThan_test.sol' },
{ type: 'testPass', debugTxHash: '0xdc325916fd93227b76231131e52e67f8913d395098c5ac767032db9bd757a91c', value: 'Greater than uint pass test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', context: 'AssertGreaterThanTest' },
{ type: 'testFailure', debugTxHash: '0xf98eea22bb86f13e0bb4072df22b540289a46b332bdb203a1e488d7e14a1dcd4', value: 'Greater than uint fail test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', errMsg: 'greaterThanUintFailTest fails', context: 'AssertGreaterThanTest', assertMethod: 'greaterThan', location: '303:69:0', expected: '4', returned: '1' },
{ type: 'testPass', debugTxHash: '0xef5ef38329ba6aac2f868d53d803053c52b1895a2c25b704260435c141a63bfc', value: 'Greater than int pass test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', context: 'AssertGreaterThanTest' },
{ type: 'testFailure', debugTxHash: '0x6b9430f3f12c12fb11e5a8d32fef849ab34614e644be20c6b41a25e510453440', value: 'Greater than int fail test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', errMsg: 'greaterThanIntFailTest fails', context: 'AssertGreaterThanTest', assertMethod: 'greaterThan', location: '569:67:0', expected: '1', returned: '-1' },
{ type: 'testPass', debugTxHash: '0x4c6e10815a5e82bf2c60950606dc886317f680028a9229ba2dda17b5ea36325a', value: 'Greater than uint int pass test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', context: 'AssertGreaterThanTest' },
{ type: 'testFailure', debugTxHash: '0x989c405c32c8e270a5dea69e6250a514c05dacd6fcf018365a241abc28c2497b', value: 'Greater than uint int fail test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', errMsg: 'greaterThanUintIntFailTest fails', context: 'AssertGreaterThanTest', assertMethod: 'greaterThan', location: '845:71:0', expected: '2', returned: '1' },
{ type: 'testPass', debugTxHash: '0x9fed670ae2061929f71780835b7ea3eb7da6d4fb553cd2d5f62950c353165861', value: 'Greater than int uint pass test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', context: 'AssertGreaterThanTest' },
{ type: 'testFailure', debugTxHash: '0xcf394fd279293cdcf58efc42f3a443595fdb171769a45df01b0c84cd76b3a9a2', value: 'Greater than int uint fail test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', errMsg: 'greaterThanIntUintFailTest fails', context: 'AssertGreaterThanTest', assertMethod: 'greaterThan', location: '1125:76:0', expected: '115792089237316195423570985008687907853269984665640564039457584007913129639836', returned: '100' }
], ['time', 'web3'])
})
}) })
})
after(() => { tests = [] })
it('should have 6 passing test', () => {
assert.equal(results.passingNum, 6)
})
it('should have 6 failing test', () => {
assert.equal(results.failureNum, 6)
})
it('should return', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'AssertNotEqualTest', filename: __dirname + '/examples_0/assert_notEqual_test.sol' },
{ type: 'testPass', debugTxHash: '0xdef34ec7fbc6a3e6c6ef619b424bf8ebf16db16ed3f74500d56d8170d3aeca66', value: 'Not equal uint pass test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', context: 'AssertNotEqualTest' },
{ type: 'testFailure', debugTxHash: '0xfcbd35bc5f460e22e885951d560171d687cf90ccdffc41fb5de1beb7075fe4e9', value: 'Not equal uint fail test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', errMsg: 'notEqualUintFailTest fails', context: 'AssertNotEqualTest', assertMethod: 'notEqual', location: '288:63:0', expected: '1', returned: '1' },
{ type: 'testPass', debugTxHash: '0x7f269855c3fc5c677eca416eb85665b8f10df00d3b7ec5dcc00cbf8e6364cba4', value: 'Not equal int pass test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', context: 'AssertNotEqualTest' },
{ type: 'testFailure', debugTxHash: '0x76555e218571d4ad69496d7d10ae46d30149c4bfd8c6e15ff2a58668ab6fba62', value: 'Not equal int fail test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', errMsg: 'notEqualIntFailTest fails', context: 'AssertNotEqualTest', assertMethod: 'notEqual', location: '525:52:0', expected: '-2', returned: '-2' },
{ type: 'testPass', debugTxHash: '0x5fe790b3f32b9580c1d5f9a2dbb0e10ddcb62846037d3f5800d47a51bb67cc91', value: 'Not equal bool pass test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', context: 'AssertNotEqualTest' },
{ type: 'testFailure', debugTxHash: '0x660d0a73395e6855aea8f6d3450e63640437dc15071842b417c39f40e1d7ae61', value: 'Not equal bool fail test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', errMsg: 'notEqualBoolFailTest fails', context: 'AssertNotEqualTest', assertMethod: 'notEqual', location: '760:57:0', expected: true, returned: true },
{ type: 'testPass', debugTxHash: '0x6fddce5573bd6723acf5a3e4137d698ff78f695873a228939276c4323ddfb132', value: 'Not equal address pass test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', context: 'AssertNotEqualTest' },
// eslint-disable-next-line @typescript-eslint/no-loss-of-precision
{ type: 'testFailure', debugTxHash: '0x51479e46db802fb598c61ca0dd630345b9d70cc58667b5a80aa79e8119fa7787', value: 'Not equal address fail test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', errMsg: 'notEqualAddressFailTest fails', context: 'AssertNotEqualTest', assertMethod: 'notEqual', location: '1084:136:0', expected: 0x7994f14563F39875a2F934Ce42cAbF48a93FdDA9, returned: 0x7994f14563F39875a2F934Ce42cAbF48a93FdDA9 },
{ type: 'testPass', debugTxHash: '0xbcaf6d8977b655fdedb280e0e9221d728706d41e85e0973d00c8da1d128022c7', value: 'Not equal bytes32 pass test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', context: 'AssertNotEqualTest' },
{ type: 'testFailure', debugTxHash: '0x34008ef0ea908fedbf80471424d801f5069e6e46221f8ee4a2ee16776a6eeef6', value: 'Not equal bytes32 fail test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', errMsg: 'notEqualBytes32FailTest fails', context: 'AssertNotEqualTest', assertMethod: 'notEqual', location: '1756:54:0', expected: '0x72656d6978000000000000000000000000000000000000000000000000000000', returned: '0x72656d6978000000000000000000000000000000000000000000000000000000' },
{ type: 'testPass', debugTxHash: '0x8e0bc9dedea6e088ca7bd82b1e9fab516be5a52f7716a26ccca8197236aae105', value: 'Not equal string pass test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', context: 'AssertNotEqualTest' },
{ type: 'testFailure', debugTxHash: '0x13c6d270c3609ef858dd6d0c79433ca0b43e47b485b2e40ffe363f18f2868ea8', value: 'Not equal string fail test', filename: __dirname + '/examples_0/assert_notEqual_test.sol', errMsg: 'notEqualStringFailTest fails', context: 'AssertNotEqualTest', assertMethod: 'notEqual', location: '2026:81:0', expected: 'remix', returned: 'remix' },
], ['time', 'web3'])
})
})
describe('assert library LESSERTHAN method tests', function () { describe('assert library GREATERTHAN method tests', function () {
const filename: string = __dirname + '/examples_0/assert_lesserThan_test.sol' const filename: string = __dirname + '/examples_0/assert_greaterThan_test.sol'
before((done) => { before((done) => {
compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) => { compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) => {
runTest('AssertLesserThanTest', contracts.AssertLesserThanTest, compilationData[filename]['AssertLesserThanTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('AssertGreaterThanTest', contracts.AssertGreaterThanTest, compilationData[filename]['AssertGreaterThanTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
})
})
after(() => { tests = [] })
it('should have 4 passing test', () => {
assert.equal(results.passingNum, 4)
})
it('should have 4 failing test', () => {
assert.equal(results.failureNum, 4)
})
it('should return', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'AssertLesserThanTest', filename: __dirname + '/examples_0/assert_lesserThan_test.sol' },
{ type: 'testPass', debugTxHash: '0x524fb46aa0e8a78bc11a99432908d422450c2933d837f858aeacba9b84706d5c', value: 'Lesser than uint pass test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', context: 'AssertLesserThanTest' },
{ type: 'testFailure', debugTxHash: '0x0551a67b10b9e13182e8bdb4e530ed92466d5054ae959f999f2c558da2c39d22', value: 'Lesser than uint fail test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', errMsg: 'lesserThanUintFailTest fails', context: 'AssertLesserThanTest', assertMethod: 'lesserThan', location: '298:67:0', expected: '2', returned: '4' },
{ type: 'testPass', debugTxHash: '0x6d63958d8c3230e837d0ca8335e57262c6e0c6b2c07a5b481842b9ad7329ac28', value: 'Lesser than int pass test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', context: 'AssertLesserThanTest' },
{ type: 'testFailure', debugTxHash: '0x38e96ef44f4e785db4d40a95862a9797e8cef6de0ce1d059da72ff42e2f3ca62', value: 'Lesser than int fail test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', errMsg: 'lesserThanIntFailTest fails', context: 'AssertLesserThanTest', assertMethod: 'lesserThan', location: '557:65:0', expected: '-1', returned: '1' },
{ type: 'testPass', debugTxHash: '0x699f9fc2bf7a14134e89b94cd9dc1c537b5d4581a1c26a34a0c3343ddede9608', value: 'Lesser than uint int pass test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', context: 'AssertLesserThanTest' },
{ type: 'testFailure', debugTxHash: '0xce1391dcfbfdc6c611e357e6c1c9f6cd9f257153ee400cb80bd36af6d239c342', value: 'Lesser than uint int fail test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', errMsg: 'lesserThanUintIntFailTest fails', context: 'AssertLesserThanTest', assertMethod: 'lesserThan', location: '826:71:0', expected: '-1', returned: '115792089237316195423570985008687907853269984665640564039457584007913129639935' },
{ type: 'testPass', debugTxHash: '0x7040e6664c13e6b35ef1daaef93a8cae36a62150d818183892096a98b921800c', value: 'Lesser than int uint pass test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', context: 'AssertLesserThanTest' },
{ type: 'testFailure', debugTxHash: '0x8c58bb433ea41760dcf11114232407d703e8ebf7d5e9637e2923282eae5caee6', value: 'Lesser than int uint fail test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', errMsg: 'lesserThanIntUintFailTest fails', context: 'AssertLesserThanTest', assertMethod: 'lesserThan', location: '1105:69:0', expected: '1', returned: '1' },
], ['time', 'web3'])
})
}) })
})
after(() => { tests = [] })
it('should have 4 passing test', () => {
assert.equal(results.passingNum, 4)
})
it('should have 4 failing test', () => {
assert.equal(results.failureNum, 4)
})
it('should return', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'AssertGreaterThanTest', filename: __dirname + '/examples_0/assert_greaterThan_test.sol' },
{ type: 'testPass', debugTxHash: '0xdc325916fd93227b76231131e52e67f8913d395098c5ac767032db9bd757a91c', value: 'Greater than uint pass test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', context: 'AssertGreaterThanTest' },
{ type: 'testFailure', debugTxHash: '0xf98eea22bb86f13e0bb4072df22b540289a46b332bdb203a1e488d7e14a1dcd4', value: 'Greater than uint fail test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', errMsg: 'greaterThanUintFailTest fails', context: 'AssertGreaterThanTest', assertMethod: 'greaterThan', location: '303:69:0', expected: '4', returned: '1' },
{ type: 'testPass', debugTxHash: '0xef5ef38329ba6aac2f868d53d803053c52b1895a2c25b704260435c141a63bfc', value: 'Greater than int pass test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', context: 'AssertGreaterThanTest' },
{ type: 'testFailure', debugTxHash: '0x6b9430f3f12c12fb11e5a8d32fef849ab34614e644be20c6b41a25e510453440', value: 'Greater than int fail test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', errMsg: 'greaterThanIntFailTest fails', context: 'AssertGreaterThanTest', assertMethod: 'greaterThan', location: '569:67:0', expected: '1', returned: '-1' },
{ type: 'testPass', debugTxHash: '0x4c6e10815a5e82bf2c60950606dc886317f680028a9229ba2dda17b5ea36325a', value: 'Greater than uint int pass test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', context: 'AssertGreaterThanTest' },
{ type: 'testFailure', debugTxHash: '0x989c405c32c8e270a5dea69e6250a514c05dacd6fcf018365a241abc28c2497b', value: 'Greater than uint int fail test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', errMsg: 'greaterThanUintIntFailTest fails', context: 'AssertGreaterThanTest', assertMethod: 'greaterThan', location: '845:71:0', expected: '2', returned: '1' },
{ type: 'testPass', debugTxHash: '0x9fed670ae2061929f71780835b7ea3eb7da6d4fb553cd2d5f62950c353165861', value: 'Greater than int uint pass test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', context: 'AssertGreaterThanTest' },
{ type: 'testFailure', debugTxHash: '0xcf394fd279293cdcf58efc42f3a443595fdb171769a45df01b0c84cd76b3a9a2', value: 'Greater than int uint fail test', filename: __dirname + '/examples_0/assert_greaterThan_test.sol', errMsg: 'greaterThanIntUintFailTest fails', context: 'AssertGreaterThanTest', assertMethod: 'greaterThan', location: '1125:76:0', expected: '115792089237316195423570985008687907853269984665640564039457584007913129639836', returned: '100' }
], ['time', 'web3'])
})
})
describe('test with before', function () { describe('assert library LESSERTHAN method tests', function () {
const filename: string = __dirname + '/examples_1/simple_storage_test.sol' const filename: string = __dirname + '/examples_0/assert_lesserThan_test.sol'
before((done) => { before((done) => {
compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) => { compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) => {
runTest('MyTest', contracts.MyTest, compilationData[filename]['MyTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('AssertLesserThanTest', contracts.AssertLesserThanTest, compilationData[filename]['AssertLesserThanTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
})
})
after(() => { tests = [] })
it('should have 3 passing test', () => {
assert.equal(results.passingNum, 3)
})
it('should have 1 failing test', () => {
assert.equal(results.failureNum, 1)
})
it('should return 6 messages', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'MyTest', filename: __dirname + '/examples_1/simple_storage_test.sol' },
{ type: 'testPass', debugTxHash: '0xed5b6898331119c6e3d1185b9de65d87ad7329cc629a8f2d43b966cf180a5dc1', value: 'Initial value should be100', filename: __dirname + '/examples_1/simple_storage_test.sol', context: 'MyTest' },
{ type: 'testPass', debugTxHash: '0x79cae5c4f44edfd7ae3490e01c75df5741b107672cef5e69800e4d30d380a721', value: 'Initial value should not be200', filename: __dirname + '/examples_1/simple_storage_test.sol', context: 'MyTest' },
{ type: 'testFailure', debugTxHash: '0x24a20f7643e88f891e469ef495911ab0b75f99e2b09b9b091e688674910d1506', value: 'Should trigger one fail', filename: __dirname + '/examples_1/simple_storage_test.sol', errMsg: 'uint test 1 fails', context: 'MyTest', assertMethod: 'equal', location: '532:51:1', expected: '2', returned: '1' },
{ type: 'testPass', debugTxHash: '0x08b1f60c908b7e6cf2dd24fc166c755f0fe5336aebfb325cae4ce00ea9bbf932', value: 'Should trigger one pass', filename: __dirname + '/examples_1/simple_storage_test.sol', context: 'MyTest' }
], ['time', 'web3'])
})
}) })
})
after(() => { tests = [] })
it('should have 4 passing test', () => {
assert.equal(results.passingNum, 4)
})
it('should have 4 failing test', () => {
assert.equal(results.failureNum, 4)
})
it('should return', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'AssertLesserThanTest', filename: __dirname + '/examples_0/assert_lesserThan_test.sol' },
{ type: 'testPass', debugTxHash: '0x524fb46aa0e8a78bc11a99432908d422450c2933d837f858aeacba9b84706d5c', value: 'Lesser than uint pass test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', context: 'AssertLesserThanTest' },
{ type: 'testFailure', debugTxHash: '0x0551a67b10b9e13182e8bdb4e530ed92466d5054ae959f999f2c558da2c39d22', value: 'Lesser than uint fail test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', errMsg: 'lesserThanUintFailTest fails', context: 'AssertLesserThanTest', assertMethod: 'lesserThan', location: '298:67:0', expected: '2', returned: '4' },
{ type: 'testPass', debugTxHash: '0x6d63958d8c3230e837d0ca8335e57262c6e0c6b2c07a5b481842b9ad7329ac28', value: 'Lesser than int pass test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', context: 'AssertLesserThanTest' },
{ type: 'testFailure', debugTxHash: '0x38e96ef44f4e785db4d40a95862a9797e8cef6de0ce1d059da72ff42e2f3ca62', value: 'Lesser than int fail test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', errMsg: 'lesserThanIntFailTest fails', context: 'AssertLesserThanTest', assertMethod: 'lesserThan', location: '557:65:0', expected: '-1', returned: '1' },
{ type: 'testPass', debugTxHash: '0x699f9fc2bf7a14134e89b94cd9dc1c537b5d4581a1c26a34a0c3343ddede9608', value: 'Lesser than uint int pass test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', context: 'AssertLesserThanTest' },
{ type: 'testFailure', debugTxHash: '0xce1391dcfbfdc6c611e357e6c1c9f6cd9f257153ee400cb80bd36af6d239c342', value: 'Lesser than uint int fail test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', errMsg: 'lesserThanUintIntFailTest fails', context: 'AssertLesserThanTest', assertMethod: 'lesserThan', location: '826:71:0', expected: '-1', returned: '115792089237316195423570985008687907853269984665640564039457584007913129639935' },
{ type: 'testPass', debugTxHash: '0x7040e6664c13e6b35ef1daaef93a8cae36a62150d818183892096a98b921800c', value: 'Lesser than int uint pass test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', context: 'AssertLesserThanTest' },
{ type: 'testFailure', debugTxHash: '0x8c58bb433ea41760dcf11114232407d703e8ebf7d5e9637e2923282eae5caee6', value: 'Lesser than int uint fail test', filename: __dirname + '/examples_0/assert_lesserThan_test.sol', errMsg: 'lesserThanIntUintFailTest fails', context: 'AssertLesserThanTest', assertMethod: 'lesserThan', location: '1105:69:0', expected: '1', returned: '1' },
], ['time', 'web3'])
})
})
describe('test with before', function () {
const filename: string = __dirname + '/examples_1/simple_storage_test.sol'
describe('test with beforeEach', function () { before((done) => {
const filename: string = __dirname + '/examples_2/simple_storage_test.sol' compileAndDeploy(filename, (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) => {
runTest('MyTest', contracts.MyTest, compilationData[filename]['MyTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
before(done => {
compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) {
runTest('MyTest', contracts.MyTest, compilationData[filename]['MyTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
})
})
after(() => { tests = [] })
it('should have 2 passing tests', () => {
assert.equal(results.passingNum, 2)
})
it('should 0 failing tests', () => {
assert.equal(results.failureNum, 0)
})
it('should return 4 messages', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'MyTest', filename: __dirname + '/examples_2/simple_storage_test.sol' },
{ type: 'testPass', debugTxHash: '0xed5b6898331119c6e3d1185b9de65d87ad7329cc629a8f2d43b966cf180a5dc1', value: 'Initial value should be100', filename: __dirname + '/examples_2/simple_storage_test.sol', context: 'MyTest' },
{ type: 'testPass', debugTxHash: '0x8ed5b4858405b43ad4052f5690b4b711c0f6cdeb67a64f54084417d43bc54308', value: 'Value is set200', filename: __dirname + '/examples_2/simple_storage_test.sol', context: 'MyTest' }
], ['time', 'web3'])
})
}) })
})
after(() => { tests = [] })
it('should have 3 passing test', () => {
assert.equal(results.passingNum, 3)
})
it('should have 1 failing test', () => {
assert.equal(results.failureNum, 1)
})
it('should return 6 messages', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'MyTest', filename: __dirname + '/examples_1/simple_storage_test.sol' },
{ type: 'testPass', debugTxHash: '0xed5b6898331119c6e3d1185b9de65d87ad7329cc629a8f2d43b966cf180a5dc1', value: 'Initial value should be100', filename: __dirname + '/examples_1/simple_storage_test.sol', context: 'MyTest' },
{ type: 'testPass', debugTxHash: '0x79cae5c4f44edfd7ae3490e01c75df5741b107672cef5e69800e4d30d380a721', value: 'Initial value should not be200', filename: __dirname + '/examples_1/simple_storage_test.sol', context: 'MyTest' },
{ type: 'testFailure', debugTxHash: '0x24a20f7643e88f891e469ef495911ab0b75f99e2b09b9b091e688674910d1506', value: 'Should trigger one fail', filename: __dirname + '/examples_1/simple_storage_test.sol', errMsg: 'uint test 1 fails', context: 'MyTest', assertMethod: 'equal', location: '532:51:1', expected: '2', returned: '1' },
{ type: 'testPass', debugTxHash: '0x08b1f60c908b7e6cf2dd24fc166c755f0fe5336aebfb325cae4ce00ea9bbf932', value: 'Should trigger one pass', filename: __dirname + '/examples_1/simple_storage_test.sol', context: 'MyTest' }
], ['time', 'web3'])
})
})
describe('test with beforeEach', function () {
const filename: string = __dirname + '/examples_2/simple_storage_test.sol'
// Test string equality before(done => {
describe('test string equality', function () { compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) {
const filename: string = __dirname + '/examples_3/simple_string_test.sol' runTest('MyTest', contracts.MyTest, compilationData[filename]['MyTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
before(done => {
compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) {
runTest('StringTest', contracts.StringTest, compilationData[filename]['StringTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
})
})
after(() => { tests = [] })
it('should 2 passing tests', () => {
assert.equal(results.passingNum, 2)
})
it('should return 4 messages', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'StringTest', filename: __dirname + '/examples_3/simple_string_test.sol' },
{ type: 'testPass', debugTxHash: '0x3567da76ffbec37e3b43a41987a7ff3e61b41b4c544f35c010d2d4b39568d6d4', value: 'Initial value should be hello world', filename: __dirname + '/examples_3/simple_string_test.sol', context: 'StringTest' },
{ type: 'testPass', debugTxHash: '0x8619b743ccc99be7d5347a064732474b2d1b69844be65b0e7754c6ac1340d275', value: 'Value should not be hello wordl', filename: __dirname + '/examples_3/simple_string_test.sol', context: 'StringTest' }
], ['time', 'web3'])
})
}) })
})
after(() => { tests = [] })
it('should have 2 passing tests', () => {
assert.equal(results.passingNum, 2)
})
it('should 0 failing tests', () => {
assert.equal(results.failureNum, 0)
})
it('should return 4 messages', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'MyTest', filename: __dirname + '/examples_2/simple_storage_test.sol' },
{ type: 'testPass', debugTxHash: '0xed5b6898331119c6e3d1185b9de65d87ad7329cc629a8f2d43b966cf180a5dc1', value: 'Initial value should be100', filename: __dirname + '/examples_2/simple_storage_test.sol', context: 'MyTest' },
{ type: 'testPass', debugTxHash: '0x8ed5b4858405b43ad4052f5690b4b711c0f6cdeb67a64f54084417d43bc54308', value: 'Value is set200', filename: __dirname + '/examples_2/simple_storage_test.sol', context: 'MyTest' }
], ['time', 'web3'])
})
})
// Test multiple directory import in test contract // Test string equality
describe('test multiple directory import in test contract', function () { describe('test string equality', function () {
const filename: string = __dirname + '/examples_5/test/simple_storage_test.sol' const filename: string = __dirname + '/examples_3/simple_string_test.sol'
before(done => { before(done => {
compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) { compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) {
runTest('StorageResolveTest', contracts.StorageResolveTest, compilationData[filename]['StorageResolveTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('StringTest', contracts.StringTest, compilationData[filename]['StringTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
})
})
after(() => { tests = [] })
it('should 3 passing tests', () => {
assert.equal(results.passingNum, 3)
})
it('should return 4 messages', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'StorageResolveTest', filename: __dirname + '/examples_5/test/simple_storage_test.sol' },
{ type: 'testPass', debugTxHash: '0xed5b6898331119c6e3d1185b9de65d87ad7329cc629a8f2d43b966cf180a5dc1', value: 'Initial value should be100', filename: __dirname + '/examples_5/test/simple_storage_test.sol', context: 'StorageResolveTest' },
{ type: 'testPass', debugTxHash: '0x6893fe4f5a83cc51f03c9237ab93b93ffd826236167d58e20666be4c1b3128a4', value: 'Check if even', filename: __dirname + '/examples_5/test/simple_storage_test.sol', context: 'StorageResolveTest' },
{ type: 'testPass', debugTxHash: '0x64e600b32be681b68926660042ddd96f22d07949b424959811b8acb56e72f719', value: 'Check if odd', filename: __dirname + '/examples_5/test/simple_storage_test.sol', context: 'StorageResolveTest' }
], ['time', 'web3'])
})
}) })
})
after(() => { tests = [] })
it('should 2 passing tests', () => {
assert.equal(results.passingNum, 2)
})
it('should return 4 messages', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'StringTest', filename: __dirname + '/examples_3/simple_string_test.sol' },
{ type: 'testPass', debugTxHash: '0x3567da76ffbec37e3b43a41987a7ff3e61b41b4c544f35c010d2d4b39568d6d4', value: 'Initial value should be hello world', filename: __dirname + '/examples_3/simple_string_test.sol', context: 'StringTest' },
{ type: 'testPass', debugTxHash: '0x8619b743ccc99be7d5347a064732474b2d1b69844be65b0e7754c6ac1340d275', value: 'Value should not be hello wordl', filename: __dirname + '/examples_3/simple_string_test.sol', context: 'StringTest' }
], ['time', 'web3'])
})
})
//Test SafeMath library methods // Test multiple directory import in test contract
describe('test SafeMath library', function () { describe('test multiple directory import in test contract', function () {
const filename: string = __dirname + '/examples_4/SafeMath_test.sol' const filename: string = __dirname + '/examples_5/test/simple_storage_test.sol'
before(done => { before(done => {
compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) { compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) {
runTest('SafeMathTest', contracts.SafeMathTest, compilationData[filename]['SafeMathTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) runTest('StorageResolveTest', contracts.StorageResolveTest, compilationData[filename]['StorageResolveTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
}) })
}) })
after(() => { tests = [] })
it('should 3 passing tests', () => {
assert.equal(results.passingNum, 3)
})
it('should return 4 messages', () => {
deepEqualExcluding(tests, [
{ type: 'accountList', value: accounts },
{ type: 'contract', value: 'StorageResolveTest', filename: __dirname + '/examples_5/test/simple_storage_test.sol' },
{ type: 'testPass', debugTxHash: '0xed5b6898331119c6e3d1185b9de65d87ad7329cc629a8f2d43b966cf180a5dc1', value: 'Initial value should be100', filename: __dirname + '/examples_5/test/simple_storage_test.sol', context: 'StorageResolveTest' },
{ type: 'testPass', debugTxHash: '0x6893fe4f5a83cc51f03c9237ab93b93ffd826236167d58e20666be4c1b3128a4', value: 'Check if even', filename: __dirname + '/examples_5/test/simple_storage_test.sol', context: 'StorageResolveTest' },
{ type: 'testPass', debugTxHash: '0x64e600b32be681b68926660042ddd96f22d07949b424959811b8acb56e72f719', value: 'Check if odd', filename: __dirname + '/examples_5/test/simple_storage_test.sol', context: 'StorageResolveTest' }
], ['time', 'web3'])
})
})
after(() => { tests = [] }) //Test SafeMath library methods
describe('test SafeMath library', function () {
const filename: string = __dirname + '/examples_4/SafeMath_test.sol'
it('should have 10 passing tests', () => { before(done => {
assert.equal(results.passingNum, 10) compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) {
}) runTest('SafeMathTest', contracts.SafeMathTest, compilationData[filename]['SafeMathTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
it('should have 0 failing tests', () => {
assert.equal(results.failureNum, 0)
})
}) })
})
//Test signed/unsigned integer weight after(() => { tests = [] })
describe('test number weight', function () {
const filename: string = __dirname + '/number/number_test.sol'
before(done => { it('should have 10 passing tests', () => {
compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) { assert.equal(results.passingNum, 10)
runTest('IntegerTest', contracts.IntegerTest, compilationData[filename]['IntegerTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) })
}) it('should have 0 failing tests', () => {
}) assert.equal(results.failureNum, 0)
})
})
after(() => { tests = [] }) //Test signed/unsigned integer weight
describe('test number weight', function () {
const filename: string = __dirname + '/number/number_test.sol'
it('should have 6 passing tests', () => { before(done => {
assert.equal(results.passingNum, 6) compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) {
}) runTest('IntegerTest', contracts.IntegerTest, compilationData[filename]['IntegerTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
it('should have 2 failing tests', () => {
assert.equal(results.failureNum, 2)
})
}) })
})
// Test Transaction with custom sender & value after(() => { tests = [] })
describe('various sender', function () {
const filename: string = __dirname + '/various_sender/sender_and_value_test.sol'
before(done => { it('should have 6 passing tests', () => {
compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) { assert.equal(results.passingNum, 6)
runTest('SenderAndValueTest', contracts.SenderAndValueTest, compilationData[filename]['SenderAndValueTest'], asts[filename], { accounts }, testCallback, resultsCallback(done)) })
}) it('should have 2 failing tests', () => {
}) assert.equal(results.failureNum, 2)
})
})
after(() => { tests = [] }) // Test Transaction with custom sender & value
describe('various sender', function () {
const filename: string = __dirname + '/various_sender/sender_and_value_test.sol'
it('should have 17 passing tests', () => { before(done => {
assert.equal(results.passingNum, 17) compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) {
}) runTest('SenderAndValueTest', contracts.SenderAndValueTest, compilationData[filename]['SenderAndValueTest'], asts[filename], { accounts }, testCallback, resultsCallback(done))
it('should have 0 failing tests', () => {
assert.equal(results.failureNum, 0)
})
}) })
})
// Test `runTest` method without sending contract object (should throw error) after(() => { tests = [] })
describe('runTest method without contract json interface', function () {
const filename: string = __dirname + '/various_sender/sender_and_value_test.sol' it('should have 17 passing tests', () => {
const errorCallback: any = (done) => { assert.equal(results.passingNum, 17)
return (err, _results) => { })
if (err && err.message.includes('Contract interface not available')) { it('should have 0 failing tests', () => {
results = _results assert.equal(results.failureNum, 0)
done() })
} })
else throw err
}
}
before(done => {
compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) {
runTest('SenderAndValueTest', undefined, compilationData[filename]['SenderAndValueTest'], asts[filename], { accounts }, testCallback, errorCallback(done))
})
})
it('should have 0 passing tests', () => {
assert.equal(results.passingNum, 0)
})
it('should have 0 failing tests', () => {
assert.equal(results.failureNum, 0)
})
})
// Test `runTest` method without sending contract object (should throw error)
describe('runTest method without contract json interface', function () {
const filename: string = __dirname + '/various_sender/sender_and_value_test.sol'
const errorCallback: any = (done) => {
return (err, _results) => {
if (err && err.message.includes('Contract interface not available')) {
results = _results
done()
}
else throw err
}
}
before(done => {
compileAndDeploy(filename, function (_err: Error | null | undefined, compilationData: any, contracts: any, asts: any, accounts: string[], web3: any) {
runTest('SenderAndValueTest', undefined, compilationData[filename]['SenderAndValueTest'], asts[filename], { accounts }, testCallback, errorCallback(done))
})
})
it('should have 0 passing tests', () => {
assert.equal(results.passingNum, 0)
})
it('should have 0 failing tests', () => {
assert.equal(results.failureNum, 0)
})
}) })
})
}) })

@ -74,10 +74,10 @@ const ModalWrapper = (props: ModalWrapperProps) => {
const createForm = (validation: ValidationResult) => { const createForm = (validation: ValidationResult) => {
return ( return (
<> <>
<form onChange={onFormChanged} ref={formRef}> <form onChange={onFormChanged} ref={formRef}>
{props.message} {props.message}
</form> </form>
{validation && !validation.valid && <span className='text-warning'>{validation.message}</span>} {validation && !validation.valid && <span className='text-warning'>{validation.message}</span>}
</> </>
) )
} }
@ -86,30 +86,30 @@ const ModalWrapper = (props: ModalWrapperProps) => {
data.current = props.data data.current = props.data
if (props.modalType) { if (props.modalType) {
switch (props.modalType) { switch (props.modalType) {
case ModalTypes.prompt: case ModalTypes.prompt:
case ModalTypes.password: case ModalTypes.password:
setState({ setState({
...props, ...props,
okFn: onFinishPrompt, okFn: onFinishPrompt,
cancelFn: onCancelFn, cancelFn: onCancelFn,
message: createModalMessage(props.defaultValue, { valid: true }) message: createModalMessage(props.defaultValue, { valid: true })
}) })
break break
case ModalTypes.form: case ModalTypes.form:
setState({ setState({
...props, ...props,
okFn: onFinishPrompt, okFn: onFinishPrompt,
cancelFn: onCancelFn, cancelFn: onCancelFn,
message: createForm({ valid: true }) message: createForm({ valid: true })
}) })
break break
default: default:
setState({ setState({
...props, ...props,
okFn: onOkFn, okFn: onOkFn,
cancelFn: onCancelFn cancelFn: onCancelFn
}) })
break break
} }
} else { } else {
setState({ setState({

@ -4,80 +4,80 @@ import { AppModal, ModalState } from '../interface'
export const modalReducer = (state: ModalState = ModalInitialState, action: ModalAction) => { export const modalReducer = (state: ModalState = ModalInitialState, action: ModalAction) => {
switch (action.type) { switch (action.type) {
case modalActionTypes.setModal: { case modalActionTypes.setModal: {
const timestamp = Date.now() const timestamp = Date.now()
const focusModal: AppModal = { const focusModal: AppModal = {
timestamp, timestamp,
id: action.payload.id || timestamp.toString(), id: action.payload.id || timestamp.toString(),
hide: false, hide: false,
title: action.payload.title, title: action.payload.title,
validationFn: action.payload.validationFn, validationFn: action.payload.validationFn,
message: action.payload.message, message: action.payload.message,
okLabel: action.payload.okLabel, okLabel: action.payload.okLabel,
okFn: action.payload.okFn, okFn: action.payload.okFn,
cancelLabel: action.payload.cancelLabel, cancelLabel: action.payload.cancelLabel,
cancelFn: action.payload.cancelFn, cancelFn: action.payload.cancelFn,
modalType: action.payload.modalType, modalType: action.payload.modalType,
defaultValue: action.payload.defaultValue, defaultValue: action.payload.defaultValue,
hideFn: action.payload.hideFn, hideFn: action.payload.hideFn,
resolve: action.payload.resolve, resolve: action.payload.resolve,
next: action.payload.next, next: action.payload.next,
data: action.payload.data data: action.payload.data
} }
const modalList: AppModal[] = state.modals.slice() const modalList: AppModal[] = state.modals.slice()
modalList.push(focusModal) modalList.push(focusModal)
if (modalList.length === 1) { if (modalList.length === 1) {
return { ...state, modals: modalList, focusModal } return { ...state, modals: modalList, focusModal }
} else { } else {
return { ...state, modals: modalList }
}
}
case modalActionTypes.handleHideModal: {
setTimeout(() => {
if (state.focusModal.hideFn) {
state.focusModal.hideFn()
}
if (state.focusModal.resolve) {
state.focusModal.resolve(undefined)
}
if (state.focusModal.next) {
state.focusModal.next()
}
}, 250)
const modalList: AppModal[] = state.modals.slice()
modalList.shift() // remove the current modal from the list
state.focusModal = { ...state.focusModal, hide: true, message: null }
return { ...state, modals: modalList } return { ...state, modals: modalList }
} }
case modalActionTypes.processQueue: { }
const modalList: AppModal[] = state.modals.slice() case modalActionTypes.handleHideModal: {
if (modalList.length) { setTimeout(() => {
const focusModal = modalList[0] // extract the next modal from the list if (state.focusModal.hideFn) {
return { ...state, modals: modalList, focusModal } state.focusModal.hideFn()
} else {
return { ...state, modals: modalList }
} }
} if (state.focusModal.resolve) {
case modalActionTypes.setToast: { state.focusModal.resolve(undefined)
const toasterList = state.toasters.slice()
toasterList.push(action.payload)
if (toasterList.length === 1) {
return { ...state, toasters: toasterList, focusToaster: action.payload }
} else {
return { ...state, toasters: toasterList }
} }
} if (state.focusModal.next) {
case modalActionTypes.handleToaster: { state.focusModal.next()
const toasterList = state.toasters.slice()
toasterList.shift()
if (toasterList.length) {
const toaster = toasterList[0]
return { ...state, toasters: toasterList, focusToaster: toaster }
} else {
return { ...state, toasters: [] }
} }
}, 250)
const modalList: AppModal[] = state.modals.slice()
modalList.shift() // remove the current modal from the list
state.focusModal = { ...state.focusModal, hide: true, message: null }
return { ...state, modals: modalList }
}
case modalActionTypes.processQueue: {
const modalList: AppModal[] = state.modals.slice()
if (modalList.length) {
const focusModal = modalList[0] // extract the next modal from the list
return { ...state, modals: modalList, focusModal }
} else {
return { ...state, modals: modalList }
}
}
case modalActionTypes.setToast: {
const toasterList = state.toasters.slice()
toasterList.push(action.payload)
if (toasterList.length === 1) {
return { ...state, toasters: toasterList, focusToaster: action.payload }
} else {
return { ...state, toasters: toasterList }
} }
} }
case modalActionTypes.handleToaster: {
const toasterList = state.toasters.slice()
toasterList.shift()
if (toasterList.length) {
const toaster = toasterList[0]
return { ...state, toasters: toasterList, focusToaster: toaster }
} else {
return { ...state, toasters: [] }
}
}
}
} }

@ -43,10 +43,10 @@ export const RemixUiCheckbox = ({
const childJSXWithTooltip = ( const childJSXWithTooltip = (
<CustomTooltip <CustomTooltip
tooltipText={title} tooltipText={title}
tooltipId={`${name}Tooltip`} tooltipId={`${name}Tooltip`}
placement={tooltipPlacement} placement={tooltipPlacement}
> >
<div className={`listenOnNetwork_2A0YE0 custom-control custom-checkbox ${optionalClassName}`} style={{ display: display, alignItems: 'center', visibility: visibility } as CSSProperties } onClick={onClick}> <div className={`listenOnNetwork_2A0YE0 custom-control custom-checkbox ${optionalClassName}`} style={{ display: display, alignItems: 'center', visibility: visibility } as CSSProperties } onClick={onClick}>
<input <input
id={id} id={id}
@ -67,20 +67,20 @@ export const RemixUiCheckbox = ({
) )
const childJSX = ( const childJSX = (
<div className="listenOnNetwork_2A0YE0 custom-control custom-checkbox" style={{ display: display, alignItems: 'center', visibility: visibility } as CSSProperties } onClick={onClick}> <div className="listenOnNetwork_2A0YE0 custom-control custom-checkbox" style={{ display: display, alignItems: 'center', visibility: visibility } as CSSProperties } onClick={onClick}>
<input <input
id={id} id={id}
type={inputType} type={inputType}
onChange={onChange} onChange={onChange}
style={{ verticalAlign: 'bottom' }} style={{ verticalAlign: 'bottom' }}
name={name} name={name}
className="custom-control-input" className="custom-control-input"
checked={checked} checked={checked}
/> />
<label className="form-check-label custom-control-label" id={`heading${categoryId}`} style={{ paddingTop: '0.15rem' }}> <label className="form-check-label custom-control-label" id={`heading${categoryId}`} style={{ paddingTop: '0.15rem' }}>
{name ? <div className="font-weight-bold">{itemName}</div> : ''} {name ? <div className="font-weight-bold">{itemName}</div> : ''}
{label} {label}
</label> </label>
</div> </div>
) )
return ( return (
title ? (childJSXWithTooltip) : (childJSX) title ? (childJSXWithTooltip) : (childJSX)

@ -52,8 +52,8 @@ export const CopyToClipboard = (props: ICopyToClipboard) => {
const childJSX = ( const childJSX = (
children || (<i className={`far ${icon} ml-1 p-2`} aria-hidden="true" children || (<i className={`far ${icon} ml-1 p-2`} aria-hidden="true"
{...otherProps} {...otherProps}
></i>) ></i>)
) )
return ( return (

@ -49,16 +49,16 @@ export const DebuggerApiMixin = (Base) => class extends Base {
await this.call('editor', 'highlight', lineColumnPos, path, '', { focus: true }) await this.call('editor', 'highlight', lineColumnPos, path, '', { focus: true })
const label = `${stepDetail.op} costs ${stepDetail.gasCost} gas - this line costs ${lineGasCost} gas - ${stepDetail.gas} gas left` const label = `${stepDetail.op} costs ${stepDetail.gasCost} gas - this line costs ${lineGasCost} gas - ${stepDetail.gas} gas left`
const linetext: lineText = { const linetext: lineText = {
content: label, content: label,
position: lineColumnPos, position: lineColumnPos,
hide: false, hide: false,
className: 'text-muted small', className: 'text-muted small',
afterContentClassName: 'text-muted small fas fa-gas-pump pl-4', afterContentClassName: 'text-muted small fas fa-gas-pump pl-4',
from: 'debugger', from: 'debugger',
hoverMessage: [{ hoverMessage: [{
value: label, value: label,
}, },
], ],
} }
await this.call('editor', 'addLineText' as any, linetext, path) await this.call('editor', 'addLineText' as any, linetext, path)
} }

@ -64,81 +64,81 @@ export const ButtonNavigation = ({ stepOverBack, stepIntoBack, stepIntoForward,
placement: 'top-start', placement: 'top-start',
tagId: 'overbackTooltip', tagId: 'overbackTooltip',
tooltipMsg: 'Step over back' tooltipMsg: 'Step over back'
}, },
stepBackJSX : { stepBackJSX : {
markup: ( markup: (
<div className={state.intoBackDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { stepIntoBack && stepIntoBack() }} data-id="buttonNavigatorIntoBack" id="buttonNavigatorIntoBackContainer"> <div className={state.intoBackDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { stepIntoBack && stepIntoBack() }} data-id="buttonNavigatorIntoBack" id="buttonNavigatorIntoBackContainer">
<button id='intoback' data-id="buttonNavigatorIntoBack" className='btn btn-link btn-sm stepButton m-0 p-0' onClick={() => { stepIntoBack && stepIntoBack() }} disabled={state.intoBackDisabled} style={{ pointerEvents: 'none', color: 'white' }}> <button id='intoback' data-id="buttonNavigatorIntoBack" className='btn btn-link btn-sm stepButton m-0 p-0' onClick={() => { stepIntoBack && stepIntoBack() }} disabled={state.intoBackDisabled} style={{ pointerEvents: 'none', color: 'white' }}>
<span className="fas fa-level-up-alt"></span> <span className="fas fa-level-up-alt"></span>
</button> </button>
</div> </div>
), ),
placement: 'top-start', placement: 'top-start',
tagId: 'intobackTooltip', tagId: 'intobackTooltip',
tooltipMsg: 'Step back' tooltipMsg: 'Step back'
}, },
stepIntoJSX : { stepIntoJSX : {
markup: ( markup: (
<div className={state.intoForwardDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { stepIntoForward && stepIntoForward() }} data-id="buttonNavigatorIntoForward" id="buttonNavigatorIntoFowardContainer"> <div className={state.intoForwardDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { stepIntoForward && stepIntoForward() }} data-id="buttonNavigatorIntoForward" id="buttonNavigatorIntoFowardContainer">
<button id='intoforward' data-id="buttonNavigatorIntoForward" className='btn btn-link btn-sm stepButton m-0 p-0' onClick={() => { stepIntoForward && stepIntoForward() }} disabled={state.intoForwardDisabled} <button id='intoforward' data-id="buttonNavigatorIntoForward" className='btn btn-link btn-sm stepButton m-0 p-0' onClick={() => { stepIntoForward && stepIntoForward() }} disabled={state.intoForwardDisabled}
style={{ pointerEvents: 'none', color: 'white' }} style={{ pointerEvents: 'none', color: 'white' }}
> >
<span className="fas fa-level-down-alt"></span> <span className="fas fa-level-down-alt"></span>
</button> </button>
</div> </div>
), ),
placement: 'top-start', placement: 'top-start',
tagId: 'intoforwardTooltip', tagId: 'intoforwardTooltip',
tooltipMsg: 'Step into' tooltipMsg: 'Step into'
}, },
stepOverForwardJSX : { stepOverForwardJSX : {
markup: ( markup: (
<div className={state.overForwardDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { stepOverForward && stepOverForward() }} data-id="buttonNavigatorOverForward" id="buttonNavigatorOverForwardContainer"> <div className={state.overForwardDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { stepOverForward && stepOverForward() }} data-id="buttonNavigatorOverForward" id="buttonNavigatorOverForwardContainer">
<button id='overforward' className='btn btn-link btn-sm stepButton m-0 p-0' onClick={() => { stepOverForward && stepOverForward() }} disabled={state.overForwardDisabled} style={{ pointerEvents: 'none', color: 'white' }}> <button id='overforward' className='btn btn-link btn-sm stepButton m-0 p-0' onClick={() => { stepOverForward && stepOverForward() }} disabled={state.overForwardDisabled} style={{ pointerEvents: 'none', color: 'white' }}>
<span className="fas fa-share"></span> <span className="fas fa-share"></span>
</button> </button>
</div> </div>
), ),
placement: 'top-end', placement: 'top-end',
tagId: 'overbackTooltip', tagId: 'overbackTooltip',
tooltipMsg: 'Step over forward', tooltipMsg: 'Step over forward',
}
} }
}
const jumpMarkupStructure = { const jumpMarkupStructure = {
jumpPreviousBreakpointJSX : { jumpPreviousBreakpointJSX : {
markup: ( markup: (
<div className={state.jumpPreviousBreakpointDisabled ? `${stepBtnStyle} ${disableJumpBtnStyle}`: `${stepBtnStyle}`} id="buttonNavigatorJumpPreviousBreakpointContainer" onClick={() => { jumpPreviousBreakpoint && jumpPreviousBreakpoint() }} data-id="buttonNavigatorJumpPreviousBreakpoint"> <div className={state.jumpPreviousBreakpointDisabled ? `${stepBtnStyle} ${disableJumpBtnStyle}`: `${stepBtnStyle}`} id="buttonNavigatorJumpPreviousBreakpointContainer" onClick={() => { jumpPreviousBreakpoint && jumpPreviousBreakpoint() }} data-id="buttonNavigatorJumpPreviousBreakpoint">
<button className='btn btn-link btn-sm jumpButton m-0 p-0' id='jumppreviousbreakpoint' data-id="buttonNavigatorJumpPreviousBreakpoint" onClick={() => { jumpPreviousBreakpoint && jumpPreviousBreakpoint() }} disabled={state.jumpPreviousBreakpointDisabled} style={{ pointerEvents: 'none', backgroundColor: 'inherit', color: 'white' }}> <button className='btn btn-link btn-sm jumpButton m-0 p-0' id='jumppreviousbreakpoint' data-id="buttonNavigatorJumpPreviousBreakpoint" onClick={() => { jumpPreviousBreakpoint && jumpPreviousBreakpoint() }} disabled={state.jumpPreviousBreakpointDisabled} style={{ pointerEvents: 'none', backgroundColor: 'inherit', color: 'white' }}>
<span className="fas fa-step-backward"></span> <span className="fas fa-step-backward"></span>
</button> </button>
</div> </div>
), ),
placement: 'bottom-start', placement: 'bottom-start',
tagId: 'jumppreviousbreakpointTooltip', tagId: 'jumppreviousbreakpointTooltip',
tooltipMsg: 'Jump to the previous breakpoint' tooltipMsg: 'Jump to the previous breakpoint'
}, },
jumpOutJSX : { jumpOutJSX : {
markup: ( markup: (
<div className={state.jumpOutDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { jumpOut && jumpOut() }} data-id="buttonNavigatorJumpOut" id="buttonNavigatorJumpOutContainer"> <div className={state.jumpOutDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { jumpOut && jumpOut() }} data-id="buttonNavigatorJumpOut" id="buttonNavigatorJumpOutContainer">
<button className='btn btn-link btn-sm jumpButton m-0 p-0' id='jumpout' onClick={() => { jumpOut && jumpOut() }} disabled={state.jumpOutDisabled} style={{ pointerEvents: 'none', backgroundColor: 'inherit', color: 'white' }} data-id="buttonNavigatorJumpOut"> <button className='btn btn-link btn-sm jumpButton m-0 p-0' id='jumpout' onClick={() => { jumpOut && jumpOut() }} disabled={state.jumpOutDisabled} style={{ pointerEvents: 'none', backgroundColor: 'inherit', color: 'white' }} data-id="buttonNavigatorJumpOut">
<span className="fas fa-eject"></span> <span className="fas fa-eject"></span>
</button> </button>
</div> </div>
), ),
placement: 'bottom-end', placement: 'bottom-end',
tagId: 'jumpoutTooltip', tagId: 'jumpoutTooltip',
tooltipMsg: 'Jump out' tooltipMsg: 'Jump out'
}, },
jumpNextBreakpointJSX : { jumpNextBreakpointJSX : {
markup: ( markup: (
<div className={state.jumpNextBreakpointDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { jumpNextBreakpoint && jumpNextBreakpoint() }} data-id="buttonNavigatorJumpNextBreakpoint" id="buttonNavigatorJumpNextBreakpointContainer"> <div className={state.jumpNextBreakpointDisabled ? `${stepBtnStyle} ${disableStepBtnStyle}`: `${stepBtnStyle}`} onClick={() => { jumpNextBreakpoint && jumpNextBreakpoint() }} data-id="buttonNavigatorJumpNextBreakpoint" id="buttonNavigatorJumpNextBreakpointContainer">
<button className='btn btn-link btn-sm jumpButton m-0 p-0' id='jumpnextbreakpoint' data-id="buttonNavigatorJumpNextBreakpoint" onClick={() => { jumpNextBreakpoint && jumpNextBreakpoint() }} disabled={state.jumpNextBreakpointDisabled} style={{ pointerEvents: 'none', color: 'white' }}> <button className='btn btn-link btn-sm jumpButton m-0 p-0' id='jumpnextbreakpoint' data-id="buttonNavigatorJumpNextBreakpoint" onClick={() => { jumpNextBreakpoint && jumpNextBreakpoint() }} disabled={state.jumpNextBreakpointDisabled} style={{ pointerEvents: 'none', color: 'white' }}>
<span className="fas fa-step-forward"></span> <span className="fas fa-step-forward"></span>
</button> </button>
</div> </div>
), ),
placement: 'bottom-end', placement: 'bottom-end',
tagId: 'jumpnextbreakpointTooltip', tagId: 'jumpnextbreakpointTooltip',
tooltipMsg: 'Jump to the next breakpoint' tooltipMsg: 'Jump to the next breakpoint'
} }
@ -162,18 +162,18 @@ export const ButtonNavigation = ({ stepOverBack, stepIntoBack, stepIntoForward,
</div> </div>
<div className="jumpButtons btn-group py-1"> <div className="jumpButtons btn-group py-1">
{ {
Object.keys(jumpMarkupStructure).map(x => ( Object.keys(jumpMarkupStructure).map(x => (
<CustomTooltip <CustomTooltip
placement={jumpMarkupStructure[x].placement} placement={jumpMarkupStructure[x].placement}
tooltipText={jumpMarkupStructure[x].tooltipMsg} tooltipText={jumpMarkupStructure[x].tooltipMsg}
tooltipId={jumpMarkupStructure[x].tooltipId} tooltipId={jumpMarkupStructure[x].tooltipId}
key={`${jumpMarkupStructure[x].placement}-${jumpMarkupStructure[x].tooltipMsg}-${jumpMarkupStructure[x].tagId}`} key={`${jumpMarkupStructure[x].placement}-${jumpMarkupStructure[x].tooltipMsg}-${jumpMarkupStructure[x].tagId}`}
> >
{jumpMarkupStructure[x].markup} {jumpMarkupStructure[x].markup}
</CustomTooltip> </CustomTooltip>
)) ))
} }
</div> </div>
<div id='reverted' style={{ display: revertedReason === '' ? 'none' : 'block' }}> <div id='reverted' style={{ display: revertedReason === '' ? 'none' : 'block' }}>
<span className='text-warning'>This call has reverted, state changes made during the call will be reverted.</span> <span className='text-warning'>This call has reverted, state changes made during the call will be reverted.</span>

@ -379,7 +379,7 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
data-id="debugGeneratedSourcesLabel" data-id="debugGeneratedSourcesLabel"
className="form-check-label custom-control-label" className="form-check-label custom-control-label"
htmlFor="debugGeneratedSourcesInput"> htmlFor="debugGeneratedSourcesInput">
<FormattedMessage id='debugger.useGeneratedSources' />(Solidity {'>='} v0.7.2) <FormattedMessage id='debugger.useGeneratedSources' />(Solidity {'>='} v0.7.2)
</label> </label>
</span> </span>
) )

@ -52,17 +52,17 @@ export const TxBrowser = ({ requestDebug, updateTxNumberFlag, unloadRequested, t
} }
const customJSX = ( const customJSX = (
<div id="debuggerTransactionStartButtonContainer" data-id="debuggerTransactionStartButton" onClick={handleSubmit} className="btn btn-primary btn-sm btn-block text-decoration-none"> <div id="debuggerTransactionStartButtonContainer" data-id="debuggerTransactionStartButton" onClick={handleSubmit} className="btn btn-primary btn-sm btn-block text-decoration-none">
<button <button
className='btn btn-link btn-sm btn-block h-75 p-0 m-0 text-decoration-none' className='btn btn-link btn-sm btn-block h-75 p-0 m-0 text-decoration-none'
id='load' id='load'
onClick={handleSubmit} onClick={handleSubmit}
data-id='debuggerTransactionStartButton' data-id='debuggerTransactionStartButton'
disabled={!state.txNumber } disabled={!state.txNumber }
style={{ pointerEvents: 'none', color: 'white' }} style={{ pointerEvents: 'none', color: 'white' }}
> >
<span><FormattedMessage id={`debugger.${debugging ? 'stopDebugging' : 'startDebugging'}`} /></span> <span><FormattedMessage id={`debugger.${debugging ? 'stopDebugging' : 'startDebugging'}`} /></span>
</button> </button>
</div> </div>
) )
return ( return (
<div className='pb-2 container px-0'> <div className='pb-2 container px-0'>

@ -44,54 +44,54 @@ const reducedOpcode = (opCodes, payload) => {
export const reducer = (state = initialState, action: Action) => { export const reducer = (state = initialState, action: Action) => {
switch (action.type) { switch (action.type) {
case 'FETCH_OPCODES_REQUEST': { case 'FETCH_OPCODES_REQUEST': {
return { return {
...state, ...state,
isRequesting: true, isRequesting: true,
isSuccessful: false, isSuccessful: false,
hasError: null hasError: null
}
} }
case 'FETCH_OPCODES_SUCCESS': { }
const opCodes = action.payload.address === state.opCodes.address ? { case 'FETCH_OPCODES_SUCCESS': {
...state.opCodes, index: action.payload.index, nextIndexes: action.payload.nextIndexes, absoluteCurrentLineIndexes: state.absoluteCurrentLineIndexes const opCodes = action.payload.address === state.opCodes.address ? {
} : deepEqual(action.payload.code, state.opCodes.code) ? state.opCodes : action.payload ...state.opCodes, index: action.payload.index, nextIndexes: action.payload.nextIndexes, absoluteCurrentLineIndexes: state.absoluteCurrentLineIndexes
} : deepEqual(action.payload.code, state.opCodes.code) ? state.opCodes : action.payload
const reduced = reducedOpcode(opCodes, action.payload) const reduced = reducedOpcode(opCodes, action.payload)
return { return {
...state, ...state,
opCodes, opCodes,
display: reduced.display, display: reduced.display,
initialIndex: action.payload.index, initialIndex: action.payload.index,
index: reduced.index, index: reduced.index,
nextIndexes: reduced.nextIndexes, nextIndexes: reduced.nextIndexes,
isRequesting: false, isRequesting: false,
isSuccessful: true, isSuccessful: true,
hasError: null, hasError: null,
returnInstructionIndexes: reduced.returnInstructionIndexes, returnInstructionIndexes: reduced.returnInstructionIndexes,
outOfGasInstructionIndexes: reduced.outOfGasInstructionIndexes, outOfGasInstructionIndexes: reduced.outOfGasInstructionIndexes,
currentLineIndexes: reduced.currentLineIndexes currentLineIndexes: reduced.currentLineIndexes
}
} }
case 'FETCH_OPCODES_ERROR': { }
return { case 'FETCH_OPCODES_ERROR': {
...state, return {
isRequesting: false, ...state,
isSuccessful: false, isRequesting: false,
hasError: action.payload isSuccessful: false,
} hasError: action.payload
} }
case 'FETCH_INDEXES_FOR_NEW_LINE': { }
let bottom = state.initialIndex - 10 case 'FETCH_INDEXES_FOR_NEW_LINE': {
bottom = bottom < 0 ? 0 : bottom let bottom = state.initialIndex - 10
return { bottom = bottom < 0 ? 0 : bottom
...state, return {
absoluteCurrentLineIndexes: action.payload.currentLineIndexes, ...state,
currentLineIndexes: action.payload.currentLineIndexes.map(index => index - bottom), absoluteCurrentLineIndexes: action.payload.currentLineIndexes,
line: action.payload.line currentLineIndexes: action.payload.currentLineIndexes.map(index => index - bottom),
} line: action.payload.line
} }
default: }
throw new Error() default:
throw new Error()
} }
} }

@ -12,50 +12,50 @@ export const initialState = {
export const reducer = (state = initialState, action: Action) => { export const reducer = (state = initialState, action: Action) => {
switch (action.type) { switch (action.type) {
case 'FETCH_CALLDATA_REQUEST': case 'FETCH_CALLDATA_REQUEST':
return { return {
...state, ...state,
isRequesting: true, isRequesting: true,
isSuccessful: false, isSuccessful: false,
hasError: null hasError: null
} }
case 'FETCH_CALLDATA_SUCCESS': case 'FETCH_CALLDATA_SUCCESS':
return { return {
calldata: action.payload, calldata: action.payload,
isRequesting: false, isRequesting: false,
isSuccessful: true, isSuccessful: true,
hasError: null hasError: null
} }
case 'FETCH_CALLDATA_ERROR': case 'FETCH_CALLDATA_ERROR':
return { return {
...state, ...state,
isRequesting: false, isRequesting: false,
isSuccessful: false, isSuccessful: false,
hasError: action.payload hasError: action.payload
} }
case 'UPDATE_CALLDATA_REQUEST': case 'UPDATE_CALLDATA_REQUEST':
return { return {
...state, ...state,
isRequesting: true, isRequesting: true,
isSuccessful: false, isSuccessful: false,
hasError: null hasError: null
} }
case 'UPDATE_CALLDATA_SUCCESS': case 'UPDATE_CALLDATA_SUCCESS':
return { return {
calldata: mergeLocals(action.payload, state.calldata), calldata: mergeLocals(action.payload, state.calldata),
isRequesting: false, isRequesting: false,
isSuccessful: true, isSuccessful: true,
hasError: null hasError: null
} }
case 'UPDATE_CALLDATA_ERROR': case 'UPDATE_CALLDATA_ERROR':
return { return {
...state, ...state,
isRequesting: false, isRequesting: false,
isSuccessful: false, isSuccessful: false,
hasError: action.payload hasError: action.payload
} }
default: default:
throw new Error() throw new Error()
} }
} }

@ -68,25 +68,25 @@ export const Draggable = (props: DraggableType) => {
<> <>
{ {
props.isDraggable ? props.children : props.isDraggable ? props.children :
<span <span
ref={dragRef} ref={dragRef}
draggable draggable
onDrop={(event) => { onDrop={(event) => {
handleDrop(event) handleDrop(event)
}} }}
onDragStart={() => { onDragStart={() => {
if (destination) { if (destination) {
handleDrag() handleDrag()
} }
}} }}
onDragOver={(event) => { onDragOver={(event) => {
if (destination) { if (destination) {
handleDragover(event) handleDragover(event)
} }
}} }}
> >
{props.children} {props.children}
</span> </span>
} }
</> </>
) )

@ -13,87 +13,87 @@ export const reducerActions = (models = initialState, action: Action) => {
const monaco = action.monaco const monaco = action.monaco
const editor = action.editor const editor = action.editor
switch (action.type) { switch (action.type) {
case 'ADD_MODEL': { case 'ADD_MODEL': {
if (!editor) return models if (!editor) return models
const uri = action.payload.uri const uri = action.payload.uri
const value = action.payload.value const value = action.payload.value
const language = action.payload.language const language = action.payload.language
const readOnly = action.payload.readOnly const readOnly = action.payload.readOnly
if (models[uri]) return models // already existing if (models[uri]) return models // already existing
models[uri] = { language, uri, readOnly } models[uri] = { language, uri, readOnly }
let model let model
try { try {
model = monaco.editor.createModel(value, language, monaco.Uri.parse(uri)) model = monaco.editor.createModel(value, language, monaco.Uri.parse(uri))
} catch (e) { } catch (e) {
}
models[uri].model = model
model.onDidChangeContent(() => action.payload.events.onDidChangeContent(uri))
return models
} }
case 'DISPOSE_MODEL': { models[uri].model = model
const uri = action.payload.uri model.onDidChangeContent(() => action.payload.events.onDidChangeContent(uri))
const model = models[uri]?.model return models
if (model) model.dispose() }
delete models[uri] case 'DISPOSE_MODEL': {
return models const uri = action.payload.uri
} const model = models[uri]?.model
case 'SET_VALUE': { if (model) model.dispose()
if (!editor) return models delete models[uri]
const uri = action.payload.uri return models
const value = action.payload.value }
const model = models[uri]?.model case 'SET_VALUE': {
if (model) { if (!editor) return models
model.setValue(value) const uri = action.payload.uri
} const value = action.payload.value
return models const model = models[uri]?.model
} if (model) {
case 'REVEAL_LINE': { model.setValue(value)
if (!editor) return models
const line = action.payload.line
const column = action.payload.column
editor.revealLine(line)
editor.setPosition({ column, lineNumber: line })
return models
}
case 'REVEAL_RANGE': {
if (!editor) return models
const range: monacoTypes.IRange = {
startLineNumber: action.payload.startLineNumber + 1,
startColumn: action.payload.startColumn,
endLineNumber: action.payload.endLineNumber + 1,
endColumn: action.payload.endColumn
}
// reset to start of line
if (action.payload.startColumn < 100) {
editor.revealRange({
startLineNumber: range.startLineNumber,
startColumn: 1,
endLineNumber: range.endLineNumber,
endColumn: 1
})
} else {
editor.revealRangeInCenter(range)
}
return models
}
case 'FOCUS': {
if (!editor) return models
editor.focus()
return models
} }
case 'SET_FONTSIZE': { return models
if (!editor) return models }
const size = action.payload.size case 'REVEAL_LINE': {
editor.updateOptions({ fontSize: size }) if (!editor) return models
return models const line = action.payload.line
const column = action.payload.column
editor.revealLine(line)
editor.setPosition({ column, lineNumber: line })
return models
}
case 'REVEAL_RANGE': {
if (!editor) return models
const range: monacoTypes.IRange = {
startLineNumber: action.payload.startLineNumber + 1,
startColumn: action.payload.startColumn,
endLineNumber: action.payload.endLineNumber + 1,
endColumn: action.payload.endColumn
} }
case 'SET_WORDWRAP': { // reset to start of line
if (!editor) return models if (action.payload.startColumn < 100) {
const wrap = action.payload.wrap editor.revealRange({
editor.updateOptions({ wordWrap: wrap ? 'on' : 'off' }) startLineNumber: range.startLineNumber,
return models startColumn: 1,
endLineNumber: range.endLineNumber,
endColumn: 1
})
} else {
editor.revealRangeInCenter(range)
} }
return models
}
case 'FOCUS': {
if (!editor) return models
editor.focus()
return models
}
case 'SET_FONTSIZE': {
if (!editor) return models
const size = action.payload.size
editor.updateOptions({ fontSize: size })
return models
}
case 'SET_WORDWRAP': {
if (!editor) return models
const wrap = action.payload.wrap
editor.updateOptions({ wordWrap: wrap ? 'on' : 'off' })
return models
}
} }
} }

@ -1,15 +1,15 @@
import { EditorAPIType, PluginType } from "../remix-ui-editor" import { EditorAPIType, PluginType } from "../remix-ui-editor"
export const retrieveNodesAtPosition = async (editorAPI: EditorAPIType, plugin: PluginType) => { export const retrieveNodesAtPosition = async (editorAPI: EditorAPIType, plugin: PluginType) => {
const cursorPosition = editorAPI.getCursorPosition() const cursorPosition = editorAPI.getCursorPosition()
let nodesAtPosition = await plugin.call('codeParser', 'nodesAtPosition', cursorPosition) let nodesAtPosition = await plugin.call('codeParser', 'nodesAtPosition', cursorPosition)
// if no nodes exits at position, try to get the block of which the position is in // if no nodes exits at position, try to get the block of which the position is in
const block = await plugin.call('codeParser', 'getANTLRBlockAtPosition', cursorPosition, null) const block = await plugin.call('codeParser', 'getANTLRBlockAtPosition', cursorPosition, null)
if (!nodesAtPosition.length) { if (!nodesAtPosition.length) {
if (block) { if (block) {
nodesAtPosition = await plugin.call('codeParser', 'nodesAtPosition', block.start) nodesAtPosition = await plugin.call('codeParser', 'nodesAtPosition', block.start)
}
} }
return { nodesAtPosition, block } }
return { nodesAtPosition, block }
} }

@ -6,431 +6,431 @@ import { monacoTypes } from '@remix-ui/editor';
import { retrieveNodesAtPosition } from "../helpers/retrieveNodesAtPosition"; import { retrieveNodesAtPosition } from "../helpers/retrieveNodesAtPosition";
export class RemixCompletionProvider implements monacoTypes.languages.CompletionItemProvider { export class RemixCompletionProvider implements monacoTypes.languages.CompletionItemProvider {
props: EditorUIProps props: EditorUIProps
monaco: any monaco: any
maximumItemsForContractCompletion = 100 maximumItemsForContractCompletion = 100
constructor(props: any, monaco: any) { constructor(props: any, monaco: any) {
this.props = props this.props = props
this.monaco = monaco this.monaco = monaco
} }
triggerCharacters = ['.', '', '"', '@', '/'] triggerCharacters = ['.', '', '"', '@', '/']
async provideCompletionItems(model: monacoTypes.editor.ITextModel, position: monacoTypes.Position, context: monacoTypes.languages.CompletionContext): Promise<monacoTypes.languages.CompletionList | undefined> { async provideCompletionItems(model: monacoTypes.editor.ITextModel, position: monacoTypes.Position, context: monacoTypes.languages.CompletionContext): Promise<monacoTypes.languages.CompletionList | undefined> {
const completionSettings = await this.props.plugin.call('config', 'getAppParameter', 'settings/auto-completion') const completionSettings = await this.props.plugin.call('config', 'getAppParameter', 'settings/auto-completion')
if (!completionSettings) return if (!completionSettings) return
const word = model.getWordUntilPosition(position); const word = model.getWordUntilPosition(position);
const range = { const range = {
startLineNumber: position.lineNumber, startLineNumber: position.lineNumber,
endLineNumber: position.lineNumber, endLineNumber: position.lineNumber,
startColumn: word.startColumn, startColumn: word.startColumn,
endColumn: word.endColumn endColumn: word.endColumn
}; };
const line = model.getLineContent(position.lineNumber) const line = model.getLineContent(position.lineNumber)
let nodes: AstNode[] = [] let nodes: AstNode[] = []
let suggestions: monacoTypes.languages.CompletionItem[] = [] let suggestions: monacoTypes.languages.CompletionItem[] = []
if (context.triggerCharacter === '"' || context.triggerCharacter === '@' || context.triggerCharacter === '/') { if (context.triggerCharacter === '"' || context.triggerCharacter === '@' || context.triggerCharacter === '/') {
const lastpart = line.substring(0, position.column - 1).split(';').pop() const lastpart = line.substring(0, position.column - 1).split(';').pop()
if (lastpart.startsWith('import')) { if (lastpart.startsWith('import')) {
const imports = await this.props.plugin.call('codeParser', 'getImports') const imports = await this.props.plugin.call('codeParser', 'getImports')
if (context.triggerCharacter === '"' || context.triggerCharacter === '@') { if (context.triggerCharacter === '"' || context.triggerCharacter === '@') {
suggestions = [...suggestions, suggestions = [...suggestions,
...GetImports(range, this.monaco, imports, context.triggerCharacter), ...GetImports(range, this.monaco, imports, context.triggerCharacter),
] ]
} else if (context.triggerCharacter === '/') { } else if (context.triggerCharacter === '/') {
const word = line.split('"')[1] const word = line.split('"')[1]
suggestions = [...suggestions, suggestions = [...suggestions,
...GetImports(range, this.monaco, imports, word), ...GetImports(range, this.monaco, imports, word),
] ]
} else { } else {
return return
} }
} }
} else if (context.triggerCharacter === '.') { } else if (context.triggerCharacter === '.') {
const lineTextBeforeCursor: string = line.substring(0, position.column - 1) const lineTextBeforeCursor: string = line.substring(0, position.column - 1)
const lastNodeInExpression = await this.getLastNodeInExpression(lineTextBeforeCursor) const lastNodeInExpression = await this.getLastNodeInExpression(lineTextBeforeCursor)
const expressionElements = lineTextBeforeCursor.split('.') const expressionElements = lineTextBeforeCursor.split('.')
let dotCompleted = false
// handles completion from for builtin types
if (lastNodeInExpression.memberName === 'sender') { // exception for this member
lastNodeInExpression.name = 'sender'
}
const globalCompletion = getContextualAutoCompleteByGlobalVariable(lastNodeInExpression.name, range, this.monaco)
if (globalCompletion) {
dotCompleted = true
suggestions = [...suggestions, ...globalCompletion]
}
// handle completion for global THIS.
if (lastNodeInExpression.name === 'this') {
dotCompleted = true
nodes = [...nodes, ...await this.getThisCompletions()]
}
// handle completion for other dot completions
if (expressionElements.length > 1 && !dotCompleted) {
const nameOfLastTypedExpression = lastNodeInExpression.name || lastNodeInExpression.memberName
const dotCompletions = await this.getDotCompletions(nameOfLastTypedExpression, range)
nodes = [...nodes, ...dotCompletions.nodes]
suggestions = [...suggestions, ...dotCompletions.suggestions]
}
} else {
// handles contract completions and other suggestions
suggestions = [...suggestions,
...GetGlobalVariable(range, this.monaco),
...getCompletionSnippets(range, this.monaco),
...GetCompletionTypes(range, this.monaco),
...GetCompletionKeywords(range, this.monaco),
...GetGlobalFunctions(range, this.monaco),
...GeCompletionUnits(range, this.monaco),
]
let contractCompletions = await this.getContractCompletions()
// we can't have external nodes without using this.
contractCompletions = contractCompletions.filter(node => {
if (node.visibility && node.visibility === 'external') {
return false
}
return true
})
let dotCompleted = false nodes = [...nodes, ...contractCompletions]
// handles completion from for builtin types }
if (lastNodeInExpression.memberName === 'sender') { // exception for this member
lastNodeInExpression.name = 'sender'
}
const globalCompletion = getContextualAutoCompleteByGlobalVariable(lastNodeInExpression.name, range, this.monaco)
if (globalCompletion) {
dotCompleted = true
suggestions = [...suggestions, ...globalCompletion]
}
// handle completion for global THIS.
if (lastNodeInExpression.name === 'this') {
dotCompleted = true
nodes = [...nodes, ...await this.getThisCompletions()]
}
// handle completion for other dot completions
if (expressionElements.length > 1 && !dotCompleted) {
const nameOfLastTypedExpression = lastNodeInExpression.name || lastNodeInExpression.memberName // remove duplicates
const dotCompletions = await this.getDotCompletions(nameOfLastTypedExpression, range) const nodeIds = {};
nodes = [...nodes, ...dotCompletions.nodes] let filteredNodes = nodes.filter((node) => {
suggestions = [...suggestions, ...dotCompletions.suggestions] if (node.id) {
} if (nodeIds[node.id]) {
} else { return false;
}
nodeIds[node.id] = true;
}
return true;
});
// 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.`)
filteredNodes = filteredNodes.slice(0, this.maximumItemsForContractCompletion)
}
// handles contract completions and other suggestions const getNodeLink = async (node: any) => {
suggestions = [...suggestions, return await this.props.plugin.call('codeParser', 'getNodeLink', node)
...GetGlobalVariable(range, this.monaco), }
...getCompletionSnippets(range, this.monaco),
...GetCompletionTypes(range, this.monaco),
...GetCompletionKeywords(range, this.monaco),
...GetGlobalFunctions(range, this.monaco),
...GeCompletionUnits(range, this.monaco),
]
let contractCompletions = await this.getContractCompletions() const getDocs = async (node: any) => {
return await this.props.plugin.call('codeParser', 'getNodeDocumentation', node)
}
// we can't have external nodes without using this. const getParamaters = async (node: any) => {
contractCompletions = contractCompletions.filter(node => { return await this.props.plugin.call('codeParser', 'getFunctionParamaters', node)
if (node.visibility && node.visibility === 'external') { }
return false
}
return true
})
nodes = [...nodes, ...contractCompletions] const completeParameters = async (parameters: any) => {
const localParam = (parameters && parameters.parameters) || (parameters)
if (localParam) {
const params = []
for (const key in localParam) {
params.push('${' + (key + 1) + ':' + localParam[key].name + '}')
}
return `(${params.join(', ')})`
}
}
const getVariableDeclaration = async (node: any) => {
let variableDeclaration = await this.props.plugin.call('codeParser', 'getVariableDeclaration', node)
if (node.scope) {
const scopeNode = await this.props.plugin.call('codeParser', 'getNodeById', node.scope)
if (scopeNode) {
variableDeclaration = `${scopeNode.name}.${variableDeclaration}`
} }
}
return variableDeclaration
}
// remove duplicates
const nodeIds = {};
let filteredNodes = nodes.filter((node) => {
if (node.id) {
if (nodeIds[node.id]) {
return false;
}
nodeIds[node.id] = true;
}
return true;
});
// truncate for performance for (const node of Object.values(filteredNodes) as any[]) {
if (filteredNodes.length > this.maximumItemsForContractCompletion) { if (!node.name) continue
// await this.props.plugin.call('notification', 'toast', `Too many completion items. Only ${this.maximumItemsForContractCompletion} items will be shown.`) if (node.nodeType === 'VariableDeclaration') {
filteredNodes = filteredNodes.slice(0, this.maximumItemsForContractCompletion) const completion = {
label: { label: `"${node.name}"`, description: await getNodeLink(node), detail: ` ${await getVariableDeclaration(node)}` },
kind: this.monaco.languages.CompletionItemKind.Variable,
insertText: node.name,
range: range,
documentation: await getDocs(node)
} }
suggestions.push(completion)
const getNodeLink = async (node: any) => { } else if (node.nodeType === 'FunctionDefinition') {
return await this.props.plugin.call('codeParser', 'getNodeLink', node) const completion = {
label: { label: `"${node.name}"`, description: await getNodeLink(node), detail: ` -> ${node.name} ${await getParamaters(node)}` },
kind: this.monaco.languages.CompletionItemKind.Function,
insertText: `${node.name}${await completeParameters(node.parameters)};`,
insertTextRules: this.monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
range: range,
documentation: await getDocs(node)
} }
suggestions.push(completion)
const getDocs = async (node: any) => { } else if
return await this.props.plugin.call('codeParser', 'getNodeDocumentation', node) (node.nodeType === 'ContractDefinition') {
const completion = {
label: { label: `"${node.name}"`, description: await getNodeLink(node), detail: ` ${node.name}` },
kind: this.monaco.languages.CompletionItemKind.Interface,
insertText: node.name,
range: range,
documentation: await getDocs(node)
} }
suggestions.push(completion)
const getParamaters = async (node: any) => { } else if
return await this.props.plugin.call('codeParser', 'getFunctionParamaters', node) (node.nodeType === 'StructDefinition') {
const completion = {
label: { label: `"${node.name}"`, description: await getNodeLink(node), detail: ` ${node.name}` },
kind: this.monaco.languages.CompletionItemKind.Struct,
insertText: node.name,
range: range,
documentation: await getDocs(node)
} }
suggestions.push(completion)
const completeParameters = async (parameters: any) => { } else if
const localParam = (parameters && parameters.parameters) || (parameters) (node.nodeType === 'EnumDefinition') {
if (localParam) { const completion = {
const params = [] label: { label: `"${node.name}"`, description: await getNodeLink(node), detail: ` ${node.name}` },
for (const key in localParam) { kind: this.monaco.languages.CompletionItemKind.Enum,
params.push('${' + (key + 1) + ':' + localParam[key].name + '}') insertText: node.name,
} range: range,
return `(${params.join(', ')})` documentation: await getDocs(node)
}
} }
suggestions.push(completion)
const getVariableDeclaration = async (node: any) => { } else if
let variableDeclaration = await this.props.plugin.call('codeParser', 'getVariableDeclaration', node) (node.nodeType === 'EventDefinition') {
if (node.scope) { const completion = {
const scopeNode = await this.props.plugin.call('codeParser', 'getNodeById', node.scope) label: { label: `"${node.name}"`, description: await getNodeLink(node), detail: ` -> ${node.name} ${await getParamaters(node)}` },
if (scopeNode) { kind: this.monaco.languages.CompletionItemKind.Event,
variableDeclaration = `${scopeNode.name}.${variableDeclaration}` insertText: `${node.name}${await completeParameters(node.parameters)};`,
} insertTextRules: this.monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
} range: range,
return variableDeclaration documentation: await getDocs(node)
} }
suggestions.push(completion)
} else if
for (const node of Object.values(filteredNodes) as any[]) { (node.nodeType === 'ModifierDefinition') {
if (!node.name) continue const completion = {
if (node.nodeType === 'VariableDeclaration') { label: { label: `"${node.name}"`, description: await getNodeLink(node), detail: ` ${node.name}` },
const completion = { kind: this.monaco.languages.CompletionItemKind.Method,
label: { label: `"${node.name}"`, description: await getNodeLink(node), detail: ` ${await getVariableDeclaration(node)}` }, insertText: node.name,
kind: this.monaco.languages.CompletionItemKind.Variable, range: range,
insertText: node.name, documentation: await getDocs(node)
range: range,
documentation: await getDocs(node)
}
suggestions.push(completion)
} else if (node.nodeType === 'FunctionDefinition') {
const completion = {
label: { label: `"${node.name}"`, description: await getNodeLink(node), detail: ` -> ${node.name} ${await getParamaters(node)}` },
kind: this.monaco.languages.CompletionItemKind.Function,
insertText: `${node.name}${await completeParameters(node.parameters)};`,
insertTextRules: this.monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
range: range,
documentation: await getDocs(node)
}
suggestions.push(completion)
} else if
(node.nodeType === 'ContractDefinition') {
const completion = {
label: { label: `"${node.name}"`, description: await getNodeLink(node), detail: ` ${node.name}` },
kind: this.monaco.languages.CompletionItemKind.Interface,
insertText: node.name,
range: range,
documentation: await getDocs(node)
}
suggestions.push(completion)
} else if
(node.nodeType === 'StructDefinition') {
const completion = {
label: { label: `"${node.name}"`, description: await getNodeLink(node), detail: ` ${node.name}` },
kind: this.monaco.languages.CompletionItemKind.Struct,
insertText: node.name,
range: range,
documentation: await getDocs(node)
}
suggestions.push(completion)
} else if
(node.nodeType === 'EnumDefinition') {
const completion = {
label: { label: `"${node.name}"`, description: await getNodeLink(node), detail: ` ${node.name}` },
kind: this.monaco.languages.CompletionItemKind.Enum,
insertText: node.name,
range: range,
documentation: await getDocs(node)
}
suggestions.push(completion)
} else if
(node.nodeType === 'EventDefinition') {
const completion = {
label: { label: `"${node.name}"`, description: await getNodeLink(node), detail: ` -> ${node.name} ${await getParamaters(node)}` },
kind: this.monaco.languages.CompletionItemKind.Event,
insertText: `${node.name}${await completeParameters(node.parameters)};`,
insertTextRules: this.monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
range: range,
documentation: await getDocs(node)
}
suggestions.push(completion)
} else if
(node.nodeType === 'ModifierDefinition') {
const completion = {
label: { label: `"${node.name}"`, description: await getNodeLink(node), detail: ` ${node.name}` },
kind: this.monaco.languages.CompletionItemKind.Method,
insertText: node.name,
range: range,
documentation: await getDocs(node)
}
suggestions.push(completion)
} else if
(node.nodeType === 'EnumValue' || node.type === 'EnumValue') {
const completion = {
label: { label: `"${node.name}"` },
kind: this.monaco.languages.CompletionItemKind.EnumMember,
insertText: node.name,
range: range,
documentation: null
}
suggestions.push(completion)
}
} }
suggestions.push(completion)
return { } else if
suggestions (node.nodeType === 'EnumValue' || node.type === 'EnumValue') {
const completion = {
label: { label: `"${node.name}"` },
kind: this.monaco.languages.CompletionItemKind.EnumMember,
insertText: node.name,
range: range,
documentation: null
} }
suggestions.push(completion)
}
} }
private getContractCompletions = async () => { return {
let nodes: any[] = [] suggestions
const { nodesAtPosition, block } = await retrieveNodesAtPosition(this.props.editorAPI, this.props.plugin) }
const fileNodes = await this.props.plugin.call('codeParser', 'getCurrentFileNodes') }
// find the contract and get the nodes of the contract and the base contracts and imports
if (isArray(nodesAtPosition) && nodesAtPosition.length) { private getContractCompletions = async () => {
let contractNode: any = {} let nodes: any[] = []
for (const node of nodesAtPosition) { const { nodesAtPosition, block } = await retrieveNodesAtPosition(this.props.editorAPI, this.props.plugin)
if (node.nodeType === 'ContractDefinition') { const fileNodes = await this.props.plugin.call('codeParser', 'getCurrentFileNodes')
contractNode = node // find the contract and get the nodes of the contract and the base contracts and imports
const contractNodes = fileNodes.contracts[node.name] if (isArray(nodesAtPosition) && nodesAtPosition.length) {
nodes = [...Object.values(contractNodes.contractScopeNodes), ...nodes] let contractNode: any = {}
nodes = [...Object.values(contractNodes.baseNodesWithBaseContractScope), ...nodes] for (const node of nodesAtPosition) {
nodes = [...Object.values(fileNodes.imports), ...nodes] if (node.nodeType === 'ContractDefinition') {
// add the nodes at the block itself contractNode = node
if (block && block.name) { const contractNodes = fileNodes.contracts[node.name]
const contractNodes = fileNodes.contracts[node.name].contractNodes nodes = [...Object.values(contractNodes.contractScopeNodes), ...nodes]
for (const contractNode of Object.values(contractNodes)) { nodes = [...Object.values(contractNodes.baseNodesWithBaseContractScope), ...nodes]
if (contractNode['name'] === block.name nodes = [...Object.values(fileNodes.imports), ...nodes]
// add the nodes at the block itself
if (block && block.name) {
const contractNodes = fileNodes.contracts[node.name].contractNodes
for (const contractNode of Object.values(contractNodes)) {
if (contractNode['name'] === block.name
|| (contractNode['kind'] === 'constructor' && block.name === 'constructor') || (contractNode['kind'] === 'constructor' && block.name === 'constructor')
) { ) {
let nodeOfScope = await this.props.plugin.call('codeParser', 'getNodesWithScope', (contractNode as any).id) let nodeOfScope = await this.props.plugin.call('codeParser', 'getNodesWithScope', (contractNode as any).id)
nodes = [...nodes, ...nodeOfScope] nodes = [...nodes, ...nodeOfScope]
if (contractNode['body']) { if (contractNode['body']) {
nodeOfScope = await this.props.plugin.call('codeParser', 'getNodesWithScope', (contractNode['body'] as any).id) nodeOfScope = await this.props.plugin.call('codeParser', 'getNodesWithScope', (contractNode['body'] as any).id)
nodes = [...nodes, ...nodeOfScope] nodes = [...nodes, ...nodeOfScope]
}
}
}
} else { // we use the block info from the nodesAtPosition
const contractNodes = fileNodes.contracts[node.name].contractNodes
for (const contractNode of Object.values(contractNodes)) {
if((contractNode as any).nodeType === 'Block'){
const nodeOfScope = await this.props.plugin.call('codeParser', 'getNodesWithScope', (contractNode as any).id)
nodes = [...nodes, ...nodeOfScope]
}
}
}
// filter private nodes, only allow them when contract ID is the same as the current contract
nodes = nodes.filter(node => {
if (node.visibility) {
if (node.visibility === 'private') {
return (node.contractId ? node.contractId === contractNode.id : false) || false
}
}
return true
})
break;
} }
}
} }
} else { } else { // we use the block info from the nodesAtPosition
// get all the nodes from a simple code parser which only parses the current file const contractNodes = fileNodes.contracts[node.name].contractNodes
const allNodesFromAntlr = await this.props.plugin.call('codeParser', 'listAstNodes') for (const contractNode of Object.values(contractNodes)) {
if (allNodesFromAntlr) { if((contractNode as any).nodeType === 'Block'){
nodes = [...nodes, ...allNodesFromAntlr] const nodeOfScope = await this.props.plugin.call('codeParser', 'getNodesWithScope', (contractNode as any).id)
nodes = [...nodes, ...nodeOfScope]
}
} }
} }
return nodes // filter private nodes, only allow them when contract ID is the same as the current contract
} nodes = nodes.filter(node => {
if (node.visibility) {
private getThisCompletions = async () => { if (node.visibility === 'private') {
let nodes: any[] = [] return (node.contractId ? node.contractId === contractNode.id : false) || false
let thisCompletionNodes = await this.getContractCompletions() }
const allowedTypesForThisCompletion = ['VariableDeclaration', 'FunctionDefinition']
// with this. you can't have internal nodes and no contractDefinitions
thisCompletionNodes = thisCompletionNodes.filter(node => {
if (node.visibility && (node.visibility === 'internal' || node.visibility === 'private')) {
return false
}
if (node.nodeType && !allowedTypesForThisCompletion.includes(node.nodeType)) {
return false
} }
return true return true
}) })
nodes = [...nodes, ...thisCompletionNodes] break;
return nodes }
}
private getDotCompletions = async (nameOfLastTypedExpression: string, range) => { }
const contractCompletions = await this.getContractCompletions() } else {
let nodes: any[] = [] // get all the nodes from a simple code parser which only parses the current file
let suggestions: monacoTypes.languages.CompletionItem[] = [] const allNodesFromAntlr = await this.props.plugin.call('codeParser', 'listAstNodes')
if (allNodesFromAntlr) {
const filterNodes = (nodes: any[], parentNode: any, declarationOf: any = null) => { nodes = [...nodes, ...allNodesFromAntlr]
return nodes && nodes.filter(node => { }
if (node.visibility) { }
if (declarationOf && declarationOf.nodeType && declarationOf.nodeType === 'StructDefinition') { return nodes
return true }
}
if ((node.visibility === 'internal' && !parentNode.isBaseNode) || node.visibility === 'private') { private getThisCompletions = async () => {
return false let nodes: any[] = []
} let thisCompletionNodes = await this.getContractCompletions()
} const allowedTypesForThisCompletion = ['VariableDeclaration', 'FunctionDefinition']
return true // with this. you can't have internal nodes and no contractDefinitions
}) thisCompletionNodes = thisCompletionNodes.filter(node => {
if (node.visibility && (node.visibility === 'internal' || node.visibility === 'private')) {
return false
}
if (node.nodeType && !allowedTypesForThisCompletion.includes(node.nodeType)) {
return false
}
return true
})
nodes = [...nodes, ...thisCompletionNodes]
return nodes
}
private getDotCompletions = async (nameOfLastTypedExpression: string, range) => {
const contractCompletions = await this.getContractCompletions()
let nodes: any[] = []
let suggestions: monacoTypes.languages.CompletionItem[] = []
const filterNodes = (nodes: any[], parentNode: any, declarationOf: any = null) => {
return nodes && nodes.filter(node => {
if (node.visibility) {
if (declarationOf && declarationOf.nodeType && declarationOf.nodeType === 'StructDefinition') {
return true
}
if ((node.visibility === 'internal' && !parentNode.isBaseNode) || node.visibility === 'private') {
return false
}
} }
return true
})
}
for (const nodeOfScope of contractCompletions) { for (const nodeOfScope of contractCompletions) {
if (nodeOfScope.name === nameOfLastTypedExpression) { if (nodeOfScope.name === nameOfLastTypedExpression) {
if (nodeOfScope.typeName && nodeOfScope.typeName.nodeType === 'UserDefinedTypeName') { if (nodeOfScope.typeName && nodeOfScope.typeName.nodeType === 'UserDefinedTypeName') {
const declarationOf: AstNode = await this.props.plugin.call('codeParser', 'declarationOf', nodeOfScope.typeName) const declarationOf: AstNode = await this.props.plugin.call('codeParser', 'declarationOf', nodeOfScope.typeName)
nodes = [...nodes, nodes = [...nodes,
...filterNodes(declarationOf.nodes, nodeOfScope, declarationOf) ...filterNodes(declarationOf.nodes, nodeOfScope, declarationOf)
|| filterNodes(declarationOf.members, nodeOfScope, declarationOf)] || filterNodes(declarationOf.members, nodeOfScope, declarationOf)]
const baseContracts = await this.getlinearizedBaseContracts(declarationOf) const baseContracts = await this.getlinearizedBaseContracts(declarationOf)
for (const baseContract of baseContracts) { for (const baseContract of baseContracts) {
nodes = [...nodes, ...filterNodes(baseContract.nodes, nodeOfScope)] nodes = [...nodes, ...filterNodes(baseContract.nodes, nodeOfScope)]
} }
} else if (nodeOfScope.members) { } else if (nodeOfScope.members) {
nodes = [...nodes, ...filterNodes(nodeOfScope.members, nodeOfScope)] nodes = [...nodes, ...filterNodes(nodeOfScope.members, nodeOfScope)]
} else if (nodeOfScope.typeName && nodeOfScope.typeName.nodeType === 'ArrayTypeName') { } else if (nodeOfScope.typeName && nodeOfScope.typeName.nodeType === 'ArrayTypeName') {
suggestions = [...suggestions, ...getContextualAutoCompleteBTypeName('ArrayTypeName', range, this.monaco)] suggestions = [...suggestions, ...getContextualAutoCompleteBTypeName('ArrayTypeName', range, this.monaco)]
} else if (nodeOfScope.typeName && nodeOfScope.typeName.nodeType === 'ElementaryTypeName' && nodeOfScope.typeName.name === 'bytes') { } else if (nodeOfScope.typeName && nodeOfScope.typeName.nodeType === 'ElementaryTypeName' && nodeOfScope.typeName.name === 'bytes') {
suggestions = [...suggestions, ...getContextualAutoCompleteBTypeName('bytes', range, this.monaco)] suggestions = [...suggestions, ...getContextualAutoCompleteBTypeName('bytes', range, this.monaco)]
} else if (nodeOfScope.typeName && nodeOfScope.typeName.nodeType === 'ElementaryTypeName' && nodeOfScope.typeName.name === 'address') { } else if (nodeOfScope.typeName && nodeOfScope.typeName.nodeType === 'ElementaryTypeName' && nodeOfScope.typeName.name === 'address') {
suggestions = [...suggestions, ...getContextualAutoCompleteBTypeName('address', range, this.monaco)] suggestions = [...suggestions, ...getContextualAutoCompleteBTypeName('address', range, this.monaco)]
}
}
} }
}
}
return { nodes, suggestions }
}
private getlinearizedBaseContracts = async (node: any) => { return { nodes, suggestions }
let params = [] }
if (node.linearizedBaseContracts) {
for (const id of node.linearizedBaseContracts) { private getlinearizedBaseContracts = async (node: any) => {
if (id !== node.id) { let params = []
const baseContract = await this.props.plugin.call('codeParser', 'getNodeById', id) if (node.linearizedBaseContracts) {
params = [...params, ...[baseContract]] for (const id of node.linearizedBaseContracts) {
} if (id !== node.id) {
} const baseContract = await this.props.plugin.call('codeParser', 'getNodeById', id)
params = [...params, ...[baseContract]]
} }
return params }
} }
return params
}
/** /**
* *
* @param lineTextBeforeCursor * @param lineTextBeforeCursor
* @returns * @returns
*/ */
private async getLastNodeInExpression(lineTextBeforeCursor: string) { private async getLastNodeInExpression(lineTextBeforeCursor: string) {
const wrapLineInFunction = async (text: string) => { const wrapLineInFunction = async (text: string) => {
return `function() { return `function() {
${text} ${text}
}` }`
} }
let lastNodeInExpression let lastNodeInExpression
const linesToCheck = const linesToCheck =
[ [
lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode;", lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode;",
lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode;}", lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode;}",
lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode);", lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode);",
await wrapLineInFunction(lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode;"), await wrapLineInFunction(lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode;"),
await wrapLineInFunction(lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode;}"), await wrapLineInFunction(lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode;}"),
await wrapLineInFunction(lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode;)"), await wrapLineInFunction(lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode;)"),
await wrapLineInFunction(lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode)"), await wrapLineInFunction(lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode)"),
await wrapLineInFunction(lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode);"), await wrapLineInFunction(lineTextBeforeCursor.substring(0, lineTextBeforeCursor.lastIndexOf('.')) + ".lastnode);"),
] ]
for (const line of linesToCheck) { for (const line of linesToCheck) {
try { try {
const lineAst = await this.props.plugin.call('codeParser', 'parseSolidity', line) const lineAst = await this.props.plugin.call('codeParser', 'parseSolidity', line)
const lastNode = await this.props.plugin.call('codeParser', 'getLastNodeInLine', lineAst) const lastNode = await this.props.plugin.call('codeParser', 'getLastNodeInLine', lineAst)
if (lastNode) { if (lastNode) {
lastNodeInExpression = lastNode lastNodeInExpression = lastNode
break break
} }
} catch (e) { } catch (e) {
} }
}
return lastNodeInExpression
} }
return lastNodeInExpression
}
} }

@ -3,86 +3,86 @@ import monaco from "../../types/monaco"
import { EditorUIProps } from "../remix-ui-editor" import { EditorUIProps } from "../remix-ui-editor"
export class RemixDefinitionProvider implements monaco.languages.DefinitionProvider { export class RemixDefinitionProvider implements monaco.languages.DefinitionProvider {
props: EditorUIProps props: EditorUIProps
monaco: Monaco monaco: Monaco
constructor(props: any, monaco: any) { constructor(props: any, monaco: any) {
this.props = props this.props = props
this.monaco = monaco this.monaco = monaco
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
async provideDefinition(model: monaco.editor.ITextModel, position: monaco.Position, token: monaco.CancellationToken): Promise<monaco.languages.Definition | monaco.languages.LocationLink[]> { async provideDefinition(model: monaco.editor.ITextModel, position: monaco.Position, token: monaco.CancellationToken): Promise<monaco.languages.Definition | monaco.languages.LocationLink[]> {
const cursorPosition = this.props.editorAPI.getCursorPosition() const cursorPosition = this.props.editorAPI.getCursorPosition()
let jumpLocation = await this.jumpToDefinition(cursorPosition) let jumpLocation = await this.jumpToDefinition(cursorPosition)
if (!jumpLocation || !jumpLocation.fileName) { if (!jumpLocation || !jumpLocation.fileName) {
const line = model.getLineContent(position.lineNumber) const line = model.getLineContent(position.lineNumber)
const lastpart = line.substring(0, position.column - 1).split(';').pop() const lastpart = line.substring(0, position.column - 1).split(';').pop()
if (lastpart.startsWith('import')) { if (lastpart.startsWith('import')) {
const importPath = line.substring(lastpart.indexOf('"') + 1) const importPath = line.substring(lastpart.indexOf('"') + 1)
const importPath2 = importPath.substring(0, importPath.indexOf('"')) const importPath2 = importPath.substring(0, importPath.indexOf('"'))
jumpLocation = { jumpLocation = {
startLineNumber: 1, startLineNumber: 1,
startColumn: 1, startColumn: 1,
endColumn: 1, endColumn: 1,
endLineNumber: 1, endLineNumber: 1,
fileName: importPath2 fileName: importPath2
}
}
} }
if (jumpLocation && jumpLocation.fileName) { }
return [{ }
uri: this.monaco.Uri.parse(jumpLocation.fileName), if (jumpLocation && jumpLocation.fileName) {
range: { return [{
startLineNumber: jumpLocation.startLineNumber, uri: this.monaco.Uri.parse(jumpLocation.fileName),
startColumn: jumpLocation.startColumn, range: {
endLineNumber: jumpLocation.endLineNumber, startLineNumber: jumpLocation.startLineNumber,
endColumn: jumpLocation.endColumn startColumn: jumpLocation.startColumn,
} endLineNumber: jumpLocation.endLineNumber,
}] endColumn: jumpLocation.endColumn
} }
return [] }]
} }
return []
}
async jumpToDefinition(position: any) { async jumpToDefinition(position: any) {
const node = await this.props.plugin.call('codeParser', 'definitionAtPosition', position) const node = await this.props.plugin.call('codeParser', 'definitionAtPosition', position)
const sourcePosition = await this.props.plugin.call('codeParser', 'positionOfDefinition', node) const sourcePosition = await this.props.plugin.call('codeParser', 'positionOfDefinition', node)
if (sourcePosition) { if (sourcePosition) {
return await this.jumpToPosition(sourcePosition) return await this.jumpToPosition(sourcePosition)
}
} }
}
/* /*
* onClick jump to position of ast node in the editor * onClick jump to position of ast node in the editor
*/ */
async jumpToPosition(position: any) { async jumpToPosition(position: any) {
const jumpToLine = async (fileName: string, lineColumn: any) => { const jumpToLine = async (fileName: string, lineColumn: any) => {
const fileTarget = await this.props.plugin.call('fileManager', 'getPathFromUrl', fileName) const fileTarget = await this.props.plugin.call('fileManager', 'getPathFromUrl', fileName)
if (fileName !== await this.props.plugin.call('fileManager', 'file')) { if (fileName !== await this.props.plugin.call('fileManager', 'file')) {
await this.props.plugin.call('contentImport', 'resolveAndSave', fileName, null) await this.props.plugin.call('contentImport', 'resolveAndSave', fileName, null)
const fileContent = await this.props.plugin.call('fileManager', 'readFile', fileName) const fileContent = await this.props.plugin.call('fileManager', 'readFile', fileName)
try { try {
await this.props.plugin.call('editor', 'addModel', fileTarget.file, fileContent) await this.props.plugin.call('editor', 'addModel', fileTarget.file, fileContent)
} catch (e) { } catch (e) {
}
}
if (lineColumn.start && lineColumn.start.line >= 0 && lineColumn.start.column >= 0) {
const pos = {
startLineNumber: lineColumn.start.line + 1,
startColumn: lineColumn.start.column + 1,
endColumn: lineColumn.end.column + 1,
endLineNumber: lineColumn.end.line + 1,
fileName: (fileTarget && fileTarget.file) || fileName
}
return pos
}
} }
const lastCompilationResult = await this.props.plugin.call('codeParser', 'getLastCompilationResult') // await this.props.plugin.call('compilerArtefacts', 'getLastCompilationResult') }
if (lastCompilationResult && lastCompilationResult.languageversion.indexOf('soljson') === 0 && lastCompilationResult.data) { if (lineColumn.start && lineColumn.start.line >= 0 && lineColumn.start.column >= 0) {
const pos = {
const lineColumn = await this.props.plugin.call('codeParser', 'getLineColumnOfPosition', position) startLineNumber: lineColumn.start.line + 1,
const filename = lastCompilationResult.getSourceName(position.file) startColumn: lineColumn.start.column + 1,
return await jumpToLine(filename, lineColumn) endColumn: lineColumn.end.column + 1,
endLineNumber: lineColumn.end.line + 1,
fileName: (fileTarget && fileTarget.file) || fileName
} }
return pos
}
}
const lastCompilationResult = await this.props.plugin.call('codeParser', 'getLastCompilationResult') // await this.props.plugin.call('compilerArtefacts', 'getLastCompilationResult')
if (lastCompilationResult && lastCompilationResult.languageversion.indexOf('soljson') === 0 && lastCompilationResult.data) {
const lineColumn = await this.props.plugin.call('codeParser', 'getLineColumnOfPosition', position)
const filename = lastCompilationResult.getSourceName(position.file)
return await jumpToLine(filename, lineColumn)
} }
}
} }

@ -4,35 +4,35 @@ import monaco from "../../types/monaco"
import { EditorUIProps } from "../remix-ui-editor" import { EditorUIProps } from "../remix-ui-editor"
export class RemixHighLightProvider implements monaco.languages.DocumentHighlightProvider { export class RemixHighLightProvider implements monaco.languages.DocumentHighlightProvider {
props: EditorUIProps props: EditorUIProps
monaco: Monaco monaco: Monaco
constructor(props: any, monaco: any) { constructor(props: any, monaco: any) {
this.props = props this.props = props
this.monaco = monaco this.monaco = monaco
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
async provideDocumentHighlights(model: monaco.editor.ITextModel, position: monaco.Position, token: monaco.CancellationToken): Promise<monaco.languages.DocumentHighlight[]> { async provideDocumentHighlights(model: monaco.editor.ITextModel, position: monaco.Position, token: monaco.CancellationToken): Promise<monaco.languages.DocumentHighlight[]> {
const cursorPosition = this.props.editorAPI.getCursorPosition() const cursorPosition = this.props.editorAPI.getCursorPosition()
const nodes = await this.props.plugin.call('codeParser', 'referrencesAtPosition', cursorPosition) const nodes = await this.props.plugin.call('codeParser', 'referrencesAtPosition', cursorPosition)
const highlights: monaco.languages.DocumentHighlight[] = [] const highlights: monaco.languages.DocumentHighlight[] = []
if (nodes && nodes.length) { if (nodes && nodes.length) {
const compilationResult = await this.props.plugin.call('codeParser', 'getLastCompilationResult') const compilationResult = await this.props.plugin.call('codeParser', 'getLastCompilationResult')
const file = await this.props.plugin.call('fileManager', 'file') const file = await this.props.plugin.call('fileManager', 'file')
if (compilationResult && compilationResult.data && compilationResult.data.sources[file]) { if (compilationResult && compilationResult.data && compilationResult.data.sources[file]) {
for (const node of nodes) { for (const node of nodes) {
const position = sourceMappingDecoder.decode(node.src) const position = sourceMappingDecoder.decode(node.src)
const fileInNode = compilationResult.getSourceName(position.file) const fileInNode = compilationResult.getSourceName(position.file)
if (fileInNode === file) { if (fileInNode === file) {
const lineColumn = await this.props.plugin.call('codeParser', 'getLineColumnOfPosition', position) const lineColumn = await this.props.plugin.call('codeParser', 'getLineColumnOfPosition', position)
const range = new this.monaco.Range(lineColumn.start.line + 1, lineColumn.start.column + 1, lineColumn.end.line + 1, lineColumn.end.column + 1) const range = new this.monaco.Range(lineColumn.start.line + 1, lineColumn.start.column + 1, lineColumn.end.line + 1, lineColumn.end.column + 1)
highlights.push({ highlights.push({
range, range,
}) })
} }
}
}
} }
return highlights }
} }
return highlights
}
} }

@ -4,203 +4,203 @@ import { EditorUIProps } from '../remix-ui-editor'
import { monacoTypes } from '@remix-ui/editor'; import { monacoTypes } from '@remix-ui/editor';
export class RemixHoverProvider implements monacoTypes.languages.HoverProvider { export class RemixHoverProvider implements monacoTypes.languages.HoverProvider {
props: EditorUIProps props: EditorUIProps
monaco: Monaco monaco: Monaco
constructor(props: any, monaco: any) { constructor(props: any, monaco: any) {
this.props = props this.props = props
this.monaco = monaco this.monaco = monaco
}
provideHover = async function (model: monacoTypes.editor.ITextModel, position: monacoTypes.Position): Promise<monacoTypes.languages.Hover> {
const cursorPosition = this.props.editorAPI.getHoverPosition(position)
const nodeAtPosition = await this.props.plugin.call('codeParser', 'definitionAtPosition', cursorPosition)
const contents = []
const getDocs = async (node: any) => {
contents.push({
value: await this.props.plugin.call('codeParser', 'getNodeDocumentation', node)
})
} }
provideHover = async function (model: monacoTypes.editor.ITextModel, position: monacoTypes.Position): Promise<monacoTypes.languages.Hover> { // eslint-disable-next-line @typescript-eslint/no-unused-vars
const cursorPosition = this.props.editorAPI.getHoverPosition(position) const getScope = async (node: any) => {
const nodeAtPosition = await this.props.plugin.call('codeParser', 'definitionAtPosition', cursorPosition) if (node.id) {
const contents = [] contents.push({
value: `id: ${node.id}`
})
}
if (node.scope) {
contents.push({
value: `scope: ${node.scope}`
})
}
}
const getDocs = async (node: any) => { const getLinks = async (node: any) => {
contents.push({ contents.push({
value: await this.props.plugin.call('codeParser', 'getNodeDocumentation', node) value: await this.props.plugin.call('codeParser', 'getNodeLink', node)
}) })
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars const getVariableDeclaration = async (node: any) => {
const getScope = async (node: any) => { return await this.props.plugin.call('codeParser', 'getVariableDeclaration', node)
if (node.id) { }
contents.push({
value: `id: ${node.id}`
})
}
if (node.scope) {
contents.push({
value: `scope: ${node.scope}`
})
}
}
const getLinks = async (node: any) => {
contents.push({
value: await this.props.plugin.call('codeParser', 'getNodeLink', node)
})
}
const getVariableDeclaration = async (node: any) => { const getParamaters = async (node: any) => {
return await this.props.plugin.call('codeParser', 'getVariableDeclaration', node) return await this.props.plugin.call('codeParser', 'getFunctionParamaters', node)
} }
const getReturnParameters = async (node: any) => {
return await this.props.plugin.call('codeParser', 'getFunctionReturnParameters', node)
}
const getParamaters = async (node: any) => { const getOverrides = async (node: any) => {
return await this.props.plugin.call('codeParser', 'getFunctionParamaters', node) if (node.overrides) {
const overrides = []
for (const override of node.overrides.overrides) {
overrides.push(override.name)
} }
if (overrides.length)
return ` overrides (${overrides.join(', ')})`
}
return ''
}
const getReturnParameters = async (node: any) => { const getlinearizedBaseContracts = async (node: any) => {
return await this.props.plugin.call('codeParser', 'getFunctionReturnParameters', node) const params = []
if (node.linearizedBaseContracts) {
for (const id of node.linearizedBaseContracts) {
const baseContract = await this.props.plugin.call('codeParser', 'getNodeById', id)
params.push(
baseContract.name
)
} }
if (params.length)
return `is ${params.join(', ')}`
}
return ''
}
if (nodeAtPosition) {
const getOverrides = async (node: any) => { if (nodeAtPosition.absolutePath) {
if (node.overrides) { const target = await this.props.plugin.call('fileManager', 'getPathFromUrl', nodeAtPosition.absolutePath)
const overrides = [] if (target.file !== nodeAtPosition.absolutePath) {
for (const override of node.overrides.overrides) { contents.push({
overrides.push(override.name) value: `${target.file}`
} })
if (overrides.length)
return ` overrides (${overrides.join(', ')})`
}
return ''
} }
contents.push({
const getlinearizedBaseContracts = async (node: any) => { value: `${nodeAtPosition.absolutePath}`
const params = [] })
if (node.linearizedBaseContracts) { }
for (const id of node.linearizedBaseContracts) { if (nodeAtPosition.nodeType === 'VariableDeclaration') {
const baseContract = await this.props.plugin.call('codeParser', 'getNodeById', id) contents.push({
params.push( value: await getVariableDeclaration(nodeAtPosition)
baseContract.name })
)
} }
if (params.length) else if (nodeAtPosition.nodeType === 'ElementaryTypeName') {
return `is ${params.join(', ')}` contents.push({
} value: `${nodeAtPosition.typeDescriptions.typeString}`
return '' })
} else if (nodeAtPosition.nodeType === 'FunctionDefinition') {
if (!nodeAtPosition.name) return
const returns = await getReturnParameters(nodeAtPosition)
contents.push({
value: `function ${nodeAtPosition.name} ${await getParamaters(nodeAtPosition)} ${nodeAtPosition.visibility} ${nodeAtPosition.stateMutability}${await getOverrides(nodeAtPosition)} ${returns ? `returns ${returns}` : ''}`
})
} else if (nodeAtPosition.nodeType === 'ModifierDefinition') {
contents.push({
value: `modifier ${nodeAtPosition.name} ${await getParamaters(nodeAtPosition)}`
})
} else if (nodeAtPosition.nodeType === 'EventDefinition') {
contents.push({
value: `modifier ${nodeAtPosition.name} ${await getParamaters(nodeAtPosition)}`
})
} else if (nodeAtPosition.nodeType === 'ContractDefinition') {
contents.push({
value: `${nodeAtPosition.contractKind || nodeAtPosition.kind} ${nodeAtPosition.name} ${await getlinearizedBaseContracts(nodeAtPosition)}`
})
} else if (nodeAtPosition.nodeType === 'InvalidNode') {
contents.push({
value: `There are errors in the code.`
})
} else if (nodeAtPosition.nodeType === 'Block') {
} else {
contents.push({
value: `${nodeAtPosition.nodeType}`
})
}
for (const key in contents) {
contents[key].value = '```remix-solidity\n' + contents[key].value + '\n```'
}
getLinks(nodeAtPosition)
getDocs(nodeAtPosition)
// getScope(nodeAtPosition)
try {
if (nodeAtPosition?.name === 'msg') {
const global = await this.props.plugin.call('debugger', 'globalContext')
if (global !== null && global[nodeAtPosition?.name]) {
contents.push({
value: `GLOBAL VARIABLE ${nodeAtPosition.name}: ${JSON.stringify(global[nodeAtPosition?.name], null, '\t')}`
})
}
} }
} catch (e) {}
if (nodeAtPosition) { try {
if (nodeAtPosition.absolutePath) { if (nodeAtPosition?.expression?.name === 'msg' && nodeAtPosition?.memberName) {
const target = await this.props.plugin.call('fileManager', 'getPathFromUrl', nodeAtPosition.absolutePath) const global = await this.props.plugin.call('debugger', 'globalContext')
if (target.file !== nodeAtPosition.absolutePath) { if (global !== null && global[nodeAtPosition?.expression?.name][nodeAtPosition.memberName] && global[nodeAtPosition?.expression?.name][nodeAtPosition.memberName]) {
contents.push({ contents.push({
value: `${target.file}` value: `GLOBAL VARIABLE msg.${nodeAtPosition.memberName}: ${global[nodeAtPosition?.expression?.name][nodeAtPosition.memberName]}`
}) })
} }
contents.push({
value: `${nodeAtPosition.absolutePath}`
})
}
if (nodeAtPosition.nodeType === 'VariableDeclaration') {
contents.push({
value: await getVariableDeclaration(nodeAtPosition)
})
}
else if (nodeAtPosition.nodeType === 'ElementaryTypeName') {
contents.push({
value: `${nodeAtPosition.typeDescriptions.typeString}`
})
} else if (nodeAtPosition.nodeType === 'FunctionDefinition') {
if (!nodeAtPosition.name) return
const returns = await getReturnParameters(nodeAtPosition)
contents.push({
value: `function ${nodeAtPosition.name} ${await getParamaters(nodeAtPosition)} ${nodeAtPosition.visibility} ${nodeAtPosition.stateMutability}${await getOverrides(nodeAtPosition)} ${returns ? `returns ${returns}` : ''}`
})
} else if (nodeAtPosition.nodeType === 'ModifierDefinition') {
contents.push({
value: `modifier ${nodeAtPosition.name} ${await getParamaters(nodeAtPosition)}`
})
} else if (nodeAtPosition.nodeType === 'EventDefinition') {
contents.push({
value: `modifier ${nodeAtPosition.name} ${await getParamaters(nodeAtPosition)}`
})
} else if (nodeAtPosition.nodeType === 'ContractDefinition') {
contents.push({
value: `${nodeAtPosition.contractKind || nodeAtPosition.kind} ${nodeAtPosition.name} ${await getlinearizedBaseContracts(nodeAtPosition)}`
})
} else if (nodeAtPosition.nodeType === 'InvalidNode') {
contents.push({
value: `There are errors in the code.`
})
} else if (nodeAtPosition.nodeType === 'Block') {
} else {
contents.push({
value: `${nodeAtPosition.nodeType}`
})
}
for (const key in contents) {
contents[key].value = '```remix-solidity\n' + contents[key].value + '\n```'
}
getLinks(nodeAtPosition)
getDocs(nodeAtPosition)
// getScope(nodeAtPosition)
try {
if (nodeAtPosition?.name === 'msg') {
const global = await this.props.plugin.call('debugger', 'globalContext')
if (global !== null && global[nodeAtPosition?.name]) {
contents.push({
value: `GLOBAL VARIABLE ${nodeAtPosition.name}: ${JSON.stringify(global[nodeAtPosition?.name], null, '\t')}`
})
}
}
} catch (e) {}
try {
if (nodeAtPosition?.expression?.name === 'msg' && nodeAtPosition?.memberName) {
const global = await this.props.plugin.call('debugger', 'globalContext')
if (global !== null && global[nodeAtPosition?.expression?.name][nodeAtPosition.memberName] && global[nodeAtPosition?.expression?.name][nodeAtPosition.memberName]) {
contents.push({
value: `GLOBAL VARIABLE msg.${nodeAtPosition.memberName}: ${global[nodeAtPosition?.expression?.name][nodeAtPosition.memberName]}`
})
}
}
} catch (e) {}
try {
const decodedVar = await this.props.plugin.call('debugger', 'decodeLocalVariable', nodeAtPosition.id)
if (decodedVar !== null && decodedVar.type) {
contents.push({
value: `LOCAL VARIABLE ${nodeAtPosition.name}: ${typeof(decodedVar.value) === 'string' ? decodedVar.value : JSON.stringify(decodedVar.value, null, '\t')}`
})
}
} catch (e) {}
try {
const decodedVar = await this.props.plugin.call('debugger', 'decodeStateVariable', nodeAtPosition.id)
if (decodedVar !== null && decodedVar.type) {
contents.push({
value: `STATE VARIABLE ${nodeAtPosition.name}: ${typeof(decodedVar.value) === 'string' ? decodedVar.value : JSON.stringify(decodedVar.value, null, '\t')}`
})
}
} catch (e) {}
} }
} catch (e) {}
setTimeout(() => {
// eslint-disable-next-line no-debugger try {
// debugger const decodedVar = await this.props.plugin.call('debugger', 'decodeLocalVariable', nodeAtPosition.id)
},1000) if (decodedVar !== null && decodedVar.type) {
contents.push({
return { value: `LOCAL VARIABLE ${nodeAtPosition.name}: ${typeof(decodedVar.value) === 'string' ? decodedVar.value : JSON.stringify(decodedVar.value, null, '\t')}`
range: new this.monaco.Range( })
position.lineNumber, }
position.column, } catch (e) {}
position.lineNumber,
model.getLineMaxColumn(position.lineNumber) try {
), const decodedVar = await this.props.plugin.call('debugger', 'decodeStateVariable', nodeAtPosition.id)
contents: contents if (decodedVar !== null && decodedVar.type) {
}; contents.push({
value: `STATE VARIABLE ${nodeAtPosition.name}: ${typeof(decodedVar.value) === 'string' ? decodedVar.value : JSON.stringify(decodedVar.value, null, '\t')}`
})
}
} catch (e) {}
} }
setTimeout(() => {
// eslint-disable-next-line no-debugger
// debugger
},1000)
return {
range: new this.monaco.Range(
position.lineNumber,
position.column,
position.lineNumber,
model.getLineMaxColumn(position.lineNumber)
),
contents: contents
};
}
} }

@ -4,44 +4,44 @@ import monaco from "../../types/monaco"
import { EditorUIProps } from "../remix-ui-editor" import { EditorUIProps } from "../remix-ui-editor"
export class RemixReferenceProvider implements monaco.languages.ReferenceProvider { export class RemixReferenceProvider implements monaco.languages.ReferenceProvider {
props: EditorUIProps props: EditorUIProps
monaco: Monaco monaco: Monaco
constructor(props: any, monaco: any) { constructor(props: any, monaco: any) {
this.props = props this.props = props
this.monaco = monaco this.monaco = monaco
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
async provideReferences(model: monaco.editor.ITextModel, position: monaco.Position, context: monaco.languages.ReferenceContext, token: monaco.CancellationToken) { async provideReferences(model: monaco.editor.ITextModel, position: monaco.Position, context: monaco.languages.ReferenceContext, token: monaco.CancellationToken) {
const cursorPosition = this.props.editorAPI.getCursorPosition() const cursorPosition = this.props.editorAPI.getCursorPosition()
const nodes = await this.props.plugin.call('codeParser', 'referrencesAtPosition', cursorPosition) const nodes = await this.props.plugin.call('codeParser', 'referrencesAtPosition', cursorPosition)
const references = [] const references = []
if (nodes && nodes.length) { if (nodes && nodes.length) {
const compilationResult = await this.props.plugin.call('codeParser', 'getLastCompilationResult') const compilationResult = await this.props.plugin.call('codeParser', 'getLastCompilationResult')
const file = await this.props.plugin.call('fileManager', 'file') const file = await this.props.plugin.call('fileManager', 'file')
if (compilationResult && compilationResult.data && compilationResult.data.sources[file]) { if (compilationResult && compilationResult.data && compilationResult.data.sources[file]) {
for (const node of nodes) { for (const node of nodes) {
const position = sourceMappingDecoder.decode(node.src) const position = sourceMappingDecoder.decode(node.src)
const fileInNode = compilationResult.getSourceName(position.file) const fileInNode = compilationResult.getSourceName(position.file)
let fileTarget = await this.props.plugin.call('fileManager', 'getPathFromUrl', fileInNode) let fileTarget = await this.props.plugin.call('fileManager', 'getPathFromUrl', fileInNode)
fileTarget = fileTarget.file fileTarget = fileTarget.file
const fileContent = await this.props.plugin.call('fileManager', 'readFile', fileInNode) const fileContent = await this.props.plugin.call('fileManager', 'readFile', fileInNode)
const lineColumn = await this.props.plugin.call('codeParser', 'getLineColumnOfPosition', position) const lineColumn = await this.props.plugin.call('codeParser', 'getLineColumnOfPosition', position)
try { try {
this.props.plugin.call('editor', 'addModel', fileTarget, fileContent) this.props.plugin.call('editor', 'addModel', fileTarget, fileContent)
} catch (e) { } catch (e) {
}
const range = new this.monaco.Range(lineColumn.start.line + 1, lineColumn.start.column + 1, lineColumn.end.line + 1, lineColumn.end.column + 1)
references.push({
range,
uri: this.monaco.Uri.parse(fileTarget)
})
}
} }
const range = new this.monaco.Range(lineColumn.start.line + 1, lineColumn.start.column + 1, lineColumn.end.line + 1, lineColumn.end.column + 1)
references.push({
range,
uri: this.monaco.Uri.parse(fileTarget)
})
} }
return references
} }
}
return references
}
} }

@ -565,7 +565,7 @@ export const EditorUI = (props: EditorUIProps) => {
}) })
editor.onDidPaste((e) => { editor.onDidPaste((e) => {
if (!pasteCodeRef.current && e && e.range && e.range.startLineNumber >= 0 && e.range.endLineNumber >= 0 && e.range.endLineNumber - e.range.startLineNumber > 10) { if (!pasteCodeRef.current && e && e.range && e.range.startLineNumber >= 0 && e.range.endLineNumber >= 0 && e.range.endLineNumber - e.range.startLineNumber > 10) {
const modalContent: AlertModal = { const modalContent: AlertModal = {
id: 'newCodePasted', id: 'newCodePasted',
title: 'Pasted Code Alert', title: 'Pasted Code Alert',
@ -767,7 +767,7 @@ export const EditorUI = (props: EditorUIProps) => {
{editorModelsState[props.currentFile]?.readOnly && <span className='pl-4 h6 mb-0 w-100 alert-info position-absolute bottom-0 end-0'> {editorModelsState[props.currentFile]?.readOnly && <span className='pl-4 h6 mb-0 w-100 alert-info position-absolute bottom-0 end-0'>
<i className="fas fa-lock-alt p-2"></i> <i className="fas fa-lock-alt p-2"></i>
The file is opened in <b>read-only</b> mode. The file is opened in <b>read-only</b> mode.
</span> </span>
} }
</div> </div>
) )

@ -2,240 +2,240 @@ import { remixTypes } from './remix-plugin-types'
import { hardhatEthersExtension } from './hardhat-ethers-extension' import { hardhatEthersExtension } from './hardhat-ethers-extension'
export const loadTypes = async (monaco) => { export const loadTypes = async (monaco) => {
// ethers.js // ethers.js
// @ts-ignore // @ts-ignore
const ethersAbi = await import('raw-loader!@ethersproject/abi/lib/index.d.ts') const ethersAbi = await import('raw-loader!@ethersproject/abi/lib/index.d.ts')
const ethersAbiDefault = ethersAbi.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersAbiDefault = ethersAbi.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersAbiDefault, `file:///node_modules/@types/@ethersproject_abi/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersAbiDefault, `file:///node_modules/@types/@ethersproject_abi/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersAbstract = await import('raw-loader!@ethersproject/abstract-provider/lib/index.d.ts') const ethersAbstract = await import('raw-loader!@ethersproject/abstract-provider/lib/index.d.ts')
const ethersAbstractDefault = ethersAbstract.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersAbstractDefault = ethersAbstract.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersAbstractDefault, `file:///node_modules/@types/@ethersproject_abstract-provider/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersAbstractDefault, `file:///node_modules/@types/@ethersproject_abstract-provider/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersSigner = await import('raw-loader!@ethersproject/abstract-signer/lib/index.d.ts') const ethersSigner = await import('raw-loader!@ethersproject/abstract-signer/lib/index.d.ts')
const ethersSignerDefault = ethersSigner.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersSignerDefault = ethersSigner.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSignerDefault, `file:///node_modules/@types/@ethersproject_abstract-signer/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSignerDefault, `file:///node_modules/@types/@ethersproject_abstract-signer/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersAddress = await import('raw-loader!@ethersproject/address/lib/index.d.ts') const ethersAddress = await import('raw-loader!@ethersproject/address/lib/index.d.ts')
const ethersAddressDefault = ethersAddress.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersAddressDefault = ethersAddress.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersAddressDefault, `file:///node_modules/@types/@ethersproject_address/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersAddressDefault, `file:///node_modules/@types/@ethersproject_address/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersBase64 = await import('raw-loader!@ethersproject/base64/lib/index.d.ts') const ethersBase64 = await import('raw-loader!@ethersproject/base64/lib/index.d.ts')
const ethersBase64Default = ethersBase64.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersBase64Default = ethersBase64.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBase64Default, `file:///node_modules/@types/@ethersproject_base64/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBase64Default, `file:///node_modules/@types/@ethersproject_base64/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersBasex = await import('raw-loader!@ethersproject/basex/lib/index.d.ts') const ethersBasex = await import('raw-loader!@ethersproject/basex/lib/index.d.ts')
const ethersBasexDefault = ethersBasex.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersBasexDefault = ethersBasex.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBasexDefault, `file:///node_modules/@types/@ethersproject_basex/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBasexDefault, `file:///node_modules/@types/@ethersproject_basex/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersBignumber = await import('raw-loader!@ethersproject/bignumber/lib/index.d.ts') const ethersBignumber = await import('raw-loader!@ethersproject/bignumber/lib/index.d.ts')
const ethersBignumberDefault = ethersBignumber.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersBignumberDefault = ethersBignumber.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBignumberDefault, `file:///node_modules/@types/@ethersproject_bignumber/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBignumberDefault, `file:///node_modules/@types/@ethersproject_bignumber/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersBytes = await import('raw-loader!@ethersproject/bytes/lib/index.d.ts') const ethersBytes = await import('raw-loader!@ethersproject/bytes/lib/index.d.ts')
const ethersBytesDefault = ethersBytes.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersBytesDefault = ethersBytes.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBytesDefault, `file:///node_modules/@types/@ethersproject_bytes/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersBytesDefault, `file:///node_modules/@types/@ethersproject_bytes/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersConstants = await import('raw-loader!@ethersproject/constants/lib/index.d.ts') const ethersConstants = await import('raw-loader!@ethersproject/constants/lib/index.d.ts')
const ethersConstantsDefault = ethersConstants.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersConstantsDefault = ethersConstants.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersConstantsDefault, `file:///node_modules/@types/@ethersproject_constants/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersConstantsDefault, `file:///node_modules/@types/@ethersproject_constants/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersContracts = await import('raw-loader!@ethersproject/contracts/lib/index.d.ts') const ethersContracts = await import('raw-loader!@ethersproject/contracts/lib/index.d.ts')
const ethersContractsDefault = ethersContracts.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersContractsDefault = ethersContracts.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersContractsDefault, `file:///node_modules/@types/@ethersproject_contracts/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersContractsDefault, `file:///node_modules/@types/@ethersproject_contracts/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersHash = await import('raw-loader!@ethersproject/hash/lib/index.d.ts') const ethersHash = await import('raw-loader!@ethersproject/hash/lib/index.d.ts')
const ethersHashDefault = ethersHash.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersHashDefault = ethersHash.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersHashDefault, `file:///node_modules/@types/@ethersproject_hash/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersHashDefault, `file:///node_modules/@types/@ethersproject_hash/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersHdnode = await import('raw-loader!@ethersproject/hdnode/lib/index.d.ts') const ethersHdnode = await import('raw-loader!@ethersproject/hdnode/lib/index.d.ts')
const ethersHdnodeDefault = ethersHdnode.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersHdnodeDefault = ethersHdnode.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersHdnodeDefault, `file:///node_modules/@types/@ethersproject_hdnode/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersHdnodeDefault, `file:///node_modules/@types/@ethersproject_hdnode/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersJsonWallets = await import('raw-loader!@ethersproject/json-wallets/lib/index.d.ts') const ethersJsonWallets = await import('raw-loader!@ethersproject/json-wallets/lib/index.d.ts')
const ethersJsonWalletsDefault = ethersJsonWallets.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersJsonWalletsDefault = ethersJsonWallets.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersJsonWalletsDefault, `file:///node_modules/@types/@ethersproject_json-wallets/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersJsonWalletsDefault, `file:///node_modules/@types/@ethersproject_json-wallets/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersKeccak256 = await import('raw-loader!@ethersproject/keccak256/lib/index.d.ts') const ethersKeccak256 = await import('raw-loader!@ethersproject/keccak256/lib/index.d.ts')
const ethersKeccak256Default = ethersKeccak256.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersKeccak256Default = ethersKeccak256.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersKeccak256Default, `file:///node_modules/@types/@ethersproject_keccak256/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersKeccak256Default, `file:///node_modules/@types/@ethersproject_keccak256/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersLogger = await import('raw-loader!@ethersproject/logger/lib/index.d.ts') const ethersLogger = await import('raw-loader!@ethersproject/logger/lib/index.d.ts')
const ethersLoggerDefault = ethersLogger.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersLoggerDefault = ethersLogger.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersLoggerDefault, `file:///node_modules/@types/@ethersproject_logger/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersLoggerDefault, `file:///node_modules/@types/@ethersproject_logger/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersNetworks = await import('raw-loader!@ethersproject/networks/lib/index.d.ts') const ethersNetworks = await import('raw-loader!@ethersproject/networks/lib/index.d.ts')
const ethersNetworksDefault = ethersNetworks.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersNetworksDefault = ethersNetworks.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersNetworksDefault, `file:///node_modules/@types/@ethersproject_networks/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersNetworksDefault, `file:///node_modules/@types/@ethersproject_networks/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersPbkdf2 = await import('raw-loader!@ethersproject/pbkdf2/lib/index.d.ts') const ethersPbkdf2 = await import('raw-loader!@ethersproject/pbkdf2/lib/index.d.ts')
const ethersPbkdf2Default = ethersPbkdf2.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersPbkdf2Default = ethersPbkdf2.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersPbkdf2Default, `file:///node_modules/@types/@ethersproject_pbkdf2/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersPbkdf2Default, `file:///node_modules/@types/@ethersproject_pbkdf2/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersProperties = await import('raw-loader!@ethersproject/properties/lib/index.d.ts') const ethersProperties = await import('raw-loader!@ethersproject/properties/lib/index.d.ts')
const ethersPropertiesDefault = ethersProperties.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersPropertiesDefault = ethersProperties.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersPropertiesDefault, `file:///node_modules/@types/@ethersproject_properties/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersPropertiesDefault, `file:///node_modules/@types/@ethersproject_properties/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersProviders = await import('raw-loader!@ethersproject/providers/lib/index.d.ts') const ethersProviders = await import('raw-loader!@ethersproject/providers/lib/index.d.ts')
const ethersProvidersDefault = ethersProviders.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersProvidersDefault = ethersProviders.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersProvidersDefault, `file:///node_modules/@types/@ethersproject_providers/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersProvidersDefault, `file:///node_modules/@types/@ethersproject_providers/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersRandom = await import('raw-loader!@ethersproject/random/lib/index.d.ts') const ethersRandom = await import('raw-loader!@ethersproject/random/lib/index.d.ts')
const ethersRandomDefault = ethersRandom.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersRandomDefault = ethersRandom.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersRandomDefault, `file:///node_modules/@types/@ethersproject_random/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersRandomDefault, `file:///node_modules/@types/@ethersproject_random/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersRlp = await import('raw-loader!@ethersproject/rlp/lib/index.d.ts') const ethersRlp = await import('raw-loader!@ethersproject/rlp/lib/index.d.ts')
const ethersRlpDefault = ethersRlp.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersRlpDefault = ethersRlp.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersRlpDefault, `file:///node_modules/@types/@ethersproject_rlp/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersRlpDefault, `file:///node_modules/@types/@ethersproject_rlp/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersSha2 = await import('raw-loader!@ethersproject/sha2/lib/index.d.ts') const ethersSha2 = await import('raw-loader!@ethersproject/sha2/lib/index.d.ts')
const ethersSha2Default = ethersSha2.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersSha2Default = ethersSha2.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSha2Default, `file:///node_modules/@types/@ethersproject_sha2/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSha2Default, `file:///node_modules/@types/@ethersproject_sha2/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersSingningkey = await import('raw-loader!@ethersproject/signing-key/lib/index.d.ts') const ethersSingningkey = await import('raw-loader!@ethersproject/signing-key/lib/index.d.ts')
const ethersSingningkeyDefault = ethersSingningkey.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersSingningkeyDefault = ethersSingningkey.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSingningkeyDefault, `file:///node_modules/@types/@ethersproject_signing-key/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSingningkeyDefault, `file:///node_modules/@types/@ethersproject_signing-key/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersSolidity = await import('raw-loader!@ethersproject/solidity/lib/index.d.ts') const ethersSolidity = await import('raw-loader!@ethersproject/solidity/lib/index.d.ts')
const ethersSolidityDefault = ethersSolidity.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersSolidityDefault = ethersSolidity.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSolidityDefault, `file:///node_modules/@types/@ethersproject_solidity/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersSolidityDefault, `file:///node_modules/@types/@ethersproject_solidity/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersStrings = await import('raw-loader!@ethersproject/strings/lib/index.d.ts') const ethersStrings = await import('raw-loader!@ethersproject/strings/lib/index.d.ts')
const ethersStringsDefault = ethersStrings.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersStringsDefault = ethersStrings.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersStringsDefault, `file:///node_modules/@types/@ethersproject_strings/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersStringsDefault, `file:///node_modules/@types/@ethersproject_strings/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersTransactions = await import('raw-loader!@ethersproject/transactions/lib/index.d.ts') const ethersTransactions = await import('raw-loader!@ethersproject/transactions/lib/index.d.ts')
const ethersTransactionsDefault = ethersTransactions.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersTransactionsDefault = ethersTransactions.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersTransactionsDefault, `file:///node_modules/@types/@ethersproject_transactions/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersTransactionsDefault, `file:///node_modules/@types/@ethersproject_transactions/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersUnits = await import('raw-loader!@ethersproject/units/lib/index.d.ts') const ethersUnits = await import('raw-loader!@ethersproject/units/lib/index.d.ts')
const ethersUnitsDefault = ethersUnits.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersUnitsDefault = ethersUnits.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersUnitsDefault, `file:///node_modules/@types/@ethersproject_units/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersUnitsDefault, `file:///node_modules/@types/@ethersproject_units/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersWallet = await import('raw-loader!@ethersproject/wallet/lib/index.d.ts') const ethersWallet = await import('raw-loader!@ethersproject/wallet/lib/index.d.ts')
const ethersWalletDefault = ethersWallet.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersWalletDefault = ethersWallet.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersWalletDefault, `file:///node_modules/@types/@ethersproject_wallet/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersWalletDefault, `file:///node_modules/@types/@ethersproject_wallet/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersWeb = await import('raw-loader!@ethersproject/web/lib/index.d.ts') const ethersWeb = await import('raw-loader!@ethersproject/web/lib/index.d.ts')
const ethersWebDefault = ethersWeb.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersWebDefault = ethersWeb.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersWebDefault, `file:///node_modules/@types/@ethersproject_web/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersWebDefault, `file:///node_modules/@types/@ethersproject_web/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethersWordlists = await import('raw-loader!@ethersproject/wordlists/lib/index.d.ts') const ethersWordlists = await import('raw-loader!@ethersproject/wordlists/lib/index.d.ts')
const ethersWordlistsDefault = ethersWordlists.default.replace(/@ethersproject\//g, '@ethersproject_') const ethersWordlistsDefault = ethersWordlists.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersWordlistsDefault, `file:///node_modules/@types/@ethersproject_wordlists/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersWordlistsDefault, `file:///node_modules/@types/@ethersproject_wordlists/index.d.ts`)
// @ts-ignore // @ts-ignore
const versionEthers = await import('raw-loader!ethers/lib/_version.d.ts') const versionEthers = await import('raw-loader!ethers/lib/_version.d.ts')
const versionEthersDefault = versionEthers.default.replace(/@ethersproject\//g, '@ethersproject_') const versionEthersDefault = versionEthers.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(versionEthersDefault, `file:///node_modules/@types/_version-ethers-lib/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(versionEthersDefault, `file:///node_modules/@types/_version-ethers-lib/index.d.ts`)
// @ts-ignore // @ts-ignore
const utilEthers = await import('raw-loader!ethers/lib/utils.d.ts') const utilEthers = await import('raw-loader!ethers/lib/utils.d.ts')
const utilEthersDefault = utilEthers.default.replace(/@ethersproject\//g, '@ethersproject_') const utilEthersDefault = utilEthers.default.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(utilEthersDefault, `file:///node_modules/@types/utils-ethers-lib/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(utilEthersDefault, `file:///node_modules/@types/utils-ethers-lib/index.d.ts`)
// @ts-ignore // @ts-ignore
const ethers = await import('raw-loader!ethers/lib/ethers.d.ts') const ethers = await import('raw-loader!ethers/lib/ethers.d.ts')
let ethersDefault = ethers.default let ethersDefault = ethers.default
ethersDefault = ethersDefault.replace(/.\/utils/g, 'utils-ethers-lib') ethersDefault = ethersDefault.replace(/.\/utils/g, 'utils-ethers-lib')
ethersDefault = ethersDefault.replace(/.\/_version/g, '_version-ethers-lib') ethersDefault = ethersDefault.replace(/.\/_version/g, '_version-ethers-lib')
ethersDefault = ethersDefault.replace(/.\/ethers/g, 'ethers-lib') ethersDefault = ethersDefault.replace(/.\/ethers/g, 'ethers-lib')
ethersDefault = ethersDefault.replace(/@ethersproject\//g, '@ethersproject_') ethersDefault = ethersDefault.replace(/@ethersproject\//g, '@ethersproject_')
ethersDefault = ethersDefault + '\n' + hardhatEthersExtension ethersDefault = ethersDefault + '\n' + hardhatEthersExtension
monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersDefault, `file:///node_modules/@types/ethers-lib/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(ethersDefault, `file:///node_modules/@types/ethers-lib/index.d.ts`)
// @ts-ignore // @ts-ignore
const indexEthers = await import('raw-loader!ethers/lib/index.d.ts') const indexEthers = await import('raw-loader!ethers/lib/index.d.ts')
let indexEthersDefault = indexEthers.default let indexEthersDefault = indexEthers.default
indexEthersDefault = indexEthersDefault.replace(/.\/ethers/g, 'ethers-lib') indexEthersDefault = indexEthersDefault.replace(/.\/ethers/g, 'ethers-lib')
indexEthersDefault = indexEthersDefault.replace(/@ethersproject\//g, '@ethersproject_') indexEthersDefault = indexEthersDefault.replace(/@ethersproject\//g, '@ethersproject_')
monaco.languages.typescript.typescriptDefaults.addExtraLib(indexEthersDefault, `file:///node_modules/@types/ethers/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(indexEthersDefault, `file:///node_modules/@types/ethers/index.d.ts`)
// Web3 // Web3
// @ts-ignore // @ts-ignore
const indexWeb3 = await import('raw-loader!web3/types/index.d.ts') const indexWeb3 = await import('raw-loader!web3/types/index.d.ts')
monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3.default, `file:///node_modules/@types/web3/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3.default, `file:///node_modules/@types/web3/index.d.ts`)
// @ts-ignore // @ts-ignore
const indexWeb3Bzz = await import('raw-loader!web3-bzz/types/index.d.ts') const indexWeb3Bzz = await import('raw-loader!web3-bzz/types/index.d.ts')
monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Bzz.default, `file:///node_modules/@types/web3-bzz/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Bzz.default, `file:///node_modules/@types/web3-bzz/index.d.ts`)
// @ts-ignore // @ts-ignore
const indexWeb3Core = await import('raw-loader!web3-core/types/index.d.ts') const indexWeb3Core = await import('raw-loader!web3-core/types/index.d.ts')
monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Core.default, `file:///node_modules/@types/web3-core/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Core.default, `file:///node_modules/@types/web3-core/index.d.ts`)
// @ts-ignore // @ts-ignore
const indexWeb3Eth = await import('raw-loader!web3-eth/types/index.d.ts') const indexWeb3Eth = await import('raw-loader!web3-eth/types/index.d.ts')
monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Eth.default, `file:///node_modules/@types/web3-eth/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Eth.default, `file:///node_modules/@types/web3-eth/index.d.ts`)
// @ts-ignore // @ts-ignore
const indexWeb3Personal = await import('raw-loader!web3-eth-personal/types/index.d.ts') const indexWeb3Personal = await import('raw-loader!web3-eth-personal/types/index.d.ts')
monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Personal.default, `file:///node_modules/@types/web3-eth-personal/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Personal.default, `file:///node_modules/@types/web3-eth-personal/index.d.ts`)
// @ts-ignore // @ts-ignore
const indexWeb3Contract = await import('raw-loader!web3-eth-contract/types/index.d.ts') const indexWeb3Contract = await import('raw-loader!web3-eth-contract/types/index.d.ts')
monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Contract.default, `file:///node_modules/@types/web3-eth-contract/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Contract.default, `file:///node_modules/@types/web3-eth-contract/index.d.ts`)
// @ts-ignore // @ts-ignore
const indexWeb3Net = await import('raw-loader!web3-net/types/index.d.ts') const indexWeb3Net = await import('raw-loader!web3-net/types/index.d.ts')
monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Net.default, `file:///node_modules/@types/web3-net/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Net.default, `file:///node_modules/@types/web3-net/index.d.ts`)
// @ts-ignore // @ts-ignore
const indexWeb3Shh = await import('raw-loader!web3-shh/types/index.d.ts') const indexWeb3Shh = await import('raw-loader!web3-shh/types/index.d.ts')
monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Shh.default, `file:///node_modules/@types/web3-shh/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Shh.default, `file:///node_modules/@types/web3-shh/index.d.ts`)
// @ts-ignore // @ts-ignore
const indexWeb3Util = await import('raw-loader!web3-utils/types/index.d.ts') const indexWeb3Util = await import('raw-loader!web3-utils/types/index.d.ts')
monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Util.default, `file:///node_modules/@types/web3-utils/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(indexWeb3Util.default, `file:///node_modules/@types/web3-utils/index.d.ts`)
// remix // remix
const indexRemixApi = remixTypes + `\n const indexRemixApi = remixTypes + `\n
declare global { declare global {
const remix: PluginClient; const remix: PluginClient;
const web3Provider; const web3Provider;
} }
` `
monaco.languages.typescript.typescriptDefaults.addExtraLib(indexRemixApi) monaco.languages.typescript.typescriptDefaults.addExtraLib(indexRemixApi)
// @ts-ignore // @ts-ignore
const chaiType = await import('raw-loader!@types/chai/index.d.ts') const chaiType = await import('raw-loader!@types/chai/index.d.ts')
monaco.languages.typescript.typescriptDefaults.addExtraLib(chaiType.default, `file:///node_modules/@types/chai/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(chaiType.default, `file:///node_modules/@types/chai/index.d.ts`)
// @ts-ignore // @ts-ignore
const mochaType = await import('raw-loader!@types/mocha/index.d.ts') const mochaType = await import('raw-loader!@types/mocha/index.d.ts')
monaco.languages.typescript.typescriptDefaults.addExtraLib(mochaType.default, `file:///node_modules/@types/mocha/index.d.ts`) monaco.languages.typescript.typescriptDefaults.addExtraLib(mochaType.default, `file:///node_modules/@types/mocha/index.d.ts`)
const loadedElement = document.createElement('span') const loadedElement = document.createElement('span')
loadedElement.setAttribute('data-id', 'typesloaded') loadedElement.setAttribute('data-id', 'typesloaded')
document.body.appendChild(loadedElement) document.body.appendChild(loadedElement)
} }

@ -24,15 +24,15 @@ export const FileDecorationIcons = (props: fileDecorationProps) => {
for (const [index, state] of states.entries()) { for (const [index, state] of states.entries()) {
switch (state.fileStateType) { switch (state.fileStateType) {
case fileDecorationType.Error: case fileDecorationType.Error:
elements.push(<FileDecorationTooltip key={index} index={index} fileDecoration={state} icon={<FileDecorationErrorIcon fileDecoration={state} key={index}/>}/>) elements.push(<FileDecorationTooltip key={index} index={index} fileDecoration={state} icon={<FileDecorationErrorIcon fileDecoration={state} key={index}/>}/>)
break break
case fileDecorationType.Warning: case fileDecorationType.Warning:
elements.push(<FileDecorationTooltip key={index} index={index} fileDecoration={state} icon={<FileDecorationWarningIcon fileDecoration={state} key={index}/>}/>) elements.push(<FileDecorationTooltip key={index} index={index} fileDecoration={state} icon={<FileDecorationWarningIcon fileDecoration={state} key={index}/>}/>)
break break
case fileDecorationType.Custom: case fileDecorationType.Custom:
elements.push(<FileDecorationTooltip key={index} index={index} fileDecoration={state} icon={<FileDecorationCustomIcon fileDecoration={state} key={index}/>}/>) elements.push(<FileDecorationTooltip key={index} index={index} fileDecoration={state} icon={<FileDecorationCustomIcon fileDecoration={state} key={index}/>}/>)
break break
} }
} }
return elements return elements

@ -5,9 +5,9 @@ import { fileDecoration } from '../../types'
const FileDecorationCustomIcon = (props: { const FileDecorationCustomIcon = (props: {
fileDecoration: fileDecoration fileDecoration: fileDecoration
}) => { }) => {
return <><span data-id={`file-decoration-custom-${props.fileDecoration.path}`} className={`${props.fileDecoration.fileStateIconClass} pr-2`}> return <><span data-id={`file-decoration-custom-${props.fileDecoration.path}`} className={`${props.fileDecoration.fileStateIconClass} pr-2`}>
<>{props.fileDecoration.fileStateIcon}</> <>{props.fileDecoration.fileStateIcon}</>
</span></> </span></>
} }
export default FileDecorationCustomIcon export default FileDecorationCustomIcon

@ -6,9 +6,9 @@ import { fileDecoration } from '../../types'
const FileDecorationErrorIcon = (props: { const FileDecorationErrorIcon = (props: {
fileDecoration: fileDecoration fileDecoration: fileDecoration
}) => { }) => {
return <> return <>
<span data-id={`file-decoration-error-${props.fileDecoration.path}`} className={`${props.fileDecoration.fileStateIconClass} text-danger pr-2`}>{props.fileDecoration.text}</span> <span data-id={`file-decoration-error-${props.fileDecoration.path}`} className={`${props.fileDecoration.fileStateIconClass} text-danger pr-2`}>{props.fileDecoration.text}</span>
</> </>
} }
export default FileDecorationErrorIcon export default FileDecorationErrorIcon

@ -25,7 +25,7 @@ const FileDecorationTooltip = (props: {
<Popover.Content id={`error-tooltip-${props.fileDecoration.path}`} style={{minWidth: "fit-content"}} className={"text-wrap bg-secondary w-100 p-1 m-0"}> <Popover.Content id={`error-tooltip-${props.fileDecoration.path}`} style={{minWidth: "fit-content"}} className={"text-wrap bg-secondary w-100 p-1 m-0"}>
<pre>{getComments(props.fileDecoration)}</pre> <pre>{getComments(props.fileDecoration)}</pre>
</Popover.Content> </Popover.Content>
</Popover> </Popover>
} }
> >
<div>{props.icon}</div> <div>{props.icon}</div>

@ -5,7 +5,7 @@ import { fileDecoration } from '../../types'
const FileDecorationWarningIcon = (props: { const FileDecorationWarningIcon = (props: {
fileDecoration: fileDecoration fileDecoration: fileDecoration
}) => { }) => {
return <><span data-id={`file-decoration-warning-${props.fileDecoration.path}`} className={`${props.fileDecoration.fileStateIconClass} text-warning pr-2`}>{props.fileDecoration.text}</span></> return <><span data-id={`file-decoration-warning-${props.fileDecoration.path}`} className={`${props.fileDecoration.fileStateIconClass} text-warning pr-2`}>{props.fileDecoration.text}</span></>
} }
export default FileDecorationWarningIcon export default FileDecorationWarningIcon

@ -2,10 +2,10 @@ import React from "react"
import { fileDecoration } from "../types" import { fileDecoration } from "../types"
export const getComments = function (fileDecoration: fileDecoration) { export const getComments = function (fileDecoration: fileDecoration) {
if(fileDecoration.comment){ if(fileDecoration.comment){
const comments = Array.isArray(fileDecoration.comment) ? fileDecoration.comment : [fileDecoration.comment] const comments = Array.isArray(fileDecoration.comment) ? fileDecoration.comment : [fileDecoration.comment]
return comments.map((comment, index) => { return comments.map((comment, index) => {
return <div key={index}>{comment}<br></br></div> return <div key={index}>{comment}<br></br></div>
}) })
} }
} }

@ -5,7 +5,7 @@ export enum fileDecorationType {
None = 'NONE' None = 'NONE'
} }
export type fileDecoration = { export type fileDecoration = {
path: string, path: string,
isDirectory: boolean, isDirectory: boolean,
fileStateType: fileDecorationType, fileStateType: fileDecorationType,
@ -20,7 +20,7 @@ export enum fileDecorationType {
comment?: string[] | string comment?: string[] | string
} }
export interface FileType { export interface FileType {
path: string, path: string,
name?: string, name?: string,
isDirectory?: boolean, isDirectory?: boolean,

@ -7,18 +7,18 @@ interface IPluginViewWrapperProps {
export const PluginViewWrapper = (props: IPluginViewWrapperProps) => { export const PluginViewWrapper = (props: IPluginViewWrapperProps) => {
const [state, setState] = useState<any>(null) const [state, setState] = useState<any>(null)
useEffect(() => { useEffect(() => {
if(props.plugin.setDispatch){ if(props.plugin.setDispatch){
props.plugin.setDispatch(setState) props.plugin.setDispatch(setState)
} }
}, []) }, [])
return ( return (
<>{state? <>{state?
<>{props.plugin.updateComponent(state)}</> <>{props.plugin.updateComponent(state)}</>
:<></> :<></>
}</> }</>
) )
} }

@ -102,7 +102,7 @@ export const ProxyDropdownMenu = React.forwardRef(
> >
<ul className="list-unstyled mb-0"> <ul className="list-unstyled mb-0">
{ {
children children
} }
</ul> </ul>
</div> </div>

@ -99,7 +99,7 @@ export const cancelUpgradeMsg = () => (
export const deployWithProxyMsg = () => ( export const deployWithProxyMsg = () => (
<div> <div>
<b>Deploy with Proxy</b> will initiate two (2) transactions: <b>Deploy with Proxy</b> will initiate two (2) transactions:
<ol className="pl-3"> <ol className="pl-3">
<li key="impl-contract" >Deploying the implementation contract</li> <li key="impl-contract" >Deploying the implementation contract</li>
<li key="proxy-contract" >Deploying an ERC1967 proxy contract</li> <li key="proxy-contract" >Deploying an ERC1967 proxy contract</li>
@ -128,7 +128,7 @@ export const upgradeReportMsg = (report: LayoutCompatibilityReport) => (
<div className="py-2 ml-2 mb-1 align-self-end mb-2 d-flex"> <div className="py-2 ml-2 mb-1 align-self-end mb-2 d-flex">
<span className="align-self-center pl-4 mt-1"> <span className="align-self-center pl-4 mt-1">
<i className="pr-2 text-warning far fa-exclamation-triangle" aria-hidden="true" style={{ fontSize: 'xxx-large', fontWeight: 'lighter' }}></i> <i className="pr-2 text-warning far fa-exclamation-triangle" aria-hidden="true" style={{ fontSize: 'xxx-large', fontWeight: 'lighter' }}></i>
</span> </span>
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<span className="pl-4 mt-1">The storage layout of new implementation is NOT</span> <span className="pl-4 mt-1">The storage layout of new implementation is NOT</span>
<span className="pl-4 mt-1">compatible with the previous implementation.</span> <span className="pl-4 mt-1">compatible with the previous implementation.</span>

@ -79,8 +79,8 @@ export const getPathIcon = (path: string) => {
? 'small fak fa-vyper2' : path.endsWith('.lex') ? 'small fak fa-vyper2' : path.endsWith('.lex')
? 'fak fa-lexon' : path.endsWith('ts') ? 'fak fa-lexon' : path.endsWith('ts')
? 'small fak fa-ts-logo' : path.endsWith('.tsc') ? 'small fak fa-ts-logo' : path.endsWith('.tsc')
? 'fad fa-brackets-curly' : path.endsWith('.cairo') ? 'fad fa-brackets-curly' : path.endsWith('.cairo')
? 'small fak fa-cairo' : 'far fa-file' ? 'small fak fa-cairo' : 'far fa-file'
} }
export const isNumeric = (value) => { export const isNumeric = (value) => {

@ -137,19 +137,19 @@ function HomeTabFile ({plugin}: HomeTabFileProps) {
<div className="d-flex flex-row"> <div className="d-flex flex-row">
{ state.modalInfo.prefix && <span className='text-nowrap align-self-center mr-2'>ipfs://</span> } { state.modalInfo.prefix && <span className='text-nowrap align-self-center mr-2'>ipfs://</span> }
<input <input
ref={inputValue} ref={inputValue}
type='text' type='text'
name='prompt_text' name='prompt_text'
id='inputPrompt_text' id='inputPrompt_text'
className="w-100 mt-1 form-control" className="w-100 mt-1 form-control"
data-id="homeTabModalDialogCustomPromptText" data-id="homeTabModalDialogCustomPromptText"
value={state.importSource} value={state.importSource}
onInput={(e) => { onInput={(e) => {
setState(prevState => { setState(prevState => {
return { ...prevState, importSource: inputValue.current.value } return { ...prevState, importSource: inputValue.current.value }
}) })
}} }}
/> />
</div> </div>
</div> </div>
</ModalDialog> </ModalDialog>

@ -118,26 +118,26 @@ function HomeTabGetStarted ({plugin}: HomeTabGetStartedProps) {
workspaceTitle="0xProject ERC20" workspaceTitle="0xProject ERC20"
description={intl.formatMessage({ id: 'home.zeroxErc20TemplateDesc' })} description={intl.formatMessage({ id: 'home.zeroxErc20TemplateDesc' })}
callback={() => createWorkspace("zeroxErc20")} /> callback={() => createWorkspace("zeroxErc20")} />
<WorkspaceTemplate <WorkspaceTemplate
gsID="sourcifyLogo" gsID="sourcifyLogo"
workspaceTitle="OpenZeppelin ERC20" workspaceTitle="OpenZeppelin ERC20"
description={intl.formatMessage({ id: 'home.ozerc20TemplateDesc' })} description={intl.formatMessage({ id: 'home.ozerc20TemplateDesc' })}
callback={() => createWorkspace("ozerc20")} /> callback={() => createWorkspace("ozerc20")} />
<WorkspaceTemplate <WorkspaceTemplate
gsID="sUTLogo" gsID="sUTLogo"
workspaceTitle="OpenZeppelin ERC721" workspaceTitle="OpenZeppelin ERC721"
description={intl.formatMessage({ id: 'home.ozerc721TemplateDesc' })} description={intl.formatMessage({ id: 'home.ozerc721TemplateDesc' })}
callback={() => createWorkspace("ozerc721")} /> callback={() => createWorkspace("ozerc721")} />
<WorkspaceTemplate <WorkspaceTemplate
gsID="sUTLogo" gsID="sUTLogo"
workspaceTitle="OpenZeppelin ERC1155" workspaceTitle="OpenZeppelin ERC1155"
description={intl.formatMessage({ id: 'home.ozerc1155TemplateDesc' })} description={intl.formatMessage({ id: 'home.ozerc1155TemplateDesc' })}
callback={() => createWorkspace("ozerc1155")} /> callback={() => createWorkspace("ozerc1155")} />
<WorkspaceTemplate <WorkspaceTemplate
gsID="solhintLogo" gsID="solhintLogo"
workspaceTitle="Remix Basic" workspaceTitle="Remix Basic"
description={intl.formatMessage({ id: 'home.remixDefaultTemplateDesc' })} description={intl.formatMessage({ id: 'home.remixDefaultTemplateDesc' })}
callback={() => createWorkspace("remixDefault")} /> callback={() => createWorkspace("remixDefault")} />
</Carousel> </Carousel>
</ThemeContext.Provider> </ThemeContext.Provider>
</div> </div>

@ -53,11 +53,11 @@ function HomeTabLearn ({plugin}: HomeTabLearnProps) {
<FormattedMessage id="home.learn" /> <FormattedMessage id="home.learn" />
</label> </label>
<CustomTooltip <CustomTooltip
placement={'top'} placement={'top'}
tooltipId="overlay-tooltip" tooltipId="overlay-tooltip"
tooltipClasses="text-nowrap" tooltipClasses="text-nowrap"
tooltipText={"See all tutorials"} tooltipText={"See all tutorials"}
tooltipTextClasses="border bg-light text-dark p-1 pr-3" tooltipTextClasses="border bg-light text-dark p-1 pr-3"
> >
<button <button
onClick={ async () => { onClick={ async () => {

@ -11,7 +11,7 @@ export function RemixUiLocaleModule({ localeModule }: RemixUiLocaleModuleProps)
const [localeCode, setLocaleCode] = useState('') const [localeCode, setLocaleCode] = useState('')
useEffect(() => { useEffect(() => {
localeModule.switchLocale() localeModule.switchLocale()
}, [localeCode, localeModule]) }, [localeCode, localeModule])
return ( return (
@ -23,31 +23,31 @@ export function RemixUiLocaleModule({ localeModule }: RemixUiLocaleModuleProps)
<div className="card-text locales-container"> <div className="card-text locales-container">
{localeModule.getLocales() {localeModule.getLocales()
? localeModule.getLocales().map((locale, idx) => ( ? localeModule.getLocales().map((locale, idx) => (
<div <div
className="radio custom-control custom-radio mb-1 form-check" className="radio custom-control custom-radio mb-1 form-check"
key={idx} key={idx}
>
<input
type="radio"
onChange={event => {
localeModule.switchLocale(locale.code);
setLocaleCode(locale.code);
}}
className="align-middle custom-control-input"
name="locale"
id={locale.code}
data-id={`settingsTabLocale${locale.code}`}
checked={localeModule.active === locale.code.toLocaleLowerCase()}
/>
<label
className="form-check-label custom-control-label"
data-id={`settingsTabLocaleLabel${locale.code}`}
htmlFor={locale.code}
> >
<input {locale.name.toLocaleUpperCase()}-{locale.localeName}
type="radio" </label>
onChange={event => { </div>
localeModule.switchLocale(locale.code); ))
setLocaleCode(locale.code);
}}
className="align-middle custom-control-input"
name="locale"
id={locale.code}
data-id={`settingsTabLocale${locale.code}`}
checked={localeModule.active === locale.code.toLocaleLowerCase()}
/>
<label
className="form-check-label custom-control-label"
data-id={`settingsTabLocaleLabel${locale.code}`}
htmlFor={locale.code}
>
{locale.name.toLocaleUpperCase()}-{locale.localeName}
</label>
</div>
))
: null} : null}
</div> </div>
</div> </div>

@ -43,7 +43,7 @@ const RemixUIPanelHeader = (props: RemixPanelProps) => {
tooltipId="maintainedByTooltip" tooltipId="maintainedByTooltip"
tooltipClasses="text-nowrap" tooltipClasses="text-nowrap"
tooltipText="Maintained by Remix" tooltipText="Maintained by Remix"
> >
<i aria-hidden="true" className="text-success mt-1 px-1 fas fa-check"></i> <i aria-hidden="true" className="text-success mt-1 px-1 fas fa-check"></i>
</CustomTooltip> </CustomTooltip>
)} )}

@ -55,9 +55,9 @@ const PermissionHandlerDialog = (props: PermissionHandlerProps) => {
</article> </article>
<article className='remember'> <article className='remember'>
{ <div className='form-check'> { <div className='form-check'>
<input type="checkbox" onChange={switchMode} className='form-check-input' id='rememberSwitchCheck' data-id={remember ? 'permissionHandlerRememberChecked' : 'permissionHandlerRememberUnchecked'}/> <input type="checkbox" onChange={switchMode} className='form-check-input' id='rememberSwitchCheck' data-id={remember ? 'permissionHandlerRememberChecked' : 'permissionHandlerRememberUnchecked'}/>
<label htmlFor='rememberSwitchCheck' className="form-check-label" data-id="permissionHandlerRememberChoice"><FormattedMessage id='permissionHandler.rememberThisChoice' /></label> <label htmlFor='rememberSwitchCheck' className="form-check-label" data-id="permissionHandlerRememberChoice"><FormattedMessage id='permissionHandler.rememberThisChoice' /></label>
</div> </div>
} }
<button className="btn-secondary btn-sm" onClick={reset}><FormattedMessage id='permissionHandler.resetAllPermissions' /></button> <button className="btn-secondary btn-sm" onClick={reset}><FormattedMessage id='permissionHandler.resetAllPermissions' /></button>
</article> </article>

@ -6,9 +6,9 @@ export type localPluginReducerActionType = {
export function localPluginToastReducer (currentState: string, toastAction: localPluginReducerActionType) { export function localPluginToastReducer (currentState: string, toastAction: localPluginReducerActionType) {
switch (toastAction.type) { switch (toastAction.type) {
case 'show': case 'show':
return `Cannot create Plugin : ${toastAction.payload!}` return `Cannot create Plugin : ${toastAction.payload!}`
default: default:
return currentState return currentState
} }
} }

@ -107,30 +107,30 @@ declare class LocalPlugin {
profile: any profile: any
}> }>
profile: any profile: any
/** /**
* Create the object to add to the plugin-list * Create the object to add to the plugin-list
*/ */
create(): any create(): any
updateName({ target }: { updateName({ target }: {
target: any target: any
}): void }): void
updateUrl({ target }: { updateUrl({ target }: {
target: any target: any
}): void }): void
updateDisplayName({ target }: { updateDisplayName({ target }: {
target: any target: any
}): void }): void
updateProfile(key: any, e: any): void updateProfile(key: any, e: any): void
updateMethods({ target }: { updateMethods({ target }: {
target: any target: any
}): void }): void
/** The form to create a local plugin */ /** The form to create a local plugin */
form(): any form(): any
} }
export interface PluginManagerContextProviderProps { export interface PluginManagerContextProviderProps {
@ -148,11 +148,11 @@ export interface RemixUiPluginManagerProps {
**/ **/
declare class PluginLoader { declare class PluginLoader {
get currentLoader(): any get currentLoader(): any
donotAutoReload: string[] donotAutoReload: string[]
loaders: Record<any, any> loaders: Record<any, any>
current: string current: string
set(plugin: any, actives: any): void set(plugin: any, actives: any): void
get(): any get(): any
} }
// eslint-disable-next-line no-redeclare // eslint-disable-next-line no-redeclare
export type PluginManagerSettings = { export type PluginManagerSettings = {

@ -240,25 +240,25 @@ const deployContract = (plugin: RunTab, selectedContract, args, contractMetadata
export const loadAddress = (plugin: RunTab, dispatch: React.Dispatch<any>, contract: ContractData, address: string) => { export const loadAddress = (plugin: RunTab, dispatch: React.Dispatch<any>, contract: ContractData, address: string) => {
loadContractFromAddress(plugin, address, loadContractFromAddress(plugin, address,
(cb) => { (cb) => {
dispatch(displayNotification('At Address', `Do you really want to interact with ${address} using the current ABI definition?`, 'OK', 'Cancel', cb, null)) dispatch(displayNotification('At Address', `Do you really want to interact with ${address} using the current ABI definition?`, 'OK', 'Cancel', cb, null))
}, },
(error, loadType, abi) => { (error, loadType, abi) => {
if (error) { if (error) {
return dispatch(displayNotification('Alert', error, 'OK', null)) return dispatch(displayNotification('Alert', error, 'OK', null))
} }
if (loadType === 'abi') { if (loadType === 'abi') {
return addInstance(dispatch, { abi, address, name: '<at address>' }) return addInstance(dispatch, { abi, address, name: '<at address>' })
} else if (loadType === 'instance') { } else if (loadType === 'instance') {
if (!contract) return dispatch(displayPopUp('No compiled contracts found.')) if (!contract) return dispatch(displayPopUp('No compiled contracts found.'))
const currentFile = plugin.REACT_API.contracts.currentFile const currentFile = plugin.REACT_API.contracts.currentFile
const compiler = plugin.REACT_API.contracts.contractList[currentFile].find(item => item.alias === contract.name) const compiler = plugin.REACT_API.contracts.contractList[currentFile].find(item => item.alias === contract.name)
const contractData = getSelectedContract(contract.name, compiler.compiler) const contractData = getSelectedContract(contract.name, compiler.compiler)
return addInstance(dispatch, { contractData, address, name: contract.name }) return addInstance(dispatch, { contractData, address, name: contract.name })
} }
} }
) )
} }
export const getContext = (plugin: RunTab) => { export const getContext = (plugin: RunTab) => {
return plugin.blockchain.context() return plugin.blockchain.context()
@ -390,23 +390,23 @@ export const isValidContractUpgrade = async (plugin: RunTab, proxyAddress: strin
const networkFile: string = await plugin.call('fileManager', 'readFile', `.deploys/upgradeable-contracts/${identifier}/UUPS.json`) const networkFile: string = await plugin.call('fileManager', 'readFile', `.deploys/upgradeable-contracts/${identifier}/UUPS.json`)
const parsedNetworkFile: NetworkDeploymentFile = JSON.parse(networkFile) const parsedNetworkFile: NetworkDeploymentFile = JSON.parse(networkFile)
if (parsedNetworkFile.deployments[proxyAddress] && parsedNetworkFile.deployments[proxyAddress].implementationAddress) { if (parsedNetworkFile.deployments[proxyAddress] && parsedNetworkFile.deployments[proxyAddress].implementationAddress) {
const solcBuildExists = await plugin.call('fileManager', 'exists', `.deploys/upgradeable-contracts/${identifier}/solc-${parsedNetworkFile.deployments[proxyAddress].implementationAddress}.json`) const solcBuildExists = await plugin.call('fileManager', 'exists', `.deploys/upgradeable-contracts/${identifier}/solc-${parsedNetworkFile.deployments[proxyAddress].implementationAddress}.json`)
if (solcBuildExists) {
const solcFile: string = await plugin.call('fileManager', 'readFile', `.deploys/upgradeable-contracts/${identifier}/solc-${parsedNetworkFile.deployments[proxyAddress].implementationAddress}.json`)
const parsedSolcFile: SolcBuildFile = JSON.parse(solcFile)
const oldImpl = new UpgradeableContract(parsedNetworkFile.deployments[proxyAddress].contractName, parsedSolcFile.solcInput, parsedSolcFile.solcOutput, { kind: 'uups' })
const newImpl = new UpgradeableContract(newContractName, solcInput, solcOutput, { kind: 'uups' })
const report = oldImpl.getStorageUpgradeReport(newImpl, { kind: 'uups' })
if (solcBuildExists) { return report
const solcFile: string = await plugin.call('fileManager', 'readFile', `.deploys/upgradeable-contracts/${identifier}/solc-${parsedNetworkFile.deployments[proxyAddress].implementationAddress}.json`)
const parsedSolcFile: SolcBuildFile = JSON.parse(solcFile)
const oldImpl = new UpgradeableContract(parsedNetworkFile.deployments[proxyAddress].contractName, parsedSolcFile.solcInput, parsedSolcFile.solcOutput, { kind: 'uups' })
const newImpl = new UpgradeableContract(newContractName, solcInput, solcOutput, { kind: 'uups' })
const report = oldImpl.getStorageUpgradeReport(newImpl, { kind: 'uups' })
return report
} else {
return { ok: false, pass: false, warning: true }
}
} else { } else {
return { ok: false, pass: false, warning: true } return { ok: false, pass: false, warning: true }
} }
} else {
return { ok: false, pass: false, warning: true }
}
} else { } else {
return { ok: false, pass: false, warning: true } return { ok: false, pass: false, warning: true }
} }

@ -23,60 +23,60 @@ export function AccountUI (props: AccountProps) {
useEffect(() => { useEffect(() => {
switch (props.selectExEnv) { switch (props.selectExEnv) {
case 'injected': case 'injected':
setPlusOpt({
classList: 'udapp_disableMouseEvents',
title: "Unfortunately it's not possible to create an account using injected provider. Please create the account directly from your provider (i.e metamask or other of the same type)."
})
break
case 'vm-merge':
setPlusOpt({
classList: '',
title: 'Create a new account'
})
break
case 'vm-london':
setPlusOpt({
classList: '',
title: 'Create a new account'
})
break
case 'vm-berlin':
setPlusOpt({
classList: '',
title: 'Create a new account'
})
break
case 'vm-shanghai':
setPlusOpt({
classList: '',
title: 'Create a new account'
})
break
case 'web3':
if (!props.personalMode) {
setPlusOpt({ setPlusOpt({
classList: 'udapp_disableMouseEvents', classList: 'disableMouseEvents',
title: "Unfortunately it's not possible to create an account using injected provider. Please create the account directly from your provider (i.e metamask or other of the same type)." title: 'Creating an account is possible only in Personal mode. Please go to Settings to enable it.'
})
break
case 'vm-merge':
setPlusOpt({
classList: '',
title: 'Create a new account'
})
break
case 'vm-london':
setPlusOpt({
classList: '',
title: 'Create a new account'
})
break
case 'vm-berlin':
setPlusOpt({
classList: '',
title: 'Create a new account'
}) })
break } else {
case 'vm-shanghai':
setPlusOpt({ setPlusOpt({
classList: '', classList: '',
title: 'Create a new account' title: 'Create a new account'
}) })
break }
break
case 'web3':
if (!props.personalMode) { default:
setPlusOpt({ setPlusOpt({
classList: 'disableMouseEvents', classList: 'disableMouseEvents',
title: 'Creating an account is possible only in Personal mode. Please go to Settings to enable it.' title: `Unfortunately it's not possible to create an account using an external wallet (${props.selectExEnv}).`
}) })
} else {
setPlusOpt({
classList: '',
title: 'Create a new account'
})
}
break
default:
setPlusOpt({
classList: 'disableMouseEvents',
title: `Unfortunately it's not possible to create an account using an external wallet (${props.selectExEnv}).`
})
} }
// this._deps.config.get('settings/personal-mode') // this._deps.config.get('settings/personal-mode')
}, [props.selectExEnv, props.personalMode]) }, [props.selectExEnv, props.personalMode])
@ -179,9 +179,9 @@ export function AccountUI (props: AccountProps) {
</label> </label>
<div className="udapp_account"> <div className="udapp_account">
<select id="txorigin" data-id="runTabSelectAccount" name="txorigin" className="form-control udapp_select custom-select pr-4" value={selectedAccount||""} onChange={(e) => { props.setAccount(e.target.value) }}> <select id="txorigin" data-id="runTabSelectAccount" name="txorigin" className="form-control udapp_select custom-select pr-4" value={selectedAccount||""} onChange={(e) => { props.setAccount(e.target.value) }}>
{ {
accounts.map((value, index) => <option value={value} key={index}>{ loadedAccounts[value] }</option>) accounts.map((value, index) => <option value={value} key={index}>{ loadedAccounts[value] }</option>)
} }
</select> </select>
<div style={{ marginLeft: -5 }}><CopyToClipboard tip='Copy account to clipboard' content={selectedAccount} direction='top' /></div> <div style={{ marginLeft: -5 }}><CopyToClipboard tip='Copy account to clipboard' content={selectedAccount} direction='top' /></div>
<CustomTooltip <CustomTooltip

@ -310,7 +310,7 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
<i style={{ cursor: 'pointer' }} className="fa fa-refresh mr-2 mt-2" aria-hidden="true"></i> <i style={{ cursor: 'pointer' }} className="fa fa-refresh mr-2 mt-2" aria-hidden="true"></i>
</button> </button>
</CustomTooltip>) </CustomTooltip>)
: null } : null }
</div> </div>
<div className="udapp_subcontainer"> <div className="udapp_subcontainer">
<CustomTooltip <CustomTooltip
@ -338,16 +338,16 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
<span className="py-1" style={{ display: abiLabel.display }}>{abiLabel.content}</span> <span className="py-1" style={{ display: abiLabel.display }}>{abiLabel.content}</span>
</div> </div>
{ evmVersion && loadedContractData && <CustomTooltip { evmVersion && loadedContractData && <CustomTooltip
placement={'right'} placement={'right'}
tooltipClasses="text-wrap text-left" tooltipClasses="text-wrap text-left"
tooltipId="info-evm-version-warn" tooltipId="info-evm-version-warn"
tooltipText={<span className="text-left"> tooltipText={<span className="text-left">
<FormattedMessage id='udapp.warningEvmVersion' values={{ evmVersion }}/> <FormattedMessage id='udapp.warningEvmVersion' values={{ evmVersion }}/>
</span> </span>
} }
> >
<span className='udapp_evmVersion badge alert-warning'>evm version: {evmVersion}</span> <span className='udapp_evmVersion badge alert-warning'>evm version: {evmVersion}</span>
</CustomTooltip> </CustomTooltip>
} }
<div> <div>
<div className="udapp_deployDropdown"> <div className="udapp_deployDropdown">

@ -89,9 +89,9 @@ export function ContractGUI (props: ContractGUIProps) {
const multiJSON = JSON.parse('[' + multiString + ']') const multiJSON = JSON.parse('[' + multiString + ']')
const encodeObj = txFormat.encodeData( const encodeObj = txFormat.encodeData(
props.funcABI, props.funcABI,
multiJSON, multiJSON,
props.funcABI.type === 'constructor' ? props.evmBC : null) props.funcABI.type === 'constructor' ? props.evmBC : null)
if (encodeObj.error) { if (encodeObj.error) {
console.error(encodeObj.error) console.error(encodeObj.error)
@ -272,27 +272,27 @@ export function ContractGUI (props: ContractGUIProps) {
className="udapp_contractActionsContainerSingle pt-2" className="udapp_contractActionsContainerSingle pt-2"
style={{ display: toggleContainer ? "none" : "flex" }} style={{ display: toggleContainer ? "none" : "flex" }}
> >
<div <div
className='d-flex' className='d-flex'
onClick={handleActionClick} onClick={handleActionClick}
>
<button
className={`udapp_instanceButton text-nowrap overflow-hidden text-truncate ${props.widthClass} btn btn-sm ${buttonOptions.classList}`}
data-id={buttonOptions.dataId}
data-title={buttonOptions.title}
disabled={(toggleUpgradeImp && !proxyAddress) || props.disabled || (props.inputs !=='' && basicInput === '')}
> >
<button <CustomTooltip
className={`udapp_instanceButton text-nowrap overflow-hidden text-truncate ${props.widthClass} btn btn-sm ${buttonOptions.classList}`} delay={0}
data-id={buttonOptions.dataId} placement={"right"}
data-title={buttonOptions.title} tooltipClasses="text-wrap"
disabled={(toggleUpgradeImp && !proxyAddress) || props.disabled || (props.inputs !=='' && basicInput === '')} tooltipId="remixUdappInstanceButtonTooltip"
tooltipText={toggleUpgradeImp && !proxyAddress ? 'Proxy address cannot be empty' : (props.inputs !=='' && basicInput === '') ? 'Input required' : buttonOptions.title}
> >
<CustomTooltip
delay={0}
placement={"right"}
tooltipClasses="text-wrap"
tooltipId="remixUdappInstanceButtonTooltip"
tooltipText={toggleUpgradeImp && !proxyAddress ? 'Proxy address cannot be empty' : (props.inputs !=='' && basicInput === '') ? 'Input required' : buttonOptions.title}
>
<div>{title}</div> <div>{title}</div>
</CustomTooltip> </CustomTooltip>
</button> </button>
</div> </div>
<input <input
className="form-control" className="form-control"
data-id={ data-id={
@ -434,57 +434,57 @@ export function ContractGUI (props: ContractGUIProps) {
onChange={(e) => handleDeployProxySelect(e.target.checked)} onChange={(e) => handleDeployProxySelect(e.target.checked)}
checked={deployState.deploy} checked={deployState.deploy}
/> />
<label <label
htmlFor="deployWithProxy" htmlFor="deployWithProxy"
data-id="contractGUIDeployWithProxyLabel" data-id="contractGUIDeployWithProxyLabel"
className="m-0 form-check-label w-100 custom-control-label udapp_checkboxAlign" className="m-0 form-check-label w-100 custom-control-label udapp_checkboxAlign"
> >
<FormattedMessage id='udapp.deployWithProxy' /> <FormattedMessage id='udapp.deployWithProxy' />
</label> </label>
</div> </div>
<div> <div>
{props.initializerOptions && {props.initializerOptions &&
props.initializerOptions.initializeInputs ? ( props.initializerOptions.initializeInputs ? (
<span onClick={handleToggleDeployProxy}> <span onClick={handleToggleDeployProxy}>
<i className={!toggleDeployProxy ? "fas fa-angle-right pt-2" : "fas fa-angle-down"} <i className={!toggleDeployProxy ? "fas fa-angle-right pt-2" : "fas fa-angle-down"}
aria-hidden="true" aria-hidden="true"
></i> ></i>
</span> </span>
) : null} ) : null}
</div> </div>
</div> </div>
{props.initializerOptions && {props.initializerOptions &&
props.initializerOptions.initializeInputs ? ( props.initializerOptions.initializeInputs ? (
<div <div
className={`pl-4 flex-column ${ className={`pl-4 flex-column ${
toggleDeployProxy ? "d-flex" : "d-none" toggleDeployProxy ? "d-flex" : "d-none"
}`} }`}
> >
<div className={`flex-column 'd-flex'}`}> <div className={`flex-column 'd-flex'}`}>
{props.initializerOptions.inputs.inputs.map((inp, index) => { {props.initializerOptions.inputs.inputs.map((inp, index) => {
return ( return (
<div className="mb-2" key={index}> <div className="mb-2" key={index}>
<label <label
className="mt-2 text-left d-block" className="mt-2 text-left d-block"
htmlFor={inp.name} htmlFor={inp.name}
> >
{" "} {" "}
{inp.name}:{" "} {inp.name}:{" "}
</label> </label>
<input <input
ref={(el) => { ref={(el) => {
initializeFields.current[index] = el; initializeFields.current[index] = el;
}} }}
style={{ height: 32 }} style={{ height: 32 }}
className="form-control udapp_input" className="form-control udapp_input"
placeholder={inp.type} placeholder={inp.type}
/> />
</div> </div>
); );
})} })}
</div>
</div> </div>
</div> ) : null}
) : null}
<div className="d-flex justify-content-between"> <div className="d-flex justify-content-between">
<div className="d-flex py-1 align-items-center custom-control custom-checkbox"> <div className="d-flex py-1 align-items-center custom-control custom-checkbox">
<input <input
@ -495,13 +495,13 @@ export function ContractGUI (props: ContractGUIProps) {
onChange={(e) => handleUpgradeImpSelect(e.target.checked)} onChange={(e) => handleUpgradeImpSelect(e.target.checked)}
checked={deployState.upgrade} checked={deployState.upgrade}
/> />
<label <label
htmlFor="upgradeImplementation" htmlFor="upgradeImplementation"
data-id="contractGUIUpgradeImplementationLabel" data-id="contractGUIUpgradeImplementationLabel"
className="m-0 form-check-label custom-control-label udapp_checkboxAlign" className="m-0 form-check-label custom-control-label udapp_checkboxAlign"
> >
<FormattedMessage id='udapp.upgradeWithProxy' /> <FormattedMessage id='udapp.upgradeWithProxy' />
</label> </label>
</div> </div>
<span onClick={handleToggleUpgradeImp}> <span onClick={handleToggleUpgradeImp}>
<i <i
@ -541,8 +541,8 @@ export function ContractGUI (props: ContractGUIProps) {
> >
<span> <span>
{ proxyAddress === deployment.address ? { proxyAddress === deployment.address ?
<span>&#10003; { deployment.contractName + ' ' + shortenProxyAddress(deployment.address) } </span> <span>&#10003; { deployment.contractName + ' ' + shortenProxyAddress(deployment.address) } </span>
: <span className="pl-3">{ deployment.contractName + ' ' + shortenProxyAddress(deployment.address) }</span> } : <span className="pl-3">{ deployment.contractName + ' ' + shortenProxyAddress(deployment.address) }</span> }
</span> </span>
</Dropdown.Item> </Dropdown.Item>
</CustomTooltip> </CustomTooltip>

@ -13,37 +13,37 @@ export function DeployButton (props: DeployButtonProps) {
return ( return (
<> <>
{ props.deployOptions && (props.deployOptions || []).length > 0 ? { props.deployOptions && (props.deployOptions || []).length > 0 ?
<Dropdown as={ButtonGroup}> <Dropdown as={ButtonGroup}>
<button <button
onClick={props.handleActionClick} onClick={props.handleActionClick}
title={props.buttonOptions.title} title={props.buttonOptions.title}
className={`udapp_instanceButton ${props.buttonOptions.widthClass} btn btn-sm ${props.buttonOptions.classList}`} className={`udapp_instanceButton ${props.buttonOptions.widthClass} btn btn-sm ${props.buttonOptions.classList}`}
data-id={props.buttonOptions.dataId} data-id={props.buttonOptions.dataId}
>
{ props.deployOptions[props.selectedIndex] ? props.deployOptions[props.selectedIndex].title : 'Deploy' }
</button>
<Dropdown.Toggle split id="dropdown-split-basic" className={`btn btn-sm dropdown-toggle dropdown-toggle-split ${props.buttonOptions.classList}`} style={{ maxWidth: 25, minWidth: 0, height: 32 }} />
<Dropdown.Menu className="deploy-items border-0">
{
(props.deployOptions).map(({ title, active }, index) => <Dropdown.Item onClick={() => {
props.setSelectedIndex(index)
toggleOptions()
}} key={index}> { props.selectedIndex === index ? <span>&#10003; {title} </span> : <span className="pl-3">{title}</span> }</Dropdown.Item>)
}
</Dropdown.Menu>
</Dropdown> :
<CustomTooltip
placement="top"
tooltipId="deployButtonTooltip"
tooltipClasses="text-nowrap"
tooltipText={props.buttonOptions.title}
> >
{ props.deployOptions[props.selectedIndex] ? props.deployOptions[props.selectedIndex].title : 'Deploy' } <button onClick={props.handleActionClick} className={`udapp_instanceButton ${props.buttonOptions.widthClass} btn btn-sm ${props.buttonOptions.classList}`} data-id={props.buttonOptions.dataId}>
</button> <FormattedMessage id='udapp.deploy' />
<Dropdown.Toggle split id="dropdown-split-basic" className={`btn btn-sm dropdown-toggle dropdown-toggle-split ${props.buttonOptions.classList}`} style={{ maxWidth: 25, minWidth: 0, height: 32 }} /> </button>
<Dropdown.Menu className="deploy-items border-0"> </CustomTooltip>
{ }
(props.deployOptions).map(({ title, active }, index) => <Dropdown.Item onClick={() => {
props.setSelectedIndex(index)
toggleOptions()
}} key={index}> { props.selectedIndex === index ? <span>&#10003; {title} </span> : <span className="pl-3">{title}</span> }</Dropdown.Item>)
}
</Dropdown.Menu>
</Dropdown> :
<CustomTooltip
placement="top"
tooltipId="deployButtonTooltip"
tooltipClasses="text-nowrap"
tooltipText={props.buttonOptions.title}
>
<button onClick={props.handleActionClick} className={`udapp_instanceButton ${props.buttonOptions.widthClass} btn btn-sm ${props.buttonOptions.classList}`} data-id={props.buttonOptions.dataId}>
<FormattedMessage id='udapp.deploy' />
</button>
</CustomTooltip>
}
</> </>
) )
} }

@ -26,8 +26,8 @@ export function EnvironmentUI (props: EnvironmentProps) {
<FormattedMessage id='udapp.environment' /> <FormattedMessage id='udapp.environment' />
<CustomTooltip placement={'right'} tooltipClasses="text-nowrap" tooltipId="info-recorder" <CustomTooltip placement={'right'} tooltipClasses="text-nowrap" tooltipId="info-recorder"
tooltipText="Open chainlist.org and get the connection specs of the chain you want to interact with."> tooltipText="Open chainlist.org and get the connection specs of the chain you want to interact with.">
<a href='https://chainlist.org/' target='_blank'><i style={{ fontSize: 'medium' }} className={'ml-2 fad fa-plug'} aria-hidden="true"></i></a> <a href='https://chainlist.org/' target='_blank'><i style={{ fontSize: 'medium' }} className={'ml-2 fad fa-plug'} aria-hidden="true"></i></a>
</CustomTooltip> </CustomTooltip>
</label> </label>
@ -63,7 +63,7 @@ export function EnvironmentUI (props: EnvironmentProps) {
</Dropdown> </Dropdown>
<CustomTooltip placement={'right-start'} tooltipClasses="text-wrap" tooltipId="runAndDeployAddresstooltip" <CustomTooltip placement={'right-start'} tooltipClasses="text-wrap" tooltipId="runAndDeployAddresstooltip"
tooltipText={<FormattedMessage id='udapp.environmentDocs' />}> tooltipText={<FormattedMessage id='udapp.environmentDocs' />}>
<a href="https://remix-ide.readthedocs.io/en/latest/run.html#environment" target="_blank" rel="noreferrer"><i className="udapp_infoDeployAction ml-2 fas fa-info"></i></a> <a href="https://remix-ide.readthedocs.io/en/latest/run.html#environment" target="_blank" rel="noreferrer"><i className="udapp_infoDeployAction ml-2 fas fa-info"></i></a>
</CustomTooltip> </CustomTooltip>

@ -28,7 +28,7 @@ export function InstanceContainerUI (props: InstanceContainerProps) {
</label> </label>
</CustomTooltip> </CustomTooltip>
{ instanceList.length > 0 { instanceList.length > 0
? ( ? (
<CustomTooltip <CustomTooltip
placement="right" placement="right"
tooltipClasses="text-nowrap" tooltipClasses="text-nowrap"
@ -38,8 +38,8 @@ export function InstanceContainerUI (props: InstanceContainerProps) {
<i className="mr-2 udapp_icon far fa-trash-alt" data-id="deployAndRunClearInstances" onClick={clearInstance} aria-hidden="true"> <i className="mr-2 udapp_icon far fa-trash-alt" data-id="deployAndRunClearInstances" onClick={clearInstance} aria-hidden="true">
</i> </i>
</CustomTooltip> </CustomTooltip>
) : null ) : null
} }
</div> </div>
{ instanceList.length > 0 { instanceList.length > 0
? <div> { props.instances.instanceList.map((instance, index) => { ? <div> { props.instances.instanceList.map((instance, index) => {

@ -42,7 +42,7 @@ export function RecorderUI (props: RecorderProps) {
tooltipId="recordedTransactionsCounttooltip" tooltipId="recordedTransactionsCounttooltip"
tooltipText={<FormattedMessage id='udapp.transactionsCountTooltip' />} tooltipText={<FormattedMessage id='udapp.transactionsCountTooltip' />}
> >
<div className="ml-2 badge badge-pill badge-primary text-center" data-title="The number of recorded transactions">{props.count}</div> <div className="ml-2 badge badge-pill badge-primary text-center" data-title="The number of recorded transactions">{props.count}</div>
</CustomTooltip> </CustomTooltip>
<CustomTooltip <CustomTooltip
placement={'right'} placement={'right'}
@ -50,8 +50,8 @@ export function RecorderUI (props: RecorderProps) {
tooltipId="info-recorder" tooltipId="info-recorder"
tooltipText={<span><FormattedMessage id='udapp.infoRecorderTooltip' values={{ br: <br /> }} /></span>} tooltipText={<span><FormattedMessage id='udapp.infoRecorderTooltip' values={{ br: <br /> }} /></span>}
> >
<i style={{ fontSize: 'medium' }} className={'ml-2 fal fa-info-circle align-self-center'} aria-hidden="true"></i> <i style={{ fontSize: 'medium' }} className={'ml-2 fal fa-info-circle align-self-center'} aria-hidden="true"></i>
</CustomTooltip> </CustomTooltip>
</div> </div>
<div className="p-3"> <div className="p-3">
<span data-id='udappRecorderTitleExpander' onClick={toggleClass}> <span data-id='udappRecorderTitleExpander' onClick={toggleClass}>
@ -79,10 +79,10 @@ export function RecorderUI (props: RecorderProps) {
tooltipClasses="text-nowrap" tooltipClasses="text-nowrap"
tooltipId="remixUdappTransactionSavetooltip" tooltipId="remixUdappTransactionSavetooltip"
tooltipText={ tooltipText={
props.count === 0 ? intl.formatMessage({ id: 'udapp.transactionSaveTooltip1' }) props.count === 0 ? intl.formatMessage({ id: 'udapp.transactionSaveTooltip1' })
: props.count === 1 ? intl.formatMessage({ id: 'udapp.transactionSaveTooltip2' }, { count: props.count }) : props.count === 1 ? intl.formatMessage({ id: 'udapp.transactionSaveTooltip2' }, { count: props.count })
: intl.formatMessage({ id: 'udapp.transactionSaveTooltip3' }, { count: props.count }) : intl.formatMessage({ id: 'udapp.transactionSaveTooltip3' }, { count: props.count })
} }
> >
<span> <span>
<button className="btn btn-sm btn-info savetransaction udapp_recorder" disabled={props.count === 0 ? true: false} onClick={triggerRecordButton} style={{ pointerEvents: props.count === 0 ? 'none' : 'auto' }}> <button className="btn btn-sm btn-info savetransaction udapp_recorder" disabled={props.count === 0 ? true: false} onClick={triggerRecordButton} style={{ pointerEvents: props.count === 0 ? 'none' : 'auto' }}>

@ -312,7 +312,7 @@ export function UniversalDappUI (props: UdappProps) {
); );
} }
) )
: null; : null;
} }
)} )}
</TreeView> </TreeView>

@ -56,23 +56,23 @@ export function ValueUI (props: ValueProps) {
tooltipId="remixValueTooltip" tooltipId="remixValueTooltip"
tooltipText="Enter an amount and choose its unit" tooltipText="Enter an amount and choose its unit"
> >
<input <input
ref={inputValue} ref={inputValue}
type="number" type="number"
min="0" min="0"
pattern="^[0-9]" pattern="^[0-9]"
step="1" step="1"
className="form-control udapp_gasNval udapp_col2" className="form-control udapp_gasNval udapp_col2"
id="value" id="value"
data-id="dandrValue" data-id="dandrValue"
onKeyPress={validateInputKey} onKeyPress={validateInputKey}
onChange={validateValue} onChange={validateValue}
value={props.sendValue} value={props.sendValue}
/> />
</CustomTooltip> </CustomTooltip>
<select name="unit" <select name="unit"
value={props.sendUnit} className="form-control p-1 udapp_gasNvalUnit udapp_col2_2 custom-select" id="unit" onChange={(e) => { props.setUnit((e.target.value) as 'ether' | 'finney' | 'gwei' | 'wei') }}> value={props.sendUnit} className="form-control p-1 udapp_gasNvalUnit udapp_col2_2 custom-select" id="unit" onChange={(e) => { props.setUnit((e.target.value) as 'ether' | 'finney' | 'gwei' | 'wei') }}>
<option data-unit="wei" value='wei'>Wei</option> <option data-unit="wei" value='wei'>Wei</option>
<option data-unit="gwei" value="gwei">Gwei</option> <option data-unit="gwei" value="gwei">Gwei</option>
<option data-unit="finney" value="finney">Finney</option> <option data-unit="finney" value="finney">Finney</option>

@ -83,581 +83,581 @@ type AddProvider = {
export const runTabReducer = (state: RunTabState = runTabInitialState, action: Action) => { export const runTabReducer = (state: RunTabState = runTabInitialState, action: Action) => {
switch (action.type) { switch (action.type) {
case FETCH_ACCOUNTS_LIST_REQUEST: { case FETCH_ACCOUNTS_LIST_REQUEST: {
return { return {
...state, ...state,
accounts: { accounts: {
...state.accounts, ...state.accounts,
isRequesting: true, isRequesting: true,
isSuccessful: false, isSuccessful: false,
error: null error: null
}
} }
} }
}
case FETCH_ACCOUNTS_LIST_SUCCESS: { case FETCH_ACCOUNTS_LIST_SUCCESS: {
const payload: Record<string, string> = action.payload const payload: Record<string, string> = action.payload
return { return {
...state, ...state,
accounts: { accounts: {
...state.accounts, ...state.accounts,
loadedAccounts: payload, loadedAccounts: payload,
isSuccessful: true, isSuccessful: true,
isRequesting: false, isRequesting: false,
error: null error: null
}
} }
} }
}
case FETCH_ACCOUNTS_LIST_FAILED: { case FETCH_ACCOUNTS_LIST_FAILED: {
const payload: string = action.payload const payload: string = action.payload
return { return {
...state, ...state,
accounts: { accounts: {
...state.accounts, ...state.accounts,
isRequesting: false, isRequesting: false,
isSuccessful: false, isSuccessful: false,
error: payload error: payload
}
} }
} }
}
case SET_SEND_VALUE: { case SET_SEND_VALUE: {
const payload: string = action.payload const payload: string = action.payload
return { return {
...state, ...state,
sendValue: payload sendValue: payload
}
} }
}
case SET_SELECTED_ACCOUNT: { case SET_SELECTED_ACCOUNT: {
const payload: string = action.payload const payload: string = action.payload
return { return {
...state, ...state,
accounts: { accounts: {
...state.accounts, ...state.accounts,
selectedAccount: payload selectedAccount: payload
}
} }
} }
}
case SET_SEND_UNIT: { case SET_SEND_UNIT: {
const payload: 'ether' | 'finney' | 'gwei' | 'wei' = action.payload const payload: 'ether' | 'finney' | 'gwei' | 'wei' = action.payload
return { return {
...state, ...state,
sendUnit: payload sendUnit: payload
}
} }
}
case SET_GAS_LIMIT: { case SET_GAS_LIMIT: {
const payload: number = action.payload const payload: number = action.payload
return { return {
...state, ...state,
gasLimit: payload gasLimit: payload
}
} }
}
case SET_EXECUTION_ENVIRONMENT: { case SET_EXECUTION_ENVIRONMENT: {
const payload: string = action.payload const payload: string = action.payload
return { return {
...state, ...state,
selectExEnv: payload, selectExEnv: payload,
networkName: state.selectExEnv === 'vm-merge' ? 'VM' : state.networkName, networkName: state.selectExEnv === 'vm-merge' ? 'VM' : state.networkName,
accounts: { accounts: {
...state.accounts, ...state.accounts,
selectedAccount: '', selectedAccount: '',
loadedAccounts: {} loadedAccounts: {}
}
} }
} }
}
case SET_PERSONAL_MODE: { case SET_PERSONAL_MODE: {
const payload: boolean = action.payload const payload: boolean = action.payload
return { return {
...state, ...state,
personalMode: payload personalMode: payload
}
} }
}
case SET_NETWORK_NAME: { case SET_NETWORK_NAME: {
const payload: string = action.payload const payload: string = action.payload
return { return {
...state, ...state,
networkName: payload networkName: payload
}
} }
}
case FETCH_PROVIDER_LIST_REQUEST: { case FETCH_PROVIDER_LIST_REQUEST: {
return { return {
...state, ...state,
providers: { providers: {
...state.providers, ...state.providers,
isRequesting: true, isRequesting: true,
isSuccessful: false, isSuccessful: false,
error: null error: null
}
} }
} }
}
case FETCH_PROVIDER_LIST_SUCCESS: { case FETCH_PROVIDER_LIST_SUCCESS: {
const payload: { id?: string, dataId?: string, title?: string, value: string, fork?: string, content: string }[] = action.payload const payload: { id?: string, dataId?: string, title?: string, value: string, fork?: string, content: string }[] = action.payload
return { return {
...state, ...state,
providers: { providers: {
...state.providers, ...state.providers,
providerList: payload, providerList: payload,
isSuccessful: true, isSuccessful: true,
isRequesting: false, isRequesting: false,
error: null error: null
}
} }
} }
}
case FETCH_PROVIDER_LIST_FAILED: { case FETCH_PROVIDER_LIST_FAILED: {
const payload: string = action.payload const payload: string = action.payload
return { return {
...state, ...state,
providers: { providers: {
...state.providers, ...state.providers,
isRequesting: false, isRequesting: false,
isSuccessful: false, isSuccessful: false,
error: payload error: payload
}
} }
} }
}
case ADD_PROVIDER: { case ADD_PROVIDER: {
const payload: AddProvider = action.payload const payload: AddProvider = action.payload
const id = action.payload.name const id = action.payload.name
state.providers.providerList.push({ state.providers.providerList.push({
content: payload.displayName, content: payload.displayName,
dataId: payload.dataId, dataId: payload.dataId,
id, id,
title: payload.title, title: payload.title,
value: id value: id
}) })
return { return {
...state, ...state,
providers: { providers: {
...state.providers, ...state.providers,
providerList: state.providers.providerList providerList: state.providers.providerList
}
} }
} }
}
case REMOVE_PROVIDER: { case REMOVE_PROVIDER: {
const id: string = action.payload const id: string = action.payload
const providers = state.providers.providerList.filter((el) => el.id !== id) const providers = state.providers.providerList.filter((el) => el.id !== id)
return { return {
...state, ...state,
providers: { providers: {
...state.providers, ...state.providers,
providerList: providers providerList: providers
}
} }
} }
}
case DISPLAY_NOTIFICATION: { case DISPLAY_NOTIFICATION: {
const payload = action.payload as { title: string, message: string, actionOk: () => void, actionCancel: () => void, labelOk: string, labelCancel: string } const payload = action.payload as { title: string, message: string, actionOk: () => void, actionCancel: () => void, labelOk: string, labelCancel: string }
return { return {
...state, ...state,
notification: { notification: {
title: payload.title, title: payload.title,
message: payload.message, message: payload.message,
actionOk: payload.actionOk || runTabInitialState.notification.actionOk, actionOk: payload.actionOk || runTabInitialState.notification.actionOk,
actionCancel: payload.actionCancel || runTabInitialState.notification.actionCancel, actionCancel: payload.actionCancel || runTabInitialState.notification.actionCancel,
labelOk: payload.labelOk, labelOk: payload.labelOk,
labelCancel: payload.labelCancel labelCancel: payload.labelCancel
}
} }
} }
}
case HIDE_NOTIFICATION: { case HIDE_NOTIFICATION: {
return { return {
...state, ...state,
notification: runTabInitialState.notification notification: runTabInitialState.notification
}
} }
}
case SET_EXTERNAL_WEB3_ENDPOINT: { case SET_EXTERNAL_WEB3_ENDPOINT: {
const payload: string = action.payload const payload: string = action.payload
return { return {
...state, ...state,
externalEndpoint: payload externalEndpoint: payload
}
} }
}
case DISPLAY_POPUP_MESSAGE: { case DISPLAY_POPUP_MESSAGE: {
const payload = action.payload as string const payload = action.payload as string
return { return {
...state, ...state,
popup: payload popup: payload
}
} }
}
case HIDE_POPUP_MESSAGE: { case HIDE_POPUP_MESSAGE: {
return { return {
...state, ...state,
popup: '' popup: ''
}
} }
}
case SET_PASSPHRASE: { case SET_PASSPHRASE: {
const passphrase: string = action.payload const passphrase: string = action.payload
return { return {
...state, ...state,
passphrase passphrase
}
} }
}
case SET_MATCH_PASSPHRASE: { case SET_MATCH_PASSPHRASE: {
const passphrase: string = action.payload const passphrase: string = action.payload
return { return {
...state, ...state,
matchPassphrase: passphrase matchPassphrase: passphrase
}
} }
}
case FETCH_CONTRACT_LIST_REQUEST: { case FETCH_CONTRACT_LIST_REQUEST: {
return { return {
...state, ...state,
contracts: { contracts: {
...state.contracts, ...state.contracts,
isRequesting: true, isRequesting: true,
isSuccessful: false, isSuccessful: false,
error: null error: null
}
} }
} }
}
case FETCH_CONTRACT_LIST_SUCCESS: { case FETCH_CONTRACT_LIST_SUCCESS: {
const payload: ContractList = action.payload const payload: ContractList = action.payload
return { return {
...state, ...state,
contracts: { contracts: {
...state.contracts, ...state.contracts,
contractList: { ...state.contracts.contractList, ...payload }, contractList: { ...state.contracts.contractList, ...payload },
isSuccessful: true, isSuccessful: true,
isRequesting: false, isRequesting: false,
error: null error: null
}
} }
} }
}
case FETCH_CONTRACT_LIST_FAILED: { case FETCH_CONTRACT_LIST_FAILED: {
const payload: string = action.payload const payload: string = action.payload
return { return {
...state, ...state,
contracts: { contracts: {
...state.contracts, ...state.contracts,
isRequesting: false, isRequesting: false,
isSuccessful: false, isSuccessful: false,
error: payload error: payload
}
} }
} }
}
case SET_CURRENT_CONTRACT: { case SET_CURRENT_CONTRACT: {
const payload: string = action.payload const payload: string = action.payload
return { return {
...state, ...state,
contracts: { contracts: {
...state.contracts, ...state.contracts,
currentContract: payload currentContract: payload
}
} }
} }
}
case SET_LOAD_TYPE: { case SET_LOAD_TYPE: {
const payload: 'abi' | 'sol' | 'other' = action.payload const payload: 'abi' | 'sol' | 'other' = action.payload
return { return {
...state, ...state,
contracts: { contracts: {
...state.contracts, ...state.contracts,
loadType: payload loadType: payload
}
} }
} }
}
case SET_CURRENT_FILE: { case SET_CURRENT_FILE: {
const payload: string = action.payload const payload: string = action.payload
return { return {
...state, ...state,
contracts: { contracts: {
...state.contracts, ...state.contracts,
currentFile: payload, currentFile: payload,
compilationCount: state.contracts.compilationCount + 1 compilationCount: state.contracts.compilationCount + 1
}
} }
} }
}
case SET_IPFS_CHECKED_STATE: { case SET_IPFS_CHECKED_STATE: {
const payload: boolean = action.payload const payload: boolean = action.payload
return { return {
...state, ...state,
ipfsChecked: payload ipfsChecked: payload
}
} }
}
case SET_GAS_PRICE_STATUS: { case SET_GAS_PRICE_STATUS: {
const payload: boolean = action.payload const payload: boolean = action.payload
return { return {
...state, ...state,
gasPriceStatus: payload gasPriceStatus: payload
}
} }
}
case SET_CONFIRM_SETTINGS: { case SET_CONFIRM_SETTINGS: {
const payload: boolean = action.payload const payload: boolean = action.payload
return { return {
...state, ...state,
confirmSettings: payload confirmSettings: payload
}
} }
}
case SET_MAX_FEE: { case SET_MAX_FEE: {
const payload: string = action.payload const payload: string = action.payload
return { return {
...state, ...state,
maxFee: payload maxFee: payload
}
} }
}
case SET_MAX_PRIORITY_FEE: { case SET_MAX_PRIORITY_FEE: {
const payload: string = action.payload const payload: string = action.payload
return { return {
...state, ...state,
maxPriorityFee: payload maxPriorityFee: payload
}
} }
}
case SET_BASE_FEE_PER_GAS: { case SET_BASE_FEE_PER_GAS: {
const payload: string = action.payload const payload: string = action.payload
return { return {
...state, ...state,
baseFeePerGas: payload baseFeePerGas: payload
}
} }
}
case SET_GAS_PRICE: { case SET_GAS_PRICE: {
const payload: string = action.payload const payload: string = action.payload
return { return {
...state, ...state,
gasPrice: payload gasPrice: payload
}
} }
}
case ADD_INSTANCE: { case ADD_INSTANCE: {
const payload: { contractData: ContractData, address: string, name: string, abi?: any, decodedResponse?: Record<number, any> } = action.payload const payload: { contractData: ContractData, address: string, name: string, abi?: any, decodedResponse?: Record<number, any> } = action.payload
return { return {
...state, ...state,
instances: { instances: {
...state.instances, ...state.instances,
instanceList: [...state.instances.instanceList, payload] instanceList: [...state.instances.instanceList, payload]
}
} }
} }
}
case UPDATE_INSTANCES_BALANCE: { case UPDATE_INSTANCES_BALANCE: {
const payload: Array<{ contractData: ContractData, address: string, balance: number, name: string, abi?: any, decodedResponse?: Record<number, any> }> = action.payload const payload: Array<{ contractData: ContractData, address: string, balance: number, name: string, abi?: any, decodedResponse?: Record<number, any> }> = action.payload
return { return {
...state, ...state,
instances: { instances: {
...state.instances, ...state.instances,
instanceList: payload instanceList: payload
}
} }
} }
}
case REMOVE_INSTANCE: { case REMOVE_INSTANCE: {
const payload: number = action.payload const payload: number = action.payload
return { return {
...state, ...state,
instances: { instances: {
...state.instances, ...state.instances,
instanceList: state.instances.instanceList.filter((_, index) => index !== payload) instanceList: state.instances.instanceList.filter((_, index) => index !== payload)
}
} }
} }
}
case CLEAR_INSTANCES: { case CLEAR_INSTANCES: {
return { return {
...state, ...state,
instances: { instances: {
instanceList: [], instanceList: [],
error: null error: null
}
} }
} }
}
case SET_DECODED_RESPONSE: { case SET_DECODED_RESPONSE: {
const payload: { instanceIndex: number, funcIndex: number, response: any } = action.payload const payload: { instanceIndex: number, funcIndex: number, response: any } = action.payload
return { return {
...state, ...state,
instances: { instances: {
...state.instances, ...state.instances,
instanceList: state.instances.instanceList.map((instance, index) => { instanceList: state.instances.instanceList.map((instance, index) => {
if (payload.instanceIndex === index) instance.decodedResponse[payload.funcIndex] = payload.response if (payload.instanceIndex === index) instance.decodedResponse[payload.funcIndex] = payload.response
return instance return instance
}) })
}
} }
} }
}
case SET_PATH_TO_SCENARIO: { case SET_PATH_TO_SCENARIO: {
const payload: string = action.payload const payload: string = action.payload
return { return {
...state, ...state,
recorder: { recorder: {
...state.recorder, ...state.recorder,
pathToScenario: payload pathToScenario: payload
}
} }
} }
}
case SET_RECORDER_COUNT: { case SET_RECORDER_COUNT: {
const payload: number = action.payload const payload: number = action.payload
return { return {
...state, ...state,
recorder: { recorder: {
...state.recorder, ...state.recorder,
transactionCount: payload transactionCount: payload
}
} }
} }
}
case CLEAR_RECORDER_COUNT: { case CLEAR_RECORDER_COUNT: {
return { return {
...state, ...state,
recorder: { recorder: {
...state.recorder, ...state.recorder,
transactionCount: 0 transactionCount: 0
}
} }
} }
}
case RESET_STATE: { case RESET_STATE: {
return { return {
...runTabInitialState, ...runTabInitialState,
ipfsChecked: state.ipfsChecked ipfsChecked: state.ipfsChecked
}
} }
}
case ADD_DEPLOY_OPTION: { case ADD_DEPLOY_OPTION: {
const payload: { [file: string]: { [name: string]: DeployOptions } } = action.payload const payload: { [file: string]: { [name: string]: DeployOptions } } = action.payload
return { return {
...state, ...state,
contracts: { contracts: {
...state.contracts, ...state.contracts,
deployOptions: {...state.contracts.deployOptions, ...payload } deployOptions: {...state.contracts.deployOptions, ...payload }
}
} }
} }
}
case REMOVE_DEPLOY_OPTION: { case REMOVE_DEPLOY_OPTION: {
const payload: string = action.payload const payload: string = action.payload
const options = state.contracts.deployOptions const options = state.contracts.deployOptions
delete options[payload] delete options[payload]
return { return {
...state, ...state,
contracts: { contracts: {
...state.contracts, ...state.contracts,
deployOptions: options deployOptions: options
}
} }
} }
}
case SET_DEPLOY_OPTIONS: { case SET_DEPLOY_OPTIONS: {
const payload: { [file: string]: { [name: string]: DeployOptions } } = action.payload const payload: { [file: string]: { [name: string]: DeployOptions } } = action.payload
return { return {
...state, ...state,
contracts: { contracts: {
...state.contracts, ...state.contracts,
deployOptions: payload deployOptions: payload
}
} }
} }
}
case SET_REMIXD_ACTIVATED: { case SET_REMIXD_ACTIVATED: {
const payload: boolean = action.payload const payload: boolean = action.payload
return { return {
...state, ...state,
remixdActivated: payload remixdActivated: payload
}
} }
}
case FETCH_PROXY_DEPLOYMENTS: { case FETCH_PROXY_DEPLOYMENTS: {
const payload: { address: string, date: string, contractName: string }[] = action.payload const payload: { address: string, date: string, contractName: string }[] = action.payload
return { return {
...state, ...state,
proxy: { proxy: {
...state.proxy, ...state.proxy,
deployments: payload deployments: payload
}
} }
} }
}
case NEW_PROXY_DEPLOYMENT: { case NEW_PROXY_DEPLOYMENT: {
const payload: { address: string, date: string, contractName: string } = action.payload const payload: { address: string, date: string, contractName: string } = action.payload
return { return {
...state, ...state,
proxy: { proxy: {
...state.proxy, ...state.proxy,
deployments: [...state.proxy.deployments, payload] deployments: [...state.proxy.deployments, payload]
}
} }
} }
}
case RESET_PROXY_DEPLOYMENTS: { case RESET_PROXY_DEPLOYMENTS: {
return { return {
...state, ...state,
proxy: { proxy: {
...state.proxy, ...state.proxy,
deployments: [] deployments: []
}
} }
} }
}
default: default:
return state return state
} }
} }

@ -2,21 +2,21 @@ import { Plugin } from "@remixproject/engine/lib/abstract";
import { ExecutionContext } from "./execution-context"; import { ExecutionContext } from "./execution-context";
import { EventEmitter } from "events"; import { EventEmitter } from "events";
export class Blockchain extends Plugin<any, any> { export class Blockchain extends Plugin<any, any> {
constructor(config: any); constructor(config: any);
event: any; event: any;
executionContext: ExecutionContext; executionContext: ExecutionContext;
events: EventEmitter; events: EventEmitter;
config: any; config: any;
txRunner: any; txRunner: any;
networkcallid: number; networkcallid: number;
networkStatus: { networkStatus: {
network: { network: {
name: string; name: string;
id: string; id: string;
}; };
}; };
setupEvents(): void; setupEvents(): void;
getCurrentNetworkStatus(): { getCurrentNetworkStatus(): {
name: string; name: string;
id: string; id: string;
network?: { network?: {
@ -24,62 +24,62 @@ export class Blockchain extends Plugin<any, any> {
id: string; id: string;
}; };
}; };
setupProviders(): void; setupProviders(): void;
providers: any; providers: any;
getCurrentProvider(): any; getCurrentProvider(): any;
/** Return the list of accounts */ /** Return the list of accounts */
getAccounts(cb?: any): any; getAccounts(cb?: any): any;
deployContractAndLibraries(selectedContract: any, args: any, contractMetadata: any, compilerContracts: any, callbacks: any, confirmationCb: any): void; deployContractAndLibraries(selectedContract: any, args: any, contractMetadata: any, compilerContracts: any, callbacks: any, confirmationCb: any): void;
deployContractWithLibrary(selectedContract: any, args: any, contractMetadata: any, compilerContracts: any, callbacks: any, confirmationCb: any): void; deployContractWithLibrary(selectedContract: any, args: any, contractMetadata: any, compilerContracts: any, callbacks: any, confirmationCb: any): void;
createContract(selectedContract: any, data: any, continueCb: any, promptCb: any, confirmationCb: any, finalCb: any): void; createContract(selectedContract: any, data: any, continueCb: any, promptCb: any, confirmationCb: any, finalCb: any): void;
determineGasPrice(cb: any): void; determineGasPrice(cb: any): void;
getInputs(funABI: any): any; getInputs(funABI: any): any;
fromWei(value: any, doTypeConversion: any, unit: any): string; fromWei(value: any, doTypeConversion: any, unit: any): string;
toWei(value: any, unit: any): import("bn.js"); toWei(value: any, unit: any): import("bn.js");
calculateFee(gas: any, gasPrice: any, unit: any): import("bn.js"); calculateFee(gas: any, gasPrice: any, unit: any): import("bn.js");
determineGasFees(tx: any): (gasPrice: any, cb: any) => void; determineGasFees(tx: any): (gasPrice: any, cb: any) => void;
changeExecutionContext(context: any, confirmCb: any, infoCb: any, cb: any): Promise<any>; changeExecutionContext(context: any, confirmCb: any, infoCb: any, cb: any): Promise<any>;
detectNetwork(cb: any): void; detectNetwork(cb: any): void;
getProvider(): any; getProvider(): any;
getInjectedWeb3Address(): any; getInjectedWeb3Address(): any;
/** /**
* return the fork name applied to the current envionment * return the fork name applied to the current envionment
* @return {String} - fork name * @return {String} - fork name
*/ */
getCurrentFork(): string; getCurrentFork(): string;
isWeb3Provider(): boolean; isWeb3Provider(): boolean;
isInjectedWeb3(): boolean; isInjectedWeb3(): boolean;
signMessage(message: any, account: any, passphrase: any, cb: any): void; signMessage(message: any, account: any, passphrase: any, cb: any): void;
web3(): any; web3(): any;
getTxListener(opts: any): any; getTxListener(opts: any): any;
runOrCallContractMethod(contractName: any, contractAbi: any, funABI: any, contract: any, value: any, address: any, callType: any, lookupOnly: any, logMsg: any, logCallback: any, outputCb: any, confirmationCb: any, continueCb: any, promptCb: any): void; runOrCallContractMethod(contractName: any, contractAbi: any, funABI: any, contract: any, value: any, address: any, callType: any, lookupOnly: any, logMsg: any, logCallback: any, outputCb: any, confirmationCb: any, continueCb: any, promptCb: any): void;
context(): "memory" | "blockchain"; context(): "memory" | "blockchain";
resetAndInit(config: any, transactionContextAPI: any): void; resetAndInit(config: any, transactionContextAPI: any): void;
transactionContextAPI: any; transactionContextAPI: any;
addProvider(provider: any): void; addProvider(provider: any): void;
removeProvider(name: any): void; removeProvider(name: any): void;
/** Listen on New Transaction. (Cannot be done inside constructor because txlistener doesn't exist yet) */ /** Listen on New Transaction. (Cannot be done inside constructor because txlistener doesn't exist yet) */
startListening(txlistener: any): void; startListening(txlistener: any): void;
resetEnvironment(): Promise<void>; resetEnvironment(): Promise<void>;
/** /**
* Create a VM Account * Create a VM Account
* @param {{privateKey: string, balance: string}} newAccount The new account to create * @param {{privateKey: string, balance: string}} newAccount The new account to create
*/ */
createVMAccount(newAccount: { createVMAccount(newAccount: {
privateKey: string; privateKey: string;
balance: string; balance: string;
}): any; }): any;
newAccount(_password: any, passwordPromptCb: any, cb: any): any; newAccount(_password: any, passwordPromptCb: any, cb: any): any;
/** Get the balance of an address, and convert wei to ether */ /** Get the balance of an address, and convert wei to ether */
getBalanceInEther(address: any): Promise<string>; getBalanceInEther(address: any): Promise<string>;
pendingTransactionsCount(): number; pendingTransactionsCount(): number;
/** /**
* This function send a tx only to Remix VM or testnet, will return an error for the mainnet * This function send a tx only to Remix VM or testnet, will return an error for the mainnet
* SHOULD BE TAKEN CAREFULLY! * SHOULD BE TAKEN CAREFULLY!
* *
* @param {Object} tx - transaction. * @param {Object} tx - transaction.
*/ */
sendTransaction(tx: any): any; sendTransaction(tx: any): any;
runTx(args: any, confirmationCb: any, continueCb: any, promptCb: any, cb: any): void; runTx(args: any, confirmationCb: any, continueCb: any, promptCb: any, cb: any): void;
} }

@ -1,36 +1,36 @@
import Web3 from 'web3' import Web3 from 'web3'
export class ExecutionContext { export class ExecutionContext {
event: any; event: any;
executionContext: any; executionContext: any;
lastBlock: any; lastBlock: any;
blockGasLimitDefault: number; blockGasLimitDefault: number;
blockGasLimit: number; blockGasLimit: number;
currentFork: string; currentFork: string;
mainNetGenesisHash: string; mainNetGenesisHash: string;
customNetWorks: any; customNetWorks: any;
blocks: any; blocks: any;
latestBlockNumber: number; latestBlockNumber: number;
txs: any; txs: any;
customWeb3: any; customWeb3: any;
init(config: any): void; init(config: any): void;
askPermission(): void; askPermission(): void;
getProvider(): any; getProvider(): any;
getCurrentFork(): string; getCurrentFork(): string;
isVM(): boolean; isVM(): boolean;
setWeb3(context: any, web3: any): void; setWeb3(context: any, web3: any): void;
web3(): any; web3(): any;
detectNetwork(callback: any): void; detectNetwork(callback: any): void;
removeProvider(name: any): void; removeProvider(name: any): void;
addProvider(network: any): void; addProvider(network: any): void;
internalWeb3(): any; internalWeb3(): any;
setContext(context: any, endPointUrl: any, confirmCb: any, infoCb: any): void; setContext(context: any, endPointUrl: any, confirmCb: any, infoCb: any): void;
executionContextChange(value: any, endPointUrl: any, confirmCb: any, infoCb: any, cb: any): Promise<any>; executionContextChange(value: any, endPointUrl: any, confirmCb: any, infoCb: any, cb: any): Promise<any>;
currentblockGasLimit(): number; currentblockGasLimit(): number;
stopListenOnLastBlock(): void; stopListenOnLastBlock(): void;
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
listenOnLastBlockId: NodeJS.Timer; listenOnLastBlockId: NodeJS.Timer;
_updateChainContext(): Promise<void>; _updateChainContext(): Promise<void>;
listenOnLastBlock(): void; listenOnLastBlock(): void;
txDetailsLink(network: any, hash: any): any; txDetailsLink(network: any, hash: any): any;
} }

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

@ -1,13 +1,13 @@
export = NodeProvider; export = NodeProvider;
declare class NodeProvider { declare class NodeProvider {
constructor(executionContext: any, config: any); constructor(executionContext: any, config: any);
executionContext: any; executionContext: any;
config: any; config: any;
getAccounts(cb: any): any; getAccounts(cb: any): any;
newAccount(passwordPromptCb: any, cb: any): any; newAccount(passwordPromptCb: any, cb: any): any;
resetEnvironment(): Promise<void>; resetEnvironment(): Promise<void>;
getBalanceInEther(address: any): Promise<string>; getBalanceInEther(address: any): Promise<string>;
getGasPrice(cb: any): void; getGasPrice(cb: any): void;
signMessage(message: any, account: any, passphrase: any, cb: any): void; signMessage(message: any, account: any, passphrase: any, cb: any): void;
getProvider(): any; getProvider(): any;
} }

@ -1,42 +1,42 @@
export class RunTab extends ViewPlugin { export class RunTab extends ViewPlugin {
constructor(blockchain: any, config: any, fileManager: any, editor: any, filePanel: any, compilersArtefacts: any, networkModule: any, mainView: any, fileProvider: any); constructor(blockchain: any, config: any, fileManager: any, editor: any, filePanel: any, compilersArtefacts: any, networkModule: any, mainView: any, fileProvider: any);
event: any; event: any;
config: any; config: any;
blockchain: Blockchain; blockchain: Blockchain;
fileManager: any; fileManager: any;
editor: any; editor: any;
logCallback: (msg: any) => void; logCallback: (msg: any) => void;
filePanel: any; filePanel: any;
compilersArtefacts: any; compilersArtefacts: any;
networkModule: any; networkModule: any;
fileProvider: any; fileProvider: any;
REACT_API: RunTabState; REACT_API: RunTabState;
el: HTMLDivElement; el: HTMLDivElement;
setupEvents(): void; setupEvents(): void;
getSettings(): any; getSettings(): any;
setEnvironmentMode(env: any): Promise<void>; setEnvironmentMode(env: any): Promise<void>;
createVMAccount(newAccount: any): any; createVMAccount(newAccount: any): any;
sendTransaction(tx: any): any; sendTransaction(tx: any): any;
getAccounts(cb: any): any; getAccounts(cb: any): any;
pendingTransactionsCount(): any; pendingTransactionsCount(): any;
renderInstanceContainer(): void; renderInstanceContainer(): void;
instanceContainer: any; instanceContainer: any;
noInstancesText: any; noInstancesText: any;
renderSettings(): void; renderSettings(): void;
settingsUI: any; settingsUI: any;
renderDropdown(udappUI: any, fileManager: any, compilersArtefacts: any, config: any, editor: any, logCallback: any): void; renderDropdown(udappUI: any, fileManager: any, compilersArtefacts: any, config: any, editor: any, logCallback: any): void;
contractDropdownUI: any; contractDropdownUI: any;
renderRecorder(udappUI: any, fileManager: any, config: any, logCallback: any): void; renderRecorder(udappUI: any, fileManager: any, config: any, logCallback: any): void;
recorderCount: any; recorderCount: any;
recorderInterface: any; recorderInterface: any;
renderRecorderCard(): void; renderRecorderCard(): void;
recorderCard: any; recorderCard: any;
udappUI: any; udappUI: any;
renderComponent(): void; renderComponent(): void;
onReady(api: any): void; onReady(api: any): void;
onInitDone(): void; onInitDone(): void;
recorder: Recorder; recorder: Recorder;
// syncContracts(): void // syncContracts(): void
} }
import { ViewPlugin } from "@remixproject/engine-web"; import { ViewPlugin } from "@remixproject/engine-web";
import { Blockchain } from "./blockchain"; import { Blockchain } from "./blockchain";

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

@ -35,7 +35,7 @@ export const FindContainer = props => {
<div className="search_plugin_find_container_internal"> <div className="search_plugin_find_container_internal">
<Find></Find> <Find></Find>
{expanded ? {expanded ?
<><Replace></Replace><OverWriteCheck></OverWriteCheck></> : null} <><Replace></Replace><OverWriteCheck></OverWriteCheck></> : null}
</div> </div>
</div> </div>
) )

@ -15,7 +15,7 @@ export const Replace = props => {
return ( return (
<> <>
<div className="search_plugin_find-part "> <div className="search_plugin_find-part ">
<label className='d-none'>replace in files</label> <label className='d-none'>replace in files</label>
<input <input
id='search_replace' id='search_replace'
placeholder={intl.formatMessage({ id: 'search.replace' })} placeholder={intl.formatMessage({ id: 'search.replace' })}

@ -3,11 +3,11 @@ import { useContext } from "react"
import { SearchContext } from "../context/context" import { SearchContext } from "../context/context"
export const StopSearch = () => { export const StopSearch = () => {
const { cancelSearch } = useContext(SearchContext) const { cancelSearch } = useContext(SearchContext)
const cancel = async () => { const cancel = async () => {
await cancelSearch(false) await cancelSearch(false)
} }
return ( return (
<a className="badge badge-danger search_plugin_stop" onClick={async () => await cancel()}>stop</a> <a className="badge badge-danger search_plugin_stop" onClick={async () => await cancel()}>stop</a>
) )
} }

@ -5,25 +5,25 @@ import { SearchContext } from "../context/context"
import * as path from 'path' import * as path from 'path'
export const Undo = () => { export const Undo = () => {
const { const {
state, state,
undoReplace undoReplace
} = useContext(SearchContext) } = useContext(SearchContext)
const { alert } = useDialogDispatchers() const { alert } = useDialogDispatchers()
const undo = async () => { const undo = async () => {
try{ try{
await undoReplace(state.undoBuffer[`${state.workspace}/${state.currentFile}`]) await undoReplace(state.undoBuffer[`${state.workspace}/${state.currentFile}`])
}catch(e){ }catch(e){
alert({ id: 'undo_error', title: 'Cannot undo this change', message: e.message }) alert({ id: 'undo_error', title: 'Cannot undo this change', message: e.message })
}
} }
}
return (<> return (<>
{state.undoBuffer && state.undoBuffer[`${state.workspace}/${state.currentFile}`] && state.undoBuffer[`${state.workspace}/${state.currentFile}`].visible ? {state.undoBuffer && state.undoBuffer[`${state.workspace}/${state.currentFile}`] && state.undoBuffer[`${state.workspace}/${state.currentFile}`].visible ?
<button data-id={`undo-replace-${state.currentFile}`} disabled={!state.undoBuffer[`${state.workspace}/${state.currentFile}`].enabled} onClick={async() => await undo()} className="undo-button btn btn-secondary btn-block my-3"> <button data-id={`undo-replace-${state.currentFile}`} disabled={!state.undoBuffer[`${state.workspace}/${state.currentFile}`].enabled} onClick={async() => await undo()} className="undo-button btn btn-secondary btn-block my-3">
<div className="fas fa-undo mr-2"></div> <div className="fas fa-undo mr-2"></div>
Undo changes to {path.basename(state.undoBuffer[`${state.workspace}/${state.currentFile}`].path)} Undo changes to {path.basename(state.undoBuffer[`${state.workspace}/${state.currentFile}`].path)}
</button> : null} </button> : null}
</>) </>)
} }

@ -127,10 +127,10 @@ export const ResultItem = (props: ResultItemProps) => {
{state.replaceEnabled? {state.replaceEnabled?
<div className="search_plugin_wrap_summary_replace"> <div className="search_plugin_wrap_summary_replace">
<div data-id={`replace-all-${props.file.filename}`} onClick={async() => replace()} className='btn btn-secondary mb-2 btn-sm'> <div data-id={`replace-all-${props.file.filename}`} onClick={async() => replace()} className='btn btn-secondary mb-2 btn-sm'>
<FormattedMessage id='search.replaceAll' /> <FormattedMessage id='search.replaceAll' />
</div> </div>
</div> </div>
:null} :null}
{lines.map((line, index) => ( {lines.map((line, index) => (
<ResultSummary <ResultSummary
setLoading={setLoading} setLoading={setLoading}

@ -39,32 +39,32 @@ export const ResultSummary = (props: ResultSummaryProps) => {
<> <>
{props.line.lines.map((lineItem, index) => ( {props.line.lines.map((lineItem, index) => (
<div className='search_plugin_search_line_container' key={index}> <div className='search_plugin_search_line_container' key={index}>
<div <div
onClick={async () => { onClick={async () => {
selectLine(lineItem) selectLine(lineItem)
}} }}
data-id={`${props.searchResult.filename}-${lineItem.position.start.line}-${lineItem.position.start.column}`} data-id={`${props.searchResult.filename}-${lineItem.position.start.line}-${lineItem.position.start.column}`}
key={props.searchResult.filename} key={props.searchResult.filename}
className='search_plugin_search_line pb-1' className='search_plugin_search_line pb-1'
> >
<div className='search_plugin_summary_left'>{lineItem.left.substring(lineItem.left.length - 20).trimStart()}</div> <div className='search_plugin_summary_left'>{lineItem.left.substring(lineItem.left.length - 20).trimStart()}</div>
<mark className={`search_plugin_summary_center ${state.replace && state.replaceEnabled? 'search_plugin_replace_strike':''}`}>{lineItem.center}</mark> <mark className={`search_plugin_summary_center ${state.replace && state.replaceEnabled? 'search_plugin_replace_strike':''}`}>{lineItem.center}</mark>
{state.replace && state.replaceEnabled? <mark className='search_plugin_replacement'>{state.replace}</mark>:<></>} {state.replace && state.replaceEnabled? <mark className='search_plugin_replacement'>{state.replace}</mark>:<></>}
<div className='search_plugin_summary_right'>{lineItem.right.substring(0, 100)}</div> <div className='search_plugin_summary_right'>{lineItem.right.substring(0, 100)}</div>
</div> </div>
{state.replaceEnabled? {state.replaceEnabled?
<div className='search_plugin_search_control'> <div className='search_plugin_search_control'>
<CustomTooltip <CustomTooltip
tooltipText="Replace" tooltipText="Replace"
tooltipClasses="text-nowrap" tooltipClasses="text-nowrap"
tooltipId="replaceTooltip" tooltipId="replaceTooltip"
placement="top-start" placement="top-start"
> >
<div data-id={`replace-${props.searchResult.filename}-${lineItem.position.start.line}-${lineItem.position.start.column}`} onClick={async () => { <div data-id={`replace-${props.searchResult.filename}-${lineItem.position.start.line}-${lineItem.position.start.column}`} onClick={async () => {
replace(lineItem) replace(lineItem)
}} className="codicon codicon-find-replace" role="button" aria-label="Replace" aria-disabled="false"></div> }} className="codicon codicon-find-replace" role="button" aria-label="Replace" aria-disabled="false"></div>
</CustomTooltip> </CustomTooltip>
</div>:null} </div>:null}
</div> </div>
))} ))}
</> </>

@ -8,7 +8,7 @@ export const Results = () => {
return ( return (
<div data-id="search_results" className="mt-2"> <div data-id="search_results" className="mt-2">
<div className="search_plugin_search_indicator py-1"> <div className="search_plugin_search_indicator py-1">
{state.searching && !state.clipped ? <StopSearch></StopSearch> : null} {state.searching && !state.clipped {state.searching && !state.clipped ? <StopSearch></StopSearch> : null} {state.searching && !state.clipped
? `searching in ${state.searching}` ? `searching in ${state.searching}`
: null}<br></br> : null}<br></br>

@ -3,93 +3,93 @@ import { SearchResultLineLine } from '../../types'
export const getDirectory = async (dir: string, plugin: any) => { export const getDirectory = async (dir: string, plugin: any) => {
let result = [] let result = []
const files = await plugin.call('fileManager', 'readdir', dir) const files = await plugin.call('fileManager', 'readdir', dir)
const fileArray = normalize(files) const fileArray = normalize(files)
for (const fi of fileArray) { for (const fi of fileArray) {
if (fi) { if (fi) {
const type = fi.data.isDirectory const type = fi.data.isDirectory
if (type === true) { if (type === true) {
result = [...result, ...(await getDirectory(`${fi.filename}`, plugin))] result = [...result, ...(await getDirectory(`${fi.filename}`, plugin))]
} else { } else {
result = [...result, fi.filename] result = [...result, fi.filename]
}
} }
} }
return result
} }
return result
}
const normalize = filesList => { const normalize = filesList => {
const folders = [] const folders = []
const files = [] const files = []
Object.keys(filesList || {}).forEach(key => { Object.keys(filesList || {}).forEach(key => {
if (filesList[key].isDirectory) { if (filesList[key].isDirectory) {
folders.push({ folders.push({
filename: key, filename: key,
data: filesList[key] data: filesList[key]
}) })
} else { } else {
files.push({ files.push({
filename: key, filename: key,
data: filesList[key] data: filesList[key]
}) })
} }
}) })
return [...folders, ...files] return [...folders, ...files]
} }
export const findLinesInStringWithMatch = (str: string, re: RegExp) => { export const findLinesInStringWithMatch = (str: string, re: RegExp) => {
return str return str
.split(/\r?\n/) .split(/\r?\n/)
.map(function (line, i) { .map(function (line, i) {
const matchResult = matchesInString(line, re) const matchResult = matchesInString(line, re)
if (matchResult.length) { if (matchResult.length) {
return { return {
lines: splitLines(matchResult, i), lines: splitLines(matchResult, i),
} }
} }
}) })
.filter(Boolean) .filter(Boolean)
} }
const matchesInString = (str: string, re: RegExp) => { const matchesInString = (str: string, re: RegExp) => {
let a: RegExpExecArray let a: RegExpExecArray
const results:RegExpExecArray[] = []; const results:RegExpExecArray[] = [];
while ((a = re.exec(str || '')) !== null) { while ((a = re.exec(str || '')) !== null) {
results.push(a); results.push(a);
} }
return results return results
} }
const splitLines = (matchResult: RegExpExecArray[], lineNumber: number) => { const splitLines = (matchResult: RegExpExecArray[], lineNumber: number) => {
return matchResult.map((matchResultPart, i) => { return matchResult.map((matchResultPart, i) => {
const result:SearchResultLineLine = { const result:SearchResultLineLine = {
left: matchResultPart.input.substring(0, matchResultPart.index), left: matchResultPart.input.substring(0, matchResultPart.index),
right: matchResultPart.input.substring(matchResultPart.index + matchResultPart[0].length), right: matchResultPart.input.substring(matchResultPart.index + matchResultPart[0].length),
center: matchResultPart[0], center: matchResultPart[0],
position : { position : {
start: { start: {
line: lineNumber, line: lineNumber,
column: matchResultPart.index, column: matchResultPart.index,
}, },
end: { end: {
line: lineNumber, line: lineNumber,
column: matchResultPart.index + matchResultPart[0].length, column: matchResultPart.index + matchResultPart[0].length,
}, },
}, },
} }
return result return result
}) })
} }
function getEOL(text) { function getEOL(text) {
const m = text.match(/\r\n|\n/g); const m = text.match(/\r\n|\n/g);
const u = m && m.filter(a => a === '\n').length; const u = m && m.filter(a => a === '\n').length;
const w = m && m.length - u; const w = m && m.length - u;
if (u === w) { if (u === w) {
return EOL; // use the OS default return EOL; // use the OS default
} }
return u > w ? '\n' : '\r\n'; return u > w ? '\n' : '\r\n';
} }
export const replaceAllInFile = (string: string, re:RegExp, newText: string) => { export const replaceAllInFile = (string: string, re:RegExp, newText: string) => {
@ -97,13 +97,13 @@ export const replaceAllInFile = (string: string, re:RegExp, newText: string) =>
} }
export const replaceTextInLine = (str: string, searchResultLine: SearchResultLineLine, newText: string) => { export const replaceTextInLine = (str: string, searchResultLine: SearchResultLineLine, newText: string) => {
return str return str
.split(/\r?\n/) .split(/\r?\n/)
.map(function (line, i) { .map(function (line, i) {
if (i === searchResultLine.position.start.line) { if (i === searchResultLine.position.start.line) {
return searchResultLine.left + newText + searchResultLine.right return searchResultLine.left + newText + searchResultLine.right
} }
return line return line
}).join(getEOL(str)) }).join(getEOL(str))
} }

@ -1,181 +1,181 @@
import { Action, SearchingInitialState, SearchState, undoBufferRecord } from "../types" import { Action, SearchingInitialState, SearchState, undoBufferRecord } from "../types"
export const SearchReducer = (state: SearchState = SearchingInitialState, action: Action) => { export const SearchReducer = (state: SearchState = SearchingInitialState, action: Action) => {
switch (action.type) { switch (action.type) {
case 'START_SEARCH': case 'START_SEARCH':
return { return {
...state, ...state,
timeStamp: Date.now() timeStamp: Date.now()
} }
case 'SET_FIND': case 'SET_FIND':
return { return {
...state, ...state,
searchResults: null, searchResults: null,
find: action.payload find: action.payload
} }
case 'SET_REPLACE': case 'SET_REPLACE':
return { return {
...state, ...state,
replace: action.payload, replace: action.payload,
} }
case 'SET_REPLACE_ENABLED': case 'SET_REPLACE_ENABLED':
return { return {
...state, ...state,
replaceEnabled: action.payload, replaceEnabled: action.payload,
} }
case 'SET_INCLUDE': case 'SET_INCLUDE':
return { return {
...state, ...state,
include: action.payload, include: action.payload,
} }
case 'SET_EXCLUDE': case 'SET_EXCLUDE':
return { return {
...state, ...state,
exclude: action.payload, exclude: action.payload,
} }
case 'SET_SEARCH_RESULTS': case 'SET_SEARCH_RESULTS':
return { return {
...state, ...state,
searchResults: action.payload, searchResults: action.payload,
count: 0, count: 0,
run: true run: true
} }
case 'SET_UNDO_ENABLED': case 'SET_UNDO_ENABLED':
if(action.payload.workspace && state.undoBuffer[`${action.payload.workspace}/${action.payload.path}`]){ if(action.payload.workspace && state.undoBuffer[`${action.payload.workspace}/${action.payload.path}`]){
state.undoBuffer[`${action.payload.workspace}/${action.payload.path}`].enabled = (action.payload.content === state.undoBuffer[`${action.payload.workspace}/${action.payload.path}`].newContent) state.undoBuffer[`${action.payload.workspace}/${action.payload.path}`].enabled = (action.payload.content === state.undoBuffer[`${action.payload.workspace}/${action.payload.path}`].newContent)
state.undoBuffer[`${action.payload.workspace}/${action.payload.path}`].visible = (action.payload.content !== state.undoBuffer[`${action.payload.workspace}/${action.payload.path}`].oldContent) state.undoBuffer[`${action.payload.workspace}/${action.payload.path}`].visible = (action.payload.content !== state.undoBuffer[`${action.payload.workspace}/${action.payload.path}`].oldContent)
} }
return { return {
...state, ...state,
} }
case 'SET_UNDO': { case 'SET_UNDO': {
const undoState = { const undoState = {
newContent : action.payload.newContent, newContent : action.payload.newContent,
oldContent: action.payload.oldContent, oldContent: action.payload.oldContent,
path: action.payload.path, path: action.payload.path,
workspace: action.payload.workspace, workspace: action.payload.workspace,
timeStamp: Date.now(), timeStamp: Date.now(),
enabled: true, enabled: true,
visible: true visible: true
} }
state.undoBuffer[`${undoState.workspace}/${undoState.path}`] = undoState state.undoBuffer[`${undoState.workspace}/${undoState.path}`] = undoState
return { return {
...state, ...state,
} }
} }
case 'CLEAR_STATS': case 'CLEAR_STATS':
return { return {
...state, ...state,
count: 0, count: 0,
fileCount: 0, fileCount: 0,
searchResults: null, searchResults: null,
searching: null searching: null
} }
case 'SET_SEARCHING': case 'SET_SEARCHING':
return { return {
...state, ...state,
searching: action.payload, searching: action.payload,
} }
case 'CLEAR_UNDO': { case 'CLEAR_UNDO': {
state.undoBuffer = [] state.undoBuffer = []
return { return {
...state, ...state,
} }
}
case 'UPDATE_COUNT':
if (state.searchResults) {
const findFile = state.searchResults.find(file => file.filename === action.payload.file)
let count = 0
let fileCount = 0
const clipped = false
if (findFile) {
findFile.count = action.payload.count
}
state.searchResults.forEach(file => {
if (file.count) {
count += file.count
fileCount++
} }
case 'UPDATE_COUNT': })
if (state.searchResults) { return {
const findFile = state.searchResults.find(file => file.filename === action.payload.file) ...state,
let count = 0 count: count,
let fileCount = 0 fileCount,
const clipped = false clipped
if (findFile) { }
findFile.count = action.payload.count } else {
} return state
state.searchResults.forEach(file => { }
if (file.count) {
count += file.count
fileCount++
}
})
return {
...state,
count: count,
fileCount,
clipped
}
} else {
return state
}
case 'SET_CLIPPED': case 'SET_CLIPPED':
return { return {
...state, ...state,
clipped: action.payload clipped: action.payload
} }
case 'SET_RUN': case 'SET_RUN':
return { return {
...state, ...state,
run: action.payload run: action.payload
} }
case 'TOGGLE_CASE_SENSITIVE': case 'TOGGLE_CASE_SENSITIVE':
return { return {
...state, ...state,
casesensitive: !state.casesensitive, casesensitive: !state.casesensitive,
timeStamp: Date.now() timeStamp: Date.now()
} }
case 'TOGGLE_USE_REGEX': case 'TOGGLE_USE_REGEX':
return { return {
...state, ...state,
useRegExp: !state.useRegExp, useRegExp: !state.useRegExp,
timeStamp: Date.now() timeStamp: Date.now()
} }
case 'TOGGLE_MATCH_WHOLE_WORD': case 'TOGGLE_MATCH_WHOLE_WORD':
return { return {
...state, ...state,
matchWord: !state.matchWord, matchWord: !state.matchWord,
timeStamp: Date.now() timeStamp: Date.now()
} }
case 'SET_REPLACE_WITHOUT_CONFIRMATION': case 'SET_REPLACE_WITHOUT_CONFIRMATION':
return { return {
...state, ...state,
replaceWithOutConfirmation: action.payload, replaceWithOutConfirmation: action.payload,
} }
case 'DISABLE_FORCE_RELOAD': case 'DISABLE_FORCE_RELOAD':
if (state.searchResults) { if (state.searchResults) {
const findFile = state.searchResults.find(file => file.filename === action.payload) const findFile = state.searchResults.find(file => file.filename === action.payload)
if (findFile) findFile.forceReload = false if (findFile) findFile.forceReload = false
} }
return { return {
...state, ...state,
} }
case 'SET_CURRENT_FILE': case 'SET_CURRENT_FILE':
return { return {
...state, ...state,
currentFile: action.payload, currentFile: action.payload,
} }
case 'SET_CURRENT_WORKSPACE': case 'SET_CURRENT_WORKSPACE':
return { return {
...state, ...state,
workspace: action.payload, workspace: action.payload,
} }
case 'RELOAD_FILE': case 'RELOAD_FILE':
if (state.searchResults) { if (state.searchResults) {
const findFile = state.searchResults.find(file => file.filename === action.payload) const findFile = state.searchResults.find(file => file.filename === action.payload)
if (findFile) findFile.forceReload = true if (findFile) findFile.forceReload = true
} }
return { return {
...state, ...state,
} }
default: default:
return { return {
...state, ...state,
}
} }
}
} }

@ -69,25 +69,25 @@ export interface SearchState {
} }
export const SearchingInitialState: SearchState = { export const SearchingInitialState: SearchState = {
find: '', find: '',
replace: '', replace: '',
include: '', include: '',
exclude: '', exclude: '',
replaceEnabled: false, replaceEnabled: false,
searchResults: [], searchResults: [],
casesensitive: false, casesensitive: false,
matchWord: false, matchWord: false,
useRegExp: false, useRegExp: false,
replaceWithOutConfirmation: false, replaceWithOutConfirmation: false,
timeStamp: 0, timeStamp: 0,
count: 0, count: 0,
fileCount: 0, fileCount: 0,
maxFiles: 5000, maxFiles: 5000,
maxLines: 5000, maxLines: 5000,
clipped: false, clipped: false,
undoBuffer: null, undoBuffer: null,
currentFile: '', currentFile: '',
workspace: '', workspace: '',
searching: null, searching: null,
run: false, run: false,
} }

@ -4,12 +4,12 @@ export const textDark = 'text-dark'
export const gitAccessTokenLink = 'https://github.com/settings/tokens/new?scopes=gist,repo&description=Remix%20IDE%20Token' export const gitAccessTokenLink = 'https://github.com/settings/tokens/new?scopes=gist,repo&description=Remix%20IDE%20Token'
export const etherscanTokenLink = 'https://etherscan.io/myapikey' export const etherscanTokenLink = 'https://etherscan.io/myapikey'
export const labels = { export const labels = {
'gist': { 'gist': {
'link': gitAccessTokenLink, 'link': gitAccessTokenLink,
'key': 'gist-access-token' 'key': 'gist-access-token'
}, },
'etherscan': { 'etherscan': {
'link': etherscanTokenLink, 'link': etherscanTokenLink,
'key': 'etherscan-access-token' 'key': 'etherscan-access-token'
} }
} }

@ -58,8 +58,8 @@ export function EtherscanSettings (props: EtherscanSettingsProps) {
placement="left-start" placement="left-start"
> >
<button className="btn btn-sm btn-secondary ml-2" id="removeetherscantoken" data-id="settingsTabRemoveEtherscanToken" title="Delete Etherscan token" onClick={removeToken}> <button className="btn btn-sm btn-secondary ml-2" id="removeetherscantoken" data-id="settingsTabRemoveEtherscanToken" title="Delete Etherscan token" onClick={removeToken}>
<FormattedMessage id='settings.remove' /> <FormattedMessage id='settings.remove' />
</button></CustomTooltip> </button></CustomTooltip>
</div> </div>
</div> </div>
</div> </div>

@ -308,38 +308,38 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => {
const ipfsSettings = () => ( const ipfsSettings = () => (
<div className="border-top"> <div className="border-top">
<div className="card-body pt-3 pb-2"> <div className="card-body pt-3 pb-2">
<h6 className="card-title"><FormattedMessage id='settings.ipfs' /></h6> <h6 className="card-title"><FormattedMessage id='settings.ipfs' /></h6>
<div className="pt-2 mb-0"><label className="m-0">IPFS HOST:</label> <div className="pt-2 mb-0"><label className="m-0">IPFS HOST:</label>
<div className="text-secondary mb-0 h6"> <div className="text-secondary mb-0 h6">
<input placeholder='e.g. ipfs.infura.io' id="settingsIpfsUrl" data-id="settingsIpfsUrl" className="form-control" onChange={handleSaveIpfsUrl} value={ ipfsUrl } /> <input placeholder='e.g. ipfs.infura.io' id="settingsIpfsUrl" data-id="settingsIpfsUrl" className="form-control" onChange={handleSaveIpfsUrl} value={ ipfsUrl } />
</div>
</div> </div>
</div> <div className="pt-2 mb-0 pb-0"><label className="m-0">IPFS PROTOCOL:</label>
<div className="pt-2 mb-0 pb-0"><label className="m-0">IPFS PROTOCOL:</label> <div className="text-secondary mb-0 h6">
<div className="text-secondary mb-0 h6"> <input placeholder='e.g. https' id="settingsIpfsProtocol" data-id="settingsIpfsProtocol" className="form-control" onChange={handleSaveIpfsProtocol} value={ ipfsProtocol } />
<input placeholder='e.g. https' id="settingsIpfsProtocol" data-id="settingsIpfsProtocol" className="form-control" onChange={handleSaveIpfsProtocol} value={ ipfsProtocol } /> </div>
</div> </div>
</div> <div className="pt-2 mb-0 pb-0"><label className="m-0">IPFS PORT:</label>
<div className="pt-2 mb-0 pb-0"><label className="m-0">IPFS PORT:</label> <div className="text-secondary mb-0 h6">
<div className="text-secondary mb-0 h6"> <input placeholder='e.g. 5001' id="settingsIpfsPort" data-id="settingsIpfsPort" className="form-control" onChange={handleSaveIpfsPort} value={ ipfsPort } />
<input placeholder='e.g. 5001' id="settingsIpfsPort" data-id="settingsIpfsPort" className="form-control" onChange={handleSaveIpfsPort} value={ ipfsPort } /> </div>
</div> </div>
</div> <div className="pt-2 mb-0 pb-0"><label className="m-0">IPFS PROJECT ID [ INFURA ]:</label>
<div className="pt-2 mb-0 pb-0"><label className="m-0">IPFS PROJECT ID [ INFURA ]:</label> <div className="text-secondary mb-0 h6">
<div className="text-secondary mb-0 h6"> <input id="settingsIpfsProjectId" data-id="settingsIpfsProjectId" className="form-control" onChange={handleSaveIpfsProjectId} value={ ipfsProjectId } />
<input id="settingsIpfsProjectId" data-id="settingsIpfsProjectId" className="form-control" onChange={handleSaveIpfsProjectId} value={ ipfsProjectId } /> </div>
</div> </div>
</div> <div className="pt-2 mb-0 pb-0"><label className="m-0">IPFS PROJECT SECRET [ INFURA ]:</label>
<div className="pt-2 mb-0 pb-0"><label className="m-0">IPFS PROJECT SECRET [ INFURA ]:</label> <div className="text-secondary mb-0 h6">
<div className="text-secondary mb-0 h6"> <input id="settingsIpfsProjectSecret" data-id="settingsIpfsProjectSecret" className="form-control" type="password" onChange={handleSaveIpfsSecret} value={ ipfsProjectSecret } />
<input id="settingsIpfsProjectSecret" data-id="settingsIpfsProjectSecret" className="form-control" type="password" onChange={handleSaveIpfsSecret} value={ ipfsProjectSecret } /> </div>
</div>
<div className="d-flex justify-content-end pt-2">
<input className="btn btn-sm btn-primary ml-2" id="saveIpfssettings" data-id="settingsTabSaveIpfsSettings" onClick={() => saveIpfsSettings()} value={intl.formatMessage({ id: 'settings.save' })} type="button"></input>
</div> </div>
</div> </div>
<div className="d-flex justify-content-end pt-2"> </div>)
<input className="btn btn-sm btn-primary ml-2" id="saveIpfssettings" data-id="settingsTabSaveIpfsSettings" onClick={() => saveIpfsSettings()} value={intl.formatMessage({ id: 'settings.save' })} type="button"></input>
</div>
</div>
</div>)
return ( return (

@ -47,89 +47,89 @@ export const initialState = {
export const settingReducer = (state, action) => { export const settingReducer = (state, action) => {
switch (action.type) { switch (action.type) {
case 'contractMetadata': case 'contractMetadata':
state.elementState.map(element => { state.elementState.map(element => {
if (element.name === 'contractMetadata') { if (element.name === 'contractMetadata') {
element.isChecked = action.payload.isChecked element.isChecked = action.payload.isChecked
element.textClass = action.payload.textClass element.textClass = action.payload.textClass
}
})
return {
...state
} }
case 'ethereumVM': })
state.elementState.map(element => { return {
if (element.name === 'ethereumVM') { ...state
element.isChecked = action.payload.isChecked }
element.textClass = action.payload.textClass case 'ethereumVM':
} state.elementState.map(element => {
}) if (element.name === 'ethereumVM') {
return { element.isChecked = action.payload.isChecked
...state element.textClass = action.payload.textClass
} }
case 'textWrap': })
state.elementState.map(element => { return {
if (element.name === 'textWrap') { ...state
element.isChecked = action.payload.isChecked }
element.textClass = action.payload.textClass case 'textWrap':
} state.elementState.map(element => {
}) if (element.name === 'textWrap') {
return { element.isChecked = action.payload.isChecked
...state element.textClass = action.payload.textClass
} }
case 'personal': })
state.elementState.map(element => { return {
if (element.name === 'personal') { ...state
element.isChecked = action.payload.isChecked }
element.textClass = action.payload.textClass case 'personal':
} state.elementState.map(element => {
}) if (element.name === 'personal') {
return { element.isChecked = action.payload.isChecked
...state element.textClass = action.payload.textClass
} }
case 'useMatomoAnalytics': })
state.elementState.map(element => { return {
if (element.name === 'useMatomoAnalytics') { ...state
element.isChecked = action.payload.isChecked }
element.textClass = action.payload.textClass case 'useMatomoAnalytics':
} state.elementState.map(element => {
}) if (element.name === 'useMatomoAnalytics') {
return { element.isChecked = action.payload.isChecked
...state element.textClass = action.payload.textClass
} }
})
return {
...state
}
case 'useAutoCompletion': case 'useAutoCompletion':
state.elementState.map(element => { state.elementState.map(element => {
if (element.name === 'useAutoCompletion') { if (element.name === 'useAutoCompletion') {
element.isChecked = action.payload.isChecked element.isChecked = action.payload.isChecked
element.textClass = action.payload.textClass element.textClass = action.payload.textClass
}
})
return {
...state
} }
case 'displayErrors': })
state.elementState.map(element => { return {
if (element.name === 'displayErrors') { ...state
element.isChecked = action.payload.isChecked }
element.textClass = action.payload.textClass case 'displayErrors':
} state.elementState.map(element => {
}) if (element.name === 'displayErrors') {
return { element.isChecked = action.payload.isChecked
...state element.textClass = action.payload.textClass
} }
case 'useShowGasInEditor': })
state.elementState.map(element => { return {
if (element.name === 'useShowGasInEditor') { ...state
element.isChecked = action.payload.isChecked }
element.textClass = action.payload.textClass case 'useShowGasInEditor':
} state.elementState.map(element => {
}) if (element.name === 'useShowGasInEditor') {
return { element.isChecked = action.payload.isChecked
...state element.textClass = action.payload.textClass
} }
default: })
return initialState return {
...state
}
default:
return initialState
} }
} }
@ -140,11 +140,11 @@ export const toastInitialState = {
export const toastReducer = (state, action) => { export const toastReducer = (state, action) => {
switch (action.type) { switch (action.type) {
case 'save' : case 'save' :
return { ...state, message: action.payload.message } return { ...state, message: action.payload.message }
case 'removed' : case 'removed' :
return { ...state, message: action.payload.message } return { ...state, message: action.payload.message }
default : default :
return { ...state, message: '' } return { ...state, message: '' }
} }
} }

@ -179,21 +179,21 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
useEffect(() => { useEffect(() => {
if (compilerContainer.compiler.mode) { if (compilerContainer.compiler.mode) {
switch (compilerContainer.compiler.mode) { switch (compilerContainer.compiler.mode) {
case 'startingCompilation': case 'startingCompilation':
startingCompilation() startingCompilation()
break break
case 'compilationDuration': case 'compilationDuration':
compilationDuration(compilerContainer.compiler.args[0]) compilationDuration(compilerContainer.compiler.args[0])
break break
case 'loadingCompiler': case 'loadingCompiler':
loadingCompiler() loadingCompiler()
break break
case 'compilerLoaded': case 'compilerLoaded':
compilerLoaded(compilerContainer.compiler.args[1]) compilerLoaded(compilerContainer.compiler.args[1])
break break
case 'compilationFinished': case 'compilationFinished':
compilationFinished() compilationFinished()
break break
} }
} }
}, [compilerContainer.compiler.mode]) }, [compilerContainer.compiler.mode])
@ -201,14 +201,14 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
useEffect(() => { useEffect(() => {
if (compilerContainer.editor.mode) { if (compilerContainer.editor.mode) {
switch (compilerContainer.editor.mode) { switch (compilerContainer.editor.mode) {
case 'sessionSwitched': case 'sessionSwitched':
sessionSwitched() sessionSwitched()
resetEditorMode()(dispatch) resetEditorMode()(dispatch)
break break
case 'contentChanged': case 'contentChanged':
contentChanged() contentChanged()
resetEditorMode()(dispatch) resetEditorMode()(dispatch)
break break
} }
} }
}, [compilerContainer.editor.mode]) }, [compilerContainer.editor.mode])
@ -800,8 +800,8 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
tooltipClasses="text-nowrap" tooltipClasses="text-nowrap"
tooltipId="overlay-tooltip-hardhat" tooltipId="overlay-tooltip-hardhat"
tooltipText={<span className="border bg-light text-dark p-1 pr-3" style={{ minWidth: '230px' }}> tooltipText={<span className="border bg-light text-dark p-1 pr-3" style={{ minWidth: '230px' }}>
<FormattedMessage id='solidity.learnHardhat' /> <FormattedMessage id='solidity.learnHardhat' />
</span>} </span>}
> >
<i style={{ fontSize: 'medium' }} className={'ml-2 fal fa-info-circle'} aria-hidden="true"></i> <i style={{ fontSize: 'medium' }} className={'ml-2 fal fa-info-circle'} aria-hidden="true"></i>
</CustomTooltip> </CustomTooltip>
@ -821,8 +821,8 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
tooltipClasses="text-nowrap" tooltipClasses="text-nowrap"
tooltipId="overlay-tooltip-truffle" tooltipId="overlay-tooltip-truffle"
tooltipText={<span className="border bg-light text-dark p-1 pr-3" style={{ minWidth: '230px' }}> tooltipText={<span className="border bg-light text-dark p-1 pr-3" style={{ minWidth: '230px' }}>
<FormattedMessage id='solidity.learnTruffle' /> <FormattedMessage id='solidity.learnTruffle' />
</span>} </span>}
> >
<i style={{ fontSize: 'medium' }} className={'ml-2 fal fa-info-circle'} aria-hidden="true"></i> <i style={{ fontSize: 'medium' }} className={'ml-2 fal fa-info-circle'} aria-hidden="true"></i>
</CustomTooltip> </CustomTooltip>
@ -904,18 +904,18 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
</div> </div>
<div className={`pt-2 ml-4 ml-2 align-items-start justify-content-between d-flex`}> <div className={`pt-2 ml-4 ml-2 align-items-start justify-content-between d-flex`}>
{(!showFilePathInput && state.useFileConfiguration) && <CustomTooltip {(!showFilePathInput && state.useFileConfiguration) && <CustomTooltip
placement="bottom" placement="bottom"
tooltipId="configfileTooltip" tooltipId="configfileTooltip"
tooltipClasses="text-nowrap" tooltipClasses="text-nowrap"
tooltipText={<span> tooltipText={<span>
Click to open the config file Click to open the config file
</span>} </span>}
> >
<span <span
onClick={configFilePath === '' ? () => { } : async () => { await openFile() }} onClick={configFilePath === '' ? () => { } : async () => { await openFile() }}
className="py-2 remixui_compilerConfigPath" className="py-2 remixui_compilerConfigPath"
>{configFilePath === '' ? 'No file selected.' : configFilePath}</span> >{configFilePath === '' ? 'No file selected.' : configFilePath}</span>
</CustomTooltip>} </CustomTooltip>}
{(!showFilePathInput && !state.useFileConfiguration) && <span className="py-2 text-secondary">{configFilePath}</span>} {(!showFilePathInput && !state.useFileConfiguration) && <span className="py-2 text-secondary">{configFilePath}</span>}
<input <input
ref={configFilePathInput} ref={configFilePathInput}
@ -941,9 +941,9 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
placement="auto" placement="auto"
tooltipId="overlay-tooltip-compile" tooltipId="overlay-tooltip-compile"
tooltipText={<div className="text-left"> tooltipText={<div className="text-left">
{!(configFilePath === '' && state.useFileConfiguration) && <div><b>Ctrl+S</b> to compile {state.compiledFileName.endsWith('.sol') ? state.compiledFileName : null} </div>} {!(configFilePath === '' && state.useFileConfiguration) && <div><b>Ctrl+S</b> to compile {state.compiledFileName.endsWith('.sol') ? state.compiledFileName : null} </div>}
{(configFilePath === '' && state.useFileConfiguration) && <div> No config file selected</div>} {(configFilePath === '' && state.useFileConfiguration) && <div> No config file selected</div>}
</div>} </div>}
> >
<div className="d-flex align-items-center justify-content-center"> <div className="d-flex align-items-center justify-content-center">
{ <i ref={compileIcon} className="fas fa-sync mr-2" aria-hidden="true"></i> } { <i ref={compileIcon} className="fas fa-sync mr-2" aria-hidden="true"></i> }
@ -959,8 +959,8 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
id: 'solidity.noFileSelected', id: 'solidity.noFileSelected',
})}>` })}>`
: `<${intl.formatMessage({ : `<${intl.formatMessage({
id: 'solidity.noFileSelected', id: 'solidity.noFileSelected',
})}>`} })}>`}
</span> </span>
</div> </div>
</div> </div>

@ -47,7 +47,7 @@ export class CompileTabLogic {
this.evmVersion === 'null' || this.evmVersion === 'null' ||
!this.evmVersion || !this.evmVersion ||
!this.evmVersions.includes(this.evmVersion)) { !this.evmVersions.includes(this.evmVersion)) {
this.evmVersion = null this.evmVersion = null
} }
this.api.setCompilerParameters({ evmVersion: this.evmVersion }) this.api.setCompilerParameters({ evmVersion: this.evmVersion })
this.compiler.set('evmVersion', this.evmVersion) this.compiler.set('evmVersion', this.evmVersion)

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save