Skip to content

Commit e4d628a

Browse files
committed
Document relay best practice in C# binding
1 parent c62e4b2 commit e4d628a

1 file changed

Lines changed: 37 additions & 0 deletions

File tree

payjoin-ffi/csharp/Payjoin.Http.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,43 @@
66

77
namespace Payjoin.Http
88
{
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+
/// Random selection only helps if the relay list itself is not identifying: prefer a shared
17+
/// relay list and discourage isolated infrastructure that other apps don't use, since a
18+
/// distinctive list fingerprints the client regardless of how a relay is picked from it.
19+
///
20+
/// Sender and receiver have distinct request patterns:
21+
/// - Receiver: long-poll GETs, then a POST
22+
/// - Sender: a POST, then long-poll GETs
23+
///
24+
/// OHTTP does not hide the client IP from the relay. A relay that sees the same
25+
/// client repeatedly can observe its access patterns to infer whether
26+
/// the IP is associated with a sender or receiver, potentially linking to identity or
27+
/// location. Based on when a session ends it may be easier to correctly guess
28+
/// whether a transaction is a PayJoin. The IP address linked information may
29+
/// additionally aid in cluster analysis, for example whether a cluster's temporal
30+
/// patterns are consistent with a location guess for the IP address.
31+
///
32+
/// Health checks: some clients call <see cref="GetOhttpKeysAsync"/> periodically to
33+
/// verify that the directory and relay infrastructure is reachable. Given the threat
34+
/// model above, this is acceptable only when:
35+
/// - The call is not triggered on any deterministic, recurring event
36+
/// (e.g. app startup, periodic timer). Prefer user-initiated actions
37+
/// (e.g. opening a settings/status screen) or piggybacking on operations
38+
/// the user already triggered (e.g. resuming an existing session).
39+
/// - The caller throttles invocations so they don't produce a recurring
40+
/// timing pattern observable by the relay.
41+
///
42+
/// A health check has a distinct traffic pattern from a real payjoin request
43+
/// and is not temporally tied to any onchain broadcast, but repeated calls
44+
/// still expose the client IP to the relay.
45+
/// </remarks>
946
internal sealed class OhttpKeysClient : IDisposable
1047
{
1148
private readonly HttpClient _client;

0 commit comments

Comments
 (0)