{"id":20309234,"url":"https://github.com/vaporyjs/vaporyjs-devp2p","last_synced_at":"2025-09-19T06:04:34.122Z","repository":{"id":57390804,"uuid":"123757435","full_name":"vaporyjs/vaporyjs-devp2p","owner":"vaporyjs","description":"components for lower-level peer-to-peer connection","archived":false,"fork":false,"pushed_at":"2021-01-14T05:16:49.000Z","size":114,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-24T21:42:02.386Z","etag":null,"topics":["node-discovery","peer-communication","peer-table"],"latest_commit_sha":null,"homepage":"https://vapory.org","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vaporyjs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-03-04T04:42:50.000Z","updated_at":"2021-01-14T05:32:07.000Z","dependencies_parsed_at":"2022-09-17T04:20:51.196Z","dependency_job_id":null,"html_url":"https://github.com/vaporyjs/vaporyjs-devp2p","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vaporyjs%2Fvaporyjs-devp2p","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vaporyjs%2Fvaporyjs-devp2p/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vaporyjs%2Fvaporyjs-devp2p/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vaporyjs%2Fvaporyjs-devp2p/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vaporyjs","download_url":"https://codeload.github.com/vaporyjs/vaporyjs-devp2p/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241809602,"owners_count":20023786,"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":["node-discovery","peer-communication","peer-table"],"created_at":"2024-11-14T17:26:22.462Z","updated_at":"2025-09-19T06:04:29.070Z","avatar_url":"https://github.com/vaporyjs.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# vaporyjs-devp2p\n\n[![NPM Package](https://img.shields.io/npm/v/vaporyjs-devp2p.svg?style=flat-square)](https://www.npmjs.org/package/vaporyjs-devp2p)\n[![Build Status](https://travis-ci.org/vaporyjs/vaporyjs-devp2p.svg?branch=master)](https://travis-ci.org/vaporyjs/vaporyjs-devp2p)\n[![Coverage Status](https://img.shields.io/coveralls/vaporyjs/vaporyjs-devp2p.svg?style=flat-square)](https://coveralls.io/r/vaporyjs/vaporyjs-devp2p)\n[![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard)\n\nThis library bundles different components for lower-level peer-to-peer connection and message exchange:\n\n- Distributed Peer Table (DPT) / Node Discovery\n- RLPx Transport Protocol\n- Vapory Wire Protocol (VAP)\n\nThe library is based on [vaporyjs/node-devp2p](https://github.com/vaporycojs/node-devp2p) as well\nas other sub-libraries (``node-*`` named) (all outdated).\n\n## Run/Build\n\nThis library has to be compiled with babel to a ``Node 6`` friendly source format.\nFor triggering a (first) build to create the ``lib/`` directory run:\n\n```\nnpm run build\n```\n\nYou can also use babel just-in-time compilation to run a script:\n\n```\nnode -r babel-register [YOUR_SCRIPT_TO_RUN.js]\n```\n\n## Usage/Examples\n\nAll components of this library are implemented as Node ``EventEmitter`` objects\nand make heavy use of the Node.js network stack.\n\nYou can react on events from the network like this:\n\n```\ndpt.on('peer:added', (peer) =\u003e {\n  // Do something...\n})\n```\n\nBasic example to connect to some bootstrap nodes and get basic peer info:\n\n  - [simple](examples/simple.js)\n\nCommunicate with peers to read new transaction and block information:\n\n  - [peer-communication](examples/peer-communication.js)\n\nRun an example with:\n\n```\nnode -r babel-register ./examples/peer-communication.js\n```\n\n## Distributed Peer Table (DPT) / Node Discovery\n\nMaintain/manage a list of peers, see [./src/dpt/](./src/dpt/), also \nincludes node discovery ([./src/dpt/server.js](./src/dpt/server.js))\n\n### Usage\n\nCreate your peer table:\n\n```\nconst dpt = new DPT(Buffer.from(PRIVATE_KEY, 'hex'), {\n  endpoint: {\n    address: '0.0.0.0',\n    udpPort: null,\n    tcpPort: null\n  }\n})\n```\n\nAdd some bootstrap nodes (or some custom nodes with ``dpt.addPeer()``):\n\n```\ndpt.bootstrap(bootnode).catch((err) =\u003e console.error('Something went wrong!'))\n```\n\n### API\n\n\n#### `DPT` (extends `EventEmitter`)\nDistributed Peer Table. Manages a Kademlia DHT K-bucket (``Kbucket``) for storing peer information \nand a ``BanList`` for keeping a list of bad peers. ``Server`` implements the node discovery (``ping``,\n``pong``, ``findNeighbours``).\n\n##### `new DPT(privateKey, options)`\nCreates new DPT object\n- `privateKey` - Key for message encoding/signing.\n- `options.refreshInterval` - Interval in ms for refreshing (calling ``findNeighbours``) the peer list (default: ``60s``).\n- `options.createSocket` - A datagram (dgram) ``createSocket`` function, passed to ``Server`` (default: ``dgram.createSocket.bind(null, 'udp4')``).\n- `options.timeout` - Timeout in ms for server ``ping``, passed to ``Server`` (default: ``10s``).\n- `options.endpoint` - Endpoint information to send with the server ``ping``, passed to ``Server`` (default: ``{ address: '0.0.0.0', udpPort: null, tcpPort: null }``).\n\n#### `dpt.bootstrap(peer)` (``async``)\nUses a peer as new bootstrap peer and calls ``findNeighbouts``.\n- `peer` - Peer to be added, format ``{ address: [ADDRESS], udpPort: [UDPPORT], tcpPort: [TCPPORT] }``.\n\n#### `dpt.addPeer(object)` (``async``)\nAdds a new peer.\n- `object` - Peer to be added, format ``{ address: [ADDRESS], udpPort: [UDPPORT], tcpPort: [TCPPORT] }``.\n\nFor other utility functions like ``getPeer``, ``getPeers`` see [./src/dpt/index.js](./src/dpt/index.js).\n\n### Events\n\nEvents emitted:\n\n| Event         | Description                              |\n| ------------- |:----------------------------------------:|\n| peer:added    | Peer added to DHT bucket                 |\n| peer:removed  | Peer removed from DHT bucket             |\n| peer:new      | New peer added                           |\n| listening     | Forwarded from server                    |\n| close         | Forwarded from server                    |\n| error         | Forwarded from server                    |\n\n### Reference\n\n- [Node discovery protocol](https://github.com/vaporyco/wiki/wiki/Node-discovery-protocol)\n- [RLPx - Node Discovery Protocol](https://github.com/vaporyco/devp2p/blob/master/rlpx.md#node-discovery)\n- [Kademlia Peer Selection](https://github.com/vaporyco/wiki/wiki/Kademlia-Peer-Selection)\n\n## RLPx Transport Protocol\n\nConnect to a peer, organize the communication, see [./src/rlpx/](./src/rlpx/)\n\n### Usage\n\nCreate your ``RLPx`` object, e.g.:\n\n```\nconst rlpx = new devp2p.RLPx(PRIVATE_KEY, {\n  dpt: dpt,\n  maxPeers: 25,\n  capabilities: [\n    devp2p.VAP.vap63,\n    devp2p.VAP.vap62\n  ],\n  listenPort: null\n})\n```\n\n### API\n\n#### `RLPx` (extends `EventEmitter`)\nManages the handshake (`ECIES`) and the handling of the peer communication (``Peer``).\n\n##### `new RLPx(privateKey, options)`\nCreates new RLPx object\n- `privateKey` - Key for message encoding/signing.\n- `options.timeout` - Peer `ping` timeout in ms (default: ``10s``).\n- `options.maxPeers` - Max number of peer connections (default: ``10``).\n- `options.clientId` - Client ID string (default example: ``vaporyjs-devp2p/v2.1.3/darwin-x64/nodejs``).\n- `options.remoteClientIdFilter` - Optional list of client ID filter strings (e.g. `['go1.5', 'quorum']`).\n- `options.capabilities` - Upper layer protocol capabilities, e.g. `[devp2p.VAP.vap63, devp2p.VAP.vap62]`.\n- `options.listenPort` - The listening port for the server or ``null`` for default.\n- `options.dpt` - `DPT` object for the peers to connect to (default: ``null``, no `DPT` peer management).\n\n#### `rlpx.connect(peer)` (``async``)\nManually connect to peer without `DPT`.\n- `peer` - Peer to connect to, format ``{ id: PEER_ID, address: PEER_ADDRESS, port: PEER_PORT }``.\n\nFor other connection/utility functions like ``listen``, ``getPeers`` see [./src/rlpx/index.js](./src/rlpx/index.js).\n\n### Events\n\nEvents emitted:\n\n| Event         | Description                              |\n| ------------- |:----------------------------------------:|\n| peer:added    | Handshake with peer successful           |\n| peer:removed  | Disconnected from peer                   |\n| peer:error    | Error connecting to peer                 |\n| listening     | Forwarded from server                    |\n| close         | Forwarded from server                    |\n| error         | Forwarded from server                    |\n\n\n### Reference\n\n- [RLPx: Cryptographic Network \u0026 Transport Protocol](https://github.com/vaporyco/devp2p/blob/master/rlpx.md)\n- [devp2p wire protocol](https://github.com/vaporyco/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol)\n\n## Vapory Wire Protocol (VAP)\n\nUpper layer protocol for exchanging Vapory network data like block headers or transactions with a node, see [./src/vap/](./src/vap/)\n\n### Usage\n\nSend the initial status message with ``sendStatus()``, then wait for the corresponding `status` message\nto arrive to start the communication.\n\n```\nvap.once('status', () =\u003e {\n  // Send an initial message\n  vap.sendMessage()\n})\n```\n\nWait for follow-up messages to arrive, send your responses. \n\n```\nvap.on('message', async (code, payload) =\u003e {\n  if (code === devp2p.VAP.MESSAGE_CODES.NEW_BLOCK_HASHES) {\n    // Do something with your new block hashes :-)\n  }\n})\n```\n\nSee the ``peer-communication.js`` example for a more detailed use case.\n\n### API\n\n#### `VAP` (extends `EventEmitter`)\nHandles the different message types like `NEW_BLOCK_HASHES` or `GET_NODE_DATA` (see `MESSAGE_CODES`) for\na complete list. Currently protocol versions `PV62` and `PV63` are supported.\n\n##### `new VAP(privateKey, options)`\nNormally not instantiated directly but created as a ``SubProtocol`` in the ``Peer`` object.\n- `version` - The protocol version for communicating, e.g. `63`.\n- `peer` - `Peer` object to communicate with.\n- `send` - Wrapped ``peer.sendMessage()`` function where the communication is routed to.\n\n#### `vap.sendStatus(status)`\nSend initial status message.\n- `status` - Status message to send, format ``{ networkId: CHAIN_ID, td: TOTAL_DIFFICULTY_BUFFER, bestHash: BEST_HASH_BUFFER, genesisHash: GENESIS_HASH_BUFFER }``.\n\n#### `vap.sendMessage(code, payload)`\nSend initial status message.\n- `code` - The message code, see `MESSAGE_CODES` for available message types.\n- `payload` - Payload as a list, will be rlp-encoded.\n\n### Events\n\nEvents emitted:\n\n| Event         | Description                              |\n| ------------- |:----------------------------------------:|\n| message       | Message received                         |\n| status        | Status info received                     |\n\n### Reference\n\n- [Vapory wire protocol](https://github.com/vaporyco/wiki/wiki/Vapory-Wire-Protocol)\n\n\n## Tests\n\nThere are unit tests in the ``test/`` directory which can be run with:\n\n```\nnpm run test\n```\n\n## Debugging\n\nThis library uses [debug](https://github.com/visionmedia/debug) debugging utility package.\n\nFor the debugging output to show up, set the ``DEBUG`` environment variable (e.g. in Linux/Mac OS: \n``export DEBUG=*,-babel``).\n\nYou should now see debug output like to following when running one of the examples above (the indented lines):\n\n```\nAdd peer: 52.3.158.184:30303 Gvap/v1.7.3-unstable-479aa61f/linux-amd64/go1.9 (vap63) (total: 2)\n  devp2p:rlpx:peer Received body 52.169.42.101:30303 01c110 +133ms\n  devp2p:rlpx:peer Message code: 1 - 0 = 1 +0ms\n  devp2p:rlpx refill connections.. queue size: 0, open slots: 20 +1ms\n  devp2p:rlpx 52.169.42.101:30303 disconnect, reason: 16 +1ms\nRemove peer: 52.169.42.101:30303 (peer disconnect, reason code: 16) (total: 1)\n```\n\n## General References\n\n### Other Implementations\n\nThe following is a list of major implementations of the ``devp2p`` stack in other languages:\n\n- [pydevp2p](https://github.com/vaporyco/pydevp2p) (Python)\n- [Go Vapory](https://github.com/vaporyco/go-vapory/tree/master/p2p) (Go)\n- [Exthereum](https://github.com/exthereum/exth_crypto) (Elixir)\n\n### Links\n\n- [Blog article series](https://ocalog.com/post/10/)  on implementing Vapory protocol stack\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvaporyjs%2Fvaporyjs-devp2p","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvaporyjs%2Fvaporyjs-devp2p","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvaporyjs%2Fvaporyjs-devp2p/lists"}