# The Network Manager API

Description: How to use the Network Manager of Hardhat 3

Note: This document was authored using MDX

  Source: https://github.com/NomicFoundation/hardhat-website/tree/main/src/content/docs/docs/reference/network-manager.mdx

  Components used in this page:
    - <Run cmd="..."/>: Runs a command in the terminal with npm/pnpm/yarn.
    - :::caution: A warning callout block. Supports custom title `:::caution[Title]` and icon `:::caution{icon="name"}` syntax.
    - wrap: Enables word wrapping in code blocks. Use `wrap=false` to disable.

import Run from "@hh/Run.astro";

The [Hardhat Runtime Environment](/docs/explanations/hardhat-runtime-environment) comes with a `NetworkManager` object available as its `network` property.

This section has reference documentation to work with its APIs. To learn more about Network Management in general, read [this explanation](/docs/explanations/network-management).

## Importing the Network Manager

You can access the Network Manager by importing Hardhat:

```ts
// script/example.ts
import hre from "hardhat";

const networkManager = hre.network;
```

Or you can import it directly:

```ts
// script/example.ts
import { network } from "hardhat";
```

## The `NetworkManager` object

The `NetworkManager` object has these methods:

- `network.create()`: To create connections to remote networks and local blockchain simulations.
- `network.getOrCreate()`: Like `network.create()`, but returns an existing connection if one was previously created with the same network name and chain type.
- `network.createServer()`: To create a local blockchain simulation and expose it through an HTTP-based JSON-RPC server.

The majority of this documentation will focus on `network.create()`, as `network.createServer()` can be considered a wrapper around it.

:::caution
`network.connect()` is deprecated and will be removed in a future version. Use `network.create()` or `network.getOrCreate()` instead.
:::

### The `network.create()` method

When you call the `network.create()` method, Hardhat creates a new `NetworkConnection` object.

The connection can either be an HTTP Network Connection connected to an external node through JSON-RPC, or an in-process connection to a new EDR-based simulated blockchain. In either case, every connection you create is independent from one another.

Both types offer the same API, so you can easily swap between them.

#### Calling it without parameters

The simplest way to create a new `NetworkConnection` is without any parameter:

```ts
// script/no-params-example.ts
import { network } from "hardhat";

const connection = await network.create();
console.log(connection.networkName);
```

