// Transforms the "๐Ÿ”‘ Sign in" nav pill on every Sirius.X page into a wallet // dropdown. Reads siriusProfile from localStorage; when null shows the three // onboarding actions (New wallet / Import a phrase / WizardConnect), when // present shows the signed-in menu (address, My names, Admin, Sign out). // // Each onboarding action deep-links portal.html?mode=new|import|wc; portal.html // picks that up and immediately runs the matching flow โ€” no extra click on // arrival. Signed-in state changes flip the button label without a reload: // the storage event covers cross-tab, a custom 'siriusProfileChanged' event // covers same-tab (portal.html and tld.html both dispatch it on write/clear). (() => { const anchor = document.querySelector(".topnav a.portal"); if (!anchor) return; // Base URL for local links โ€” the nav's brand link is already set with the // right relative path per page (./ at root, ../ in subdirs). Reuse it so // absolute /sirius-x/... paths (which break under the BCNR route) never // slip in. const PORTAL_URL = anchor.getAttribute("href") || "./portal.html"; const BASE = PORTAL_URL.replace(/portal\.html.*$/, ""); const ADMIN_URL = BASE + "admin/"; const readProfile = () => { try { return JSON.parse(localStorage.getItem("siriusProfile") || "null"); } catch { return null; } }; // Build wrapper + button + (empty) menu around the existing pill. const wrap = document.createElement("div"); wrap.className = "profile-wrap"; const btn = document.createElement("button"); btn.type = "button"; btn.className = anchor.className; // reuse .portal (and .here if present) btn.setAttribute("aria-haspopup", "menu"); btn.setAttribute("aria-expanded", "false"); const menu = document.createElement("div"); menu.className = "profile-menu"; menu.setAttribute("role", "menu"); menu.hidden = true; // Header "Dashboard" button โ€” sits left of the wallet pill and is the one // way into names, TLDs, the web-builder and (for the operator) the admin // panel. Always visible: signed out it lands on the portal's sign-in. const dash = document.createElement("a"); dash.className = "dash-link" + (/\/portal\.html(?:$|[?#])/.test(location.pathname) ? " here" : ""); dash.href = PORTAL_URL; dash.innerHTML = ` Dashboard`; const readWalletInfo = () => { try { return JSON.parse(localStorage.getItem("siriusWalletInfo") || "null"); } catch { return null; } }; const fmtInt = (n) => String(n).replace(/\B(?=(\d{3})+(?!\d))/g, ","); // ---------- render ---------- // Re-renders the button label AND the menu innerHTML from the current // profile in localStorage. Called at load, on every open(), and whenever // another tab or this tab updates the storage key. function render() { const p = readProfile(); if (p) { const dot = ``; const label = shortAddr(p.address); const sourceBadge = p.source === "wc" ? `WC` : `seed`; btn.innerHTML = `${dot}${escapeAttr(label)}${sourceBadge}`; btn.setAttribute("aria-label", `Wallet ${label}, signed in via ${p.source || "seed"}`); // Wallet-only menu: identity, balance, receive, settings, sign out. // Names/TLDs/admin live behind the Dashboard button next to this one. const info = readWalletInfo(); const bal = info?.sats != null ? `${fmtInt(info.sats)} sat` : "โ€”"; const held = info ? `${info.names ?? 0} name${info.names === 1 ? "" : "s"} ยท ${info.tlds ?? 0} TLD${info.tlds === 1 ? "" : "s"}` : "open the dashboard to load"; menu.innerHTML = `
Signed in via ${escapeAttr(p.source === "wc" ? "WizardConnect" : "seed phrase")} ยท chipnet ${escapeAttr(p.address)}
Balance${escapeAttr(bal)}
Holdings${escapeAttr(held)}
โง‰ Copy addressreceive coins or names here ${p.tokenAddress ? ` ๐ŸŽŸ Copy token addresswhere name certificates are minted ` : ""} ๐Ÿšฐ Get test coinschipnet faucet โš™ Wallet settingssession, PIN, forget device
๐Ÿšช Sign outclear this browser `; } else { const dot = ``; btn.innerHTML = `${dot}Wallet`; btn.setAttribute("aria-label", "Wallet โ€” not signed in"); // If a saved encrypted wallet already exists in this browser (created // in a previous session), surface an Unlock option as the first item so // users can sign back into the same wallet the mint flow would use โ€” // instead of hunting for it inside the Register modal's wallet-choice. const hasSaved = (() => { try { return !!localStorage.getItem("bns.wallet.v1"); } catch { return false; } })(); const unlockItem = hasSaved ? ` ๐Ÿ”“ Unlock my walletone you already created on this device
` : ""; const headerHint = hasSaved ? `Locked wallet on this deviceUnlock or pick another action` : `No wallet yetPick how to sign in`; // Four direct actions โ€” each opens the shared modal at the matching // step (Unlock/Create/Import/WizardConnect) with tabs across the top // of the modal so the user can switch between them without going back // to a landing screen. menu.innerHTML = `
${headerHint}
${unlockItem} ๐Ÿ†• Create a walletgenerate a fresh 12-word phrase (sign up) ๐Ÿ“ฅ Import a walletseed phrase you already have (sign in) ๐Ÿ”— WizardConnectCashonize / Paytaca via QR `; } } render(); // ---------- open/close ---------- // Opening the menu asks the dashboard (when it is the current page) for a // fresh electrum balance; the numbers repaint when it arrives. Other pages // show the last figure the dashboard or a sign-in wrote, with its age. const open = () => { render(); menu.hidden = false; btn.setAttribute("aria-expanded", "true"); if (typeof window.siriusRefreshBalance === "function") { try { window.siriusRefreshBalance(); } catch {} } }; window.addEventListener("sirius:balance", () => { if (!menu.hidden) render(); }); const close = () => { menu.hidden = true; btn.setAttribute("aria-expanded", "false"); }; btn.addEventListener("click", (e) => { e.stopPropagation(); menu.hidden ? open() : close(); }); document.addEventListener("click", (e) => { if (!wrap.contains(e.target)) close(); }); document.addEventListener("keydown", (e) => { if (e.key === "Escape") close(); }); // Cross-tab (storage event fires only in other tabs) + same-tab (portal.html // dispatches this after writing/clearing) โ€” either wakes render(). window.addEventListener("storage", (e) => { if (e.key === "siriusProfile") render(); }); window.addEventListener("siriusProfileChanged", render); // ---------- menu actions ---------- // Sign-out clears siriusProfile; the wallet-onboarding items (new/import/wc) // open the shared mint modal inline (register-flow.js). If the page did not // ship register-flow.js in its own