fix(settings): scope portfolio groups by wallet identity
Market-tab portfolio groups were tied to a wallet by a hash of its address set. That hash changed whenever an address was added, so a group built for a wallet could silently drop out of view once the wallet gained a new address. - Groups are now scoped by the wallet's stable id, which is persisted and never derived from the address set, so adding an address can no longer orphan a group. - An older build's address-hash scope fails open (the group stays visible) and is migrated once per wallet per session to the stable id. A legacy group is claimed when its old hash matches, when one of its own addresses belongs to this wallet, or when only one wallet is known; anything ambiguous is left legacy and stays visible. - Scope filtering waits until the wallet's addresses are loaded, so a group never flashes an empty 0.0000 balance and Add stays disabled until the wallet is resolved. This works on Lite, which never stamps an address-update time. Behaviour: an older build opened after this change hides groups tagged with a stable "w:" scope (they are not deleted and return on the next upgrade) - worth a release note. Tests: group visibility across global, stable and legacy scopes with the wallet resolved and not; the migration rules (hash match, address overlap, single-wallet claim, ambiguous left alone, idempotent); and a save/load round trip where an address-set change cannot orphan the scope. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -724,12 +724,12 @@ void RenderSharedAddressList(App* app, float listH, float availW,
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginMenu(TR("portfolio_add_to"))) {
|
||||
const auto& pf = app->settings()->getPortfolioEntries();
|
||||
const std::string activeHash = app->activeWalletIdentityHash();
|
||||
const std::string scopeId = app->portfolioScopeId();
|
||||
int shown = 0;
|
||||
for (int pi = 0; pi < (int)pf.size(); pi++) {
|
||||
// Only this wallet's groups (or legacy/unscoped), matching the Market summary —
|
||||
// don't offer to add this address to another wallet's group.
|
||||
if (!(pf[pi].scope.empty() || activeHash.empty() || pf[pi].scope == activeHash))
|
||||
// Only this wallet's groups (or global / not-yet-migrated legacy), matching the Market
|
||||
// summary - don't offer to add this address to another wallet's group.
|
||||
if (!pf[pi].visibleInWallet(scopeId))
|
||||
continue;
|
||||
// PushID keeps the item ID unique even when two groups share a label (a
|
||||
// label-derived MenuItem ID would collide); a blank label shows a placeholder
|
||||
|
||||
Reference in New Issue
Block a user