| … | … | @@ -0,0 +1,18 @@ |
| 1 | // DID-derived P2P discovery (the "sneaky P2P" binding, Option 2). |
| 2 | // |
| 3 | // The rendezvous topic for a DID is DERIVED, not written anywhere: the DID document stays |
| 4 | // 100% vanilla atproto (only atproto_pds -> the bridge), so bsky/HTTP never sees a P2P side. |
| 5 | // A self-custody peer announces on discoveryTopic(did); a bridge, given the DID, derives the |
| 6 | // SAME topic, connects, and AUTHENTICATES the peer on connect (the peer's served repo must |
| 7 | // sign against the DID's key — a squatter on the public topic can't forge that). So the lookup |
| 8 | // is deterministic + unauthenticated; trust is established at the connection, not the address. |
| 9 | |
| 10 | import crypto from 'hypercore-crypto' |
| 11 | |
| 12 | const NS = 'hyper-peer/discovery/v1:' |
| 13 | |
| 14 | // did (string) -> 32-byte Hyperswarm topic. Deterministic; anyone with the DID can compute it. |
| 15 | export function discoveryTopic (did) { |
| 16 | if (!did || typeof did !== 'string') throw new Error('discoveryTopic: did (string) required') |
| 17 | return crypto.data(new TextEncoder().encode(NS + did)) |
| 18 | } |