SyncPeerRole.kt
1package com.peachpasswords.sync23/**4 * Who speaks first in a relay room.5 *6 * The relay is a two-party splice with no buffering and no "peer joined"7 * signal, so exactly one side must open with `PEACH_RECONNECT` and the other8 * must wait for it. Both sides derive the same room id from the shared pair9 * secret, so the role has to be derivable from state both already hold —10 * there is nothing on the wire to negotiate it with.11 *12 * The lower long-term public key dials and the higher key waits, independent13 * of device type. Browser service workers keep their waiter WebSocket alive14 * with application liveness frames, so extension-to-extension edges no longer15 * need a native device to act as the permanent listener.16 *17 * The keys are hex of the same length, so an ordinary lexicographic compare is18 * a total order over them. Ties are impossible: two devices sharing a static19 * key are the same device.20 */21internal fun weDialPeer(ourLongTermPublicKeyHex: String, peer: PairedDevice): Boolean {22 val theirs = peer.longTermPublicKeyHex ?: return false23 return ourLongTermPublicKeyHex.compareTo(theirs) < 024}