Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incompatible Typescript types between contracts #6419

Closed
Amxx opened this issue Feb 26, 2025 · 5 comments
Closed

Incompatible Typescript types between contracts #6419

Amxx opened this issue Feb 26, 2025 · 5 comments
Assignees
Labels
hardhat-3-alpha Feedback about the Hardhat 3 Alpha status:ready This issue is ready to be worked on

Comments

@Amxx
Copy link
Contributor

Amxx commented Feb 26, 2025

Feedback

Disclaimer: I'm new to viem (comming from ethers.js), and that is my first type working with the viem typescript types.

I am trying to build functions that operate on "contracts object" that implement interfaces. I'm then calling these functions with "contract objects" that are actual implementation of the interfaces.

For example, lets consider the following solidity code

interface MyInterface {
    function executeMessage(string calldata input) external payable returns (bytes4);
}
contract MyContract is MyInterface {
    function executeMessage(string calldata input) external payable returns (bytes4) { return MyInterface.executeMessage.selector; }
}

and the test code

import { network } from "hardhat";
import { it } from "node:test";

import type { ContractReturnType } from "@nomicfoundation/hardhat-viem/types";

async function execute(instance: ContractReturnType<"MyInterface">) {
    console.log(await instance.simulate.executeMessage([ 'hello' ]));
}

it("sandbox", async function () {
    const client = await network.connect();
    const c = await client.viem.deployContract("MyContract", []);
    await execute(c);
});

Everything works fine, except I have a solidity warning Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.

So I decide to update my solidity code to

contract MyContract is MyInterface {
-    function executeMessage(string calldata input) external payable returns (bytes4) { return MyInterface.executeMessage.selector; }
+    function executeMessage(string calldata) external payable returns (bytes4) { return MyInterface.executeMessage.selector; }
}

And that is when things start to break!

All of the sudden, I get a typescript error telling me that the types are incompatible. I guess that is because the ABI is not the same for the executeMessage function. In one case it has a named input, and in the other case it doesn't.

I'm getting errors about "legacy" and "eip7702" types being different. Not sure what tx envelops have to do with this, but it really isn't great.

In practice, compatible ABI are often implemented with minor changes to in args name. That doesn't break compatibility, and it should honestly no affect type resolution here.

@Amxx Amxx added the hardhat-3-alpha Feedback about the Hardhat 3 Alpha label Feb 26, 2025
@github-project-automation github-project-automation bot moved this to Backlog in Hardhat Feb 26, 2025
@Amxx
Copy link
Contributor Author

Amxx commented Feb 26, 2025

Note: I'm not sure weither that is a Hardhat-viem issue (comming from how the ABI are extracted from artefacts) or a viem issue (comming from how contracts are typed).

@kanej
Copy link
Member

kanej commented Feb 27, 2025

Hey @Amxx, is the repo you are working with open source, to help us reproduce the issue?

@Amxx
Copy link
Contributor Author

Amxx commented Feb 27, 2025

Here is a minimal example:

https://github.com/Amxx/hardhat3-minimal-example

(just run npm prepare)

@kanej kanej moved this from Backlog to To-do in Hardhat Feb 27, 2025
@kanej kanej added this to the Public Alpha Feature Rollout milestone Feb 27, 2025
@kanej kanej added status:ready This issue is ready to be worked on and removed status:triaging labels Feb 27, 2025
@kanej kanej removed their assignment Feb 27, 2025
@ChristopherDedominici ChristopherDedominici self-assigned this Mar 5, 2025
@ChristopherDedominici ChristopherDedominici moved this from To-do to In Progress in Hardhat Mar 5, 2025
@ChristopherDedominici
Copy link
Contributor

Hi @Amxx , thanks for reporting the issue. I just wanted to share a quick update: we're still investigating it

@fvictorio
Copy link
Member

Hey @Amxx, as far as I can tell, this is a limitation from viem. Here's a minimal reproduction using only viem stuff:

import { GetContractReturnType, WalletClient, parseAbi } from "viem";

const myContractAbi = parseAbi(["function executeMessage(string calldata) external payable returns (bytes4)"])
const myInterfaceAbi = parseAbi(["function executeMessage(string calldata input) external payable returns (bytes4)"])

type MyContract = GetContractReturnType<typeof myContractAbi, WalletClient>;
type MyInterface = GetContractReturnType<typeof myInterfaceAbi, WalletClient>;

let myContract: MyContract = null as any;
let myInterface: MyInterface = null as any;

myContract = myInterface
myInterface = myContract

The last two lines won't compile because apparently using different names for a function produces incompatible ABI types. Adding a name other than "input" to MyContract's ABI also results in compilation errors.

I don't think there's much we can do on our side here, so I'll tentatively close this, but happy to take another look if there's anything with which we could help.

@fvictorio fvictorio closed this as not planned Won't fix, can't repro, duplicate, stale Mar 14, 2025
@github-project-automation github-project-automation bot moved this from In Progress to Done in Hardhat Mar 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hardhat-3-alpha Feedback about the Hardhat 3 Alpha status:ready This issue is ready to be worked on
Projects
Status: Done
Development

No branches or pull requests

4 participants