cryptoadvance / cryptoadvance/specter-desktop

Liquid DIY wallet fails to load after receive from Blockstream.app: `Failed to load utxos, KeyError: <txid>` while Elements has the tx

Open
#2,706 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
847
Forks
259
Avg merge
6d 18h
Merged PRs (30d)
2

Description

**Describe the bug**

A Liquid singlesig wallet (Specter DIY Lite) coordinated by Specter Desktop against Elements Core fails to load after receiving L-BTC from Blockstream.app (Green).

Error:
`Failed to load utxos, KeyError: f6d0fb22c0488fa6f1b18a08763ee38cd119bdca85f6dc9a8ed9bdcf1b4eafda`

On the Elements watch-only wallet the same txid is present and consistent:
- `listunspent` returns the UTXO (0.00021629 L-BTC, 1446+ confirmations)
- `listtransactions "*"` returns the receive
- `gettransaction ` succeeds

Specter’s `check_utxo()` looks the txid up in `txlist_dict` (from `fetch_transactions()` / local TxList). The entry is missing. A second lookup after `fetch_transactions()` still misses, and Specter raises instead of inserting or skipping the tx.

Same path as #2429: `liquid/wallet.py getdata` → `wallet.py check_utxo` → `KeyError`.

The receive output is a **confidential** Liquid output (asset/value commitments, nonce, range proof). `listunspent` prints the unconfidential `ex1q…` form of the same `scriptPubKey`. That is normal Elements behavior, not a send to an unblinded address. Liquid also always adds an explicit unblinded fee output; a “full coin” send is still 1 input + receive output + fee output.

**To Reproduce**

1. Run Elements Core (`liquidv1`) and connect Specter Desktop to that node (Specter may run on another machine).
2. Add a Specter DIY Lite as device, derivation `m/84h/1776h/0h`.
3. Create a Liquid singlesig wallet in Specter. Import the device/wallet from SD card (DIY JSON export). Specter creates an Elements watch-only descriptor wallet under `specter/`.
4. In Specter the wallet JSON stores `blinded(slip77(...), wpkh(...))` and confidential `lq1q…` receive addresses.
5. Send a single L-BTC coin from **Blockstream.app** (Green) to a receive address of this wallet.
6. Open the wallet in Specter Desktop → KeyError.

Observed on-chain / node details for this receive:

- txid `f6d0fb22c0488fa6f1b18a08763ee38cd119bdca85f6dc9a8ed9bdcf1b4eafda`, vout 0
- `scriptPubKey` `001473e1142c5659318040dce13491ec2f14a3ed3b9d`
- Elements `listunspent` address `ex1qw0s3gtzktyccqsxuuy6frmp0zj376wua427zcs` (unconfidential encoding of index `/0/0`)
- derivation `wpkh([455edac7/84'/1776'/0'/0/0]…)`
- output has `assetcommitment` / `amountcommitment` / blinders (confidential receive; fee output is separate and explicit)

**Expected behavior**

Wallet loads, shows the confirmed UTXO, and can build a PSET for the DIY.

If TxList is missing a tx that `listunspent` reports, Specter should `gettransaction` that txid and insert it, or skip the UTXO. A cache miss must not make the wallet unloadable.

**Screenshots**

N/A. UI: `Failed to load utxos, KeyError: f6d0fb22c0488fa6f1b18a08763ee38cd119bdca85f6dc9a8ed9bdcf1b4eafda`

**Desktop**

- Node: linux local (external) Elements Core, datadir `/mnt/sde1/elements`, chain `liquidv1`
- Specter: separate Linux machine, `~/.specter`
- OS: Linux (Ubuntu 24.04) on both machines
- Browser: Google Chrome Version 152.0.7977.64 (Offizieller Build) (x86_64)
- Specter Version: 2.1.11 (installed with pipx install --python python3.10 cryptoadvance.specter)
- Elements version: 23.3.3
- Sender wallet: Blockstream.app (Green) on Linux

**Additional context**

Elements wallet actually used by Specter:

- RPC name: `specter73f00378dd35eee3/liquid9`
- sqlite descriptor wallet, `private_keys_enabled: false`
- `txcount`: 1, `balance.bitcoin`: 0.00021629
- `listdescriptors` on the node are **unblinded** only:
- `wpkh([455edac7/84'/1776'/0']xpub…/0/*)`
- `wpkh([455edac7/84'/1776'/0']xpub…/1/*)`

Specter JSON (`~/.specter/wallets/liquidv1/liquid9.json`):

- `recv_descriptor` / `change_descriptor` are `blinded(slip77(...), wpkh(...))`
- current `address` is confidential `lq1q…` at `address_index: 1` (next address, not the funded `/0/0`)
- `blockheight`: 0
- no `*_txs.csv` in the wallet dir

A hand-created empty wallet `createwallet "liquid9" …` also exists at `wallets/liquid9` and does **not** contain this tx (`gettransaction` → `-5`). Only `specter73f00378dd35eee3/liquid9` does.

`loadwallet specter73f00378dd35eee3` fails with `-18` because that path is a directory; the wallet file is `specter73f00378dd35eee3/liquid9/wallet.dat`.

Recreating the wallet in Specter fails with `createwallet('specter73f00378dd35eee3/liquid9', True): Database already exists`.

Clearing `liquid9_addr.csv` / `last_block` and rescanning does not fix the KeyError.

Likely two stacked issues:

1. `check_utxo` treats a TxList miss as fatal (should fetch or skip).
2. Specter stores SLIP-77 blinded descriptors, but imports only bare `wpkh` into Elements. `listunspent` still works; Specter’s Liquid `fetch_transactions` / TxList may not ingest that receive.

Workaround idea: in `check_utxo`, on `KeyError` after refresh, `continue` or pull `gettransaction(txid)` into TxList. Funds are not lost; only the UI fails to open.

Related: #2429, #2236.

Contributor guide

Open the contributing guide

Research direction

Start with liquid/wallet.py getdata and wallet.py check_utxo, then trace fetch_transactions() and the local TxList lookup. Reproduce the missing transaction case using the listed Elements Core wallet details and confirm why the receive is absent after refresh. Done means the wallet loads the confirmed UTXO and can build a PSET, without a TxList cache miss making it unloadable.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.