- password-vault: createVault takes { messengerRootHex } opt; unlockVault
surfaces messengerRoot (null on legacy vaults, so nothing regresses);
saveVault persists it; bindMessengerRoot mutates an unlocked state for a
later attach-mnemonic-to-existing-vault flow.
- main.js password-setup: when the user provides a mnemonic, ALSO compute
seedToPurposeRoot(seed, "messenger/0") and store it. Random-seed vaults
stay as-is (no mnemonic = no messenger root to store).
- main.js hermes-init: two modes now — { mnemonic } (unchanged) or
{ useVault: true } (uses vaultState.messengerRoot directly, no mnemonic).
Response includes source: "vault" | "mnemonic" for the panel to badge.
- main.js hermes-can-use-vault: cheap availability probe used by the panel
to decide whether to show the vault sign-in shortcut.
- hermes.js: nostrKeyFromRoot(root) accepts 32-byte Uint8Array or 64-char
hex; produces the same {sk, pkHex, npub} as nostrKeyFromMnemonic for the
same seed (unit-verified: derivation paths converge on f2c92519...67f4).
- Messages panel: "Sign in with password vault" button appears above the
mnemonic entry iff the vault is unlocked AND was set up from a mnemonic.
The mnemonic path stays as the always-available fallback — bind is
genuinely optional, not required.
25 lines
1.2 KiB
JavaScript
25 lines
1.2 KiB
JavaScript
// Renderer bridge for the Messages panel.
|
|
// All hermes-* IPC returns { ok, ... } | { ok: false, err }.
|
|
const { contextBridge, ipcRenderer } = require("electron");
|
|
|
|
contextBridge.exposeInMainWorld("hermes", {
|
|
status: () => ipcRenderer.invoke("hermes-status"),
|
|
canUseVault: () => ipcRenderer.invoke("hermes-can-use-vault"),
|
|
init: (mnemonic) => ipcRenderer.invoke("hermes-init", { mnemonic }),
|
|
initFromVault: () => ipcRenderer.invoke("hermes-init", { useVault: true }),
|
|
close: () => ipcRenderer.invoke("hermes-close"),
|
|
inbox: () => ipcRenderer.invoke("hermes-inbox"),
|
|
send: (to, text) => ipcRenderer.invoke("hermes-send", { to, text }),
|
|
// Server-push: new decrypted message arrived. Callback gets { senderPkHex, senderName, text, createdAt }.
|
|
onMessage: (cb) => {
|
|
const wrapped = (_e, msg) => cb(msg);
|
|
ipcRenderer.on("hermes-message", wrapped);
|
|
return () => ipcRenderer.removeListener("hermes-message", wrapped);
|
|
},
|
|
// Server-push: relay connection state changed. Callback gets { relaysConnected, relaysTotal }.
|
|
onStatus: (cb) => {
|
|
const wrapped = (_e, s) => cb(s);
|
|
ipcRenderer.on("hermes-status-update", wrapped);
|
|
return () => ipcRenderer.removeListener("hermes-status-update", wrapped);
|
|
},
|
|
});
|