{"id":20388220,"url":"https://github.com/libp2p/js-libp2p-example-circuit-relay","last_synced_at":"2025-04-12T10:36:16.615Z","repository":{"id":203526718,"uuid":"709799720","full_name":"libp2p/js-libp2p-example-circuit-relay","owner":"libp2p","description":"How to use Circuit Relay to connect two nodes","archived":false,"fork":false,"pushed_at":"2025-02-23T13:52:30.000Z","size":17,"stargazers_count":5,"open_issues_count":1,"forks_count":3,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-08T18:51:49.196Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/libp2p.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-25T12:27:47.000Z","updated_at":"2025-03-03T04:03:48.000Z","dependencies_parsed_at":"2025-02-17T09:27:46.480Z","dependency_job_id":"689eb1f1-51ef-447a-9390-4952dd4ee8b7","html_url":"https://github.com/libp2p/js-libp2p-example-circuit-relay","commit_stats":null,"previous_names":["libp2p/js-libp2p-example-circuit-relay"],"tags_count":0,"template":false,"template_full_name":"libp2p/js-libp2p-example-fork-go-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libp2p%2Fjs-libp2p-example-circuit-relay","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libp2p%2Fjs-libp2p-example-circuit-relay/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libp2p%2Fjs-libp2p-example-circuit-relay/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libp2p%2Fjs-libp2p-example-circuit-relay/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/libp2p","download_url":"https://codeload.github.com/libp2p/js-libp2p-example-circuit-relay/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248553778,"owners_count":21123517,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T03:08:05.513Z","updated_at":"2025-04-12T10:36:16.591Z","avatar_url":"https://github.com/libp2p.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @libp2p/example-circuit-relay \u003c!-- omit in toc --\u003e\n\n[![libp2p.io](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/)\n[![Discuss](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg?style=flat-square)](https://discuss.libp2p.io)\n[![codecov](https://img.shields.io/codecov/c/github/libp2p/js-libp2p-examples.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p-examples)\n[![CI](https://img.shields.io/github/actions/workflow/status/libp2p/js-libp2p-examples/ci.yml?branch=main\\\u0026style=flat-square)](https://github.com/libp2p/js-libp2p-examples/actions/workflows/ci.yml?query=branch%3Amain)\n\n\u003e Shows how to configure relayed connections\n\n## Table of contents \u003c!-- omit in toc --\u003e\n\n- [0. Setup the example](#0-setup-the-example)\n- [1. Set up a relay node](#1-set-up-a-relay-node)\n- [2. Set up a listener node with a circuit relay address](#2-set-up-a-listener-node-with-a-circuit-relay-address)\n- [3. Set up a dialer node for testing connectivity](#3-set-up-a-dialer-node-for-testing-connectivity)\n- [4. What is next?](#4-what-is-next)\n- [Need help?](#need-help)\n- [License](#license)\n- [Contribution](#contribution)\n\n## 0. Setup the example\n\nFirst of all run `npm install` in the example folder. This will install all\nrequired dependencies and you'll be ready to go.\n\nThis example comes with 3 main files. A `relay.js` file to be used in the first\nstep, a `listener.js` file to be used in the second step and a `dialer.js` file\nto be used on the third step. All of these scripts will run their own libp2p\nnode, which will interact with the previous ones. All nodes must be running in\norder for you to proceed.\n\n## 1. Set up a relay node\n\nIn the first step of this example, we need to configure and run a relay node in\norder for our target node to bind to for accepting inbound connections.\n\nThe relay node will need to have a relay service added which will allow a\nlimited number of remote peers to make relay reservations with it.\n\nIt can be configured as follows:\n\n```js\nimport { noise } from '@chainsafe/libp2p-noise'\nimport { yamux } from '@chainsafe/libp2p-yamux'\nimport { circuitRelayServer } from '@libp2p/circuit-relay-v2'\nimport { identify } from '@libp2p/identify'\nimport { webSockets } from '@libp2p/websockets'\nimport { createLibp2p } from 'libp2p'\n\nconst node = await createLibp2p({\n  addresses: {\n    listen: ['/ip4/0.0.0.0/tcp/0/ws']\n    // TODO check \"What is next?\" section\n  },\n  transports: [\n    webSockets()\n  ],\n  connectionEncrypters: [\n    noise()\n  ],\n  streamMuxers: [\n    yamux()\n  ],\n  services: {\n    identify: identify(),\n    relay: circuitRelayServer()\n  }\n})\n\nconsole.log(`Node started with id ${node.peerId.toString()}`)\nconsole.log('Listening on:')\nnode.getMultiaddrs().forEach((ma) =\u003e console.log(ma.toString()))\n```\n\nYou should now run the following to start the relay node:\n\n```sh\nnode relay.js\n```\n\nThis should print out something similar to the following:\n\n```sh\nNode started with id QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3\nListening on:\n/ip4/127.0.0.1/tcp/61592/ws/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3\n/ip4/192.168.1.120/tcp/61592/ws/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3\n```\n\n## 2. Set up a listener node with a circuit relay address\n\nOne of the typical use cases for Circuit Relay is nodes behind a NAT or browser\nnodes due to their inability to expose a public address.\n\nFor running a libp2p node that automatically discovers available relays, you can\nsee the following:\n\n```js\nimport { noise } from '@chainsafe/libp2p-noise'\nimport { yamux } from '@chainsafe/libp2p-yamux'\nimport { circuitRelayTransport } from '@libp2p/circuit-relay-v2'\nimport { identify } from '@libp2p/identify'\nimport { webSockets } from '@libp2p/websockets'\nimport { multiaddr } from '@multiformats/multiaddr'\nimport { createLibp2p } from 'libp2p'\n\nconst relayAddr = process.argv[2]\nif (!relayAddr) {\n  throw new Error('the relay address needs to be specified as a parameter')\n}\n\nconst node = await createLibp2p({\n  addresses: {\n    listen: [\n      '/p2p-circuit'\n    ]\n  },\n  transports: [\n    webSockets(),\n    circuitRelayTransport()\n  ],\n  connectionEncrypters: [\n    noise()\n  ],\n  streamMuxers: [\n    yamux()\n  ],\n  services: {\n    identify: identify()\n  }\n})\n\nconsole.log(`Node started with id ${node.peerId.toString()}`)\n\nconst conn = await node.dial(relayAddr)\n\nconsole.log(`Connected to the relay ${conn.remotePeer.toString()}`)\n\n// Wait for connection and relay to be bind for the example purpose\nnode.addEventListener('self:peer:update', (evt) =\u003e {\n  // Updated self multiaddrs?\n  console.log(`Advertising with a relay address of ${node.getMultiaddrs()[0].toString()}`)\n})\n```\n\nAs you can see in the code, we need to provide the relay address, `relayAddr`,\nas a process argument. This node will dial the provided relay address and\nautomatically bind to it.\n\nYou should now run the following to start the listener and see it automatically\nacquire a circuit relay address:\n\n```sh\nnode listener.js /ip4/192.168.1.120/tcp/61592/ws/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3\n```\n\nThis should print out something similar to the following:\n\n```sh\nNode started with id QmerrWofKF358JE6gv3z74cEAyL7z1KqhuUoVfGEynqjRm\nConnected to the HOP relay QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3\nListening on a relay address of /ip4/192.168.1.120/tcp/61592/ws/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3/p2p-circuit/p2p/QmerrWofKF358JE6gv3z74cEAyL7z1KqhuUoVfGEynqjRm\n```\n\nPer the listening address, it is possible to verify that the listener node is\nindeed listening on the circuit relay node address.\n\nInstead of dialing this relay manually, you could set up this node with the\n`@libp2p/bootstrap` module and provide it in the bootstrap list.\n\nAlternatively, you can use other `peer-discovery` modules such as\n`@libp2p/kad-dht` which allow your node to perform a random walk of the network\nto discover peers running the Circuit Relay HOP protocol and the node will\nautomatically bind to these relays until reaching the maximum number of\nlisteners defined by how many `/p2p-circuit` entries in the `address.listen`\narray (usually one is sufficient).\n\n## 3. Set up a dialer node for testing connectivity\n\nNow that you have a relay node and a node bound to that relay, you can test\nconnecting to the listening node via the relay.\n\n```js\nimport { createLibp2p } from 'libp2p'\nimport { webSockets } from '@libp2p/websockets'\nimport { noise } from '@chainsafe/libp2p-noise'\nimport { yamux } from '@chainsafe/libp2p-yamux'\nimport { multiaddr } from '@multiformats/multiaddr'\n\nconst listenNodeAddr = process.argv[2]\nif (!listenNodeAddr) {\n  throw new Error('The listening node address needs to be specified')\n}\n\nconst node = await createLibp2p({\n  transports: [webSockets()],\n  connectionEncrypters: [noise()],\n  streamMuxers: [yamux()]\n})\n\nconsole.log(`Node started with id ${node.peerId.toString()}`)\n\nconst ma = multiaddr(listenNodeAddr)\nconst conn = await node.dial(ma, {\n  signal: AbortSignal.timeout(10_000)\n})\nconsole.log(`Connected to the listen node via ${conn.remoteAddr.toString()}`)\n```\n\nYou should now run the following to start the relay node using the listen\naddress from step 2:\n\n```sh\nnode dialer.js /ip4/192.168.1.120/tcp/61592/ws/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3/p2p-circuit/p2p/QmerrWofKF358JE6gv3z74cEAyL7z1KqhuUoVfGEynqjRm\n```\n\nOnce you start your test node, it should print out something similar to the\nfollowing:\n\n```sh\nNode started: Qme7iEzDxFoFhhkrsrkHkMnM11aPYjysaehP4NZeUfVMKG\nConnected to the listening node via /ip4/192.168.1.120/tcp/61592/ws/p2p/QmWDn2LY8nannvSWJzruUYoLZ4vV83vfCBwd8DipvdgQc3/p2p-circuit/p2p/QmerrWofKF358JE6gv3z74cEAyL7z1KqhuUoVfGEynqjRm\n```\n\nAs you can see from the output, the remote address of the established connection\nuses the relayed connection.\n\n## 4. What is next?\n\nBefore moving into production, there are a few things that you should take into\naccount.\n\nA relay node should not advertise its private address in a real world scenario,\nas the node would not be reachable by others.\n\nIf you are using websockets, bear in mind that due to browser’s security\npolicies you cannot establish unencrypted connection from secure context.\n\nOne solution is to setup TLS with nginx and proxy to the node and setup\na domain name for the certificate. You can then provide an list of public\naddresses in the libp2p `addresses.announce` config option.\n\nAlternatively you can use the public [AutoTLS service](https://blog.libp2p.io/autotls/)\n(provided by [Interplanetary Shipyard](https://blog.ipfs.tech/shipyard-hello-world/))\nto automatically provision a TLS certificate and accompanying domain name - see\nthe [js-libp2p-example-auto-tls](https://github.com/libp2p/js-libp2p-example-auto-tls)\nfor more information.\n\n## Need help?\n\n- Read the [js-libp2p documentation](https://github.com/libp2p/js-libp2p/tree/main/doc)\n- Check out the [js-libp2p API docs](https://libp2p.github.io/js-libp2p/)\n- Check out the [general libp2p documentation](https://docs.libp2p.io) for tips, how-tos and more\n- Read the [libp2p specs](https://github.com/libp2p/specs)\n- Ask a question on the [js-libp2p discussion board](https://github.com/libp2p/js-libp2p/discussions)\n\n## License\n\nLicensed under either of\n\n- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / \u003chttp://www.apache.org/licenses/LICENSE-2.0\u003e)\n- MIT ([LICENSE-MIT](LICENSE-MIT) / \u003chttp://opensource.org/licenses/MIT\u003e)\n\n## Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibp2p%2Fjs-libp2p-example-circuit-relay","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flibp2p%2Fjs-libp2p-example-circuit-relay","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibp2p%2Fjs-libp2p-example-circuit-relay/lists"}