1234567891011export interface PendingVouchedDevice {12 deviceId: string;13 deviceName: string;14 deviceType: string;15 longTermPublicKeyHex: string;16 signingPublicKeyHex: string;17 wsPort?: number;18 19 pairedAt: number;20 receivedAt: number;21 22 vouchedByDeviceId: string;23}2425const PENDING_KEY = "peach_pending_vouched_devices_v1";2627export async function listPendingVouchedDevices(): Promise<PendingVouchedDevice[]> {28 try {29 const result = await chrome.storage.local.get(PENDING_KEY);30 const value = (result as Record<string, unknown>)[PENDING_KEY];31 if (!Array.isArray(value)) return [];32 return value.filter(isPendingVouchedDevice);33 } catch {34 return [];35 }36}3738export async function getPendingVouchedDevice(39 deviceId: string,40): Promise<PendingVouchedDevice | null> {41 const pending = await listPendingVouchedDevices();42 return pending.find((d) => d.deviceId === deviceId) ?? null;43}4445export async function removePendingVouchedDevice(deviceId: string): Promise<void> {46 const pending = await listPendingVouchedDevices();47 await chrome.storage.local.set({48 [PENDING_KEY]: pending.filter((d) => d.deviceId !== deviceId),49 });50}5152function isPendingVouchedDevice(x: unknown): x is PendingVouchedDevice {53 if (typeof x !== "object" || x === null) return false;54 const r = x as Record<string, unknown>;55 return (56 typeof r.deviceId === "string" && !!r.deviceId &&57 typeof r.deviceName === "string" &&58 typeof r.deviceType === "string" &&59 typeof r.longTermPublicKeyHex === "string" &&60 /^[0-9a-f]{64}$/.test(r.longTermPublicKeyHex as string) &&61 typeof r.signingPublicKeyHex === "string" &&62 /^[0-9a-f]{64}$/.test(r.signingPublicKeyHex as string) &&63 typeof r.receivedAt === "number" &&64 typeof r.vouchedByDeviceId === "string"65 );66}