Skip to content

Commit

Permalink
Merge branch 'master' into irubido/initLocalEnvironment
Browse files Browse the repository at this point in the history
# Conflicts:
#	packages/plugin/src/MultichainHardhatRuntimeEnvironmentField.ts
  • Loading branch information
BeroBurny committed Feb 7, 2024
2 parents 58227bf + 6149872 commit cb40277
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 51 deletions.
6 changes: 6 additions & 0 deletions docs/plugin/DeployOptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface DeployOptions {
salt?: MatchPrimitiveType<"bytes32", unknown>;
isUniquePerChain?: boolean;
customNonPayableTxOptions?: NonPayableCallOptions;
adapterAddress?: Address;
}
```

Expand All @@ -25,6 +26,10 @@ interface DeployOptions {
- **Details**: Customizes transaction settings for contract calls. This option allows setting sender details and other transaction parameters.
- **Reference**: For detailed information about `NonPayableCallOptions`, please refer to the [web3.js documentation](https://docs.web3js.org/api/web3-types/interface/NonPayableCallOptions/).

### adapterAddress
- **Description**: Specifies address of a custom adapter for deployments. This is useful for local testing or when needing to interact with a specific deployment strategy, such as a mocked adapter.
- **Purpose**: Allows the user to override the default deployment adapter with their own, providing greater flexibility and control over the deployment process.

## Example

In this example, `DeployOptions` is configured to deploy a contract with a specified salt for address generation, ensuring unique addresses on each chain, and customizing the sender address for the deployment transaction.
Expand All @@ -36,6 +41,7 @@ const options: DeployOptions = {
customNonPayableTxOptions: {
from: "0x1605B51d318bFfBFd246D565Ee55522b66ddc34a",
},
adapterAddress: "0x1234567890ABCDEF1234567890ABCDEF12345678"
};
```

