wighawag / hardhat-deploy-ethers

MIT License
70 stars 25 forks source link

After installing `hardhat-deploy`, deployed contracts are no longer properly typed #23

Closed CyclopsRex closed 1 year ago

CyclopsRex commented 2 years ago

Background

I have a typescript codebase which deploys some contracts and then calls functions on them according to their specific type. e.g.

const myFactory = await ethers.getContractFactory(
    "MyContract"
  );
const myContract = await myFactory.deploy();
await myContract.foo();

In this example, myContract is given type MtyContract. This is exactly what I want, and without fully understanding all the code it seems to be facilitated by a typechain/hardhat.d.ts file, which was generated when I ran hh typechain.

So far, so good.

Issue

After installing hardhat-deploy by running npm install -D hardhat-deploy and npm install --save-dev @nomiclabs/hardhat-ethers@npm:hardhat-deploy-ethers, I find that hardhat.d.ts has gone missing and myContract now has the much less useful type of Contract. I can explicitly cast it but this code appears in a hundred places in it's a pain to do so, as well as unnecessarily verbose.

This seems to be related to the unlink introduced in f4b68f729b96982b8497cd538c46fd8dbd0eed97, which removes the hardhat.d.ts file that contains the properly typed functions, immediately after it is generated.

There is also a similar problem with attach, though I'm not sure that has the same root cause cos this seems to come from somewhere other than hardhat.d.ts?

Question

Hardhat-deploy seems nice but is there a way to have it play nicely and maintain all the strongly typed contracts I've become used to, both when calling deploy on a factory and when calling attach?

It's perfectly possible that I've just missed an instruction or mistyped something, but after debugging for quite a while only to find the unlink, I'm at a bit of loss.

Extract from package.json follows:

  "devDependencies": {
    "@ethersproject/bignumber": "^5.5.0",
    "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13",
    "@nomiclabs/hardhat-etherscan": "^2.1.6",
    "@nomiclabs/hardhat-solhint": "^2.0.0",
    "@nomiclabs/hardhat-waffle": "^2.0.1",
    "@openzeppelin/hardhat-upgrades": "^1.12.0",
    "@primitivefi/hardhat-dodoc": "^0.1.3",
    "@tenderly/hardhat-tenderly": "^1.0.13",
    "@typechain/ethers-v5": "^7.2.0",
    "@typechain/hardhat": "^2.3.1",
    "@types/chai": "^4.2.22",
    "@types/mocha": "^9.0.0",
    "@types/node": "^16.11.0",
    "@typescript-eslint/eslint-plugin": "^4.33.0",
    "@typescript-eslint/parser": "^4.33.0",
    "bignumber.js": "^9.0.2",
    "chai": "^4.3.4",
    "cross-env": "^7.0.3",
    "decimal.js": "^10.3.1",
    "decimal.js-light": "^2.5.1",
    "dotenv": "^10.0.0",
    "eslint": "^7.32.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-config-standard": "^16.0.3",
    "eslint-plugin-import": "^2.25.2",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-prettier": "^3.4.1",
    "eslint-plugin-promise": "^5.1.0",
    "ethereum-waffle": "^3.4.0",
    "ethers": "^5.5.4",
    "evm-bn": "^1.1.1",
    "hardhat": "^2.8.0",
    "hardhat-deploy": "^0.10.4",
    "hardhat-gas-reporter": "^1.0.4",
    "husky": "^7.0.4",
    "mathjs": "^10.0.2",
    "mocha": "^9.1.3",
    "prettier": "^2.4.1",
    "prettier-plugin-solidity": "^1.0.0-beta.19",
    "solhint": "^3.3.6",
    "solidity-coverage": "^0.7.17",
    "ts-node": "^10.3.0",
    "typechain": "^5.2.0",
    "typescript": "^4.4.4"
  },
wighawag commented 2 years ago

Unfortunately the unlink was done due to a limitation of typechain, see : https://github.com/dethcrypto/TypeChain/issues/399

There might be other way around for now though and welcome PR to solve it.

haydenyoung commented 2 years ago

Getting same problem. For me, seems to be related to npm install --save-dev @nomiclabs/hardhat-ethers@npm:hardhat-deploy-ethers from installation instructions results in typechain typed contract data. If I install both hardhat-ethers and hardhat-deploy-ethers as separate packages (without the alias(?)) typing works but I no longer have access to ethers.getContract().

wighawag commented 2 years ago

Might be worth voicing your issue in https://github.com/dethcrypto/TypeChain/issues/399 too

typechain is currently hard-coding the type from @nomiclabs/hardhat-ethers and this what make it incompatible with hardhat-deploy-ethers that add extra types to hre.ethers

haydenyoung commented 2 years ago

Will do. Thanks for the tip.

lebed2045 commented 2 years ago

workaround

image
haydenyoung commented 2 years ago

workaround image

Thanks for the suggestion. I tried adding to my deployment but it had no effect (I.e. no typechain definitions for my solidity contracts).

So is the idea here that type definitions for ethers deploy getContract, etc are pulled from the hardhat deploy types rather than from the typechain-types dir?

edumudu commented 2 years ago

For someone that found this issue, a current workaround to keep the types is to pass the typechain type to the generic of the getContract function. But is more verbose than the native approach from typechain


Get the type from the typechain folder image

pass to getContract image

haydenyoung commented 2 years ago

@edumudu thanks. This worked for me. But, yes, you're correct, it adds verbosity to the code.

haydenyoung commented 2 years ago

@edumudu thanks. This worked for me. But, yes, you're correct, it adds verbosity to the code.

Further to my implementation of importing and declaring typechain types explicitly, I've found that this only works if I have the typechain types already generated (i.e. ./typechain-types dir already exists), otherwise I get a "cannot find module typechain-types". As typechain even recommends NOT committing the typechain-types dir to source control, Therefore, I cannot generate typechain-types because it is looking for typechain-types during compilation, hence I'm stuck in a failure loop.

Edit: Whoops. Seems like you can ignore missing imports with // @ts-ignore

// @ts-ignore
import type { ArbitrageMediator } from "../typechain-types";
wighawag commented 1 year ago

Latest version 0.4.1 allow you to specify a generic