From bc3aa5e0f1f2b5ed046fd247208515f5de166996 Mon Sep 17 00:00:00 2001 From: acul71 Date: Fri, 16 May 2025 03:06:10 +0200 Subject: [PATCH] feat: add identify protocol example --- examples/js-libp2p-example-identify/README.md | 106 ++++++++++++++++++ .../js-libp2p-example-identify/package.json | 24 ++++ .../js-libp2p-example-identify/src/dialer.js | 75 +++++++++++++ .../src/listener.js | 58 ++++++++++ 4 files changed, 263 insertions(+) create mode 100644 examples/js-libp2p-example-identify/README.md create mode 100644 examples/js-libp2p-example-identify/package.json create mode 100644 examples/js-libp2p-example-identify/src/dialer.js create mode 100644 examples/js-libp2p-example-identify/src/listener.js diff --git a/examples/js-libp2p-example-identify/README.md b/examples/js-libp2p-example-identify/README.md new file mode 100644 index 0000000..9f4ad52 --- /dev/null +++ b/examples/js-libp2p-example-identify/README.md @@ -0,0 +1,106 @@ +# js-libp2p-example-identify + +This example demonstrates how to use the identify protocol in js-libp2p to exchange peer information. + +## Requirements + +- Node.js version 20 or higher +- npm version 7 or higher + +## Setup + +1. Install dependencies: + ```console + $ npm install + ``` + +2. Run the example in two terminals: + + Terminal 1 (Listener): + ```console + $ npm start + ``` + + Terminal 2 (Dialer): + ```console + $ npm run dial -- + ``` + Replace `` with the multiaddr shown in the listener's output. + +## How It Works + +- The example creates two libp2p nodes: a listener and a dialer +- The listener starts and displays its peer ID and multiaddrs +- The dialer connects to the listener using the provided multiaddr +- When the connection is established, the identify protocol is triggered automatically +- Both peers exchange and display detailed information about each other + +## Example Output + +When running the example, you'll see output similar to this: + +Listener output: +``` +Listener node started with peer ID: 12D3KooWF496AdcXPuXgiUeGpRVR29QZeRyyiyYK3dsmgyhqbacp +Listener multiaddrs: /ip4/127.0.0.1/tcp/37097/p2p/12D3KooWF496AdcXPuXgiUeGpRVR29QZeRyyiyYK3dsmgyhqbacp +/ip4/192.168.1.17/tcp/37097/p2p/12D3KooWF496AdcXPuXgiUeGpRVR29QZeRyyiyYK3dsmgyhqbacp +/ip4/10.155.221.162/tcp/37097/p2p/12D3KooWF496AdcXPuXgiUeGpRVR29QZeRyyiyYK3dsmgyhqbacp +/ip4/127.0.0.1/tcp/37941/ws/p2p/12D3KooWF496AdcXPuXgiUeGpRVR29QZeRyyiyYK3dsmgyhqbacp +/ip4/192.168.1.17/tcp/37941/ws/p2p/12D3KooWF496AdcXPuXgiUeGpRVR29QZeRyyiyYK3dsmgyhqbacp +/ip4/10.155.221.162/tcp/37941/ws/p2p/12D3KooWF496AdcXPuXgiUeGpRVR29QZeRyyiyYK3dsmgyhqbacp +New connection opened: 12D3KooWKYAhezQQqwWvQ8iECUv9R5tTy6639s13ZqrS5tp66Hpd + +=== Identify Information === +Peer ID: 12D3KooWKYAhezQQqwWvQ8iECUv9R5tTy6639s13ZqrS5tp66Hpd +Agent Version: js-libp2p/2.8.5 node/21.7.3 +Protocol Version: ipfs/0.1.0 +Supported protocols: [ '/ipfs/id/1.0.0' ] +Observed address: Multiaddr(/ip4/127.0.0.1/tcp/37097/p2p/12D3KooWF496AdcXPuXgiUeGpRVR29QZeRyyiyYK3dsmgyhqbacp) +Listen addresses: [ + '/ip4/127.0.0.1/tcp/41267', + '/ip4/192.168.1.17/tcp/41267', + '/ip4/10.155.221.162/tcp/41267', + '/ip4/127.0.0.1/tcp/45747/ws', + '/ip4/192.168.1.17/tcp/45747/ws', + '/ip4/10.155.221.162/tcp/45747/ws' +] +=========================== +``` + +Dialer output: +``` +Dialer node started with peer ID: 12D3KooWKYAhezQQqwWvQ8iECUv9R5tTy6639s13ZqrS5tp66Hpd +Dialing to: /ip4/127.0.0.1/tcp/37097/p2p/12D3KooWF496AdcXPuXgiUeGpRVR29QZeRyyiyYK3dsmgyhqbacp +New connection opened: 12D3KooWF496AdcXPuXgiUeGpRVR29QZeRyyiyYK3dsmgyhqbacp +Successfully dialed to target node + +=== Identify Information === +Peer ID: 12D3KooWF496AdcXPuXgiUeGpRVR29QZeRyyiyYK3dsmgyhqbacp +Agent Version: js-libp2p/2.8.5 node/21.7.3 +Protocol Version: ipfs/0.1.0 +Supported protocols: [ '/ipfs/id/1.0.0' ] +Observed address: Multiaddr(/ip4/127.0.0.1/tcp/49744/p2p/12D3KooWKYAhezQQqwWvQ8iECUv9R5tTy6639s13ZqrS5tp66Hpd) +Listen addresses: [ + '/ip4/127.0.0.1/tcp/37097', + '/ip4/192.168.1.17/tcp/37097', + '/ip4/10.155.221.162/tcp/37097', + '/ip4/127.0.0.1/tcp/37941/ws', + '/ip4/192.168.1.17/tcp/37941/ws', + '/ip4/10.155.221.162/tcp/37941/ws' +] +=========================== +``` + +The identify information includes: +- Peer ID: The unique identifier of the peer +- Agent Version: The version of the libp2p implementation and runtime +- Protocol Version: The version of the identify protocol +- Supported protocols: List of protocols that the peer supports +- Observed address: The address that the peer sees you connecting from +- Listen addresses: All addresses that the peer is listening on + +## Need Help? + +- Read the [js-libp2p documentation](https://github.com/libp2p/js-libp2p/tree/main/doc) +- Check out the [js-libp2p API docs](https://libp2p.github.io/js-libp2p/) +- Ask a question on the [js-libp2p discussion board](https://github.com/libp2p/js-libp2p/discussions) \ No newline at end of file diff --git a/examples/js-libp2p-example-identify/package.json b/examples/js-libp2p-example-identify/package.json new file mode 100644 index 0000000..cc4ad1c --- /dev/null +++ b/examples/js-libp2p-example-identify/package.json @@ -0,0 +1,24 @@ +{ + "name": "js-libp2p-example-identify", + "version": "1.0.0", + "description": "Example of using the identify protocol with js-libp2p", + "main": "src/listener.js", + "scripts": { + "start": "node src/listener.js", + "dial": "node src/dialer.js" + }, + "dependencies": { + "@chainsafe/libp2p-noise": "^12.0.0", + "@chainsafe/libp2p-yamux": "^4.0.0", + "@libp2p/identify": "^3.0.0", + "@libp2p/mdns": "^8.0.0", + "@libp2p/tcp": "^8.0.0", + "@libp2p/websockets": "^7.0.0", + "@multiformats/multiaddr": "^12.0.0", + "libp2p": "^2.0.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "type": "module" +} \ No newline at end of file diff --git a/examples/js-libp2p-example-identify/src/dialer.js b/examples/js-libp2p-example-identify/src/dialer.js new file mode 100644 index 0000000..b527664 --- /dev/null +++ b/examples/js-libp2p-example-identify/src/dialer.js @@ -0,0 +1,75 @@ +import { createLibp2p } from 'libp2p' +import { tcp } from '@libp2p/tcp' +import { webSockets } from '@libp2p/websockets' +import { noise } from '@chainsafe/libp2p-noise' +import { yamux } from '@chainsafe/libp2p-yamux' +import { mdns } from '@libp2p/mdns' +import { multiaddr } from '@multiformats/multiaddr' +import { identify } from '@libp2p/identify' + +async function main () { + const node = await createLibp2p({ + addresses: { + listen: [ + '/ip4/0.0.0.0/tcp/0', + '/ip4/0.0.0.0/tcp/0/ws' + ] + }, + transports: [ + tcp(), + webSockets() + ], + streamMuxers: [ + yamux() + ], + connectionEncrypters: [ + noise() + ], + peerDiscovery: [ + mdns() + ], + services: { + identify: identify() + } + }) + + // Listen for new connections + node.addEventListener('connection:open', (evt) => { + console.log('New connection opened:', evt.detail.remotePeer.toString()) + }) + + // Listen for identify events + node.addEventListener('peer:identify', (evt) => { + const { peerId, protocols, observedAddr, agentVersion, protocolVersion, listenAddrs } = evt.detail + console.log('\n=== Identify Information ===') + console.log('Peer ID:', peerId.toString()) + console.log('Agent Version:', agentVersion) + console.log('Protocol Version:', protocolVersion) + console.log('Supported protocols:', protocols) + console.log('Observed address:', observedAddr) + console.log('Listen addresses:', listenAddrs.map(addr => addr.toString())) + console.log('===========================\n') + }) + + await node.start() + console.log('Dialer node started with peer ID:', node.peerId.toString()) + + // Get targetMultiaddr from command line arguments + const targetMultiaddrStr = process.argv[2] + + if (!targetMultiaddrStr) { + console.error('Usage: node dialer.js ') + process.exit(1) + } + + try { + const targetMultiaddr = multiaddr(targetMultiaddrStr) + console.log('Dialing to:', targetMultiaddr.toString()) + await node.dial(targetMultiaddr) + console.log('Successfully dialed to target node') + } catch (err) { + console.error('Failed to dial target node:', err) + } +} + +main().catch(console.error) \ No newline at end of file diff --git a/examples/js-libp2p-example-identify/src/listener.js b/examples/js-libp2p-example-identify/src/listener.js new file mode 100644 index 0000000..b22939e --- /dev/null +++ b/examples/js-libp2p-example-identify/src/listener.js @@ -0,0 +1,58 @@ +import { createLibp2p } from 'libp2p' +import { tcp } from '@libp2p/tcp' +import { webSockets } from '@libp2p/websockets' +import { noise } from '@chainsafe/libp2p-noise' +import { yamux } from '@chainsafe/libp2p-yamux' +import { mdns } from '@libp2p/mdns' +import { identify } from '@libp2p/identify' + +async function main () { + const node = await createLibp2p({ + addresses: { + listen: [ + '/ip4/0.0.0.0/tcp/0', + '/ip4/0.0.0.0/tcp/0/ws' + ] + }, + transports: [ + tcp(), + webSockets() + ], + streamMuxers: [ + yamux() + ], + connectionEncrypters: [ + noise() + ], + peerDiscovery: [ + mdns() + ], + services: { + identify: identify() + } + }) + + // Listen for new connections + node.addEventListener('connection:open', (evt) => { + console.log('New connection opened:', evt.detail.remotePeer.toString()) + }) + + // Listen for identify events + node.addEventListener('peer:identify', (evt) => { + const { peerId, protocols, observedAddr, agentVersion, protocolVersion, listenAddrs } = evt.detail + console.log('\n=== Identify Information ===') + console.log('Peer ID:', peerId.toString()) + console.log('Agent Version:', agentVersion) + console.log('Protocol Version:', protocolVersion) + console.log('Supported protocols:', protocols) + console.log('Observed address:', observedAddr) + console.log('Listen addresses:', listenAddrs.map(addr => addr.toString())) + console.log('===========================\n') + }) + + await node.start() + console.log('Listener node started with peer ID:', node.peerId.toString()) + console.log('Listener multiaddrs:', node.getMultiaddrs().map(addr => addr.toString()).join('\n')) +} + +main().catch(console.error) \ No newline at end of file