By default, this will create a `NetworkConnection` based on the `"default"` Network Config of your Hardhat configuration. This Network Config is always defined, and by default it has an [`edr-simulated` type](/docs/explanations/network-management#edr-simulated-network-configs), so it creates a new blockchain simulation every time it's called.

You can also control which Network Config is used when none is provided by using the `network` [Global Option](/docs/explanations/global-options). For example, running that same script like this will use the `localhost` Network Config:

<Run command="hardhat run script/no-params-example.ts --network localhost" />

#### Choosing a Network Config

You can also choose a Network Config by providing its name as a string, or as part of its options object:

```ts
// script/with-name-example.ts
import { network } from "hardhat";

const connection = await network.create("localhost");

const connectionWithOptions = await network.create({ network: "localhost" });
```

#### Network Config overrides

When you use the second option from the ones shown above, you can also use an `override` parameter. When you use it, the Network Config is read from the `HardhatUserConfig`, and the provided values overridden. Then it goes through the config validation process and resolution, and if successful, its result is used to create the connection.

For example, this script creates a Network Connection with logging enabled, and mines a block, whose results are printed to the terminal:

```ts
// script/with-overrides-example.ts
import { network } from "hardhat";

const { networkHelpers } = await network.create({
  override: { loggingEnabled: true },
});

await networkHelpers.mine();
```

#### Providing a Chain Type option

You can also provide a `chainType` in the options object. For example:

```ts
import { network } from "hardhat";

const { viem } = await network.create({
  network: "hardhatOp",
  chainType: "op",
});
```

When you do this, the `NetworkConnection` is created with `op` as its type parameter. This has several implications:

- If you are using a plugin with multichain support, like `hardhat-viem`, it can extend the type of the `NetworkConnection<"op">`, adding new functionality in the form of new fields and methods.
- Multichain plugins and HTTP Network Connections in general can also change how they behave at runtime. For example, estimating gas differently depending on the Chain Type you are using.
- Network Connections to simulated networks will change how they work, running a higher-fidelity simulation.

You can learn more about these concepts in the [Multichain support explanation](/docs/explanations/multichain-support).

##### Defining a Chain Type in your Network Config

You can define a `chainType` property in each Network Config. For example:

```ts ins={9}
// hardhat.config.ts
// ... imports ...

export default defineConfig({
  // ... other config ...
  networks: {
    hardhatMainnet: {
      type: "edr-simulated",
      chainType: "l1",
    },
    // ... other networks ...
  },
});
```

When you do this, you get most of the benefits of providing it as an option, except for the type-level extensions that a plugin can provide.

If you provide a Chain Type both as an option and as part of your Network Config, the one provided in the `network.create()` options will take precedence, and chain-type-dependent fields like `hardfork` will be re-resolved accordingly.

##### Changing the default Chain Type

By default, the default Chain Type that's used when neither a Network Config nor the `network.create()` options provide one is `generic`.

You can customize this with a [Type Extension](/docs/plugin-development/explanations/type-extensions), and a config value. Like this:

```ts ins={4-9,12}
// hardhat.config.ts
// ... imports ...

import "hardhat/types/network";
declare module "hardhat/types/network" {
  interface ChainTypeConfig {
    defaultChainType: "op";
  }
}

export default defineConfig({
  defaultChainType: "op",
  // ... other config ...
  networks: {
    opHardhat: {},
  },
});
```

Note that the Type Extension and the config value must both be present and match, or you'll get a compilation error.

When you do that, the default Chain Type will be updated both at type-level and runtime. For example, this will work with the config above:

```ts "publicClient.estimateL1Gas"
// scripts/example-op.ts
import { network } from "hardhat";

const { viem } = await network.create();

const publicClient = await viem.getPublicClient();
const l1Gas = await publicClient.estimateL1Gas({
  account: "0x1111111111111111111111111111111111111111",
  to: "0x2222222222222222222222222222222222222222",
  value: 1n,
});

console.log("l1Gas:", l1Gas);
```

You can run it with:

<Run command="hardhat run scripts/example-op.ts" />

### The `network.getOrCreate()` method

The `network.getOrCreate()` method works like `network.create()`, but returns an existing connection if one was previously created with the same network name and chain type, instead of always creating a new one.

This is useful when you want to share a single connection across different parts of your code without having to pass it around manually.

```ts
import { network } from "hardhat";

// Creates a new connection the first time
const connection1 = await network.getOrCreate("mainnet");

// Returns the same connection
const connection2 = await network.getOrCreate("mainnet");

// connection1 === connection2
```

`network.getOrCreate()` takes the same parameters as `network.create()`, except that the `override` option is not supported.

### The `network.createServer()` method

The `network.createServer()` method creates a local blockchain simulation and exposes it through an HTTP-based JSON-RPC server, similar to what `hardhat node` does.

#### Parameters

This method takes the same arguments as `network.create()`, plus two additional optional parameters:

- `hostname`: The hostname of the network interface the server should use to listen for new connections. Defaults to `"127.0.0.1"`, or `"0.0.0.0"` if running in a Docker container.
- `port`: The port to use for the HTTP server. If not provided, an unused random port will be assigned by the OS.

#### Return value

Calling `await network.createServer()` returns a `JsonRpcServer` object, which provides the following methods:

- `listen()`: Starts the server and returns the `hostname` and `port` being used.
- `close()`: Stops the server.
- `afterClosed()`: Returns a promise that resolves when the server has fully closed. Useful if `close()` is called from another async context.

To learn more about how to use this method, see the [Running a local development node guide](/docs/guides/hardhat-node#running-a-development-node-programmatically).

## The `NetworkConnection<ChainTypeT>` object

The `NetworkConnection` returned by `network.create()` provides the basic functionality to interact with the network, and can be extended through plugins.

To learn more about it, read [this explanation](/docs/explanations/network-management#the-networkconnection-object).
