## 1. Project Overview & Quickstart (libp2p/rust-libp2p)

## File: README.md

# Central repository for work on libp2p

[](http://libp2p.io/)
[](https://deps.rs/repo/github/libp2p/rust-libp2p)
[](https://crates.io/crates/libp2p)
[](https://docs.rs/libp2p)
[](https://libp2p.github.io/rust-libp2p/libp2p/)

This repository is the central place for Rust development of the [libp2p](https://libp2p.io) spec.

## Getting started

- **Main documentation** can be found on https://docs.rs/libp2p.

- The **[examples](examples)** folder contains small binaries showcasing the
  many protocols in this repository.

- For **security related issues** please [file a private security vulnerability
  report](https://github.com/libp2p/rust-libp2p/security/advisories/new) . Please do not file a
  public issue on GitHub.

- To **report bugs, suggest improvements or request new features** please open a
  GitHub issue on this repository.

- For **rust-libp2p specific questions** please use the GitHub _Discussions_
  forum https://github.com/libp2p/rust-libp2p/discussions.

- For **discussions and questions related to multiple libp2p implementations**
  please use the libp2p _Discourse_ forum https://discuss.libp2p.io.

- For synchronous discussions join the [open rust-libp2p maintainer
  calls](https://github.com/libp2p/rust-libp2p/discussions?discussions_q=open+maintainers+call+)
  or the [biweekly libp2p community calls](https://discuss.libp2p.io/t/libp2p-community-calls/1157).

## Repository Structure

The main components of this repository are structured as follows:

  * `core/`: The implementation of `libp2p-core` with its `Transport` and
    `StreamMuxer` API on which almost all other crates depend.

  * `transports/`: Implementations of transport protocols (e.g. TCP) and protocol upgrades
    (e.g. for authenticated encryption, compression, ...) based on the `libp2p-core` `Transport`
    API.

  * `muxers/`: Implementations of the `StreamMuxer` interface of `libp2p-core`,
    e.g. (sub)stream multiplexing protocols on top of (typically TCP) connections.
    Multiplexing protocols are (mandatory) `Transport` upgrades.

  * `swarm/`: The implementation of `libp2p-swarm` building on `libp2p-core`
    with the central interfaces `NetworkBehaviour` and `ConnectionHandler` used
    to implement application protocols (see `protocols/`).

  * `protocols/`: Implementations of application protocols based on the
    `libp2p-swarm` APIs.

  * `misc/`: Utility libraries.

  * `libp2p/examples/`: Worked examples of built-in application protocols (see `protocols/`)
    with common `Transport` configurations.

## Community Guidelines

The libp2p project operates under the [IPFS Code of
Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).

> tl;dr
>
> - Be respectful.
> - We're here to help: abuse@ipfs.io
> - Abusive behavior is never tolerated.
> - Violations of this code may result in swift and permanent expulsion from the
>   IPFS [and libp2p] community.
> - "Too long, didn't read" is not a valid excuse for not knowing what is in
>   this document.

## Maintainers

(In alphabetical order.)

- Elena Frank ([@elenaf9](https://github.com/elenaf9))
- João Oliveira ([@jxs](https://github.com/jxs))

## Notable users

(open a pull request if you want your project to be added here)

- [COMIT](https://github.com/comit-network/xmr-btc-swap) - Bitcoin–Monero Cross-chain Atomic Swap.
- [Forest](https://github.com/ChainSafe/forest) - An implementation of Filecoin written in Rust.
- [fuel-core](https://github.com/FuelLabs/fuel-core) - A Rust implementation of the Fuel protocol.
- [HotShot](https://github.com/EspressoSystems/HotShot) - Decentralized sequencer in Rust developed by [Espresso Systems](https://www.espressosys.com/).
- [ipfs-embed](https://github.com/ipfs-rust/ipfs-embed) - A small embeddable ipfs implementation used and maintained by [Actyx](https://www.actyx.com).
- [Homestar](https://github.com/ipvm-wg/homestar) - An InterPlanetary Virtual Machine (IPVM) implementation used and maintained by Fission.
- [beetle](https://github.com/n0-computer/beetle) - Next-generation implementation of IPFS for Cloud & Mobile platforms.
- [Lighthouse](https://github.com/sigp/lighthouse) - Ethereum consensus client in Rust.
- [Locutus](https://github.com/freenet/locutus) - Global, observable, decentralized key-value store.
- [Neptune](https://github.com/Neptune-Crypto/neptune-core) - post-quantum, scalable, and private blockchain with zk-STARKs on Layer-1.
- [OpenMina](https://github.com/openmina/openmina) - In-browser Mina Rust implementation.
- [qaul قول](https://github.com/qaul/qaul.net) - Internet Independent Wireless Mesh Communication App
- [rust-ipfs](https://github.com/rs-ipfs/rust-ipfs) - IPFS implementation in Rust.
- [Safe Network](https://github.com/maidsafe/safe_network) - Safe Network implementation in Rust.
- [SQD Network](https://github.com/subsquid/sqd-network) - A decentralized storage for Web3 data.
- [Starcoin](https://github.com/starcoinorg/starcoin) - A smart contract blockchain network that scales by layering.
- [Subspace](https://github.com/subspace/subspace) - Subspace Network reference implementation
- [Substrate](https://github.com/paritytech/substrate) - Framework for blockchain innovation,
used by [Polkadot](https://www.parity.io/technologies/polkadot/).
- [Swarm NL](https://github.com/algorealmInc/SwarmNL) - A library that makes it easy to configure the networking requirements for any distributed application.
- [Taple](https://github.com/opencanarias/taple-core) - Sustainable DLT for asset and process traceability by [OpenCanarias](https://www.opencanarias.com/en/).
- [Ceylon](https://github.com/ceylonai/ceylon) - A Multi-Agent System (MAS) Development Framework.
- [Fungi](https://github.com/enbop/fungi) - A platform built for seamless multi-device integration.
- [Kinetic](https://github.com/saifmukhtar/kinetic) - Stateless, Sybil-resistant naming system with permanent identities using VDFs and drand.

---

## File: docs/coding-guidelines.md

# Coding Guidelines


**Table of Contents**

- [Coding Guidelines](#coding-guidelines)
    - [Hierarchical State Machines](#hierarchical-state-machines)
        - [Conventions for `poll` implementations](#conventions-for-poll-implementations)
        - [Prioritize local work over new work from a remote](#prioritize-local-work-over-new-work-from-a-remote)
    - [Bound everything](#bound-everything)
        - [Channels](#channels)
        - [Local queues](#local-queues)
        - [Tasks](#tasks)
        - [Further reading](#further-reading)
    - [No premature optimizations](#no-premature-optimizations)
    - [Keep things sequential unless proven to be slow](#keep-things-sequential-unless-proven-to-be-slow)
    - [Use `async/await` for sequential execution only](#use-asyncawait-for-sequential-execution-only)
    - [Don't communicate by sharing memory; share memory by communicating.](#dont-communicate-by-sharing-memory-share-memory-by-communicating)
        - [Further Reading](#further-reading)
    - [Use iteration not recursion](#use-iteration-not-recursion)
        - [Further Reading](#further-reading-1)
    - [Allow Correlating Asynchronous Responses to Their Requests](#allow-correlating-asynchronous-responses-to-their-requests)




Below is a set of coding guidelines followed across the rust-libp2p code base.

## Hierarchical State Machines

If you squint, rust-libp2p is just a big hierarchy of [state
machines](https://en.wikipedia.org/wiki/Finite-state_machine) where parents pass
events down to their children and children pass events up to their parents.




    Reproduce diagram

    ```
    @startuml
    Swarm <|-- RootBehaviour
    Swarm <|-- ConnectionPool
    Swarm <|-- Transport
    RootBehaviour <|-- PingBehaviour
    RootBehaviour <|-- IdentifyBehaviour
    RootBehaviour <|-- KademliaBehaviour

    Swarm : poll()
    RootBehaviour : poll()
    ConnectionPool : poll()
    Transport : poll()
    PingBehaviour : poll()
    IdentifyBehaviour : poll()
    KademliaBehaviour : poll()
    @enduml
    ```


Using hierarchical state machines is a deliberate choice throughout the
rust-libp2p code base. It makes reasoning about control and data flow simple. It
works well with Rust's `Future` model. It allows fine-grain control e.g. on the
order child state machines are polled.

The above comes with downsides. It feels more verbose. The mix of control flow (`loop`, `return`,
`break`, `continue`) in `poll` functions together with the asynchronous and thus decoupled
communication via events can be very hard to understand. Both are a form of complexity that we are
trading for correctness and performance which aligns with Rust's and rust-libp2p's goals.

The architecture pattern of hierarchical state machines should be used wherever possible.

### Conventions for `poll` implementations

The `poll` method of a single state machine can be complex especially when that
state machine itself `poll`s many child state machines. The patterns shown below
have proven useful and should be followed across the code base.

```
/* Detailed source-code truncated for AI context efficiency. */
```

### Prioritize local work over new work from a remote

When handling multiple work streams, prioritize local work items over
accepting new work items from a remote. Take the following state machine as an
example, reading and writing from a socket, returning result to its parent:

``` rust
struct SomeStateMachine {
  socket: Socket,
  events_to_return_to_parent: VecDeque<Event>,
  messages_to_send_on_socket: VecDeque<Message>,
}

impl Stream for SomeStateMachine {
  type Item = Event;

  fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
    loop {
      // First priority is returning local finished work.
      if let Some(event) = events_to_return_to_parent.pop_front() {
        return Poll::Ready(Some(event));
      }

      // Second priority is finishing local work, i.e. sending on the socket.
      if let Poll::Ready(()) = socket.poll_ready(cx) {
        todo!("Send messages")
        continue // Go back to the top. One might be able to send more.
      }

      // Last priority is accepting new work, i.e. reading from the socket.
      if let Poll::Ready(work_item) = socket.poll_next(cx) {
        todo!("Start work on new item")
        continue // Go back to the top. There might be more progress to be made.
      }

      // At this point in time, there is no more progress to be made. Return
      // `Pending` and be woken up later.
      return Poll::Pending;
    }
  }
}
```

This prioritization provides:
- Low memory footprint as local queues (here `events_to_return_to_parent`) stay small.
- Low latency as accepted local work is not stuck in queues.
- DOS defense as a remote does not control the size of the local queue, nor starves local work with its remote work.

## Bound everything

The concept of unboundedness is an illusion. Use bounded mechanisms to prevent
unbounded memory growth and high latencies.

### Channels

When using channels (e.g. `futures::channel::mpsc` or `std::sync::mpsc`)
always use the bounded variant, never use the unbounded variant. When using a
bounded channel, a slow consumer eventually slows down a fast producer once
the channel bound is reached, ideally granting the slow consumer more system
resources e.g. CPU time, keeping queues small and thus latencies low. When
using an unbounded channel a fast producer continues being a fast producer,
growing the channel buffer indefinitely, increasing latency until the illusion
of unboundedness breaks and the system runs out of memory.

One may use an unbounded channel if one enforces backpressure through an
out-of-band mechanism, e.g. the consumer granting the producer send-tokens
through a side-channel.

### Local queues

As for channels shared across potentially concurrent actors (e.g. future tasks
or OS threads), the same applies to queues owned by a single actor only. E.g.
reading events from a socket into a `Vec<Event>` without some mechanism
bounding the size of that `Vec<Event>` again can lead to unbounded memory
growth and high latencies.

Note that rust-libp2p fails at this guideline, i.e. still has many unbounded
local queues.

### Tasks

Bound the number of
[tasks](https://docs.rs/futures/latest/futures/task/index.html) being spawned.
As an example, say we spawn one task per incoming request received from a
socket. If the number of pending requests is not bounded by some limit, a
misbehaving or malicious remote peer can send requests at a higher rate than the
local node can respond at. This results in unbounded growth in the number of
requests, and thus unbounded growth in the number of tasks and used memory.

Simply put, rust-libp2p spawns one task per connection but limits the overall
number of connections, thus adhering to this guideline.

### Further reading

- https://en.wikipedia.org/wiki/Bufferbloat
- https://apenwarr.ca/log/20170814
- https://twitter.com/peterbourgon/status/1212800031406739456

## No premature optimizations

Optimizations that add complexity need to be accompanied with a proof of their
effectiveness.

This as well applies to increasing buffer or channel sizes, as the downside of
such pseudo optimizations is increased memory footprint and latency.

## Keep things sequential unless proven to be slow

Concurrency adds complexity. Concurrency adds overhead due to synchronization.
Thus unless proven to be a bottleneck, don't make things concurrent. As an example
the hierarchical `NetworkBehaviour` state machine runs sequentially. It is easy
to debug as it runs sequentially. Thus far there has been no proof that
shows a speed-up when running it concurrently.

## Use `async/await` for sequential execution only

Using `async/await` for sequential execution makes things significantly simpler.
Though unfortunately using `async/await` does not allow accessing methods on the
object being `await`ed unless paired with some synchronization mechanism like an
`Arc<Mutex<_>>`.

Example: Read and once done write from/to a socket. Use `async/await`.

``` rust
socket.read_exact(&mut read_buf).await;
socket.write(&write_buf).await;
```

Example: Read and concurrently write from/to a socket. Use `poll`.

``` rust
loop {
    match socket.poll_read(cx, &mut read_buf) {
        Poll::Ready(_) => {
            todo!();
            continue;
        }
        Poll::Pending => {}
    }
    match socket.poll_write(cx, &write_buf) {
        Poll::Ready(_) => {
            todo!();
            continue;
        }
        Poll::Pending => {}
    }

    return Poll::Pending;
}
```

When providing `async` methods, make it explicit whether it is safe to cancel
the resulting `Future`, i.e. whether it is safe to drop the `Future` returned
by the `async` method.

## Don't communicate by sharing memory; share memory by communicating.

The majority of rust-libp2p's code base follows the above Golang philosophy,
e.g. using channels instead of mutexes. This pattern enforces single ownership
over data, which works well with Rust's ownership model and makes reasoning
about data flow easier.

### Further Reading

- https://go.dev/blog/codelab-share

## Use iteration not recursion

Rust does not support tail call optimization, thus using recursion may grow the
stack potentially unboundedly. Instead use iteration e.g. via `loop` or `for`.

### Further Reading

- https://en.wikipedia.org/wiki/Tail_call
- https://stackoverflow.com/questions/65948553/why-is-recursion-not-suggested-in-rust
- https://stackoverflow.com/questions/59257543/when-is-tail-recursion-guaranteed-in-rust

## Allow Correlating Asynchronous Responses to Their Requests

In an asynchronous context, it is important to enable users to determine the correlation between a
response and a previous request. For example, if a user requests two new connections to the same
peer, they should be able to match each new connection to the corresponding previous connection
request without having to guess.

When accepting a **command** that eventually results in a response through an event requires that
command to contain a unique ID, which is later on contained in the asynchronous response event. One
such example is the `Swarm` accepting a `ToSwarm::Dial` from the `NetworkBehaviour`.

``` rust
struct Command {
  id: Id,
  // ...
}

struct Response {
  command_id: Id,
  // ...
}
```

---

## File: docs/maintainer-handbook.md

# Maintainer handbook

This document describes whatever maintainer of the repository should know.

## GitHub settings

All settings around GitHub like branch protection settings are managed through https://github.com/libp2p/github-mgmt.
For example, adding, removing or renaming a required CI job will need to be preceded by a PR that changes the configuration.

To streamline things, it is good to _prepare_ such a PR together with the one that changes the CI workflows.
Take care to not merge the configuration change too early because it will block CI of all other PRs because GitHub now requires the new set of jobs (which will only be valid for the PR that actually changes the CI definition).

## Mergify

We utilize mergify as a merge-queue and overall automation bot on the repository.
The configuration file is [.github/mergify.yml](../.github/mergify.yml).

The main feature is the `send-it` label.
Once a PR fulfills all merge requirements (approvals, passing CI, etc), applying the `send-it` labels activates mergify's merge-queue.

- All branch protection rules, i.e. minimum number of reviews, green CI, etc are _implicit_ and thus do not need to be listed.
- Changing the mergify configuration file **always** requires the PR to be merged manually.
  In other words, applying `send-it` to a PR that changes the mergify configuration has **no** effect.
  This is a security feature of mergify to make sure changes to the automation are carefully reviewed.

In case of a trivial code change, maintainers may choose to apply the `trivial` label.
This will have mergify approve your PR, thus fulfilling all requirements to automatically queue a PR for merging.

## Changelog entries

Our CI checks that each crate which is modified gets a changelog entry.
Whilst this is a good default safety-wise, it creates a lot of false-positives for changes that are internal and don't need a changelog entry.

For PRs in the categories `chore`, `deps`, `refactor` and `docs`, this check is disabled automatically.
Any other PR needs to explicitly disable this check if desired by applying the `internal-change` label.

## Dependencies

We version our `Cargo.lock` file for better visibility into which dependencies are required for a functional build.
Additionally, this makes us resilient to semver-incompatible updates of our dependencies (which would otherwise result in a build error).

As a consequence, we receive many dependency bump PRs from dependabot.
We have some automation in place to deal with those.

1. semver-compatible updates (i.e. patch bumps for 0.x dependencies and minor bumps for 1.x dependencies) are approved automatically by mergify.
2. all approved dependabot PRs are queued for merging automatically

The `send-it` label is not necessary (but also harmless) for dependabot PRs.

## Issues vs discussions

We typically use issues to handle bugs, feature-requests and track to-be-done work.
As a rule of thumb, we use issues for things that are fairly clear in nature.

Broader ideas or brainstorming happens in GitHub's discussions.
Those allow for more fine-granular threading which is likely to happen for ideas that are not yet fleshed out.

Unless specified otherwise, it is safe to assume that what is documented in issues represents the consensus of the maintainers.

## Labels

For the most part, the labels we use on issues are pretty self-explanatory.

- `decision-pending`: Documents that the issue is blocked.
  Maintainers are encouraged to provide their input on issues marked with this label.
- `need/author-input`: Integrates with our [.github/workflows/stale.yml](../.github/workflows/stale.yml) workflow.
  Any issue tagged with this label will be auto-closed due to inactivity after a certain time.

---

## File: docs/release.md

# Release process

This project follows [semantic versioning](https://semver.org/). The following
documentation will refer to `X.Y.Z` as _major_, _minor_ and _patch_ version.

## Development between releases

### Prefer non-breaking changes

We strive to minimize breaking changes for our users.
PRs with breaking changes are not merged immediately but collected in a milestone.
For example: https://github.com/libp2p/rust-libp2p/milestone/6.

Non-breaking changes are typically merged very quickly and often released as patch-releases soon after.

### Make changelog entries

Every crate that we publish on `crates.io` has a `CHANGELOG.md` file.
Substantial PRs should add an entry to each crate they modify.
We have a CI check[^1] that enforces adding a changelog entry if you modify code in a particular crate.
In case the current version is already released (we also check that in CI), you'll have to add a new header at the top.
For example, the top-listed version might be `0.17.3` but it is already released.
In that case, add a new heading `## 0.17.4` with your changelog entry in case it is a non-breaking change.

The version in the crate's `Cargo.toml` and the top-most version in the `CHANGELOG.md` file always have to be in sync.
Additionally, we also enforce that all crates always depend on the latest version of other workspace-crates through workspace inheritance.
As a consequence, you'll also have to bump the version in `[workspace.dependencies]` in the workspace `Cargo.toml` manifest.

## Releasing one or more crates

The above changelog-management strategy means `master` is always in a state where we can make a release.

### Prerequisites

- [cargo release](https://github.com/crate-ci/cargo-release/)

### Steps

1. Run the two commands below on the (squash-) merged commit on the `master` branch.

    1. `cargo release publish --execute`

    2. `cargo release tag --sign-tag --execute`

2. Confirm that `cargo release` tagged the commit correctly via `git push $YOUR_ORIGIN --tag --dry-run`
   Push the new tags via `git push $YOUR_ORIGIN --tag`.
   Make sure not to push unrelated git tags.

## Patch release

1. Create a branch `v0.XX` off of the minor release tag.

2. Merge patches into branch in accordance with [development between releases section](#development-between-releases).

3. Cut release in accordance with [releasing one or more crates section](#releasing-one-or-more-crates) replacing `master` with `v0.XX`.

## Dealing with alphas

Unfortunately, `cargo` has a rather unintuitive behaviour when it comes to dealing with pre-releases like `0.1.0-alpha`.
See this internals thread for some context: https://internals.rust-lang.org/t/changing-cargo-semver-compatibility-for-pre-releases

In short, cargo will automatically update from `0.1.0-alpha.1` to `0.1.0-alpha.2` UNLESS you pin the version directly with `=0.1.0-alpha.1`.
However, from a semver perspective, changes between pre-releases can be breaking.

To avoid accidental breaking changes for our users, we employ the following convention for alpha releases:

- For a breaking change in a crate with an alpha release, bump the "minor" version but retain the "alpha" tag.
  Example: `0.1.0-alpha` to `0.2.0-alpha`.
- For a non-breaking change in a crate with an alpha release, bump or append number to the "alpha" tag.
  Example: `0.1.0-alpha` to `0.1.0-alpha.1`.

[^1]: See [ci.yml](../.github/workflows/ci.yml) and look for "Ensure manifest and CHANGELOG are properly updated".

---

## File: examples/ping/README.md

## Description

The ping example showcases how to create a network of nodes that establish connections, negotiate the ping protocol, and ping each other.

## Usage

To run the example, follow these steps:

1. In a first terminal window, run the following command:

   ```sh
   cargo run
   ```

   This command starts a node and prints the `PeerId` and the listening addresses, such as `Listening on "/ip4/0.0.0.0/tcp/24915"`.

2. In a second terminal window, start a new instance of the example with the following command:

   ```sh
   cargo run -- /ip4/127.0.0.1/tcp/24915
   ```

   Replace `/ip4/127.0.0.1/tcp/24915` with the listen address of the first node obtained from the first terminal window.

3. The two nodes will establish a connection, negotiate the ping protocol, and begin pinging each other.

## Conclusion

The ping example demonstrates the basic usage of **libp2p** to create a simple p2p network and implement a ping protocol.
By running multiple nodes and observing the ping behavior, users can gain insights into how **libp2p** facilitates communication and interaction between peers.

---

## File: examples/metrics/README.md

## Description

The example showcases how to run a p2p network with **libp2p** and collect metrics using `libp2p-metrics` as well as span data via `opentelemetry`.
It sets up multiple nodes in the network and measures various metrics, such as `libp2p_ping`, to evaluate the network's performance.

## Usage

To run the example, follow these steps:

1. Run the following command to start the first node:

   ```sh
   cargo run
   ```

2. Open a second terminal and run the following command to start a second node:

   ```sh
   cargo run -- <listen-addr-of-first-node>
   ```

   Replace `<listen-addr-of-first-node>` with the listen address of the first node reported in the first terminal.
   Look for the line that says `NewListenAddr` to find the address.

3. Open a third terminal and run the following command to retrieve the metrics from either the first or second node:

   ```sh
   curl localhost:<metrics-port-of-first-or-second-node>/metrics
   ```

   Replace `<metrics-port-of-first-or-second-node>` with the listen port of the metrics server of either the first or second node.
   Look for the line that says `tide::server Server listening on` to find the port.

   After executing the command, you should see a long list of metrics printed to the terminal.
   Make sure to check the `libp2p_ping` metrics, which should have a value greater than zero (`>0`).

## Opentelemetry

To see the span data collected as part of the `Swarm`s activity, start up an opentelemetry collector:

```sh
docker compose up
```

Then, configure tracing to output spans:

```shell
export RUST_LOG=info,[ConnectionHandler::poll]=trace,[NetworkBehaviour::poll]=trace
```

Next, (re)-start the two example for it to connect to the OTEL collector.
Finally, open the Jaeger UI in a browser and explore the spans: http://localhost:16686.

### Filtering spans

For a precise documentation, please see the following documentation in tracing: <https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives>.

`rust-libp2p` consistently applies spans to the following functions:

- `ConnectionHandler::poll` implementations
- `NetworkBehaviour::poll` implementations

The above spans are all called exactly that: `ConnectionHandler::poll` and `NetworkBehaviour::poll`.
You can activate _all_ of them by setting:

```
RUST_LOG=[ConnectionHandler::poll]=trace
```

If you just wanted to see the spans of the `libp2p_ping` crate, you can filter like this:

```
RUST_LOG=libp2p_ping[ConnectionHandler::poll]=trace
```

## Conclusion

This example demonstrates how to utilize the `libp2p-metrics` crate to collect and analyze metrics in a libp2p network.
By running multiple nodes and examining the metrics, users can gain insights into the network's performance and behavior.

---

## File: examples/ipfs-private/README.md

## Description

This example showcases a minimal implementation of a **libp2p** node that can interact with IPFS.
It utilizes the gossipsub protocol for pubsub messaging, the ping protocol for network connectivity testing, and the identify protocol for peer identification.
The node can be used to communicate with other IPFS nodes that have gossipsub enabled.

To establish a connection with other nodes, you can provide their multiaddresses as command-line arguments.
On startup, the example will display a list of addresses that you can dial from a `go-ipfs` or `js-ipfs` node.

## Usage

To run the example, follow these steps:

1.  Build and run the example using Cargo:
    ```sh
    cargo run [ADDRESS_1] [ADDRESS_2] ...
    ```

    Replace `[ADDRESS_1]`, `[ADDRESS_2]`, etc., with the multiaddresses of the nodes you want to connect to.
    You can provide multiple addresses as command-line arguments.

    **Note:** The multiaddress should be in the following format: `/ip4/127.0.0.1/tcp/4001/p2p/peer_id`.

2.  Once the example is running, you can interact with the IPFS node using the following commands:

    -   **Pubsub (Gossipsub):** You can use the gossipsub protocol to send and receive messages on the "chat" topic.
        To send a message, type it in the console and press Enter.
        The message will be broadcasted to other connected nodes using gossipsub.

    -   **Ping:** You can ping other connected nodes to test network connectivity.
        The example will display the round-trip time (RTT) for successful pings or indicate if a timeout occurs.


## Conclusion

This example provides a basic implementation of an IPFS node using **libp2p**.
It demonstrates the usage of the gossipsub, ping, and identify protocols to enable communication with other IPFS nodes.
By running this example and exploring its functionality, you can gain insights into how to build more advanced P2P applications using Rust.

Feel free to experiment with different multiaddresses and explore the capabilities of **libp2p** in the context of IPFS. Happy coding!

---

## File: examples/ipfs-kad/README.md

## Description

This example showcases the usage of **libp2p** to interact with the Kademlia protocol on the IPFS network.
The code demonstrates how to: 
 - perform Kademlia queries to find the closest peers to a specific peer ID
 - insert PK records into the Kademlia DHT

By running this example, users can gain a better understanding of how the Kademlia protocol operates and performs operations on the IPFS network.

## Usage

The example code demonstrates how to perform Kademlia queries on the IPFS network using the Rust P2P Library.

### Getting closest peers

By specifying a peer ID as a parameter, the code will search for the closest peers to the given peer ID.

#### Parameters

Run the example code:

```sh
cargo run -- get-peers --peer-id [PEER_ID]
```

Replace `[PEER_ID]` with the base58-encoded peer ID you want to search for.
If no peer ID is provided, a random peer ID will be generated.

#### Example Output

Upon running the example code, you will see the output in the console.
The output will display the result of the Kademlia query, including the closest peers to the specified peer ID.

#### Successful Query Output

If the Kademlia query successfully finds closest peers, the output will be:

```sh
Searching for the closest peers to [PEER_ID]
Query finished with closest peers: [peer1, peer2, peer3]
```

#### Failed Query Output

If the Kademlia query times out or there are no reachable peers, the output will indicate the failure:

```sh
Searching for the closest peers to [PEER_ID]
Query finished with no closest peers.
```

### Inserting PK records into the DHT

By specifying `put-pk-record` as a subcommand, the code will insert the generated public key as a PK record into the DHT.

#### Parameters

Run the example code:

```sh
cargo run -- put-pk-record
```

#### Example Output

Upon running the example code, you will see the output in the console.
The output will display the result of the Kademlia operation.

#### Successful Operation Output

If the Kademlia query successfully finds closest peers, the output will be:

```sh
Putting PK record into the DHT
Successfully inserted the PK record
```

#### Failed Query Output

If the Kademlia operation times out or there are no reachable peers, the output will indicate the failure:

```sh
Putting PK record into the DHT
Failed to insert the PK record
```

## Conclusion

In conclusion, this example provides a practical demonstration of using the Rust P2P Library to interact with the Kademlia protocol on the IPFS network.
By examining the code and running the example, users can gain insights into the inner workings of Kademlia and how it performs various basic actions like getting the closest peers or inserting records into the DHT.
This knowledge can be valuable when developing peer-to-peer applications or understanding decentralized networks.

---

## File: examples/identify/README.md

## Description

The example demonstrates how to create a connection between two nodes using TCP transport, authenticate with the noise protocol, and multiplex data streams with yamux.
The library provides a behavior for identity network interactions, allowing nodes to exchange identification information securely.
By running the example, the nodes will establish a connection, negotiate the identity protocol, and exchange identification information, which will be displayed in the console.

## Usage

1. In the first terminal window, run the following command:
    ```sh
    cargo run
    ```
    This will print the peer ID (`PeerId`) and the listening addresses, e.g., `Listening on "/ip4/127.0.0.1/tcp/24915"`

2. In the second terminal window, start a new instance of the example with the following command:
    ```sh
    cargo run -- /ip4/127.0.0.1/tcp/24915
    ```
    The two nodes establish a connection, negotiate the identity protocol, and send each other identification information, which is then printed to the console.

## Conclusion

The included identity example demonstrates how to establish connections and exchange identification information between nodes using the library's protocols and behaviors.

---

## File: examples/file-sharing/README.md

## Description

The File Sharing example demonstrates a basic file sharing application built using **libp2p**.
This example showcases how to integrate **rust-libp2p** into a larger application while providing a simple file sharing functionality.

In this application, peers in the network can either act as file providers or file retrievers.
Providers advertise the files they have available on a Distributed Hash Table (DHT) using `libp2p-kad`.
Retrievers can locate and retrieve files by their names from any node in the network.

## How it Works

Let's understand the flow of the file sharing process:

- **File Providers**: Nodes A and B serve as file providers.
  Each node offers a specific file: file FA for node A and file FB for node B.
  To make their files available, they advertise themselves as providers on the DHT using `libp2p-kad`.
  This enables other nodes in the network to discover and retrieve their files.

- **File Retrievers**: Node C acts as a file retriever.
  It wants to retrieve either file FA or FB.
  Using `libp2p-kad`, it can locate the providers for these files on the DHT without being directly connected to them.
  Node C connects to the corresponding provider node and requests the file content using `libp2p-request-response`.

- **DHT and Network Connectivity**: The DHT (Distributed Hash Table) plays a crucial role in the file sharing process.
  It allows nodes to store and discover information about file providers.
  Nodes in the network are interconnected via the DHT, enabling efficient file discovery and retrieval.

## Architectural Properties

The File Sharing application has the following architectural properties:

- **Clean and Cloneable Interface**: The application provides a clean and cloneable async/await interface, allowing users to interact with the network layer seamlessly.
  The `Client` module encapsulates the necessary functionality for network communication.

- **Efficient Network Handling**: The application operates with a single task that drives the network layer.
  This design choice ensures efficient network communication without the need for locks or complex synchronization mechanisms.

## Usage

To set up a simple file sharing scenario with a provider and a retriever, follow these steps:

1. **Start a File Provider**: In one terminal, run the following command to start a file provider node:
   ```sh
   cargo run -- --listen-address /ip4/127.0.0.1/tcp/40837 \
             --secret-key-seed 1 \
             provide \
             --path  \
             --name <name-for-others-to-find-your-file>
   ```
   This command initiates a node that listens on the specified address and provides a file located at the specified path.
   The file is identified by the provided name, which allows other nodes to discover and retrieve it.

2. **Start a File Retriever**: In another terminal, run the following command to start a file retriever node:
   ```sh
   cargo run -- --peer /ip4/127.0.0.1/tcp/40837/p2p/12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X \
             get \
             --name <name-for-others-to-find-your-file>
   ```
   This command initiates a node that connects to the specified peer (the provider) and requests the file with the given name.

Note: It is not necessary for the retriever node to be directly connected to the provider.
As long as both nodes are connected to any node in the same DHT network, the file can be successfully retrieved.

This File Sharing example demonstrates the fundamental concepts of building a file sharing application using **libp2p**.
By understanding the flow and architectural properties of this example, you can leverage the power of **libp2p** to integrate peer-to-peer networking capabilities into your own applications.

## Conclusion

The File Sharing example provides a practical implementation of a basic file sharing application using **libp2p**.
By leveraging the capabilities of **libp2p**, such as the DHT and network connectivity protocols, it demonstrates how peers can share files in a decentralized manner.

By exploring and understanding the file sharing process and architectural properties presented in this example, developers can gain insights into building their own file sharing applications using **libp2p**.

## 2. Official Technical Reference & Guides (libp2p/docs)

## File: README.md

- [Overview](#overview)
- [Contributing content](#contributing-content)
- [Running locally](#running-locally)
  - [Prerequisites](#prerequisites)
  - [Installation](#installation)
- [Configuration guide](#configuration-guide)
  - [Static site generator](#static-site-generator)
  - [Automated deployments](#automated-deployments)
  - [Translation](#translation)
- [Primary maintainers](#primary-maintainers)
- [License](#license)


---

## Overview

libp2p is a modular framework that encapsulates an evolving set of specifications for peer-to-peer networking. What started as the networking component that enables IPFS turned into a general-purpose framework to deliver a modular, peer-to-peer networking stack of protocols that are transport agnostic, flexible, reusable, and easy to upgrade.

libp2p enables interoperability between applications, resilient applications, and advanced networking features like decentralized publish-subscribe or advanced data structures like distributed hash tables.

## Contributing content

The documentation site contains several different kinds of content. We’d love ❤️ your help with any of it:

1. **Introductory overviews**: If you spot a problem or have improvements, please post an issue or PR.

2. **Concept guides**: Concept guides are intended to present a brief overview of libp2p-related concepts.
   They strive to answer:

    - **What** is this?
    - How does it **relate** to the rest of libp2p?
    - How can (or should?) you **use** it? (This can often vary by implementation
    - **Where** do you go to learn more?
    - What is the **current state** of affairs?

    See a list of concepts we need help with by [checking the issues](https://github.com/libp2p/docs/issues?utf8=✓&q=is%3Aissue+is%3Aopen+label%3Acontent+concept).

3. **Guides**: Most examples currently live in other repositories, like [js-libp2p examples](https://github.com/libp2p/js-libp2p/tree/master/examples). If you have thoughts on integrating them better, please file an issue. If you have feedback on individual examples or want to add a new one, please file an issue or pull request on the relevant repository. If you have ideas for guides or tutorials, they belong here! Please propose them in an issue here before creating a pull request.

3. **Reference material**: The navbar includes all the reference material available for libp2p. Please see the issues in this repository for current activity around reference/API documentation.

4. **Community**: If there are missing community links, feel free to file an issue or pull request,

This repository is also a website; we could use your help with design and technical features (interactive examples, better syntax highlighting, scripts to pull in content from other repositories, etc.) in addition to writing. To get a sense of what we could use help on, check the [issues](https://github.com/libp2p/docs/issues). If you decide to work on one, please post to the issue to let us know!

Before posting a pull request with your changes, please check [our style guide](https://github.com/ipfs/community/blob/master/DOCS_STYLEGUIDE.md) and [contributing guide](https://github.com/libp2p/community/blob/master/CONTRIBUTE.md).

Finally, let’s work together to keep this a respectful and friendly space. Please make sure to follow our [official code of conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).

## Running locally

### Prerequisites

To run the libp2p documentation site locally, you must have
[NPM installed](https://www.npmjs.com/).
If you already have NPM installed, make sure you are running the latest version:

```shell
npm install npm@latest -g
```

### Installation

Follow these steps to run a copy of this site on your local machine.

1. Clone this repository:

    ```shell
    git clone https://github.com/libp2p/docs
    ```

1. Navigate into the new folder and download the dependencies by running:

    ```shell
    cd docs
    npm install
    ```

2. Build the project and serve the static files to Hugo with:

    ```shell
    npm run build
    ```

3. Start the local Hugo's development server with:

    ```shell
    npm start
    ```

4. Visit [localhost:1313](http://localhost:1313) to view the site.
5. Press `CTRL` + `c` in the terminal to stop the local server.

## Configuration guide

### Static site generator

The libp2p documentation site uses [Hugo](https://gohugo.io/) as a static site generator,
making it easy to serve and host the static files on IPFS. In particular, the site uses
the [Hugo Doks theme](https://github.com/h-enk/doks) to present the libp2p documentation.

### Automated deployments

When opening a pull request, CI scripts will run against your feature branch to test your changes.

The CI/CD production workflow builds on the `master` branch and deploys the documentation site on [fleek](https://fleek.co/). It reflects the latest commit on `master` and publishes at [https://docs.libp2p.io](https://docs.libp2p.io).

### Translation

Please stay tuned for the steps to translate the documentation.

## Primary maintainers

- [@DannyS03](https://github.com/DannyS03): primary contact, project organization & technical writing
- [@mxinden](https://github.com/mxinden): libp2p steward, primarily rust-libp2p
- [@marten-seemann](https://github.com/marten-seemann): libp2p steward, primarily go-libp2p
- [@MarcoPolo](https://github.com/MarcoPolo): libp2p steward, primarily go-libp2p
- [@jennijuju](https://github.com/jennijuju): documentation management
- [@p-shahi](https://github.com/p-shahi): libp2p project management
- [@BigLep](https://github.com/BigLep): interplanetary management and supervision

## License

All software code is copyright (c) Protocol Labs, Inc. under the **MIT/Apache-2 dual license**.
Other written documentation and content are copyright (c) Protocol Labs, Inc. under the
[**Creative Commons Attribution-Share-Alike License**](https://creativecommons.org/licenses/by/4.0/).

---

## File: content/guides/getting-started/_index.md

---
title: "Get Started"
weight: 1
---

---

## File: content/guides/getting-started/go.md

---
title: "Run a go-libp2p node"
weight: 2
aliases:
    - "/tutorials/go"
    - "/guides"
    - "/guides/go"
---

The getting started tutorial covers setting up a development environment, getting familiar
with libp2p basics, and implementing a simple node that can send and receive "ping" messages
in go-libp2p.

The [Protocol Labs Launchpad curriculum](https://curriculum.pl-launchpad.io/) also includes
a tutorial on spinning up a libp2p node using a go-libp2p boilerplate. Check it out
[here](https://pl-launchpad.io/tutorials/libp2p/creating-simple-node/).

This is the first in a series of tutorials on working with libp2p’s Go implementation,
[go-libp2p](https://github.com/libp2p/go-libp2p). We’ll cover installing Go, setting up
a new Go module, starting libp2p nodes, and sending ping messages between them.

### Install Go

- Ensure your Go version is at least 1.20.
- You can install a recent version of Go by following the [official installation instructions](https://golang.org/doc/install).
- Once installed, you should be able to run `go version` and see a version >= 1.20, for example:

```bash
$ go version
go version go1.20 darwin/arm64
```

### Create a Go module

We're going to create a Go module that can be run from the command line.

Let's create a new directory and use `go mod` to initialize it as a module. We'll create it in
`/tmp`, but you can equally create it anywhere on your filesystem. We'll also initialize it with the
module name `github.com/user/go-libp2p-tutorial`, but you may want to replace this with a name that
corresponds to a repository name you have the rights to push to if you want to publish your version
of the code.

```bash
mkdir -p /tmp/go-libp2p-tutorial
cd /tmp/go-libp2p-tutorial
go mod init github.com/user/go-libp2p-tutorial
```

You should now have a `go.mod` file in the current directory containing the name of the module you
initialized and the version of Go you're using, for example:

```bash
$ cat go.mod
module github.com/user/go-libp2p-tutorial

go 1.20
```

### Start a libp2p node

We'll now add some code to our module to start a libp2p node.
Let's start by creating a `main.go` file that simply starts a libp2p node with default settings,
prints the node's listening addresses, then shuts the node down:

```go
package main

import (
    "fmt"
    "github.com/libp2p/go-libp2p"
)

func main() {
    // start a libp2p node with default settings
    node, err := libp2p.New()
    if err != nil {
        panic(err)
    }

    // print the node's listening addresses
    fmt.Println("Listen addresses:", node.Addrs())

    // shut the node down
    if err := node.Close(); err != nil {
        panic(err)
    }
}
```

Import the `libp2p/go-libp2p` module:

```bash
go get github.com/libp2p/go-libp2p
```

We can now compile this into an executable using `go build` and run it from the command line:

```bash
$ go build -o libp2p-node

$ ./libp2p-node
Listen addresses: [/ip6/::1/tcp/57666 /ip4/192.0.2.0/tcp/57665 /ip4/198.51.100.0/tcp/57665]
```

The listening addresses are formatted using the [multiaddr](https://github.com/multiformats/multiaddr)
format, and there is typically more than one printed because go-libp2p will listen on all available
IPv4 and IPv6 network interfaces by default.

#### Configure the node

A node's default settings can be overridden by passing extra arguments to `libp2p.New`. Let's use
`libp2p.ListenAddrStrings` to configure the node to listen on TCP port 2000 on the IPv4 loopback
interface:

```go
func main() {
        ...

        // start a libp2p node that listens on TCP port 2000 on the IPv4
        // loopback interface
        node, err := libp2p.New(
                libp2p.ListenAddrStrings("/ip4/192.0.2.0/tcp/2000"),
        )
    if err != nil {
        panic(err)
    }

        ...
}
```

Re-building and running the executable again now prints the explicit listen address we've configured:

```bash
$ go build -o libp2p-node

$ ./libp2p-node
Listening addresses: [/ip4/192.0.2.0/tcp/2000]
```

`libp2p.New` accepts a variety of arguments to configure most aspects of the node. See
[options.go](https://github.com/libp2p/go-libp2p/blob/master/options.go) for a full list of those
options.

#### Wait for a signal

A node that immediately exits is not all that useful. Let's add the following towards the end of the
`main` function that blocks waiting for an OS signal before shutting down the node:

```go
func main() {
        ...

        // wait for a SIGINT or SIGTERM signal
        ch := make(chan os.Signal, 1)
        signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
        <-ch
        fmt.Println("Received signal, shutting down...")

        // shut the node down
        if err := node.Close(); err != nil {
                panic(err)
        }
}
```

We also need to update the list of imports at the top of the file to include the `os`, `os/signal`
and `syscall` packages we're now using:

```go
import (
    "fmt"
    "os"
    "os/signal"
    "syscall"

    "github.com/libp2p/go-libp2p"
)
```

Running the node now waits until it receives a SIGINT (i.e. a `ctrl-c` key press) or a SIGTERM signal
before shutting down:

```bash
$ ./libp2p-node
Listening addresses: [/ip4/192.0.2.0/tcp/2000]
^CReceived signal, shutting down...
```

### Run the ping protocol

Now that we have the ability to configure and start libp2p nodes, we can start communicating!

#### Set a stream handler

A node started with go-libp2p will run its own ping protocol by default, but let's disable it and
set it up manually to demonstrate the process of running protocols by registering stream handlers.

The object returned from `libp2p.New` implements the [Host interface](https://pkg.go.dev/github.com/libp2p/go-libp2p/core/host#Host),
and we'll use the `SetStreamHandler` method to set a handler for our ping protocol.

First, let's add the `github.com/libp2p/go-libp2p/p2p/protocol/ping` package to our list of
imported packages:

```go
import (
    ...

    "github.com/libp2p/go-libp2p"
    "github.com/libp2p/go-libp2p/p2p/protocol/ping"
)
```

Now we'll pass an argument to `libp2p.New` to disable the built-in ping protocol, and then use the
`PingService` type from the ping package to set a stream handler manually (note that we're also
configuring the node to listen on a random local TCP port rather than a hard coded one, which means
we'll be able to run multiple nodes on the same machine without them trying to listen on the same
port):

```go
func main() {
    ...

    // start a libp2p node that listens on a random local TCP port,
    // but without running the built-in ping protocol
    node, err := libp2p.New(
        libp2p.ListenAddrStrings("/ip4/192.0.2.0/tcp/0"),
        libp2p.Ping(false),
    )
    if err != nil {
        panic(err)
    }

    // configure our own ping protocol
    pingService := &ping.PingService{Host: node}
    node.SetStreamHandler(ping.ID, pingService.PingHandler)

    ...
}
```

#### Connect to a peer

With the ping protocol configured, we need a way to instruct the node to connect to another node and
send it ping messages.

We'll first expand the log message that we've been printing after starting the node to include
its `PeerId` value, as we'll need that to instruct other nodes to connect to it. Let's import the
`github.com/libp2p/go-libp2p/core/peer` package and use it to replace the "Listen addresses" log
message with something that prints both the listen address and the `PeerId` as a multiaddr string:

```go
import (
    ...

    "github.com/libp2p/go-libp2p"
    peerstore "github.com/libp2p/go-libp2p/core/peer"
    "github.com/libp2p/go-libp2p/p2p/protocol/ping"
)

func main() {
    ...

    // print the node's PeerInfo in multiaddr format
    peerInfo := peerstore.AddrInfo{
        ID:    node.ID(),
        Addrs: node.Addrs(),
    }
    addrs, err := peerstore.AddrInfoToP2pAddrs(&peerInfo)
    fmt.Println("libp2p node address:", addrs[0])

    ...
}
```

Running the node now prints the node's address that can be used to connect to it:

```bash
$ ./libp2p-node
libp2p node address: /ip4/192.0.2.0/tcp/62268/ipfs/QmfQzWnLu4UX1cW7upgyuFLyuBXqze7nrPB4qWYqQiTHwt
```

Let's also accept a command line argument that is the address of a peer to send ping messages to,
allowing us to either just run a listening node that waits for a signal, or run a node that connects
to another node and pings it a few times before shutting down (we'll use the `github.com/multiformats/go-multiaddr`
package to parse the peer's address from the command line argument):

```go
import (
    ...

    "github.com/libp2p/go-libp2p"
    peerstore "github.com/libp2p/go-libp2p/core/peer"
    "github.com/libp2p/go-libp2p/p2p/protocol/ping"
    multiaddr "github.com/multiformats/go-multiaddr"
)

func main() {
    ...
    fmt.Println("libp2p node address:", addrs[0])

    // if a remote peer has been passed on the command line, connect to it
    // and send it 5 ping messages, otherwise wait for a signal to stop
    if len(os.Args) > 1 {
        addr, err := multiaddr.NewMultiaddr(os.Args[1])
        if err != nil {
            panic(err)
        }
        peer, err := peerstore.AddrInfoFromP2pAddr(addr)
        if err != nil {
            panic(err)
        }
        if err := node.Connect(context.Background(), *peer); err != nil {
            panic(err)
        }
        fmt.Println("sending 5 ping messages to", addr)
        ch := pingService.Ping(context.Background(), peer.ID)
        for i := 0; i < 5; i++ {
            res := <-ch
            fmt.Println("got ping response!", "RTT:", res.RTT)
        }
    } else {
        // wait for a SIGINT or SIGTERM signal
        ch := make(chan os.Signal, 1)
        signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
        <-ch
        fmt.Println("Received signal, shutting down...")
    }

    // shut the node down
    if err := node.Close(); err != nil {
        panic(err)
    }
}
```

### Let's play ping pong!

We are finally in a position to run two libp2p nodes, have one connect to the other and for
them to run a protocol!

To recap, here is the full program we have written:

```
/* Detailed source-code truncated for AI context efficiency. */
```

In one terminal window, let's start a listening node (i.e. don't pass any command line arguments):

```bash
$ ./libp2p-node
libp2p node address: /ip4/192.0.2.0/tcp/61790/ipfs/QmZKjsGJ6ukXVRXVEcExx9GhiyWoJC97onYpzBwCHPWqpL
```

In another terminal window, let's run a second node but pass the address of the first node, and we
should see some ping responses logged:

```bash
$ ./libp2p-node /ip4/192.0.2.0/tcp/61790/ipfs/QmZKjsGJ6ukXVRXVEcExx9GhiyWoJC97onYpzBwCHPWqpL
libp2p node address: /ip4/192.0.2.0/tcp/61846/ipfs/QmVyKLTLswap3VYbpBATsgNpi6JdwSwsZALPxEnEbEndup
sending 5 ping messages to /ip4/192.0.2.0/tcp/61790/ipfs/QmZKjsGJ6ukXVRXVEcExx9GhiyWoJC97onYpzBwCHPWqpL
pinged /ip4/192.0.2.0/tcp/61790/ipfs/QmZKjsGJ6ukXVRXVEcExx9GhiyWoJC97onYpzBwCHPWqpL in 431.231µs
pinged /ip4/192.0.2.0/tcp/61790/ipfs/QmZKjsGJ6ukXVRXVEcExx9GhiyWoJC97onYpzBwCHPWqpL in 164.94µs
pinged /ip4/192.0.2.0/tcp/61790/ipfs/QmZKjsGJ6ukXVRXVEcExx9GhiyWoJC97onYpzBwCHPWqpL in 220.544µs
pinged /ip4/192.0.2.0/tcp/61790/ipfs/QmZKjsGJ6ukXVRXVEcExx9GhiyWoJC97onYpzBwCHPWqpL in 208.761µs
pinged /ip4/192.0.2.0/tcp/61790/ipfs/QmZKjsGJ6ukXVRXVEcExx9GhiyWoJC97onYpzBwCHPWqpL in 201.37µs
```

Success! Our two peers are now communicating using go-libp2p! Sure, they can only say “ping”, but it’s a start!

---

## File: content/guides/getting-started/javascript.md

---
title: "Run a js-libp2p node"
weight: 3
aliases:
    - "/tutorials/javascript"
    - "/guides"
    - "/guides/javascript"
---

This is the first in a series of tutorials on working with libp2p's javascript implementation,
[js-libp2p](https://github.com/libp2p/js-libp2p).
We will walk you through setting up a fully functional libp2p node with some basic functionality,
and finally we'll send ping messages back and forth between two peers.

### Install node.js

Working with js-libp2p requires [node.js](https://nodejs.org) >= v16 for development. If you haven't already, install
node using whatever package manager you prefer or [using the official installer](https://nodejs.org/en/download/).
We recommend using the latest stable version of node, but anything fairly recent should work fine. If you want to see how low you can go, the current version requirements can always be found at the [js-libp2p project page](https://github.com/libp2p/js-libp2p).

### Create an empty project

We need a place to put our work, so open a terminal to make a new directory for your project somewhere and set it up as an npm project:

```shell
# create a directory for the project and `cd` into it
> mkdir hello-libp2p
> mkdir hello-libp2p/src
> cd hello-libp2p

# make it a git repository
> git init .

# make it an npm project. fill in the prompts with info for your project
# when asked for your project's entry point, enter "src/index.js"
> npm init es6
```

Side note: throughout this tutorial, we use the `>` character to indicate your terminal's shell prompt. When following along, don't type the `>` character, or you'll get some weird errors.

### Configure libp2p

libp2p is a very modular framework, which allows javascript devs to target different runtime environments and opt-in to various features by including a custom selection of modules.

Because every application is different, we recommend configuring your libp2p node with just the modules you need. You can even make more than one configuration, if you want to target multiple javascript runtimes with different features.

> In a production application, it may make sense to create a separate npm module for your libp2p node, which will give you one place to manage the libp2p dependencies for all your javascript projects. In that case, you should not depend on `libp2p` directly in your application. Instead you'd depend on your libp2p configuration module, which would in turn depend on `libp2p` and whatever modules (transports, etc) you might need.

If you're new to libp2p, we recommend configuring your node in stages, as this can make troubleshooting configuration issues much easier. In this tutorial, we'll do just that. If you're more experienced with libp2p, you may wish to jump to the [Configuration readme](https://github.com/libp2p/js-libp2p/blob/master/doc/CONFIGURATION.md).

As an initial step, you should install libp2p module.

```shell
npm install libp2p
```

#### Basic setup

Now that we have libp2p installed, let's configure the minimum needed to get your node running. The only modules libp2p requires are a **Transport** and **Crypto** module. However, we recommend that a basic setup should also have a **Stream Multiplexer** configured, which we will explain shortly. Let's start by setting up a Transport.

#### Transports

Libp2p uses Transports to establish connections between peers over the network. You can configure any number of Transports, but you only need 1 to start with.

You should select Transports according to the runtime of your application; Node.js or the browser. You can see a list of some of the available Transports in the [configuration readme](https://github.com/libp2p/js-libp2p/blob/master/doc/CONFIGURATION.md#transport). For this guide let's install `@libp2p/tcp`.

```sh
npm install @libp2p/tcp
```

Now that we have the module installed, let's configure libp2p to use the Transport. We'll use the `createLibp2p` method, which takes a single configuration object as its only parameter. We can add the Transport by passing it into the `transports` array. Create a `src/index.js` file and have the following code in it:

```js
import { createLibp2p } from 'libp2p'
import { tcp } from '@libp2p/tcp'

const node = await createLibp2p({
  transports: [tcp()]
})

```

You can add as many transports as you like to `transports` in order to establish connections with as many peers as possible.

#### Connection Encryption

Every connection must be encrypted to help ensure security for everyone. As such, Connection Encryption (Crypto) is a required component of libp2p.

There are a growing number of Crypto modules being developed for libp2p. As those are released they will be tracked in the [Connection Encryption section of the configuration readme](https://github.com/libp2p/js-libp2p/blob/master/doc/CONFIGURATION.md#connection-encryption). For now, we are going to configure our node to use the `@chainsafe/libp2p-noise` module.

```sh
npm install @chainsafe/libp2p-noise
```

```js
import { createLibp2p } from 'libp2p'
import { tcp } from '@libp2p/tcp'
import { noise } from '@chainsafe/libp2p-noise'

const node = await createLibp2p({
  transports: [tcp()],
  connectionEncrypters: [noise()]
})

```

#### Multiplexing

While multiplexers are not strictly required, they are highly recommended as they improve the effectiveness and efficiency of connections for the various protocols libp2p runs.

Looking at the [available stream multiplexing](https://github.com/libp2p/js-libp2p/blob/master/doc/CONFIGURATION.md#stream-multiplexing) modules, js-libp2p supports `@chainsafe/libp2p-yamux` and `@libp2p/mplex`, but [mplex](https://docs.libp2p.io/concepts/multiplex/mplex/) is [deprecated](https://github.com/libp2p/specs/issues/553) so we will use [Yamux]([https://github.com/hashicorp/yamux/blob/master/spec.md](https://docs.libp2p.io/concepts/multiplex/yamux/)) here. You can install `@chainsafe/libp2p-yamux` and add it to your libp2p node as follows in the next example.

```sh
npm install @chainsafe/libp2p-yamux
```

```js
import { createLibp2p } from 'libp2p'
import { tcp } from '@libp2p/tcp'
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'

const node = await createLibp2p({
  transports: [tcp()],
  connectionEncrypters: [noise()],
  streamMuxers: [yamux()]
})

```

#### Running libp2p

Now that you have configured a **Transport**, **Crypto** and **Stream Multiplexer** module, you can start your libp2p node. We can start and stop libp2p using the [`libp2p.start()`](https://github.com/libp2p/js-libp2p/blob/master/doc/API.md#start) and [`libp2p.stop()`](https://github.com/libp2p/js-libp2p/blob/master/doc/API.md#stop) methods.

```js
import { createLibp2p } from 'libp2p'
import { tcp } from '@libp2p/tcp'
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'

const main = async () => {
  const node = await createLibp2p({
    addresses: {
      // add a listen address (localhost) to accept TCP connections on a random port
      listen: ['/ip4/127.0.0.1/tcp/0']
    },
    transports: [tcp()],
    connectionEncrypters: [noise()],
    streamMuxers: [yamux()]
  })

  // start libp2p
  await node.start()
  console.log('libp2p has started')

  // print out listening addresses
  console.log('listening on addresses:')
  node.getMultiaddrs().forEach((addr) => {
    console.log(addr.toString())
  })

  // stop libp2p
  await node.stop()
  console.log('libp2p has stopped')
}

main().then().catch(console.error)

```

Try running the code with `node src/index.js`. You should see something like:

```shell
libp2p has started
listening on addresses:
/ip4/192.0.2.0/tcp/50626/p2p/QmYoqzFj5rhzFy7thCPPGbDkDkLMbQzanxCNwefZd3qTkz
libp2p has stopped
```

### Lets play ping pong!

Now that we have the basic building blocks of transport, multiplexing, and security in place, we can start communicating!

We can configure and use [`pingService`](https://libp2p.github.io/js-libp2p/modules/ping.html) to dial and send ping messages to another peer. That peer will send back a "pong" message, so that we know that it is still alive. This also enables us to measure the latency between peers.

We can have our application accepting a peer multiaddress via command line argument and try to ping it. To do so, we'll need to add a couple things. First, require the `process` module so that we can get the command line arguments. Then we'll need to parse the multiaddress from the command line and try to ping it:

```sh
npm install multiaddr @libp2p/ping
```

```javascript
import process from 'node:process'
import { createLibp2p } from 'libp2p'
import { tcp } from '@libp2p/tcp'
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { multiaddr } from 'multiaddr'
import { ping } from '@libp2p/ping'

const node = await createLibp2p({
  addresses: {
    // add a listen address (localhost) to accept TCP connections on a random port
    listen: ['/ip4/127.0.0.1/tcp/0']
  },
  transports: [tcp()],
  connectionEncrypters: [noise()],
  streamMuxers: [yamux()],
  services: {
    ping: ping({
      protocolPrefix: 'ipfs', // default
    }),
  },
})

// start libp2p
await node.start()
console.log('libp2p has started')

// print out listening addresses
console.log('listening on addresses:')
node.getMultiaddrs().forEach((addr) => {
  console.log(addr.toString())
})

// ping peer if received multiaddr
if (process.argv.length >= 3) {
  const ma = multiaddr(process.argv[2])
  console.log(`pinging remote peer at ${process.argv[2]}`)
  const latency = await node.services.ping.ping(ma)
  console.log(`pinged ${process.argv[2]} in ${latency}ms`)
} else {
  console.log('no remote peer address given, skipping ping')
}

const stop = async () => {
  // stop libp2p
  await node.stop()
  console.log('libp2p has stopped')
  process.exit(0)
}

process.on('SIGTERM', stop)
process.on('SIGINT', stop)

```

Now we can start one instance with no arguments:

```shell
> node src/index.js
libp2p has started
listening on addresses:
/ip4/192.0.2.0/tcp/50775/p2p/QmcafwJSsCsnjMo2fyf1doMjin8nrMawfwZiPftBDpahzN
no remote peer address given, skipping ping
```

Grab the `/ip4/...` address printed above and use it as an argument to another instance.  In a new terminal:

```shell
> node src/index.js /ip4/192.0.2.0/tcp/50775/p2p/QmcafwJSsCsnjMo2fyf1doMjin8nrMawfwZiPftBDpahzN
libp2p has started
listening on addresses:
/ip4/192.0.2.0/tcp/50777/p2p/QmYZirEPREz9vSRFznxhQbWNya2LXPz5VCahRCT7caTLGm
pinging remote peer at /ip4/192.0.2.0/tcp/50775/p2p/QmcafwJSsCsnjMo2fyf1doMjin8nrMawfwZiPftBDpahzN
pinged /ip4/192.0.2.0/tcp/50775/p2p/QmcafwJSsCsnjMo2fyf1doMjin8nrMawfwZiPftBDpahzN in 3ms
```

Success! Our two peers are now communicating over a multiplexed, secure channel.  Sure, they can only say "ping", but it's a start!

### What's next?

After finishing this tutorial, you should have a look into the [js-libp2p getting started](https://github.com/libp2p/js-libp2p/blob/master/doc/GETTING_STARTED.md) document, which goes from a base configuration like this one, to more custom ones.

A range of examples are available in the [js-libp2p-examples repo](https://github.com/libp2p/js-libp2p-examples) for you to learn how to use `js-libp2p` for several different use cases and runtimes.

[definition_multiaddress]: /reference/glossary/#multiaddr
[definition_multiplexer]: /reference/glossary/#multiplexer
[definition_peerid]: /reference/glossary/#peerid

---

## File: content/guides/getting-started/nim.md

---
title: "Run a nim-libp2p node"
weight: 5
aliases:
    - "/tutorials/nim"
    - "/guides/nim"
---

Check out [tutorials of the Nim libp2p implementation](https://vacp2p.github.io/nim-libp2p/docs/).

---

## File: content/guides/getting-started/rust.md

---
title: "Run a rust-libp2p node"
weight: 4
aliases:
    - "/tutorials/rust"
    - "/guides"
    - "/guides/rust"
---

Check out [tutorials of the Rust libp2p implementation](https://docs.rs/libp2p/newest/libp2p/tutorials/index.html).

---

## File: content/guides/getting-started/webrtc.md

---
title: "WebRTC with js-libp2p"
weight: 3
aliases:
  - "/tutorials/webrtc-js-libp2p"
  - "/guides/js-libp2p-webrtc"
---

## Introduction

In this guide, you will learn how to establish direct peer-to-peer (p2p) connections between browsers using [js-libp2p](https://github.com/libp2p/js-libp2p) and WebRTC.

Browser-to-browser connectivity is the foundation for distributed apps. When combined with GossipSub, like in the [universal connectivity](https://github.com/libp2p/universal-connectivity) chat app, it gives you the building blocks for peer-to-peer event-based apps with mesh topologies.

By the end of the guide, you will be familiar with the requisite libp2p and WebRTC protocols and concepts and how to use them to establish libp2p connections between browsers. You can find [the associated code for this guide on GitHub](https://github.com/libp2p/libp2p-webrtc-guide).

Since js-libp2p runs both in the browser and Node.js with WebRTC being supported in both, what's covered in this guide also applies to using the WebRTC transport to dial browsers _from_ Node.js.

WebRTC is a set of open standards and Web APIs that enable Web apps to establish direct connectivity for audio/video conferencing and exchanging arbitrary data. Today, WebRTC is [supported by most browsers](https://caniuse.com/?search=webrtc) and powers a lot of popular web conferencing apps.

Both js-libp2p and WebRTC are quite complicated technologies due to the complex nature of peer-to-peer networking, browser standards, and security. In favor of brevity, this guide will skim over some details while linking out to relevant resources.

## Why WebRTC & libp2p

WebRTC and libp2p can be used independently of each other. This begs the question, why use the two together? The **TL;DR is that they complement each other.**

WebRTC's goal is to enable applications to establish direct connections between their users in the browser, i.e. _peer-to-peer "browser-to-browser" connectivity_.

Libp2p gives you the tools to build interoperable cross-platform peer-to-peer applications with mesh topologies that work both on the web and as stand-alone binaries.

Direct connections are especially useful for video and audio calling, because they allow traffic, i.e. the packets, to flow directly from one peer to another without an additional network hop to a server that may be geographically far (network latency is still bound to distances and the speed of light).

However, the reality of public internet networking—given routers, NAT layers, VPNs, and firewalls—is such that p2p connectivity is riddled with challenges. These are commonly overcome by running additional infrastructure such as signaling, [STUN](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Protocols), and [TURN](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Protocols) servers, some of which are standardized as part of WebRTC.

While WebRTC is a solution to peer-to-peer connectivity in the context of browsers. Libp2p encompasses a wider scope with building blocks for constructing peer-to-peer apps that support WebRTC in addition to [other transports, such as QUIC, TCP, WebSocket, WebTransport](https://connectivity.libp2p.io/), and essentially form a mesh topology:



Another benefit of WebRTC and libp2p is that it allows you to dial a js-libp2p peer in the browser from a js-libp2p in Node.js.

The diagram above illustrates a mesh topology with libp2p, whereby each peer is identified by a [Peer ID](https://docs.libp2p.io/concepts/fundamentals/peers/) that is derived from a public key. When you create a new peer libp2p will first create a new public-private key pair, unless you provide one. Each Peer can have multiple addresses depending on the transport protocols it can be dialed with, e.g. WebRTC in the browser, which can also change.

## Peer-to-peer connections: when two aren't enough to tango

Perhaps the most important thing to note about WebRTC and the connection flow is that you need additional server(s) to establish a direct connection between two browsers.
The role of these servers is to assist the two browsers in discovering their public IP address so that they can set up a direct connection.

Specifically, these include:

- **STUN** server: helps the browser discover its observed public address and is necessary in almost all cases, due to NAT making it hard for a browser to know its observed public IP. There are many [free public STUN servers](https://gist.github.com/mondain/b0ec1cf5f60ae726202e) that you can use.
- **TURN** (Relay) server: relays traffic if the browsers fail to establish a direct connection and is defined as part of the WebRTC specification. Unlike signaling and STUN servers, TURN servers can be costly to run because they route all traffic between peers. This guide does not use TURN servers. Instead, it leans on GossipSub to ensure delivery of messages when direct connections cannot be established.
- **Signaling**: helps the browsers exchange [SDP (Session Description Protocol)](https://developer.mozilla.org/en-US/docs/Glossary/SDP) messages: the metadata necessary to establish a connection. Most importantly, signaling is not part of the WebRTC specification. This means that applications are free to implement signaling as they see fit. In this guide, you will use Libp2p's [protocol for signaling](https://github.com/libp2p/specs/blob/master/webrtc/webrtc.md#signaling-protocol) over Circuit Relay v2 connections.
- **Libp2p relay**: The libp2p peer serves two roles:
  - **Circuit Relay V2**: A publicly reachable libp2p peer that can serve as a relay between browser nodes that have yet to establish a direct connection between each other. Unlike TURN servers, which are WebRTC-specific and can be costly to run, Circuit Relay V2 is a libp2p protocol that is resource-constrained by design. It's also decentralized and trustless, in the sense that any publicly reachable libp2p peer supporting the protocol can help browser-based libp2p nodes by serving as a (time and bandwidth-constrained) relay.
  - **PubSub Peer Discovery**: For browser peers to discover each other, they require a mechanism to announce their multiaddresses to other libp2p peers, including browsers. GossipSub is a PubSub implementation that helps by relaying those peer discovery messages between browsers, kicking off the direct connection establishment. Note that this approach to peer discovery is not very scalable and probably not fit for production use cases.

In summary, as part of this guide, you will learn how to run a publicly reachable, long-running libp2p peer that serves as both a circuit relay and a GossipSub message relay. This guide refer to that libp2p peer as the **"relay"** or **"bootstrapper"** peer depending on the context.

## Connection flow diagram

The following diagrams visualize the connection flow between two browsers using js-libp2p and WebRTC.

The first diagram illustrates the peer discovery and establishment of a relayed connection between the two browsers:



The second diagram, which continues from the first, illustrates the SDP handshake via the Circuit Relay:



The connection flow seems complex, but thankfully, libp2p abstracts away some of that complexity and the rest is explained in this guide.

Either way, there are several noteworthy things about the connection flow:

1. There's no prescribed mechanism in libp2p for how the two peers discover each other's multiaddress; this is also known as **"peer discovery"**. This guide uses a [dedicated GossipSub channel for the application where you publish your multiaddrs (periodically) similar to mdns](https://github.com/libp2p/js-libp2p-pubsub-peer-discovery/). PubSub peer discovery works well for demos and guides, but its current design is not battle-tested for production use cases at scale.
2. Other approaches to Peer routing and discovery include [DHT FIND_NODE query](https://github.com/libp2p/specs/blob/master/kad-dht/README.md#dht-operations), [HTTP Delegated Routing](https://specs.ipfs.tech/routing/http-routing-v1/), and [GossipSub Peer Exchange](https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md), though browser peers don't tend to be long-lived enough to appear in the results of the first two.
3. Since this guide uses a GossipSub channel for peer discovery, the relay node listens to the discovery topic too so that it relays messages between browsers who've yet to establish a direct connection.

## Prerequisites

- [Node.js](https://nodejs.org/en) installed to build the frontend and to run the relay
- Chrome or Firefox, for WebTransport connectivity to the relay ([Safari does not support WebTransport](https://caniuse.com/webtransport))

This guide assumes a basic understanding of libp2p concepts such as:

- [Peer ID]({{< relref "/concepts/fundamentals/peers#peer-id" >}})
- [Multiaddresses (often abbreviated multiaddr)]({{< relref "/concepts/fundamentals/addressing" >}})
- [Libp2p transports]({{< relref "/concepts/transports/overview" >}})
- [GossipSub]({{< relref "/concepts/pubsub/overview" >}})

Besides that, most of this guide focuses on js-libp2p, i.e. JavaScript.

## Step 1: Clone the repository and install dependencies

Clone the repository:

```bash
git clone https://github.com/libp2p/libp2p-webrtc-guide
```

Once the repository is cloned, enter the `libp2p-webrtc-guide` folder, and install the npm dependencies

```bash
cd libp2p-webrtc-guide
npm install
```

## Step 2: Start the js-libp2p node.js relay

In this step, you start the node.js relay.

Run the following command:

```bash
npm run start:relay
```

It also outputs the PeerID and the multiaddrs it's listening on and should look similar to:

```bash
PeerID:  12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ
Multiaddrs:  [
  Multiaddr(/ip4/127.0.0.1/tcp/9001/ws/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ),
  Multiaddr(/ip4/192.168.3.174/tcp/9001/ws/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ),
  Multiaddr(/ip4/127.0.0.1/tcp/9002/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ),
  Multiaddr(/ip4/192.168.3.174/tcp/9002/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ)
]
```

## Step 3: Start js-libp2p in the browser

In this step, you start the js-libp2p peer in the browser/

In a new terminal window, open the repository cloned in the previous step:

```bash
cd libp2p-webrtc-guide
```

Run the following command to start the frontend development server:

```bash
npm run start
```

The output contains the address of the local development server:

```bash
 > Local:   http://127.0.0.1:8000/
```

Next, open the `src/index.js` file in your code editor and find the call to `createLibp2p`:

```js
const libp2p = await createLibp2p({
  transports: [
    webSockets(),
    webTransport(),
    webRTC(),
  ],
  connectionEncrypters: [noise()],
  streamMuxers: [yamux()],
  connectionGater: {
    // Allow private addresses for local testing
    denyDialMultiaddr: async () => false,
  },
  services: {
    identify: identify(),
  },
});
```

The `createLibp2p` invocation creates a libp2p peer which has its associated key pair and [Peer ID]({{< relref "/concepts/fundamentals/peers#peer-id" >}}) with support for the WebSocket , WebTransport and WebRTC transports, as well as the [identify protocol]({{< relref "/concepts/fundamentals/protocols#identify" >}}). It also uses noise to ensure all connections are encrypted, and yamux as the stream multiplexer for the relayed connection.

{{< alert icon="💡" context="note">}}
**Why is yamux needed?**

You may notice that the above js-libp2p configuration adds yamux as the stream multiplexer. While both WebRTC and WebTransport come with native [stream multiplexing]({{< relref "/concepts/multiplex/overview" >}}), yamux is still required for WebSockets to multiplex streams on the circuit relay connection.



When a browser initiates the connection to another browser over a circuit relay, the underlying WebSocket stream to the relay is multiplexed by yamux and encrypted by Noise. In the case of WebTransport it is multiplexed and encrypted natively. Either way, the relayed connection between the two browsers must be encrypted by noise otherwise the relay could eavesdrop on the traffic. Once the relayed connection between the browsers is encrypted, it also requires yamux to create a stream for the signaling protocol.

{{< /alert >}}

This is the minimal configuration needed to establish a connection to the local
relay.

Finally, open `http://127.0.0.1:8000/` in your browser and you will see your Peer ID. This Peer ID is created automatically and persists in memory. Reloading the page results in a new PeerID

## Step 4: Connect to the relay from the browser

In this step, you connect the browser js-libp2p peer to the node.js relay peer.

Open the frontend in your browser (or use the one open from the previous step) and enter the loopback WebSocket multiaddr of the relay, i.e. `/ip4/127.0.0.1/tcp/9001/ws/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ`



Now click Connect and the peer should appear in the peer List:



Congratulations, you have now established a WebSocket connection to the relay.

{{< alert icon="💡" context="info">}}
In a production application that is deployed and served with TLS, the relay peer needs a stable hostname and a TLS certificate due to [Secure Contexts](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts). This requires you to use a reverse proxy, e.g. Nginx or Caddy, to handle [TLS termination](https://en.wikipedia.org/wiki/TLS_termination_proxy).
{{< /alert >}}

## Step 5: Make the browser dialable with Circuit Relay

In this step, you enable the circuit relay transport to make the browser dialable via the relay peer (that is already configured as a circuit relay server).

In the `src/index.js` file, update the call to `createLibp2p` as follows:

```diff
+import { circuitRelayTransport } from '@libp2p/circuit-relay-v2'

const libp2p = await createLibp2p({
+  addresses: {
+    listen: [
+      // 👇 Required to create circuit relay reservations in order to respond to incoming WebRTC connections
+      '/p2p-circuit',
+    ],
+  },
  transports: [
    webSockets(),
    webTransport(),
    webRTC(),
+    circuitRelayTransport(),
  ],
  connectionEncrypters: [noise()],
  streamMuxers: [yamux()],
  connectionGater: {
    // Allow private addresses for local testing
    denyDialMultiaddr: async () => false,
  },
  services: {
    identify: identify(),
  },
})
```

If you reload the page and connect to the relay multiaddr (by copying the multiaddr of the relay from the terminal) notice that the browser peer now shows (depending on your network setup) four multiaddrs addresses (or two if you don't have a private network IP) that look as follows:

```bash
/ip4/127.0.0.1/tcp/9001/ws/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ/p2p-circuit/p2p/12D3KooWQny42bDJfqPoBfpd9qNw2HrqtUTStUmCgBktnDXhisW7
/ip4/192.168.3.174/tcp/9001/ws/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ/p2p-circuit/p2p/12D3KooWQny42bDJfqPoBfpd9qNw2HrqtUTStUmCgBktnDXhisW7
/ip4/127.0.0.1/tcp/9002/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ/p2p-circuit/p2p/12D3KooWQny42bDJfqPoBfpd9qNw2HrqtUTStUmCgBktnDXhisW7
/ip4/192.168.3.174/tcp/9002/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ/p2p-circuit/p2p/12D3KooWQny42bDJfqPoBfpd9qNw2HrqtUTStUmCgBktnDXhisW7
```

For each network interface the relay binds to, there are two addresses: **one TCP multiaddr and one WebSocket (denoted by `ws` in the multiaddr).** This means that the browser is now dialable via both the localhost, private network over two transports: WebSockets and TCP.

Observe that the beginning of the multiaddr is the same as the relay, followed by `/p2p-circuit/p2p/BROWSER_PEER_ID`. This multiaddr can be used by other browser peers (capable of WebTransport) to connect to the first browser window using the relay:



By adding a `circuitRelayTransport` and configuring a `/p2p-circuit` listen address, js-libp2p was able to create circuit relay reservation (time and bandwidth-constrained) on the relay.

### Testing circuit relay

To test dialing the browser with circuit relay:

1. Copy the local WebSocket multiaddr (`127.0.0.1` with `ws`) relay address from the browser tab.
2. Open a second browser tab, paste the multiaddr and click **Connect**.

The second browser tab should connect to two peers, i.e. the relay and the browser. You should also see two Peer IDs appear in the list of peers.

## Step 6: Set the relay in the browser app as a bootstrap peer

In this step you configure js-libp2p to automatically connect to the relay peer. In libp2p, peers that you automatically connect to are commonly bootstrap peers, hence the name of the module.

Update the `src/index.js` file as follows, making sure to replace the multiaddr with the one from your relay:

```diff
+import { bootstrap } from '@libp2p/bootstrap'

const libp2p = await createLibp2p({
  addresses: {
    listen: [
      '/p2p-circuit',
    ],
  },
  transports: [
    webSockets(),
    webTransport(),
    webRTC(),
    circuitRelayTransport(),
  ],
  connectionEncrypters: [noise()],
  streamMuxers: [yamux()],
  connectionGater: {
    // Allow private addresses for local testing
    denyDialMultiaddr: async () => false,
  },
+  peerDiscovery: [
+      bootstrap({
+        // replace with your relay multiaddr
+        list: ['/ip4/127.0.0.1/tcp/9001/ws/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ'],
+      }),
+  ]
  services: {
    identify: identify(),
  },
})
```

Reload the page, and the peer automatically reconnects to the relay.

## Step 7: Listen on WebRTC and establish a direct connection

In this step, the js-libp2p configuration is updated to listen for WebRTC connections.

In the `src/index.js` file, update the call to `createLibp2p` as follows:

```diff
const libp2p = await createLibp2p({
  addresses: {
    listen: [
      '/p2p-circuit',
+      // 👇 Listen for webRTC connections
+      '/webrtc',
    ],
  },
  transports: [
    webSockets(),
    webTransport(),
    webRTC(),
    circuitRelayTransport(),
  ],
  connectionEncrypters: [noise()],
  streamMuxers: [yamux()],
  connectionGater: {
    // Allow private addresses for local testing
    denyDialMultiaddr: async () => false,
  },
  peerDiscovery: [
      bootstrap({
        // replace with your relay multiaddr
        list: ['/ip4/127.0.0.1/tcp/9001/ws/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ'],
      }),
  ]
  services: {
    identify: identify(),
  },
})
```

With the change above, libp2p leverages circuit relays as the signalling channel for WebRTC connections.

Reload the frontend, and once again connect to the relay by copying its `ws` multiaddr from the terminal.

After connecting to the relay, the frontend renders four new multiaddrs that look like:

```bash
/ip4/127.0.0.1/tcp/9001/ws/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ/p2p-circuit/webrtc/p2p/12D3KooWQny42bDJfqPoBfpd9qNw2HrqtUTStUmCgBktnDXhisW7
/ip4/192.168.3.174/tcp/9001/ws/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ/p2p-circuit/webrtc/p2p/12D3KooWQny42bDJfqPoBfpd9qNw2HrqtUTStUmCgBktnDXhisW7
/ip4/127.0.0.1/tcp/9002/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ/p2p-circuit/webrtc/p2p/12D3KooWQny42bDJfqPoBfpd9qNw2HrqtUTStUmCgBktnDXhisW7
/ip4/192.168.3.174/tcp/9002/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ/p2p-circuit/webrtc/p2p/12D3KooWQny42bDJfqPoBfpd9qNw2HrqtUTStUmCgBktnDXhisW7
```

These new multiaddrs all contain `/webrtc/` meaning they are intended for establishing a direct WebRTC connection between two browsers. The first two are relevant for the browser, since they are WebSocket multiaddrs.

Copy the first multiaddr that contains: `.../ws/p2p/RELAY_PEER_ID/p2p-circuit/webrtc/p2p/BROWSER_PEER_ID`, open another browser window, and paste the multiaddr into the input, and click Connect.

Once the connection succeeds, the WebRTC connection count in both browsers is **1** and both browsers are connected to the relay as well as the other browser Peer ID:



Congratulations! You have successfully established a direct connection between two browsers.

Exchanging multiaddrs manually is cumbersome. To avoid this, let's introduce PubSub-based peer discovery in the next step.

## Step 8: PubSub peer discovery

In the previous steps, you worked through the process of establishing a WebRTC connection by manually copying the multiaddrs.

In this step, PubSub peer discovery is introduced so the browsers can exchange their multiaddrs and discover each other automatically (with the help of the relay).

In libp2p, PubSub is implemented with the [GossipSub protocol]({{< relref "/concepts/pubsub/overview" >}}), which provides an efficient way for mesh networks to exchange messages.

For PubSub peer discovery to work, both frontend and the relay must use the same topic. As soon as the frontend discovers its own multiaddrs, it publishes it in a message to the discovery topic. The relay, which is also listening to the discovery topic, gossips the message to other browser peers connected to it, which in turn, establish direct WebRTC connections. From a high level, it looks as follows:



In the `src/index.js` file, update the call to `createLibp2p` as follows:

```diff

+import { gossipsub } from '@chainsafe/libp2p-gossipsub'
+import { pubsubPeerDiscovery } from '@libp2p/pubsub-peer-discovery'
+import { PUBSUB_PEER_DISCOVERY } from './constants.js'

const libp2p = await createLibp2p({
  addresses: {
    listen: [
      '/p2p-circuit',
      '/webrtc',
    ],
  },
  transports: [
    webSockets(),
    webTransport(),
    webRTC(),
    circuitRelayTransport(),
  ],
  connectionEncrypters: [noise()],
  streamMuxers: [yamux()],
  connectionGater: {
    // Allow private addresses for local testing
    denyDialMultiaddr: async () => false,
  },
  peerDiscovery: [
      bootstrap({
        // replace with your relay multiaddr
        list: ['/ip4/127.0.0.1/tcp/9001/ws/p2p/12D3KooWQtCgYCZ7JZQoe7Ao6KP5CDMnmEiURqMoarfBgJwbnCPQ'],
      }),
+      pubsubPeerDiscovery({
+        // Every 10 seconds publish our multiaddrs
+        interval: 10_000,
+        // The topic that the relay is also subscribed to
+        topics: [PUBSUB_PEER_DISCOVERY],
+      }),
  ],
  services: {
+    pubsub: gossipsub(),
    identify: identify(),
  },
})

+libp2p.addEventListener('peer:discovery', async (evt) => {
+  // Encapsulate the peer ID to ensure dialing succeeds
+  // Should be removed once https://github.com/libp2p/js-libp2p/issues/3239 is resolved.
+  const maddrs = evt.detail.multiaddrs.map((ma) => ma.encapsulate(`/p2p/${evt.detail.id.toString()}`))
+  console.log(
+    `Discovered new peer (${evt.detail.id.toString()}). Dialling:`, maddrs.map((ma) => ma.toString()),
+  )
+  try {
+    await libp2p.dial(maddrs)
+  } catch (err) {
+    console.error(`Failed to dial peer (${evt.detail.id.toString()}):`, err)
+  }
+})
```

A couple of note-worthy things about these changes:

- The `pubsub` service adds GossipSub protocol capabilities to the node.
- `pubsubPeerDiscovery` depends on the `pubsub` service and introduces the peer discovery mechanism. [GossipSub is a large dependency](https://packagephobia.com/result?p=%40chainsafe%2Flibp2p-gossipsub) making it suboptimal for browser bundles.
- When js-libp2p discovers a new peer (and its multiaddrs) it emits a `peer:discovery` event.
- To dial a newly discovered peer, add an event listener for the `peer:discovery` event and dial the peer with the `dial` method.
- PubSub peer discovery works well for demos and guides, but its current design is not battle-tested for production use cases.

Next, open two browser tabs of the frontend, and you should see them connected to each other within a couple of seconds 🎉.

## Summary

If you have reached this far in the guide, well done! You learned how to establish browser-to-browser connectivity with libp2p and WebRTC and how libp2p abstracts aspects of WebRTC like signaling and SDP exchange. You also learned about js-libp2p's configuration options and concepts such as Peer IDs, Multiaddrs, and GossipSub.

## Final notes

### NAT hole punching

Peer-to-peer connectivity is inherently hard, which is why in this guide, all connections were on a local machine which significantly increases connection success rates.

On public networks where both browser peers are behind NAT, NAT hole punching success rates range around 80% depending on the network conditions and the [types of NAT the peers are behind](https://tailscale.com/blog/how-nat-traversal-works#the-nature-of-nats). The implications of this depend on the nature of your app. PubSub with GossipSub is designed to ensure the delivery of messages without requiring a connection to the whole mesh. In other words, the GossipSub protocol is designed with sparsely-connected networks, where you are not connected to all other peers. So long as the browser peer can publish a message to at least one other peer, the message propagates to all subscribers.

Another approach is to introduce a TURN server, however, TURN servers tend to be complex to run, bandwidth-heavy, and prone to abuse, since they relay all traffic.

If you want to experiment with this example over public networks, the relay peer must be publicly reachable, i.e. have a public IP that is dialable by browser peers.

### Differences between js-libp2p in Node.js and browser

Connectivity between the browser and relay is constrained by supported transports of the browser and the specific libp2p implementation.

At the time of writing, **js-libp2p in browsers** supports:

- WebSocket: this works well and is broadly adopted by libp2p implementations, but requires the relay to have CA-signed TLS certificate and a domain name to work in [Secure Contexts](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts). Another disadvantage of Secure WebSocket is that it results in double encryption (TLS and Noise) with libp2p.
- WebTransport: Supported by [Chrome, Firefox, Opera, and Edge](https://caniuse.com/webtransport), but not Safari.
- WebRTC: Supported by most browsers
- [WebRTC-direct](https://github.com/libp2p/js-libp2p/tree/main/packages/transport-webrtc#webrtc-vs-webrtc-direct): Supported by all browsers that support WebRTC.

While **js-libp2p in Node.js** supports:

1. WebRTC: this one is rather confusing because [unlike](https://github.com/libp2p/js-libp2p/tree/main/packages/transport-webrtc#webrtc-vs-webrtc-direct) [WebRTC direct](https://github.com/libp2p/specs/blob/master/webrtc/webrtc-direct.md), it requires an additional circuit relay peer to forward SDP messages between the browser and the Node.js relay, making it infeasible for the Node.js peer to be the relay. WebRTC-direct solves this problem, however, at the time of writing it isn't supported by js-libp2p (See [tracking issue](https://github.com/libp2p/js-libp2p/issues/2581)).
2. WebSocket: as mentioned above, requires a CA-signed TLS certificate and a domain.
3. TCP: not available in browsers.

Therefore, until WebRTC-Direct or WebTransport support is added to js-libp2p in Node.js, it's much easier to use go-libp2p.

## Next steps

As a next step, the [universal connectivity app](https://github.com/libp2p/universal-connectivity) can be a great learning resource, as it expands on many of the concepts and patterns implemented by this guide, in addition to having two bootstrapper implementations in Rust and Go.

### Try the go-libp2p relay with WebTransport

Go into the `go-relay` directory and install dependencies

```bash
cd go-relay
go get .
```

From the `go-relay` folder, run the following command to compile and run the relay:

```bash
go run .
```

This compiles and runs the relay. It also outputs the PeerID and the multiaddrs it's listening on. The output looks similar to:

```bash
2024/05/21 17:43:43 PeerID: 12D3KooWMEZEwzATAoXFbPmb1kgD7p4Ue3jzHGQ8ti2UrsFg11YJ
2024/05/21 17:43:43 Listening on: /ip4/127.0.0.1/udp/9095/quic-v1/p2p/12D3KooWMEZEwzATAoXFbPmb1kgD7p4Ue3jzHGQ8ti2UrsFg11YJ
2024/05/21 17:43:43 Listening on: /ip4/127.0.0.1/udp/9095/quic-v1/webtransport/certhash/uEiAbhhQxJeJ6nAWdpB6NdSV4UPaTwEcy9eA76p22SoKyvg/certhash/uEiBTPUrn6BebjshxC80Uarqi4ZsMhrPPQNu2RDu1N4n_Ww/p2p/12D3KooWMEZEwzATAoXFbPmb1kgD7p4Ue3jzHGQ8ti2UrsFg11YJ
2024/05/21 17:43:43 Listening on: /ip4/192.168.3.174/udp/9095/quic-v1/p2p/12D3KooWMEZEwzATAoXFbPmb1kgD7p4Ue3jzHGQ8ti2UrsFg11YJ
2024/05/21 17:43:43 Listening on: /ip4/192.168.3.174/udp/9095/quic-v1/webtransport/certhash/uEiAbhhQxJeJ6nAWdpB6NdSV4UPaTwEcy9eA76p22SoKyvg/certhash/uEiBTPUrn6BebjshxC80Uarqi4ZsMhrPPQNu2RDu1N4n_Ww/p2p/12D3KooWMEZEwzATAoXFbPmb1kgD7p4Ue3jzHGQ8ti2UrsFg11YJ
```

Note that it's listening on two interfaces (the loopback and the private network) and two transports: QUIC and WebTransport (which is on top of QUIC). QUIC can be used for connections to other go-libp2p relays, while WebTransport for connections from browsers. That means that QUIC isn't strictly necessary, but it's useful if you deploy another relay for resilience or leverage the DHT for peer discovery.

#### Ephemeral WebTransport multiaddr

Another thing worth noting is that the WebTransport multiaddr contains two certificate hashes. These are needed by the browser to verify a self-signed certificate of the go-relay peer. Unlike CA-signed certificates, self-signed certificates can be created on the fly without interaction with a certificate authority.

So why two certificate hashes? Self-signed certificates are valid for at most 14 days. So by convention, go-libp2p generates two consecutively valid certificates to ensure a smooth transition when a new certificate is rolled out.

Another challenge you may face is that the WebTransport multiaddr that is hardcoded into the js-libp2p configuration is ephemeral and valid for around 28 days (2 certificate hashes valid for 14 days each). One way to address this is using the DHT to resolve the Peer ID (which is stable and would be hard coded in the frontend) to its latest multiaddrs as done by the [universal connectivity app](https://github.com/libp2p/universal-connectivity).

---

## File: content/concepts/transports/_index.md

---
title : "Transports"
weight: 3
---

---

## File: content/concepts/transports/listen-and-dial.md

---
title: "Listening and Dialing"
weight: 80
aliases:
    - "/concepts/transports/listen-and-dial"
---

## Common transport interfaces

Transports are defined in terms of two core operations, **listening** and
**dialing**.

Listening means that you can accept incoming connections from other peers,
using whatever facility is provided by the
transport implementation. For example, a TCP transport on a unix platform could
use the `bind` and `listen` system calls to have the operating system route
traffic on a given TCP port to the application.

Dialing is the process of opening an outgoing connection to a listening peer.
Like listening, the specifics are determined by the implementation, but every
transport in a libp2p implementation will share the same programmatic interface.

## Addresses

Before you can dial up a peer and open a connection, you need to know how to
reach them. Because each transport will likely require its own address scheme,
libp2p uses a convention called a "multiaddress" or `multiaddr` to encode
many different addressing schemes.

The [addressing doc]({{< relref "/concepts/fundamentals/addressing.md" >}}) goes into more detail, but an overview
of how multiaddresses work is helpful for understanding the dial and listen
interfaces.

Here's an example of a multiaddr for a TCP/IP transport:

```shell
/ip4/198.51.100.0/tcp/6543
```

This is equivalent to the more familiar `198.51.100.0:6543` construction, but it
has the advantage of being explicit about the protocols that are being
described. With the multiaddr, you can see at a glance that the `198.51.100.0`
address belongs to the IPv4 protocol, and the `6543` belongs to TCP.

For more complex examples, see [addressing]({{< relref "/concepts/fundamentals/addressing.md" >}}).

Both dial and listen deal with multiaddresses. When listening, you give the
transport the address you'd like to listen on, and when dialing you provide the
address to dial to.

When dialing a remote peer, the multiaddress should include the
[PeerId]({{< relref "/concepts/fundamentals/peers.md#peer-id" >}}) of the peer you're trying to reach.
This lets libp2p establish a [secure communication channel]({{< relref "/concepts/secure-comm/overview.md" >}})
and prevents impersonation.

An example multiaddress that includes a `PeerId`:

```shell
/ip4/192.0.2.0/tcp/4321/p2p/QmcEPrat8ShnCph8WjkREzt5CPXF2RwhYxYBALDcLC1iV6
```

The `/p2p/QmcEPrat8ShnCph8WjkREzt5CPXF2RwhYxYBALDcLC1iV6` component uniquely
identifies the remote peer using the hash of its public key.
For more, see the [peer identity content]({{< relref "/concepts/fundamentals/peers.md#peer-id" >}}).

{{< alert icon="💡" context="tip">}}
When peer routing is enabled, you can dial peers using just their PeerId,
without needing to know their transport addresses before hand.
{{< /alert >}}

## Supporting multiple transports

libp2p applications often need to support multiple transports at once. For
example, you might want your services to be usable from long-running daemon
processes via TCP, while also accepting websocket connections from peers running
in a web browser.

The libp2p component responsible for managing the transports is called the
[switch][definition_switch], which also coordinates
[protocol negotiation]({{< relref "/concepts/fundamentals/protocols.md#protocol-negotiation" >}}),
[stream multiplexing]({{< relref "/concepts/multiplex/overview.md" >}}),
[establishing secure communication]({{< relref "/concepts/secure-comm/overview.md" >}}) and other forms of
"connection upgrading".

The switch provides a single "entry point" for dialing and listening, and frees
up your application code from having to worry about the specific transports
and other pieces of the "connection stack" that are used under the hood.

{{< alert icon="💡" context="note" text="The term \"swarm\" was previously used to refer to what is now called the \"switch\", and some places in the codebase still use the \"swarm\" terminology." />}}

[definition_switch]: {{< relref "/concepts/appendix/glossary#switch" >}}