Wallets
Troubleshooting

Wallet Troubleshooting

Find your symptom, read the cause, apply the fix.

Passkeys

Tapping the passkey option does nothing

The WebAuthn Relying Party ID for wallet passkeys is pinned into the build from VITE_WEBAUTHN_RP_ID and is never derived from the host serving the page. If that pinned value is not a registrable domain suffix of the origin you are on, the browser rejects the ceremony with a SecurityError before the operating system shows anything. No Face ID sheet, no Touch ID prompt, no Windows Hello dialog, no error dialog.

Where you areCorrect VITE_WEBAUTHN_RP_IDPasskeys work?
superhero.com (production)superhero.com, the defaultYes
Local dev on localhostlocalhostYes, if set
Any other originA registrable suffix of that originOnly if set for that build

Fix: on production, report it. On any other origin, rebuild with the right VITE_WEBAUTHN_RP_ID, or use a recovery phrase instead.

The app catches this exception and shows "Passkeys aren't available on this domain (this build expects …). Use a recovery phrase instead." The name it prints is the RP ID the build was compiled with. The DOM exception name and message are also written to the browser console; include them in any report.

The passkey prompt appeared, then the wallet did not open

The ceremony ran but the derived key did not unwrap this vault, so the unlock failed closed. Two common causes:

  • You picked the wrong passkey from the OS list. Retry and choose the Superhero one.
  • The credential was rekeyed by the platform. Apple has a known passkey-rekey issue that can invalidate a previously stable PRF output. This is why the recovery code exists as a passkey-independent factor.

Fix: unlock with your recovery code or passphrase instead, on the same device. Both are offered on the "this device already has a wallet" screen.

Tapping the passkey card opens an onboarding screen instead of a biometric prompt

Your device has a wallet, but that wallet has no passkey factor; it unlocks with a passphrase and recovery code. The card hands off to the wallet screen, where your passphrase opens it. You can enroll a device passkey from there.

It says "Tap to try again" with no error

You cancelled, or the OS dismissed the sheet. Nothing is logged as an error. Tap again.

Connecting an external wallet

The wallet is not detected

Superhero scans for an injected wallet over a browser message connection with a short window:

SituationDetection window
Desktop browser, user-initiated connect4 seconds
Mobile or Safari, not framed100 ms, failing fast to the deep-link path
Silent reconnect after a page refresh15 seconds

The reconnect window is longer because the extension's content script can be injected after the app has already booted.

Fix: confirm the extension is installed and enabled for this site, unlock it, then reload the page and use Connect again. If no wallet answers and the page is not framed, the app falls back to a deep link: superhero:// on mobile, otherwise wallet.superhero.com in a new window.

The app opened wallet.superhero.com instead of my extension

That is the fallback firing: no extension answered within the detection window. See above.

After a refresh the app shows my address but cannot sign

You have a restored static (read-only) account rather than a live RPC session. Account subscription and address-change events only exist over a live connection.

Fix: click Connect again to re-establish the RPC session. Silent reconnection is attempted once per page load, but only when both a previously active account and persisted wallet info exist.

The app spontaneously shows "disconnected" while the extension is open

A health check runs every five seconds and clears connection state when the SDK reports no accounts. A stale connection is treated as no connection. Reconnect.

Disconnect did not stick; it reconnected on refresh

Disconnecting clears the persisted session keys (account:activeAccount, wallet:walletInfo, wallet:balance, dex:recentActivities, liquidityPositions), stops wallet detection and drops the cached connection. If a reconnect still happens, check for a stale ?address= query parameter in the URL. The app consumes that parameter to install a static account, then strips it.

Hardware accounts in Superhero Wallet

There is no "Add Ledger accounts" button

It is hidden, not missing. The button appears only when the account protocol is æternity and the surface is neither Firefox nor a mobile app:

SurfaceLedger button
Chrome, Brave, Opera extensionShown
wallet.superhero.com in a Chromium browserShown
Firefox (extension or web)Hidden; Firefox does not implement WebUSB
iOS or Android appHidden
A non-æternity account selectedHidden

Fix: use a Chromium browser, or switch to an æternity account first. AirGap has none of these restrictions.

"Connection timed out" when importing from a Ledger

Two causes: the device is not properly plugged in, or the æternity app is not open on it. Plug in over USB, open the æternity app, then press connect. The same applies when signing: the device must be unlocked with the æternity app active.

An AirGap QR code will not scan or decode

Set AirGap Vault to QR code V3. A V2 payload will not deserialize. Every AirGap screen also accepts the airgap-wallet://?ur=… string pasted by hand, which is the way through if the camera is the problem.

An AirGap account will not sign a message

