|
|
|
@ -1,5 +1,11 @@ |
|
|
|
|
import { Mailbox } from '@hyperlane-xyz/core'; |
|
|
|
|
import { Address, ProtocolType, rootLogger } from '@hyperlane-xyz/utils'; |
|
|
|
|
import { |
|
|
|
|
Address, |
|
|
|
|
Domain, |
|
|
|
|
ProtocolType, |
|
|
|
|
assert, |
|
|
|
|
rootLogger, |
|
|
|
|
} from '@hyperlane-xyz/utils'; |
|
|
|
|
|
|
|
|
|
import { |
|
|
|
|
attachContractsMap, |
|
|
|
@ -26,30 +32,38 @@ import { EvmCoreReader } from './EvmCoreReader.js'; |
|
|
|
|
import { EvmIcaModule } from './EvmIcaModule.js'; |
|
|
|
|
import { HyperlaneCoreDeployer } from './HyperlaneCoreDeployer.js'; |
|
|
|
|
import { CoreFactories } from './contracts.js'; |
|
|
|
|
import { CoreConfigSchema } from './schemas.js'; |
|
|
|
|
|
|
|
|
|
export type DeployedCoreAdresses = HyperlaneAddresses<CoreFactories> & { |
|
|
|
|
testRecipient: Address; |
|
|
|
|
timelockController?: Address; // Can be optional because it is only deployed if config.upgrade = true
|
|
|
|
|
interchainAccountRouter: Address; |
|
|
|
|
interchainAccountIsm: Address; |
|
|
|
|
} & HyperlaneAddresses<ProxyFactoryFactories>; |
|
|
|
|
type DeployedCoreAddresses = Partial< |
|
|
|
|
HyperlaneAddresses<CoreFactories> & { |
|
|
|
|
testRecipient: Address; |
|
|
|
|
timelockController: Address; |
|
|
|
|
interchainAccountRouter: Address; |
|
|
|
|
interchainAccountIsm: Address; |
|
|
|
|
} & HyperlaneAddresses<ProxyFactoryFactories> |
|
|
|
|
>; |
|
|
|
|
|
|
|
|
|
export class EvmCoreModule extends HyperlaneModule< |
|
|
|
|
ProtocolType.Ethereum, |
|
|
|
|
CoreConfig, |
|
|
|
|
DeployedCoreAdresses |
|
|
|
|
DeployedCoreAddresses |
|
|
|
|
> { |
|
|
|
|
protected logger = rootLogger.child({ module: 'EvmCoreModule' }); |
|
|
|
|
protected coreReader: EvmCoreReader; |
|
|
|
|
public readonly chainName: string; |
|
|
|
|
|
|
|
|
|
protected constructor( |
|
|
|
|
// We use domainId here because MultiProvider.getDomainId() will always
|
|
|
|
|
// return a number, and EVM the domainId and chainId are the same.
|
|
|
|
|
public readonly domainId: Domain; |
|
|
|
|
|
|
|
|
|
constructor( |
|
|
|
|
protected readonly multiProvider: MultiProvider, |
|
|
|
|
args: HyperlaneModuleParams<CoreConfig, DeployedCoreAdresses>, |
|
|
|
|
args: HyperlaneModuleParams<CoreConfig, DeployedCoreAddresses>, |
|
|
|
|
) { |
|
|
|
|
super(args); |
|
|
|
|
this.coreReader = new EvmCoreReader(multiProvider, this.args.chain); |
|
|
|
|
this.chainName = this.multiProvider.getChainName(this.args.chain); |
|
|
|
|
this.domainId = multiProvider.getDomainId(args.chain); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -57,11 +71,53 @@ export class EvmCoreModule extends HyperlaneModule< |
|
|
|
|
* @returns The core config. |
|
|
|
|
*/ |
|
|
|
|
public async read(): Promise<CoreConfig> { |
|
|
|
|
assert(this.args.addresses.mailbox, 'Mailbox not provided for read'); |
|
|
|
|
return this.coreReader.deriveCoreConfig(this.args.addresses.mailbox); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public async update(_config: CoreConfig): Promise<AnnotatedEV5Transaction[]> { |
|
|
|
|
throw new Error('Method not implemented.'); |
|
|
|
|
/** |
|
|
|
|
* Updates the core contracts with the provided configuration. |
|
|
|
|
* |
|
|
|
|
* @param expectedConfig - The configuration for the core contracts to be updated. |
|
|
|
|
* @returns An array of Ethereum transactions that were executed to update the contract. |
|
|
|
|
*/ |
|
|
|
|
public async update( |
|
|
|
|
expectedConfig: CoreConfig, |
|
|
|
|
): Promise<AnnotatedEV5Transaction[]> { |
|
|
|
|
CoreConfigSchema.parse(expectedConfig); |
|
|
|
|
const actualConfig = await this.read(); |
|
|
|
|
|
|
|
|
|
const transactions: AnnotatedEV5Transaction[] = []; |
|
|
|
|
|
|
|
|
|
transactions.push( |
|
|
|
|
...this.createMailboxOwnershipTransferTx(actualConfig, expectedConfig), |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
return transactions; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Create a transaction to transfer ownership of an existing mailbox with a given config. |
|
|
|
|
* |
|
|
|
|
* @param actualConfig - The on-chain core configuration. |
|
|
|
|
* @param expectedConfig - The expected token core configuration. |
|
|
|
|
* @returns Ethereum transaction that need to be executed to update the owner. |
|
|
|
|
*/ |
|
|
|
|
createMailboxOwnershipTransferTx( |
|
|
|
|
actualConfig: CoreConfig, |
|
|
|
|
expectedConfig: CoreConfig, |
|
|
|
|
): AnnotatedEV5Transaction[] { |
|
|
|
|
assert( |
|
|
|
|
this.args.addresses.mailbox, |
|
|
|
|
'Mailbox not provided for update ownership', |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
return EvmCoreModule.createTransferOwnershipTx({ |
|
|
|
|
actualOwner: actualConfig.owner, |
|
|
|
|
expectedOwner: expectedConfig.owner, |
|
|
|
|
deployedAddress: this.args.addresses.mailbox, |
|
|
|
|
chainId: this.domainId, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -102,7 +158,7 @@ export class EvmCoreModule extends HyperlaneModule< |
|
|
|
|
multiProvider: MultiProvider; |
|
|
|
|
chain: ChainNameOrId; |
|
|
|
|
contractVerifier?: ContractVerifier; |
|
|
|
|
}): Promise<DeployedCoreAdresses> { |
|
|
|
|
}): Promise<DeployedCoreAddresses> { |
|
|
|
|
const { config, multiProvider, chain, contractVerifier } = params; |
|
|
|
|
const chainName = multiProvider.getChainName(chain); |
|
|
|
|
|
|
|
|
@ -167,7 +223,7 @@ export class EvmCoreModule extends HyperlaneModule< |
|
|
|
|
).address; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Deploy Test Receipient
|
|
|
|
|
// Deploy Test Recipient
|
|
|
|
|
const testRecipient = ( |
|
|
|
|
await coreDeployer.deployTestRecipient( |
|
|
|
|
chainName, |
|
|
|
|