Compare commits

...

27 Commits

Author SHA1 Message Date
e6e5b872dc chore: release version v0.23.0 2018-07-27 14:01:36 +02:00
550af3cbde chore: update contributors 2018-07-27 14:01:36 +02:00
5aa9ebbbe8 chore: update deps 2018-07-27 13:57:15 +02:00
7f68a13433 docs: updte release template - no sharness or interop tests for now :( 2018-07-24 19:55:59 +02:00
2b7cc55c88 feat: add check for protector and enforced pnet
fix: update protector config and tests
docs: add private network info to the readme
test: fix an issue with config
2018-07-24 19:53:53 +02:00
40739e9639 docs: update release template 2018-07-22 19:32:07 +01:00
6106915923 fix: start and stop connection manager with libp2p
test: add test to verify libp2p starts and stops the right things
test: add test for verifying disabled modules
fix: linting
2018-07-22 19:29:19 +01:00
d9059dbad9 chore: update deps 2018-07-13 18:10:03 +02:00
187d584086 docs: update logo url 2018-07-06 19:16:21 +02:00
7502ba86a5 docs: better packages table (#218) 2018-07-05 17:17:47 +02:00
cc51fa59f9 docs: add missing commas to readme example (#216) 2018-07-05 11:47:00 +02:00
1c10842bd3 docs: 2018 Q3 OKRs (#207)
* docs: 2018 Q3 OKRs placeholder

* docs: first draft

* Update OKR.md

* Update OKR.md

* Update OKR.md

* Update OKR.md

* Update OKR.md

* Update OKR.md

* adding 3 more KRs

@jacobheun what you think about taking on these?

* Update OKR.md

* Update OKR.md

* Update OKR.md
2018-07-04 14:03:25 +02:00
c07ffa1317 docs: add release checklist 2018-07-02 14:43:34 +02:00
b7f67f2764 chore: release version v0.22.0 2018-06-29 23:27:29 +01:00
8665286764 chore: update contributors 2018-06-29 23:27:28 +01:00
a43d73eea7 chore: update deps 2018-06-29 23:23:54 +01:00
4ad70efb00 fix: remove peer discovery module config checks
Configuration for the peer discovery modules is now optional so this does not need to be validated. This also cleans up the config module to reduce repetition.

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
2018-06-29 23:42:43 +02:00
1af5ba9093 fix: typo in fixture and fail for correct reason
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
2018-06-29 23:42:43 +02:00
be9eafe20f fix: remove .only
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
2018-06-29 23:42:43 +02:00
27c6587747 test: add test for default registration of function module
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
2018-06-29 23:42:43 +02:00
9521e79061 test: add tests for peer discovery module registration
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
2018-06-29 23:42:43 +02:00
80f0b6077a fix: add null property guards
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
2018-06-29 23:42:43 +02:00
ac5cacba33 fix: do not mutate the config object
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
2018-06-29 23:42:43 +02:00
e320854db7 feat: enable peer discovery modules by default
This PR will enable any provided peer discovery modules by default if no configuration for the module is supplied/needed.

As before, modules can be explicitly disabled or enabled by passing config.

This also enables pre-configured modules (instances) to be passed and enabled without them having to have a `tag` and an unused config section.

License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
2018-06-29 23:42:43 +02:00
501cc22fb4 test: prevent ci collision 2018-06-29 20:38:40 +02:00
a57f1b22d0 chore: update latest webrtc 2018-06-29 20:38:40 +02:00
7baf9f47ac chore: remove travis CI badge 2018-06-28 10:35:18 +02:00
15 changed files with 748 additions and 128 deletions

View File

@ -1,3 +1,37 @@
<a name="0.23.0"></a>
# [0.23.0](https://github.com/libp2p/js-libp2p/compare/v0.22.0...v0.23.0) (2018-07-27)
### Bug Fixes
* start and stop connection manager with libp2p ([6106915](https://github.com/libp2p/js-libp2p/commit/6106915))
### Features
* add check for protector and enforced pnet ([2b7cc55](https://github.com/libp2p/js-libp2p/commit/2b7cc55))
<a name="0.22.0"></a>
# [0.22.0](https://github.com/libp2p/js-libp2p/compare/v0.21.0...v0.22.0) (2018-06-29)
### Bug Fixes
* add null property guards ([80f0b60](https://github.com/libp2p/js-libp2p/commit/80f0b60))
* do not mutate the config object ([ac5cacb](https://github.com/libp2p/js-libp2p/commit/ac5cacb))
* remove .only ([be9eafe](https://github.com/libp2p/js-libp2p/commit/be9eafe))
* remove peer discovery module config checks ([4ad70ef](https://github.com/libp2p/js-libp2p/commit/4ad70ef))
* typo in fixture and fail for correct reason ([1af5ba9](https://github.com/libp2p/js-libp2p/commit/1af5ba9))
### Features
* enable peer discovery modules by default ([e320854](https://github.com/libp2p/js-libp2p/commit/e320854))
<a name="0.21.0"></a>
# [0.21.0](https://github.com/libp2p/js-libp2p/compare/v0.20.4...v0.21.0) (2018-06-28)

11
OKR.md Normal file
View File

@ -0,0 +1,11 @@
# Quarterly Objectives and Key Results
We try to frame our ongoing work using a process based on quarterly Objectives and Key Results (OKRs). Objectives reflect outcomes that are challenging, but realistic. Results are tangible and measurable.
## 2018 Q3
Find the js-libp2p OKRs for 2018 Q2 at the [2018 Q3 libp2p OKRs Spreadsheet](https://docs.google.com/spreadsheets/d/1HTXfgR5FyPTFhsTkFPRThkeMvHvCgJOaAs7BSl_vQ_0/edit#gid=1241853194)
## Previous Quarters
For the quarters before 2018 Q3, js-libp2p shared their KRs with the [IPFS OKRs](https://github.com/ipfs/js-ipfs/blob/master/OKR.md).

125
README.md
View File

@ -1,5 +1,5 @@
<h1 align="center">
<a href="libp2p.io"><img width="250" src="https://github.com/libp2p/libp2p/blob/master/logo/alternates/libp2p-logo-alt-2.png?raw=true" alt="libp2p hex logo" /></a>
<a href="libp2p.io"><img width="250" src="https://github.com/libp2p/libp2p/blob/master/logo/black-bg-2.png?raw=true" alt="libp2p hex logo" /></a>
</h1>
<h3 align="center">The JavaScript implementation of the libp2p Networking Stack.</h3>
@ -12,9 +12,8 @@
</p>
<p align="center">
<a href="https://travis-ci.org/libp2p/js-libp2p"><img src="https://travis-ci.org/libp2p/js-libp2p.svg?branch=master" /></a>
<a href="https://circleci.com/gh/libp2p/js-libp2p"><img src="https://circleci.com/gh/libp2p/js-libp2p.svg?style=svg" /></a>
<a href="https://coveralls.io/github/libp2p/js-libp2p?branch=master"><img src="https://coveralls.io/repos/github/libp2p/js-libp2p/badge.svg?branch=master"></a>
<a href="https://ci.ipfs.team/job/libp2p/job/js-libp2p/job/master/"><img src="https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p/master" /></a>
<a href="https://codecov.io/gh/libp2p/js-libp2p"><img src="https://codecov.io/gh/libp2p/js-libp2p/branch/master/graph/badge.svg"></a>
<br>
<a href="https://david-dm.org/libp2p/js-libp2p"><img src="https://david-dm.org/libp2p/js-libp2p.svg?style=flat-square" /></a>
<a href="https://github.com/feross/standard"><img src="https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square"></a>
@ -116,11 +115,12 @@ const SECIO = require('libp2p-secio')
const MulticastDNS = require('libp2p-mdns')
const DHT = require('libp2p-kad-dht')
const defaultsDeep = require('@nodeutils/defaults-deep')
const Protector = require('libp2p-pnet')
class Node extends libp2p {
constructor (_peerInfo, _peerBook, _options) {
const defaults = {
peerInfo: _peerInfo // The Identity of your Peer
peerInfo: _peerInfo, // The Identity of your Peer
peerBook: _peerBook, // Where peers get tracked, if undefined libp2p will create one instance
// The libp2p modules for this libp2p bundle
@ -135,12 +135,13 @@ class Node extends libp2p {
],
connEncryption: [
SECIO
]
],
connProtector: new Protector(/*protector specific opts*/),
peerDiscovery: [
MulticastDNS
],
peerRouting: {}, // Currently both peerRouting and contentRouting are patched through the DHT,
contentRouting: {} // this will change once we factor that into two modules, for now do the following line:
contentRouting: {}, // this will change once we factor that into two modules, for now do the following line:
dht: DHT // DHT enables PeerRouting, ContentRouting and DHT itself components
},
@ -165,13 +166,16 @@ class Node extends libp2p {
enabled: false,
active: false
}
}
},
dht: {
kBucketSize: 20
},
// Enable/Disable Experimental features
EXPERIMENTAL: { // Experimental features ("behind a flag")
pubsub: false,
dht: false
}
},
}
}
// overload any defaults of your bundle using https://github.com/nodeutils/defaults-deep
@ -429,6 +433,16 @@ Each one of these values is [an exponential moving-average instance](https://git
Stats are not updated in real-time. Instead, measurements are buffered and stats are updated at an interval. The maximum interval can be defined through the `Switch` constructor option `stats.computeThrottleTimeout`, defined in miliseconds.
### Private Networks
#### Enforcement
Libp2p provides support for connection protection, such as for private networks. You can enforce network protection by setting the environment variable `LIBP2P_FORCE_PNET=1`. When this variable is on, if no protector is set via `options.connProtector`, Libp2p will throw an error upon creation.
#### Protectors
Some available network protectors:
* [libp2p-pnet](https://github.com/libp2p/js-libp2p-pnet)
## Development
@ -471,39 +485,70 @@ N/A
List of packages currently in existence for libp2p
| Package | Version | Dependencies | DevDependencies |
|---------|---------|--------------|-----------------|
| **Transports** |
| [`libp2p-utp`](//github.com/libp2p/js-libp2p-utp) | [![npm](https://img.shields.io/npm/v/libp2p-utp.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-utp/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-utp.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-utp) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-utp/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-utp?type=dev) |
| [`libp2p-websockets`](//github.com/libp2p/js-libp2p-websockets) | [![npm](https://img.shields.io/npm/v/libp2p-websockets.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-websockets/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-websockets.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websockets) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-websockets/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websockets?type=dev) |
| [`libp2p-webrtc-star`](//github.com/libp2p/js-libp2p-webrtc-star) | [![npm](https://img.shields.io/npm/v/libp2p-webrtc-star.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-webrtc-star/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-webrtc-star.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-webrtc-star) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-webrtc-star/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-webrtc-star?type=dev) |
| [`libp2p-websocket-star`](//github.com/libp2p/js-libp2p-websocket-star) | [![npm](https://img.shields.io/npm/v/libp2p-websocket-star.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-websocket-star/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-websocket-star.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websocket-star) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-websocket-star/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websocket-star?type=dev) |
| [`libp2p-websocket-star-rendezvous`](//github.com/libp2p/js-libp2p-websocket-star-rendezvous) | [![npm](https://img.shields.io/npm/v/libp2p-websocket-star-rendezvous.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-websocket-star-rendezvous/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-websocket-star-rendezvous.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websocket-star-rendezvous) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-websocket-star-rendezvous/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websocket-star-rendezvous?type=dev) |
| **Connection Upgrades** |
| [`interface-connection`](//github.com/libp2p/interface-connection) | [![npm](https://img.shields.io/npm/v/interface-connection.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/interface-connection/releases) | [![Dependency Status](https://david-dm.org/libp2p/interface-connection.svg?style=flat-square)](https://david-dm.org/libp2p/interface-connection) | [![devDependency Status](https://david-dm.org/libp2p/interface-connection/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/interface-connection?type=dev) |
| **Stream Muxers** |
| [`interface-stream-muxer`](//github.com/libp2p/interface-stream-muxer) | [![npm](https://img.shields.io/npm/v/interface-stream-muxer.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/interface-stream-muxer/releases) | [![Dependency Status](https://david-dm.org/libp2p/interface-stream-muxer.svg?style=flat-square)](https://david-dm.org/libp2p/interface-stream-muxer) | [![devDependency Status](https://david-dm.org/libp2p/interface-stream-muxer/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/interface-stream-muxer?type=dev) |
| [`libp2p-spdy`](//github.com/libp2p/js-libp2p-spdy) | [![npm](https://img.shields.io/npm/v/libp2p-spdy.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-spdy/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-spdy.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-spdy) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-spdy/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-spdy?type=dev) |
| [`libp2p-multiplex`](https://github.com/libp2p/js-libp2p-multiplex)
| **Discovery** |
| [`libp2p-mdns-discovery`](//github.com/libp2p/js-libp2p-mdns-discovery) | [![npm](https://img.shields.io/npm/v/libp2p-mdns-discovery.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-mdns-discovery/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-mdns-discovery.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-mdns-discovery) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-mdns-discovery/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-mdns-discovery?type=dev) |
| [`libp2p-railing`](//github.com/libp2p/js-libp2p-railing) | [![npm](https://img.shields.io/npm/v/libp2p-railing.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-railing/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-railing.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-railing) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-railing/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-railing?type=dev) |
| Package | Version | Deps | CI | Coverage |
| ---------|---------|---------|---------|--------- |
| **Libp2p** |
| [`interface-libp2p`](//github.com/libp2p/interface-libp2p) | [![npm](https://img.shields.io/npm/v/interface-libp2p.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/interface-libp2p/releases) | [![Deps](https://david-dm.org/libp2p/interface-libp2p.svg?style=flat-square)](https://david-dm.org/libp2p/interface-libp2p) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/interface-libp2p/master)](https://ci.ipfs.team/job/libp2p/job/interface-libp2p/job/master/) | [![codecov](https://codecov.io/gh/libp2p/interface-libp2p/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/interface-libp2p) |
| [`libp2p`](//github.com/libp2p/js-libp2p) | [![npm](https://img.shields.io/npm/v/libp2p.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p) |
| **Connection** |
| [`interface-connection`](//github.com/libp2p/interface-connection) | [![npm](https://img.shields.io/npm/v/interface-connection.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/interface-connection/releases) | [![Deps](https://david-dm.org/libp2p/interface-connection.svg?style=flat-square)](https://david-dm.org/libp2p/interface-connection) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/interface-connection/master)](https://ci.ipfs.team/job/libp2p/job/interface-connection/job/master/) | [![codecov](https://codecov.io/gh/libp2p/interface-connection/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/interface-connection) |
| **Transport** |
| [`interface-transport`](//github.com/libp2p/interface-transport) | [![npm](https://img.shields.io/npm/v/interface-transport.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/interface-transport/releases) | [![Deps](https://david-dm.org/libp2p/interface-transport.svg?style=flat-square)](https://david-dm.org/libp2p/interface-transport) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/interface-transport/master)](https://ci.ipfs.team/job/libp2p/job/interface-transport/job/master/) | [![codecov](https://codecov.io/gh/libp2p/interface-transport/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/interface-transport) |
| [`libp2p-circuit`](//github.com/libp2p/js-libp2p-circuit) | [![npm](https://img.shields.io/npm/v/libp2p-circuit.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-circuit/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-circuit.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-circuit) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-circuit/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-circuit/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-circuit/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-circuit) |
| [`libp2p-tcp`](//github.com/libp2p/js-libp2p-tcp) | [![npm](https://img.shields.io/npm/v/libp2p-tcp.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-tcp/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-tcp.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-tcp) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-tcp/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-tcp/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-tcp/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-tcp) |
| [`libp2p-udp`](//github.com/libp2p/js-libp2p-udp) | [![npm](https://img.shields.io/npm/v/libp2p-udp.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-udp/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-udp.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-udp) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-udp/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-udp/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-udp/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-udp) |
| [`libp2p-udt`](//github.com/libp2p/js-libp2p-udt) | [![npm](https://img.shields.io/npm/v/libp2p-udt.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-udt/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-udt.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-udt) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-udt/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-udt/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-udt/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-udt) |
| [`libp2p-utp`](//github.com/libp2p/js-libp2p-utp) | [![npm](https://img.shields.io/npm/v/libp2p-utp.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-utp/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-utp.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-utp) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-utp/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-utp/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-utp/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-utp) |
| [`libp2p-webrtc-direct`](//github.com/libp2p/js-libp2p-webrtc-direct) | [![npm](https://img.shields.io/npm/v/libp2p-webrtc-direct.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-webrtc-direct/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-webrtc-direct.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-webrtc-direct) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-webrtc-direct/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-webrtc-direct/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-webrtc-direct/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-webrtc-direct) |
| [`libp2p-webrtc-star`](//github.com/libp2p/js-libp2p-webrtc-star) | [![npm](https://img.shields.io/npm/v/libp2p-webrtc-star.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-webrtc-star/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-webrtc-star.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-webrtc-star) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-webrtc-star/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-webrtc-star/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-webrtc-star/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-webrtc-star) |
| [`libp2p-websockets`](//github.com/libp2p/js-libp2p-websockets) | [![npm](https://img.shields.io/npm/v/libp2p-websockets.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-websockets/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-websockets.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websockets) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-websockets/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-websockets/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-websockets/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-websockets) |
| [`libp2p-websocket-star`](//github.com/libp2p/js-libp2p-websocket-star) | [![npm](https://img.shields.io/npm/v/libp2p-websocket-star.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-websocket-star/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-websocket-star.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websocket-star) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-websocket-star/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-websocket-star/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-websocket-star/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-websocket-star) |
| [`libp2p-websocket-star-rendezvous`](//github.com/libp2p/js-libp2p-websocket-star-rendezvous) | [![npm](https://img.shields.io/npm/v/libp2p-websocket-star-rendezvous.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-websocket-star-rendezvous/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-websocket-star-rendezvous.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websocket-star-rendezvous) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-websocket-star-rendezvous/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-websocket-star-rendezvous/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-websocket-star-rendezvous/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-websocket-star-rendezvous) |
| **Crypto Channels** |
| [`libp2p-secio`](//github.com/libp2p/js-libp2p-secio) | [![npm](https://img.shields.io/npm/v/libp2p-secio.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-secio/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-secio.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-secio) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-secio/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-secio?type=dev) |
| **Peer Routing** |
| [`libp2p-kad-routing`](//github.com/libp2p/js-libp2p-kad-routing) | [![npm](https://img.shields.io/npm/v/libp2p-kad-routing.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-kad-routing/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-kad-routing.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-kad-routing) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-kad-routing/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-kad-routing?type=dev) |
| **Content Routing** |
| [`interface-record-store`](//github.com/libp2p/interface-record-store) | [![npm](https://img.shields.io/npm/v/interface-record-store.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/interface-record-store/releases) | [![Dependency Status](https://david-dm.org/libp2p/interface-record-store.svg?style=flat-square)](https://david-dm.org/libp2p/interface-record-store) | [![devDependency Status](https://david-dm.org/libp2p/interface-record-store/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/interface-record-store?type=dev) |
| [`libp2p-record`](//github.com/libp2p/js-libp2p-record) | [![npm](https://img.shields.io/npm/v/libp2p-record.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-record/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-record.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-record) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-record/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-record?type=dev) |
| [`libp2p-distributed-record-store`](//github.com/libp2p/js-libp2p-distributed-record-store) | [![npm](https://img.shields.io/npm/v/undefined.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-distributed-record-store/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-distributed-record-store.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-distributed-record-store) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-distributed-record-store/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-distributed-record-store?type=dev) |
| [`libp2p-kad-record-store`](//github.com/libp2p/js-libp2p-kad-record-store) | [![npm](https://img.shields.io/npm/v/libp2p-kad-record-store.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-kad-record-store/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-kad-record-store.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-kad-record-store) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-kad-record-store/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-kad-record-store?type=dev) |
| **Generics** |
| [`libp2p-switch`](//github.com/libp2p/js-libp2p-switch) | [![npm](https://img.shields.io/npm/v/libp2p-switch.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-switch/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-switch.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-switch) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-switch/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-switch?type=dev) |
| [`libp2p-ping`](//github.com/libp2p/js-libp2p-ping) | [![npm](https://img.shields.io/npm/v/libp2p-ping.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-ping/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-ping.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-ping) | [![devDependency Status](https://david-dm.org/libp2p/js-libp2p-ping/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-ping?type=dev) |
| [`multistream-select`](//github.com/libp2p/js-multistream) | [![npm](https://img.shields.io/npm/v/multistream-select.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-multistream/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-multistream.svg?style=flat-square)](https://david-dm.org/libp2p/js-multistream) | [![devDependency Status](https://david-dm.org/libp2p/js-multistream/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-multistream?type=dev) |
| [`libp2p-secio`](//github.com/libp2p/js-libp2p-secio) | [![npm](https://img.shields.io/npm/v/libp2p-secio.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-secio/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-secio.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-secio) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-secio/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-secio/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-secio/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-secio) |
| **Stream Muxers** |
| [`interface-stream-muxer`](//github.com/libp2p/interface-stream-muxer) | [![npm](https://img.shields.io/npm/v/interface-stream-muxer.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/interface-stream-muxer/releases) | [![Deps](https://david-dm.org/libp2p/interface-stream-muxer.svg?style=flat-square)](https://david-dm.org/libp2p/interface-stream-muxer) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/interface-stream-muxer/master)](https://ci.ipfs.team/job/libp2p/job/interface-stream-muxer/job/master/) | [![codecov](https://codecov.io/gh/libp2p/interface-stream-muxer/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/interface-stream-muxer) |
| [`libp2p-mplex`](//github.com/libp2p/js-libp2p-mplex) | [![npm](https://img.shields.io/npm/v/libp2p-mplex.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-mplex/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-mplex.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-mplex) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-mplex/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-mplex/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-mplex/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-mplex) |
| [`libp2p-spdy`](//github.com/libp2p/js-libp2p-spdy) | [![npm](https://img.shields.io/npm/v/libp2p-spdy.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-spdy/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-spdy.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-spdy) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-spdy/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-spdy/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-spdy/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-spdy) |
| **Discovery** |
| [`interface-peer-discovery`](//github.com/libp2p/interface-peer-discovery) | [![npm](https://img.shields.io/npm/v/interface-peer-discovery.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/interface-peer-discovery/releases) | [![Deps](https://david-dm.org/libp2p/interface-peer-discovery.svg?style=flat-square)](https://david-dm.org/libp2p/interface-peer-discovery) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/interface-peer-discovery/master)](https://ci.ipfs.team/job/libp2p/job/interface-peer-discovery/job/master/) | [![codecov](https://codecov.io/gh/libp2p/interface-peer-discovery/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/interface-peer-discovery) |
| [`libp2p-bootstrap`](//github.com/libp2p/js-libp2p-bootstrap) | [![npm](https://img.shields.io/npm/v/libp2p-bootstrap.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-bootstrap/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-bootstrap.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-bootstrap) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-bootstrap/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-bootstrap/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-bootstrap/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-bootstrap) |
| [`libp2p-kad-dht`](//github.com/libp2p/js-libp2p-kad-dht) | [![npm](https://img.shields.io/npm/v/libp2p-kad-dht.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-kad-dht/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-kad-dht.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-kad-dht) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-kad-dht/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-kad-dht/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-kad-dht/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-kad-dht) |
| [`libp2p-mdns`](//github.com/libp2p/js-libp2p-mdns) | [![npm](https://img.shields.io/npm/v/libp2p-mdns.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-mdns/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-mdns.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-mdns) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-mdns/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-mdns/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-mdns/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-mdns) |
| [`libp2p-rendezvous`](//github.com/libp2p/js-libp2p-rendezvous) | [![npm](https://img.shields.io/npm/v/libp2p-rendezvous.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-rendezvous/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-rendezvous.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-rendezvous) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-rendezvous/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-rendezvous/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-rendezvous/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-rendezvous) |
| [`libp2p-webrtc-star`](//github.com/libp2p/js-libp2p-webrtc-star) | [![npm](https://img.shields.io/npm/v/libp2p-webrtc-star.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-webrtc-star/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-webrtc-star.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-webrtc-star) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-webrtc-star/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-webrtc-star/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-webrtc-star/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-webrtc-star) |
| [`libp2p-websocket-star`](//github.com/libp2p/js-libp2p-websocket-star) | [![npm](https://img.shields.io/npm/v/libp2p-websocket-star.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-websocket-star/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-websocket-star.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-websocket-star) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-websocket-star/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-websocket-star/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-websocket-star/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-websocket-star) |
| **NAT Traversal** |
| [`libp2p-circuit`](//github.com/libp2p/js-libp2p-circuit) | [![npm](https://img.shields.io/npm/v/libp2p-circuit.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-circuit/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-circuit.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-circuit) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-circuit/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-circuit/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-circuit/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-circuit) |
| [`libp2p-nat-mngr`](//github.com/libp2p/js-libp2p-nat-mngr) | [![npm](https://img.shields.io/npm/v/libp2p-nat-mngr.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-nat-mngr/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-nat-mngr.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-nat-mngr) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-nat-mngr/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-nat-mngr/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-nat-mngr/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-nat-mngr) |
| **Data Types** |
| [`peer-book`](//github.com/libp2p/js-peer-book) | [![npm](https://img.shields.io/npm/v/peer-book.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-peer-book/releases) | [![Dependency Status](https://david-dm.org/libp2p/js-peer-book.svg?style=flat-square)](https://david-dm.org/libp2p/js-peer-book) | [![devDependency Status](https://david-dm.org/libp2p/js-peer-book/dev-status.svg?style=flat-square)](https://david-dm.org/libp2p/js-peer-book?type=dev) |
| [`peer-id`](https://github.com/libp2p/js-peer-id)
| [`peer-book`](//github.com/libp2p/js-peer-book) | [![npm](https://img.shields.io/npm/v/peer-book.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-peer-book/releases) | [![Deps](https://david-dm.org/libp2p/js-peer-book.svg?style=flat-square)](https://david-dm.org/libp2p/js-peer-book) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-peer-book/master)](https://ci.ipfs.team/job/libp2p/job/js-peer-book/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-peer-book/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-peer-book) |
| [`peer-id`](//github.com/libp2p/js-peer-id) | [![npm](https://img.shields.io/npm/v/peer-id.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-peer-id/releases) | [![Deps](https://david-dm.org/libp2p/js-peer-id.svg?style=flat-square)](https://david-dm.org/libp2p/js-peer-id) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-peer-id/master)](https://ci.ipfs.team/job/libp2p/job/js-peer-id/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-peer-id/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-peer-id) |
| [`peer-info`](//github.com/libp2p/js-peer-info) | [![npm](https://img.shields.io/npm/v/peer-info.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-peer-info/releases) | [![Deps](https://david-dm.org/libp2p/js-peer-info.svg?style=flat-square)](https://david-dm.org/libp2p/js-peer-info) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-peer-info/master)](https://ci.ipfs.team/job/libp2p/job/js-peer-info/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-peer-info/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-peer-info) |
| **Content Routing** |
| [`interface-content-routing`](//github.com/libp2p/interface-content-routing) | [![npm](https://img.shields.io/npm/v/interface-content-routing.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/interface-content-routing/releases) | [![Deps](https://david-dm.org/libp2p/interface-content-routing.svg?style=flat-square)](https://david-dm.org/libp2p/interface-content-routing) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/interface-content-routing/master)](https://ci.ipfs.team/job/libp2p/job/interface-content-routing/job/master/) | [![codecov](https://codecov.io/gh/libp2p/interface-content-routing/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/interface-content-routing) |
| [`libp2p-delegated-content-routing`](//github.com/libp2p/js-libp2p-delegated-content-routing) | [![npm](https://img.shields.io/npm/v/libp2p-delegated-content-routing.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-delegated-content-routing/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-delegated-content-routing.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-delegated-content-routing) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-delegated-content-routing/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-delegated-content-routing/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-delegated-content-routing/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-delegated-content-routing) |
| [`libp2p-kad-dht`](//github.com/libp2p/js-libp2p-kad-dht) | [![npm](https://img.shields.io/npm/v/libp2p-kad-dht.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-kad-dht/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-kad-dht.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-kad-dht) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-kad-dht/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-kad-dht/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-kad-dht/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-kad-dht) |
| **Peer Routing** |
| [`interface-peer-routing`](//github.com/libp2p/interface-peer-routing) | [![npm](https://img.shields.io/npm/v/interface-peer-routing.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/interface-peer-routing/releases) | [![Deps](https://david-dm.org/libp2p/interface-peer-routing.svg?style=flat-square)](https://david-dm.org/libp2p/interface-peer-routing) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/interface-peer-routing/master)](https://ci.ipfs.team/job/libp2p/job/interface-peer-routing/job/master/) | [![codecov](https://codecov.io/gh/libp2p/interface-peer-routing/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/interface-peer-routing) |
| [`libp2p-delegated-peer-routing`](//github.com/libp2p/js-libp2p-delegated-peer-routing) | [![npm](https://img.shields.io/npm/v/libp2p-delegated-peer-routing.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-delegated-peer-routing/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-delegated-peer-routing.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-delegated-peer-routing) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-delegated-peer-routing/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-delegated-peer-routing/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-delegated-peer-routing/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-delegated-peer-routing) |
| [`libp2p-kad-dht`](//github.com/libp2p/js-libp2p-kad-dht) | [![npm](https://img.shields.io/npm/v/libp2p-kad-dht.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-kad-dht/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-kad-dht.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-kad-dht) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-kad-dht/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-kad-dht/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-kad-dht/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-kad-dht) |
| **Record Store** |
| [`interface-record-store`](//github.com/libp2p/interface-record-store) | [![npm](https://img.shields.io/npm/v/interface-record-store.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/interface-record-store/releases) | [![Deps](https://david-dm.org/libp2p/interface-record-store.svg?style=flat-square)](https://david-dm.org/libp2p/interface-record-store) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/interface-record-store/master)](https://ci.ipfs.team/job/libp2p/job/interface-record-store/job/master/) | [![codecov](https://codecov.io/gh/libp2p/interface-record-store/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/interface-record-store) |
| [`libp2p-record`](//github.com/libp2p/js-libp2p-record) | [![npm](https://img.shields.io/npm/v/libp2p-record.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-record/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-record.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-record) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-record/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-record/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-record/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-record) |
| **Generics** |
| [`libp2p-connection-manager`](//github.com/libp2p/js-libp2p-connection-manager) | [![npm](https://img.shields.io/npm/v/libp2p-connection-manager.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-connection-manager/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-connection-manager.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-connection-manager) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-connection-manager/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-connection-manager/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-connection-manager/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-connection-manager) |
| [`libp2p-crypto`](//github.com/libp2p/js-libp2p-crypto) | [![npm](https://img.shields.io/npm/v/libp2p-crypto.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-crypto/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-crypto.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-crypto) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-crypto/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-crypto/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-crypto/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-crypto) |
| [`libp2p-crypto-secp256k1`](//github.com/libp2p/js-libp2p-crypto-secp256k1) | [![npm](https://img.shields.io/npm/v/libp2p-crypto-secp256k1.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-crypto-secp256k1/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-crypto-secp256k1.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-crypto-secp256k1) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-crypto-secp256k1/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-crypto-secp256k1/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-crypto-secp256k1/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-crypto-secp256k1) |
| [`libp2p-switch`](//github.com/libp2p/js-libp2p-switch) | [![npm](https://img.shields.io/npm/v/libp2p-switch.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-switch/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-switch.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-switch) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-switch/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-switch/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-switch/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-switch) |
| **Extensions** |
| [`libp2p-floodsub`](//github.com/libp2p/js-libp2p-floodsub) | [![npm](https://img.shields.io/npm/v/libp2p-floodsub.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-floodsub/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-floodsub.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-floodsub) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-floodsub/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-floodsub/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-floodsub/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-floodsub) |
| [`libp2p-identify`](//github.com/libp2p/js-libp2p-identify) | [![npm](https://img.shields.io/npm/v/libp2p-identify.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-identify/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-identify.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-identify) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-identify/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-identify/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-identify/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-identify) |
| [`libp2p-keychain`](//github.com/libp2p/js-libp2p-keychain) | [![npm](https://img.shields.io/npm/v/libp2p-keychain.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-keychain/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-keychain.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-keychain) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-keychain/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-keychain/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-keychain/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-keychain) |
| [`libp2p-ping`](//github.com/libp2p/js-libp2p-ping) | [![npm](https://img.shields.io/npm/v/libp2p-ping.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-ping/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-ping.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-ping) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-ping/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-ping/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-ping/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-ping) |
| [`libp2p-pnet`](//github.com/libp2p/js-libp2p-pnet) | [![npm](https://img.shields.io/npm/v/libp2p-pnet.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-libp2p-pnet/releases) | [![Deps](https://david-dm.org/libp2p/js-libp2p-pnet.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-pnet) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-libp2p-pnet/master)](https://ci.ipfs.team/job/libp2p/job/js-libp2p-pnet/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-libp2p-pnet/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-libp2p-pnet) |
| **Utilities** |
| [`p2pcat`](//github.com/libp2p/js-p2pcat) | [![npm](https://img.shields.io/npm/v/p2pcat.svg?maxAge=86400&style=flat-square)](//github.com/libp2p/js-p2pcat/releases) | [![Deps](https://david-dm.org/libp2p/js-p2pcat.svg?style=flat-square)](https://david-dm.org/libp2p/js-p2pcat) | [![jenkins](https://ci.ipfs.team/buildStatus/icon?job=libp2p/js-p2pcat/master)](https://ci.ipfs.team/job/libp2p/job/js-p2pcat/job/master/) | [![codecov](https://codecov.io/gh/libp2p/js-p2pcat/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/js-p2pcat) |
## Contribute

41
RELEASE.md Normal file
View File

@ -0,0 +1,41 @@
# Release Template
> short tl;dr; of the release
# 🗺 What's left for release
# 🔦 Highlights
# 🏗 API Changes
# ✅ Release Checklist
- Robustness and quality
- [ ] Ensure that all tests are passing, this includes:
- [ ] unit
- [ ] Run tests of the following projects with the new release:
- [ ] [js-ipfs](https://github.com/ipfs/js-ipfs)
- Documentation
- [ ] Ensure that README.md is up to date
- [ ] Ensure that all the examples run
- Communication
- [ ] Create the release issue
- [ ] Announcements (both pre-release and post-release)
- [ ] Twitter
- [ ] IRC
- [ ] Reddit
- [ ] Blog post
# 🙌🏽 Want to contribute?
Would you like to contribute to the libp2p project and don't know how? Well, there are a few places you can get started:
- Check the issues with the `help wanted` label at the Ready column in our waffle board - https://waffle.io/libp2p/js-libp2p?label=help%20wanted
- Join an IPFS All Hands, introduce yourself and let us know where you would like to contribute - https://github.com/ipfs/pm/#all-hands-call
- Hack with IPFS and show us what you made! The All Hands call is also the perfect venue for demos, join in and show us what you built
- Join the discussion at http://discuss.ipfs.io/ and help users finding their answers.
- Join the [⚡️ⒿⓈ Core Dev Team Weekly Sync 🙌🏽 ](https://github.com/ipfs/pm/issues/650) and be part of the Sprint action!
# ⁉️ Do you have questions?
The best place to ask your questions about libp2p, how it works and what you can do with it is at [discuss.ipfs.io](http://discuss.ipfs.io). We are also available at the #libp2p channel on Freenode.

2
ci/Jenkinsfile vendored
View File

@ -1,2 +1,2 @@
// Warning: This file is automatically synced from https://github.com/ipfs/ci-sync so if you want to change it, please change it there and ask someone to sync all repositories.
javascript(['nodejs_versions': ['8.11.3']])
javascript()

View File

@ -1,6 +1,6 @@
{
"name": "libp2p",
"version": "0.21.0",
"version": "0.23.0",
"description": "JavaScript base class for libp2p bundles",
"leadMaintainer": "David Dias <daviddias@ipfs.io>",
"main": "src/index.js",
@ -33,35 +33,36 @@
},
"homepage": "https://github.com/libp2p/js-libp2p",
"browser": {
"joi": "joi-browser"
"joi": "joi-browser",
"./test/utils/bundle-nodejs": "./test/utils/bundle-browser"
},
"dependencies": {
"async": "^2.6.0",
"async": "^2.6.1",
"joi": "^13.4.0",
"joi-browser": "^13.4.0",
"libp2p-connection-manager": "~0.0.2",
"libp2p-floodsub": "~0.15.0",
"libp2p-ping": "~0.8.0",
"libp2p-switch": "~0.40.4",
"libp2p-switch": "~0.40.7",
"libp2p-websockets": "~0.12.0",
"mafmt": "^6.0.0",
"multiaddr": "^5.0.0",
"peer-book": "~0.8.0",
"peer-id": "~0.10.7",
"peer-id": "~0.11.0",
"peer-info": "~0.14.1"
},
"devDependencies": {
"@nodeutils/defaults-deep": "^1.1.0",
"aegir": "^14.0.0",
"aegir": "^15.1.0",
"chai": "^4.1.2",
"cids": "~0.5.3",
"dirty-chai": "^2.0.1",
"electron-webrtc": "~0.3.0",
"libp2p-circuit": "~0.2.0",
"libp2p-kad-dht": "~0.10.0",
"libp2p-kad-dht": "~0.10.1",
"libp2p-mdns": "~0.12.0",
"libp2p-mplex": "~0.8.0",
"libp2p-railing": "~0.9.1",
"libp2p-railing": "~0.9.2",
"libp2p-secio": "~0.10.0",
"libp2p-spdy": "~0.12.1",
"libp2p-tcp": "~0.12.0",
@ -72,10 +73,12 @@
"pull-goodbye": "0.0.2",
"pull-serializer": "~0.3.2",
"pull-stream": "^3.6.8",
"sinon": "^5.0.7",
"wrtc": "0.1.1"
"sinon": "^6.1.4",
"webrtcsupport": "^2.2.0",
"wrtc": "~0.1.6"
},
"contributors": [
"Alan Shaw <alan@tableflip.io>",
"Chris Bratlien <chrisbratlien@gmail.com>",
"Chris Dostert <chrisdostert@users.noreply.github.com>",
"Daijiro Wachi <daijiro.wachi@gmail.com>",
@ -88,6 +91,7 @@
"Giovanni T. Parra <fiatjaf@gmail.com>",
"Hugo Dias <hugomrdias@gmail.com>",
"Irakli Gozalishvili <rfobic@gmail.com>",
"Jacob Heun <jacobheun@gmail.com>",
"Joel Gustafson <joelg@mit.edu>",
"John Rees <johnrees@users.noreply.github.com>",
"João Santos <joaosantos15@users.noreply.github.com>",

View File

@ -0,0 +1,146 @@
#! /usr/bin/env node
'use strict'
// This script generates the table of packages you can see in the readme
// Columns to show at the header of the table
const columns = [
'Package',
'Version',
'Deps',
'CI',
'Coverage'
]
// Headings are a string
// Arrays are packages. Index 0 is the GitHub repo and index 1 is the npm package
const rows = [
'Libp2p',
['libp2p/interface-libp2p', 'interface-libp2p'],
['libp2p/js-libp2p', 'libp2p'],
'Connection',
['libp2p/interface-connection', 'interface-connection'],
'Transport',
['libp2p/interface-transport', 'interface-transport'],
['libp2p/js-libp2p-circuit', 'libp2p-circuit'], // should this be NAT Traversal only?
['libp2p/js-libp2p-tcp', 'libp2p-tcp'],
['libp2p/js-libp2p-udp', 'libp2p-udp'],
['libp2p/js-libp2p-udt', 'libp2p-udt'],
['libp2p/js-libp2p-utp', 'libp2p-utp'],
['libp2p/js-libp2p-webrtc-direct', 'libp2p-webrtc-direct'],
['libp2p/js-libp2p-webrtc-star', 'libp2p-webrtc-star'],
['libp2p/js-libp2p-websockets', 'libp2p-websockets'],
['libp2p/js-libp2p-websocket-star', 'libp2p-websocket-star'],
['libp2p/js-libp2p-websocket-star-rendezvous', 'libp2p-websocket-star-rendezvous'],
'Crypto Channels',
['libp2p/js-libp2p-secio', 'libp2p-secio'],
'Stream Muxers',
['libp2p/interface-stream-muxer', 'interface-stream-muxer'],
['libp2p/js-libp2p-mplex', 'libp2p-mplex'],
['libp2p/js-libp2p-spdy', 'libp2p-spdy'],
'Discovery',
['libp2p/interface-peer-discovery', 'interface-peer-discovery'],
['libp2p/js-libp2p-bootstrap', 'libp2p-bootstrap'],
['libp2p/js-libp2p-kad-dht', 'libp2p-kad-dht'], // should this be here?
['libp2p/js-libp2p-mdns', 'libp2p-mdns'],
['libp2p/js-libp2p-rendezvous', 'libp2p-rendezvous'],
['libp2p/js-libp2p-webrtc-star', 'libp2p-webrtc-star'],
['libp2p/js-libp2p-websocket-star', 'libp2p-websocket-star'],
'NAT Traversal',
['libp2p/js-libp2p-circuit', 'libp2p-circuit'],
['libp2p/js-libp2p-nat-mngr', 'libp2p-nat-mngr'],
'Data Types',
['libp2p/js-peer-book', 'peer-book'],
['libp2p/js-peer-id', 'peer-id'],
['libp2p/js-peer-info', 'peer-info'],
'Content Routing',
['libp2p/interface-content-routing', 'interface-content-routing'],
['libp2p/js-libp2p-delegated-content-routing', 'libp2p-delegated-content-routing'],
['libp2p/js-libp2p-kad-dht', 'libp2p-kad-dht'],
'Peer Routing',
['libp2p/interface-peer-routing', 'interface-peer-routing'],
['libp2p/js-libp2p-delegated-peer-routing', 'libp2p-delegated-peer-routing'],
['libp2p/js-libp2p-kad-dht', 'libp2p-kad-dht'],
'Record Store',
['libp2p/interface-record-store', 'interface-record-store'],
['libp2p/js-libp2p-record', 'libp2p-record'],
'Generics',
['libp2p/js-libp2p-connection-manager', 'libp2p-connection-manager'],
['libp2p/js-libp2p-crypto', 'libp2p-crypto'],
['libp2p/js-libp2p-crypto-secp256k1', 'libp2p-crypto-secp256k1'],
['libp2p/js-libp2p-switch', 'libp2p-switch'],
'Extensions',
['libp2p/js-libp2p-floodsub', 'libp2p-floodsub'],
['libp2p/js-libp2p-identify', 'libp2p-identify'],
['libp2p/js-libp2p-keychain', 'libp2p-keychain'],
['libp2p/js-libp2p-ping', 'libp2p-ping'],
['libp2p/js-libp2p-pnet', 'libp2p-pnet'],
'Utilities',
['libp2p/js-p2pcat', 'p2pcat']
]
const isItemPackage = (item) => {
return Array.isArray(item)
}
const packageBadges = [
// Package
(gh, npm) => `[\`${npm}\`](//github.com/${gh})`,
// Version
(gh, npm) => `[![npm](https://img.shields.io/npm/v/${npm}.svg?maxAge=86400&style=flat-square)](//github.com/${gh}/releases)`,
// Deps
(gh, npm) => `[![Deps](https://david-dm.org/${gh}.svg?style=flat-square)](https://david-dm.org/${gh})`,
// CI
(gh, npm) => {
// Need to fix the path for jenkins links, as jenkins adds `/job/` between everything
const jenkinsPath = gh.split('/').join('/job/')
return `[![jenkins](https://ci.ipfs.team/buildStatus/icon?job=${gh}/master)](https://ci.ipfs.team/job/${jenkinsPath}/job/master/)`
},
// Coverage
(gh, npm) => `[![codecov](https://codecov.io/gh/${gh}/branch/master/graph/badge.svg)](https://codecov.io/gh/${gh})`
]
// Creates the table row for a package
const generatePackageRow = (item) => {
const row = packageBadges.map((func) => {
// First string is GitHub path, second is npm package name
return func(item[0], item[1])
}).join(' | ')
const fullRow = `| ${row} |`
return fullRow
}
// Generates a row for the table, depending if it's a package or a heading
const generateRow = (item) => {
if (isItemPackage(item)) {
return generatePackageRow(item)
} else {
return `| **${item}** |`
}
}
const header = `| ${columns.join(' | ')} |`
const hr = `| ${columns.map(() => '---------').join('|')} |`
const toPrint = [
header,
hr,
rows.map((row) => generateRow(row)).join('\n')
]
toPrint.forEach((t) => console.log(t))

View File

@ -2,40 +2,22 @@
const Joi = require('joi')
const schema = Joi.object({
const ModuleSchema = Joi.alternatives().try(Joi.func(), Joi.object())
const OptionsSchema = Joi.object({
// TODO: create proper validators for the generics
connectionManager: Joi.object(),
peerInfo: Joi.object().required(),
peerBook: Joi.object(),
modules: Joi.object().keys({
transport: Joi.array().items(
Joi.alternatives().try(
Joi.func(),
Joi.object()
)
).min(1).required(),
streamMuxer: Joi.array().items(
Joi.alternatives().try(
Joi.func(),
Joi.object()
)
).allow(null),
connEncryption: Joi.array().items(
Joi.alternatives().try(
Joi.func(),
Joi.object()
)
).allow(null),
peerDiscovery: Joi.array().items(
Joi.alternatives().try(
Joi.func(),
Joi.object()
)
).allow(null),
dht: Joi.alternatives().try(
Joi.func(),
Joi.object()
).allow(null)
transport: Joi.array().items(ModuleSchema).min(1).required(),
streamMuxer: Joi.array().items(ModuleSchema).allow(null),
connEncryption: Joi.array().items(ModuleSchema).allow(null),
connProtector: Joi.object().keys({
protect: Joi.func().required()
}).unknown(),
peerDiscovery: Joi.array().items(ModuleSchema).allow(null),
dht: ModuleSchema.allow(null)
}).required(),
config: Joi.object().keys({
peerDiscovery: Joi.object().allow(null),
@ -57,27 +39,12 @@ const schema = Joi.object({
})
module.exports.validate = (options) => {
let newSchema = schema
// Throw an intial error early for required props
let config = Joi.attempt(options, newSchema)
// Ensure discoveries are properly configured
if (config.modules.peerDiscovery) {
config.modules.peerDiscovery.forEach((discovery) => {
// If it's a function, validate we have configs for it
if (typeof discovery === 'function') {
Joi.reach(schema, 'config.peerDiscovery').keys({
[discovery.tag]: Joi.object().required()
})
}
})
}
options = Joi.attempt(options, OptionsSchema)
// Ensure dht is correct
if (config.config.EXPERIMENTAL && config.config.EXPERIMENTAL.dht) {
newSchema = newSchema.requiredKeys('modules.dht')
if (options.config.EXPERIMENTAL.dht) {
Joi.assert(options.modules.dht, ModuleSchema.required())
}
// Finish validation and return the updated config
return Joi.attempt(config, newSchema)
return options
}

View File

@ -75,6 +75,13 @@ class Node extends EventEmitter {
})
}
// Attach private network protector
if (this._modules.connProtector) {
this._switch.protector = this._modules.connProtector
} else if (process.env.LIBP2P_FORCE_PNET) {
throw new Error('Private network is enforced, but no protector was provided')
}
// dht provided components (peerRouting, contentRouting, dht)
if (this._config.EXPERIMENTAL.dht) {
const DHT = this._modules.dht
@ -87,7 +94,7 @@ class Node extends EventEmitter {
}
// enable/disable pubsub
if (this._config.EXPERIMENTAL && this._config.EXPERIMENTAL.pubsub) {
if (this._config.EXPERIMENTAL.pubsub) {
this.pubsub = pubsub(this)
}
@ -146,7 +153,10 @@ class Node extends EventEmitter {
})
series([
(cb) => this._switch.start(cb),
(cb) => {
this.connectionManager.start()
this._switch.start(cb)
},
(cb) => {
if (ws) {
// always add dialing on websockets
@ -154,15 +164,25 @@ class Node extends EventEmitter {
}
// all transports need to be setup before discover starts
if (this._modules.peerDiscovery && this._config.peerDiscovery) {
if (this._modules.peerDiscovery) {
each(this._modules.peerDiscovery, (D, _cb) => {
let config = {}
if (D.tag &&
this._config.peerDiscovery &&
this._config.peerDiscovery[D.tag]) {
config = this._config.peerDiscovery[D.tag]
}
// If not configured to be enabled/disabled then enable by default
const enabled = config.enabled == null ? true : config.enabled
// If enabled then start it
if (this._config.peerDiscovery[D.tag].enabled) {
if (enabled) {
let d
if (typeof D === 'function') {
this._config.peerDiscovery[D.tag].peerInfo = this.peerInfo
d = new D(this._config.peerDiscovery[D.tag])
d = new D(Object.assign({}, config, { peerInfo: this.peerInfo }))
} else {
d = D
}
@ -246,7 +266,10 @@ class Node extends EventEmitter {
}
cb()
},
(cb) => this._switch.stop(cb),
(cb) => {
this.connectionManager.stop()
this._switch.stop(cb)
},
(cb) => {
this.emit('stop')
cb()

View File

@ -113,21 +113,4 @@ describe('configuration', () => {
expect(() => validateConfig(options)).to.throw()
})
it('should require a non instanced peerDiscovery module to have associated options', () => {
const options = {
peerInfo,
modules: {
transport: [ WS ],
peerDiscover: [ Bootstrap ]
},
config: {
EXPERIMENTAL: {
dht: true
}
}
}
expect(() => validateConfig(options)).to.throw()
})
})

79
test/create.spec.js Normal file
View File

@ -0,0 +1,79 @@
/* eslint-env mocha */
'use strict'
const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const series = require('async/series')
const createNode = require('./utils/create-node')
const sinon = require('sinon')
describe('libp2p creation', () => {
it('should be able to start and stop successfully', (done) => {
createNode([], {
config: {
EXPERIMENTAL: {
dht: true,
pubsub: true
}
}
}, (err, node) => {
expect(err).to.not.exist()
let sw = node._switch
let cm = node.connectionManager
let dht = node._dht
let pub = node._floodSub
sinon.spy(sw, 'start')
sinon.spy(cm, 'start')
sinon.spy(dht, 'start')
sinon.spy(pub, 'start')
sinon.spy(sw, 'stop')
sinon.spy(cm, 'stop')
sinon.spy(dht, 'stop')
sinon.spy(pub, 'stop')
sinon.spy(node, 'emit')
series([
(cb) => node.start(cb),
(cb) => {
expect(sw.start.calledOnce).to.equal(true)
expect(cm.start.calledOnce).to.equal(true)
expect(dht.start.calledOnce).to.equal(true)
expect(pub.start.calledOnce).to.equal(true)
expect(node.emit.calledWith('start')).to.equal(true)
cb()
},
(cb) => node.stop(cb)
], (err) => {
expect(err).to.not.exist()
expect(sw.stop.calledOnce).to.equal(true)
expect(cm.stop.calledOnce).to.equal(true)
expect(dht.stop.calledOnce).to.equal(true)
expect(pub.stop.calledOnce).to.equal(true)
expect(node.emit.calledWith('stop')).to.equal(true)
done()
})
})
})
it('should not create disabled modules', (done) => {
createNode([], {
config: {
EXPERIMENTAL: {
dht: false,
pubsub: false
}
}
}, (err, node) => {
expect(err).to.not.exist()
expect(node._dht).to.not.exist()
expect(node._floodSub).to.not.exist()
done()
})
})
})

View File

@ -1,5 +1,6 @@
'use strict'
require('./pnet.node')
require('./transports.node')
require('./stream-muxing.node')
require('./peer-discovery.node')

View File

@ -4,8 +4,10 @@
const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const sinon = require('sinon')
const signalling = require('libp2p-webrtc-star/src/sig-server')
const parallel = require('async/parallel')
const crypto = require('crypto')
const createNode = require('./utils/create-node')
const echo = require('./utils/echo')
@ -57,12 +59,193 @@ describe('peer discovery', () => {
})
}
describe('module registration', () => {
it('should enable by default a module passed as an object', (done) => {
const mockDiscovery = {
on: sinon.stub(),
start: sinon.stub().callsArg(0),
stop: sinon.stub().callsArg(0)
}
const options = { modules: { peerDiscovery: [ mockDiscovery ] } }
createNode(['/ip4/0.0.0.0/tcp/0'], options, (err, node) => {
expect(err).to.not.exist()
node.start((err) => {
expect(err).to.not.exist()
expect(mockDiscovery.start.called).to.be.true()
node.stop(done)
})
})
})
it('should enable by default a module passed as a function', (done) => {
const mockDiscovery = {
on: sinon.stub(),
start: sinon.stub().callsArg(0),
stop: sinon.stub().callsArg(0)
}
const MockDiscovery = sinon.stub().returns(mockDiscovery)
const options = { modules: { peerDiscovery: [ MockDiscovery ] } }
createNode(['/ip4/0.0.0.0/tcp/0'], options, (err, node) => {
expect(err).to.not.exist()
node.start((err) => {
expect(err).to.not.exist()
expect(mockDiscovery.start.called).to.be.true()
node.stop(done)
})
})
})
it('should enable module by configutation', (done) => {
const mockDiscovery = {
on: sinon.stub(),
start: sinon.stub().callsArg(0),
stop: sinon.stub().callsArg(0),
tag: 'mockDiscovery'
}
const enabled = sinon.stub().returns(true)
const options = {
modules: { peerDiscovery: [ mockDiscovery ] },
config: {
peerDiscovery: {
mockDiscovery: {
get enabled () {
return enabled()
}
}
}
}
}
createNode(['/ip4/0.0.0.0/tcp/0'], options, (err, node) => {
expect(err).to.not.exist()
node.start((err) => {
expect(err).to.not.exist()
expect(mockDiscovery.start.called).to.be.true()
expect(enabled.called).to.be.true()
node.stop(done)
})
})
})
it('should disable module by configutation', (done) => {
const mockDiscovery = {
on: sinon.stub(),
start: sinon.stub().callsArg(0),
stop: sinon.stub().callsArg(0),
tag: 'mockDiscovery'
}
const disabled = sinon.stub().returns(false)
const options = {
modules: { peerDiscovery: [ mockDiscovery ] },
config: {
peerDiscovery: {
mockDiscovery: {
get enabled () {
return disabled()
}
}
}
}
}
createNode(['/ip4/0.0.0.0/tcp/0'], options, (err, node) => {
expect(err).to.not.exist()
node.start((err) => {
expect(err).to.not.exist()
expect(mockDiscovery.start.called).to.be.false()
expect(disabled.called).to.be.true()
node.stop(done)
})
})
})
it('should register module passed as function', (done) => {
const mockDiscovery = {
on: sinon.stub(),
start: sinon.stub().callsArg(0),
stop: sinon.stub().callsArg(0)
}
const MockDiscovery = sinon.stub().returns(mockDiscovery)
MockDiscovery.tag = 'mockDiscovery'
const options = {
modules: { peerDiscovery: [ MockDiscovery ] },
config: {
peerDiscovery: {
mockDiscovery: {
enabled: true,
time: Date.now()
}
}
}
}
createNode(['/ip4/0.0.0.0/tcp/0'], options, (err, node) => {
expect(err).to.not.exist()
node.start((err) => {
expect(err).to.not.exist()
expect(mockDiscovery.start.called).to.be.true()
expect(MockDiscovery.called).to.be.true()
// Ensure configuration was passed
expect(MockDiscovery.firstCall.args[0])
.to.deep.include(options.config.peerDiscovery.mockDiscovery)
node.stop(done)
})
})
})
it('should register module passed as object', (done) => {
const mockDiscovery = {
on: sinon.stub(),
start: sinon.stub().callsArg(0),
stop: sinon.stub().callsArg(0),
tag: 'mockDiscovery'
}
const options = {
modules: { peerDiscovery: [ mockDiscovery ] },
config: {
peerDiscovery: {
mockDiscovery: { enabled: true }
}
}
}
createNode(['/ip4/0.0.0.0/tcp/0'], options, (err, node) => {
expect(err).to.not.exist()
node.start((err) => {
expect(err).to.not.exist()
expect(mockDiscovery.start.called).to.be.true()
node.stop(done)
})
})
})
})
describe('MulticastDNS', () => {
setup({
config: {
peerDiscovery: {
mdns: {
enabled: true
enabled: true,
// use a random tag to prevent CI collision
serviceTag: crypto.randomBytes(10).toString('hex')
}
}
}
@ -81,7 +264,15 @@ describe('peer discovery', () => {
// TODO needs a delay (this test is already long)
describe.skip('WebRTCStar', () => {
setup({ webRTCStar: true })
setup({
config: {
peerDiscovery: {
webRTCStar: {
enabled: true
}
}
}
})
it('find a peer', function (done) {
this.timeout(15 * 1000)
@ -98,7 +289,9 @@ describe('peer discovery', () => {
config: {
peerDiscovery: {
mdns: {
enabled: true
enabled: true,
// use a random tag to prevent CI collision
serviceTag: crypto.randomBytes(10).toString('hex')
},
webRTCStar: {
enabled: true

90
test/pnet.node.js Normal file
View File

@ -0,0 +1,90 @@
/* eslint-env mocha */
'use strict'
const chai = require('chai')
chai.use(require('dirty-chai'))
const expect = chai.expect
const PeerInfo = require('peer-info')
const PeerId = require('peer-id')
const waterfall = require('async/waterfall')
const WS = require('libp2p-websockets')
const defaultsDeep = require('@nodeutils/defaults-deep')
const Libp2p = require('../src')
describe('private network', () => {
let config
before((done) => {
waterfall([
(cb) => PeerId.create({ bits: 512 }, cb),
(peerId, cb) => PeerInfo.create(peerId, cb),
(peerInfo, cb) => {
config = {
peerInfo,
modules: {
transport: [ WS ]
}
}
cb()
}
], () => done())
})
describe('enforced network protection', () => {
before(() => {
process.env.LIBP2P_FORCE_PNET = 1
})
after(() => {
delete process.env.LIBP2P_FORCE_PNET
})
it('should throw an error without a provided protector', () => {
expect(() => {
return new Libp2p(config)
}).to.throw('Private network is enforced, but no protector was provided')
})
it('should create a libp2p node with a provided protector', () => {
let node
let protector = {
psk: '123',
tag: '/psk/1.0.0',
protect: () => { }
}
expect(() => {
let options = defaultsDeep(config, {
modules: {
connProtector: protector
}
})
node = new Libp2p(options)
return node
}).to.not.throw()
expect(node._switch.protector).to.deep.equal(protector)
})
it('should throw an error if the protector does not have a protect method', () => {
expect(() => {
let options = defaultsDeep(config, {
modules: {
connProtector: { }
}
})
return new Libp2p(options)
}).to.throw()
})
})
describe('network protection not enforced', () => {
it('should not throw an error with no provided protector', () => {
expect(() => {
return new Libp2p(config)
}).to.not.throw()
})
})
})

View File

@ -78,6 +78,9 @@ class Node extends libp2p {
active: false
}
},
dht: {
kBucketSize: 20
},
EXPERIMENTAL: {
dht: false,
pubsub: false