Expand Down
92 changes: 47 additions & 45 deletions packages/plugin/src/MultichainHardhatRuntimeEnvironmentField.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { Config, Domain } from "@buildwithsygma/sygma-sdk-core";
import Web3, {
ContractAbi,
Transaction,
utils,
PayableCallOptions,
} from "web3";
import Web3, { ContractAbi, utils, PayableCallOptions } from "web3";
import { vars } from "hardhat/config";
import {
getConfigEnvironmentVariable,
Expand All @@ -20,7 +15,11 @@ import {
CreateXABI,
CreateXBytecode,
} from "./adapterABI";
import { DeployOptions, DeploymentInfo, NetworkArguments } from "./types";
import {
DeployOptions,
NetworkArguments,
DeployMultichainResponse,
} from "./types";

export class MultichainHardhatRuntimeEnvironmentField {
private isInitiated: boolean = false;
Expand Down Expand Up @@ -98,10 +97,9 @@ export class MultichainHardhatRuntimeEnvironmentField {
* @param contractName - The name of the contract to be deployed.
* @param networkArgs - An object mapping network identifiers to their deployment arguments. Each network can have unique settings for the deployment. See {@link https://github.com/ChainSafe/hardhat-plugin-multichain-deploy/docs/plugin/NetworkArguments NetworkArguments}.
* @param options - Optional settings for the deployment process. These can include various configurations specific to the deployment. See {@link https://github.com/ChainSafe/hardhat-plugin-multichain-deploy/docs/plugin/DeployOptions DeployOptions}.
* @returns A Promise resolving to a Transaction object or void.
* @returns A Promise resolving to a Transaction object.
*
* @example
* ```
* const networkArgs = {
* sepolia: {
* args: [ 18, "token" ],
Expand All @@ -113,16 +111,12 @@ export class MultichainHardhatRuntimeEnvironmentField {
* };
*
* this.hre.multichain.deployMultichain("HelloContract", networkArgs, options);
* ```
*/
public async deployMultichain<Abi extends ContractAbi = any>(
contractName: string,
networkArgs: NetworkArguments<Abi>,
options?: DeployOptions
): Promise<{
deploymentInfo: DeploymentInfo[];
receipt: Transaction;
}> {
): Promise<DeployMultichainResponse> {
const artifact = this.hre.artifacts.readArtifactSync(contractName);

return this.deployMultichainBytecode(
Expand All @@ -140,10 +134,9 @@ export class MultichainHardhatRuntimeEnvironmentField {
* @param contractAbi - The ABI of the contract. It defines the methods and structures used to interact with the binary contract.
* @param networkArgs - An object mapping network identifiers to their deployment arguments. Each network can have unique settings for the deployment. See {@link https://github.com/ChainSafe/hardhat-plugin-multichain-deploy/docs/plugin/NetworkArguments NetworkArguments}.
* @param options - Optional settings for the deployment process. These can include various configurations specific to the deployment. See {@link https://github.com/ChainSafe/hardhat-plugin-multichain-deploy/docs/plugin/DeployOptions DeployOptions}.
* @returns A Promise resolving to a Transaction object or void.
* @returns A Promise resolving to a Transaction object.
*
* @example
* ```
* const contractBytecode = "0x60a060405234801561001057600080fd5b5060405161052b38038061052b83...";
* const contractAbi = [{ ... }, { ... }];
*
Expand All @@ -157,36 +150,32 @@ export class MultichainHardhatRuntimeEnvironmentField {
* salt: "0xcafe00000000000000000000000000000000000000000000000000000000cafe",
* };
*
* this.hre.multichain.deployMultichain(contractBytecode, contractAbi, networkArgs, options);
* ```
* this.hre.multichain.deployMultichainBytecode(contractBytecode, contractAbi, networkArgs, options);
*/
public async deployMultichainBytecode<Abi extends ContractAbi = any>(
contractBytecode: string,
contractAbi: Abi,
networkArgs: NetworkArguments<Abi>,
options?: DeployOptions
): Promise<{
deploymentInfo: DeploymentInfo[];
receipt: Transaction;
}> {
): Promise<DeployMultichainResponse> {
if (!this.isInitiated) await this.initConfig();

//optional params
const salt = options?.salt ?? utils.randomBytes(32);
const isUniquePerChain = options?.isUniquePerChain ?? false;

//adapter contract
const adapterContract = new this.web3.eth.Contract<typeof AdapterABI>(
AdapterABI,
this.ADAPTER_ADDRESS
);
const adapterAddress = options?.adapterAddress ?? this.ADAPTER_ADDRESS;

const { constructorArgs, initDatas, deployDomainIDs } = mapNetworkArgs(
contractAbi,
networkArgs,
this.domains
);

const adapterContract = new this.web3.eth.Contract<typeof AdapterABI>(
AdapterABI,
adapterAddress
);

const fees = await adapterContract.methods
.calculateDeployFee(
contractBytecode,
Expand Down Expand Up @@ -223,9 +212,7 @@ export class MultichainHardhatRuntimeEnvironmentField {
const networkNames = Object.keys(networkArgs);
const { transactionHash } = receipt;
console.log(
`Multichain deployment initiated, transaction hash: ${transactionHash}
` +
`Multichain deployment initiated, transaction hash: ${transactionHash}` +
"\n" +
"Destinaton networks:" +
networkNames.join("\r\n")
Expand All @@ -240,7 +227,7 @@ export class MultichainHardhatRuntimeEnvironmentField {
return deployDomain.chainId;
});

const deploymentInfo: DeploymentInfo[] = await Promise.all(
await Promise.all(
destinationDomainChainIDs.map(async (domainChainID, index) => {
const network = networkNames[index];

Expand All @@ -255,27 +242,42 @@ export class MultichainHardhatRuntimeEnvironmentField {
console.log(
`Contract deploying on ${network.toUpperCase()}: ${contractAddress}`
);
})
);

return {
transactionHash,
domainIDs: deployDomainIDs,
};
}

/**
* Fetches and logs the deployment information for a smart contract deployed across multiple blockchain networks.
* This function retrieves the status of a contract's deployment on each specified network domain using the transaction hash
* obtained from the `deployMultichain` or `deployMultichainBytecode` function.
*
* @param transactionHash The hash of the transaction returned by `deployMultichain` or `deployMultichainBytecode`.
* @param domainIDs An array of bigint values representing the domain IDs on which the contract was deployed. These IDs correspond
* to the blockchain networks registered on Sygma and should match the ones used during the deployment process.
*
* @example
* const { transactionHash, domainIDs } = await this.hre.multichain.deployMultichain("HelloContract", networkArgs);
* await getDeploymentInfo(transactionHash, domainIDs);
*/
public async getDeploymentInfo(
transactionHash: string,
domainIDs: bigint[]
): Promise<void> {
await Promise.all(
domainIDs.map(async (domainId): Promise<void> => {
const explorerUrl = await transferStatusInterval(
this.hre.config.multichain.environment,
transactionHash,
domainChainID
domainId
);

console.log(`Bridge transfer executed. More details: ${explorerUrl}`);

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

return {
receipt,
deploymentInfo,
};
}
}
11 changes: 6 additions & 5 deletions packages/plugin/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import {
Address,
ContractAbi,
ContractConstructorArgs,
ContractMethods,
HexString,
MatchPrimitiveType,
NonPayableCallOptions,
} from "web3";
Expand Down Expand Up @@ -31,11 +33,10 @@ export interface DeployOptions {
salt?: MatchPrimitiveType<"bytes32", unknown>;
isUniquePerChain?: boolean;
customNonPayableTxOptions?: NonPayableCallOptions;
adapterAddress?: Address;
}

export interface DeploymentInfo {
network: string;
contractAddress: string;
explorerUrl: string;
transactionHash: string;
export interface DeployMultichainResponse {
domainIDs: bigint[];
transactionHash: HexString;
}
2 changes: 1 addition & 1 deletion packages/plugin/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export function mapNetworkArgs<Abi extends ContractAbi = any>(
export async function transferStatusInterval(
environment: Environment,
txHash: string,
domainID: number
domainID: bigint
): Promise<string> {
let explorerUrl: string = "";

Expand Down

0 comments on commit cb40277

Please sign in to comment.