If you use three relays, then you have three 'sessions' nested inside each other so that each relay learns very little about your connection. You have one session with the first relay, and you use that connection to open a second session with the second relay, and so on. Typical onion routing.
NoiseNK encryption+authentication in session, which itself wraps HTTP2 which can be used for multiplexing multiple requests. One of the streams inside HTTP2 is used to control the payments. So the client exposes a SOCKS5 proxy which might be processing multiple requests in parallel, which is responsible for setting up these nested sessions and making the payments, while all the relays (except the last) just see a single encrypted stream. The relays know the previous hop and the next hop, but that's it; except that the final relay might see you exiting to multiple 'normal' final connections.
Don't be misled by the 'HTTP' in 'HTTP2'; the multiplexed connections can be any arbitrary TCP session, I use it for 'ssh' and am happy with the latency
If there are multiple users, then a given pair of relays would have one connection per user, which has one of that user's sessions (which might itself be many managin multiple 'exit' connections). Those per-user connections are wrapped inside QUIC, which apparently is the very scalable way to multiplex large numbers of connections. This should help a little with privacy, as external viewers see all the traffic between two relays as just one QUIC connection, and QUIC itself adds another layer of encryption. Also, QUIC sometimes merges packets from separate user's streams into one packet, which might help a little with privacy too
I'm not implying QUIC is designed for privacy, but I find it a good place to start.
Links (I haven't pushed recently, trying to only push with each major update):
- MONAD itself:
https://github.com/SatsAndSports/MONAD- Cashu Spilman Channels:
https://github.com/SatsAndSports/cashu_spilman_channels