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

The Nautilus Wallet extension generates its 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 in its source code. Instead, the build pipeline in 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 (lines 20-58), the Vite configuration reads the NETWORK environment variable and passes it to the manifest generator:

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 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.

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) 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:

// 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.

To build for mainnet (default behavior):

pnpm run build:mainnet:chrome

To build for testnet:

NETWORK=testnet pnpm run build:mainnet:chrome

Alternatively, use the dedicated development script:

pnpm run dev:testnet

Summary

  • The manifest.json is generated dynamically in vite.config.ts using the buildManifest function from 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 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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →