1234567891011121314import {15 pairWithDesktopHelper,16 type DesktopPairingDeps,17 type PairWithDesktopCallbacks,18} from "./desktop-pairing";19import { openPairingSocket } from "../shared/pairing-dial";20import { upsertPairedDevice, setLastKnownIp } from "./paired-devices";21import { buildLocalIdentity } from "./chirp-identity";22import { computeVaultId } from "../shared/sync-identity";23import { isUnlocked, getRootKeyHex } from "./vault";24import { probeSubnetForPort, wsPortOpen } from "./desktop-pairing-probe";25import { discoverPeachSync } from "./desktop-pairing-mdns";26import { getLocalSubnet } from "../shared/local-network";27import type { LocalIdentity } from "../shared/chirp-handshake";2829function hexToBytesLocal(hex: string): Uint8Array {30 const out = new Uint8Array(hex.length / 2);31 for (let i = 0; i < out.length; i++) out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);32 return out;33}343536function push(type: string, payload: unknown): void {37 try {38 const maybe = chrome.runtime.sendMessage({ type, payload }) as unknown;39 if (maybe && typeof (maybe as Promise<unknown>).catch === "function") {40 (maybe as Promise<unknown>).catch(() => undefined);41 }42 } catch {43 44 }45}4647484950515253export { openPairingSocket as openBinaryWebSocket };545556export function productionDesktopPairingDeps(): DesktopPairingDeps {57 return {58 async findHost(port) {59 60 61 62 if (await wsPortOpen("127.0.0.1", port, 800)) return "127.0.0.1";63 64 const discovered = await discoverPeachSync();65 if (discovered && (await wsPortOpen(discovered.ip, port, 800))) return discovered.ip;66 67 const subnet = await getLocalSubnet();68 if (!subnet) return null;69 return probeSubnetForPort(subnet, port);70 },71 openSocket: (ip, port) => openPairingSocket(ip, port),72 async getLocalIdentity(): Promise<LocalIdentity> {73 if (!isUnlocked()) throw new Error("vault_locked");74 const masterKeyHex = getRootKeyHex();75 if (!masterKeyHex) throw new Error("vault_locked");76 77 78 const masterKey = hexToBytesLocal(masterKeyHex);79 try {80 const base = await buildLocalIdentity(masterKey);81 const vaultId = await computeVaultId(masterKey);82 return { ...base, vaultId };83 } finally {84 masterKey.fill(0);85 }86 },87 persistDevice: (d) => upsertPairedDevice(d),88 cacheLastKnownIp: (pubkeyHex, ip) => setLastKnownIp(pubkeyHex, ip),89 };90}9192939495let pendingConfirm: ((confirmed: boolean) => void) | null = null;96let inFlight = false;9798function clearPairingState(): void {99 pendingConfirm = null;100 inFlight = false;101}102103export function isDesktopPairingInFlight(): boolean {104 return inFlight;105}106107108109110111112export function startDesktopPairing(113 code: string,114 deps: DesktopPairingDeps = productionDesktopPairingDeps(),115): void {116 inFlight = true;117 const cb: PairWithDesktopCallbacks = {118 onSasReady: (sas) => push("DESKTOP_PAIR_SAS", { sas }),119 onComplete: (device) => {120 push("DESKTOP_PAIR_RESULT", { status: "complete", device });121 clearPairingState();122 },123 onError: (error) => {124 push("DESKTOP_PAIR_RESULT", { status: "error", error });125 clearPairingState();126 },127 };128 129 const confirm = (_sas: string): Promise<boolean> =>130 new Promise<boolean>((resolve) => { pendingConfirm = resolve; });131132 void pairWithDesktopHelper(code, cb, deps, confirm).finally(() => {133 134 135 if (inFlight) clearPairingState();136 });137}138139140export function resolveDesktopPairingConfirm(confirmed: boolean): void {141 const resolve = pendingConfirm;142 pendingConfirm = null;143 if (resolve) resolve(confirmed);144}