Skip to content

Commit 544634f

Browse files
committed
docs: add comprehensive README with API reference and examples
1 parent bc01259 commit 544634f

File tree

11 files changed

+1848
-603
lines changed

11 files changed

+1848
-603
lines changed

.claude/settings.local.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"WebFetch(domain:github.com)",
5+
"WebFetch(domain:raw.githubusercontent.com)",
6+
"WebSearch",
7+
"WebFetch(domain:pkg.go.dev)",
8+
"Read(//Users/ordishs/dev/taal/ilumis/teranode_workspace/go-p2p/**)"
9+
],
10+
"deny": [],
11+
"ask": []
12+
}
13+
}

README.md

Lines changed: 268 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,268 @@
1-
# p2p_poc
2-
# p2p_poc
1+
# P2P Messaging Library
2+
3+
A simple, channel-based peer-to-peer messaging library built on libp2p.
4+
5+
## Features
6+
7+
- **Simple API**: Create a client, subscribe to topics, and publish messages with minimal code
8+
- **Channel-based**: Receive messages through Go channels for idiomatic concurrent programming
9+
- **Auto-discovery**: Automatic peer discovery via DHT, mDNS, and peer caching
10+
- **NAT traversal**: Built-in support for hole punching and relay connections
11+
- **Persistent peers**: Automatically caches and reconnects to known peers
12+
13+
## Installation
14+
15+
```bash
16+
go get github.com/ordishs/p2p_poc
17+
```
18+
19+
## Quick Start
20+
21+
```go
22+
package main
23+
24+
import (
25+
"fmt"
26+
"log"
27+
28+
"github.com/ordishs/p2p_poc"
29+
)
30+
31+
func main() {
32+
// Generate a private key (do this once and save it)
33+
keyHex, err := p2p.GeneratePrivateKeyHex()
34+
if err != nil {
35+
log.Fatal(err)
36+
}
37+
// In production, save keyHex to config file, env var, or database
38+
39+
// Create a P2P client
40+
client, err := p2p.NewPeer(p2p.Config{
41+
Name: "my-node",
42+
PrivateKeyHex: keyHex,
43+
})
44+
if err != nil {
45+
log.Fatal(err)
46+
}
47+
defer client.Close()
48+
49+
// Subscribe to a topic
50+
msgChan := client.Subscribe("my-topic")
51+
52+
// Receive messages
53+
go func() {
54+
for msg := range msgChan {
55+
fmt.Printf("Received from %s: %s\n", msg.From, string(msg.Data))
56+
}
57+
}()
58+
59+
// Publish a message
60+
if err := client.Publish("my-topic", []byte("Hello, P2P!")); err != nil {
61+
log.Printf("Error publishing: %v", err)
62+
}
63+
64+
// Get connected peers
65+
peers := client.GetPeers()
66+
for _, peer := range peers {
67+
fmt.Printf("Peer: %s [%s]\n", peer.Name, peer.ID)
68+
}
69+
70+
select {} // Wait forever
71+
}
72+
```
73+
74+
## API Reference
75+
76+
### Config
77+
78+
```go
79+
type Config struct {
80+
Name string // Required: identifier for this peer
81+
BootstrapPeers []string // Optional: initial peers to connect to
82+
Logger Logger // Optional: custom logger (uses DefaultLogger if not provided)
83+
PrivateKey crypto.PrivKey // Required: private key for persistent peer ID
84+
PeerCacheFile string // Optional: file path for peer persistence
85+
}
86+
```
87+
88+
**Logger Interface:**
89+
90+
The library defines a `Logger` interface and provides a `DefaultLogger` implementation:
91+
92+
```go
93+
type Logger interface {
94+
Debugf(format string, v ...any)
95+
Infof(format string, v ...any)
96+
Warnf(format string, v ...any)
97+
Errorf(format string, v ...any)
98+
}
99+
100+
// DefaultLogger is provided out of the box
101+
logger := &p2p.DefaultLogger{}
102+
103+
// Or use your own custom logger that implements the interface
104+
```
105+
106+
**Persistent Peer Identity:**
107+
108+
The `PrivateKeyHex` field is **required** to ensure consistent peer IDs across restarts:
109+
110+
```go
111+
// Generate a new key for first-time setup
112+
keyHex, err := p2p.GeneratePrivateKeyHex()
113+
if err != nil {
114+
log.Fatal(err)
115+
}
116+
// Save keyHex somewhere (env var, config file, database, etc.)
117+
118+
// Create client with the saved key
119+
client, err := p2p.NewPeer(p2p.Config{
120+
Name: "node1",
121+
PrivateKeyHex: keyHex,
122+
})
123+
124+
// You can also retrieve the key from an existing client
125+
retrievedKey, _ := client.GetPrivateKeyHex()
126+
```
127+
128+
**Peer Persistence:**
129+
130+
The `PeerCacheFile` field is optional and enables peer persistence for faster reconnection:
131+
132+
```go
133+
client, err := p2p.NewPeer(p2p.Config{
134+
Name: "node1",
135+
PrivateKey: privKey,
136+
PeerCacheFile: "peers.json", // Enable peer caching
137+
})
138+
```
139+
140+
When enabled:
141+
- Connected peers are automatically saved to the specified file
142+
- On restart, the client will reconnect to previously known peers
143+
- This significantly speeds up network reconnection
144+
- If not provided, peer caching is disabled
145+
146+
### Client
147+
148+
#### GeneratePrivateKeyHex
149+
150+
```go
151+
func GeneratePrivateKeyHex() (string, error)
152+
```
153+
154+
Generates a new Ed25519 private key and returns it as a hex string. Use this function to create a new key for `Config.PrivateKeyHex` when setting up a new peer for the first time.
155+
156+
#### NewPeer
157+
158+
```go
159+
func NewPeer(config Config) (*Client, error)
160+
```
161+
162+
Creates and starts a new P2P client. The client automatically:
163+
- Creates a libp2p host with NAT traversal support
164+
- Bootstraps to the DHT network
165+
- Starts peer discovery (DHT + mDNS)
166+
- Connects to cached peers from previous sessions
167+
168+
**Note:** Requires `Config.PrivateKeyHex` to be set. Use `GeneratePrivateKeyHex()` to create a new key.
169+
170+
#### Subscribe
171+
172+
```go
173+
func (c *Client) Subscribe(topic string) <-chan Message
174+
```
175+
176+
Subscribes to a topic and returns a channel that receives messages. The channel is closed when the client is closed.
177+
178+
#### Publish
179+
180+
```go
181+
func (c *Client) Publish(topic string, data []byte) error
182+
```
183+
184+
Publishes a message to a topic. The message is broadcast to all peers subscribed to the topic.
185+
186+
#### GetPeers
187+
188+
```go
189+
func (c *Client) GetPeers() []PeerInfo
190+
```
191+
192+
Returns information about all known peers on subscribed topics.
193+
194+
#### GetPrivateKeyHex
195+
196+
```go
197+
func (c *Client) GetPrivateKeyHex() (string, error)
198+
```
199+
200+
Returns the hex-encoded private key for this peer. This can be saved and used in `Config.PrivateKey` to maintain the same peer ID across restarts.
201+
202+
#### Close
203+
204+
```go
205+
func (c *Client) Close() error
206+
```
207+
208+
Shuts down the client and releases all resources.
209+
210+
### Message
211+
212+
```go
213+
type Message struct {
214+
Topic string // Topic this message was received on
215+
From string // Sender's name
216+
FromID string // Sender's peer ID
217+
Data []byte // Message payload
218+
Timestamp time.Time // When the message was received
219+
}
220+
```
221+
222+
### PeerInfo
223+
224+
```go
225+
type PeerInfo struct {
226+
ID string // Peer ID
227+
Name string // Peer name (if known)
228+
Addrs []string // Peer addresses
229+
}
230+
```
231+
232+
## Example
233+
234+
See [example/main.go](example/main.go) for a complete working example.
235+
236+
To run the example:
237+
238+
```bash
239+
cd example
240+
go run main.go -name "node1"
241+
```
242+
243+
In another terminal:
244+
245+
```bash
246+
cd example
247+
go run main.go -name "node2"
248+
```
249+
250+
The two nodes will discover each other and exchange messages.
251+
252+
## How It Works
253+
254+
1. **Peer Discovery**: The library uses multiple discovery mechanisms:
255+
- **DHT**: Connects to IPFS bootstrap peers and advertises topics on the distributed hash table
256+
- **mDNS**: Discovers peers on the local network
257+
- **Peer Cache**: Persists peer information to `peer_cache.json` for faster reconnection
258+
259+
2. **NAT Traversal**: Automatically handles NAT traversal through:
260+
- **Hole Punching**: Attempts direct connections between NAT'd peers
261+
- **Relay**: Falls back to relay connections when direct connections fail
262+
- **UPnP/NAT-PMP**: Automatically configures port forwarding when possible
263+
264+
3. **Message Routing**: Uses GossipSub for efficient topic-based message propagation
265+
266+
## License
267+
268+
MIT

0 commit comments

Comments
 (0)