add_templates

fix E2E
pull/5042/head
yann300 6 months ago committed by Aniket
parent 3bbedd600d
commit 2ac386a2f4
  1. 2
      apps/etherscan/src/app/views/VerifyView.tsx
  2. 2
      apps/remix-ide-e2e/src/tests/ballot.test.ts
  3. 12
      apps/remix-ide-e2e/src/tests/circom.test.ts
  4. 4
      apps/remix-ide-e2e/src/tests/erc721.test.ts
  5. 2
      apps/remix-ide-e2e/src/tests/solidityUnittests.test.ts
  6. 47
      apps/remix-ide-e2e/src/tests/workspace.test.ts
  7. 8
      apps/remix-ide-e2e/src/tests/workspace_git.test.ts
  8. 7
      apps/remix-ide/src/app.js
  9. 2
      apps/remix-ide/src/app/panels/file-panel.js
  10. 473
      apps/remix-ide/src/app/plugins/templates-selection.tsx
  11. 14
      libs/remix-ui/workspace/src/lib/actions/events.ts
  12. 42
      libs/remix-ui/workspace/src/lib/actions/workspace.ts
  13. 41
      libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx
  14. 203
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
  15. 18
      libs/remix-ui/workspace/src/lib/utils/constants.ts
  16. 2
      libs/remix-ws-templates/src/script-templates/contract-deployer/index.ts
  17. 2
      libs/remix-ws-templates/src/script-templates/create2-solidity-factory/index.ts
  18. 2
      libs/remix-ws-templates/src/script-templates/etherscan/index.ts
  19. 2
      libs/remix-ws-templates/src/script-templates/sindri/index.ts

