diff --git a/packages/plugin/src/MultichainHardhatRuntimeEnvironmentField.ts b/packages/plugin/src/MultichainHardhatRuntimeEnvironmentField.ts index d7f109d..e8951c0 100644 --- a/packages/plugin/src/MultichainHardhatRuntimeEnvironmentField.ts +++ b/packages/plugin/src/MultichainHardhatRuntimeEnvironmentField.ts @@ -12,9 +12,10 @@ import { getNetworkChainId, mapNetworkArgs, sumedFees, + transferStatusInterval, } from "./utils"; import { AdapterABI } from "./adapterABI"; -import { DeployOptions, NetworkArguments } from "./types"; +import { DeployOptions, DeploymentInfo, NetworkArguments } from "./types"; export class MultichainHardhatRuntimeEnvironmentField { private isValidated: boolean = false; @@ -62,7 +63,10 @@ export class MultichainHardhatRuntimeEnvironmentField { contractName: string, networkArgs: NetworkArguments, options?: DeployOptions - ): Promise { + ): Promise<{ + deploymentInfo: DeploymentInfo[]; + receipt: Transaction; + } | void> { const artifact = this.hre.artifacts.readArtifactSync(contractName); return this.deployMultichainBytecode( @@ -78,7 +82,10 @@ export class MultichainHardhatRuntimeEnvironmentField { contractAbi: Abi, networkArgs: NetworkArguments, options?: DeployOptions - ): Promise { + ): Promise<{ + deploymentInfo: DeploymentInfo[]; + receipt: Transaction; + } | void> { if (!this.isValidated) await this.validateConfig(); if (!this.web3) return; @@ -118,8 +125,8 @@ export class MultichainHardhatRuntimeEnvironmentField { value: sumedFees(fees), }; } - - return adapterContract.methods + console.log("Sending transaction..."); + const receipt = await adapterContract.methods .deploy( contractBytecode, this.gasLimit, @@ -131,5 +138,58 @@ export class MultichainHardhatRuntimeEnvironmentField { fees ) .send(payableTxOptions); + + const { from, to, transactionHash } = receipt; + console.log( + `Transacion sent from ${from} to ${to}, transaction hash: ${transactionHash}` + ); + + const [deployer] = await this.web3.eth.getAccounts(); + + const destinationDomainChainIDs = deployDomainIDs.map((deployDomainID) => { + const deployDomain: Domain = this.domains.find( + (domain) => BigInt(domain.id) === deployDomainID + )!; + return deployDomain.chainId; + }); + + const networkNames = Object.keys(networkArgs); + + const deploymentInfo: DeploymentInfo[] = await Promise.all( + destinationDomainChainIDs.map(async (domainChainID, index) => { + const network = networkNames[index]; + + const contractAddress = await adapterContract.methods + .computeContractAddressForChain( + deployer, + salt, + isUniquePerChain, + domainChainID + ) + .call(); + console.log( + `Contract address for ${network.toUpperCase()}: ${contractAddress}` + ); + + const explorerUrl = transferStatusInterval( + this.hre.config.multichain.environment, + transactionHash, + domainChainID + ); + console.log(`Bridge transfer executed, explorer url: ${explorerUrl}`); + + return { + network, + contractAddress, + explorerUrl, + transactionHash, + }; + }) + ); + + return { + receipt, + deploymentInfo, + }; } } diff --git a/packages/plugin/src/types.ts b/packages/plugin/src/types.ts index a3f5dda..7714cf2 100644 --- a/packages/plugin/src/types.ts +++ b/packages/plugin/src/types.ts @@ -22,3 +22,10 @@ export interface DeployOptions { isUniquePerChain?: boolean; customNonPayableTxOptions?: NonPayableCallOptions; } + +export interface DeploymentInfo { + network: string; + contractAddress: string; + explorerUrl: string; + transactionHash: string; +} diff --git a/packages/plugin/src/utils.ts b/packages/plugin/src/utils.ts index f0716b8..d08aa57 100644 --- a/packages/plugin/src/utils.ts +++ b/packages/plugin/src/utils.ts @@ -1,6 +1,10 @@ import assert from "assert"; import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { Domain, Environment } from "@buildwithsygma/sygma-sdk-core"; +import { + Domain, + Environment, + getTransferStatusData, +} from "@buildwithsygma/sygma-sdk-core"; import { AbiFallbackFragment, Bytes, @@ -150,3 +154,29 @@ export function mapNetworkArgs( initDatas, }; } + +export function transferStatusInterval( + environment: Environment, + txHash: string, + domainID: number +): string { + let controller: AbortController; + let explorerUrl: string = ""; + + const interval = setInterval(() => { + controller = new AbortController(); + void getTransferStatusData(environment, txHash, domainID.toString()).then( + (transferStatus) => { + explorerUrl = transferStatus.explorerUrl; + + if (transferStatus.status === "executed") { + clearInterval(interval); + controller.abort(); + return; + } + } + ); + }, 1000) as unknown as number; + + return explorerUrl; +}