Skip to content

multi: add labels for static addresses - #1178

Open
GustavoStingelin wants to merge 9 commits into
lightninglabs:multi-address-corefrom
GustavoStingelin:feat/static-address-label
Open

GustavoStingelin wants to merge 9 commits into
lightninglabs:multi-address-corefrom
GustavoStingelin:feat/static-address-label

Conversation

@GustavoStingelin

@GustavoStingelin GustavoStingelin commented Jul 17, 2026 •

Copy link
Copy Markdown
Contributor

Adds local labels for static addresses. Stacked on #1139 (multi-address-core).

  • loop static new --label labels a new receive address, and loop static updatelabel changes or clears a label.
  • Labels are stored in LoopDB. They are never sent to the server and are not part of the address script.
  • loop static listunspent shows each UTXO's address_label. Deposits in the deposit, withdrawal and loop-in listings show address_label and funding_tx_label, the lnd label of the funding transaction.
  • Change addresses created by withdrawals and loop-ins inherit the labels of the deposits they spend. Distinct labels are joined with , up to the 500-character limit.
  • Also fixes the shared --label help text: adds a missing space, and gives listswaps its own help, since there the flag is a filter.

ListStaticAddresses, for finding labeled addresses that haven't been funded yet, will come in a follow-up PR.

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

Comment thread staticaddr/address/manager.go Outdated
@GustavoStingelin
GustavoStingelin force-pushed the feat/static-address-label branch from ae23a9d to 92270e0 Compare July 17, 2026 21:32
@starius

starius commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

I propose to include the current state of #1139 into this PR, so own label commits go after @hieblmi's commits. Add a note to the PR description not to review the multi-address commits.

I attempted to do a rebase using AI, here is my attempt: https://github.com/starius/loop/commits/staticaddr-combined/ It is not functional.

Some semantic rebase is needed. For example:

  • PR 1178 adds 000022_static_address_label, while PR 1139 already uses migrations 22–24 for multi-address persistence.
  • PR 1178 assigns protobuf field 2 in NewStaticAddressRequest to label; PR 1139 assigns field 2 to send_coins.
  • PR 1178 assigns protobuf field 3 in NewStaticAddressResponse to label; PR 1139 assigns field 3 to send_coins_response.

Found some issues in that multi-address + labels branch that I got:

  • the multi-address manager returns an internal *Parameters pointer after releasing its lock, while label update mutates that same object. go test -race reports a real concurrent read/write race. repro
  • after multi-address is applied, static new returns a derived receive address, but static summary still reads the legacy/root seed. The two commands no longer describe the same address. repro
  • every generated change address is stored with an empty label, regardless of the labels on the consumed deposits. I think labels should be inherited by change - that is a common practice among wallets
  • testing gap: the SQL tests read the label back through the same open database/store instance. They do not close and reopen the database or rebuild the manager cache.
  • CLI: the shared --label help text says "label for this swap" and lacks a space, while static deposit --label labels the lnd funding transaction and static new --label labels the address.
  • ListUnspentDeposits includes the label, but historical deposit/list responses carry the address without the corresponding label - needs unification

Some of them will be resolved by a proper rebase, but some seem genuine.

@GustavoStingelin

Copy link
Copy Markdown
Contributor Author

Okay, if we agree to rebase this on top of #1139, I’d prefer to wait until @hieblmi has finished it and its CI is green. This should avoid premature conflicts and duplicated work from having to address #1139’s current race failures in the combined branch.

@GustavoStingelin

Copy link
Copy Markdown
Contributor Author

just rebased from master

@GustavoStingelin
GustavoStingelin force-pushed the feat/static-address-label branch 2 times, most recently from 3172db4 to af8f2ae Compare September 24, 2026 19:17
@GustavoStingelin
GustavoStingelin changed the base branch from master to multi-address-core September 24, 2026 19:17
@GustavoStingelin
GustavoStingelin force-pushed the feat/static-address-label branch from af8f2ae to 084565d Compare September 24, 2026 19:47
@GustavoStingelin

Copy link
Copy Markdown
Contributor Author

@hieblmi rebased this on multi-address-core (thanks!). The rebase raised two design questions I'd like to settle before we go further:

  1. How should address labels relate to funding transaction labels?
  2. Should we add a ListStaticAddresses RPC?

@hieblmi

hieblmi commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator

Thanks @GustavoStingelin

  1. How should address labels relate to funding transaction labels?

