Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/remix-ide/src/app/files/foundry-handle.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const profile = {
name: 'foundry',
displayName: 'Foundry',
url: 'ws://127.0.0.1:65525',
methods: ['sync'],
methods: ['compile', 'sync'],
description: 'Using Remixd daemon, allow to access foundry API',
kind: 'other',
version: packageJson.version
Expand Down
2 changes: 2 additions & 0 deletions apps/remix-ide/src/app/tabs/locales/en/solidity.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
"solidity.hideWarnings": "Hide warnings",
"solidity.enableHardhat": "Enable Hardhat Compilation",
"solidity.learnHardhat": "Learn how to use Hardhat Compilation",
"solidity.learnFoundry": "Learn how to use Foundry Compilation",
"solidity.enableTruffle": "Enable Truffle Compilation",
"solidity.enableFoundry": "Enable Foundry Compilation",
"solidity.learnTruffle": "Learn how to use Truffle Compilation",
"solidity.advancedConfigurations": "Advanced Configurations",
"solidity.compilerConfiguration": "Compiler configuration",
Expand Down
44 changes: 28 additions & 16 deletions apps/remixdesktop/src/plugins/foundryPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,33 +110,45 @@ class FoundryPluginClient extends ElectronBasePluginRemixdClient {
return true
}

private async emitContract(file: string, cache) {
const path = join(this.buildPath, file) // out/Counter.sol/
const compilationResult = {
input: {},
output: {
contracts: {},
sources: {}
},
inputSources: { sources: {}, target: '' },
solcVersion: null,
compilationTarget: null
}
compilationResult.inputSources.target = file
await this.readContract(path, compilationResult, cache)
this.emit('compilationFinished', compilationResult.compilationTarget, { sources: compilationResult.input }, 'soljson', compilationResult.output, compilationResult.solcVersion)
}

private async processArtifact() {
if (!this.checkPath()) return
const folderFiles = await fs.promises.readdir(this.buildPath) // "out" folder
console.log('Foundry compilation detected, processing artifact...', folderFiles)
try {
const cache = JSON.parse(await fs.promises.readFile(join(this.cachePath, 'solidity-files-cache.json'), { encoding: 'utf-8' }))
const currentFile = await this.call('fileManager', 'getCurrentFile')
// name of folders are file names
for (const file of folderFiles) {
const path = join(this.buildPath, file) // out/Counter.sol/
const compilationResult = {
input: {},
output: {
contracts: {},
sources: {}
},
inputSources: { sources: {}, target: '' },
solcVersion: null,
compilationTarget: null
}
compilationResult.inputSources.target = file
await this.readContract(path, compilationResult, cache)
this.emit('compilationFinished', compilationResult.compilationTarget, { sources: compilationResult.input }, 'soljson', compilationResult.output, compilationResult.solcVersion)
if (file !== basename(currentFile)) {
await this.emitContract(file, cache)
}
}

if (folderFiles.includes(basename(currentFile))) {
console.log('emitting current file', currentFile, basename(currentFile))
await this.emitContract(basename(currentFile), cache) // we emit the current file at the end to make sure it is the last one
}

clearTimeout(this.logTimeout)
this.logTimeout = setTimeout(() => {
// @ts-ignore
this.call('terminal', 'log', { type: 'log', value: `receiving compilation result from Foundry. Select a file to populate the contract interaction interface.` })
// this.call('terminal', 'log', { type: 'log', value: `receiving compilation result from Foundry. Select a file to populate the contract interaction interface.` })
console.log('Syncing compilation result from Foundry')
}, 1000)

Expand Down
1 change: 1 addition & 0 deletions libs/remix-lib/src/types/ICompilerApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export interface ICompilerApi {

logToTerminal: (log: terminalLog) => void

compileWithFoundry: (configPath: string) => Promise<string>
compileWithHardhat: (configPath: string) => Promise<string>
compileWithTruffle: (configPath: string) => Promise<string>
statusChanged: (data: { key: string, title?: string, type?: string }) => void,
Expand Down
10 changes: 10 additions & 0 deletions libs/remix-ui/solidity-compiler/src/lib/api/compiler-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ export const CompilerApiMixin = (Base) => class extends Base {
return this.call('hardhat', 'compile', configFile)
}

compileWithFoundry (configFile) {
return this.call('foundry', 'compile', configFile)
}

compileWithTruffle (configFile) {
return this.call('truffle', 'compile', configFile)
}
Expand Down Expand Up @@ -256,6 +260,11 @@ export const CompilerApiMixin = (Base) => class extends Base {
if (this.onSetWorkspace) this.onSetWorkspace(workspace.isLocalhost, workspace.name)
})

this.on('fs', 'workingDirChanged', (path) => {
this.resetResults()
if (this.onSetWorkspace) this.onSetWorkspace(true, 'localhost')
})

this.on('fileManager', 'fileRemoved', (path) => {
if (this.onFileRemoved) this.onFileRemoved(path)
})
Expand Down Expand Up @@ -366,6 +375,7 @@ export const CompilerApiMixin = (Base) => class extends Base {
if (this.currentFile && (this.currentFile.endsWith('.sol') || this.currentFile.endsWith('.yul'))) {
if (await this.getAppParameter('hardhat-compilation')) this.compileTabLogic.runCompiler('hardhat')
else if (await this.getAppParameter('truffle-compilation')) this.compileTabLogic.runCompiler('truffle')
else if (await this.getAppParameter('foundry-compilation')) this.compileTabLogic.runCompiler('foundry')
else this.compileTabLogic.runCompiler(undefined).catch((error) => {
this.call('notification', 'toast', error.message)
})
Expand Down
51 changes: 48 additions & 3 deletions libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,17 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const [disableCompileButton, setDisableCompileButton] = useState<boolean>(false)
const compileIcon = useRef(null)
const promptMessageInput = useRef(null)
const [hhCompilation, sethhCompilation] = useState(false)
const [foundryCompilation, setFoundryCompilation] = useState(isFoundryProject)
const [hhCompilation, sethhCompilation] = useState(isHardhatProject)
const [truffleCompilation, setTruffleCompilation] = useState(false)
const [compilerContainer, dispatch] = useReducer(compilerReducer, compilerInitialState)
useEffect(() => {
setFoundryCompilation(isFoundryProject)
}, [isFoundryProject])

useEffect(() => {
sethhCompilation(isHardhatProject)
}, [isHardhatProject])

const intl = useIntl()

Expand Down Expand Up @@ -439,6 +447,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
let externalCompType
if (hhCompilation) externalCompType = 'hardhat'
else if (truffleCompilation) externalCompType = 'truffle'
else if (foundryCompilation) externalCompType = 'foundry'
compileTabLogic.runCompiler(externalCompType).catch((error) => {
tooltip(error.message)
compileIcon.current.classList.remove('remixui_bouncingIcon')
Expand Down Expand Up @@ -711,14 +720,21 @@ export const CompilerContainer = (props: CompilerContainerProps) => {

const updatehhCompilation = (event) => {
const checked = event.target.checked
if (checked) setTruffleCompilation(false) // wayaround to reset the variable
if (checked) sethhCompilation(false) // wayaround to reset the variable
sethhCompilation(checked)
api.setAppParameter('hardhat-compilation', checked)
}

const updateFoundryCompilation = (event) => {
const checked = event.target.checked
if (checked) setFoundryCompilation(false) // wayaround to reset the variable
setFoundryCompilation(checked)
api.setAppParameter('foundry-compilation', checked)
}

const updateTruffleCompilation = (event) => {
const checked = event.target.checked
if (checked) sethhCompilation(false) // wayaround to reset the variable
if (checked) setTruffleCompilation(false) // wayaround to reset the variable
setTruffleCompilation(checked)
api.setAppParameter('truffle-compilation', checked)
}
Expand Down Expand Up @@ -820,6 +836,35 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
<FormattedMessage id="solidity.hideWarnings" />
</label>
</div>
{isFoundryProject && (
<div className="mt-3 remixui_compilerConfig form-check">
<input
className="form-check-input"
onChange={updateFoundryCompilation}
id="enableFoundry"
type="checkbox"
title="Enable Foundry Compilation"
checked={foundryCompilation}
/>
<label className="form-check-label" htmlFor="enableFoundry">
<FormattedMessage id="solidity.enableFoundry" />
</label>
<a className="mt-1 text-nowrap" href="https://remix-ide.readthedocs.io/en/latest/foundry.html#enable-foundry-compilation" target={'_blank'}>
<CustomTooltip
placement={'right'}
tooltipClasses="text-nowrap"
tooltipId="overlay-tooltip-foundry"
tooltipText={
<span className="border bg-light text-dark p-1 pe-3" style={{ minWidth: '230px' }}>
<FormattedMessage id="solidity.learnFoundry" />
</span>
}
>
<i className={'ms-2 fas fa-info'} aria-hidden="true"></i>
</CustomTooltip>
</a>
</div>
)}
{isHardhatProject && (
<div className="mt-3 remixui_compilerConfig form-check">
<input
Expand Down
24 changes: 24 additions & 0 deletions libs/remix-ui/solidity-compiler/src/lib/logic/compileTabLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,30 @@ export class CompileTabLogic {
this.api.logToTerminal({ type: 'error', value: error })
})
}
} else if (externalCompType === 'foundry') {
const { currentVersion, optimize, runs } = this.compiler.state
if (currentVersion) {
const fileContent = `module.exports = {
solidity: '${currentVersion.substring(0, currentVersion.indexOf('+commit'))}',
settings: {
optimizer: {
enabled: ${optimize},
runs: ${runs}
}
}
}
`
const configFilePath = 'remix-compiler.config.js'
this.api.writeFile(configFilePath, fileContent)
if (window._matomoManagerInstance) {
window._matomoManagerInstance.trackEvent('compiler', 'runCompile', 'compileWithFoundry')
}
this.api.compileWithFoundry(configFilePath).then((result) => {
this.api.logToTerminal({ type: 'log', value: result })
}).catch((error) => {
this.api.logToTerminal({ type: 'error', value: error })
})
}
}
}
// TODO readd saving current file
Expand Down
5 changes: 3 additions & 2 deletions libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,12 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {

api.onSetWorkspace = async (isLocalhost: boolean, workspaceName: string) => {
const isDesktop = platform === appPlatformTypes.desktop

const isHardhat = (isLocalhost || isDesktop) && (await compileTabLogic.isHardhatProject())
const isTruffle = (isLocalhost || isDesktop) && (await compileTabLogic.isTruffleProject())
const isFoundry = (isLocalhost || isDesktop) && (await compileTabLogic.isFoundryProject())

console.log('Solidity compiler detected workspace change', { isLocalhost, workspaceName, isDesktop, isFoundry })

setState((prevState) => {
return {
...prevState,
Expand Down
1 change: 1 addition & 0 deletions libs/remix-ui/workspace/src/lib/actions/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,7 @@ export const checkoutRemoteBranch = async (branch: branch) => {

export const openElectronFolder = async (path: string) => {
await plugin.call('fs', 'openFolderInSameWindow', path)

}

export const getElectronRecentFolders = async () => {
Expand Down