Receiving address
+
+
+
Assets
+
+
Tokens held by this wallet.
+
diff --git a/bundled-addons/aegis/panel.js b/bundled-addons/aegis/panel.js
index 09574d77..72bc4d45 100644
--- a/bundled-addons/aegis/panel.js
+++ b/bundled-addons/aegis/panel.js
@@ -2136,6 +2136,29 @@ function paintSendMode() {
if (host && consolidateInlineHost !== host) { consolidateInlineHost = host; renderConsolidateInline(host); }
}
}
+// Which half of the Receive pane is showing. Persistent: the choice sticks
+// across re-renders and across wallet switches, because someone comparing
+// token balances between wallets should not be knocked back to the QR on
+// every click.
+let rcvView = "address";
+try { rcvView = localStorage.getItem("aegis/rcvView") === "assets" ? "assets" : "address"; } catch (_e) {}
+function paintRcvView() {
+ const addr = $("rcvAddressPane"), assets = $("rcvAssetsPane");
+ if (!addr || !assets) return;
+ document.querySelectorAll("[data-rcv-view]").forEach((b) =>
+ b.classList.toggle("on", b.dataset.rcvView === rcvView));
+ addr.hidden = rcvView !== "address";
+ assets.hidden = rcvView !== "assets";
+ // The QR's backing store is sized from its rendered box, so one drawn
+ // while its pane was hidden comes out blank. Redraw on reveal — and note
+ // renderReceive only redraws when the address CHANGES, so switching back
+ // to an unchanged address would otherwise never repaint it.
+ if (rcvView === "address") {
+ const a = sel()?.address || "";
+ if (a) { try { drawQr(qrPayload(chain(), a, sel()?.network)); } catch (_e) {} }
+ }
+}
+
function paintRcvMode() {
const normal = $("rcvNormal"); const cons = $("rcvConsolidate");
if (!normal || !cons) return;
@@ -2522,15 +2545,16 @@ function renderWalletStrip() {
pill = `
${esc(meta.networkLabel)}`;
}
- // ▾ chevron shown only when the chain has more than one network —
- // otherwise the click affordance would be a lie and the ticker acts
- // like plain text.
- const multiNet = nets.length > 1;
- const chevron = multiNet ? `
▾` : "";
- const nameCls = multiNet ? "wcname wswitchable" : "wcname";
- const nameTitle = multiNet
- ? `Switch network — ${nets.map((n) => networkLabelFor(chain, n, n)).join(" / ")}`
- : meta.coinName;
+ // 0.16.0: no ▾ network dropdown on the coin row. The coin view already
+ // carries real network chips (data-browse-net — they filter the list and
+ // show a per-network count), so a popover menu doing the same job was a
+ // second way to do one thing, and the only one that hid its options
+ // behind a click. Chips are the single network control now; the ticker
+ // is plain text again.
+ const multiNet = false;
+ const chevron = "";
+ const nameCls = "wcname";
+ const nameTitle = meta.coinName;
// Single wallet under the active network → click selects it. Multi-
// wallet: click selects the "active" wallet for this bucket (defaults
@@ -3323,6 +3347,7 @@ function render() {
if (!showToggle) { sendMode = "send"; rcvMode = "receive"; }
paintSendMode();
paintRcvMode();
+ paintRcvView();
}
// Sum every wallet's confirmed+unconfirmed × price and show "≈ $X across N
@@ -3355,6 +3380,24 @@ function renderPortfolio() {
el.innerHTML = `Portfolio:
${esc(fmtFiat(total))} across ${wallets.length} ${noun}`;
}
+// Assets is a chip now, not a card that disappears when the count is zero.
+// The count rides on the chip and an empty wallet says so in the pane, so
+// "this wallet holds nothing" is a visible answer rather than a missing
+// section the user has to infer — which is exactly how 46 CashTokens managed
+// to look like a working, empty wallet before 0.15.0.
+function setAssetsCount(n) {
+ const chip = $("rcvAssetsCount");
+ if (chip) chip.textContent = n ? String(n) : "";
+ const card = $("tokensCard");
+ if (card) card.hidden = false;
+ if (!n) {
+ const el = $("tokensList");
+ if (el) el.innerHTML = `
No assets held by this wallet.
`;
+ const cnt = $("tokensCount");
+ if (cnt) cnt.textContent = "";
+ }
+}
+
function renderTokens() {
const s = sel();
const card = $("tokensCard");
@@ -3362,7 +3405,7 @@ function renderTokens() {
// SOL wallets: SPL tokens with a Send button (existing flow).
if (chain() === "sol") {
const tokens = s?.tokens || [];
- card.hidden = tokens.length === 0;
+ setAssetsCount(tokens.length);
const hintEl = $("tokensHint");
if (hintEl) hintEl.textContent = "SPL tokens held by this wallet. Send by picking one under the Send tab's Asset dropdown.";
if (!tokens.length) return;
@@ -3388,7 +3431,7 @@ function renderTokens() {
if (chain() === "bch") {
const balances = s?.tokenBalances || {};
const cats = Object.keys(balances);
- card.hidden = cats.length === 0;
+ setAssetsCount(cats.length);
const hintEl = $("tokensHint");
if (hintEl) hintEl.textContent = "CashTokens held by this wallet. Names come from BCMR — configure custom registries in Settings.";
if (!cats.length) return;
@@ -3432,8 +3475,8 @@ function renderTokens() {
// through to a hidden card the way ETH did until 0.9.3.
{
const tokens = s?.tokens || [];
- if (!tokens.length) { card.hidden = true; return; }
- card.hidden = false;
+ if (!tokens.length) { setAssetsCount(0); return; }
+ setAssetsCount(tokens.length);
const hintEl = $("tokensHint");
const kindLabel = chain() === "trx" ? "TRC20" : chain() === "eth" ? "ERC20" : "Tokens";
if (hintEl) hintEl.textContent = `${kindLabel} tokens held by this wallet. Read-only in this build — open the explorer from the header to move them.`;
@@ -3830,10 +3873,17 @@ document.querySelectorAll("[data-send-mode]").forEach((b) => b.addEventListener(
consolidateInlineHost = null; // force re-render on next switch
paintSendMode();
}));
+// Address & QR / Assets — the persistent pair inside the Receive body.
+document.querySelectorAll("[data-rcv-view]").forEach((b) => b.addEventListener("click", () => {
+ rcvView = b.dataset.rcvView === "assets" ? "assets" : "address";
+ try { localStorage.setItem("aegis/rcvView", rcvView); } catch (_e) {}
+ paintRcvView();
+}));
document.querySelectorAll("[data-rcv-mode]").forEach((b) => b.addEventListener("click", () => {
rcvMode = b.dataset.rcvMode;
consolidateInlineHost = null;
paintRcvMode();
+ paintRcvView();
}));
["sendTo", "sendAmt"].forEach((id) => $(id).addEventListener("input", () => {
if (id === "sendAmt" && sendMax) return;