# Debugging and Troubleshooting dApp Connection Issues with Nautilus Wallet: A Complete Developer Guide

> Resolve Nautilus Wallet dApp connection issues. Learn common fixes including content script verification, IndexedDB checks, and popup approval troubleshooting. Your complete developer guide.

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

---

**The most common fixes for Nautilus Wallet connection failures involve verifying the content script injection in [`injected.ts`](https://github.com/nautls/nautilus-wallet/blob/main/injected.ts), checking the IndexedDB `connectedDApps` store for the origin entry, and ensuring the background service worker successfully opens the approval popup via `createWindow` in [`src/common/uiHelpers.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/common/uiHelpers.ts).**

Nautilus Wallet is a popular browser extension for interacting with the Ergo blockchain, but developers often encounter friction when establishing connections between decentralized applications (dApps) and the wallet. Understanding the internal message flow and state management within the `nautls/nautilus-wallet` repository is essential for effectively debugging and troubleshooting dApp connection issues with Nautilus Wallet. This guide walks through the connection architecture, identifies common failure points, and provides concrete diagnostic snippets.

## Understanding the Nautilus Connection Architecture

The connection flow relies on a multi-layer message passing system between the dApp, content script, background service worker, and popup UI. According to the source code in [`src/extension/content-scripts/injected.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/content-scripts/injected.ts) and [`src/extension/background/background.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/background/background.ts), the process follows five distinct steps:

1. **dApp Initiates Request**: The dApp calls `window.ergoConnector.nautilus.connect()` (or the legacy `window.ergo_request_read_access`). The injected content script sends an `ExternalRequest.Connect` message to the background via *webext-bridge* using `sendMessage`.

2. **Background Validates Origin**: The background script receives the request as `InternalRequest.Connect` and verifies the request originates from an internal endpoint. It checks `connectedDAppsDbService.getByOrigin` to see if the dApp is already authorized.

3. **User Approval Flow**: If unauthorized, the background opens a popup window. The connector router ([`src/extension/connector/router.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/connector/router.ts)) handles the `/connect` route, and the popup UI writes the approval to the database via `connectedDAppsDbService.put`.

4. **Connection Established**: The background stores the approval and replies `true` to the content script. The content script stores the API object in `window.ergo` if `createErgoObject` was requested.

5. **Subsequent API Calls**: Methods like `get_utxos` or `sign_tx` route through the same message channel, with the background checking `connectedDAppsDbService` via the `onMessageAuth` guard before fulfilling requests.

The connection state persists in the **`connectedDAppsDbService`** IndexedDB table and is validated on every internal request. Any break in this chain results in "Not connected" or "Refused" errors.

## Common Failure Points and Diagnostic Strategies

When debugging and troubleshooting dApp connection issues with Nautilus Wallet, symptoms typically cluster around specific architectural failure points. Use the following diagnostic approach based on the source code in [`src/extension/background/background.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/background/background.ts) and related files.

### Connection Resolves to False or Popup Never Opens

If `window.ergoConnector.nautilus.connect()` resolves to `false`, the popup window likely failed to open or was blocked by the browser.

Open **Extension → Service Workers** in Chrome DevTools and check the console for `openWindow` errors. Verify that `createWindow` in [`src/common/uiHelpers.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/common/uiHelpers.ts) succeeded and that the extension manifest includes the **`activeTab`** permission required for window creation.

### window.ergo Remains Undefined After Connection

When `window.ergo` is `undefined` despite a successful connection, the `createErgoObject` flag was likely set to `false` or the connection was implicitly denied.

Inspect the content script console for the resolution log in `connect()` (line 33 of [`injected.ts`](https://github.com/nautls/nautilus-wallet/blob/main/injected.ts)). Check the boolean return value to confirm whether the API object should have been injected.

### "Not Connected" Errors on API Calls

If the dApp receives `{ code: 400, info: "Not connected." }` when calling `get_utxos` or similar methods, the background cannot find a matching entry in the connection database.

Open the **IndexedDB** panel in DevTools and inspect the `connectedDApps` store managed by `connectedDAppsDbService`. Verify the record contains the correct `origin` and `walletId` matching the current dApp domain.

### Signing Requests Hang or Return Invalid Params

When `sign_tx` or data signing requests hang or return validation errors, the payload may be malformed or the address might not belong to the connected wallet.

Check the background logs for `handleDataSigningRequest` validation (lines 19-24 in the relevant handler). Confirm the requested address exists in `addressesDbService` and is associated with the currently connected wallet ID.

### Permission Denied in UI Despite User Approval

If the popup shows "Permission denied" even after the user clicks Allow, the `graphQLService` URL may be mismatched or the backend connection failed.

Check the `InternalEvent.UpdatedBackendUrl` listener (lines 51-54 in background handlers) and confirm the URL stored in `browser.storage` matches the active backend endpoint.

### No Background Console Messages Appear

When no messages appear in the background console, the content script likely failed to inject, often due to Content Security Policy (CSP) restrictions.

Open the page’s **Sources** tab and verify [`injected.js`](https://github.com/nautls/nautilus-wallet/blob/main/injected.js) is loaded. If blocked by CSP, test on a non-CSP page or adjust the server headers to allow the extension script.

## Practical Debugging Snippets

Use these console commands and code blocks to inspect the connection state directly in the browser environment.

### Testing the Connection Flow

Run this in your dApp console to verify the basic connection handshake:

```javascript
window.ergoConnector.nautilus
  .connect()
  .then(granted => console.log('Connect granted?', granted))
  .catch(err => console.error('Connect error', err));

```

If the promise rejects, the error object contains the `APIErrorCode` defined in [`src/types/connector.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/types/connector.ts).

### Logging Bridge Messages in the Background

Add this temporary listener to the background service worker console to trace all message traffic:

```javascript
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  console.log('Bridge message →', msg.type, msg);
  return true; // keep the channel open
});

```

### Verifying the Database Entry

Check if the connection persisted correctly by querying the IndexedDB service directly:

```javascript
connectedDAppsDbService.getByOrigin(window.location.origin)
  .then(conn => console.log('DB entry →', conn))
  .catch(e => console.error('DB error', e));

```

### Resetting the Connection State

Force a clean reconnection when the state becomes stale:

```javascript
await window.ergoConnector.nautilus.disconnect();
await window.ergoConnector.nautilus.connect();

```

## Key Source Files for Reference

Keep these files open when debugging to trace the execution flow:

- **[`src/extension/content-scripts/injected.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/content-scripts/injected.ts)** – Exposes the public `NautilusAuthApi` and sends bridge messages to the background.
- **[`src/extension/background/background.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/background/background.ts)** – Handles internal requests, validates connections via `onMessageAuth`, and opens popup windows.
- **[`src/database/connectedDAppsDbService.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/database/connectedDAppsDbService.ts)** – Persisted storage of authorized dApp origins using Dexie IndexedDB.
- **[`src/extension/connector/rpc/protocol.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/connector/rpc/protocol.ts)** – Definitions for `ExternalRequest`, `InternalRequest`, and result wrappers.
- **[`src/extension/connector/rpc/asyncRequestQueue.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/connector/rpc/asyncRequestQueue.ts)** – Queues UI-popup requests and resolves them when the popup signals readiness.
- **[`src/common/uiHelpers.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/common/uiHelpers.ts)** – Utility for creating popup windows via `createWindow`.
- **[`src/extension/connector/router.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/connector/router.ts)** – Vue router definitions for connector routes (`/connect`, `/sign-tx`).
- **[`src/types/connector.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/types/connector.ts)** – Central enum of error codes (`APIErrorCode`, `TxSendErrorCode`).

## Summary

Effective debugging and troubleshooting of dApp connection issues with Nautilus Wallet requires tracing the message flow from the injected content script through the background service worker to the popup UI. Key takeaways include:

- Verify [`injected.js`](https://github.com/nautls/nautilus-wallet/blob/main/injected.js) loads correctly to ensure `window.ergoConnector` is available.
- Check the **IndexedDB** `connectedDApps` store to confirm the origin is authorized.
- Monitor the background console for `createWindow` errors if the approval popup fails to appear.
- Ensure the `activeTab` permission is present in the extension manifest.
- Use `disconnect()` followed by `connect()` to reset stale connection states.

## Frequently Asked Questions

### Why does my dApp connection resolve to false even after the user clicks Allow?

This occurs when the background service worker fails to open the approval popup or the user denies the permission. Check the background console for errors in `createWindow` from [`src/common/uiHelpers.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/common/uiHelpers.ts) and verify the extension has the `activeTab` permission. Additionally, ensure the `connectedDAppsDbService.put` call in `src/extension/popup/*` successfully writes the origin to IndexedDB.

### How can I verify that Nautilus has stored my dApp's connection persistently?

Open the browser's DevTools, navigate to the **Application** (or **Storage**) tab, and inspect the **IndexedDB** `connectedDApps` store managed by [`connectedDAppsDbService.ts`](https://github.com/nautls/nautilus-wallet/blob/main/connectedDAppsDbService.ts). Run the following in the background console to verify programmatically:

```javascript
connectedDAppsDbService.getByOrigin(window.location.origin)
  .then(conn => console.log('Stored connection:', conn));

```

A valid entry must contain the correct `origin` and `walletId`.

### What causes "Not connected" errors when calling `sign_tx` or `get_utxos`?

The background script's `onMessageAuth` guard (lines 40-50 in [`src/extension/background/background.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/background/background.ts)) validates every API call against the `connectedDAppsDbService`. If the dApp's origin is missing from the database, or if the requested address does not exist in `addressesDbService` for the connected wallet, the request returns `{ code: 400, info: "Not connected." }`. Verify the connection flow completed successfully and the address belongs to the user's wallet.

### Where can I find background service worker logs to debug message routing?

In Chrome or Edge, open the extensions management page (`chrome://extensions`), enable **Developer mode**, and click the **service worker** link under the Nautilus extension. This opens a dedicated DevTools window for the background script. Look for logs related to `InternalRequest.Connect`, `ExternalRequest.Connect`, and `createWindow` calls. If no messages appear, the content script ([`injected.ts`](https://github.com/nautls/nautilus-wallet/blob/main/injected.ts)) may be blocked by a Content Security Policy and failed to inject into the page.