diff --git a/docs/plugin/DeployOptions.md b/docs/plugin/DeployOptions.md new file mode 100644 index 0000000..7d2429f --- /dev/null +++ b/docs/plugin/DeployOptions.md @@ -0,0 +1,42 @@ +# DeployOptions + +DeployOptions provides additional configuration settings for deploying smart contracts across multiple blockchain networks. These options allow for customization of the deployment process, including contract address generation, network-specific deployments, and transaction settings. + +## Interface + +```ts +interface DeployOptions { + salt?: MatchPrimitiveType<"bytes32", unknown>; + isUniquePerChain?: boolean; + customNonPayableTxOptions?: NonPayableCallOptions; +} +``` + +## Usages + +### salt +- **Description**: Provides entropy for generating a unique contract address. This can be a hexadecimal string `HexString` or a `Uint8Array`. +- **Purpose**: Used to create a predictable yet unique address for the smart contract across different deployments. + +### isUniquePerChain +- **Description**: A boolean flag that, when set to true, ensures the contract is deployed with distinct addresses on each blockchain network. + +### customNonPayableTxOptions +- **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/). + +## 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. + +```ts +const options: DeployOptions = { + salt: "0x0d832502cc5af3e4cf5c9118b013acea29808616be3bd44f89d231c1c56af61f", + isUniquePerChain: true, + customNonPayableTxOptions: { + from: "0x1605B51d318bFfBFd246D565Ee55522b66ddc34a", + }, +}; +``` + +This setup ensures a predictable and unique deployment process tailored to specific requirements of a multichain environment. \ No newline at end of file diff --git a/docs/plugin/NetworkArguments.md b/docs/plugin/NetworkArguments.md new file mode 100644 index 0000000..2db2bc5 --- /dev/null +++ b/docs/plugin/NetworkArguments.md @@ -0,0 +1,62 @@ +# NetworkArguments + +NetworkArguments define the configuration for deploying smart contracts across various blockchain networks. This setup allows for specifying different deployment settings for each network, providing detailed control over the deployment process. + +## Interface + +```typescript +interface NetworkArguments { + [network: string]: NetworkArgument; +} + +interface NetworkArgument { + args: ContractConstructorArgs; + initData?: { + initMethodName: keyof ContractMethods; + initMethodArgs: unknown[]; + }; +} +``` + +## Usages + +### NetworkArguments + - **Description**: An object where each key is a network name registered on Sygma, mapped to their respective `NetworkArgument`. This structure facilitates network-specific deployment configurations, allowing for deployment across networks recognized by the Sygma protocol. + - **Purpose**: Enables the deployment of contracts to specified networks, leveraging the configurations tailored for each network as recognized by Sygma. + +### NetworkArgument +- **args** + - **Description**: Constructor arguments for the contract on each specified network. + - **Purpose**: Used for initializing the contract upon deployment. + +- **initData** + - **Description**: An optional object that specifies additional initialization to be performed after the contract's deployment. When used, it must include both `initMethodName` and `initMethodArgs`. + - **initMethodName** + - **Description**: Specifies the contract method to call for further initialization. + - **initMethodArgs** + - **Description**: An array of values that correspond to the parameters required by the method named in `initMethodName`. These arguments are passed directly to the initialization method call. + +## Example + +```typescript +const abi = [ ... ] as const; + +const networks: NetworkArguments = { + sepolia: { + args: [18, "zToken"], + initData: { + initMethodName: "setName", + initMethodArgs: ["SuperToken"], + } + }, + goerli: { + args: [18, "zToken"], + initData: { + initMethodName: "setName", + initMethodArgs: ["GummyToken"], + } + }, +}; +``` + +This example shows how `NetworkArguments` can be used to deploy a contract with specific constructor arguments on the Sepolia and Goerli test networks. It includes optional post-deployment initialization to set unique token names for each network through the `setName` method. diff --git a/packages/plugin/README.md b/packages/plugin/README.md index 89ad591..b3d09fc 100644 --- a/packages/plugin/README.md +++ b/packages/plugin/README.md @@ -1,58 +1,78 @@ -# Chainsafe's Hardhat Plugin for Multichain deployment with Sygma - -Experience the seamless integration of Hardhat with Sygma: the ultimate plugin for effortlessly deploying your Ethereum smart contracts across multiple chains. -Embrace the power of Sygma protocol, and transform your deployment process into a streamlined, efficient, and multi-chain adventure. -With this tool, you're not just deploying contracts; you're unlocking new horizons in the blockchain ecosystem. +# ChainSafe's Hardhat Plugin for Multichain Deployment with Sygma +Unlock the full potential of Hardhat with Sygma: the premier plugin for effortlessly deploying your Ethereum smart contracts across multiple blockchain networks. Leveraging the Sygma protocol, this tool revolutionizes your deployment process, making it efficient, streamlined, and truly multi-chain. With ChainSafe's plugin, you're not just deploying contracts—you're exploring new possibilities within the blockchain ecosystem. ## Installation +To install, run: + ```bash -npm install --save-dev @chainsafe/hardhat-plugin-multichain-deploy +npm install --save-dev @chainsafe/hardhat-plugin-multichain-deploy @buildwithsygma/sygma-sdk-core ``` -Import the plugin in your `hardhat.config.js``: +### Importing the Plugin + +For JavaScript users, add this line to your `hardhat.config.js`: ```js require("@chainsafe/hardhat-plugin-multichain-deploy"); ``` -Or if you are using TypeScript, in your `hardhat.config.ts``: +For TypeScript users, include it in your `hardhat.config.ts`: ```js import "@chainsafe/hardhat-plugin-multichain-deploy"; ``` -## Environment extensions +## Environment Extensions + +The plugin adds a `multichain` namespace to the Hardhat Runtime Environment (HRE), introducing new methods for deployment: + +```ts +async deployMultichain( + contractName: string, + networkArgs: NetworkArguments, + options?: DeployOptions +): Promise<{ + deploymentInfo: DeploymentInfo[]; + receipt: Transaction; +} | void> + +async deployMultichainBytecode( + contractBytecode: string, + contractAbi: Abi, + networkArgs: NetworkArguments, + options?: DeployOptions +): Promise<{ + deploymentInfo: DeploymentInfo[]; + receipt: Transaction; +} | void> +``` + +- `contractName`: Name of the contract for deployment. +- `contractBytecode`: Compiled bytecode of the contract. +- `contractAbi`: Contract ABI, detailing methods and structures for interaction. +- `networkArgs`: Maps network identifiers to deployment arguments. Refer to [NetworkArguments.md](../../docs/plugin/NetworkArguments.md) for more. +- `options`: Optional deployment settings. Details in [DeployOptions.md](../../docs/plugin/DeployOptions.md). -The package introduces a `multichain` namespace to the Hardhat Runtime Environment (HRE). +## Environment Variable -New methods introduced: - * `async waitInitialization(): Promise`: Returns a promise. Wait for this promise to resolve to ensure readiness for using Sygma. - * `async deployMultichain(nameOrBytecode: string, arguments: string[], options?: Object): Promise`: Deploys a smart contract. - * `nameOrBytecode`: Name or bytecode of the smart contract. - * `arguments`: Arguments for the smart contract deployment. - * `options`: Additional deployment options (details TBD). +- `ADAPTER_ADDRESS`: Address of the adapter, facilitating deployment across chains with Sygma. Use this if deploying custom adapters. ## Configuration -The Hardhat Plugin Multichain Deployment plugin requires specific configurations for successful multi-chain deployment. +To utilize the Multichain Deployment plugin, specific settings are required: -This plugin extends introduce new name space called `multichain` with options: - * `environment`: Specifies the Sygma environment for deployment. - * Import `Environment` from `@buildwithsygma/sygma-sdk-core` for constant values. - * Options: `mainnet`, `testnet`, `devnet`, `local`. - * `deploymentNetworks`: List of networks for deployment. - * Ensure network names match those in `networks`. - * Networks must correspond with Sygma routes. Refer to [Sygma documentation](https://docs.buildwithsygma.com/environments) for routes. +- `multichain` namespace: Configures deployment settings. + - `environment`: Defines the Sygma environment. Use `Environment` from `@buildwithsygma/sygma-sdk-core` for constants. -Example configuration: +### Example Configuration ```typescript import { Environment } from "@buildwithsygma/sygma-sdk-core"; const config: HardhatUserConfig = { - // ... other configurations ... + // Other configurations... defaultNetwork: "goerli", networks: { sepolia: { ... }, @@ -61,25 +81,30 @@ const config: HardhatUserConfig = { }, multichain: { environment: Environment.TESTNET, - deploymentNetworks: ["sepolia", "optimisticGoerli"], }, }; ``` -## Usages - -### TODO +## Usage -After familiarizing yourself with the capabilities, let's see how everything works together. +With the setup complete, let’s deploy an ERC20 contract across multiple chains: -Example scenario: You've created an ERC20 contract and want to deploy it across multiple chains using the configuration mentioned above. ```typescript -// Deploy the contract -const tx = await hre.multichain.deployMultichain('MySuperToken', [name, symbol, decimals], { singer: web3signer }); +const networkArgs = { + sepolia: { + args: [name, symbol, decimals], + }, + goerli: { + args: [name, symbol, decimals], + }, +}; +const options = { + salt: "0xcafe00000000000000000000000000000000000000000000000000000000cafe", +}; -console.log("Transaction Hash: ", tx); +this.hre.multichain.deployMultichain("MySuperToken", networkArgs, options); ``` ## Contribution -For contributing to the project, please refer to the [root readme](../../README.md) file. +To contribute to this project, please see the [monorepo readme](../../README.md) for guidelines. diff --git a/packages/plugin/src/MultichainHardhatRuntimeEnvironmentField.ts b/packages/plugin/src/MultichainHardhatRuntimeEnvironmentField.ts index 75ed528..1e0ed5b 100644 --- a/packages/plugin/src/MultichainHardhatRuntimeEnvironmentField.ts +++ b/packages/plugin/src/MultichainHardhatRuntimeEnvironmentField.ts @@ -51,13 +51,27 @@ export class MultichainHardhatRuntimeEnvironmentField { } /** - * @param contractName name of the contract - * @param networkArgs record key is name of the networks on which contract is being deployed - * @param args contract contructor args - * @param initData optional init method details, method name and args required - * @param salt optional or generated by default from randombytes(32) - * @param isUniquePerChain optional - * @param customNonPayableTxOptions non payable options for web3 deploy.method.send(), payable summed fees are always calculated by the method + * Deploys a contract to multiple blockchain networks. + * + * @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. + * + * @example + * ``` + * const networkArgs = { + * sepolia: { + * args: [ 18, "token" ], + * }, + * goerli: { ... }, + * }; + * const options = { + * salt: "0xcafe00000000000000000000000000000000000000000000000000000000cafe", + * }; + * + * this.hre.multichain.deployMultichain("HelloContract", networkArgs, options); + * ``` */ public async deployMultichain( contractName: string, @@ -77,6 +91,33 @@ export class MultichainHardhatRuntimeEnvironmentField { ); } + /** + * Deploys a contract using its bytecode and ABI to multiple blockchain networks. + * + * @param contractBytecode - The bytecode of the contract to be deployed. This is the compiled code of the contract. + * @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. + * + * @example + * ``` + * const contractBytecode = "0x60a060405234801561001057600080fd5b5060405161052b38038061052b83..."; + * const contractAbi = [{ ... }, { ... }]; + * + * const networkArgs = { + * sepolia: { + * args: [ 18, "token" ], + * }, + * goerli: { ... }, + * }; + * const options = { + * salt: "0xcafe00000000000000000000000000000000000000000000000000000000cafe", + * }; + * + * this.hre.multichain.deployMultichain(contractBytecode, contractAbi, networkArgs, options); + * ``` + */ public async deployMultichainBytecode( contractBytecode: string, contractAbi: Abi, diff --git a/packages/plugin/src/types.ts b/packages/plugin/src/types.ts index 7dd6037..d465a88 100644 --- a/packages/plugin/src/types.ts +++ b/packages/plugin/src/types.ts @@ -14,15 +14,17 @@ export type DeploymentNetwork = | "holesky" | string; -export type NetworkArguments = { - [network in DeploymentNetwork]: { - args: ContractConstructorArgs; - initData?: { - initMethodName: keyof ContractMethods; - //impossible to type unless we do something like this.getInitMethod(artifact, methodName).encode(args); - initMethodArgs: unknown[]; - }; +interface NetworkArgument { + args: ContractConstructorArgs; + initData?: { + initMethodName: keyof ContractMethods; + //impossible to type unless we do something like this.getInitMethod(artifact, methodName).encode(args); + initMethodArgs: unknown[]; }; +} + +export type NetworkArguments = { + [network in DeploymentNetwork]: NetworkArgument; }; export interface DeployOptions {