It cannot. Superhero Wallet shows "Signing messages is currently not supported for AirGap accounts" and stops. Transactions are supported; messages are not. If an æpp needs a message signature, use a non-AirGap account for it.

Network

The wallet is on a different network from the app

Superhero builds are network-pinned at build time through VITE_NETWORK. The app offers only the network its bundle was built for; there is no in-app network switcher.

Fix: switch networks in your wallet to match the build: ae_mainnet on superhero.com. For testnet work, use a testnet build and see Using Testnet.

Balances and signing

"Insufficient balance" when the balance looks sufficient

On a token trade, the Max button does not offer your whole balance. It withholds a slippage allowance plus a flat gas reserve:

max = balance − balance × (slippage + 1) / 100 − 0.001 AE

With the default 1% slippage that is a 2% reserve plus 0.001 AE. Separately, gas is charged on top of the transaction fee, up to the gas limit, which is why the signing prompt shows a "Gas, at most" row as well as "Network fee". A balance that exactly covers the amount will not cover the amount plus fee plus gas.

Fix: leave headroom, or lower the amount. Do not lower slippage to free up funds; that just makes the trade fail differently.

The signing prompt refuses to let me approve

By design. If the transaction envelope, a contract call's arguments, or a wrapped inner transaction cannot be decoded, the confirmation fails closed and approval is not offered. There is no "show raw bytes and sign anyway".

Fix: do not try to work around it. Report what you were doing when it appeared.

"no unlock prompt is mounted — refusing to sign"

The in-page signer asked for user verification and found no prompt host mounted, so it rejected immediately rather than hanging. This is the fail-closed guard, not a crash.

Fix: reload the page and retry the action. If it recurs reproducibly, report it with the exact action.

"derived key does not match the expected account address — refusing to sign"

The signer derived a key that does not produce the address it was installed for, and refused. The device's wallet changed underneath a live session (a restore or import replaced it), or an address and index pair drifted apart.

Fix: reload the page so the account list is rebuilt from the current vault, then retry.

Storage and the built-in wallet

My built-in wallet disappeared

The encrypted vault lives in this browser's IndexedDB for this origin. Clearing site data deletes it, and Safari's Intelligent Tracking Prevention can evict it after roughly seven days without interaction.

Neither your passphrase nor your recovery code can bring it back, because both need the deleted record to unwrap anything. What survives is the written recovery phrase, or a syncing passkey if the wallet was created by the passkey path. The full matrix is in The Built-In Wallet.

My wallet unlocks but the app does not know my address

The address list in localStorage was cleared while the encrypted vault in IndexedDB survived. This is a normal outcome of some "clear site data" variants.

Fix: open the wallet screen and unlock once; addresses are re-derived from index 0 upward and the list is rebuilt.

Restoring from a passkey shows an address I do not recognise

The restore screen checks the derived address for on-chain activity before saving anything. If it says the account has no on-chain activity, you very likely picked a passkey that belongs to a seed-phrase wallet, which derives a valid but completely empty different wallet.

Fix: do not confirm. Go back and import your recovery phrase (installed app), or connect your existing wallet instead. Confirming would persist the wrong wallet and then block the correct import with "a vault already exists".

There is no "Import an existing wallet" option

Importing a seed phrase or private key is offered only in the installed app (Add to Home Screen / installed PWA). In a plain browser tab, "I already have a wallet" means Connect, which never asks for your secret.

Nothing persists at all (private browsing)

In Safari private mode and with site data blocked, storage reads can fail. The app treats an unreadable address list as "no wallet on this device" and an unreadable vault probe as unknown rather than claiming you have no wallet.

Fix: use a normal window for anything you intend to keep.

Reporting a bug

WhatWhere
App, mobile app or PWA buggithub.com/superhero-com/superhero/issues (opens in a new tab), the same destination as the in-app "Send Feedback" button
API, indexer or a wrong figure in a responsegithub.com/superhero-com/superhero-api/issues (opens in a new tab)
Superhero Wallet (extension, app, web wallet) bugThe wallet's own Report a bug entry, at form.typeform.com/to/Kk3Zyjdr (opens in a new tab), or github.com/superhero-com/superhero-wallet/issues (opens in a new tab)
Security report, legal, privacy or data protectionsuperherowallet@protonmail.com
Chatchat.superhero.com

Include in any report:

  • the token name or page you were on,
  • your ak_... address,
  • the transaction hash if one was produced,
  • what you expected and what happened,
  • for a Superhero Wallet bug, the software version and commit from the wallet's More → About screen, which also shows the node and middleware versions it is talking to,
  • for passkey problems, the DOM exception name from the browser console and the exact on-screen message.

Never include a private key, a seed phrase, or a screenshot showing either.

Related