# 🍐 > Experiments in local-first & friend-to-friend `libp2p` connectivity [`libp2p`](https://libp2p.io/) Go binaries for testing p2p connectivity. I mostly rely on having out-of-band methods for sharing connection details, so I'm not looking at discovery. Since `libp2p` was developed within the context of global p2p connectivity, I'm curious if it smoothly supports local-first and friend-to-friend network architectures like those of the [Scuttleverse](https://www.scuttlebutt.nz/) (no DHT by default and use of relay facilitated connections ("pubs", rooms)). > Update: the answer is: *yes, it does!* ## Scenarios ### Public to public (IPv4) First: ``` ./pear ``` Second: ``` ./pear -with ``` ### Local-first First: ``` ./pear ``` Second: ``` ./pear -port 9001 -with ``` ### Private to private (NAT) using self-hosted relay Here's some [useful docs](https://docs.libp2p.io/concepts/nat/circuit-relay/) for this one. There's quite a few things going on under the hood to keep in mind, e.g. both peers making connections to the relay first, reserving a slot via the one receiving the connection and then the multiaddr of the relayed address is also a bit involved. Ideally, your two `pear` instances which will make relayed connections in this scenario won't have connectivity already. You'll need two machines which are both NATT'd behind a router. I don't think they can be on the same machine because `libp2p` seems to be smart enough to know that two `pear` instances are on the same machine and achieve connectivity. Run a `pear` instance in relay mode on a VPS with a public IPv4, and then connect two additional `pear` instances running on your NATT'd machines via this relay. Relay: ``` ./pear -relay ``` First: ``` ./pear -reserve -with ``` The first peer must reserve a slot at the relay and permit the relay to listen for incoming connections on its behalf ([docs](https://docs.libp2p.io/concepts/nat/circuit-relay/)). Second: ``` ./pear -with -via ``` ### Private to private (NAT) using holepunching (also with self-hosted relay) Same as the above example but for the first peer, you pass `-holepunch`: ``` ./pear -reserve -holepunch -with ``` ## Build ``` go build -v . ``` ## Notes ### Multiaddr including peer identifiers `pear` encapsulates addresses that it outputs to stdout which is handy for copy/pasta'ing to other `pear` instances. So, for example, instead of only getting: > `/ip4/10.137.13.236/tcp/9000`, You get: > `/ip4/10.137.13.236/tcp/9000/p2p/12D3KooWPfGmeozKqrge9Peoi1KV8neku2rqTddZ9aLiZM7Htgpq` This is the `pear` multiaddr which includes the peer identifier which other `pear` instances will require for addressing. ### Binary size Even the simplest `libp2p` Go program ends up being ~ 20/30 megabytes in size. This can be reduced using some tricks e.g. `upx --best --lzma` and `-ldflags="-s -w"`.