From ca474fd66a9a057e065bc3a8e3bc3377a8621dcf Mon Sep 17 00:00:00 2001 From: Vasco Santos Date: Tue, 10 Dec 2019 15:23:04 +0100 Subject: [PATCH] docs: new api (#472) * docs: new api * chore: new iteration * chore: apply suggestions from code review Co-Authored-By: Alan Shaw * chore: apply suggestions from code review Co-Authored-By: Jacob Heun * chore: address review * docs: add events * chore: apply suggestions from code review Co-Authored-By: Jacob Heun --- README.md | 317 +-------------------------- doc/API.md | 611 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 612 insertions(+), 316 deletions(-) create mode 100644 doc/API.md diff --git a/README.md b/README.md index e28f2dfd47..6e78b29931 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,6 @@ We've come a long way, but this project is still in Alpha, lots of development i - [Install](#install) - [Usage](#usage) - [API](#api) - - [Events](#events) - [Development](#development) - [Tests](#tests) - [Packages](#packages) @@ -209,321 +208,7 @@ class Node extends Libp2p { ### API -**IMPORTANT NOTE**: All the methods listed in the API section that take a callback are also now Promisified. Libp2p is migrating away from callbacks to async/await, and in a future release (that will be announced in advance), callback support will be removed entirely. You can follow progress of the async/await endeavor at https://github.com/ipfs/js-ipfs/issues/1670. - -#### Create a Node - `Libp2p.create(options)` - -> Behaves exactly like `new Libp2p(options)`, but doesn't require a PeerInfo. One will be generated instead - -```js -const { create } = require('libp2p') -const libp2p = await create(options) - -await libp2p.start() -``` - -- `options`: Object of libp2p configuration options - -#### Create a Node alternative - `new Libp2p(options)` - -> Creates an instance of Libp2p with a custom `PeerInfo` provided via `options.peerInfo`. - -Required keys in the `options` object: - -- `peerInfo`: instance of [PeerInfo][] that contains the [PeerId][], Keys and [multiaddrs][multiaddr] of the libp2p Node. -- `modules.transport`: An array that must include at least 1 transport, such as `libp2p-tcp`. - -#### `libp2p.start(callback)` - -> Start the libp2p Node. - -`callback` following signature `function (err) {}`, where `err` is an Error in case starting the node fails. - -#### `libp2p.stop(callback)` - -> Stop the libp2p Node. - -`callback` following signature `function (err) {}`, where `err` is an Error in case stopping the node fails. - -#### `libp2p.dial(peer, callback)` - -> Dials to another peer in the network, establishes the connection. - -- `peer`: can be an instance of [PeerInfo][], [PeerId][], [multiaddr][], or a multiaddr string -- `callback` following signature `function (err, conn) {}`, where `err` is an Error in of failure to dial the connection and `conn` is a [Connection][] instance in case of a protocol selected, if not it is undefined. - -#### `libp2p.dialProtocol(peer, protocol, callback)` - -> Dials to another peer in the network and selects a protocol to talk with that peer. - -- `peer`: can be an instance of [PeerInfo][], [PeerId][], [multiaddr][], or a multiaddr string -- `protocol`: String that defines the protocol (e.g '/ipfs/bitswap/1.1.0') -- `callback`: Function with signature `function (err, conn) {}`, where `conn` is a [Connection](https://github.com/libp2p/interface-connection) object - -`callback` following signature `function (err, conn) {}`, where `err` is an Error in of failure to dial the connection and `conn` is a [Connection][] instance in case of a protocol selected, if not it is undefined. - -#### `libp2p.dialFSM(peer, protocol, callback)` - -> Behaves like `.dial` and `.dialProtocol` but calls back with a Connection State Machine - -- `peer`: can be an instance of [PeerInfo][], [PeerId][], [multiaddr][], or a multiaddr string -- `protocol`: an optional String that defines the protocol (e.g '/ipfs/bitswap/1.1.0') -- `callback`: following signature `function (err, connFSM) {}`, where `connFSM` is a [Connection State Machine](https://github.com/libp2p/js-libp2p-switch#connection-state-machine) - -#### `libp2p.hangUp(peer, callback)` - -> Closes an open connection with a peer, graciously. - -- `peer`: can be an instance of [PeerInfo][], [PeerId][] or [multiaddr][] - -`callback` following signature `function (err) {}`, where `err` is an Error in case stopping the node fails. - -#### `libp2p.peerRouting.findPeer(id, options, callback)` - -> Looks up for multiaddrs of a peer in the DHT - -- `id`: instance of [PeerId][] -- `options`: object of options -- `options.maxTimeout`: Number milliseconds - -#### `libp2p.contentRouting.findProviders(key, options, callback)` - -- `key`: Buffer -- `options`: object of options -- `options.maxTimeout`: Number milliseconds -- `options.maxNumProviders` maximum number of providers to find - -#### `libp2p.contentRouting.provide(key, callback)` - -- `key`: Buffer - -#### `libp2p.handle(protocol, handlerFunc [, matchFunc])` - -> Handle new protocol - -- `protocol`: String that defines the protocol (e.g '/ipfs/bitswap/1.1.0') -- `handlerFunc`: following signature `function (protocol, conn) {}`, where `conn` is a [Connection](https://github.com/libp2p/interface-connection) object -- `matchFunc`: Function for matching on protocol (exact matching, semver, etc). Default to exact match. - -#### `libp2p.unhandle(protocol)` - -> Stop handling protocol - -- `protocol`: String that defines the protocol (e.g '/ipfs/bitswap/1.1.0') - -#### Events - -##### `libp2p.on('start', () => {})` - -> Libp2p has started, along with all its services. - -##### `libp2p.on('stop', () => {})` - -> Libp2p has stopped, along with all its services. - -##### `libp2p.on('error', (err) => {})` - -> An error has occurred - -- `err`: instance of `Error` - -##### `libp2p.on('peer:discovery', (peer) => {})` - -> Peer has been discovered. - -If `autoDial` is `true`, applications should **not** attempt to connect to the peer -unless they are performing a specific action. See [peer discovery and auto dial](./doc/PEER_DISCOVERY.md) for more information. - -- `peer`: instance of [PeerInfo][] - -##### `libp2p.on('peer:connect', (peer) => {})` - -> We have a new muxed connection to a peer - -- `peer`: instance of [PeerInfo][] - -##### `libp2p.on('peer:disconnect', (peer) => {})` - -> We have closed a connection to a peer - -- `peer`: instance of [PeerInfo][] - -##### `libp2p.on('connection:start', (peer) => {})` - -> We created a new connection to a peer - -- `peer`: instance of [PeerInfo][] - -##### `libp2p.on('connection:end', (peer) => {})` - -> We closed a connection to a peer - -- `peer`: instance of [PeerInfo][] - -#### `libp2p.isStarted()` - -> Check if libp2p is started - -#### `libp2p.ping(peer [, options], callback)` - -> Ping a node in the network - -#### `libp2p.peerBook` - -> PeerBook instance of the node - -#### `libp2p.peerInfo` - -> PeerInfo instance of the node - -#### `libp2p.pubsub` - -> Same API as IPFS PubSub, defined in the [CORE API Spec](https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/PUBSUB.md). Just replace `ipfs` by `libp2p` and you are golden. - ---------------------- - -`DHT methods also exposed for the time being` - -#### `libp2p.dht.put(key, value, callback)` - -- `key`: Buffer -- `value`: Buffer - -#### `libp2p.dht.get(key, options, callback)` - -- `key`: Buffer -- `options`: object of options -- `options.maxTimeout`: Number milliseconds - -#### `libp2p.dht.getMany(key, nVals, options, callback)` - -- `key`: Buffer -- `nVals`: Number -- `options`: object of options -- `options.maxTimeout`: Number milliseconds - -[PeerInfo]: https://github.com/libp2p/js-peer-info -[PeerId]: https://github.com/libp2p/js-peer-id -[PeerBook]: https://github.com/libp2p/js-peer-book -[multiaddr]: https://github.com/multiformats/js-multiaddr -[Connection]: https://github.com/libp2p/interface-connection - -------- - -### Switch Stats API - -##### `libp2p.stats.emit('update')` - -Every time any stat value changes, this object emits an `update` event. - -#### Global stats - -##### `libp2p.stats.global.snapshot` - -Should return a stats snapshot, which is an object containing the following keys and respective values: - -- dataSent: amount of bytes sent, [Big](https://github.com/MikeMcl/big.js#readme) number -- dataReceived: amount of bytes received, [Big](https://github.com/MikeMcl/big.js#readme) number - -##### `libp2p.stats.global.movingAverages` - -Returns an object containing the following keys: - -- dataSent -- dataReceived - -Each one of them contains an object that has a key for each interval (`60000`, `300000` and `900000` milliseconds). - -Each one of these values is [an exponential moving-average instance](https://github.com/pgte/moving-average#readme). - -#### Per-transport stats - -##### `libp2p.stats.transports()` - -Returns an array containing the tags (string) for each observed transport. - -##### `libp2p.stats.forTransport(transportTag).snapshot` - -Should return a stats snapshot, which is an object containing the following keys and respective values: - -- dataSent: amount of bytes sent, [Big](https://github.com/MikeMcl/big.js#readme) number -- dataReceived: amount of bytes received, [Big](https://github.com/MikeMcl/big.js#readme) number - -##### `libp2p.stats.forTransport(transportTag).movingAverages` - -Returns an object containing the following keys: - - dataSent - dataReceived - -Each one of them contains an object that has a key for each interval (`60000`, `300000` and `900000` milliseconds). - -Each one of these values is [an exponential moving-average instance](https://github.com/pgte/moving-average#readme). - -#### Per-protocol stats - -##### `libp2p.stats.protocols()` - -Returns an array containing the tags (string) for each observed protocol. - -##### `libp2p.stats.forProtocol(protocolTag).snapshot` - -Should return a stats snapshot, which is an object containing the following keys and respective values: - -- dataSent: amount of bytes sent, [Big](https://github.com/MikeMcl/big.js#readme) number -- dataReceived: amount of bytes received, [Big](https://github.com/MikeMcl/big.js#readme) number - - -##### `libp2p.stats.forProtocol(protocolTag).movingAverages` - -Returns an object containing the following keys: - -- dataSent -- dataReceived - -Each one of them contains an object that has a key for each interval (`60000`, `300000` and `900000` milliseconds). - -Each one of these values is [an exponential moving-average instance](https://github.com/pgte/moving-average#readme). - -#### Per-peer stats - -##### `libp2p.stats.peers()` - -Returns an array containing the peerIDs (B58-encoded string) for each observed peer. - -##### `libp2p.stats.forPeer(peerId:String).snapshot` - -Should return a stats snapshot, which is an object containing the following keys and respective values: - -- dataSent: amount of bytes sent, [Big](https://github.com/MikeMcl/big.js#readme) number -- dataReceived: amount of bytes received, [Big](https://github.com/MikeMcl/big.js#readme) number - - -##### `libp2p.stats.forPeer(peerId:String).movingAverages` - -Returns an object containing the following keys: - -- dataSent -- dataReceived - -Each one of them contains an object that has a key for each interval (`60000`, `300000` and `900000` milliseconds). - -Each one of these values is [an exponential moving-average instance](https://github.com/pgte/moving-average#readme). - -#### Stats update interval - -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 milliseconds. - -### 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/tree/master/src/pnet) +See [API.md](./doc/API.md). ## Development diff --git a/doc/API.md b/doc/API.md new file mode 100644 index 0000000000..38886c69bc --- /dev/null +++ b/doc/API.md @@ -0,0 +1,611 @@ +# API + +* [Static Functions](#static-functions) + * [`create`](#create) +* [Instance Methods](#instance-methods) + * [`start`](#start) + * [`stop`](#stop) + * [`dial`](#dial) + * [`dialProtocol`](#dialProtocol) + * [`hangUp`](#hangUp) + * [`handle`](#handle) + * [`unhandle`](#unhandle) + * [`peerRouting.findPeer`](#peerRouting.findPeer) + * [`contentRouting.findProviders`](#contentRouting.findProviders) + * [`contentRouting.provide`](#contentRouting.provide) + * [`contentRouting.put`](#contentRouting.put) + * [`contentRouting.get`](#contentRouting.get) + * [`contentRouting.getMany`](#contentRouting.getMany) + * [`pubsub.getSubscribers`](#pubsub.getSubscribers) + * [`pubsub.getTopics`](#pubsub.getTopics) + * [`pubsub.publish`](#pubsub.publish) + * [`pubsub.subscribe`](#pubsub.subscribe) + +## Static Functions + +### create + +Creates an instance of Libp2p. + +`create(options)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| options | `Object` | libp2p options | +| options.modules | `Array` | libp2p modules to use | +| [options.config] | `Object` | libp2p modules configuration and core configuration | +| [options.datastore] | `Object` | must implement [ipfs/interface-datastore](https://github.com/ipfs/interface-datastore) (in memory datastore will be used if not provided) | +| [options.peerInfo] | [PeerInfo](https://github.com/libp2p/js-peer-info) | peerInfo instance (it will be created if not provided) | + +For Libp2p configurations and modules details read the [Configuration Document](./CONFIGURATION.md). + +#### Returns + +| Type | Description | +|------|-------------| +| `Promise` | Promise resolves with the Libp2p instance | + +#### Example + +```js +const Libp2p = require('libp2p') + +// specify options +const options = {} + +// create libp2p +const libp2p = await Libp2p.create(options) +``` + +Note: The `PeerInfo` option is not required and will be generated if it is not provided. + +
Alternative +As an alternative, it is possible to create a Libp2p instance with the constructor: + +#### Example + +```js +const Libp2p = require('libp2p') + +// specify options +const options = {} + +// create libp2p +const libp2p = new Libp2p(options) +``` + +Required keys in the `options` object: + +- `peerInfo`: instance of [PeerInfo][] that contains the [PeerId][], Keys and [multiaddrs][multiaddr] of the libp2p Node (optional when using `.create`). +- `modules.transport`: An array that must include at least 1 compliant transport. See [modules that implement the transport interface](https://github.com/libp2p/js-interfaces/tree/master/src/transport#modules-that-implement-the-interface). + +
+ +Once you have a libp2p instance, you are able to listen to several events it emmits, so that you can be noticed of relevant network events. + +
Events + +#### An error has occurred + +`libp2p.on('error', (err) => {})` + +- `err`: instance of `Error` + +#### A peer has been discovered + +`libp2p.on('peer:discovery', (peer) => {})` + +If `autoDial` option is `true`, applications should **not** attempt to connect to the peer +unless they are performing a specific action. See [peer discovery and auto dial](./PEER_DISCOVERY.md) for more information. + +- `peer`: instance of [PeerInfo][https://github.com/libp2p/js-peer-info] + +#### We have a new connection to a peer + +`libp2p.on('peer:connect', (peer) => {})` + +- `peer`: instance of [PeerInfo][https://github.com/libp2p/js-peer-info] + +#### We have closed a connection to a peer + +`libp2p.on('peer:disconnect', (peer) => {})` + +- `peer`: instance of [PeerInfo][https://github.com/libp2p/js-peer-info] + +
+ +## Libp2p Instance Methods + +### start + +Starts the libp2p node. + +`libp2p.start()` + +#### Returns + +| Type | Description | +|------|-------------| +| `Promise` | Promise resolves when the node is ready | + +#### Example + +```js +const Libp2p = require('libp2p') + +// ... + +const libp2p = await Libp2p.create(options) + +// start libp2p +await libp2p.start() +``` + +### stop + +Stops the libp2p node. + +`libp2p.stop()` + +#### Returns + +| Type | Description | +|------|-------------| +| `Promise` | Promise resolves when the node is fully stopped | + +#### Example + +```js +const Libp2p = require('libp2p') + +// ... +const libp2p = await Libp2p.create(options) +// ... + +// stop libp2p +await libp2p.stop() +``` + +### dial + +Dials to another peer in the network and establishes the connection. + +`dial(peer, options)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| peer | [PeerInfo](https://github.com/libp2p/js-peer-info), [PeerId](https://github.com/libp2p/js-peer-id), [multiaddr](https://github.com/multiformats/js-multiaddr), `string` | peer to dial | +| [options] | `Object` | dial options | +| [options.signal] | [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) | An `AbortSignal` instance obtained from an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) that can be used to abort the connection before it completes | + +#### Returns + +| Type | Description | +|------|-------------| +| `Promise` | Promise resolves with the [Connection](https://github.com/libp2p/js-interfaces/tree/master/src/connection) instance | + +#### Example + +```js +// ... +const conn = await libp2p.dial(remotePeerInfo) + +// create a new stream within the connection +const { stream, protocol } = await conn.newStream(['/echo/1.1.0', '/echo/1.0.0']) + +// protocol negotiated: 'echo/1.0.0' means that the other party only supports the older version + +// ... +await conn.close() +``` + +### dialProtocol + +Dials to another peer in the network and selects a protocol to communicate with that peer. The stream between both parties is returned, together with the negotiated protocol. + +`dialProtocol(peer, protocols, options)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| peer | [PeerInfo](https://github.com/libp2p/js-peer-info), [PeerId](https://github.com/libp2p/js-peer-id), [multiaddr](https://github.com/multiformats/js-multiaddr), `string` | peer to dial | +| protocols | `String|Array` | A list of protocols (or single protocol) to negotiate with. Protocols are attempted in order until a match is made. (e.g '/ipfs/bitswap/1.1.0') | +| [options] | `Object` | dial options | +| [options.signal] | [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) | An `AbortSignal` instance obtained from an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) that can be used to abort the connection before it completes | + +#### Returns + +| Type | Description | +|------|-------------| +| `Promise<{ stream:*, protocol:string }>` | Promise resolves with a [duplex stream](https://gist.github.com/alanshaw/591dc7dd54e4f99338a347ef568d6ee9#duplex-it) and the protocol used | + +#### Example + +```js +// ... +const pipe = require('it-pipe') + +const { stream, protocol } = await libp2p.dialProtocol(remotePeerInfo, protocols) + +// Use this new stream like any other duplex stream +pipe([1, 2, 3], stream, consume) +``` + +### hangUp + +Attempts to gracefully close an open connection to the given peer. If the connection is not closed in the grace period, it will be forcefully closed. + +`hangUp(peer)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| peer | [PeerInfo](https://github.com/libp2p/js-peer-info), [PeerId](https://github.com/libp2p/js-peer-id), [multiaddr](https://github.com/multiformats/js-multiaddr), `string` | peer to hang up | + +#### Returns + +| Type | Description | +|------|-------------| +| `Promise` | Promise resolves once connection closes | + +#### Example + +```js +// ... +await libp2p.hangUp(remotePeerInfo) +``` + +### handle + +Sets up [multistream-select routing](https://github.com/multiformats/multistream-select) of protocols to their application handlers. Whenever a stream is opened on one of the provided protocols, the handler will be called. `handle` must be called in order to register a handler and support for a given protocol. This also informs other peers of the protocols you support. + +`libp2p.handle(protocols, handler)` + +In the event of a new handler for the same protocol being added, the first one is discarded. + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| protocols | `Array|String` | protocols to register | +| handler | `function({ connection:*, stream:*, protocol:string })` | handler to call | + + +#### Example + +```js +// ... +const handler = ({ connection, stream, protocol }) => { + // use stream or connection according to the needs +} + +libp2p.handle('/echo/1.0.0', handler) +``` + +### unhandle + +Unregisters all handlers with the given protocols + +`libp2p.unhandle(protocols)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| protocols | `Array|String` | protocols to unregister | + +#### Example + +```js +// ... +libp2p.unhandle(['/echo/1.0.0']) +``` + +### peerRouting.findPeer + +Iterates over all peer routers in series to find the given peer. If the DHT is enabled, it will be tried first. + +`libp2p.peerRouting.findPeer(peerId, options)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| peerId | [`PeerId`](https://github.com/libp2p/js-peer-id) | ID of the peer to find | +| options | `Object` | operation options | +| options.timeout | `number` | maximum time the query should run | + +#### Returns + +| Type | Description | +|------|-------------| +| `Promise` | Peer info of a known peer | + +#### Example + +```js +// ... +const peerInfo = await libp2p.peerRouting.findPeer(peerId, options) +``` + +### contentRouting.findProviders + +Iterates over all content routers in series to find providers of the given key. +Once a content router succeeds, the iteration will stop. If the DHT is enabled, it will be queried first. + +`libp2p.contentRouting.findProviders(cid, options)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| cid | [`CID`](https://github.com/multiformats/js-cid) | cid to find | +| options | `Object` | operation options | +| options.timeout | `number` | maximum time the query should run | +| options.maxNumProviders | `number` | maximum number of providers to find | + +#### Returns + +| Type | Description | +|------|-------------| +| `AsyncIterator` | Async iterator for [`PeerInfo`](https://github.com/libp2p/js-peer-info) | + +#### Example + +```js +// Iterate over the providers found for the given cid +for await (const provider of libp2p.contentRouting.findProviders(cid)) { + console.log(provider) +} +``` + +### contentRouting.provide + +Iterates over all content routers in parallel, in order to notify it is a provider of the given key. + +`libp2p.contentRouting.provide(cid)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| cid | [`CID`](https://github.com/multiformats/js-cid) | cid to provide | + +#### Returns + +| Type | Description | +|------|-------------| +| `Promise` | Promise resolves once notifications are sent | + +#### Example + +```js +// ... +await libp2p.contentRouting.provide(cid) +``` + +### contentRouting.put + +Writes a value to a key in the DHT. + +`libp2p.contentRouting.put(key, value, options)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| key | `String` | key to add to the dht | +| value | `Buffer` | value to add to the dht | +| [options] | `Object` | put options | +| [options.minPeers] | `number` | minimum number of peers required to successfully put (default: closestPeers.length) | + +#### Returns + +| Type | Description | +|------|-------------| +| `Promise` | Promise resolves once value is stored | + +#### Example + +```js +// ... +const key = '/key' +const value = Buffer.from('oh hello there') + +await libp2p.contentRouting.put(key, value) +``` + +### contentRouting.get + +Queries the DHT for a value stored for a given key. + +`libp2p.contentRouting.get(key, options)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| key | `String` | key to get from the dht | +| [options] | `Object` | get options | +| [options.timeout] | `number` | maximum time the query should run | + +#### Returns + +| Type | Description | +|------|-------------| +| `Promise` | Value obtained from the DHT | + +#### Example + +```js +// ... + +const key = '/key' +const value = await libp2p.contentRouting.get(key) +``` + +### contentRouting.getMany + +Queries the DHT for the n values stored for the given key (without sorting). + +`libp2p.contentRouting.getMany(key, nvals, options)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| key | `String` | key to get from the dht | +| nvals | `number` | number of values aimed | +| [options] | `Object` | get options | +| [options.timeout] | `number` | maximum time the query should run | + +#### Returns + +| Type | Description | +|------|-------------| +| `Promise>` | Array of records obtained from the DHT | + +#### Example + +```js +// ... + +const key = '/key' +const { from, val } = await libp2p.contentRouting.get(key) +``` + +### pubsub.getSubscribers + +Gets a list of the peer-ids that are subscribed to one topic. + +`libp2p.pubsub.getSubscribers(topic)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| topic | `string` | topic to publish | + +#### Returns + +| Type | Description | +|------|-------------| +| `Array` | peer-id subscribed to the topic | + +#### Example + +```js +const peerIds = libp2p.pubsub.getSubscribers(topic) +``` + +### pubsub.getTopics + +Gets a list of topics the node is subscribed to. + +`libp2p.pubsub.getTopics()` + +#### Returns + +| Type | Description | +|------|-------------| +| `Array` | topics the node is subscribed to | + +#### Example + +```js +const topics = libp2p.pubsub.getTopics() +``` + +### pubsub.publish + +Publishes messages to the given topics. + +`libp2p.pubsub.publish(topic, data)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| topic | `string` | topic to publish | +| data | `Buffer` | data to publish | + +#### Returns + +| Type | Description | +|------|-------------| +| `Promise` | publish success | + +#### Example + +```js +const topic = 'topic' +const data = Buffer.from('data') + +await libp2p.pubsub.publish(topic, data) +``` + +### pubsub.subscribe + +Subscribes the given handler to a pubsub topic. + +`libp2p.pubsub.subscribe(topic, handler)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| topic | `string` | topic to subscribe | +| handler | `function({ from: String, data: Buffer, seqno: Buffer, topicIDs: Array, signature: Buffer, key: Buffer })` | handler for new data on topic | + +#### Returns + +| Type | Description | +|------|-------------| +| `void` | | + +#### Example + +```js +const topic = 'topic' +const handler = (msg) => { + // msg.data - pubsub data received +} + +libp2p.pubsub.subscribe(topic, handler) +``` + +### pubsub.unsubscribe + +Unsubscribes the given handler from a pubsub topic. If no handler is provided, all handlers for the topic are removed. + +`libp2p.pubsub.unsubscribe(topic, handler)` + +#### Parameters + +| Name | Type | Description | +|------|------|-------------| +| topic | `string` | topic to unsubscribe | +| handler | `function()` | handler subscribed | + +#### Returns + +| Type | Description | +|------|-------------| +| `void` | | + +#### Example + +```js +const topic = 'topic' +const handler = (msg) => { + // msg.data - pubsub data received +} + +libp2p.pubsub.unsubscribe(topic, handler) +```