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

123 lines (119 loc) • 4.01 kB
import type { NetworkConnection } from 'hardhat/types/network'; import type { GetContractReturnType, KeyedClient } from '@nomicfoundation/hardhat-viem/types'; import type { Address } from 'viem'; /** * ABI of the UpgradeableBeacon contract from OpenZeppelin Contracts 5.x, which is the beacon * that `deployBeacon` deploys. Exposed as a `const` so that the beacon contract instances * returned by the viem-based API have typed `read` and `write` functions. */ export const upgradeableBeaconAbi = [ { inputs: [ { internalType: 'address', name: 'implementation_', type: 'address' }, { internalType: 'address', name: 'initialOwner', type: 'address' }, ], stateMutability: 'nonpayable', type: 'constructor', }, { inputs: [{ internalType: 'address', name: 'implementation', type: 'address' }], name: 'BeaconInvalidImplementation', type: 'error', }, { inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], name: 'OwnableInvalidOwner', type: 'error', }, { inputs: [{ internalType: 'address', name: 'account', type: 'address' }], name: 'OwnableUnauthorizedAccount', type: 'error', }, { anonymous: false, inputs: [ { indexed: true, internalType: 'address', name: 'previousOwner', type: 'address' }, { indexed: true, internalType: 'address', name: 'newOwner', type: 'address' }, ], name: 'OwnershipTransferred', type: 'event', }, { anonymous: false, inputs: [{ indexed: true, internalType: 'address', name: 'implementation', type: 'address' }], name: 'Upgraded', type: 'event', }, { inputs: [], name: 'implementation', outputs: [{ internalType: 'address', name: '', type: 'address' }], stateMutability: 'view', type: 'function', }, { inputs: [], name: 'owner', outputs: [{ internalType: 'address', name: '', type: 'address' }], stateMutability: 'view', type: 'function', }, { inputs: [], name: 'renounceOwnership', outputs: [], stateMutability: 'nonpayable', type: 'function', }, { inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], name: 'transferOwnership', outputs: [], stateMutability: 'nonpayable', type: 'function', }, { inputs: [{ internalType: 'address', name: 'newImplementation', type: 'address' }], name: 'upgradeTo', outputs: [], stateMutability: 'nonpayable', type: 'function', }, ] as const; /** * A viem contract instance for an UpgradeableBeacon contract. */ export type UpgradeableBeaconContract = GetContractReturnType<typeof upgradeableBeaconAbi>; /** * Gets a viem contract instance for the UpgradeableBeacon at the given address. * The beacon contract is not a project artifact, so the instance is created directly with * viem's `getContract` instead of `connection.viem.getContractAt`, using the same clients * that hardhat-viem would use by default. */ export async function getUpgradeableBeaconContract( connection: NetworkConnection, address: Address, client?: KeyedClient, ): Promise<UpgradeableBeaconContract> { const { getContract } = await import('viem'); const [publicClient, walletClient] = await Promise.all([ client?.public ?? connection.viem.getPublicClient(), client?.wallet ?? connection.viem.getWalletClients().then(clients => clients[0]), ]); // A wallet client enables writes (owner / upgradeTo). Without one — e.g. force-importing a beacon // on a connection with no accounts — the instance is still usable for reads, matching the // ethers-based API instead of failing after the import was already recorded. if (walletClient === undefined) { return getContract({ address, abi: upgradeableBeaconAbi, client: { public: publicClient }, }) as unknown as UpgradeableBeaconContract; } return getContract({ address, abi: upgradeableBeaconAbi, client: { public: publicClient, wallet: walletClient }, }); }