UNPKG

@openzeppelin/hardhat-upgrades

Version:

[![Docs](https://img.shields.io/badge/docs-%F0%9F%93%84-blue)](https://docs.openzeppelin.com/upgrades-plugins/hardhat-upgrades) [![NPM Package](https://img.shields.io/npm/v/@openzeppelin/hardhat-upgrades.svg)](https://www.npmjs.org/package/@openzeppelin/h

91 lines • 4.3 kB
import { Interface } from 'ethers'; import { deploy } from './utils/deploy.js'; import { getSigner } from './utils/ethers.js'; import { getRemoteDeployment } from './defender/utils.js'; /** * Builds the client-neutral engine binding for the ethers API. Deployments still go through the * ethers `ContractFactory` (preserving the existing behavior, including the Defender path and the * `proxyFactory`/`deployFunction` escape hatches), while the engine drives the orchestration. * * @param runner the contract factory's runner, whose signer signs the plugin's transactions */ export function makeEthersBinding(hre, connection, runner, opts) { const signer = getSigner(runner); return { hre, provider: connection.provider, encodeConstructorArgs(info, args) { return new Interface(info.abi).encodeDeploy(args); }, encodeFunctionData(abi, fn, args) { return new Interface(abi).encodeFunctionData(fn, args); }, hasFunction(abi, fn) { return new Interface(abi).getFunction(fn) !== null; }, formatManifestAbi(abi) { return new Interface(abi).format(true); }, async getSignerAddress() { return signer === undefined ? undefined : await signer.getAddress(); }, deployUnconfirmed(info, args) { // ethers' deploy already returns the pending transaction without waiting for the receipt, so // upgrades-core confirms it the same way; there is nothing different to do for ethers. return this.deploy(info, args); }, async deploy(info, args) { const factory = await connection.ethers.getContractFactory([...info.abi], info.bytecode, signer); return toDeployedContract(await deploy(hre, opts, factory, ...args)); }, async deployProxy(info, args) { // Build the proxy factory the way the previous implementation did, falling back to the // connection's default signer when the implementation factory has no signer. const factory = opts.proxyFactory ?? (await connection.ethers.getContractFactory([...info.abi], info.bytecode, signer)); const deployFn = opts.deployFunction || deploy; return toDeployedContract(await deployFn(hre, opts, factory, ...args)); }, async sendTransaction(tx) { // The signer that signs the plugin's transactions, falling back to the connection's default // signer to match `connection.ethers.getContractAt(...)` when no factory signer is available. const txSigner = signer ?? (await connection.ethers.provider.getSigner()); const overrides = opts.txOverrides ?? {}; // Apply overrides first so caller-supplied `to`/`data` cannot replace the plugin's call. const response = await txSigner.sendTransaction({ ...overrides, to: tx.to, data: tx.data }); return { txHash: response.hash, txResponse: response }; }, getRemoteDeployment: remoteDeploymentId => getRemoteDeployment(hre, remoteDeploymentId), }; } /** * Builds the engine's client-neutral {@link ContractInfo} from an ethers `ContractFactory`. */ export function contractInfo(factory) { return { abi: JSON.parse(factory.interface.formatJson()), bytecode: factory.bytecode, }; } function toDeployedContract(deployment) { return { address: deployment.address, txHash: deployment.txHash, deployTransaction: deployment.deployTransaction, remoteDeploymentId: deployment.remoteDeploymentId, }; } /** * Resolves the ethers `TransactionResponse` of an implementation deployment for the `getTxResponse` * option: the deployment's own transaction when freshly deployed, or otherwise the transaction * looked up from the manifest's recorded hash. */ export async function txResponseOf(deployment, connection) { if (deployment.deployTransaction !== undefined) { return deployment.deployTransaction; } if (deployment.txHash !== undefined) { return (await connection.ethers.provider.getTransaction(deployment.txHash)) ?? undefined; } return undefined; } //# sourceMappingURL=ethers-binding.js.map