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

feat: transaction details and deployment info #33

Merged
merged 7 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@
"@types/sinon": "^17",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"chalk": "^5.3.0",
"eslint": "^8",
"hardhat": "^2.0.0",
"mocha": "^10",
"sinon": "^17.0.1",
"terminal-link": "^3.0.0",
"ts-node": "^10",
"typescript": "^5"
},
Expand Down
84 changes: 79 additions & 5 deletions packages/plugin/src/MultichainHardhatRuntimeEnvironmentField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ import Web3, {
PayableCallOptions,
} from "web3";
import { vars } from "hardhat/config";
import chalk from "chalk";
import terminalLink from "terminal-link";
import {
getConfigEnvironmentVariable,
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;
Expand Down Expand Up @@ -62,7 +65,10 @@ export class MultichainHardhatRuntimeEnvironmentField {
contractName: string,
networkArgs: NetworkArguments<Abi>,
options?: DeployOptions
): Promise<Transaction | void> {
): Promise<{
deploymentInfo: DeploymentInfo[];
receipt: Transaction;
} | void> {
const artifact = this.hre.artifacts.readArtifactSync(contractName);

return this.deployMultichainBytecode(
Expand All @@ -78,7 +84,10 @@ export class MultichainHardhatRuntimeEnvironmentField {
contractAbi: Abi,
networkArgs: NetworkArguments<Abi>,
options?: DeployOptions
): Promise<Transaction | void> {
): Promise<{
deploymentInfo: DeploymentInfo[];
receipt: Transaction;
} | void> {
if (!this.isValidated) await this.validateConfig();
if (!this.web3) return;

Expand Down Expand Up @@ -118,8 +127,8 @@ export class MultichainHardhatRuntimeEnvironmentField {
value: sumedFees(fees),
};
}

return adapterContract.methods
console.log("Sending transaction...");
const receipt = await adapterContract.methods
.deploy(
contractBytecode,
this.gasLimit,
Expand All @@ -131,5 +140,70 @@ export class MultichainHardhatRuntimeEnvironmentField {
fees
)
.send(payableTxOptions);
const networkNames = Object.keys(networkArgs);
const { transactionHash } = receipt;
console.log(
`Multichain deployment initiated, transaction hash: ${chalk.bold(
transactionHash
)}

` +
"\n" +
"Destinaton networks:" +
networkNames.join("\r\n")
);

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 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 deploying on ${chalk.bold(
network.toUpperCase()
)}: ${chalk.bold(contractAddress)}`
);

const explorerUrl = await transferStatusInterval(
this.hre.config.multichain.environment,
transactionHash,
domainChainID
);
const explorerLink = terminalLink(explorerUrl, explorerUrl);
console.log(
`Bridge transfer executed. More details: ${chalk.underline(
explorerLink
)}`
);

return {
network,
contractAddress,
explorerUrl,
transactionHash,
};
})
);

return {
receipt,
deploymentInfo,
};
}
}
7 changes: 7 additions & 0 deletions packages/plugin/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,10 @@ export interface DeployOptions {
isUniquePerChain?: boolean;
customNonPayableTxOptions?: NonPayableCallOptions;
}

export interface DeploymentInfo {
network: string;
contractAddress: string;
explorerUrl: string;
transactionHash: string;
}
39 changes: 38 additions & 1 deletion packages/plugin/src/utils.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -151,3 +155,36 @@ export function mapNetworkArgs<Abi extends ContractAbi = any>(
initDatas,
};
}

export async function transferStatusInterval(
environment: Environment,
txHash: string,
domainID: number
): Promise<string> {
let explorerUrl: string = "";

await new Promise((resolve) => {
let controller: AbortController;
setInterval(() => {
controller = new AbortController();
void getTransferStatusData(environment, txHash, domainID.toString()).then(
(transferStatus) => {
explorerUrl = transferStatus.explorerUrl;

if (transferStatus.status === "executed") {
controller.abort();
resolve(explorerUrl);
}
if (transferStatus.status === "failed") {
throw new HardhatPluginError(
"@chainsafe/hardhat-plugin-multichain-deploy",
`Bridge transfer failed`
);
}
}
);
}, 1000);
});

return explorerUrl;
}
47 changes: 46 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,12 @@ __metadata:
"@types/sinon": ^17
chai: ^4.2.0
chai-as-promised: ^7.1.1
chalk: ^5.3.0
eslint: ^8
hardhat: ^2.0.0
mocha: ^10
sinon: ^17.0.1
terminal-link: ^3.0.0
ts-node: ^10
typescript: ^5
web3: ^4.3.0
Expand Down Expand Up @@ -3692,6 +3694,15 @@ __metadata:
languageName: node
linkType: hard

"ansi-escapes@npm:^5.0.0":
version: 5.0.0
resolution: "ansi-escapes@npm:5.0.0"
dependencies:
type-fest: ^1.0.2
checksum: f705cc7fbabb981ddf51562cd950792807bccd7260cc3d9478a619dda62bff6634c87ca100f2545ac7aade9b72652c4edad8c7f0d31a0b949b5fa58f33eaf0d0
languageName: node
linkType: hard

"ansi-regex@npm:^3.0.0":
version: 3.0.1
resolution: "ansi-regex@npm:3.0.1"
Expand Down Expand Up @@ -4549,6 +4560,13 @@ __metadata:
languageName: node
linkType: hard

"chalk@npm:^5.3.0":
version: 5.3.0
resolution: "chalk@npm:5.3.0"
checksum: 8297d436b2c0f95801103ff2ef67268d362021b8210daf8ddbe349695333eb3610a71122172ff3b0272f1ef2cf7cc2c41fdaa4715f52e49ffe04c56340feed09
languageName: node
linkType: hard

"charenc@npm:>= 0.0.1":
version: 0.0.2
resolution: "charenc@npm:0.0.2"
Expand Down Expand Up @@ -11394,7 +11412,7 @@ __metadata:
languageName: node
linkType: hard

"supports-color@npm:^7.1.0, supports-color@npm:^7.2.0":
"supports-color@npm:^7.0.0, supports-color@npm:^7.1.0, supports-color@npm:^7.2.0":
version: 7.2.0
resolution: "supports-color@npm:7.2.0"
dependencies:
Expand All @@ -11403,6 +11421,16 @@ __metadata:
languageName: node
linkType: hard

"supports-hyperlinks@npm:^2.2.0":
version: 2.3.0
resolution: "supports-hyperlinks@npm:2.3.0"
dependencies:
has-flag: ^4.0.0
supports-color: ^7.0.0
checksum: 4057f0d86afb056cd799602f72d575b8fdd79001c5894bcb691176f14e870a687e7981e50bc1484980e8b688c6d5bcd4931e1609816abb5a7dc1486b7babf6a1
languageName: node
linkType: hard

"supports-preserve-symlinks-flag@npm:^1.0.0":
version: 1.0.0
resolution: "supports-preserve-symlinks-flag@npm:1.0.0"
Expand Down Expand Up @@ -11498,6 +11526,16 @@ __metadata:
languageName: node
linkType: hard

"terminal-link@npm:^3.0.0":
version: 3.0.0
resolution: "terminal-link@npm:3.0.0"
dependencies:
ansi-escapes: ^5.0.0
supports-hyperlinks: ^2.2.0
checksum: 2ccf93f474d9c4fe1ac75764a48836e61c281def08f4aff154696bc83dd764078ee2f5a6a6148382fb928943d53f44313ae513c5f457649d2961a95e5cd343b3
languageName: node
linkType: hard

"terser-webpack-plugin@npm:^5.3.7":
version: 5.3.9
resolution: "terser-webpack-plugin@npm:5.3.9"
Expand Down Expand Up @@ -11774,6 +11812,13 @@ __metadata:
languageName: node
linkType: hard

"type-fest@npm:^1.0.2":
version: 1.4.0
resolution: "type-fest@npm:1.4.0"
checksum: a3c0f4ee28ff6ddf800d769eafafcdeab32efa38763c1a1b8daeae681920f6e345d7920bf277245235561d8117dab765cb5f829c76b713b4c9de0998a5397141
languageName: node
linkType: hard

"type-is@npm:~1.6.18":
version: 1.6.18
resolution: "type-is@npm:1.6.18"
Expand Down
Loading