UNPKG

@nomicfoundation/hardhat-viem

Version:
146 lines 6.38 kB
import { HardhatError } from "@nomicfoundation/hardhat-errors"; import { toBigInt } from "@nomicfoundation/hardhat-utils/bigint"; import { resolveLinkedBytecode } from "@nomicfoundation/hardhat-utils/bytecode"; import { ensureError } from "@nomicfoundation/hardhat-utils/error"; import { getContractAddress, getContract } from "viem"; import { getDefaultWalletClient, getPublicClient } from "./clients.js"; export async function deployContract(provider, artifactManager, chainDescriptors, networkName, contractName, constructorArgs = [], deployContractConfig = {}) { const { client, confirmations = 1, libraries = {}, ...deployContractParameters } = deployContractConfig; if (confirmations < 0) { throw new HardhatError(HardhatError.ERRORS.HARDHAT_VIEM.GENERAL.INVALID_CONFIRMATIONS, { error: "Confirmations must be greater than 0.", }); } if (confirmations === 0) { throw new HardhatError(HardhatError.ERRORS.HARDHAT_VIEM.GENERAL.INVALID_CONFIRMATIONS, { error: "deployContract does not support 0 confirmations. Use sendDeploymentTransaction if you want to handle the deployment transaction yourself.", }); } const [publicClient, walletClient, { abi, bytecode }] = await Promise.all([ client?.public ?? getPublicClient(provider, "l1", chainDescriptors, networkName), client?.wallet ?? getDefaultWalletClient(provider, "l1", chainDescriptors, networkName), getContractAbiAndBytecode(artifactManager, contractName, libraries), ]); let deploymentTxHash; // If gasPrice is defined, then maxFeePerGas and maxPriorityFeePerGas // must be undefined because it's a legacy tx. if (deployContractParameters.gasPrice !== undefined) { deploymentTxHash = await walletClient.deployContract({ abi, bytecode, args: constructorArgs, ...deployContractParameters, maxFeePerGas: undefined, maxPriorityFeePerGas: undefined, }); } else { deploymentTxHash = await walletClient.deployContract({ abi, bytecode, args: constructorArgs, ...deployContractParameters, gasPrice: undefined, }); } const { contractAddress } = await publicClient.waitForTransactionReceipt({ hash: deploymentTxHash, confirmations, }); if (contractAddress === null || contractAddress === undefined) { const transaction = await publicClient.getTransaction({ hash: deploymentTxHash, }); throw new HardhatError(HardhatError.ERRORS.HARDHAT_VIEM.GENERAL.DEPLOY_CONTRACT_ERROR, { txHash: deploymentTxHash, blockNumber: transaction.blockNumber, }); } const contract = createContractInstance(contractName, publicClient, walletClient, abi, contractAddress); return contract; } export async function sendDeploymentTransaction(provider, artifactManager, chainDescriptors, networkName, contractName, constructorArgs = [], sendDeploymentTransactionConfig = {}) { const { client, libraries = {}, ...deployContractParameters } = sendDeploymentTransactionConfig; const [publicClient, walletClient, { abi, bytecode }] = await Promise.all([ client?.public ?? getPublicClient(provider, "l1", chainDescriptors, networkName), client?.wallet ?? getDefaultWalletClient(provider, "l1", chainDescriptors, networkName), getContractAbiAndBytecode(artifactManager, contractName, libraries), ]); let deploymentTxHash; // If gasPrice is defined, then maxFeePerGas and maxPriorityFeePerGas // must be undefined because it's a legacy tx. if (deployContractParameters.gasPrice !== undefined) { deploymentTxHash = await walletClient.deployContract({ abi, bytecode, args: constructorArgs, ...deployContractParameters, maxFeePerGas: undefined, maxPriorityFeePerGas: undefined, }); } else { deploymentTxHash = await walletClient.deployContract({ abi, bytecode, args: constructorArgs, ...deployContractParameters, gasPrice: undefined, }); } const deploymentTx = await publicClient.getTransaction({ hash: deploymentTxHash, }); const contractAddress = getContractAddress({ from: walletClient.account.address, nonce: toBigInt(deploymentTx.nonce), }); const contract = createContractInstance(contractName, publicClient, walletClient, abi, contractAddress); return { contract, deploymentTransaction: deploymentTx }; } export async function getContractAt(provider, artifactManager, chainDescriptors, networkName, contractName, address, getContractAtConfig = {}) { const [publicClient, walletClient, artifact] = await Promise.all([ getContractAtConfig.client?.public ?? getPublicClient(provider, "l1", chainDescriptors, networkName), getContractAtConfig.client?.wallet ?? getDefaultWalletClient(provider, "l1", chainDescriptors, networkName), artifactManager.readArtifact(contractName), ]); return createContractInstance(contractName, publicClient, walletClient, artifact.abi, address); } function createContractInstance(_contractName, publicClient, walletClient, abi, address) { const contract = getContract({ address, client: { public: publicClient, wallet: walletClient, }, abi, }); /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Cast it as TS can't infer the type of the contract */ return contract; } async function getContractAbiAndBytecode(artifacts, contractName, libraries) { const artifact = await artifacts.readArtifact(contractName); let bytecode; try { bytecode = resolveLinkedBytecode(artifact, libraries); } catch (error) { ensureError(error); throw new HardhatError(HardhatError.ERRORS.HARDHAT_VIEM.GENERAL.LINKING_CONTRACT_ERROR, { contractName, error: error.message, }, error); } return { abi: artifact.abi, bytecode, }; } //# sourceMappingURL=contracts.js.map