diff --git a/apps/remix-ide-e2e/src/tests/erc721.test.ts b/apps/remix-ide-e2e/src/tests/erc721.test.ts index 550508358a..d88e3dae9b 100644 --- a/apps/remix-ide-e2e/src/tests/erc721.test.ts +++ b/apps/remix-ide-e2e/src/tests/erc721.test.ts @@ -14,7 +14,8 @@ module.exports = { }, 'Deploy SampleERC721 whose bytecode is very similar to ERC721': function (browser: NightwatchBrowser) { browser.clickLaunchIcon('filePanel') - .click('*[data-id="workspaceCreate"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') // create contract .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') diff --git a/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts b/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts index 17e340cd2d..18295838cd 100644 --- a/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts +++ b/apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts @@ -178,7 +178,8 @@ module.exports = { .click('*[data-id="testTabGenerateTestFolder"]') .clickLaunchIcon('filePanel') // creating a new workspace - .click('*[data-id="workspaceCreate"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') .click('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]') .setValue('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_new') diff --git a/apps/remix-ide-e2e/src/tests/workspace.test.ts b/apps/remix-ide-e2e/src/tests/workspace.test.ts index a5b0fe7ca8..09fe9057fe 100644 --- a/apps/remix-ide-e2e/src/tests/workspace.test.ts +++ b/apps/remix-ide-e2e/src/tests/workspace.test.ts @@ -36,7 +36,8 @@ module.exports = { 'Should create Remix default workspace with files #group1': function (browser: NightwatchBrowser) { browser .clickLaunchIcon('filePanel') - .click('*[data-id="workspaceCreate"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') // eslint-disable-next-line dot-notation @@ -107,7 +108,8 @@ module.exports = { 'Should create blank workspace with no files #group1': function (browser: NightwatchBrowser) { browser - .click('*[data-id="workspaceCreate"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') // eslint-disable-next-line dot-notation @@ -129,7 +131,8 @@ module.exports = { 'Should create ERC20 workspace with files #group1': function (browser: NightwatchBrowser) { browser - .click('*[data-id="workspaceCreate"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') // eslint-disable-next-line dot-notation @@ -189,7 +192,8 @@ module.exports = { 'Should create ERC721 workspace with files #group1': function (browser: NightwatchBrowser) { browser - .click('*[data-id="workspaceCreate"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') // eslint-disable-next-line dot-notation @@ -249,7 +253,8 @@ module.exports = { 'Should create ERC1155 workspace with files #group1': function (browser: NightwatchBrowser) { browser - .click('*[data-id="workspaceCreate"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') // eslint-disable-next-line dot-notation @@ -309,7 +314,8 @@ module.exports = { 'Should create ERC1155 workspace with template customizations #group1': function (browser: NightwatchBrowser) { browser - .click('*[data-id="workspaceCreate"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') .click('select[id="wstemplate"]') @@ -381,7 +387,8 @@ module.exports = { 'Should create two workspace and switch to the first one #group1': function (browser: NightwatchBrowser) { browser - .click('*[data-id="workspaceCreate"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') .click('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]') .setValue('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_name') @@ -394,7 +401,8 @@ module.exports = { selector: "//div[contains(@class, 'view-line') and contains(.//span, 'test')]", locateStrategy: 'xpath' }) - .click('*[data-id="workspaceCreate"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') .click('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]') .setValue('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_name_1') @@ -449,7 +457,8 @@ module.exports = { 'Should create workspace for test #group2': function (browser: NightwatchBrowser) { browser .clickLaunchIcon('filePanel') - .click('*[data-id="workspaceCreate"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') .click('select[id="wstemplate"]') @@ -475,7 +484,8 @@ module.exports = { 'Should create workspace for next test #group2': function (browser: NightwatchBrowser) { browser - .click('*[data-id="workspaceCreate"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') // eslint-disable-next-line dot-notation diff --git a/apps/remix-ide-e2e/src/tests/workspace_git.test.ts b/apps/remix-ide-e2e/src/tests/workspace_git.test.ts index e4f95a67ea..6bc35fe9d4 100644 --- a/apps/remix-ide-e2e/src/tests/workspace_git.test.ts +++ b/apps/remix-ide-e2e/src/tests/workspace_git.test.ts @@ -11,7 +11,8 @@ module.exports = { 'Should not be able to create GIT without credentials #group1': function (browser: NightwatchBrowser) { browser .clickLaunchIcon('filePanel') - .click('*[data-id="workspaceCreate"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') .waitForElementVisible({ @@ -43,7 +44,8 @@ module.exports = { browser .clickLaunchIcon('filePanel') .waitForElementNotVisible('[data-id="workspaceGitPanel"]') - .click('*[data-id="workspaceCreate"]') + .click('*[data-id="workspacesMenuDropdown"]') + .click('*[data-id="workspacecreate"]') .waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]') .waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button') // eslint-disable-next-line dot-notation diff --git a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json index e1dd413634..c241f23f60 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/filePanel.json +++ b/apps/remix-ide/src/app/tabs/locales/en/filePanel.json @@ -27,8 +27,14 @@ "filePanel.solghaction": "Solidity Test Workflow", "filePanel.workspace.tssoltestghaction": "Adds a preset yml file to run mocha and chai tests for solidity on github actions CI", "filePanel.tssoltestghaction": "Mocha Chai Test Workflow", + "filePanel.workspace.addscriptetherscan": "Adds a scripts which can be used to interact with the etherscan API.", + "filePanel.addscriptetherscan": "Add Etherscan script", + "filePanel.workspace.addscriptdeployer": "Adds a scripts which can be used to deploy contracts.", + "filePanel.addscriptdeployer": "Add Contract deployer script", "filePanel.workspace.slitherghaction": "Adds a preset yml file to run slither analysis on github actions CI", "filePanel.slitherghaction": "Slither Workflow", + "filePanel.workspace.helperscripts": "Adds convenient scripts to the 'scripts' directory", + "filePanel.helperscripts": "Web3 Scripts", "filePanel.newFile": "New File", "filePanel.newFolder": "New Folder", "filePanel.rename": "Rename", diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts index 0e23965cdb..b59e756ac0 100644 --- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts +++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts @@ -13,6 +13,7 @@ import { ROOT_PATH, slitherYml, solTestYml, tsSolTestYml } from '../utils/consta import { IndexedDBStorage } from '../../../../../../apps/remix-ide/src/app/files/filesystems/indexedDB' import { getUncommittedFiles } from '../utils/gitStatusFilter' import { AppModal, ModalTypes } from '@remix-ui/app' +import { scripts } from '../scripts' declare global { interface Window { remixFileSystemCallback: IndexedDBStorage; } @@ -677,6 +678,12 @@ export const createSlitherGithubAction = async () => { plugin.call('fileManager', 'open', path) } +export const createHelperScripts = async (script: string) => { + if (!scripts[script]) return + await scripts[script](plugin) + plugin.call('notification', 'toast', 'scripts added in the "scripts" folder') +} + export const checkoutRemoteBranch = async (branch: string, remote: string) => { const localChanges = await hasLocalChanges() diff --git a/libs/remix-ui/workspace/src/lib/components/workspace-hamburger-item.tsx b/libs/remix-ui/workspace/src/lib/components/workspace-hamburger-item.tsx index 082746eec5..9651c94c09 100644 --- a/libs/remix-ui/workspace/src/lib/components/workspace-hamburger-item.tsx +++ b/libs/remix-ui/workspace/src/lib/components/workspace-hamburger-item.tsx @@ -1,6 +1,6 @@ import React from 'react' -import { CustomTooltip } from '@remix-ui/helper' -import { Dropdown } from 'react-bootstrap' +import { CustomTooltip, CustomMenu, CustomIconsToggle } from '@remix-ui/helper' +import { Dropdown, NavDropdown} from 'react-bootstrap' import { FormattedMessage } from 'react-intl' const _paq = window._paq = window._paq || [] @@ -48,4 +48,66 @@ export function HamburgerMenuItem (props: HamburgerMenuItemProps) { ) + } + + // keeping the following for a later use: + export function NavHamburgerMenuItem (props: HamburgerMenuItemProps) { + const { hideOption } = props + const uid = 'workspace' + props.kind + return ( + <> + + } + > +
{ + props.actionOnClick() + _paq.push(['trackEvent', 'fileExplorer', 'workspaceMenu', uid]) + }} + > + + + + +
+
+
+ + ) + } + + export interface HamburgerSubMenuItemProps { + id: string + title: string + subMenus: Array + } + + export function HamburgerSubMenuItem (props: HamburgerSubMenuItemProps) { + return ( + <> + + {props.subMenus.map(item => )} + + + ) } \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx b/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx index 9941dee29a..bf00c5aa56 100644 --- a/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx +++ b/libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx @@ -1,6 +1,6 @@ import React from 'react' import { Dropdown } from 'react-bootstrap' -import { HamburgerMenuItem } from './workspace-hamburger-item' +import { HamburgerMenuItem, HamburgerSubMenuItem } from './workspace-hamburger-item' export interface HamburgerMenuProps { createWorkspace: () => void, @@ -15,6 +15,7 @@ export interface HamburgerMenuProps { addGithubAction: () => void, addTsSolTestGithubAction: () => void, addSlitherGithubAction: () => void, + addHelperScripts: (script: string) => void, showIconsMenu: boolean, hideWorkspaceOptions: boolean, hideLocalhostOptions: boolean @@ -70,6 +71,44 @@ export function HamburgerMenu (props: HamburgerMenuProps) { props.addSlitherGithubAction() props.hideIconsMenu(!showIconsMenu) }}> + + { + props.addHelperScripts('etherscan') + props.hideIconsMenu(!showIconsMenu) + }}> + { + props.addHelperScripts('deployer') + props.hideIconsMenu(!showIconsMenu) + }}> ) - } \ No newline at end of file + } + + // keep for later use + /* { + alert('etherscan') + props.addHelperScripts() + props.hideIconsMenu(!showIconsMenu) + } + }, + { + kind:'contract-deployer-factory-script', + fa: 'fak fa-ts-logo', + hideOption: hideWorkspaceOptions, + actionOnClick: () => { + alert('deloyer') + props.addHelperScripts() + props.hideIconsMenu(!showIconsMenu) + } + } + ]} + > + */ \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/contexts/index.ts b/libs/remix-ui/workspace/src/lib/contexts/index.ts index 44783948be..3423323a90 100644 --- a/libs/remix-ui/workspace/src/lib/contexts/index.ts +++ b/libs/remix-ui/workspace/src/lib/contexts/index.ts @@ -45,6 +45,7 @@ export const FileSystemContext = createContext<{ dispatchCreateSolidityGithubAction: () => Promise, dispatchCreateTsSolGithubAction: () => Promise, dispatchCreateSlitherGithubAction: () => Promise + dispatchCreateHelperScripts: (script: string) => Promise }>(null) \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx index ae038142a7..29399275e1 100644 --- a/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx +++ b/libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx @@ -8,7 +8,7 @@ import { browserReducer, browserInitialState } from '../reducers/workspace' import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, deleteAllWorkspaces, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder, deletePath, renamePath, downloadPath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace, fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, uploadFolder, handleDownloadWorkspace, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder, - showAllBranches, switchBranch, createNewBranch, checkoutRemoteBranch, createSolidityGithubAction, createTsSolGithubAction, createSlitherGithubAction + showAllBranches, switchBranch, createNewBranch, checkoutRemoteBranch, createSolidityGithubAction, createTsSolGithubAction, createSlitherGithubAction, createHelperScripts } from '../actions' import { Modal, WorkspaceProps, WorkspaceTemplate } from '../types' // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -183,6 +183,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => { await createSlitherGithubAction() } + const dispatchCreateHelperScripts = async (script: string) => { + await createHelperScripts(script) + } + useEffect(() => { dispatchInitWorkspace() }, []) @@ -299,7 +303,8 @@ export const FileSystemProvider = (props: WorkspaceProps) => { dispatchCheckoutRemoteBranch, dispatchCreateSolidityGithubAction, dispatchCreateTsSolGithubAction, - dispatchCreateSlitherGithubAction + dispatchCreateSlitherGithubAction, + dispatchCreateHelperScripts } return ( diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx index de26194620..648206b32b 100644 --- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx +++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx @@ -209,6 +209,10 @@ export function Workspace () { global.dispatchCreateSlitherGithubAction() } + const addHelperScripts = (script: string) => { + global.dispatchCreateHelperScripts(script) + } + const downloadWorkspaces = async () => { try { await global.dispatchHandleDownloadFiles() @@ -677,65 +681,45 @@ export function Workspace () {
-
-
- - - - {currentWorkspace !== LOCALHOST ? ( - } - > - - - hideIconsMenu(!showIconsMenu)} show={showIconsMenu}> - { - hideIconsMenu(!showIconsMenu) - }} - icon={'fas fa-bars'} - > - - - - - ) : null} +
+
+ {currentWorkspace !== LOCALHOST ? ( + hideIconsMenu(!showIconsMenu)} show={showIconsMenu}> + { + hideIconsMenu(!showIconsMenu) + }} + icon={'fas fa-bars'} + > + + + + + ) : null} + + +
- } args list of constructor' parameters + * @param {Number} accountIndex account index from the exposed account + * @return {Contract} deployed contract + */ +export const deploy = async (contractName: string, args: Array, accountIndex?: number): Promise => { + + console.log(`deploying ${contractName}`) + // Note that the script needs the ABI which is generated from the compilation artifact. + // Make sure contract is compiled and artifacts are generated + const artifactsPath = `browser/contracts/artifacts/${contractName}.json` // Change this for different path + + const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath)) + // 'web3Provider' is a remix global variable object + + const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner(accountIndex) + + const factory = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer) + + const contract = await factory.deploy(...args) + + // The contract is NOT deployed yet; we must wait until it is mined + await contract.deployed() + return contract +} \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/scripts/contract-deployer/create2-factory-deploy.ts b/libs/remix-ui/workspace/src/lib/scripts/contract-deployer/create2-factory-deploy.ts new file mode 100644 index 0000000000..13b6d690a7 --- /dev/null +++ b/libs/remix-ui/workspace/src/lib/scripts/contract-deployer/create2-factory-deploy.ts @@ -0,0 +1,258 @@ +import { ethers } from 'ethers' + +// https://etherscan.io/address/0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2#code +export const CREATE2_DEPLOYER_ADDRESS = + "0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2"; + +/** + * Deploy the given contract using a factory + * @param {string} address of the factory contract + * @param {string} contractName name of the contract to deploy + * @param {Array} args list of constructor' parameters + * @param {number} salt (using during address generation) + * @param {number} accountIndex account index from the exposed account + * @return {string} deployed contract address + */ +export const deploy = async (contractName: string, args: Array, salt: string, accountIndex?: number): Promise => { + + console.log(`deploying ${contractName}`) + + const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner(accountIndex) + + const factory = new ethers.Contract(CREATE2_DEPLOYER_ADDRESS, contractDeployerAbi, signer); + + const contract = await ethers.getContractFactory(contractName) + const initCode = contract.getDeployTransaction(args) + + const codeHash = ethers.utils.keccak256(initCode.data) + const saltBytes = ethers.utils.id(salt) + const deployedAddress = await factory.computeAddress(saltBytes, codeHash) + try { + const tx = await factory.deploy(0, saltBytes, initCode.data) + await tx.wait() + return deployedAddress + } catch (e) { + console.error(e.message) + console.error(`Please check a contract isn't already deployed at that address`) + throw e + } +} + +export const contractDeployerAbi = [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "codeHash", + "type": "bytes32" + } + ], + "name": "computeAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "codeHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "deployer", + "type": "address" + } + ], + "name": "computeAddressWithDeployer", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "code", + "type": "bytes" + } + ], + "name": "deploy", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "name": "deployERC1820Implementer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "payoutAddress", + "type": "address" + } + ], + "name": "killCreate2Deployer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/scripts/contract-deployer/index.ts b/libs/remix-ui/workspace/src/lib/scripts/contract-deployer/index.ts new file mode 100644 index 0000000000..0fbeeb1f48 --- /dev/null +++ b/libs/remix-ui/workspace/src/lib/scripts/contract-deployer/index.ts @@ -0,0 +1,11 @@ +export const contractDeployerScripts = async (plugin) => { + await plugin.call('fileManager', 'writeFile', + 'scripts/contract-deployer/create2-factory-deploy.ts' , + // @ts-ignore + (await import('!!raw-loader!./create2-factory-deploy.ts')).default) + + await plugin.call('fileManager', 'writeFile', + 'scripts/contract-deployer/basic-contract-deploy.ts' , + // @ts-ignore + (await import('!!raw-loader!./basic-contract-deploy.ts')).default) +} \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/scripts/etherscan/index.ts b/libs/remix-ui/workspace/src/lib/scripts/etherscan/index.ts new file mode 100644 index 0000000000..34000b7ca2 --- /dev/null +++ b/libs/remix-ui/workspace/src/lib/scripts/etherscan/index.ts @@ -0,0 +1,11 @@ +export const etherscanScripts = async (plugin) => { + await plugin.call('fileManager', 'writeFile', + 'scripts/etherscan/verifyScript.ts' , + // @ts-ignore + (await import('!!raw-loader!./verifyScript.ts')).default) + + await plugin.call('fileManager', 'writeFile', + 'scripts/etherscan/receiptGuidScript.ts' , + // @ts-ignore + (await import('!!raw-loader!./receiptGuidScript.ts')).default) +} \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/scripts/etherscan/receiptGuidScript.ts b/libs/remix-ui/workspace/src/lib/scripts/etherscan/receiptGuidScript.ts new file mode 100644 index 0000000000..a09a9fb780 --- /dev/null +++ b/libs/remix-ui/workspace/src/lib/scripts/etherscan/receiptGuidScript.ts @@ -0,0 +1,8 @@ +/** + * @param {string} apikey - etherscan api key. + * @param {string} guid - receipt id. + * @returns {{ status, message, succeed }} receiptStatus + */ +export const receiptStatus = async (apikey: string, guid: string) => { + return await remix.call('etherscan' as any, 'receiptStatus', guid, apikey) +} \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/scripts/etherscan/verifyScript.ts b/libs/remix-ui/workspace/src/lib/scripts/etherscan/verifyScript.ts new file mode 100644 index 0000000000..3531595239 --- /dev/null +++ b/libs/remix-ui/workspace/src/lib/scripts/etherscan/verifyScript.ts @@ -0,0 +1,13 @@ +/** + * @param {string} apikey - etherscan api key. + * @param {string} contractAddress - Address of the contract to verify. + * @param {string} contractArguments - Parameters used in the contract constructor during the initial deployment. It should be the hex encoded value. + * @param {string} contractName - Name of the contract + * @param {string} contractFile - File where the contract is located + * @returns {{ guid, status, message, succeed }} verification result + */ +export const verify = async (apikey: string, contractAddress: string, contractArguments: string, contractName: string, contractFile: string) => { + const compilationResultParam = await remix.call('compilerArtefacts' as any, 'getCompilerAbstract', contractFile) + console.log('verifying.. ' + contractName) + return await remix.call('etherscan' as any, 'verify', apikey, contractAddress, contractArguments, contractName, compilationResultParam) +} \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/scripts/index.ts b/libs/remix-ui/workspace/src/lib/scripts/index.ts new file mode 100644 index 0000000000..4f2c005e98 --- /dev/null +++ b/libs/remix-ui/workspace/src/lib/scripts/index.ts @@ -0,0 +1,7 @@ +import { contractDeployerScripts } from '../scripts/contract-deployer' +import { etherscanScripts } from '../scripts/etherscan' + +export const scripts = { + 'etherscan': etherscanScripts, + 'deployer': contractDeployerScripts +} \ No newline at end of file