Convert packages from CJS to ESM (#3531)
### Description - Reconfigure tsconfig and package.json for the utils, core, sdk, and helloworld packages - Update imports to use ESM syntax - Add patch for typechain to address [issue 898](https://github.com/dethcrypto/TypeChain/pull/898) ### Drive-by changes Improve package Readme content ### Related issues Fixes https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/1354 ### Backward compatibility No: package consumers using CJS will need to modify their imports or update to ESM. See [this popular gist](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c#pure-esm-package) for details. ### Testing - [x] CI test coverage which invokes a lot of code via the CLI e2e - [x] Manually test in Warp UI by copying packages - [x] Publish beta packages and test in a few popular bundlersnoah/node-expwarn-cli
parent
040641bf42
commit
b63714ede8
@ -0,0 +1,9 @@ |
||||
--- |
||||
'@hyperlane-xyz/helloworld': minor |
||||
'@hyperlane-xyz/utils': minor |
||||
'@hyperlane-xyz/cli': minor |
||||
'@hyperlane-xyz/sdk': minor |
||||
'@hyperlane-xyz/core': minor |
||||
--- |
||||
|
||||
Convert all public hyperlane npm packages from CJS to pure ESM |
@ -1,3 +1,4 @@ |
||||
node_modules |
||||
dist |
||||
coverage |
||||
*.cts |
@ -0,0 +1,23 @@ |
||||
diff --git a/dist/codegen/createBarrelFiles.js b/dist/codegen/createBarrelFiles.js
|
||||
index 4bf574d7f6701bc5a8fcb2c281b5c63f31923e79..7f9cbdbd0491d4fa6338a10b23d06c2665c9d968 100644
|
||||
--- a/dist/codegen/createBarrelFiles.js
|
||||
+++ b/dist/codegen/createBarrelFiles.js
|
||||
@@ -38,15 +38,13 @@ function createBarrelFiles(paths, { typeOnly, postfix = '', moduleSuffix = '' })
|
||||
const namespacesExports = nestedDirs
|
||||
.map((p) => {
|
||||
const namespaceIdentifier = (0, normalizeDirName_1.normalizeDirName)(p);
|
||||
+ const fromFilePath = moduleSuffix ? `'./${p}/index${moduleSuffix}'` : `'./${p}'`
|
||||
if (typeOnly)
|
||||
return [
|
||||
- `import type * as ${namespaceIdentifier} from './${p}';`,
|
||||
+ `import type * as ${namespaceIdentifier} from ${fromFilePath};`,
|
||||
`export type { ${namespaceIdentifier} };`,
|
||||
].join('\n');
|
||||
- if (moduleSuffix) {
|
||||
- return `export * as ${namespaceIdentifier} from './${p}/index${moduleSuffix}';`;
|
||||
- }
|
||||
- return `export * as ${namespaceIdentifier} from './${p}';`;
|
||||
+ return `export * as ${namespaceIdentifier} from ${fromFilePath};`;
|
||||
})
|
||||
.join('\n');
|
||||
const contracts = (fileReexports[path] || []).sort();
|
@ -1,15 +1,19 @@ |
||||
# Hyperlane Solidity |
||||
# Hyperlane Core |
||||
|
||||
On-chain implementations of Hyperlane in Solidity. |
||||
Hyperlane Core contains the contracts and typechain artifacts for the Hyperlane implementation for EVM. |
||||
|
||||
## Setup |
||||
## Install |
||||
|
||||
- `yarn install` |
||||
```bash |
||||
# Install with NPM |
||||
npm install @hyperlane-xyz/utils |
||||
|
||||
## Build |
||||
# Or with Yarn |
||||
yarn add @hyperlane-xyz/utils |
||||
``` |
||||
|
||||
- `yarn build` |
||||
Note, this package uses [ESM Modules](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c#pure-esm-package) |
||||
|
||||
## Test |
||||
## License |
||||
|
||||
- `yarn test` |
||||
Apache 2.0 |
||||
|
@ -0,0 +1,12 @@ |
||||
import type { Wallet } from 'ethers'; |
||||
import hre from 'hardhat'; |
||||
|
||||
export async function getSigners(): Promise<Wallet[]> { |
||||
// @ts-ignore Hardhat type overrides from @nomiclabs/hardhat-ethers don't work
|
||||
return hre.ethers.getSigners(); |
||||
} |
||||
|
||||
export async function getSigner(): Promise<Wallet> { |
||||
const [signer] = await getSigners(); |
||||
return signer; |
||||
} |
@ -1,8 +1,8 @@ |
||||
{ |
||||
"extends": "../tsconfig.json", |
||||
"compilerOptions": { |
||||
"outDir": "./dist", |
||||
"rootDir": "./types" |
||||
}, |
||||
"exclude": ["./test", "hardhat.config.ts", "./dist"], |
||||
"extends": "../tsconfig.json" |
||||
"exclude": ["./test", "hardhat.config.cts", "./dist"] |
||||
} |
||||
|
@ -1,10 +1,10 @@ |
||||
export { HelloWorldApp } from './app/app'; |
||||
export { HelloWorldFactories, helloWorldFactories } from './app/contracts'; |
||||
export { HelloWorldChecker } from './deploy/check'; |
||||
export { HelloWorldConfig } from './deploy/config'; |
||||
export { HelloWorldDeployer } from './deploy/deploy'; |
||||
export { EvmHelloWorldAdapter } from './multiProtocolApp/evmAdapter'; |
||||
export { HelloMultiProtocolApp } from './multiProtocolApp/multiProtocolApp'; |
||||
export { SealevelHelloWorldAdapter } from './multiProtocolApp/sealevelAdapter'; |
||||
export { IHelloWorldAdapter } from './multiProtocolApp/types'; |
||||
export * as types from './types'; |
||||
export { HelloWorldApp } from './app/app.js'; |
||||
export { HelloWorldFactories, helloWorldFactories } from './app/contracts.js'; |
||||
export { HelloWorldChecker } from './deploy/check.js'; |
||||
export { HelloWorldConfig } from './deploy/config.js'; |
||||
export { HelloWorldDeployer } from './deploy/deploy.js'; |
||||
export { EvmHelloWorldAdapter } from './multiProtocolApp/evmAdapter.js'; |
||||
export { HelloMultiProtocolApp } from './multiProtocolApp/multiProtocolApp.js'; |
||||
export { SealevelHelloWorldAdapter } from './multiProtocolApp/sealevelAdapter.js'; |
||||
export { IHelloWorldAdapter } from './multiProtocolApp/types.js'; |
||||
export * as types from './types/index.js'; |
||||
|
@ -0,0 +1,19 @@ |
||||
import '@nomiclabs/hardhat-ethers'; |
||||
import '@nomiclabs/hardhat-waffle'; |
||||
|
||||
/** |
||||
* @type import('hardhat/config').HardhatUserConfig |
||||
*/ |
||||
module.exports = { |
||||
solidity: { |
||||
version: '0.7.6', |
||||
}, |
||||
networks: { |
||||
hardhat: { |
||||
mining: { |
||||
auto: true, |
||||
interval: 2000, |
||||
}, |
||||
}, |
||||
}, |
||||
}; |
@ -1,186 +0,0 @@ |
||||
import '@nomiclabs/hardhat-etherscan'; |
||||
import '@nomiclabs/hardhat-waffle'; |
||||
import { task } from 'hardhat/config'; |
||||
import { HardhatRuntimeEnvironment } from 'hardhat/types'; |
||||
|
||||
import { Mailbox, TestSendReceiver__factory } from '@hyperlane-xyz/core'; |
||||
import { |
||||
ChainName, |
||||
HookType, |
||||
HyperlaneCore, |
||||
MultiProvider, |
||||
} from '@hyperlane-xyz/sdk'; |
||||
import { addressToBytes32 } from '@hyperlane-xyz/utils'; |
||||
|
||||
import { Modules, getAddresses } from './scripts/agent-utils'; |
||||
import { sleep } from './src/utils/utils'; |
||||
|
||||
enum MailboxHookType { |
||||
REQUIRED = 'requiredHook', |
||||
DEFAULT = 'defaultHook', |
||||
} |
||||
|
||||
/** |
||||
* If a hookArg is provided, set the mailbox hook to the defaultHookArg. |
||||
* The hook is set either as the default hook or the required hook, |
||||
* depending on the mailboxHookType argument. |
||||
*/ |
||||
async function setMailboxHook( |
||||
mailbox: Mailbox, |
||||
coreAddresses: any, |
||||
local: ChainName, |
||||
mailboxHookType: MailboxHookType, |
||||
hookArg: HookType, |
||||
) { |
||||
const hook = coreAddresses[local][hookArg]; |
||||
switch (mailboxHookType) { |
||||
case MailboxHookType.REQUIRED: { |
||||
await mailbox.setRequiredHook(hook); |
||||
break; |
||||
} |
||||
case MailboxHookType.DEFAULT: { |
||||
await mailbox.setDefaultHook(hook); |
||||
break; |
||||
} |
||||
} |
||||
console.log(`set the ${mailboxHookType} hook on ${local} to ${hook}`); |
||||
} |
||||
|
||||
const chainSummary = async (core: HyperlaneCore, chain: ChainName) => { |
||||
const coreContracts = core.getContracts(chain); |
||||
const mailbox = coreContracts.mailbox; |
||||
const dispatched = await mailbox.nonce(); |
||||
// TODO: Allow processed messages to be filtered by
|
||||
// origin, possibly sender and recipient.
|
||||
const processFilter = mailbox.filters.Process(); |
||||
const processes = await mailbox.queryFilter(processFilter); |
||||
const processed = processes.length; |
||||
|
||||
const summary = { |
||||
chain, |
||||
dispatched, |
||||
processed, |
||||
}; |
||||
return summary; |
||||
}; |
||||
|
||||
task('kathy', 'Dispatches random hyperlane messages') |
||||
.addParam( |
||||
'messages', |
||||
'Number of messages to send; defaults to having no limit', |
||||
'0', |
||||
) |
||||
.addParam('timeout', 'Time to wait between messages in ms.', '5000') |
||||
.addFlag('mineforever', 'Mine forever after sending messages') |
||||
.addParam( |
||||
MailboxHookType.DEFAULT, |
||||
'Default hook to call in postDispatch', |
||||
HookType.AGGREGATION, |
||||
) |
||||
.addParam( |
||||
MailboxHookType.REQUIRED, |
||||
'Required hook to call in postDispatch', |
||||
HookType.PROTOCOL_FEE, |
||||
) |
||||
.setAction( |
||||
async ( |
||||
taskArgs: { |
||||
messages: string; |
||||
timeout: string; |
||||
mineforever: boolean; |
||||
defaultHook: HookType; |
||||
requiredHook: HookType; |
||||
}, |
||||
hre: HardhatRuntimeEnvironment, |
||||
) => { |
||||
const timeout = Number.parseInt(taskArgs.timeout); |
||||
const environment = 'test'; |
||||
const [signer] = await hre.ethers.getSigners(); |
||||
const multiProvider = MultiProvider.createTestMultiProvider({ signer }); |
||||
const addresses = getAddresses(environment, Modules.CORE); |
||||
const core = HyperlaneCore.fromAddressesMap(addresses, multiProvider); |
||||
|
||||
const randomElement = <T>(list: T[]) => |
||||
list[Math.floor(Math.random() * list.length)]; |
||||
|
||||
// Deploy a recipient
|
||||
const recipientF = new TestSendReceiver__factory(signer); |
||||
const recipient = await recipientF.deploy(); |
||||
await recipient.deployTransaction.wait(); |
||||
|
||||
const isAutomine: boolean = await hre.network.provider.send( |
||||
'hardhat_getAutomine', |
||||
); |
||||
|
||||
// Generate artificial traffic
|
||||
let messages = Number.parseInt(taskArgs.messages) || 0; |
||||
const run_forever = messages === 0; |
||||
while (run_forever || messages-- > 0) { |
||||
// Round robin origin chain
|
||||
const local = core.chains()[messages % core.chains().length]; |
||||
// Random remote chain
|
||||
const remote: ChainName = randomElement(await core.remoteChains(local)); |
||||
const remoteId = multiProvider.getDomainId(remote); |
||||
const contracts = core.getContracts(local); |
||||
const mailbox = contracts.mailbox; |
||||
await setMailboxHook( |
||||
mailbox, |
||||
addresses, |
||||
local, |
||||
MailboxHookType.DEFAULT, |
||||
taskArgs.defaultHook, |
||||
); |
||||
await setMailboxHook( |
||||
mailbox, |
||||
addresses, |
||||
local, |
||||
MailboxHookType.REQUIRED, |
||||
taskArgs.requiredHook, |
||||
); |
||||
const quote = await mailbox['quoteDispatch(uint32,bytes32,bytes)']( |
||||
remoteId, |
||||
addressToBytes32(recipient.address), |
||||
'0x1234', |
||||
); |
||||
await recipient['dispatchToSelf(address,uint32,bytes)']( |
||||
mailbox.address, |
||||
remoteId, |
||||
'0x1234', |
||||
{ |
||||
value: quote, |
||||
}, |
||||
); |
||||
console.log( |
||||
`send to ${recipient.address} on ${remote} via mailbox ${ |
||||
mailbox.address |
||||
} on ${local} with nonce ${(await mailbox.nonce()) - 1}`,
|
||||
); |
||||
console.log(await chainSummary(core, local)); |
||||
console.log(await chainSummary(core, remote)); |
||||
|
||||
await sleep(timeout); |
||||
} |
||||
|
||||
while (taskArgs.mineforever && isAutomine) { |
||||
await hre.network.provider.send('hardhat_mine', ['0x01']); |
||||
await sleep(timeout); |
||||
} |
||||
}, |
||||
); |
||||
|
||||
/** |
||||
* @type import('hardhat/config').HardhatUserConfig |
||||
*/ |
||||
module.exports = { |
||||
solidity: { |
||||
version: '0.7.6', |
||||
}, |
||||
networks: { |
||||
hardhat: { |
||||
mining: { |
||||
auto: true, |
||||
interval: 2000, |
||||
}, |
||||
}, |
||||
}, |
||||
}; |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue