Skip to content

Commit 8da166e

Browse files
authored
Merge pull request #99 from libp2p/docs/stellar-examples
docs: examples - transports, crypto channels, protocol and stream muxing
2 parents b6e4192 + f583b1b commit 8da166e

File tree

19 files changed

+1051
-6
lines changed

19 files changed

+1051
-6
lines changed

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
- [Bundles](#bundles)
3131
- [Usage](#usage)
3232
- [Install](#install)
33+
- [Usage](#usage)
3334
- [API](#api)
3435
- [Development](#development)
3536
- [Tests](#tests)
@@ -46,7 +47,7 @@ We are in the process of writting better documentation, blog posts, tutorials an
4647
- [libp2p.io](https://libp2p.io)
4748
- [Specification (WIP)](https://github.com/libp2p/specs)
4849
- Talks
49-
- [`libp2p <3 ethereum` at DEVCON2](https://ethereumfoundation.org/devcon/?session=libp2p) [video](https://www.youtube.com/watch?v=HxueJbeMVG4) [slides](https://ethereumfoundation.org/devcon/wp-content/uploads/2016/10/libp2p-HEART-devp2p-IPFS-PLUS-Ethereum-networking.pdf) [demo-1](https://ethereumfoundation.org/devcon/wp-content/uploads/2016/10/libp2p_demo1-1.mp4) [demo-2](https://ethereumfoundation.org/devcon/wp-content/uploads/2016/10/libp2p_demo2-1.mp4)
50+
- [`libp2p <3 ethereum` at DEVCON2](https://ethereumfoundation.org/devcon/?session=libp2p) [📼 video](https://www.youtube.com/watch?v=HxueJbeMVG4) [slides](https://ethereumfoundation.org/devcon/wp-content/uploads/2016/10/libp2p-HEART-devp2p-IPFS-PLUS-Ethereum-networking.pdf) [📼 demo-1](https://ethereumfoundation.org/devcon/wp-content/uploads/2016/10/libp2p_demo1-1.mp4) [📼 demo-2](https://ethereumfoundation.org/devcon/wp-content/uploads/2016/10/libp2p_demo2-1.mp4)
5051
- Articles
5152
- [The overview of libp2p](https://github.com/libp2p/libp2p#description)
5253

@@ -71,6 +72,10 @@ npm install --save libp2p
7172

7273
## Usage
7374

75+
### [Tutorials and Examples](/examples)
76+
77+
You can find multiple examples on the [examples folder](/examples) that will guide you through using libp2p for several scenarions.
78+
7479
### Extending libp2p skeleton
7580

7681
libp2p becomes very simple and basically acts as a glue for every module that compose this library. Since it can be highly customized, it requires some setup. What we recommend is to have a libp2p build for the system you are developing taking into account in your needs (e.g. for a browser working version of libp2p that acts as the network layer of IPFS, we have a built and minified version that browsers can require).

examples/README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,23 @@ In this folder, you can find a variety of examples to help you get started in us
44

55
Let us know if you find any issue or if you want to contribute and add a new tutorial, feel welcome to submit a PR, thank you!
66

7-
## Examples
7+
## Understanding how libp2p works
88

9+
- [Transports](./transports)
10+
- [Protocol and Stream Muxing](./protocol-and-stream-muxing)
11+
- [Encrypted Communications](./encrypted-communications)
12+
- [Discovery Mechanisms](./discovery-mechanisms)
13+
- [Peer Routing](./peer-routing)
14+
- [Content Routing](./content-routing)
15+
- [PubSub](./pubsub)
16+
- [NAT Traversal](./nat-traversal)
17+
- Circuit Relay (future)
18+
- Naming (future)
19+
20+
## Other examples
21+
22+
- [Running libp2p in the Browser](./libp2p-in-the-browser)
23+
- Running libp2p in the Electron (future)
924
- [The standard echo net example with libp2p](./echo)
1025
- [A simple chat app with](./chat)
1126
- [See other nodes in the network using WebRTC Star discovery mechanism](./see-nodes)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# WIP - This example is still in the works
2+
![](http://1.bp.blogspot.com/-tNvSnCW0KlQ/U-KOKGVoJkI/AAAAAAAAA3Q/aiSLMeSJFtw/s1600/WIP-sign.jpg)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
'use strict'
2+
3+
const libp2p = require('libp2p')
4+
const TCP = require('libp2p-tcp')
5+
const SPDY = require('libp2p-spdy')
6+
const SECIO = require('libp2p-secio')
7+
const PeerInfo = require('peer-info')
8+
const waterfall = require('async/waterfall')
9+
const parallel = require('async/parallel')
10+
const pull = require('pull-stream')
11+
12+
class MyBundle extends libp2p {
13+
constructor (peerInfo) {
14+
const modules = {
15+
transport: [new TCP()],
16+
connection: {
17+
muxer: [SPDY],
18+
crypto: [SECIO]
19+
}
20+
}
21+
super(modules, peerInfo)
22+
}
23+
}
24+
25+
function createNode (callback) {
26+
let node
27+
28+
waterfall([
29+
(cb) => PeerInfo.create(cb),
30+
(peerInfo, cb) => {
31+
peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0')
32+
node = new MyBundle(peerInfo)
33+
node.start(cb)
34+
}
35+
], (err) => callback(err, node))
36+
}
37+
38+
parallel([
39+
(cb) => createNode(cb),
40+
(cb) => createNode(cb)
41+
], (err, nodes) => {
42+
if (err) { throw err }
43+
44+
const node1 = nodes[0]
45+
const node2 = nodes[1]
46+
47+
node2.handle('/a-protocol', (protocol, conn) => {
48+
pull(
49+
conn,
50+
pull.map((v) => v.toString()),
51+
pull.log()
52+
)
53+
})
54+
55+
node1.dial(node2.peerInfo, '/a-protocol', (err, conn) => {
56+
if (err) { throw err }
57+
pull(pull.values(['This information is sent out encrypted to the other peer']), conn)
58+
})
59+
})
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Encrypted Communications
2+
3+
libp2p can leverage the encrypted communications from the transports it uses (i.e WebRTC). To ensure that every connection is encrypted, independently of how it was set up, libp2p also supports a set of modules that encrypt every communication established.
4+
5+
We call this usage a _connection upgrade_ where given a connection between peer A to peer B, a protocol handshake can be performed that gives that connection new properties.
6+
7+
A byproduct of having these encrypted communications modules is that we can authenticate the peers we are dialing to. You might have noticed that every time we dial to a peer in libp2p space, we always use its PeerId at the end (e.g /ip4/127.0.0.1/tcp/89765/ipfs/QmWCbVw1XZ8hiYBwwshPce2yaTDYTqTaP7GCHGpry3ykWb), this PeerId is generated by hashing the Public Key of the peer. With this, we can create a crypto challenge when dialing to another peer and prove that peer is the owner of a PrivateKey that matches the Public Key we know.
8+
9+
# 1. Set up encrypted communications with SECIO
10+
11+
We will build this example on top of example for [Protocol and Stream Multiplexing](../protocol-and-stream-multiplexing). You will need the module `libp2p-secio` to complete it, go ahead and `npm install libp2p-secio`.
12+
13+
SECIO is the crypto channel developed for IPFS, it is a TLS 1.3 like crypto channel that established an encrypted communication channel between two peers.
14+
15+
To add it to your libp2p bundle, all you have to do is:
16+
17+
```JavaScript
18+
const SECIO = require('libp2p-secio')
19+
20+
class MyBundle extends libp2p {
21+
constructor (peerInfo) {
22+
const modules = {
23+
transport: [new TCP()],
24+
connection: {
25+
muxer: [SPDY],
26+
// Attach secio as the crypto channel to use
27+
crypto: [SECIO]
28+
}
29+
}
30+
super(modules, peerInfo)
31+
}
32+
}
33+
```
34+
35+
And that's it, from now on, all your libp2p communications are encrypted. Try running the exampme [1.js](./1.js) to see it working.
36+
37+
If you want to want to learn more about how SECIO works, you can read the [great write up done by Dominic Tarr](https://github.com/auditdrivencrypto/secure-channel/blob/master/prior-art.md#ipfss-secure-channel).
38+
39+
Importante note: SECIO hasn't been audited and so, we do not recommend to trust its security. We intent to move to TLS 1.3 once the specification is finalized and an implementation exists that we can use.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# WIP - This example is still in the works
2+
![](http://1.bp.blogspot.com/-tNvSnCW0KlQ/U-KOKGVoJkI/AAAAAAAAA3Q/aiSLMeSJFtw/s1600/WIP-sign.jpg)

examples/nat-traversal/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# WIP - This example is still in the works
2+
![](http://1.bp.blogspot.com/-tNvSnCW0KlQ/U-KOKGVoJkI/AAAAAAAAA3Q/aiSLMeSJFtw/s1600/WIP-sign.jpg)

examples/peer-routing/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# WIP - This example is still in the works
2+
![](http://1.bp.blogspot.com/-tNvSnCW0KlQ/U-KOKGVoJkI/AAAAAAAAA3Q/aiSLMeSJFtw/s1600/WIP-sign.jpg)
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
'use strict'
2+
3+
const libp2p = require('libp2p')
4+
const TCP = require('libp2p-tcp')
5+
const PeerInfo = require('peer-info')
6+
const waterfall = require('async/waterfall')
7+
const parallel = require('async/parallel')
8+
const pull = require('pull-stream')
9+
10+
class MyBundle extends libp2p {
11+
constructor (peerInfo) {
12+
const modules = {
13+
transport: [new TCP()]
14+
}
15+
super(modules, peerInfo)
16+
}
17+
}
18+
19+
function createNode (callback) {
20+
let node
21+
22+
waterfall([
23+
(cb) => PeerInfo.create(cb),
24+
(peerInfo, cb) => {
25+
peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0')
26+
node = new MyBundle(peerInfo)
27+
node.start(cb)
28+
}
29+
], (err) => callback(err, node))
30+
}
31+
32+
parallel([
33+
(cb) => createNode(cb),
34+
(cb) => createNode(cb)
35+
], (err, nodes) => {
36+
if (err) { throw err }
37+
38+
const node1 = nodes[0]
39+
const node2 = nodes[1]
40+
41+
// exact matching
42+
node2.handle('/your-protocol', (protocol, conn) => {
43+
pull(
44+
conn,
45+
pull.map((v) => v.toString()),
46+
pull.log()
47+
)
48+
})
49+
50+
// semver matching
51+
/*
52+
node2.handle('/another-protocol/1.0.1', (protocol, conn) => {
53+
pull(
54+
conn,
55+
pull.map((v) => v.toString()),
56+
pull.log()
57+
)
58+
})
59+
*/
60+
61+
// custom func matching
62+
/*
63+
node2.handle('/custom-match-func', (protocol, conn) => {
64+
pull(
65+
conn,
66+
pull.map((v) => v.toString()),
67+
pull.log()
68+
)
69+
}, (myProtocol, requestedProtocol, callback) => {
70+
if (myProtocol.indexOf(requestedProtocol)) {
71+
callback(null, true)
72+
} else {
73+
callback(null, false)
74+
}
75+
})
76+
*/
77+
78+
node1.dial(node2.peerInfo, '/your-protocol', (err, conn) => {
79+
if (err) { throw err }
80+
pull(pull.values(['my own protocol, wow!']), conn)
81+
})
82+
83+
/*
84+
node1.dial(node2.peerInfo, '/another-protocol/1.0.0', (err, conn) => {
85+
if (err) { throw err }
86+
pull(pull.values(['semver me please']), conn)
87+
})
88+
*/
89+
90+
/*
91+
node1.dial(node2.peerInfo, '/custom-match-func/some-query', (err, conn) => {
92+
if (err) { throw err }
93+
pull(pull.values(['do I fall into your criteria?']), conn)
94+
})
95+
*/
96+
})
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
'use strict'
2+
3+
const libp2p = require('libp2p')
4+
const TCP = require('libp2p-tcp')
5+
const SPDY = require('libp2p-spdy')
6+
const PeerInfo = require('peer-info')
7+
const waterfall = require('async/waterfall')
8+
const parallel = require('async/parallel')
9+
const series = require('async/series')
10+
const pull = require('pull-stream')
11+
12+
class MyBundle extends libp2p {
13+
constructor (peerInfo) {
14+
const modules = {
15+
transport: [new TCP()],
16+
connection: {
17+
muxer: [SPDY]
18+
}
19+
}
20+
super(modules, peerInfo)
21+
}
22+
}
23+
24+
function createNode (callback) {
25+
let node
26+
27+
waterfall([
28+
(cb) => PeerInfo.create(cb),
29+
(peerInfo, cb) => {
30+
peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0')
31+
node = new MyBundle(peerInfo)
32+
node.start(cb)
33+
}
34+
], (err) => callback(err, node))
35+
}
36+
37+
parallel([
38+
(cb) => createNode(cb),
39+
(cb) => createNode(cb)
40+
], (err, nodes) => {
41+
if (err) { throw err }
42+
43+
const node1 = nodes[0]
44+
const node2 = nodes[1]
45+
46+
node2.handle('/a', (protocol, conn) => {
47+
pull(
48+
conn,
49+
pull.map((v) => v.toString()),
50+
pull.log()
51+
)
52+
})
53+
54+
node2.handle('/b', (protocol, conn) => {
55+
pull(
56+
conn,
57+
pull.map((v) => v.toString()),
58+
pull.log()
59+
)
60+
})
61+
62+
series([
63+
(cb) => node1.dial(node2.peerInfo, '/a', (err, conn) => {
64+
if (err) { throw err }
65+
pull(pull.values(['protocol (a)']), conn)
66+
cb()
67+
}),
68+
(cb) => node1.dial(node2.peerInfo, '/b', (err, conn) => {
69+
if (err) { throw err }
70+
pull(pull.values(['protocol (b)']), conn)
71+
cb()
72+
}),
73+
(cb) => node1.dial(node2.peerInfo, '/b', (err, conn) => {
74+
if (err) { throw err }
75+
pull(pull.values(['another conn on protocol (b)']), conn)
76+
cb()
77+
})
78+
])
79+
})

0 commit comments

Comments
 (0)