@ -211,7 +211,7 @@ export const VerifyView = ({apiKey, client, contracts, onVerifiedContract, netwo
type="button"
className="mr-2 mb-2 py-1 px-2 btn btn-secondary btn-block"
onClick={async () => {
etherscanScripts(client)
etherscanScripts({}, client)
}}
>
Generate Verification Scripts

@ -97,6 +97,8 @@ module.exports = {
.clickLaunchIcon('filePanel')
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-remixDefault"]')
.scrollAndClick('*[data-id="create-remixDefault"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
// eslint-disable-next-line dot-notation

@ -13,10 +13,8 @@ module.exports = {
.clickLaunchIcon('filePanel')
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=semaphore]')
.waitForElementPresent('*[data-id="create-semaphore"]')
.scrollAndClick('*[data-id="create-semaphore"]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(100)
@ -155,10 +153,8 @@ module.exports = {
.clickLaunchIcon('filePanel')
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=hashchecker]')
.waitForElementPresent('*[data-id="create-hashchecker"]')
.scrollAndClick('*[data-id="create-hashchecker"]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(100)

@ -17,12 +17,12 @@ module.exports = {
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
// create contract
.waitForElementPresent('*[data-id="create-hashchecker"]')
.scrollAndClick('*[data-id="create-hashchecker"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
// eslint-disable-next-line dot-notation
.execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_erc721' })
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=ozerc721]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(100)

@ -180,6 +180,8 @@ module.exports = {
// creating a new workspace
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-remixDefault"]')
.scrollAndClick('*[data-id="create-remixDefault"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.click('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]')
.setValue('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_new')

@ -38,6 +38,8 @@ module.exports = {
.clickLaunchIcon('filePanel')
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-remixDefault"]')
.scrollAndClick('*[data-id="create-remixDefault"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
// eslint-disable-next-line dot-notation
@ -110,12 +112,12 @@ module.exports = {
browser
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-blank"]')
.scrollAndClick('*[data-id="create-blank"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
// eslint-disable-next-line dot-notation
.execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_blank' })
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=blank]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(100)
@ -133,12 +135,12 @@ module.exports = {
browser
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-ozerc20"]')
.scrollAndClick('*[data-id="create-ozerc20"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
// eslint-disable-next-line dot-notation
.execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_erc20' })
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=ozerc20]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(100)
@ -194,12 +196,12 @@ module.exports = {
browser
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-ozerc721"]')
.scrollAndClick('*[data-id="create-ozerc721"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
// eslint-disable-next-line dot-notation
.execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_erc721' })
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=ozerc721]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(100)
@ -255,12 +257,12 @@ module.exports = {
browser
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-ozerc1155"]')
.scrollAndClick('*[data-id="create-ozerc1155"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
// eslint-disable-next-line dot-notation
.execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_erc1155' })
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=ozerc1155]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(100)
@ -316,15 +318,10 @@ module.exports = {
browser
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-ozerc1155-{"upgradeable":"uups","mintable":true,"burnable":true,"pausable":true}"]')
.scrollAndClick('*[data-id="create-ozerc1155-{"upgradeable":"uups","mintable":true,"burnable":true,"pausable":true}')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=ozerc1155]')
.waitForElementPresent('*[data-id="ozCustomization"]')
.click('*[data-id="featureTypeMintable"]')
.click('*[data-id="featureTypeBurnable"]')
.click('*[data-id="featureTypePausable"]')
.click('*[data-id="upgradeTypeUups"]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(100)
@ -386,10 +383,10 @@ module.exports = {
browser
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-hashchecker"]')
.scrollAndClick('*[data-id="create-hashchecker"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=hashchecker]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(100)
@ -424,6 +421,8 @@ module.exports = {
browser
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-remixDefault"]')
.scrollAndClick('*[data-id="create-remixDefault"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.click('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]')
.setValue('*[data-id="fileSystemModalDialogContainer-react"] input[data-id="modalDialogCustomPromptTextCreate"]', 'workspace_name')
@ -438,6 +437,8 @@ module.exports = {
})
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-remixDefault"]')
.scrollAndClick('*[data-id="create-remixDefault"]')
.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')
@ -494,10 +495,10 @@ module.exports = {
.clickLaunchIcon('filePanel')
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-ozerc1155"]')
.scrollAndClick('*[data-id="create-ozerc1155"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=ozerc1155]')
.execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'sometestworkspace' })
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
@ -521,11 +522,11 @@ module.exports = {
browser
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-ozerc1155"]')
.scrollAndClick('*[data-id="create-ozerc1155"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
// eslint-disable-next-line dot-notation
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=ozerc1155]')
.execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'workspace_db_test' })
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
@ -551,10 +552,10 @@ module.exports = {
.clickLaunchIcon('filePanel')
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-uniswapV4HookBookMultiSigSwapHook"]')
.scrollAndClick('*[data-id="create-uniswapV4HookBookMultiSigSwapHook"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=uniswapV4HookBookMultiSigSwapHook]')
// eslint-disable-next-line dot-notation
.execute(function () { document.querySelector('*[data-id="modalDialogCustomPromptTextCreate"]')['value'] = 'multisig cookbook' })
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')

@ -13,6 +13,8 @@ module.exports = {
.clickLaunchIcon('filePanel')
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-remixDefault"]')
.scrollAndClick('*[data-id="create-remixDefault"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
.waitForElementVisible({
@ -47,6 +49,8 @@ module.exports = {
.waitForElementNotVisible('[data-id="workspaceGitPanel"]')
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-blank"]')
.scrollAndClick('*[data-id="create-blank"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
// eslint-disable-next-line dot-notation
@ -391,10 +395,10 @@ module.exports = {
browser
.click('*[data-id="workspacesMenuDropdown"]')
.click('*[data-id="workspacecreate"]')
.waitForElementPresent('*[data-id="create-uniswapV4Template"]')
.scrollAndClick('*[data-id="create-uniswapV4Template"]')
.waitForElementVisible('*[data-id="modalDialogCustomPromptTextCreate"]')
.waitForElementVisible('[data-id="fileSystemModalDialogModalFooter-react"] > button')
.click('select[id="wstemplate"]')
.click('select[id="wstemplate"] option[value=uniswapV4Template]')
.waitForElementPresent('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok')
.execute(function () { (document.querySelector('[data-id="fileSystemModalDialogModalFooter-react"] .modal-ok') as HTMLElement).click() })
.pause(100)

@ -61,6 +61,8 @@ import { Matomo } from './app/plugins/matomo'
import {SolCoder} from './app/plugins/solcoderAI'
import {TemplatesSelection} from './app/plugins/templates-selection'
const isElectron = require('is-electron')
const remixLib = require('@remix-project/remix-lib')
@ -315,6 +317,8 @@ class AppComponent {
// ----------------- run script after each compilation results -----------
const pluginStateLogger = new PluginStateLogger()
const templateSelection = new TemplatesSelection()
this.engine.register([
permissionHandler,
this.layout,
@ -366,7 +370,8 @@ class AppComponent {
solcoder,
git,
pluginStateLogger,
matomo
matomo,
templateSelection
])
//---- fs plugin

@ -195,7 +195,7 @@ module.exports = class Filepanel extends ViewPlugin {
if (err) reject(err)
else resolve(data || true)
})
})
}, false)
}
renameWorkspace(oldName, workspaceName) {

@ -0,0 +1,473 @@
import React from 'react'
import { FormattedMessage, useIntl } from 'react-intl'
import { AppModal } from '@remix-ui/app'
import { ViewPlugin } from '@remixproject/engine-web'
import { PluginViewWrapper } from '@remix-ui/helper'
import { RemixUIGridView } from '@remix-ui/remix-ui-grid-view'
import { RemixUIGridSection } from '@remix-ui/remix-ui-grid-section'
import { RemixUIGridCell } from '@remix-ui/remix-ui-grid-cell'
import type { TemplateGroup } from '@remix-ui/workspace'
const isElectron = require('is-electron')
//@ts-ignore
const _paq = (window._paq = window._paq || [])
const profile = {
name: 'templateSelection',
displayName: 'Template Selection',
description: 'templateSelection',
location: 'mainPanel',
methods: [],
events: []
}
export class TemplatesSelection extends ViewPlugin {
templates: Array<TemplateGroup>
dispatch: React.Dispatch<any> = () => { }
constructor() {
super(profile)
}
async onActivation() {
this.handleThemeChange()
await this.call('tabs', 'focus', 'remixGuide')
this.renderComponent()
_paq.push(['trackEvent', 'plugin', 'activated', 'remixGuide'])
}
onDeactivation(): void {
}
private handleThemeChange() {
this.on('theme', 'themeChanged', (theme: any) => {
this.renderComponent()
})
}
setDispatch(dispatch: React.Dispatch<any>): void {
this.dispatch = dispatch
this.renderComponent()
}
render() {
return (
<div className="bg-dark" id="remixGuide">
<PluginViewWrapper plugin={this} />
</div>
)
}
renderComponent() {
this.dispatch({
...this,
})
}
updateComponent() {
/*
const opts = {
// @ts-ignore: Object is possibly 'null'.
mintable: mintableCheckboxRef.current.checked,
// @ts-ignore: Object is possibly 'null'.
burnable: burnableCheckboxRef.current.checked,
// @ts-ignore: Object is possibly 'null'.
pausable: pausableCheckboxRef.current.checked,
// @ts-ignore: Object is possibly 'null'.
upgradeable: transparentRadioRef.current.checked ? transparentRadioRef.current.value : uupsRadioRef.current.checked ? uupsRadioRef.current.value : false
}
*/
this.templates = [
{
name: "Generic",
items: [
{ value: "remixDefault", displayName: window._intl.formatMessage({ id: 'filePanel.basic' }) },
{ value: "blank", displayName: window._intl.formatMessage({ id: 'filePanel.blank' }) }
]
},
{
name: "OpenZeppelin",
items: [
{
value: "ozerc20",
displayName: "ERC20"
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)"
},
{
value: "ozerc1155",
displayName: "ERC1155"
},
{
value: "ozerc20",
displayName: "ERC20",
opts: {
mintable: true
}
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)",
opts: {
mintable: true
}
},
{
value: "ozerc1155",
displayName: "ERC1155",
opts: {
mintable: true
}
},
{
value: "ozerc20",
displayName: "ERC20",
opts: {
mintable: true,
burnable: true
}
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)",
opts: {
mintable: true,
burnable: true
}
},
{
value: "ozerc1155",
displayName: "ERC1155",
opts: {
mintable: true,
burnable: true
}
},
{
value: "ozerc20",
displayName: "ERC20",
opts: {
mintable: true,
pausable: true
}
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)",
opts: {
mintable: true,
pausable: true
}
},
{
value: "ozerc1155",
displayName: "ERC1155",
opts: {
mintable: true,
pausable: true
}
}
]
},
{
name: "OpenZeppelin Proxy",
items: [
{
value: "ozerc20",
displayName: "ERC20",
opts: {
upgradeable: 'uups'
}
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)",
opts: {
upgradeable: 'uups'
}
},
{
value: "ozerc1155",
displayName: "ERC1155",
opts: {
upgradeable: 'uups'
}
},
{
value: "ozerc20",
displayName: "ERC20",
opts: {
upgradeable: 'uups',
mintable: true
}
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)",
opts: {
upgradeable: 'uups',
mintable: true
}
},
{
value: "ozerc1155",
displayName: "ERC1155",
opts: {
upgradeable: 'uups',
mintable: true
}
},
{
value: "ozerc20",
displayName: "ERC20",
opts: {
upgradeable: 'uups',
mintable: true,
burnable: true
}
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)",
opts: {
upgradeable: 'uups',
mintable: true,
burnable: true
}
},
{
value: "ozerc1155",
displayName: "ERC1155",
opts: {
upgradeable: 'uups',
mintable: true,
burnable: true
}
},
{
value: "ozerc20",
displayName: "ERC20",
opts: {
upgradeable: 'uups',
mintable: true,
pausable: true
}
},
{
value: "ozerc721",
displayName: "ERC721 (NFT)",
opts: {
upgradeable: 'uups',
mintable: true,
pausable: true
}
},
{
value: "ozerc1155",
displayName: "ERC1155",
opts: {
upgradeable: 'uups',
mintable: true,
pausable: true
}
},
{
value: "ozerc1155",
displayName: "ERC1155",
opts: {
upgradeable: 'uups',
mintable: true,
burnable: true,
pausable: true
}
}
]
},
{
name: "OxProject",
items: [
{ value: "zeroxErc20", displayName: "ERC20" }
]
},
{
name: "Gnosis Safe",
items: [
{ value: "gnosisSafeMultisig", displayName: window._intl.formatMessage({ id: 'filePanel.multiSigWallet' }) }
]
},
{
name: "Circom ZKP",
items: [
{ value: "semaphore", displayName: window._intl.formatMessage({ id: 'filePanel.semaphore' }) },
{ value: "hashchecker", displayName: window._intl.formatMessage({ id: 'filePanel.hashchecker' }) },
{ value: "rln", displayName: window._intl.formatMessage({ id: 'filePanel.rln' }) }
]
},
{
name: "Generic ZKP",
items: [
{ value: "sindriScripts", displayName: window._intl.formatMessage({ id: 'filePanel.addscriptsindri' }) },
]
},
{
name: "Uniswap V4",
items: [
{ value: "uniswapV4Template", displayName: window._intl.formatMessage({ id: 'filePanel.uniswapV4Template' }) },
{ value: "breakthroughLabsUniswapv4Hooks", displayName: window._intl.formatMessage({ id: 'filePanel.breakthroughLabsUniswapv4Hooks' }) },
{ value: "uniswapV4HookBookMultiSigSwapHook", displayName: window._intl.formatMessage({ id: 'filePanel.uniswapV4HookBookMultiSigSwapHook' }) }
]
},
{
name: "Solidity CREATE2",
items: [
{ value: "contractCreate2Factory", displayName: window._intl.formatMessage({ id: 'filePanel.addcreate2solidityfactory' }) },
{ value: "contractDeployerScripts", displayName: window._intl.formatMessage({ id: 'filePanel.addscriptdeployer' }) }
]
},
{
name: "Contract Verification",
items: [
{ value: "etherscanScripts", displayName: window._intl.formatMessage({ id: 'filePanel.addscriptetherscan' }) },
]
}
]
const createWorkspace = async (item) => {
const defaultName = await this.call('filePanel', 'getAvailableWorkspaceName', item.displayName)
const username = await this.call('settings', 'get', 'settings/github-user-name')
const email = await this.call('settings', 'get', 'settings/github-email')
const gitNotSet = !username || !email
let workspaceName = defaultName
let initGit = true
const modal: AppModal = {
id: 'TemplatesSelection',
title: window._intl.formatMessage({ id: !isElectron() ? 'filePanel.workspace.create': 'filePanel.workspace.create.desktop' }),
message: await createModalMessage(defaultName, gitNotSet, (value) => workspaceName = value, (value) => initGit = !!value),
okLabel: window._intl.formatMessage({ id: !isElectron() ? 'filePanel.ok':'filePanel.selectFolder' }),
}
const modalResult = await this.call('notification', 'modal', modal)
if (!modalResult) return
this.emit('createWorkspaceReducerEvent', workspaceName, item.value, item.opts, false, (e, data) => {
if (e) {
const modal: AppModal = {
id: 'TemplatesSelection',
title: window._intl.formatMessage({ id: !isElectron() ? 'filePanel.workspace.create': 'filePanel.workspace.create.desktop' }),
message: e.message,
okLabel: window._intl.formatMessage({ id: 'filePanel.ok' }),
cancelLabel: window._intl.formatMessage({ id: 'filePanel.cancel' })
}
this.call('notification', 'modal', modal)
console.error(e)
}
}, initGit)
}
const addToExistingWorkspace = async (item) => {
this.emit('addTemplateToWorkspaceReducerEvent', item.value, item.opts, false, (e, data) => {
if (e) {
const modal: AppModal = {
id: 'TemplatesSelection',
title: window._intl.formatMessage({ id: !isElectron() ? 'filePanel.workspace.create': 'filePanel.workspace.create.desktop' }),
message: e.message,
okLabel: window._intl.formatMessage({ id: 'filePanel.ok' }),
cancelLabel: window._intl.formatMessage({ id: 'filePanel.cancel' })
}
this.call('notification', 'modal', modal)
console.error(e)
}
})
}
return (
<RemixUIGridView
plugin={this}
styleList={""}
logo='/assets/img/YouTubeLogo.webp'
enableFilter={true}
showUntagged={true}
showPin={false}
tagList={[]}
title='Remix Guide'
description="Template Selection"
>
{
this.templates.map(template => {
return <RemixUIGridSection
plugin={this}
title={template.name}
hScrollable= {true}
>
{template.items.map(item => {
return <RemixUIGridCell
plugin={this}
title={item.displayName}
>
<div>
{item.displayName}
{JSON.stringify(item.opts)}
<div><button data-id={`create-${item.value}${item.opts ? JSON.stringify(item.opts) : ''}`} onClick={async () => createWorkspace(item)} className="btn btn-secondary" >Create a new workspace</button><button data-id={`add-${item.value}`} onClick={async () => addToExistingWorkspace(item)} className="btn btn-primary" >Add to existing workspace</button></div>
</div>
</RemixUIGridCell>
})}
</RemixUIGridSection>
})}
</RemixUIGridView>
)
}
}
const createModalMessage = async (
defaultName: string,
gitConfigNotSet: boolean,
onChangeTemplateName: (name: string) => void,
onChangeInitGit: (name: string) => void) => {
return (
<>
<label id="wsName" className="form-check-label" style={{ fontWeight: 'bolder' }}>
<FormattedMessage id="filePanel.workspaceName" />
</label>
<input
type="text"
data-id="modalDialogCustomPromptTextCreate"
defaultValue={defaultName}
className="form-control"
onChange={(e) => onChangeTemplateName(e.target.value)}
/>
<div className="d-flex py-2 align-items-center custom-control custom-checkbox">
<input
id="initGitRepository"
data-id="initGitRepository"
className="form-check-input custom-control-input"
type="checkbox"
disabled={gitConfigNotSet}
onChange={(e) => onChangeInitGit(e.target.value)}
/>
<label
htmlFor="initGitRepository"
data-id="initGitRepositoryLabel"
className="m-0 form-check-label custom-control-label udapp_checkboxAlign"
title={window._intl.formatMessage({ id: 'filePanel.initGitRepoTitle' })}
>
<FormattedMessage id="filePanel.initGitRepositoryLabel" />
</label>
</div>
{gitConfigNotSet ? (
<div className="text-warning">
<FormattedMessage id="filePanel.initGitRepositoryWarning" />
</div>
) : (
<></>
)}
</>
)
}

@ -5,7 +5,7 @@ import React from 'react'
import { action, FileTree, WorkspaceTemplate } from '../types'
import { ROOT_PATH } from '../utils/constants'
import { displayNotification, displayPopUp, fileAddedSuccess, fileRemovedSuccess, fileRenamedSuccess, folderAddedSuccess, loadLocalhostError, loadLocalhostRequest, loadLocalhostSuccess, removeContextMenuItem, removeFocus, rootFolderChangedSuccess, setContextMenuItem, setMode, setReadOnlyMode, setFileDecorationSuccess } from './payload'
import { addInputField, createWorkspace, deleteWorkspace, fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile } from './workspace'
import { addInputField, createWorkspace, populateWorkspace, deleteWorkspace, fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile } from './workspace'
const LOCALHOST = ' - connect to localhost - '
let plugin, dispatch: React.Dispatch<any>
@ -13,8 +13,16 @@ let plugin, dispatch: React.Dispatch<any>
export const listenOnPluginEvents = (filePanelPlugin) => {
plugin = filePanelPlugin
plugin.on('filePanel', 'createWorkspaceReducerEvent', (name: string, workspaceTemplateName: WorkspaceTemplate, isEmpty = false, cb: (err: Error, result?: string | number | boolean | Record<string, any>) => void) => {
createWorkspace(name, workspaceTemplateName, null, isEmpty, cb)
plugin.on('templateSelection', 'createWorkspaceReducerEvent', (name: string, workspaceTemplateName: WorkspaceTemplate, opts: any, isEmpty = false, cb: (err: Error, result?: string | number | boolean | Record<string, any>) => void, isGitRepo: boolean) => {
createWorkspace(name, workspaceTemplateName, opts, isEmpty, cb, isGitRepo)
})
plugin.on('templateSelection', 'addTemplateToWorkspaceReducerEvent', (workspaceTemplateName: WorkspaceTemplate, opts: any, isEmpty = false, cb: (err: Error, result?: string | number | boolean | Record<string, any>) => void) => {
populateWorkspace(workspaceTemplateName, opts, isEmpty, cb)
})
plugin.on('filePanel', 'createWorkspaceReducerEvent', (name: string, workspaceTemplateName: WorkspaceTemplate, isEmpty = false, cb: (err: Error, result?: string | number | boolean | Record<string, any>) => void, isGitRepo: boolean) => {
createWorkspace(name, workspaceTemplateName, null, isEmpty, cb, isGitRepo)
})
plugin.on('filePanel', 'renameWorkspaceReducerEvent', (oldName: string, workspaceName: string, cb: (err: Error, result?: string | number | boolean | Record<string, any>) => void) => {

@ -1,6 +1,7 @@
import React from 'react'
import { bytesToHex } from '@ethereumjs/util'
import { hash } from '@remix-project/remix-lib'
import { createNonClashingNameAsync } from '@remix-ui/helper'
import { TEMPLATE_METADATA, TEMPLATE_NAMES } from '../utils/constants'
import { TemplateType } from '../types'
import IpfsHttpClient from 'ipfs-http-client'
@ -154,6 +155,7 @@ export const createWorkspace = async (
await plugin.workspaceCreated(workspaceName)
if (isGitRepo && createCommit) {
console.log('CREATE COMMIT')
const name = await plugin.call('settings', 'get', 'settings/github-user-name')
const email = await plugin.call('settings', 'get', 'settings/github-email')
const currentBranch: branch = await dgitPlugin.call('dgitApi', 'currentbranch')
@ -191,6 +193,25 @@ export const createWorkspace = async (
}
}
}
await populateWorkspace(workspaceTemplateName, opts, isEmpty, (err: Error) => { cb && cb(err, workspaceName) }, isGitRepo, createCommit)
// this call needs to be here after the callback because it calls dGitProvider which also calls this function and that would cause an infinite loop
await plugin.setWorkspaces(await getWorkspaces())
}).catch((error) => {
dispatch(createWorkspaceError(error.message))
cb && cb(error)
})
return promise
}
export const populateWorkspace = async (
workspaceTemplateName: WorkspaceTemplate,
opts = null,
isEmpty = false,
cb?: (err: Error, result?: string | number | boolean | Record<string, any>) => void,
isGitRepo: boolean = false,
createCommit: boolean = false
) => {
const metadata = TEMPLATE_METADATA[workspaceTemplateName]
if (metadata && metadata.type === 'plugin') {
plugin.call('notification', 'toast', 'Please wait while the workspace is being populated with the template.')
dispatch(cloneRepositoryRequest())
@ -203,20 +224,17 @@ export const createWorkspace = async (
})
}, 5000)
} else if (!isEmpty && !(isGitRepo && createCommit)) await loadWorkspacePreset(workspaceTemplateName, opts)
cb && cb(null, workspaceName)
cb && cb(null)
if (isGitRepo) {
await checkGit()
const isActive = await plugin.call('manager', 'isActive', 'dgit')
if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit')
}
if (workspaceTemplateName === 'semaphore' || workspaceTemplateName === 'hashchecker' || workspaceTemplateName === 'rln') {
const isCircomActive = await plugin.call('manager', 'isActive', 'circuit-compiler')
if (!isCircomActive) await plugin.call('manager', 'activatePlugin', 'circuit-compiler')
_paq.push(['trackEvent', 'circuit-compiler', 'template', 'create', workspaceTemplateName])
}
// this call needs to be here after the callback because it calls dGitProvider which also calls this function and that would cause an infinite loop
await plugin.setWorkspaces(await getWorkspaces())
}).catch((error) => {
dispatch(createWorkspaceError(error.message))
cb && cb(error)
})
return promise
}
export const createWorkspaceTemplate = async (workspaceName: string, template: WorkspaceTemplate = 'remixDefault', metadata?: TemplateType) => {
@ -388,12 +406,14 @@ export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDe
try {
const templateList = Object.keys(templateWithContent)
if (!templateList.includes(template)) break
_paq.push(['trackEvent', 'workspace', 'template', template])
// @ts-ignore
const files = await templateWithContent[template](opts)
const files = await templateWithContent[template](opts, plugin)
for (const file in files) {
try {
await workspaceProvider.set(file, files[file])
const uniqueFileName = await createNonClashingNameAsync(file, plugin.fileManager)
await workspaceProvider.set(uniqueFileName, files[file])
} catch (error) {
console.error(error)
}

@ -163,47 +163,6 @@ export function HamburgerMenu(props: HamburgerMenuProps) {
}}
platforms={[appPlatformTypes.web, appPlatformTypes.desktop]}
></HamburgerMenuItem>
<Dropdown.Divider className="border mb-0 mt-0 remixui_menuhr" style={{ pointerEvents: 'none' }} />
<HamburgerMenuItem
kind="addscriptetherscan"
fa="fa-kit fa-ts-logo"
hideOption={hideWorkspaceOptions || hideFileOperations}
actionOnClick={() => {
props.addHelperScripts('etherscanScripts')
props.hideIconsMenu(!showIconsMenu)
}}
platforms={[appPlatformTypes.web, appPlatformTypes.desktop]}
></HamburgerMenuItem>
<HamburgerMenuItem
kind="addscriptdeployer"
fa="fa-kit fa-ts-logo"
hideOption={hideWorkspaceOptions || hideFileOperations}
actionOnClick={() => {
props.addHelperScripts('contractDeployerScripts')
props.hideIconsMenu(!showIconsMenu)
}}
platforms={[appPlatformTypes.web, appPlatformTypes.desktop]}
></HamburgerMenuItem>
<HamburgerMenuItem
kind="addscriptsindri"
fa="fa-kit fa-ts-logo"
hideOption={hideWorkspaceOptions || hideFileOperations}
actionOnClick={() => {
props.addHelperScripts('sindriScripts')
props.hideIconsMenu(!showIconsMenu)
}}
platforms={[appPlatformTypes.web, appPlatformTypes.desktop]}
></HamburgerMenuItem>
<HamburgerMenuItem
kind="addcreate2solidityfactory"
fa="fa-kit fa-ts-logo"
hideOption={hideWorkspaceOptions || hideFileOperations}
actionOnClick={() => {
props.addHelperScripts('contractCreate2Factory')
props.hideIconsMenu(!showIconsMenu)
}}
platforms={[appPlatformTypes.web, appPlatformTypes.desktop]}
></HamburgerMenuItem>
</>
)
}

@ -42,11 +42,8 @@ export function Workspace() {
const uupsRadioRef = useRef()
const global = useContext(FileSystemContext)
const workspaceRenameInput = useRef()
const workspaceCreateInput = useRef()
const workspaceCreateTemplateInput = useRef()
const intl = useIntl()
const cloneUrlRef = useRef<HTMLInputElement>()
const initGitRepoRef = useRef<HTMLInputElement>()
const filteredBranches = selectedWorkspace ? (selectedWorkspace.branches || []).filter((branch) => branch.name.includes(branchFilter) && branch.name !== 'HEAD').slice(0, 20) : []
const currentBranch = selectedWorkspace ? selectedWorkspace.currentBranch : null
@ -321,14 +318,9 @@ export function Workspace() {
intl.formatMessage({ id: 'filePanel.cancel' })
)
}
const createWorkspace = () => {
global.modal(
intl.formatMessage({ id: (platform !== appPlatformTypes.desktop)? 'filePanel.workspace.create': 'filePanel.workspace.create.desktop' }),
createModalMessage(),
intl.formatMessage({ id: (platform !== appPlatformTypes.desktop)? 'filePanel.ok':'filePanel.selectFolder' }),
onFinishCreateWorkspace,
intl.formatMessage({ id: 'filePanel.cancel' })
)
const createWorkspace = async () => {
await global.plugin.call('manager', 'activatePlugin', 'templateSelection')
await global.plugin.call('tabs', 'focus', 'templateSelection')
}
const deleteCurrentWorkspace = () => {
@ -448,38 +440,6 @@ export function Workspace() {
}
}
const onFinishCreateWorkspace = async () => {
if (workspaceCreateInput.current === undefined) return
// @ts-ignore: Object is possibly 'null'.
const workspaceName = workspaceCreateInput.current.value
// @ts-ignore: Object is possibly 'null'.
const workspaceTemplateName = workspaceCreateTemplateInput.current.value || 'remixDefault'
const initGitRepo = initGitRepoRef.current.checked
const opts = {
// @ts-ignore: Object is possibly 'null'.
mintable: mintableCheckboxRef.current.checked,
// @ts-ignore: Object is possibly 'null'.
burnable: burnableCheckboxRef.current.checked,
// @ts-ignore: Object is possibly 'null'.
pausable: pausableCheckboxRef.current.checked,
// @ts-ignore: Object is possibly 'null'.
upgradeable: transparentRadioRef.current.checked ? transparentRadioRef.current.value : uupsRadioRef.current.checked ? uupsRadioRef.current.value : false
}
try {
await global.dispatchCreateWorkspace(workspaceName, workspaceTemplateName, opts, initGitRepo)
} catch (e) {
global.modal(
intl.formatMessage({ id: (platform !== appPlatformTypes.desktop)? 'filePanel.workspace.create': 'filePanel.workspace.create.desktop' }),
e.message,
intl.formatMessage({ id: 'filePanel.ok' }),
() => {},
intl.formatMessage({ id: 'filePanel.cancel' })
)
console.error(e)
}
}
const onFinishDeleteWorkspace = async () => {
try {
await global.dispatchDeleteWorkspace(global.fs.browser.currentWorkspace)
@ -868,163 +828,6 @@ export function Workspace() {
}
}
const createModalMessage = () => {
return (
<>
<label id="selectWsTemplate" className="form-check-label" style={{ fontWeight: 'bolder' }}>
<FormattedMessage id="filePanel.workspace.chooseTemplate" />
</label>
<select
name="wstemplate"
className="mb-3 form-control custom-select"
id="wstemplate"
defaultValue="remixDefault"
ref={workspaceCreateTemplateInput}
onChange={updateWsName}
>
<optgroup style={{ fontSize: 'medium' }} label="General">
<option style={{ fontSize: 'small' }} value="remixDefault">
{intl.formatMessage({ id: 'filePanel.basic' })}
</option>
<option style={{ fontSize: 'small' }} value="blank">
{intl.formatMessage({ id: 'filePanel.blank' })}
</option>
</optgroup>
<optgroup style={{ fontSize: 'medium' }} label="OpenZeppelin">
<option style={{ fontSize: 'small' }} value="ozerc20">
ERC20
</option>
<option style={{ fontSize: 'small' }} value="ozerc721">
ERC721
</option>
<option style={{ fontSize: 'small' }} value="ozerc1155">
ERC1155
</option>
</optgroup>
<optgroup style={{ fontSize: 'medium' }} label="0xProject">
<option style={{ fontSize: 'small' }} value="zeroxErc20">
ERC20
</option>
</optgroup>
<optgroup style={{ fontSize: 'medium' }} label="GnosisSafe">
<option style={{ fontSize: 'small' }} value="gnosisSafeMultisig">
{intl.formatMessage({ id: 'filePanel.multiSigWallet' })}
</option>
</optgroup>
<optgroup style={{ fontSize: 'medium' }} label="Circom ZKP">
<option style={{ fontSize: 'small' }} value="semaphore">
{intl.formatMessage({ id: 'filePanel.semaphore' })}
</option>
<option style={{ fontSize: 'small' }} value="hashchecker">
{intl.formatMessage({ id: 'filePanel.hashchecker' })}
</option>
<option style={{ fontSize: 'small' }} value="rln">
{intl.formatMessage({ id: 'filePanel.rln' })}
</option>
</optgroup>
<optgroup style={{ fontSize: 'medium' }} label="Uniswap V4">
<option style={{ fontSize: 'small' }} value="uniswapV4Template">
{intl.formatMessage({ id: 'filePanel.uniswapV4Template' })}
</option>
<option style={{ fontSize: 'small' }} value="breakthroughLabsUniswapv4Hooks">
{intl.formatMessage({ id: 'filePanel.breakthroughLabsUniswapv4Hooks' })}
</option>
<option style={{ fontSize: 'small' }} value="uniswapV4HookBookMultiSigSwapHook">
{intl.formatMessage({ id: 'filePanel.uniswapV4HookBookMultiSigSwapHook' })}
</option>
</optgroup>
</select>
<div id="ozcustomization" data-id="ozCustomization" ref={displayOzCustomRef} style={{ display: 'none' }} className="mb-2">
<label className="form-check-label d-block mb-2" style={{ fontWeight: 'bolder' }}>
<FormattedMessage id="filePanel.customizeTemplate" />
</label>
<label id="wsName" className="form-check-label d-block mb-1">
<FormattedMessage id="filePanel.features" />
</label>
<div className="mb-2">
<div className="d-flex ml-2 custom-control custom-checkbox">
<input className="custom-control-input" type="checkbox" name="feature" value="mintable" id="mintable" ref={mintableCheckboxRef} />
<label className="form-check-label custom-control-label" htmlFor="mintable" data-id="featureTypeMintable">
<FormattedMessage id="filePanel.mintable" />
</label>
</div>
<div className="d-flex ml-2 custom-control custom-checkbox">
<input className="custom-control-input" type="checkbox" name="feature" value="burnable" id="burnable" ref={burnableCheckboxRef} />
<label className="form-check-label custom-control-label" htmlFor="burnable" data-id="featureTypeBurnable">
<FormattedMessage id="filePanel.burnable" />
</label>
</div>
<div className="d-flex ml-2 custom-control custom-checkbox">
<input className="custom-control-input" type="checkbox" name="feature" value="pausable" id="pausable" ref={pausableCheckboxRef} />
<label className="form-check-label custom-control-label" htmlFor="pausable" data-id="featureTypePausable">
<FormattedMessage id="filePanel.pausable" />
</label>
</div>
</div>
<label id="wsName" className="form-check-label d-block mb-1">
<FormattedMessage id="filePanel.upgradeability" />
</label>
<div>
<div className="d-flex ml-2 custom-control custom-radio">
<input className="custom-control-input" type="radio" name="upgradeability" value="transparent" id="transparent" ref={transparentRadioRef} />
<label className="form-check-label custom-control-label" htmlFor="transparent" data-id="upgradeTypeTransparent">
<FormattedMessage id="filePanel.transparent" />
</label>
</div>
<div className="d-flex ml-2 custom-control custom-radio">
<input className="custom-control-input" type="radio" name="upgradeability" value="uups" id="uups" ref={uupsRadioRef} />
<label className="form-check-label custom-control-label" htmlFor="uups" data-id="upgradeTypeUups">
UUPS
</label>
</div>
</div>
</div>
<label id="wsName" className="form-check-label" style={{ fontWeight: 'bolder' }}>
<FormattedMessage id="filePanel.workspaceName" />
</label>
<input
type="text"
data-id="modalDialogCustomPromptTextCreate"
defaultValue={global.plugin.getAvailableWorkspaceName(TEMPLATE_NAMES['remixDefault'])}
ref={workspaceCreateInput}
className="form-control"
/>
<div className="d-flex py-2 align-items-center custom-control custom-checkbox">
<input
ref={initGitRepoRef}
id="initGitRepository"
data-id="initGitRepository"
className="form-check-input custom-control-input"
type="checkbox"
disabled={!global.fs.gitConfig.username || !global.fs.gitConfig.email}
onChange={() => { }}
/>
<label
htmlFor="initGitRepository"
data-id="initGitRepositoryLabel"
className="m-0 form-check-label custom-control-label udapp_checkboxAlign"
title={intl.formatMessage({ id: 'filePanel.initGitRepoTitle' })}
>
<FormattedMessage id="filePanel.initGitRepositoryLabel" />
</label>
</div>
{!global.fs.gitConfig.username || !global.fs.gitConfig.email ? (
<div className="text-warning">
<FormattedMessage id="filePanel.initGitRepositoryWarning" />
</div>
) : (
<></>
)}
</>
)
}
const renameModalMessage = (workspaceName?: string) => {
return (
<div className='d-flex flex-column'>

@ -110,3 +110,21 @@ export const TEMPLATE_METADATA: Record<string, TemplateType> = {
}
}
export type TemplateOption = {
mintable?: boolean
burnable?: boolean
pausable?: boolean
upgradeable?: 'uups' | 'transparent'
}
export type Template = {
value: string
displayName: string
opts?: TemplateOption
}
export type TemplateGroup = {
name: string
items: Array<Template>
}

@ -1,4 +1,4 @@
export const contractDeployerScripts = async (plugin) => {
export const contractDeployerScripts = async (opts, plugin) => {
await plugin.call('fileManager', 'writeFile',
'scripts/contract-deployer/create2-factory-deploy.ts' ,
// @ts-ignore

@ -1,4 +1,4 @@
export const contractCreate2Factory = async (plugin) => {
export const contractCreate2Factory = async (opts, plugin) => {
await plugin.call('fileManager', 'writeFile',
'contracts/libs/create2-factory.sol' ,
// @ts-ignore

@ -1,4 +1,4 @@
export const etherscanScripts = async (plugin) => {
export const etherscanScripts = async (opts, plugin) => {
await plugin.call('fileManager', 'writeFile',
'scripts/etherscan/verifyScript.ts' ,
// @ts-ignore

@ -18,7 +18,7 @@ const getWorkspaceFilesByPath = async (plugin: any, pathRegex: RegExp | null = n
return filesByPath
}
export const sindriScripts = async (plugin: any) => {
export const sindriScripts = async (opts, plugin: any) => {
// Load in all of the Sindri or circuit-related files in the workspace.
const existingFilesByPath = await getWorkspaceFilesByPath(plugin, /sindri|\.circom$/i)
const writeIfNotExists = async (path: string, content: string) => {

Loading…
Cancel
Save