|
6 | 6 |
|
7 | 7 | namespace Payjoin.Http |
8 | 8 | { |
| 9 | + /// <summary> |
| 10 | + /// Fetch OHTTP keys from a payjoin directory through an OHTTP relay. |
| 11 | + /// </summary> |
| 12 | + /// <remarks> |
| 13 | + /// When multiple relays are configured, callers should pick one at random per request |
| 14 | + /// to avoid a fixed contact pattern at the network layer. |
| 15 | + /// |
| 16 | + /// Sender and receiver have distinct request patterns: |
| 17 | + /// - Receiver: long-poll GETs, then a POST |
| 18 | + /// - Sender: a POST, then long-poll GETs |
| 19 | + /// |
| 20 | + /// OHTTP does not hide the client IP from the relay. A relay that sees the same |
| 21 | + /// client repeatedly can observe its access patterns to infer whether |
| 22 | + /// the IP is associated with a sender or receiver, potentially linking to identity or |
| 23 | + /// location. Based on when a session ends it may be easier to correctly guess |
| 24 | + /// whether a transaction is a PayJoin. The IP address linked information may |
| 25 | + /// additionally aid in cluster analysis, for example whether a cluster's temporal |
| 26 | + /// patterns are consistent with a location guess for the IP address. |
| 27 | + /// |
| 28 | + /// Health checks: some clients call <see cref="GetOhttpKeysAsync"/> periodically to |
| 29 | + /// verify that the directory and relay infrastructure is reachable. Given the threat |
| 30 | + /// model above, this is acceptable only when: |
| 31 | + /// - The call is not triggered on any deterministic, recurring event |
| 32 | + /// (e.g. app startup, periodic timer). Prefer user-initiated actions |
| 33 | + /// (e.g. opening a settings/status screen) or piggybacking on operations |
| 34 | + /// the user already triggered (e.g. resuming an existing session). |
| 35 | + /// - The caller throttles invocations so they don't produce a recurring |
| 36 | + /// timing pattern observable by the relay. |
| 37 | + /// |
| 38 | + /// A health check has a distinct traffic pattern from a real payjoin request |
| 39 | + /// and is not temporally tied to any onchain broadcast, but repeated calls |
| 40 | + /// still expose the client IP to the relay. |
| 41 | + /// </remarks> |
9 | 42 | internal sealed class OhttpKeysClient : IDisposable |
10 | 43 | { |
11 | 44 | private readonly HttpClient _client; |
|
0 commit comments