I think it is valuable to the user to show these together with the funding outpoitns. The loop s listdeposits in multi-address shows something like

{
  "filtered_deposits": [
    {
      "id": "ea6abb…53e71",
      "state": "DEPOSITED",
      "outpoint": "188f55…561be:0",
      "value": "2500000",
      "confirmation_height": "131",
      "blocks_until_expiry": "14395",
      "swap_hash": "",
      "static_address": "bcrt1p…addressA"
    },
    {
      "id": "ab1234…789ef",
      "state": "DEPOSITED",
      "outpoint": "992abc…456de:1",
      "value": "1000000",
      "confirmation_height": "135",
      "blocks_until_expiry": "14399",
      "swap_hash": "",
      "static_address": "bcrt1p…addressB"
    }
  ]
}

We can then add the fields per entry:

"static_address": "bcrt1p…addressA",
"address_label": "Treasury",
"funding_tx_label": "September top-up"

What do you think?

Should we add a ListStaticAddresses RPC?

Is the intention to find addresses with labels, especially if they don't show up in listdeposits?
I think we can do that, and have it paged since this can result in a huge list. And filter for labelled addresses for example.

@GustavoStingelin

Copy link
Copy Markdown
Contributor Author

We can then add the fields per entry

Sounds good 👍

Is the intention to find addresses with labels, especially if they don't show up in listdeposits?

Yes. The main case is a user who generates a few receive addresses but hasn't funded them yet. loop static new always derives a fresh address, so those unfunded addresses don't appear in listunspent/listdeposits. If the user didn't save them elsewhere, they're effectively lost and unused addresses keep piling up. A ListStaticAddresses RPC would let users find their addresses again by label, whether or not they've been funded.

To keep this PR focused on labels, I'll add ListStaticAddresses in a follow-up PR.

@hieblmi
hieblmi force-pushed the multi-address-core branch 3 times, most recently from ad14247 to 5b76079 Compare September 28, 2026 14:40
@litbot-9000

Copy link
Copy Markdown

@hieblmi: review reminder

@GustavoStingelin
GustavoStingelin removed the request for review from hieblmi October 2, 2026 15:00
@GustavoStingelin
GustavoStingelin force-pushed the feat/static-address-label branch from 084565d to 9108321 Compare October 2, 2026 15:52
Add the missing space in the shared --label help, and give listswaps its
own --label help since there it filters swaps instead of labeling one.
@GustavoStingelin
GustavoStingelin force-pushed the feat/static-address-label branch 2 times, most recently from 65dfd51 to 91b3073 Compare October 5, 2026 21:12
Add a label column to static_addresses and a query to update it, and
select it wherever deposits and change addresses join their address.
Add a Label field to the static address parameters. It is local
metadata and not part of the script or server protocol.
@GustavoStingelin
GustavoStingelin force-pushed the feat/static-address-label branch from 91b3073 to 03027f4 Compare October 5, 2026 21:52
Read and write address labels in the address store, and load them with
deposits and loop-in change addresses.
Add a label to NewStaticAddress, a new UpdateStaticAddressLabel RPC,
and labels on unspent deposits and deposit listings.
Label new addresses, relabel them without mutating published address
snapshots, and fill in address and funding transaction labels in
deposit responses.
Add --label to static new and a static updatelabel command. Also run
the static deposit CLI tests serially and cover its funding --label.
Change addresses take the distinct labels of the addresses they spend,
joined with ", " up to the label limit.
@GustavoStingelin
GustavoStingelin force-pushed the feat/static-address-label branch from 03027f4 to d60dc33 Compare October 6, 2026 02:03
@GustavoStingelin

Copy link
Copy Markdown
Contributor Author
  • Deposits in the deposit, withdrawal and loop-in listings now include address_label and funding_tx_label (the lnd label of the funding transaction), as discussed.
  • Renamed Utxo.label to address_label in ListUnspentDeposits, so both listings use the same name.
  • Removed the label from StaticAddressSummaryResponse. It only ever referred to the legacy/root address.
  • Change addresses created by withdrawals and loop-ins now inherit the labels of the deposits they spend. Distinct labels are joined with , in spend order, labels already inherited aren't repeated, and labels that would exceed the 500-character limit are dropped whole.
  • Deposits and loop-in change addresses loaded from the DB now carry their address label.
  • UpdateStaticAddressLabel returns gRPC NotFound for an unknown address.
  • Fixed the shared --label help text (missing space), and gave listswaps --label its own help, since there it's a filter.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants