Skip to content

Transaction labels are misleading #2018

Open

Description

@moneymanolis

Currently, in Specter, there is only address labelling. The data structures are:

For the CSV:

Address,Label
bc1qj3...,some_label

For the JSON:
{"labels": {"some_label": ["bc1qj3..."], ...}

Unlike for example in Electrum, where you have this structure:
{"8a5e4...": "some tx id label", "bc1qj3...": "some address label"}

The tx labels are by default currently some address that is chosen to be the somewhat relevant destinaton address for the tx:
E.g. sending to bcrt1qhrk4jmxky43nf2jup7pz6336nr4py97td5szrp results in:

image

If you change the "tx label" it will change the label for the associated address, and vice versa, which is, in particular, problematic if you have a tx where you receive, since this can lead to unexpected results:

If you label the tx with id 63882... like this:

image

image

Now, we change the label for bcrt1q9mkrhmxcn7rslzfv6lke8859m7ntwudfjqmcx7 to:

image

which also changes the label for the tx itself:

image

Solution: Have a separate key-value pair for tx-ids and labels.
Intermediate solution: Deactivate the labels column in the tx overview.

Activity

  1. moneymanolis commented on Dec 15, 2022

    @moneymanolis
    CollaboratorAuthor

    Perhaps the easiest thing is to (at least partially) implement Craig's BIP proposal, to have sth. like:

    { "type": "tx", "ref": "f91d0a8a78462bc59398f2c5d7a84fcff491c26ba54c4833478b202796c8aafd", "label": "Transaction" }
    { "type": "addr", "ref": "bc1q34aq5drpuwy3wgl9lhup9892qp6svr8ldzyy7c", "label": "Address" }
    

    The BIP-PR is still open, not sure what is blocking the merge.

  2. moneymanolis commented on Dec 17, 2022

    @moneymanolis
    CollaboratorAuthor

    Multiple recipients

    Also, if you send to multiple recipients no label is used at all, just some html with the number of recipients is injected:

    image

    So, you couldn't label this with e.g. "Donations to different FOSS projects" or "Payments to suppliers".

    What works fine here, though, is persisting labels for individual addresses. Here I simulated "loosing" somehow the label for Output 2 where I mocked the multisig address as donation address of Specter (this is regtest, don't use this!).

    Label lost:

    image

    Reimported the Specter JSON backup file:

    image

  3. al-munazzim commented on Apr 1, 2026

    @al-munazzim
    Contributor

    Triage Assessment

    Type: Enhancement / Architecture
    Priority: MEDIUM
    Verdict: FIX

    This is a well-documented structural issue: transaction labels are stored as address labels, causing confusing coupling where editing a tx label changes the address label (and vice versa). Multi-recipient transactions cannot be labeled at all.

    The good news: BIP-329 (Wallet Labels Export Format) has been finalized since this was filed. It defines a standard JSON Lines format with separate type fields for tx, addr, pubkey, input, output, and xpub — exactly what's needed here.

    Recommended approach:

    1. Add a separate tx_labels dict ({txid: label}) alongside the existing address labels
    2. Update the UI to distinguish address vs transaction labels
    3. Implement BIP-329 export/import for interoperability with Sparrow and other wallets that already support it

    This is a meaningful improvement for users who actively label transactions for accounting or privacy tracking.

  4. schnuartz-ai commented on Sep 11, 2026

    @schnuartz-ai
    Contributor

    I have been exploring a backwards-compatible BIP-329 interoperability layer for the current Specter label model. A working fork PR is available here for review and discussion:

    schnuartz-ai#1

    This does not claim to solve the underlying architecture problem described in this issue. It makes the trade-off explicit:

    1. Full long-term solution: redesign Specter's canonical label model so address, transaction, and output labels are stored independently, then map those concepts directly to BIP-329.
    2. Backwards-compatible adapter: keep the existing address-label store and wallet backup format unchanged, but project the semantics Specter currently exposes into a separate BIP-329 JSONL import/export path.

    The fork PR implements option 2.

    One important detail is that the conversion is intentionally asymmetric. Specter stores an explicit address label but currently uses it as the effective label shown for that address's UTXOs. Sparrow imports BIP-329 addr and output records independently; an imported address label is not automatically propagated to existing outputs. An addr-only export would therefore preserve the address metadata but not the UTXO-label semantics users rely on for coin control.

    The adapter consequently exports:

    • an addr record for each explicitly stored Specter address label;
    • an output record with the same derived label for each current known UTXO on that address;
    • spendable:false for frozen outputs.

    These derived output records do not imply that Specter has an independent per-output label store.

    The reverse mapping is deliberately not performed. Imported addr labels map directly to Specter's existing store, while arbitrary imported output.label values are reported as unsupported. Collapsing potentially different output labels—including historical outputs on a reused address—into one address label would be lossy and could change the apparent labels of unrelated transactions. Output spendable state can still map safely to Specter's existing frozen-UTXO mechanism, with pending-PSBT/Core-lock protections.

    The existing Specter labels backup structure remains unchanged and no migration is introduced. The broader issue here should remain open even if the adapter approach is eventually accepted, because independent transaction/output labeling would still require the full model redesign described above.

    The Sparrow behavior referenced for this decision is in its current WalletLabels importer:
    https://github.com/sparrowwallet/sparrow/blob/3dc99b6b54a6c7a43071aa9e8852c8b2e813b6d1/src/main/java/com/sparrowwallet/sparrow/io/WalletLabels.java#L255-L306

  5. al-munazzim commented on Sep 11, 2026

    @al-munazzim
    Contributor

    Thanks for digging into this and for spelling out the adapter-vs-model-redesign trade-off.

    I agree with keeping this issue open for the broader architectural problem: Specter still does not have independent canonical transaction/output labels, so a BIP-329 adapter should not be treated as closing the misleading-transaction-label behavior by itself.

    For maintainers to review this concretely, please open the work as a draft PR against cryptoadvance/specter-desktop rather than only as a fork PR. In the PR description, the most useful review checkpoints will be:

    • exactly which BIP-329 record types are supported on import/export (addr, output, tx, etc.);
    • confirmation that imported output.label values are reported but not collapsed into Specter address labels;
    • how spendable:false maps to frozen UTXO state, especially around pending PSBTs and pre-existing Core locks;
    • whether the existing Specter JSON/CSV backup/import paths remain byte/behavior compatible;
    • the regression tests covering repeated-address outputs and conflicting duplicate BIP-329 records.

    That will make it much easier to review the compatibility layer on its own merits while still tracking the full independent-label-model redesign here.

  6. schnuartz-ai commented on Sep 13, 2026

    @schnuartz-ai
    Contributor

    Follow-up: the backwards-compatible adapter is now open against upstream as #2712. The PR has a manual Testnet3 Sparrow ↔ Specter report with three screenshots, including a real frozen 38,759-sat UTXO. This implements the interoperability option discussed above; it does not add independent transaction/output label storage or resolve the misleading transaction-label behavior in this issue. Please keep #2018 open for that longer-term model redesign.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    UIUXenhancementNew feature or requestguild/designStuff which might be interesting for design people

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions