# @libp2p/interface-pubsub

> PubSub interface for libp2p

Latest version **4.0.1** (published 2023-05-04) · Apache-2.0 OR MIT license · 0 weekly downloads

## Install

```sh
npm install @libp2p/interface-pubsub
pnpm add @libp2p/interface-pubsub
yarn add @libp2p/interface-pubsub
bun add @libp2p/interface-pubsub
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities.

Warnings: low downloads.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 4.0.1 |
| Published | 2023-05-04 |
| First published | 2022-06-10 |
| Weekly downloads | 0 |
| License | Apache-2.0 OR MIT |
| TypeScript types | bundled |
| Module format | ESM |
| Node | >=16.0.0 |
| Dependencies | 5 |
| Unpacked size | 38.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 74 |
| Maintainers | jacobheun, npm-service-account-libp2p, alanshaw, vascosantos, achingbrain, daviddias |
| Keywords | interface, libp2p |

## Links

- npm: https://www.npmjs.com/package/@libp2p/interface-pubsub
- Repository: https://github.com/libp2p/js-libp2p-interfaces
- Homepage: https://github.com/libp2p/js-libp2p-interfaces/tree/master/packages/interface-pubsub#readme
- Issues: https://github.com/libp2p/js-libp2p-interfaces/issues
- npm.io page: https://npm.io/package/@libp2p/interface-pubsub

## Dependencies (5)

- [it-pushable](https://npm.io/package/it-pushable.md) ^3.1.3
- [uint8arraylist](https://npm.io/package/uint8arraylist.md) ^2.4.3
- [@libp2p/interfaces](https://npm.io/package/@libp2p/interfaces.md) ^3.0.0
- [@libp2p/interface-peer-id](https://npm.io/package/@libp2p/interface-peer-id.md) ^2.0.0
- [@libp2p/interface-connection](https://npm.io/package/@libp2p/interface-connection.md) ^5.0.0

## Recent versions

- 4.0.1 (latest) — 2023-05-04
- 4.0.1-d853d124 (next) — 2023-06-19
- 4.0.1-ea8a0637 — 2023-06-19
- 4.0.1-ab0e3980 — 2023-06-19
- 4.0.1-3dfc236e — 2023-06-16
- 4.0.1-8c6b6d24 — 2023-06-15
- 4.0.1-d2f1eff4 — 2023-06-15
- 4.0.1-5a9fb4d6 — 2023-06-15
- 4.0.1-883082ca — 2023-06-15
- 4.0.1-1c6702c8 — 2023-06-15
- 4.0.0 — 2023-04-18
- 3.0.7 — 2023-04-11
- 3.0.6 — 2023-01-18
- 3.0.5 — 2023-01-06
- 3.0.4 — 2022-12-19
- … 13 more at https://npm.io/package/@libp2p/interface-pubsub/versions

## README

# @libp2p/interface-pubsub <!-- omit in toc -->

[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/)
[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io)
[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p-interfaces.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p-interfaces)
[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p-interfaces/js-test-and-release.yml?branch=master\&style=flat-square)](https://github.com/libp2p/js-libp2p-interfaces/actions/workflows/js-test-and-release.yml?query=branch%3Amaster)

> PubSub interface for libp2p

## Table of contents <!-- omit in toc -->

- - [Install](#install)
- [Table of Contents <!-- omit in toc -->](#table-of-contents----omit-in-toc---)
  - [Implementations using this interface](#implementations-using-this-interface)
  - [Interface usage](#interface-usage)
    - [Extend interface](#extend-interface)
    - [Example](#example)
  - [API](#api)
    - [Constructor](#constructor)
      - [`new Pubsub({options})`](#new-pubsuboptions)
        - [Parameters](#parameters)
    - [Start](#start)
      - [`pubsub.start()`](#pubsubstart)
    - [Stop](#stop)
      - [`pubsub.stop()`](#pubsubstop)
    - [Publish](#publish)
      - [`pubsub.publish(topic, message)`](#pubsubpublishtopic-message)
        - [Parameters](#parameters-1)
        - [Returns](#returns)
    - [Subscribe](#subscribe)
      - [`pubsub.subscribe(topic)`](#pubsubsubscribetopic)
        - [Parameters](#parameters-2)
    - [Unsubscribe](#unsubscribe)
      - [`pubsub.unsubscribe(topic)`](#pubsubunsubscribetopic)
        - [Parameters](#parameters-3)
    - [Get Topics](#get-topics)
      - [`pubsub.getTopics()`](#pubsubgettopics)
        - [Returns](#returns-1)
    - [Get Peers Subscribed to a topic](#get-peers-subscribed-to-a-topic)
      - [`pubsub.getSubscribers(topic)`](#pubsubgetsubscriberstopic)
        - [Parameters](#parameters-4)
        - [Returns](#returns-2)
    - [Validate](#validate)
      - [`pubsub.validate(message)`](#pubsubvalidatemessage)
        - [Parameters](#parameters-5)
      - [Returns](#returns-3)
  - [Test suite usage](#test-suite-usage)
  - [API Docs](#api-docs)
  - [License](#license)
  - [Contribution](#contribution)

## Install

```console
$ npm i @libp2p/interface-pubsub
```

The `interface-pubsub` contains the base implementation for a libp2p pubsub router implementation. This interface should be used to implement a pubsub router compatible with libp2p. It includes a test suite that pubsub routers should run, in order to ensure compatibility with libp2p.

# Table of Contents <!-- omit in toc -->

- [Implementations using this interface](#implementations-using-this-interface)
- [Interface usage](#interface-usage)
  - [Extend interface](#extend-interface)
  - [Example](#example)
- [API](#api)
  - [Constructor](#constructor)
    - [`new Pubsub({options})`](#new-pubsuboptions)
      - [Parameters](#parameters)
  - [Start](#start)
    - [`pubsub.start()`](#pubsubstart)
  - [Stop](#stop)
    - [`pubsub.stop()`](#pubsubstop)
  - [Publish](#publish)
    - [`pubsub.publish(topic, message)`](#pubsubpublishtopic-message)
      - [Parameters](#parameters-1)
      - [Returns](#returns)
  - [Subscribe](#subscribe)
    - [`pubsub.subscribe(topic)`](#pubsubsubscribetopic)
      - [Parameters](#parameters-2)
  - [Unsubscribe](#unsubscribe)
    - [`pubsub.unsubscribe(topic)`](#pubsubunsubscribetopic)
      - [Parameters](#parameters-3)
  - [Get Topics](#get-topics)
    - [`pubsub.getTopics()`](#pubsubgettopics)
      - [Returns](#returns-1)
  - [Get Peers Subscribed to a topic](#get-peers-subscribed-to-a-topic)
    - [`pubsub.getSubscribers(topic)`](#pubsubgetsubscriberstopic)
      - [Parameters](#parameters-4)
      - [Returns](#returns-2)
  - [Validate](#validate)
    - [`pubsub.validate(message)`](#pubsubvalidatemessage)
      - [Parameters](#parameters-5)
    - [Returns](#returns-3)
- [Test suite usage](#test-suite-usage)
- [License](#license)
  - [Contribution](#contribution)

## Implementations using this interface

You can check the following implementations as examples for building your own pubsub router.

- [libp2p/js-libp2p-floodsub](https://github.com/libp2p/js-libp2p-floodsub)
- [ChainSafe/js-libp2p-gossipsub](https://github.com/ChainSafe/js-libp2p-gossipsub)

## Interface usage

`interface-pubsub` abstracts the implementation protocol registration within `libp2p` and takes care of all the protocol connections and streams, as well as the subscription management and the features describe in the libp2p [pubsub specs](https://github.com/libp2p/specs/tree/master/pubsub). This way, a pubsub implementation can focus on its message routing algorithm, instead of also needing to create the setup for it.

### Extend interface

A pubsub router implementation should start by extending the `interface-pubsub` class and **MUST** override the `_publish` function, according to the router algorithms. This function is responsible for forwarding publish messages to other peers, as well as forwarding received messages if the router provides the `canRelayMessage` option to the base implementation.

Other functions, such as `start`, `stop`, `subscribe`, `unsubscribe`, `_encodeRpc`, `_decodeRpc`, `_processRpcMessage`, `_addPeer` and `_removePeer` may be overwritten if the pubsub implementation needs to customize their logic. Implementations overriding these functions **MUST** call `super`.

The `start` and `stop` functions are responsible for the registration of the pubsub protocol with libp2p. The `stop` function also guarantees that the open streams in the protocol are properly closed.

The `subscribe` and `unsubscribe` functions take care of the subscription management and its inherent message propagation.

When using a custom protobuf definition for message marshalling, you should override `_encodeRpc` and `_decodeRpc` to use the new protobuf instead of the default one.

`_processRpcMessage` is responsible for handling messages received from other peers. This should be extended if further operations/validations are needed by the router.

The `_addPeer` and `_removePeer` functions are called when new peers running the pubsub router protocol establish a connection with the peer. They are used for tracking the open streams between the peers.

All the remaining functions **MUST NOT** be overwritten.

### Example

The following example aims to show how to create your pubsub implementation extending this base protocol. The pubsub implementation will handle the subscriptions logic.

```JavaScript
const Pubsub = require('libp2p-interfaces/src/pubsub')

class PubsubImplementation extends Pubsub {
  constructor({ libp2p, options })
    super({
      debugName: 'libp2p:pubsub',
      multicodecs: '/pubsub-implementation/1.0.0',
      libp2p,
      globalSigningPolicy: options.globalSigningPolicy
    })
  }

  _publish (message) {
    // Required to be implemented by the subclass
    // Routing logic for the message
  }
}
```

## API

The interface aims to specify a common interface that all pubsub router implementation should follow. A pubsub router implementation should extend the [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter). When peers receive pubsub messages, these messages will be emitted by the event emitter where the `eventName` will be the `topic` associated with the message.

### Constructor

The base class constructor configures the pubsub instance for use with a libp2p instance. It includes settings for logging, signature policies, etc.

#### `new Pubsub({options})`

##### Parameters

| Name                          | Type                             | Description                                     | Default              |
| ----------------------------- | -------------------------------- | ----------------------------------------------- | -------------------- |
| options.libp2p                | `Libp2p`                         | libp2p instance                                 | required, no default |
| options.debugName             | `string`                         | log namespace                                   | required, no default |
| options.multicodecs           | `string \| Array<string>`        | protocol identifier(s)                          | required, no default |
| options.globalSignaturePolicy | `'StrictSign' \| 'StrictNoSign'` | signature policy to be globally applied         | `'StrictSign'`       |
| options.canRelayMessage       | `boolean`                        | if can relay messages if not subscribed         | `false`              |
| options.emitSelf              | `boolean`                        | if `publish` should emit to self, if subscribed | `false`              |

### Start

Starts the pubsub subsystem. The protocol will be registered to `libp2p`, which will result in pubsub being notified when peers who support the protocol connect/disconnect to `libp2p`.

#### `pubsub.start()`

### Stop

Stops the pubsub subsystem. The protocol will be unregistered from `libp2p`, which will remove all listeners for the protocol and the established connections will be closed.

#### `pubsub.stop()`

### Publish

Publish data message to pubsub topics.

#### `pubsub.publish(topic, message)`

##### Parameters

| Name    | Type         | Description        |
| ------- | ------------ | ------------------ |
| topic   | `string`     | pubsub topic       |
| message | `Uint8Array` | message to publish |

##### Returns

| Type            | Description                                           |
| --------------- | ----------------------------------------------------- |
| `Promise<void>` | resolves once the message is published to the network |

### Subscribe

Subscribe to the given topic.

#### `pubsub.subscribe(topic)`

##### Parameters

| Name  | Type     | Description  |
| ----- | -------- | ------------ |
| topic | `string` | pubsub topic |

### Unsubscribe

Unsubscribe from the given topic.

#### `pubsub.unsubscribe(topic)`

##### Parameters

| Name  | Type     | Description  |
| ----- | -------- | ------------ |
| topic | `string` | pubsub topic |

### Get Topics

Get the list of topics which the peer is subscribed to.

#### `pubsub.getTopics()`

##### Returns

| Type            | Description                |
| --------------- | -------------------------- |
| `Array<String>` | Array of subscribed topics |

### Get Peers Subscribed to a topic

Get a list of the [PeerId](https://github.com/libp2p/js-peer-id) strings that are subscribed to one topic.

#### `pubsub.getSubscribers(topic)`

##### Parameters

| Name  | Type     | Description  |
| ----- | -------- | ------------ |
| topic | `string` | pubsub topic |

##### Returns

| Type            | Description               |
| --------------- | ------------------------- |
| `Array<string>` | Array of base-58 PeerId's |

### Validate

Validates a message according to the signature policy and topic-specific validation function.

#### `pubsub.validate(message)`

##### Parameters

| Name    | Type      | Description      |
| ------- | --------- | ---------------- |
| message | `Message` | a pubsub message |

#### Returns

| Type            | Description                      |
| --------------- | -------------------------------- |
| `Promise<void>` | resolves if the message is valid |

## Test suite usage

```js
'use strict'

const tests = require('libp2p-interfaces-compliance-tests/pubsub')
const YourPubsubRouter = require('../src')

describe('compliance', () => {
  let peers
  let pubsubNodes = []

  tests({
    async setup (number = 1, options = {}) {
      // Create number pubsub nodes with libp2p
      peers = await createPeers({ number })

      peers.forEach((peer) => {
        const ps = new YourPubsubRouter(peer, options)

        pubsubNodes.push(ps)
      })

      return pubsubNodes
    },
    async teardown () {
      // Clean up any resources created by setup()
      await Promise.all(pubsubNodes.map(ps => ps.stop()))
      peers.length && await Promise.all(peers.map(peer => peer.stop()))
    }
  })
})
```

## API Docs

- <https://libp2p.github.io/js-libp2p-interfaces/modules/_libp2p_interface_pubsub.html>

## License

Licensed under either of

- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT ([LICENSE-MIT](LICENSE-MIT) / <http://opensource.org/licenses/MIT>)

## Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

---
_Source: https://npm.io/package/@libp2p/interface-pubsub · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
