diff --git a/.changeset/gorgeous-eagles-judge.md b/.changeset/gorgeous-eagles-judge.md new file mode 100644 index 0000000..32e61e4 --- /dev/null +++ b/.changeset/gorgeous-eagles-judge.md @@ -0,0 +1,5 @@ +--- +'ethereum-mars': patch +--- + +Allow to pass waffle and ganache providers in opts diff --git a/packages/mars/src/options/Options.ts b/packages/mars/src/options/Options.ts index 4ccc0dd..e31bbba 100644 --- a/packages/mars/src/options/Options.ts +++ b/packages/mars/src/options/Options.ts @@ -1,6 +1,8 @@ -import { BigNumber } from 'ethers' +import { BigNumber, providers } from 'ethers' import type Ganache from 'ganache-core' +export type NetworkLike = string | Ganache.Provider | providers.JsonRpcProvider + export interface Options { /** * Private key of the account to be used to sign deployment transactions. @@ -11,7 +13,7 @@ export interface Options { * If this is a name, then it is used to locate an ethereum network in one of the services (Infura, Alchemy etc.) * If this is a URL or a provider instance, then it is used to construct an RPC provider to an existing network node. */ - network?: string | Ganache.Provider + network?: NetworkLike /** * API key to Infura service. See: https://infura.io/ */ diff --git a/packages/mars/src/options/config.ts b/packages/mars/src/options/config.ts index 46aa6dc..c0f6bf6 100644 --- a/packages/mars/src/options/config.ts +++ b/packages/mars/src/options/config.ts @@ -11,6 +11,7 @@ import { Options } from './Options' import { ensureMultisigConfig } from '../multisig/multisigConfig' import { logConfig } from '../logging' import { chains } from './chain' +import { JsonRpcProvider } from '@ethersproject/providers' export async function getConfig(options: Options): Promise { const merged = { @@ -64,7 +65,9 @@ export async function getConfig(options: Options): Promise { } } -function isNetworkProvider(network: string | Ganache.Provider): network is Ganache.Provider { +function isNetworkProvider( + network: string | Ganache.Provider | providers.JsonRpcProvider +): network is Ganache.Provider | providers.JsonRpcProvider { return !!network && typeof network === 'object' && (network as Ganache.Provider).send !== undefined } @@ -78,7 +81,9 @@ async function getSigner(options: Options) { let rpcUrl: string | undefined let provider: providers.JsonRpcProvider | undefined - if (isNetworkProvider(network)) { + if (JsonRpcProvider.isProvider(network)) { + provider = network + } else if (isNetworkProvider(network)) { // this causes 'MaxListenersExceededWarning: Possible EventEmitter memory leak detected.' when many contracts in use // details at https://github.com/ChainSafe/web3.js/issues/1648 provider = new providers.Web3Provider(network as any) diff --git a/packages/mars/test/options/config.test.ts b/packages/mars/test/options/config.test.ts index 16e2299..d6aa44a 100644 --- a/packages/mars/test/options/config.test.ts +++ b/packages/mars/test/options/config.test.ts @@ -1,6 +1,8 @@ import { expect } from 'chai' import { BigNumber, Wallet } from 'ethers' +import Ganache from 'ganache-core' import { getConfig } from '../../src/options' +import { MockProvider } from 'ethereum-waffle' const PRIVATE_KEY_1 = `0x${'1'.repeat(64)}` const PRIVATE_KEY_2 = `0x${'2'.repeat(64)}` @@ -44,6 +46,29 @@ describe('getConfig', () => { expect((result3.signer as Wallet).privateKey).to.equal(PRIVATE_KEY_3) }) + it('can pass ganache as network', async () => { + const ganache = Ganache.provider({ networkId: 1337 }) + const config = await getConfig({ ...defaults, network: ganache, privateKey: PRIVATE_KEY_1 }) + + expect((config.signer as Wallet).privateKey).to.equal(PRIVATE_KEY_1) + + const network = await config.provider.getNetwork() + expect(network.chainId).to.equal(1337) + + // eslint-disable-next-line @typescript-eslint/no-empty-function + ganache.close(() => {}) + }) + + it('can pass Waffle MockProvider as network', async () => { + const waffle = new MockProvider({ ganacheOptions: { networkId: 1337 } }) + const config = await getConfig({ ...defaults, network: waffle, privateKey: PRIVATE_KEY_1 }) + + expect((config.signer as Wallet).privateKey).to.equal(PRIVATE_KEY_1) + + const network = await config.provider.getNetwork() + expect(network.chainId).to.equal(1337) + }) + it('dry run implies noConfirm', async () => { const result = await getConfig({ dryRun: true, ...defaults }) expect(result.noConfirm).to.equal(true)