sync-types.ts

2.4 KB · raw

1/**2 * Types for Peach Sync - encrypted cross-device credential synchronization3 */45export interface TrustedNetwork {6  ssid?: string;7  bssid?: string;8  isTailscale: boolean;9  addedAt: number;10}1112export interface PairedDevice {13  deviceId: string;14  displayName: string;15  x25519PublicKey: string;16  pairedAt: number;17  lastSeenAt?: number;18  lastSyncAt?: number;19}2021export interface SyncManifestEntry {22  id: string;23  modifiedAt: number;24  deletedAt?: number;25  hash: string;26}2728export type SyncMessage =29  | { type: "SYNC_HELLO"; deviceId: string; clockMs: number; vaultVersion: number }30  | { type: "SYNC_MANIFEST"; entries: SyncManifestEntry[] }31  | { type: "SYNC_REQUEST"; ids: string[] }32  | { type: "SYNC_ENTRIES"; entries: EncryptedSyncEntry[] }33  | { type: "SYNC_DONE" }34  | { type: "SYNC_ERROR"; code: string; message: string }35  | { type: "PAIR_REQUEST"; edPublicKey: string; name: string; code: string }36  | { type: "PAIR_ACCEPT"; edPublicKey: string; name: string }37  | { type: "PAIR_REJECT"; reason: string };3839export interface EncryptedSyncEntry {40  id: string;41  modifiedAt: number;42  deletedAt?: number;43  ciphertext: string;44  nonce: string;45  tag: string;46}4748export type SyncStatus = "synced" | "syncing" | "no_peers" | "not_trusted" | "offline";4950export interface SyncState {51  status: SyncStatus;52  lastSyncAt?: number;53  pairedDevices: PairedDevice[];54  trustedNetworks: TrustedNetwork[];55  isPro: boolean;56}5758export type PairingStep =59  | { stage: "idle" }60  | { stage: "generating_code"; code: string; expiresAt: number }61  | { stage: "waiting_for_peer" }62  | { stage: "entering_code" }63  | { stage: "connecting"; peerName: string }64  | { stage: "verifying" }65  | { stage: "done"; device: PairedDevice }66  | { stage: "error"; message: string };6768export interface NoiseHandshakeResult {69  sessionKey: Uint8Array;70  sendNonce: number;71  receiveNonce: number;72  isInitiator: boolean;73}7475/**76 * Pairing request received from a peer that needs user confirmation.77 *78 * The banner expires after 60 seconds (`expiresAt - receivedAt = 60_000`);79 * after that the popup hides the banner and the background drops the80 * request. The publicKeyHex is the peer's static X25519 identity — it81 * gets written to trusted devices on accept and discarded on reject.82 */83export interface IncomingPairingRequest {84  deviceName: string;85  publicKeyHex: string;86  receivedAt: number;87  expiresAt: number;88}