# How the Nautilus Wallet Extension Manifest is Configured for Different Ergo Networks (Mainnet/Testnet)

> Discover how Nautilus Wallet dynamically configures its manifest.json for Ergo mainnet and testnet using environment variables for tailored network experiences.

- Repository: [Nautilus Team/nautilus-wallet](https://github.com/nautls/nautilus-wallet)
- Tags: how-to-guide
- Published: 2026-03-07

---

**The Nautilus Wallet extension generates its [`manifest.json`](https://github.com/nautls/nautilus-wallet/blob/main/manifest.json) dynamically at build time using environment variables, switching the title, description, and icon set between mainnet and testnet while keeping permissions and scripts identical.**

The nautls/nautilus-wallet repository adapts its browser extension branding and assets automatically based on the target Ergo blockchain network. This configuration happens entirely at build time through TypeScript functions that construct the manifest object programmatically rather than relying on static JSON files.

## Dynamic Manifest Generation Architecture

The extension does not ship with a static [`manifest.json`](https://github.com/nautls/nautilus-wallet/blob/main/manifest.json) in its source code. Instead, the build pipeline in [`vite.config.ts`](https://github.com/nautls/nautilus-wallet/blob/main/vite.config.ts) invokes a specialized builder function that assembles the manifest object based on environment variables.

### Build-time Network Detection

In [`vite.config.ts`](https://github.com/nautls/nautilus-wallet/blob/main/vite.config.ts) (lines 20-58), the Vite configuration reads the `NETWORK` environment variable and passes it to the manifest generator:

```typescript
const env = { 
  NETWORK: (process.env.NETWORK as "mainnet" | "testnet") ?? "mainnet", 
  … 
}
…
manifest: () => buildManifest(env.NETWORK, env.TARGET, mode)

```

The default value is `"mainnet"`, ensuring that standard builds target the production Ergo network unless explicitly overridden.

### Core Manifest Assembly Logic

The `buildManifest` function in [`src/extension/manifest.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/manifest.ts) serves as the central factory for manifest objects. It accepts the `network` parameter (`"mainnet"` or `"testnet"`) and delegates to helper functions that construct network-specific strings and asset paths. This approach ensures type safety throughout the build process, with the `NETWORK` type declared as `"mainnet" | "testnet"` in [`src/types/d.ts/vite-env.d.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/types/d.ts/vite-env.d.ts).

## Network-Specific Manifest Differences

When targeting different Ergo networks, the manifest adjusts three specific fields to prevent user confusion between production assets and testing environments. All functional components—permissions, background scripts, and content scripts—remain identical across builds.

### Title and Description Variations

The `buildTitle` and `buildDescription` functions (lines 20-30 in [`src/extension/manifest.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/manifest.ts)) return distinct values based on the network parameter:

- **Mainnet**: Returns *"Nautilus Wallet"* with the standard description *"A secure and user-friendly wallet for the Ergo Platform"*
- **Testnet**: Returns *"Nautilus Wallet (Testnet)"* with the description *"Testnet distribution of Nautilus Wallet"*

### Icon Asset Routing

The `buildIcons` function (lines 10-18) selects asset paths using network-specific prefixes. Mainnet builds use the **`m`** prefix, while testnet builds use the **`t`** prefix:

```json
// Mainnet output
"icons": {
  "48": "icons/app/m-48.png",
  "128": "icons/app/m-128.png",
  "512": "icons/app/m-512.png"
}

// Testnet output
"icons": {
  "48": "icons/app/t-48.png",
  "128": "icons/app/t-128.png",
  "512": "icons/app/t-512.png"
}

```

The actual PNG files reside in `public/icons/app/`, with the naming convention distinguishing the target network.

## Building for Different Ergo Networks

Developers can generate network-specific extension packages using environment variable overrides or dedicated npm scripts defined in [`package.json`](https://github.com/nautls/nautilus-wallet/blob/main/package.json).

To build for mainnet (default behavior):

```bash
pnpm run build:mainnet:chrome

```

To build for testnet:

```bash
NETWORK=testnet pnpm run build:mainnet:chrome

```

Alternatively, use the dedicated development script:

```bash
pnpm run dev:testnet

```

## Summary

- The [`manifest.json`](https://github.com/nautls/nautilus-wallet/blob/main/manifest.json) is generated dynamically in [`vite.config.ts`](https://github.com/nautls/nautilus-wallet/blob/main/vite.config.ts) using the `buildManifest` function from [`src/extension/manifest.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/manifest.ts)
- The **NETWORK** environment variable controls whether the extension targets Ergo mainnet or testnet, defaulting to `"mainnet"`
- Three manifest fields change between networks: the extension `name`, `description`, and `icons` paths (using `m-` vs `t-` prefixes)
- All functional settings including permissions, background scripts, and side-panel configuration remain constant across network builds
- Type safety is enforced through TypeScript literal types `"mainnet" | "testnet"` declared in the project's environment type definitions

## Frequently Asked Questions

### Does the extension use separate manifest.json files for mainnet and testnet?

No. The nautls/nautilus-wallet repository generates the manifest dynamically at build time. The `buildManifest` function in [`src/extension/manifest.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/manifest.ts) constructs the appropriate configuration object based on the `NETWORK` environment variable, eliminating the need to maintain duplicate static JSON files that could drift out of sync.

### Which manifest fields change between mainnet and testnet builds?

Only the user-facing branding fields differ between networks: the `name` (which appends "(Testnet)" for testnet builds), the `description` (switching to a testnet-specific explanation), and the `icons` paths (referencing `t-` prefixed assets instead of `m-` prefixed ones). All functional components including permissions, host permissions, and background script entries remain identical.

### How do I build the extension for Ergo testnet locally?

Set the `NETWORK` environment variable to `"testnet"` before executing your build command. For example, run `NETWORK=testnet pnpm run build:mainnet:chrome` or use the provided `dev:testnet` script. The Vite configuration in [`vite.config.ts`](https://github.com/nautls/nautilus-wallet/blob/main/vite.config.ts) automatically detects this variable and passes it to the manifest generator, requiring no changes to the source code itself.

### Are the icon files located in different directories for each network?

No, all icon assets reside in the same directory: `public/icons/app/`. The files use a naming convention to distinguish networks, with `m-48.png`, `m-128.png`, and `m-512.png` serving mainnet builds, and `t-48.png`, `t-128.png`, and `t-512.png` serving testnet builds. The `buildIcons` function maps these prefixes dynamically based on the network parameter passed from the build configuration.