NomicFoundation / hardhat

Hardhat is a development environment to compile, deploy, test, and debug your Ethereum software.
https://hardhat.org
Other
7.3k stars 1.41k forks source link

Unable to have circular monorepo package imports. #2660

Open shottah opened 2 years ago

shottah commented 2 years ago

When using a monorepo with multiple projects, one or more smart contracts cannot import in a circular reference between projects. I need this because I would like ContractA to use ContractB interface in order to make an external call to ContractB.

Problem: ContractA cannot import ContractB where ContractA lives in ProjectA and ContractB lives in ProjectB if and only if ContractB also imports ContractA.

N.B. This issue does not occur if ContractA imports ContractB, and ContractB does not import ContractA, where ContractA and ContractB exist in separate monorepo packages.

I have the following monorepo structure.

monorepo
   \package1
      \contracts
         \ICO.sol
   \package2
      \contracts
         \Router.sol

The following contracts reference each other in order to call specific functions.

package1/ICO

import 'package2/contracts/Router.sol'

package2/Router.sol

import 'package1/contracts/ICO.sol'

In the package definitions I have also included them as dependencies. These are resolved without issue.

package1/package.json

"dependencies: {
   "package2" : "^0.1.0"
}

package2/package.json

"dependencies: {
   "package1" : "^0.1.0"
}

Running yarn hardhat compile in project2 or project1 results in the following error: This throws with the error:

Error HH306: The 'file' parameter expects a value, but none was passed.

HardhatError: HH306: The 'file' parameter expects a value, but none was passed.
    at Environment._resolveArgument (/monorepo/node_modules/hardhat/src/internal/core/runtime-environment.ts:313:13)
    at /monorepo/node_modules/hardhat/src/internal/core/runtime-environment.ts:263:46
    at Array.reduce (<anonymous>)
    at Environment._resolveValidTaskArguments (/monorepo/node_modules/hardhat/src/internal/core/runtime-environment.ts:258:55)
    at Environment.run (/monorepo/node_modules/hardhat/src/internal/core/runtime-environment.ts:125:40)
    at /monorepo/node_modules/hardhat/src/builtin-tasks/compile.ts:270:15
    at createCompilationJobsFromConnectedComponent (/monorepo/node_modules/hardhat/src/internal/solidity/compilation-job.ts:152:41)
    at async Promise.all (index 0)
    at async SimpleTaskDefinition.action (/monorepo/node_modules/hardhat/src/builtin-tasks/compile.ts:265:46)
    at async Environment._runTaskDefinition (/monorepo/node_modules/hardhat/src/internal/core/runtime-environment.ts:219:14)
github-actions[bot] commented 2 years ago

This issue is also being tracked on Linear.

We use Linear to manage our development process, but we keep the conversations on Github.

LINEAR-ID: 349db0f4-ad3a-4636-b57b-a8ae442e7584

github-actions[bot] commented 2 years ago

This issue was marked as stale because it didn't have any activity in the last 30 days. If you think it's still relevant, please leave a comment indicating so. Otherwise, it will be closed in 7 days.

fvictorio commented 2 years ago

Hi @matabeitt, thanks for reporting this.

Since we support circular dependencies in single-repository projects, I think it makes sense to also support it in monorepos.

I don't know when we'll be able to work on this though, so for the time being, one workaround would be to extract the interface to a different file (say, I.sol), so that both A and B import I and there isn't a circular dependency anymore. I know this is not ideal, but maybe it can help you while you wait for a fix.