migrate fork util to SDK (#3625)

### Description

* Migrates fork util to SDK

### Drive-by changes

* None

### Related issues

- Fixes https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/3624

### Backward compatibility

* Yes

### Testing

* Manual on core & warp
pull/3654/head
Noah Bayindirli 🥂 6 months ago committed by GitHub
parent e10735a718
commit 450e8e0d55
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 6
      .changeset/nice-pianos-tease.md
  2. 13
      typescript/cli/src/deploy/dry-run.ts
  3. 7
      typescript/cli/src/deploy/utils.ts
  4. 3
      typescript/cli/src/utils/keys.ts
  5. 8
      typescript/sdk/src/index.ts
  6. 55
      typescript/sdk/src/utils/fork.ts

@ -0,0 +1,6 @@
---
'@hyperlane-xyz/cli': minor
'@hyperlane-xyz/sdk': minor
---
Migrate fork util from CLI to SDK. Anvil IP & Port are now optionally passed into fork util by client.

@ -1,13 +1,14 @@
import { MultiProvider } from '@hyperlane-xyz/sdk';
import { Command } from '../commands/deploy.js';
import { logGray, logGreen, warnYellow } from '../logger.js';
import {
ANVIL_RPC_METHODS,
MultiProvider,
getLocalProvider,
resetFork,
setFork,
} from '../utils/fork.js';
} from '@hyperlane-xyz/sdk';
import { Command } from '../commands/deploy.js';
import { logGray, logGreen, warnYellow } from '../logger.js';
import { ENV } from '../utils/env.js';
import { toUpperCamelCase } from './utils.js';
@ -33,7 +34,7 @@ export async function forkNetworkToMultiProvider(
export async function verifyAnvil() {
logGray('🔎 Verifying anvil node is running...');
const provider = getLocalProvider();
const provider = getLocalProvider(ENV.ANVIL_IP_ADDR, ENV.ANVIL_PORT);
try {
await provider.send(ANVIL_RPC_METHODS.NODE_INFO, []);
} catch (error: any) {

@ -6,6 +6,7 @@ import {
IsmConfig,
MultiProvider,
MultisigConfig,
getLocalProvider,
} from '@hyperlane-xyz/sdk';
import { Address, ProtocolType } from '@hyperlane-xyz/utils';
@ -13,7 +14,7 @@ import { Command } from '../commands/deploy.js';
import { parseIsmConfig } from '../config/ism.js';
import { log, logGreen, logPink } from '../logger.js';
import { assertGasBalances } from '../utils/balances.js';
import { getLocalProvider } from '../utils/fork.js';
import { ENV } from '../utils/env.js';
import { assertSigner } from '../utils/keys.js';
import { completeDryRun } from './dry-run.js';
@ -111,7 +112,7 @@ export async function prepareDeploy(
await Promise.all(
chains.map(async (chain: ChainName) => {
const provider = dryRun
? getLocalProvider()
? getLocalProvider(ENV.ANVIL_IP_ADDR, ENV.ANVIL_PORT)
: multiProvider.getProvider(chain);
const currentBalance = await provider.getBalance(userAddress);
initialBalances[chain] = currentBalance;
@ -131,7 +132,7 @@ export async function completeDeploy(
if (chains.length > 0) logPink(` Gas Usage Statistics`);
for (const chain of chains) {
const provider = dryRun
? getLocalProvider()
? getLocalProvider(ENV.ANVIL_IP_ADDR, ENV.ANVIL_PORT)
: multiProvider.getProvider(chain);
const currentBalance = await provider.getBalance(userAddress);
const balanceDelta = initialBalances[chain].sub(currentBalance);

@ -1,12 +1,11 @@
import { input } from '@inquirer/prompts';
import { ethers, providers } from 'ethers';
import { impersonateAccount } from '@hyperlane-xyz/sdk';
import { Address, ensure0x } from '@hyperlane-xyz/utils';
import { ContextSettings, KeyConfig } from '../context.js';
import { impersonateAccount } from './fork.js';
const ETHEREUM_ADDRESS_LENGTH = 42;
const DEFAULT_KEY_TYPE = 'private key';
const IMPERSONATED_KEY_TYPE = 'address';

@ -442,6 +442,14 @@ export {
} from './types.js';
export { MultiGeneric } from './utils/MultiGeneric.js';
export { filterByChains } from './utils/filter.js';
export {
ANVIL_RPC_METHODS,
resetFork,
setFork,
impersonateAccount,
stopImpersonatingAccount,
getLocalProvider,
} from './utils/fork.js';
export { multisigIsmVerificationCost } from './utils/ism.js';
export {
SealevelAccountDataWrapper,

@ -1,12 +1,11 @@
import { providers } from 'ethers';
import { ChainName, MultiProvider } from '@hyperlane-xyz/sdk';
import { Address, isValidAddressEvm } from '@hyperlane-xyz/utils';
import { Address, isValidAddressEvm, rootLogger } from '@hyperlane-xyz/utils';
import { logGray, logGreen } from '../logger.js';
import { warnYellow } from '../logger.js';
import { MultiProvider } from '../providers/MultiProvider.js';
import { ChainName } from '../types.js';
import { ENV } from './env.js';
const logger = rootLogger.child({ module: 'fork-utils' });
const ENDPOINT_PREFIX = 'http';
const DEFAULT_ANVIL_ENDPOINT = 'http://127.0.0.1:8545';
@ -19,12 +18,12 @@ export enum ANVIL_RPC_METHODS {
}
/**
* Resets the local node to it's original start (anvil [31337] at block zero).
* Resets the local node to it's original state (anvil [31337] at block zero).
*/
export const resetFork = async () => {
logGray(`Resetting forked network...`);
export const resetFork = async (anvilIPAddr?: string, anvilPort?: number) => {
logger.info(`Resetting forked network...`);
const provider = getLocalProvider();
const provider = getLocalProvider(anvilIPAddr, anvilPort);
await provider.send(ANVIL_RPC_METHODS.RESET, [
{
forking: {
@ -33,7 +32,7 @@ export const resetFork = async () => {
},
]);
logGreen(`✅ Successfully reset forked network`);
logger.info(`✅ Successfully reset forked network`);
};
/**
@ -44,10 +43,12 @@ export const resetFork = async () => {
export const setFork = async (
multiProvider: MultiProvider,
chain: ChainName | number,
anvilIPAddr?: string,
anvilPort?: number,
) => {
logGray(`Forking ${chain} for dry-run...`);
logger.info(`Forking ${chain} for dry-run...`);
const provider = getLocalProvider();
const provider = getLocalProvider(anvilIPAddr, anvilPort);
const currentChainMetadata = multiProvider.metadata[chain];
await provider.send(ANVIL_RPC_METHODS.RESET, [
@ -60,7 +61,7 @@ export const setFork = async (
multiProvider.setProvider(chain, provider);
logGreen(`✅ Successfully forked ${chain} for dry-run`);
logger.info(`✅ Successfully forked ${chain} for dry-run`);
};
/**
@ -70,13 +71,15 @@ export const setFork = async (
*/
export const impersonateAccount = async (
address: Address,
anvilIPAddr?: string,
anvilPort?: number,
): Promise<providers.JsonRpcSigner> => {
logGray(`Impersonating account (${address})...`);
logger.info(`Impersonating account (${address})...`);
const provider = getLocalProvider();
const provider = getLocalProvider(anvilIPAddr, anvilPort);
await provider.send(ANVIL_RPC_METHODS.IMPERSONATE_ACCOUNT, [address]);
logGreen(`✅ Successfully impersonated account (${address})`);
logger.info(`✅ Successfully impersonated account (${address})`);
return provider.getSigner(address);
};
@ -85,20 +88,24 @@ export const impersonateAccount = async (
* Stops account impersonation.
* @param address the address to stop impersonating
*/
export const stopImpersonatingAccount = async (address: Address) => {
logGray(`Stopping account impersonation for address (${address})...`);
export const stopImpersonatingAccount = async (
address: Address,
anvilIPAddr?: string,
anvilPort?: number,
) => {
logger.info(`Stopping account impersonation for address (${address})...`);
if (isValidAddressEvm(address))
throw new Error(
`Cannot stop account impersonation: invalid address format: ${address}`,
);
const provider = getLocalProvider();
const provider = getLocalProvider(anvilIPAddr, anvilPort);
await provider.send(ANVIL_RPC_METHODS.STOP_IMPERSONATING_ACCOUNT, [
address.substring(2),
]);
logGreen(
logger.info(
`✅ Successfully stopped account impersonation for address (${address})`,
);
};
@ -109,14 +116,16 @@ export const stopImpersonatingAccount = async (address: Address) => {
* @returns a local JSON-RPC provider
*/
export const getLocalProvider = (
anvilIPAddr?: string,
anvilPort?: number,
urlOverride?: string,
): providers.JsonRpcProvider => {
let envUrl;
if (ENV.ANVIL_IP_ADDR && ENV.ANVIL_PORT)
envUrl = `${ENDPOINT_PREFIX}${ENV.ANVIL_IP_ADDR}:${ENV.ANVIL_PORT}`;
if (anvilIPAddr && anvilPort)
envUrl = `${ENDPOINT_PREFIX}${anvilIPAddr}:${anvilPort}`;
if (urlOverride && !urlOverride.startsWith(ENDPOINT_PREFIX)) {
warnYellow(
logger.warn(
` Provided URL override (${urlOverride}) does not begin with ${ENDPOINT_PREFIX}. Defaulting to ${
envUrl ?? DEFAULT_ANVIL_ENDPOINT
}`,
Loading…
Cancel
Save