diff --git a/js/profile-menu.js b/js/profile-menu.js index ca252c1..d2650d0 100644 --- a/js/profile-menu.js +++ b/js/profile-menu.js @@ -155,6 +155,11 @@ const action = t.dataset.action; if (action === "signout") { try { localStorage.removeItem("siriusProfile"); } catch {} + // Also drop the session-cached seed so a reload after sign-out really + // signs the user out (else the next page load would silently rebuild + // the same wallet from sessionStorage). + try { sessionStorage.removeItem("siriusSessionMnemonic"); sessionStorage.removeItem("siriusSessionSource"); } catch {} + try { delete window.siriusWallet; } catch { window.siriusWallet = null; } window.dispatchEvent(new Event("siriusProfileChanged")); // Reload so any signed-in section on the current page (portal, tld) resets. location.reload(); diff --git a/js/register-flow.js b/js/register-flow.js index 702e8e7..9ed1e83 100644 --- a/js/register-flow.js +++ b/js/register-flow.js @@ -242,11 +242,20 @@ function writeProfile(w) { // mode, mark siriusProfile and close the modal here; otherwise return // false so the caller keeps going to Fund → Confirm → Register. function finishSignIn(w) { - writeProfile({ address: w.address, tokenAddress: w.tokenAddress, source: w.source ?? "seed" }); - // Expose the live wallet globally so the portal / TLD page can pick it up - // without re-prompting for a password. In-memory only — cleared on reload, - // sign-out, or navigation away. + // Expose the live wallet globally BEFORE writeProfile so any listener of + // siriusProfileChanged (portal.html adoptWalletFromModal) sees the wallet + // and can switch to the signed-in view synchronously. window.siriusWallet = w; + // Session-cache the seed so a page reload restores the wallet without + // asking for the password again. sessionStorage is per-tab and clears on + // browser close — same lifetime as a "keep me signed in for this session" + // toggle in a normal app. Chipnet-only convenience; mainnet gets the PIN + // escrow pattern (see finishSignIn comment history). + try { + if (w?.mnemonic) sessionStorage.setItem("siriusSessionMnemonic", w.mnemonic); + if (w?.source === "wc") sessionStorage.setItem("siriusSessionSource", "wc"); + } catch {} + writeProfile({ address: w.address, tokenAddress: w.tokenAddress, source: w.source ?? "seed" }); if (state.signInOnly) { render(`

Signed in

You are signed in as ${esc(w.address)}. Names you own @@ -337,7 +346,24 @@ function adoptSignedInWallet() { return false; } -function startFlow(name, opts = {}) { +// Best-effort silent rebuild from sessionStorage — same session ⇒ same +// wallet, no password prompt. Returns true when the wallet is ready. +async function adoptSessionWalletAsync() { + if (state.wallet) return true; + if (adoptSignedInWallet()) return true; + try { + const cached = typeof sessionStorage !== "undefined" + ? sessionStorage.getItem("siriusSessionMnemonic") + : null; + if (!cached) return false; + const w = await BNS.BuiltInWallet.fromMnemonic(cached); + window.siriusWallet = w; + state.wallet = w; + return true; + } catch { return false; } +} + +async function startFlow(name, opts = {}) { state.name = name; state.tld = null; state.signInOnly = false; @@ -350,7 +376,7 @@ function startFlow(name, opts = {}) { ? BigInt(opts.serviceFeeSats) : (p ? p.sats : null); open(); - if (adoptSignedInWallet()) stepFund(); + if (await adoptSessionWalletAsync()) stepFund(); else stepWallet(); } @@ -358,12 +384,12 @@ function startFlow(name, opts = {}) { // the mint step calls registerTldWith(Built|External)Wallet instead of the // name variant, and the "done" screen skips the record editor since a TLD // certificate goes to the operator's token address as-is. -function startTldFlow(label, opts = {}) { +async function startTldFlow(label, opts = {}) { state.name = `.${label}`; // used for headings only state.tld = { label, serviceFeeSats: BigInt(opts.serviceFeeSats ?? 0n) }; state.signInOnly = false; open(); - if (adoptSignedInWallet()) stepFund(); + if (await adoptSessionWalletAsync()) stepFund(); else stepWallet(); } diff --git a/portal.html b/portal.html index 71ca787..c69665f 100644 --- a/portal.html +++ b/portal.html @@ -278,6 +278,20 @@ async function adoptWalletFromModal() { await enterPortal(); return true; } + // No live wallet in memory — but if a session mnemonic is cached from an + // earlier sign-in in this browser session, rebuild the wallet silently. + // Same tab (or a reload) keeps the user signed in; a full browser close + // clears sessionStorage and drops the user back to Unlock. + try { + const cached = sessionStorage.getItem("siriusSessionMnemonic"); + if (cached) { + const w = await BNS.BuiltInWallet.fromMnemonic(cached); + wallet = w; + window.siriusWallet = w; + await enterPortal(); + return true; + } + } catch { /* fall through to sign-in prompt */ } return false; } function readProfile() {