We are building a P2P network to store and share contact
& relationships
info between peers.
There are three parties in the network: User, Application & Hub. Each party runs a node and has certain responsibilities and connectivity. We are using Helia for node creation and gossipsub for pubsub.
- Hub: These are Nodejs Helia nodes running in cloud, used by all participants to pin data for long-term storage.
- Users run a node in browser using Helia and indexeddb as blockstore. They store and retrieve data locally and periodically sync with hubs.
- Application developers can also run nodes which are nodejs+helia. they are used mostly for communication purposes, when application need to subscribe to a topic.
Each User and Application communicate with each other to perform Handshakes to exchange contacts and relationship info.
Handshakes:
- Link: A user wants to use the app from two different devices. Two Browser nodes should be able to subscribe to a common topic.
- Join: A user signs up for an app. Browser Node & App Node should be able to subscribe to a common topic.
- Relate: Two users want to connect to share contact info & app wants to observe the relationship events to maintain an index. Two Browser Nodes and One App node should be able to publish & subscribe to a common topic.
Connectivity assumptions:
All user nodes and app nodes dial the Hubs by default when they come online, creating a star topology.
What I have observed till now:
For two nodes to publish and subscribe to a topic they either need to be
- Directly connected (dialing PeerId)
- Connected via another node, but this requires the connector node to also be subscribed to the topic for message forwarding to work.
What I have done till now:
- Link: Since this is a communication between two browser nodes, we chose to go forward with using WebRTC transport, with the Hub acting as the Circuit Relay. We are exchanging PeerID using a Link Url
- Join: Since this is a communication between a browser node and an app node, we chose to use WebSocket transport, app embeds its PeerID in the app html which is used by the client to dial and make a connection
- Relate: This is a three-party handshake, 2 users and one app. We use the app node as the central node for this communication. Where user1 informs app about the topic noth users want to talk over, so that the app node subscribes to the desired topic and message forwarding starts working
I want to achieve the above three handshakes in the most efficient way possible, without each node having to dial each other explicitly. That would require them to know the PeerIDs, which seems non-trivial as a lot of the Browser nodes are transient.
Any advice on the overall design and how to improve it is appreciated
Detailed Doc for the design
Git Repo with current Implementation