From a007fb2b07cf091bbcd47c5bd1ebeddebceb5588 Mon Sep 17 00:00:00 2001 From: Jawad <38837406+JDawg287@users.noreply.github.com> Date: Thu, 7 Mar 2024 10:05:29 -0500 Subject: [PATCH] feat: add multi-target Typechain typings build option (#127) Signed-off-by: Jawad Tariq --- README.md | 32 ++++++++++++++ hardhat.config.ts | 7 ++++ scripts/const-addr-deployer.ts | 2 +- scripts/deploy-subnet-registrator.ts | 2 +- scripts/deploy-topos-core.ts | 8 ++-- scripts/deploy-topos-msg-protocol-dynamic.ts | 12 +++--- scripts/deploy-topos-msg-protocol.ts | 3 +- scripts/register-subnet.ts | 6 ++- scripts/test/send-token.ts | 9 ++-- scripts/upgrade-topos-core.ts | 6 ++- tasks/compile.ts | 42 +++++++++++++++++++ .../BurnableMintableCappedERC20.test.ts | 6 ++- test/topos-core/Bytes32Sets.test.ts | 6 ++- test/topos-core/SubnetRegistrator.test.ts | 6 ++- test/topos-core/ToposCore.test.ts | 11 +++-- test/topos-core/ToposMessaging.test.ts | 2 +- tsconfig.json | 2 +- 17 files changed, 131 insertions(+), 31 deletions(-) create mode 100644 tasks/compile.ts diff --git a/README.md b/README.md index d802e0c..32c5673 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,38 @@ To build: $ npm run build ``` +## Build contracts with different Typechain target + +To build different Typechain target: + +``` +npx hardhat compile --typechain-target target +``` + +Where `target` can be `ethers-v6`, `web3-v1`, etc. + +*Note: you need to install the appropriate package for the target you want to build for. For example, to build for `web3-v1`, you need to install `@typechain/web3-v1` package.* + +Default target is `ethers-v6` and it is output to `typechain-types/ethers-v6` directory. + +You can specify the target in several ways: +- By setting the `TYPECHAIN_TARGET` environment variable +```bash +export TYPECHAIN_TARGET=web3-v1 +``` +- By setting the `--typechain-target` command line option +```bash +npx hardhat compile --typechain-target web3-v1 +``` +- By setting the `typechain` field in `hardhat.config.ts` +```typescript +module.exports = { + typechain: { + target: 'web3-v1' + } +} +``` + ## Tests To run the tests: diff --git a/hardhat.config.ts b/hardhat.config.ts index bcedbd0..2685104 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,6 +1,8 @@ import { HardhatUserConfig } from 'hardhat/config' import '@nomicfoundation/hardhat-toolbox' +import './tasks/compile' + const config: HardhatUserConfig = { solidity: { version: '0.8.9', @@ -11,6 +13,11 @@ const config: HardhatUserConfig = { }, }, }, + typechain: { + // default 'ethers-v6' + outDir: 'typechain-types/ethers-v6', + target: 'ethers-v6', + }, } export default config diff --git a/scripts/const-addr-deployer.ts b/scripts/const-addr-deployer.ts index c28b98c..1c457da 100644 --- a/scripts/const-addr-deployer.ts +++ b/scripts/const-addr-deployer.ts @@ -8,7 +8,7 @@ import { Wallet, } from 'ethers' -import { ConstAddressDeployer__factory } from '../typechain-types/factories/contracts/topos-core/ConstAddressDeployer__factory' +import { ConstAddressDeployer__factory } from '../typechain-types/ethers-v6' export type Arg = string | number diff --git a/scripts/deploy-subnet-registrator.ts b/scripts/deploy-subnet-registrator.ts index ef95a51..4864d6f 100644 --- a/scripts/deploy-subnet-registrator.ts +++ b/scripts/deploy-subnet-registrator.ts @@ -1,7 +1,7 @@ import { computeAddress, isHexString, JsonRpcProvider, Wallet } from 'ethers' import subnetRegistratorJSON from '../artifacts/contracts/topos-core/SubnetRegistrator.sol/SubnetRegistrator.json' -import { SubnetRegistrator__factory } from '../typechain-types/factories/contracts/topos-core/SubnetRegistrator__factory' +import { SubnetRegistrator__factory } from '../typechain-types/ethers-v6' import { Arg, deployContractConstant } from './const-addr-deployer' const main = async function (..._args: Arg[]) { diff --git a/scripts/deploy-topos-core.ts b/scripts/deploy-topos-core.ts index 58b0a31..ef92ec6 100644 --- a/scripts/deploy-topos-core.ts +++ b/scripts/deploy-topos-core.ts @@ -1,8 +1,10 @@ import { isHexString, JsonRpcProvider, Wallet } from 'ethers' -import { ToposCore__factory } from '../typechain-types/factories/contracts/topos-core/ToposCore__factory' -import { ToposCoreProxy__factory } from '../typechain-types/factories/contracts/topos-core/ToposCoreProxy__factory' -import { ToposCore } from '../typechain-types/contracts/topos-core/ToposCore' +import { + ToposCore, + ToposCore__factory, + ToposCoreProxy__factory, +} from '../typechain-types/ethers-v6' const main = async function (...args: string[]) { const [_providerEndpoint, _sequencerPrivateKey, _gasLimit] = args diff --git a/scripts/deploy-topos-msg-protocol-dynamic.ts b/scripts/deploy-topos-msg-protocol-dynamic.ts index 72391f3..afcbb62 100644 --- a/scripts/deploy-topos-msg-protocol-dynamic.ts +++ b/scripts/deploy-topos-msg-protocol-dynamic.ts @@ -1,10 +1,12 @@ import { isHexString, JsonRpcProvider, Wallet } from 'ethers' -import { TokenDeployer__factory } from '../typechain-types/factories/contracts/topos-core/TokenDeployer__factory' -import { ToposCore__factory } from '../typechain-types/factories/contracts/topos-core/ToposCore__factory' -import { ToposCoreProxy__factory } from '../typechain-types/factories/contracts/topos-core/ToposCoreProxy__factory' -import { ERC20Messaging__factory } from '../typechain-types/factories/contracts/examples/ERC20Messaging__factory' -import { ToposCore } from '../typechain-types/contracts/topos-core/ToposCore' +import { + ERC20Messaging__factory, + TokenDeployer__factory, + ToposCore__factory, + ToposCoreProxy__factory, + ToposCore, +} from '../typechain-types/ethers-v6' const main = async function (...args: string[]) { const [providerEndpoint, _sequencerPrivateKey] = args diff --git a/scripts/deploy-topos-msg-protocol.ts b/scripts/deploy-topos-msg-protocol.ts index d1002d6..b241cad 100644 --- a/scripts/deploy-topos-msg-protocol.ts +++ b/scripts/deploy-topos-msg-protocol.ts @@ -10,8 +10,7 @@ import { deployContractConstant, predictContractConstant, } from './const-addr-deployer' -import { ToposCore__factory } from '../typechain-types/factories/contracts/topos-core/ToposCore__factory' -import { ToposCore } from '../typechain-types/contracts/topos-core/ToposCore' +import { ToposCore__factory, ToposCore } from '../typechain-types/ethers-v6' const main = async function (...args: string[]) { const [providerEndpoint, _sequencerPrivateKey] = args diff --git a/scripts/register-subnet.ts b/scripts/register-subnet.ts index cdd223f..0889d0d 100644 --- a/scripts/register-subnet.ts +++ b/scripts/register-subnet.ts @@ -1,7 +1,9 @@ import { isHexString, JsonRpcProvider, Wallet } from 'ethers' -import { SubnetRegistrator__factory } from '../typechain-types/factories/contracts/topos-core/SubnetRegistrator__factory' -import { SubnetRegistrator } from '../typechain-types/contracts/topos-core/SubnetRegistrator' +import { + SubnetRegistrator, + SubnetRegistrator__factory, +} from '../typechain-types/ethers-v6' const main = async function (...args: string[]) { const [ diff --git a/scripts/test/send-token.ts b/scripts/test/send-token.ts index d1ef103..b86cff0 100644 --- a/scripts/test/send-token.ts +++ b/scripts/test/send-token.ts @@ -1,7 +1,10 @@ import { isHexString, JsonRpcProvider, Wallet } from 'ethers' -import { ERC20Messaging__factory } from '../../typechain-types/factories/contracts/examples/ERC20Messaging__factory' -import { BurnableMintableCappedERC20__factory } from '../../typechain-types/factories/contracts/topos-core/BurnableMintableCappedERC20__factory' -import { ERC20Messaging } from '../../typechain-types/contracts/examples/ERC20Messaging' + +import { + BurnableMintableCappedERC20__factory, + ERC20Messaging, + ERC20Messaging__factory, +} from '../../typechain-types/ethers-v6' import * as cc from '../../test/topos-core/shared/constants/certificates' import * as tc from '../../test/topos-core/shared/constants/tokens' import * as testUtils from '../../test/topos-core/shared/utils/common' diff --git a/scripts/upgrade-topos-core.ts b/scripts/upgrade-topos-core.ts index 700f93a..3d64401 100644 --- a/scripts/upgrade-topos-core.ts +++ b/scripts/upgrade-topos-core.ts @@ -8,8 +8,10 @@ import { Wallet, } from 'ethers' -import { ToposCore__factory } from '../typechain-types/factories/contracts/topos-core/ToposCore__factory' -import { CodeHash__factory } from '../typechain-types/factories/contracts/topos-core/CodeHash__factory' +import { + ToposCore__factory, + CodeHash__factory, +} from '../typechain-types/ethers-v6' import toposCoreJSON from '../artifacts/contracts/topos-core/ToposCore.sol/ToposCore.json' diff --git a/tasks/compile.ts b/tasks/compile.ts new file mode 100644 index 0000000..1a820c1 --- /dev/null +++ b/tasks/compile.ts @@ -0,0 +1,42 @@ +import { task } from 'hardhat/config' + +enum SupportedTypechainTargets { + 'ethers-v5' = 'ethers-v5', + 'ethers-v6' = 'ethers-v6', + 'truffle-v4' = 'truffle-v4', + 'truffle-v5' = 'truffle-v5', + 'web3-v1' = 'web3-v1', +} + +/** + * This task overrides the original compile task to allow for setting the Typechain target + * via several methods: + * 1. Command line argument: `npx hardhat compile --typechain ethers-v5` + * 2. Environment variable: `TYPECHAIN_TARGET=ethers-v5 npx hardhat compile` + * 3. Hardhat config: `const config: HardhatUserConfig = { typechain: { target: 'ethers-v5' } }` + * @param args.typechainTarget (optional) The Typechain target to build for + */ +task( + 'compile', + 'Compiles the entire project, building all artifacts and custom Typechain typings' +) + .addOptionalParam('typechainTarget', 'The Typechain target to build for') + .setAction(async (args, hre, runSuper) => { + const typechainTarget = + args.typechainTarget || + process.env.TYPECHAIN_TARGET || + hre.config.typechain.target // default 'ethers-v6' + + // Validate the Typechain target + if (!Object.values(SupportedTypechainTargets).includes(typechainTarget)) { + throw new Error(`Unsupported typechain target: ${typechainTarget}`) + } + // Override the Typechain target + hre.config.typechain.target = typechainTarget + hre.config.typechain.outDir = `typechain-types/${typechainTarget}` + + // Call the original compile task + if (runSuper.isDefined) { + await runSuper(args) + } + }) diff --git a/test/topos-core/BurnableMintableCappedERC20.test.ts b/test/topos-core/BurnableMintableCappedERC20.test.ts index 66047a1..bff011e 100644 --- a/test/topos-core/BurnableMintableCappedERC20.test.ts +++ b/test/topos-core/BurnableMintableCappedERC20.test.ts @@ -2,8 +2,10 @@ import { EventLog } from 'ethers' import { expect } from 'chai' import { ethers } from 'hardhat' -import { BurnableMintableCappedERC20__factory } from '../../typechain-types/factories/contracts/topos-core/BurnableMintableCappedERC20__factory' -import { TokenDeployer__factory } from '../../typechain-types/factories/contracts/topos-core/TokenDeployer__factory' +import { + BurnableMintableCappedERC20__factory, + TokenDeployer__factory, +} from '../../typechain-types/ethers-v6' import * as tc from './shared/constants/tokens' describe('BurnableMintableCappedERC20', () => { diff --git a/test/topos-core/Bytes32Sets.test.ts b/test/topos-core/Bytes32Sets.test.ts index 3f4eb18..20a08b3 100644 --- a/test/topos-core/Bytes32Sets.test.ts +++ b/test/topos-core/Bytes32Sets.test.ts @@ -1,8 +1,10 @@ import { ethers } from 'hardhat' import { expect } from 'chai' -import { Bytes32SetsTest__factory } from '../../typechain-types/factories/contracts/topos-core/Bytes32Sets.sol/Bytes32SetsTest__factory' -import { Bytes32SetsTest } from '../../typechain-types/contracts/topos-core/Bytes32Sets.sol/Bytes32SetsTest' +import { + Bytes32SetsTest, + Bytes32SetsTest__factory, +} from '../../typechain-types/ethers-v6' describe('Bytes32Sets', () => { let bytes32SetsTest: Bytes32SetsTest diff --git a/test/topos-core/SubnetRegistrator.test.ts b/test/topos-core/SubnetRegistrator.test.ts index 7061eff..f46fdb2 100644 --- a/test/topos-core/SubnetRegistrator.test.ts +++ b/test/topos-core/SubnetRegistrator.test.ts @@ -2,8 +2,10 @@ import { Signer } from 'ethers' import { ethers } from 'hardhat' import { expect } from 'chai' -import { SubnetRegistrator__factory } from '../../typechain-types/factories/contracts/topos-core/SubnetRegistrator__factory' -import { SubnetRegistrator } from '../../typechain-types' +import { + SubnetRegistrator__factory, + SubnetRegistrator, +} from '../../typechain-types/ethers-v6' describe('SubnetRegistrator', () => { const chainId = 1 diff --git a/test/topos-core/ToposCore.test.ts b/test/topos-core/ToposCore.test.ts index 6f84417..ddd534d 100644 --- a/test/topos-core/ToposCore.test.ts +++ b/test/topos-core/ToposCore.test.ts @@ -2,10 +2,13 @@ import { loadFixture } from '@nomicfoundation/hardhat-network-helpers' import { ethers } from 'hardhat' import { expect } from 'chai' -import { ToposCore__factory } from '../../typechain-types/factories/contracts/topos-core/ToposCore__factory' -import { ToposCoreProxy__factory } from '../../typechain-types/factories/contracts/topos-core/ToposCoreProxy__factory' -import { CodeHash__factory } from '../../typechain-types/factories/contracts/topos-core/CodeHash__factory' -import { ToposCoreProxy } from '../../typechain-types/contracts/topos-core/ToposCoreProxy' +import { + CodeHash__factory, + ToposCore__factory, + ToposCoreProxy, + ToposCoreProxy__factory, +} from '../../typechain-types/ethers-v6' + import * as cc from './shared/constants/certificates' import * as testUtils from './shared/utils/common' diff --git a/test/topos-core/ToposMessaging.test.ts b/test/topos-core/ToposMessaging.test.ts index a12442c..5cb7a56 100644 --- a/test/topos-core/ToposMessaging.test.ts +++ b/test/topos-core/ToposMessaging.test.ts @@ -15,7 +15,7 @@ import { ToposCoreProxy__factory, ERC20Messaging__factory, ERC20Messaging, -} from '../../typechain-types' +} from '../../typechain-types/ethers-v6' import * as cc from './shared/constants/certificates' import * as testUtils from './shared/utils/common' import { getReceiptMptProof } from './shared/utils/mpt_proof' diff --git a/tsconfig.json b/tsconfig.json index 63cc994..7ccde2c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,6 +9,6 @@ "skipLibCheck": true, "resolveJsonModule": true }, - "include": ["./scripts", "./test", "./typechain-types"], + "include": ["./scripts", "./test", "./typechain-types", "./tasks"], "files": ["./hardhat.config.ts"] }