diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2379d8e..2fb0ece 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -34,6 +34,7 @@ jobs:
- js-libp2p-example-pubsub
- js-libp2p-example-transports
- js-libp2p-example-webrtc-private-to-private
+ - js-libp2p-example-webrtc-private-to-public
defaults:
run:
working-directory: examples/${{ matrix.project }}
@@ -95,6 +96,7 @@ jobs:
- js-libp2p-example-pubsub
- js-libp2p-example-transports
- js-libp2p-example-webrtc-private-to-private
+ - js-libp2p-example-webrtc-private-to-public
steps:
- uses: convictional/trigger-workflow-and-wait@f69fa9eedd3c62a599220f4d5745230e237904be
with:
diff --git a/examples/js-libp2p-example-auto-tls/package.json b/examples/js-libp2p-example-auto-tls/package.json
index 7649b3c..7b41e5c 100644
--- a/examples/js-libp2p-example-auto-tls/package.json
+++ b/examples/js-libp2p-example-auto-tls/package.json
@@ -16,21 +16,22 @@
},
"type": "module",
"dependencies": {
- "@chainsafe/libp2p-noise": "^16.0.0",
- "@chainsafe/libp2p-yamux": "^7.0.0",
+ "@chainsafe/libp2p-noise": "^17.0.0",
+ "@chainsafe/libp2p-yamux": "^8.0.0",
"@ipshipyard/libp2p-auto-tls": "^1.0.0",
- "@libp2p/autonat": "^2.0.13",
- "@libp2p/bootstrap": "^11.0.14",
+ "@libp2p/autonat": "^3.0.0",
+ "@libp2p/bootstrap": "^12.0.0",
"@libp2p/config": "^1.0.0",
- "@libp2p/identify": "^3.0.13",
- "@libp2p/kad-dht": "^15.0.0",
- "@libp2p/keychain": "^5.0.11",
- "@libp2p/ping": "^2.0.27",
- "@libp2p/upnp-nat": "^3.0.1",
- "@libp2p/websockets": "^9.1.0",
- "@multiformats/multiaddr-matcher": "^1.6.0",
+ "@libp2p/identify": "^4.0.0",
+ "@libp2p/kad-dht": "^16.0.0",
+ "@libp2p/keychain": "^6.0.0",
+ "@libp2p/ping": "^3.0.0",
+ "@libp2p/tcp": "^11.0.1",
+ "@libp2p/upnp-nat": "^4.0.0",
+ "@libp2p/websockets": "^10.0.0",
+ "@multiformats/multiaddr-matcher": "^3.0.1",
"datastore-level": "^11.0.1",
- "libp2p": "^2.0.0"
+ "libp2p": "^3.0.0"
},
"private": true
}
diff --git a/examples/js-libp2p-example-browser-pubsub/README.md b/examples/js-libp2p-example-browser-pubsub/README.md
index c385f9c..10fcbe2 100644
--- a/examples/js-libp2p-example-browser-pubsub/README.md
+++ b/examples/js-libp2p-example-browser-pubsub/README.md
@@ -9,6 +9,9 @@
This example leverages the [vite bundler](https://vitejs.dev/) to compile and serve the libp2p code in the browser. You can use other bundlers such as Webpack, but we will not be covering them here.
+> [!TIP]
+> This example uses `@libp2p/floodsub` as a pubsub implementation - it is not suitable for production use, instead use `@chainsafe/libp2p-gossipsub`
+
## Table of contents
- [Setup](#setup)
diff --git a/examples/js-libp2p-example-browser-pubsub/index.js b/examples/js-libp2p-example-browser-pubsub/index.js
index a62499f..6dad44f 100644
--- a/examples/js-libp2p-example-browser-pubsub/index.js
+++ b/examples/js-libp2p-example-browser-pubsub/index.js
@@ -1,13 +1,12 @@
-import { gossipsub } from '@chainsafe/libp2p-gossipsub'
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { circuitRelayTransport } from '@libp2p/circuit-relay-v2'
-import { dcutr } from '@libp2p/dcutr'
+import { floodsub } from '@libp2p/floodsub'
import { identify } from '@libp2p/identify'
import { webRTC } from '@libp2p/webrtc'
import { webSockets } from '@libp2p/websockets'
-import * as filters from '@libp2p/websockets/filters'
import { multiaddr } from '@multiformats/multiaddr'
+import { WebRTC } from '@multiformats/multiaddr-matcher'
import { createLibp2p } from 'libp2p'
import { fromString, toString } from 'uint8arrays'
@@ -48,10 +47,7 @@ const libp2p = await createLibp2p({
},
transports: [
// the WebSocket transport lets us dial a local relay
- webSockets({
- // this allows non-secure WebSocket connections for purposes of the demo
- filter: filters.all
- }),
+ webSockets(),
// support dialing/listening on WebRTC addresses
webRTC(),
// support dialing/listening on Circuit Relay addresses
@@ -72,8 +68,7 @@ const libp2p = await createLibp2p({
},
services: {
identify: identify(),
- pubsub: gossipsub(),
- dcutr: dcutr()
+ pubsub: floodsub()
}
})
@@ -113,6 +108,7 @@ libp2p.addEventListener('connection:close', () => {
// update listening addresses
libp2p.addEventListener('self:peer:update', () => {
const multiaddrs = libp2p.getMultiaddrs()
+ .filter(ma => WebRTC.matches(ma))
.map((ma) => {
const el = document.createElement('li')
el.textContent = ma.toString()
diff --git a/examples/js-libp2p-example-browser-pubsub/package.json b/examples/js-libp2p-example-browser-pubsub/package.json
index 01bad9a..d945434 100644
--- a/examples/js-libp2p-example-browser-pubsub/package.json
+++ b/examples/js-libp2p-example-browser-pubsub/package.json
@@ -21,16 +21,17 @@
"test": "npm run build && test-browser-example test"
},
"dependencies": {
- "@chainsafe/libp2p-gossipsub": "^14.0.0",
- "@chainsafe/libp2p-noise": "^16.0.0",
- "@chainsafe/libp2p-yamux": "^7.0.0",
- "@libp2p/circuit-relay-v2": "^3.0.0",
- "@libp2p/dcutr": "^2.0.0",
- "@libp2p/identify": "^3.0.0",
- "@libp2p/webrtc": "^5.0.0",
- "@libp2p/websockets": "^9.0.0",
- "@multiformats/multiaddr": "^12.3.1",
- "libp2p": "^2.0.0",
+ "@chainsafe/libp2p-noise": "^17.0.0",
+ "@chainsafe/libp2p-yamux": "^8.0.0",
+ "@libp2p/circuit-relay-v2": "^4.0.1",
+ "@libp2p/floodsub": "^11.0.1",
+ "@libp2p/identify": "^4.0.1",
+ "@libp2p/webrtc": "^6.0.3",
+ "@libp2p/websockets": "^10.0.1",
+ "@multiformats/multiaddr": "^13.0.1",
+ "@multiformats/multiaddr-matcher": "^3.0.1",
+ "libp2p": "^3.0.2",
+ "uint8arrays": "^5.1.0",
"vite": "^6.0.3"
},
"devDependencies": {
diff --git a/examples/js-libp2p-example-browser-pubsub/relay.js b/examples/js-libp2p-example-browser-pubsub/relay.js
index 0fbcc52..3b8da52 100644
--- a/examples/js-libp2p-example-browser-pubsub/relay.js
+++ b/examples/js-libp2p-example-browser-pubsub/relay.js
@@ -5,7 +5,6 @@ import { yamux } from '@chainsafe/libp2p-yamux'
import { circuitRelayServer } from '@libp2p/circuit-relay-v2'
import { identify } from '@libp2p/identify'
import { webSockets } from '@libp2p/websockets'
-import * as filters from '@libp2p/websockets/filters'
import { createLibp2p } from 'libp2p'
const server = await createLibp2p({
@@ -13,9 +12,7 @@ const server = await createLibp2p({
listen: ['/ip4/127.0.0.1/tcp/0/ws']
},
transports: [
- webSockets({
- filter: filters.all
- })
+ webSockets()
],
connectionEncrypters: [noise()],
streamMuxers: [yamux()],
diff --git a/examples/js-libp2p-example-browser-pubsub/test/index.spec.js b/examples/js-libp2p-example-browser-pubsub/test/index.spec.js
index a004341..51b2f76 100644
--- a/examples/js-libp2p-example-browser-pubsub/test/index.spec.js
+++ b/examples/js-libp2p-example-browser-pubsub/test/index.spec.js
@@ -1,10 +1,8 @@
-/* eslint-disable no-console */
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { circuitRelayServer } from '@libp2p/circuit-relay-v2'
import { identify } from '@libp2p/identify'
import { webSockets } from '@libp2p/websockets'
-import * as filters from '@libp2p/websockets/filters'
import { createLibp2p } from 'libp2p'
import { setup, expect } from 'test-ipfs-example/browser'
@@ -32,9 +30,7 @@ async function spawnRelay () {
listen: ['/ip4/127.0.0.1/tcp/0/ws']
},
transports: [
- webSockets({
- filter: filters.all
- })
+ webSockets()
],
connectionEncrypters: [noise()],
streamMuxers: [yamux()],
@@ -53,7 +49,6 @@ test.describe('pubsub browser example:', () => {
let relayNode
let relayNodeAddr
- // eslint-disable-next-line no-empty-pattern
test.beforeAll(async ({ servers }, testInfo) => {
testInfo.setTimeout(5 * 60_000)
const r = await spawnRelay()
@@ -70,7 +65,7 @@ test.describe('pubsub browser example:', () => {
await page.goto(url)
})
- test('should connect via a relay node', async ({ page: pageA, context }) => {
+ test('should send and receive a message', async ({ page: pageA, context }) => {
// load second page
const pageB = await context.newPage()
await pageB.goto(url)
diff --git a/examples/js-libp2p-example-chat/package.json b/examples/js-libp2p-example-chat/package.json
index d735a63..feb0e7e 100644
--- a/examples/js-libp2p-example-chat/package.json
+++ b/examples/js-libp2p-example-chat/package.json
@@ -16,21 +16,18 @@
"test": "test-node-example test/*"
},
"dependencies": {
- "@chainsafe/libp2p-noise": "^16.0.0",
- "@chainsafe/libp2p-yamux": "^7.0.0",
- "@libp2p/mdns": "^11.0.1",
- "@libp2p/tcp": "^10.0.0",
- "@libp2p/websockets": "^9.0.0",
- "@multiformats/multiaddr": "^12.3.1",
+ "@chainsafe/libp2p-noise": "^17.0.0",
+ "@chainsafe/libp2p-yamux": "^8.0.0",
+ "@libp2p/mdns": "^12.0.2",
+ "@libp2p/tcp": "^11.0.1",
+ "@libp2p/utils": "^7.0.1",
+ "@libp2p/websockets": "^10.0.1",
"@nodeutils/defaults-deep": "^1.1.0",
- "it-length-prefixed": "^10.0.1",
- "it-map": "^3.0.3",
- "it-pipe": "^3.0.1",
- "libp2p": "^2.0.0",
- "p-defer": "^4.0.0",
+ "libp2p": "^3.0.2",
"uint8arrays": "^5.1.0"
},
"devDependencies": {
+ "p-defer": "^4.0.0",
"test-ipfs-example": "^1.1.0"
},
"private": true
diff --git a/examples/js-libp2p-example-chat/src/listener.js b/examples/js-libp2p-example-chat/src/listener.js
index 5311be9..05fc004 100644
--- a/examples/js-libp2p-example-chat/src/listener.js
+++ b/examples/js-libp2p-example-chat/src/listener.js
@@ -18,7 +18,7 @@ async function run () {
})
// Handle messages for the protocol
- await listener.handle('/chat/1.0.0', async ({ stream }) => {
+ await listener.handle('/chat/1.0.0', async (stream) => {
// Send stdin to the stream
stdinToStream(stream)
// Read the stream and output to console
diff --git a/examples/js-libp2p-example-chat/src/stream.js b/examples/js-libp2p-example-chat/src/stream.js
index 194a9c1..bc1e683 100644
--- a/examples/js-libp2p-example-chat/src/stream.js
+++ b/examples/js-libp2p-example-chat/src/stream.js
@@ -1,41 +1,27 @@
/* eslint-disable no-console */
-import * as lp from 'it-length-prefixed'
-import map from 'it-map'
-import { pipe } from 'it-pipe'
-import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
+import { lpStream } from '@libp2p/utils'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
export function stdinToStream (stream) {
- // Read utf-8 from stdin
- process.stdin.setEncoding('utf8')
- pipe(
- // Read from stdin (the source)
- process.stdin,
- // Turn strings into buffers
- (source) => map(source, (string) => uint8ArrayFromString(string)),
- // Encode with length prefix (so receiving side knows how much data is coming)
- (source) => lp.encode(source),
- // Write to the stream (the sink)
- stream.sink
- )
+ // Encode with length prefix (so receiving side knows how much data is coming)
+ const lp = lpStream(stream)
+
+ process.stdin.addListener('data', (buf) => {
+ lp.write(buf)
+ })
}
export function streamToConsole (stream) {
- pipe(
- // Read from the stream (the source)
- stream.source,
- // Decode length-prefixed data
- (source) => lp.decode(source),
- // Turn buffers into strings
- (source) => map(source, (buf) => uint8ArrayToString(buf.subarray())),
- // Sink function
- async function (source) {
- // For each chunk of data
- for await (const msg of source) {
- // Output the data as a utf8 string
- console.log('> ' + msg.toString().replace('\n', ''))
- }
+ const lp = lpStream(stream)
+
+ Promise.resolve().then(async () => {
+ while (true) {
+ // Read from the stream
+ const message = await lp.read()
+
+ // Output the data as a utf8 string
+ console.log('> ' + uint8ArrayToString(message.subarray()).replace('\n', ''))
}
- )
+ })
}
diff --git a/examples/js-libp2p-example-circuit-relay/package.json b/examples/js-libp2p-example-circuit-relay/package.json
index 6e04cac..7f0ca48 100644
--- a/examples/js-libp2p-example-circuit-relay/package.json
+++ b/examples/js-libp2p-example-circuit-relay/package.json
@@ -16,13 +16,13 @@
"test": "test-node-example test/*"
},
"dependencies": {
- "@chainsafe/libp2p-noise": "^16.0.0",
- "@chainsafe/libp2p-yamux": "^7.0.0",
- "@libp2p/circuit-relay-v2": "^3.0.0",
- "@libp2p/identify": "^3.0.0",
- "@libp2p/websockets": "^9.0.0",
- "@multiformats/multiaddr": "^12.3.1",
- "libp2p": "^2.0.0"
+ "@chainsafe/libp2p-noise": "^17.0.0",
+ "@chainsafe/libp2p-yamux": "^8.0.0",
+ "@libp2p/circuit-relay-v2": "^4.0.1",
+ "@libp2p/identify": "^4.0.1",
+ "@libp2p/websockets": "^10.0.1",
+ "@multiformats/multiaddr": "^13.0.1",
+ "libp2p": "^3.0.2"
},
"devDependencies": {
"test-ipfs-example": "^1.1.0"
diff --git a/examples/js-libp2p-example-connection-encryption/noise.js b/examples/js-libp2p-example-connection-encryption/noise.js
index d2834a3..c734a90 100644
--- a/examples/js-libp2p-example-connection-encryption/noise.js
+++ b/examples/js-libp2p-example-connection-encryption/noise.js
@@ -3,7 +3,6 @@
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { tcp } from '@libp2p/tcp'
-import { pipe } from 'it-pipe'
import { createLibp2p } from 'libp2p'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
@@ -24,20 +23,12 @@ const createNode = async () => {
const node1 = await createNode()
const node2 = await createNode()
-node2.handle('/a-protocol', ({ stream }) => {
- pipe(
- stream,
- async function (source) {
- for await (const msg of source) {
- console.log(uint8ArrayToString(msg.subarray()))
- }
- }
- )
+node2.handle('/a-protocol', (stream) => {
+ stream.addEventListener('message', (evt) => {
+ console.log(uint8ArrayToString(evt.data.subarray()))
+ })
})
const stream = await node1.dialProtocol(node2.getMultiaddrs(), '/a-protocol')
-await pipe(
- [uint8ArrayFromString('This information is sent out encrypted to the other peer')],
- stream
-)
+stream.send(uint8ArrayFromString('This information is sent out encrypted to the other peer'))
diff --git a/examples/js-libp2p-example-connection-encryption/package.json b/examples/js-libp2p-example-connection-encryption/package.json
index 80a18b6..12a9f5f 100644
--- a/examples/js-libp2p-example-connection-encryption/package.json
+++ b/examples/js-libp2p-example-connection-encryption/package.json
@@ -16,12 +16,11 @@
"test": "test-node-example test/*"
},
"dependencies": {
- "@chainsafe/libp2p-noise": "^16.0.0",
- "@chainsafe/libp2p-yamux": "^7.0.0",
- "@libp2p/plaintext": "^2.0.0",
- "@libp2p/tcp": "^10.0.0",
- "it-pipe": "^3.0.1",
- "libp2p": "^2.0.0",
+ "@chainsafe/libp2p-noise": "^17.0.0",
+ "@chainsafe/libp2p-yamux": "^8.0.0",
+ "@libp2p/plaintext": "^3.0.1",
+ "@libp2p/tcp": "^11.0.1",
+ "libp2p": "^3.0.2",
"uint8arrays": "^5.1.0"
},
"devDependencies": {
diff --git a/examples/js-libp2p-example-connection-encryption/plaintext.js b/examples/js-libp2p-example-connection-encryption/plaintext.js
index 3ef3861..e1573d7 100644
--- a/examples/js-libp2p-example-connection-encryption/plaintext.js
+++ b/examples/js-libp2p-example-connection-encryption/plaintext.js
@@ -3,7 +3,6 @@
import { yamux } from '@chainsafe/libp2p-yamux'
import { plaintext } from '@libp2p/plaintext'
import { tcp } from '@libp2p/tcp'
-import { pipe } from 'it-pipe'
import { createLibp2p } from 'libp2p'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
@@ -24,20 +23,12 @@ const createNode = async () => {
const node1 = await createNode()
const node2 = await createNode()
-node2.handle('/a-protocol', ({ stream }) => {
- pipe(
- stream,
- async function (source) {
- for await (const msg of source) {
- console.log(uint8ArrayToString(msg.subarray()))
- }
- }
- )
+node2.handle('/a-protocol', (stream) => {
+ stream.addEventListener('message', (evt) => {
+ console.log(uint8ArrayToString(evt.data.subarray()))
+ })
})
const stream = await node1.dialProtocol(node2.getMultiaddrs(), '/a-protocol')
-await pipe(
- [uint8ArrayFromString('This information is sent out encrypted to the other peer')],
- stream
-)
+stream.send(uint8ArrayFromString('This information is sent out encrypted to the other peer'))
diff --git a/examples/js-libp2p-example-custom-protocols/1-echo.js b/examples/js-libp2p-example-custom-protocols/1-echo.js
index 4d06306..504f431 100644
--- a/examples/js-libp2p-example-custom-protocols/1-echo.js
+++ b/examples/js-libp2p-example-custom-protocols/1-echo.js
@@ -3,7 +3,6 @@
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { tcp } from '@libp2p/tcp'
-import { pipe } from 'it-pipe'
import { createLibp2p } from 'libp2p'
async function createNode () {
@@ -33,36 +32,26 @@ const local = await createNode()
const ECHO_PROTOCOL = '/echo/1.0.0'
// the remote will handle incoming streams opened on the protocol
-await remote.handle(ECHO_PROTOCOL, ({ stream }) => {
+await remote.handle(ECHO_PROTOCOL, (stream) => {
// pipe the stream output back to the stream input
- pipe(stream, stream)
+ stream.addEventListener('message', evt => {
+ stream.send(evt.data)
+ })
+
+ // close the incoming writable end when the remote writable end closes
+ stream.addEventListener('remoteCloseWrite', () => {
+ stream.close()
+ })
})
// the local will dial the remote on the protocol stream
const stream = await local.dialProtocol(remote.getMultiaddrs(), ECHO_PROTOCOL)
-// now it will write some data and read it back
-const output = await pipe(
- async function * () {
- // the stream input must be bytes
- yield new TextEncoder().encode('hello world')
- },
- stream,
- async (source) => {
- let string = ''
- const decoder = new TextDecoder()
-
- for await (const buf of source) {
- // buf is a `Uint8ArrayList` so we must turn it into a `Uint8Array`
- // before decoding it
- string += decoder.decode(buf.subarray())
- }
-
- return string
- }
-)
-
-console.info(`Echoed back to us: "${output}"`)
+stream.addEventListener('message', (evt) => {
+ // evt.data is a `Uint8ArrayList` so we must turn it into a `Uint8Array`
+ // before decoding it
+ console.info(`Echoed back to us: "${new TextDecoder().decode(evt.data.subarray())}"`)
+})
-await remote.stop()
-await local.stop()
+// the stream input must be bytes
+stream.send(new TextEncoder().encode('hello world'))
diff --git a/examples/js-libp2p-example-custom-protocols/2-request-response.js b/examples/js-libp2p-example-custom-protocols/2-request-response.js
index 99ab722..765f472 100644
--- a/examples/js-libp2p-example-custom-protocols/2-request-response.js
+++ b/examples/js-libp2p-example-custom-protocols/2-request-response.js
@@ -3,7 +3,7 @@
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { tcp } from '@libp2p/tcp'
-import { lpStream } from 'it-length-prefixed-stream'
+import { lpStream } from '@libp2p/utils'
import { createLibp2p } from 'libp2p'
async function createNode () {
@@ -33,7 +33,7 @@ const local = await createNode()
const REQ_RESP_PROTOCOL = '/request-response/1.0.0'
// the remote will handle incoming streams opened on the protocol
-await remote.handle(REQ_RESP_PROTOCOL, ({ stream }) => {
+await remote.handle(REQ_RESP_PROTOCOL, (stream) => {
Promise.resolve().then(async () => {
// lpStream lets us read/write in a predetermined order
const lp = lpStream(stream)
@@ -77,6 +77,3 @@ const res = await lp.read()
const output = JSON.parse(new TextDecoder().decode(res.subarray()))
console.info(`The answer is: "${output.answer}"`)
-
-await remote.stop()
-await local.stop()
diff --git a/examples/js-libp2p-example-custom-protocols/package.json b/examples/js-libp2p-example-custom-protocols/package.json
index 4cc5dee..35b6d86 100644
--- a/examples/js-libp2p-example-custom-protocols/package.json
+++ b/examples/js-libp2p-example-custom-protocols/package.json
@@ -16,16 +16,11 @@
"test": "test-node-example test/*"
},
"dependencies": {
- "@chainsafe/libp2p-noise": "^16.0.0",
- "@chainsafe/libp2p-yamux": "^7.0.0",
- "@libp2p/tcp": "^10.0.0",
- "@libp2p/websockets": "^9.0.0",
- "@multiformats/multiaddr": "^12.1.5",
- "@nodeutils/defaults-deep": "^1.1.0",
- "it-length-prefixed-stream": "^1.1.4",
- "it-pipe": "^3.0.1",
- "libp2p": "^2.0.0",
- "uint8arrays": "^5.1.0"
+ "@chainsafe/libp2p-noise": "^17.0.0",
+ "@chainsafe/libp2p-yamux": "^8.0.0",
+ "@libp2p/tcp": "^11.0.1",
+ "@libp2p/utils": "^7.0.1",
+ "libp2p": "^3.0.2"
},
"devDependencies": {
"test-ipfs-example": "^1.1.0"
diff --git a/examples/js-libp2p-example-delegated-routing/package.json b/examples/js-libp2p-example-delegated-routing/package.json
index 74aba1d..2ce413d 100644
--- a/examples/js-libp2p-example-delegated-routing/package.json
+++ b/examples/js-libp2p-example-delegated-routing/package.json
@@ -23,15 +23,15 @@
"dependencies": {
"@helia/delegated-routing-v1-http-api-client": "^4.0.0",
"@helia/delegated-routing-v1-http-api-server": "^4.0.0",
- "libp2p": "^2.0.0",
+ "@libp2p/peer-id": "^6.0.1",
+ "helia": "^5.0.0",
+ "libp2p": "^3.0.2",
+ "multiformats": "^13.4.1",
"react": "^18.3.1",
- "react-dom": "^18.3.1",
"vite": "^6.0.3"
},
"devDependencies": {
- "@libp2p/peer-id": "^5.0.4",
- "eslint-config-ipfs": "^7.0.2",
- "helia": "^5.0.0",
+ "eslint-config-ipfs": "^8.0.0",
"test-ipfs-example": "^1.0.0"
},
"private": true
diff --git a/examples/js-libp2p-example-delegated-routing/src/App.js b/examples/js-libp2p-example-delegated-routing/src/App.jsx
similarity index 81%
rename from examples/js-libp2p-example-delegated-routing/src/App.js
rename to examples/js-libp2p-example-delegated-routing/src/App.jsx
index 53a4bab..0e99e13 100644
--- a/examples/js-libp2p-example-delegated-routing/src/App.js
+++ b/examples/js-libp2p-example-delegated-routing/src/App.jsx
@@ -1,7 +1,3 @@
-/* eslint-disable no-console */
-// eslint-disable-next-line
-'use strict'
-
import { peerIdFromString } from '@libp2p/peer-id'
import { CID } from 'multiformats/cid'
import React from 'react'
@@ -90,30 +86,30 @@ class App extends Component {
render () {
return (
-
+
-
+
0 ? 'loading' : '', 'loader'].join(' ')}>
-
+
-
+
{this.state.response}
diff --git a/examples/js-libp2p-example-delegated-routing/src/index.js b/examples/js-libp2p-example-delegated-routing/src/index.js
index 8b2c97d..5939553 100644
--- a/examples/js-libp2p-example-delegated-routing/src/index.js
+++ b/examples/js-libp2p-example-delegated-routing/src/index.js
@@ -1,5 +1,3 @@
-/* eslint-disable no-console */
-
import { createDelegatedRoutingV1HttpApiClient } from '@helia/delegated-routing-v1-http-api-client'
import { peerIdFromString } from '@libp2p/peer-id'
import { createLibp2p } from 'libp2p'
diff --git a/examples/js-libp2p-example-delegated-routing/test/index.spec.js b/examples/js-libp2p-example-delegated-routing/test/index.spec.js
index 4ecda46..b8797be 100644
--- a/examples/js-libp2p-example-delegated-routing/test/index.spec.js
+++ b/examples/js-libp2p-example-delegated-routing/test/index.spec.js
@@ -1,4 +1,3 @@
-/* eslint-disable no-console */
import { createDelegatedRoutingV1HttpApiServer } from '@helia/delegated-routing-v1-http-api-server'
import { peerIdFromString } from '@libp2p/peer-id'
import { createHelia, libp2pDefaults } from 'helia'
@@ -59,7 +58,6 @@ test.describe('delegated routing example:', () => {
let helia
let fastify
- // eslint-disable-next-line no-empty-pattern
test.beforeAll(async ({ servers }, testInfo) => {
testInfo.setTimeout(5 * 60_000)
const r = await spawnServer()
diff --git a/examples/js-libp2p-example-discovery-mechanisms/3-pubsub.js b/examples/js-libp2p-example-discovery-mechanisms/3-pubsub.js
index 4522829..9db7541 100644
--- a/examples/js-libp2p-example-discovery-mechanisms/3-pubsub.js
+++ b/examples/js-libp2p-example-discovery-mechanisms/3-pubsub.js
@@ -1,9 +1,9 @@
/* eslint-disable no-console */
-import { gossipsub } from '@chainsafe/libp2p-gossipsub'
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { bootstrap } from '@libp2p/bootstrap'
+import { floodsub } from '@libp2p/floodsub'
import { identify } from '@libp2p/identify'
import { pubsubPeerDiscovery } from '@libp2p/pubsub-peer-discovery'
import { tcp } from '@libp2p/tcp'
@@ -23,7 +23,7 @@ const createNode = async (bootstrappers = []) => {
})
],
services: {
- pubsub: gossipsub(),
+ pubsub: floodsub(),
identify: identify()
}
}
diff --git a/examples/js-libp2p-example-discovery-mechanisms/README.md b/examples/js-libp2p-example-discovery-mechanisms/README.md
index 1fd5035..8b7b546 100644
--- a/examples/js-libp2p-example-discovery-mechanisms/README.md
+++ b/examples/js-libp2p-example-discovery-mechanisms/README.md
@@ -127,6 +127,9 @@ Pub/sub based peer discovery is useful for deployments where other mechanisms ma
You can find the complete solution at [3-pubsub.js](./3-pubsub.js).
+> [!TIP]
+> The pubsub example uses `@libp2p/floodsub` - it is not suitable for production use, instead use `@chainsafe/libp2p-gossipsub`
+
In the example we create three nodes. The first is used to bootstrap the network. The second and third dial the bootstrapper, then discover each other via the pub/sub peer discovery topic.
## 4. Where to find other Peer Discovery Mechanisms
diff --git a/examples/js-libp2p-example-discovery-mechanisms/package.json b/examples/js-libp2p-example-discovery-mechanisms/package.json
index 020b74c..ad641b2 100644
--- a/examples/js-libp2p-example-discovery-mechanisms/package.json
+++ b/examples/js-libp2p-example-discovery-mechanisms/package.json
@@ -16,22 +16,21 @@
"test": "test-node-example test/*"
},
"dependencies": {
- "@chainsafe/libp2p-gossipsub": "^14.1.0",
- "@chainsafe/libp2p-noise": "^16.0.0",
- "@chainsafe/libp2p-yamux": "^7.0.0",
- "@libp2p/bootstrap": "^11.0.0",
- "@libp2p/circuit-relay-v2": "^3.0.0",
- "@libp2p/identify": "^3.0.0",
- "@libp2p/kad-dht": "^15.0.0",
- "@libp2p/mdns": "^11.0.0",
- "@libp2p/ping": "^2.0.27",
- "@libp2p/pubsub-peer-discovery": "^11.0.0",
- "@libp2p/tcp": "^10.0.0",
- "libp2p": "^2.0.0"
+ "@chainsafe/libp2p-noise": "^17.0.0",
+ "@chainsafe/libp2p-yamux": "^8.0.0",
+ "@libp2p/bootstrap": "^12.0.2",
+ "@libp2p/floodsub": "^11.0.1",
+ "@libp2p/identify": "^4.0.1",
+ "@libp2p/kad-dht": "^16.0.1",
+ "@libp2p/mdns": "^12.0.2",
+ "@libp2p/ping": "^3.0.1",
+ "@libp2p/pubsub-peer-discovery": "^12.0.0",
+ "@libp2p/tcp": "^11.0.1",
+ "libp2p": "^3.0.2"
},
"devDependencies": {
"execa": "^9.2.0",
- "p-wait-for": "^5.0.2",
+ "p-wait-for": "^6.0.0",
"test-ipfs-example": "^1.1.0",
"uint8arrays": "^5.1.0"
},
diff --git a/examples/js-libp2p-example-peer-and-content-routing/package.json b/examples/js-libp2p-example-peer-and-content-routing/package.json
index ad19a06..1136ce0 100644
--- a/examples/js-libp2p-example-peer-and-content-routing/package.json
+++ b/examples/js-libp2p-example-peer-and-content-routing/package.json
@@ -13,18 +13,17 @@
},
"type": "module",
"scripts": {
- "lint": "aegir lint",
"test": "test-node-example test/*"
},
"dependencies": {
- "@chainsafe/libp2p-noise": "^16.0.0",
- "@chainsafe/libp2p-yamux": "^7.0.0",
- "@libp2p/identify": "^3.0.1",
- "@libp2p/kad-dht": "^15.0.0",
- "@libp2p/ping": "^2.0.27",
- "@libp2p/tcp": "^10.0.0",
+ "@chainsafe/libp2p-noise": "^17.0.0",
+ "@chainsafe/libp2p-yamux": "^8.0.0",
+ "@libp2p/identify": "^4.0.1",
+ "@libp2p/kad-dht": "^16.0.1",
+ "@libp2p/ping": "^3.0.1",
+ "@libp2p/tcp": "^11.0.1",
"it-all": "^3.0.2",
- "libp2p": "^2.0.0",
+ "libp2p": "^3.0.2",
"multiformats": "^13.1.1"
},
"devDependencies": {
diff --git a/examples/js-libp2p-example-pnet/index.js b/examples/js-libp2p-example-pnet/index.js
index 5a00839..623948e 100644
--- a/examples/js-libp2p-example-pnet/index.js
+++ b/examples/js-libp2p-example-pnet/index.js
@@ -1,7 +1,6 @@
/* eslint no-console: ["off"] */
import { generateKey } from '@libp2p/pnet'
-import { pipe } from 'it-pipe'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
import { privateLibp2pNode } from './libp2p-node.js'
@@ -25,20 +24,12 @@ console.log('nodes started...')
// connect node1 to node2
await node1.dial(node2.getMultiaddrs())
-node2.handle('/private', ({ stream }) => {
- pipe(
- stream,
- async function (source) {
- for await (const msg of source) {
- console.log(uint8ArrayToString(msg.subarray()))
- }
- }
- )
+node2.handle('/private', (stream) => {
+ stream.addEventListener('message', (evt) => {
+ console.log(uint8ArrayToString(evt.data.subarray()))
+ })
})
const stream = await node1.dialProtocol(node2.peerId, '/private')
-await pipe(
- [uint8ArrayFromString('This message is sent on a private network')],
- stream
-)
+stream.send(uint8ArrayFromString('This message is sent on a private network'))
diff --git a/examples/js-libp2p-example-pnet/package.json b/examples/js-libp2p-example-pnet/package.json
index 0b427d7..9de69a9 100644
--- a/examples/js-libp2p-example-pnet/package.json
+++ b/examples/js-libp2p-example-pnet/package.json
@@ -16,12 +16,11 @@
"test": "test-node-example test/*"
},
"dependencies": {
- "@chainsafe/libp2p-noise": "^16.0.0",
- "@chainsafe/libp2p-yamux": "^7.0.0",
- "@libp2p/pnet": "^2.0.1",
- "@libp2p/tcp": "^10.0.0",
- "it-pipe": "^3.0.1",
- "libp2p": "^2.0.0",
+ "@chainsafe/libp2p-noise": "^17.0.0",
+ "@chainsafe/libp2p-yamux": "^8.0.0",
+ "@libp2p/pnet": "^3.0.3",
+ "@libp2p/tcp": "^11.0.1",
+ "libp2p": "^3.0.2",
"uint8arrays": "^5.1.0"
},
"devDependencies": {
diff --git a/examples/js-libp2p-example-protocol-and-stream-muxing/1.js b/examples/js-libp2p-example-protocol-and-stream-muxing/1.js
index a80ccf2..106064c 100644
--- a/examples/js-libp2p-example-protocol-and-stream-muxing/1.js
+++ b/examples/js-libp2p-example-protocol-and-stream-muxing/1.js
@@ -3,7 +3,6 @@
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { tcp } from '@libp2p/tcp'
-import { pipe } from 'it-pipe'
import { createLibp2p } from 'libp2p'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
@@ -27,46 +26,31 @@ const [node1, node2] = await Promise.all([
])
// exact matching
-node2.handle('/your-protocol', ({ stream }) => {
- pipe(
- stream,
- async function (source) {
- for await (const msg of source) {
- console.log(uint8ArrayToString(msg.subarray()))
- }
- }
- )
+node2.handle('/your-protocol', (stream) => {
+ stream.addEventListener('message', (evt) => {
+ console.log(uint8ArrayToString(evt.data.subarray()))
+ })
})
// multiple protocols
/*
-node2.handle(['/another-protocol/1.0.0', '/another-protocol/2.0.0'], ({ protocol, stream }) => {
- if (protocol === '/another-protocol/2.0.0') {
+node2.handle(['/another-protocol/1.0.0', '/another-protocol/2.0.0'], (stream) => {
+ if (stream.protocol === '/another-protocol/2.0.0') {
// handle backwards compatibility
}
- pipe(
- stream,
- async function (source) {
- for await (const msg of source) {
- console.log(uint8ArrayToString(msg))
- }
- }
- )
+ stream.addEventListener('message', (evt) => {
+ console.log(uint8ArrayToString(evt.data.subarray()))
+ })
})
*/
const stream = await node1.dialProtocol(node2.getMultiaddrs(), ['/your-protocol'])
-await pipe(
- [uint8ArrayFromString('my own protocol, wow!')],
- stream
-)
+
+stream.send(uint8ArrayFromString('my own protocol, wow!'))
/*
const stream = node1.dialProtocol(node2.peerId, ['/another-protocol/1.0.0'])
-await pipe(
- ['my own protocol, wow!'],
- stream
-)
+stream.send(uint8ArrayFromString('my own protocol, wow!'))
*/
diff --git a/examples/js-libp2p-example-protocol-and-stream-muxing/2.js b/examples/js-libp2p-example-protocol-and-stream-muxing/2.js
index 3f4a011..51a9997 100644
--- a/examples/js-libp2p-example-protocol-and-stream-muxing/2.js
+++ b/examples/js-libp2p-example-protocol-and-stream-muxing/2.js
@@ -3,7 +3,6 @@
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { tcp } from '@libp2p/tcp'
-import { pipe } from 'it-pipe'
import { createLibp2p } from 'libp2p'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
@@ -31,34 +30,24 @@ await node1.peerStore.patch(node2.peerId, {
multiaddrs: node2.getMultiaddrs()
})
-node2.handle(['/a', '/b'], ({ protocol, stream }) => {
- pipe(
- stream,
- async function (source) {
- for await (const msg of source) {
- console.log(`from: ${protocol}, msg: ${uint8ArrayToString(msg.subarray())}`)
- }
- }
- ).finally(() => {
+node2.handle(['/a', '/b'], (stream) => {
+ stream.addEventListener('message', (evt) => {
+ console.log(`from: ${stream.protocol}, msg: ${uint8ArrayToString(evt.data.subarray())}`)
+ })
+ stream.addEventListener('remoteCloseWrite', () => {
// clean up resources
stream.close()
+ .catch(err => {
+ stream.abort(err)
+ })
})
})
-const stream1 = await node1.dialProtocol(node2.peerId, ['/a'])
-await pipe(
- [uint8ArrayFromString('protocol (a)')],
- stream1
-)
+const stream = await node1.dialProtocol(node2.peerId, ['/a'])
+stream.send(uint8ArrayFromString('protocol (a)'))
const stream2 = await node1.dialProtocol(node2.peerId, ['/b'])
-await pipe(
- [uint8ArrayFromString('protocol (b)')],
- stream2
-)
+stream2.send(uint8ArrayFromString('protocol (b)'))
const stream3 = await node1.dialProtocol(node2.peerId, ['/b'])
-await pipe(
- [uint8ArrayFromString('another stream on protocol (b)')],
- stream3
-)
+stream3.send(uint8ArrayFromString('another stream on protocol (b)'))
diff --git a/examples/js-libp2p-example-protocol-and-stream-muxing/3.js b/examples/js-libp2p-example-protocol-and-stream-muxing/3.js
index f153de6..c7321cf 100644
--- a/examples/js-libp2p-example-protocol-and-stream-muxing/3.js
+++ b/examples/js-libp2p-example-protocol-and-stream-muxing/3.js
@@ -3,7 +3,6 @@
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { tcp } from '@libp2p/tcp'
-import { pipe } from 'it-pipe'
import { createLibp2p } from 'libp2p'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
@@ -31,36 +30,20 @@ await node1.peerStore.patch(node2.peerId, {
multiaddrs: node2.getMultiaddrs()
})
-node1.handle('/node-1', ({ stream }) => {
- pipe(
- stream,
- async function (source) {
- for await (const msg of source) {
- console.log(uint8ArrayToString(msg.subarray()))
- }
- }
- )
+node1.handle('/node-1', (stream) => {
+ stream.addEventListener('message', (evt) => {
+ console.log(`from: ${stream.protocol}, msg: ${uint8ArrayToString(evt.data.subarray())}`)
+ })
})
-node2.handle('/node-2', ({ stream }) => {
- pipe(
- stream,
- async function (source) {
- for await (const msg of source) {
- console.log(uint8ArrayToString(msg.subarray()))
- }
- }
- )
+node2.handle('/node-2', (stream) => {
+ stream.addEventListener('message', (evt) => {
+ console.log(`from: ${stream.protocol}, msg: ${uint8ArrayToString(evt.data.subarray())}`)
+ })
})
const stream1 = await node1.dialProtocol(node2.peerId, ['/node-2'])
-await pipe(
- [uint8ArrayFromString('from 1 to 2')],
- stream1
-)
+stream1.send(uint8ArrayFromString('from 1 to 2'))
const stream2 = await node2.dialProtocol(node1.peerId, ['/node-1'])
-await pipe(
- [uint8ArrayFromString('from 2 to 1')],
- stream2
-)
+stream2.send(uint8ArrayFromString('from 2 to 1'))
diff --git a/examples/js-libp2p-example-protocol-and-stream-muxing/README.md b/examples/js-libp2p-example-protocol-and-stream-muxing/README.md
index 9f59e8c..3d0a2c3 100644
--- a/examples/js-libp2p-example-protocol-and-stream-muxing/README.md
+++ b/examples/js-libp2p-example-protocol-and-stream-muxing/README.md
@@ -27,8 +27,6 @@ for this example: `libp2p`, `@libp2p/tcp`, `@libp2p/peer-id`, `it-pipe`,
After creating the nodes, we need to tell libp2p which protocols to handle.
```JavaScript
-import { pipe } from 'it-pipe'
-import { map } from 'streaming-iterables'
import { toBuffer } from 'it-buffer'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
@@ -47,15 +45,10 @@ await node1.peerStore.patch(node2.peerId, {
// Here we are telling libp2p that if someone dials this node to talk with the `/your-protocol`
// multicodec, the protocol identifier, please call this handler and give it the stream
// so that incomming data can be handled
-node2.handle('/your-protocol', ({ stream }) => {
- pipe(
- stream,
- source => (async function () {
- for await (const msg of source) {
- console.log(uint8ArrayToString(msg.subarray()))
- }
- })()
- )
+node2.handle('/your-protocol', (stream) => {
+ stream.addEventListener('message', (evt) => {
+ console.log(uint8ArrayToString(evt.data.subarray()))
+ })
})
```
@@ -64,10 +57,7 @@ After the protocol is *handled*, now we can dial to it.
```JavaScript
const stream = await node1.dialProtocol(node2.peerId, ['/your-protocol'])
-await pipe(
- [uint8ArrayFromString('my own protocol, wow!')],
- stream
-)
+stream.send(uint8ArrayFromString('my own protocol, wow!'))
```
You might have seen this in the [Transports](../transports) examples. However,
@@ -75,23 +65,15 @@ what it was not explained is that you can do more than exact string matching,
for example, you can use semver.
```JavaScript
-node2.handle('/another-protocol/1.0.1', ({ stream }) => {
- pipe(
- stream,
- async function (source) {
- for await (const msg of source) {
- console.log(uint8ArrayToString(msg.subarray()))
- }
- }
- )
+node2.handle('/another-protocol/1.0.1', (stream) => {
+ stream.addEventListener('message', (evt) => {
+ console.log(uint8ArrayToString(evt.data.subarray()))
+ })
})
// ...
const stream = await node1.dialProtocol(node2.peerId, ['/another-protocol/1.0.0'])
-await pipe(
- [uint8ArrayFromString('my own protocol, wow!')],
- stream
-)
+stream.send(uint8ArrayFromString('my own protocol, wow!'))
```
This feature is super power for network protocols. It works in the same way as
@@ -105,19 +87,14 @@ changes to the code, you may prefer to do protocol checking instead of having
multiple handlers
```JavaScript
-node2.handle(['/another-protocol/1.0.0', '/another-protocol/2.0.0'], ({ stream }) => {
+node2.handle(['/another-protocol/1.0.0', '/another-protocol/2.0.0'], (stream) => {
if (stream.protocol === '/another-protocol/2.0.0') {
// handle backwards compatibility
}
- pipe(
- stream,
- async function (source) {
- for await (const msg of source) {
- console.log(uint8ArrayToString(msg.subarray()))
- }
- }
- )
+ stream.addEventListener('message', (evt) => {
+ console.log(uint8ArrayToString(evt.data.subarray()))
+ })
})
```
@@ -164,34 +141,20 @@ With this, we can dial as many times as we want to a peer and always reuse the
same established underlying connection.
```JavaScript
-node2.handle(['/a', '/b'], ({ stream }) => {
- pipe(
- stream,
- async function (source) {
- for await (const msg of source) {
- console.log(`from: ${stream.protocol}, msg: ${uint8ArrayToString(msg.subarray())}`)
- }
- }
- )
+node2.handle(['/a', '/b'], (stream) => {
+ stream.addEventListener('message', (evt) => {
+ console.log(`from: ${stream.protocol}, msg: ${uint8ArrayToString(evt.data.subarray())}`)
+ })
})
const stream = await node1.dialProtocol(node2.peerId, ['/a'])
-await pipe(
- [uint8ArrayFromString('protocol (a)')],
- stream
-)
+stream.send(uint8ArrayFromString('protocol (a)'))
const stream2 = await node1.dialProtocol(node2.peerId, ['/b'])
-await pipe(
- [uint8ArrayFromString('protocol (b)')],
- stream2
-)
+stream2.send(uint8ArrayFromString('protocol (b)'))
const stream3 = await node1.dialProtocol(node2.peerId, ['/b'])
-await pipe(
- [uint8ArrayFromString('another stream on protocol (b)')],
- stream3
-)
+stream3.send(uint8ArrayFromString('another stream on protocol (b)'))
```
By running [2.js](./2.js) you should see the following result:
@@ -257,41 +220,25 @@ because we want to dial up a bidirectional connection between these two nodes.
Finally, let's create protocols for `node1` & `node2` and dial those protocols.
```js
-node1.handle('/node-1', ({ stream }) => {
- pipe(
- stream,
- async function (source) {
- for await (const msg of source) {
- console.log(uint8ArrayToString(msg.subarray()))
- }
- }
- )
+node1.handle('/node-1', (stream) => {
+ stream.addEventListener('message', (evt) => {
+ console.log(uint8ArrayToString(evt.data.subarray()))
+ })
})
node2.handle('/node-2', ({ stream }) => {
- pipe(
- stream,
- async function (source) {
- for await (const msg of source) {
- console.log(uint8ArrayToString(msg.subarray()))
- }
- }
- )
+ stream.addEventListener('message', (evt) => {
+ console.log(uint8ArrayToString(evt.data.subarray()))
+ })
})
// Dialing node2 from node1
const stream1 = await node1.dialProtocol(node2.peerId, ['/node-2'])
-await pipe(
- [uint8ArrayFromString('from 1 to 2')],
- stream1
-)
+stream1.send(uint8ArrayFromString('from 1 to 2'))
// Dialing node1 from node2
const stream2 = await node2.dialProtocol(node1.peerId, ['/node-1'])
-await pipe(
- [uint8ArrayFromString('from 2 to 1')],
- stream2
-)
+stream2.send(uint8ArrayFromString('from 2 to 1'))
```
If we run this code, the result should look like the following:
@@ -314,17 +261,11 @@ The code below will result into an error as `the dial address is not valid`.
```js
// Dialing from node2 to node1
const stream2 = await node2.dialProtocol(node1.peerId, ['/node-1'])
-await pipe(
- [uint8ArrayFromString('from 2 to 1')],
- stream2
-)
+stream2.send(uint8ArrayFromString('from 2 to 1'))
// Dialing from node1 to node2
const stream1 = await node1.dialProtocol(node2.peerId, ['/node-2'])
-await pipe(
- [uint8ArrayFromString('from 1 to 2')],
- stream1
-)
+stream1.send(uint8ArrayFromString('from 1 to 2'))
```
## Need help?
diff --git a/examples/js-libp2p-example-protocol-and-stream-muxing/package.json b/examples/js-libp2p-example-protocol-and-stream-muxing/package.json
index ed34f38..773215c 100644
--- a/examples/js-libp2p-example-protocol-and-stream-muxing/package.json
+++ b/examples/js-libp2p-example-protocol-and-stream-muxing/package.json
@@ -16,11 +16,10 @@
"test": "test-node-example test/*"
},
"dependencies": {
- "@chainsafe/libp2p-noise": "^16.0.0",
- "@chainsafe/libp2p-yamux": "^7.0.0",
- "@libp2p/tcp": "^10.0.0",
- "it-pipe": "^3.0.1",
- "libp2p": "^2.0.0",
+ "@chainsafe/libp2p-noise": "^17.0.0",
+ "@chainsafe/libp2p-yamux": "^8.0.0",
+ "@libp2p/tcp": "^11.0.1",
+ "libp2p": "^3.0.2",
"uint8arrays": "^5.1.0"
},
"devDependencies": {
diff --git a/examples/js-libp2p-example-pubsub/1.js b/examples/js-libp2p-example-pubsub/1.js
index 22b1909..a772677 100644
--- a/examples/js-libp2p-example-pubsub/1.js
+++ b/examples/js-libp2p-example-pubsub/1.js
@@ -1,8 +1,8 @@
/* eslint-disable no-console */
-import { gossipsub } from '@chainsafe/libp2p-gossipsub'
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
+import { floodsub } from '@libp2p/floodsub'
import { identify, identifyPush } from '@libp2p/identify'
import { tcp } from '@libp2p/tcp'
import { createLibp2p } from 'libp2p'
@@ -18,7 +18,7 @@ const createNode = async () => {
streamMuxers: [yamux()],
connectionEncrypters: [noise()],
services: {
- pubsub: gossipsub(),
+ pubsub: floodsub(),
identify: identify(),
identifyPush: identifyPush()
}
diff --git a/examples/js-libp2p-example-pubsub/2.js b/examples/js-libp2p-example-pubsub/2.js
index d51bdbe..6d5bb79 100644
--- a/examples/js-libp2p-example-pubsub/2.js
+++ b/examples/js-libp2p-example-pubsub/2.js
@@ -1,8 +1,8 @@
/* eslint-disable no-console */
-import { gossipsub } from '@chainsafe/libp2p-gossipsub'
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
+import { floodsub } from '@libp2p/floodsub'
import { identify, identifyPush } from '@libp2p/identify'
import { tcp } from '@libp2p/tcp'
import { createLibp2p } from 'libp2p'
@@ -18,7 +18,7 @@ const createNode = async () => {
streamMuxers: [yamux()],
connectionEncrypters: [noise()],
services: {
- pubsub: gossipsub(),
+ pubsub: floodsub(),
identify: identify(),
identifyPush: identifyPush()
}
diff --git a/examples/js-libp2p-example-pubsub/README.md b/examples/js-libp2p-example-pubsub/README.md
index f2b81da..8f5ddc1 100644
--- a/examples/js-libp2p-example-pubsub/README.md
+++ b/examples/js-libp2p-example-pubsub/README.md
@@ -13,6 +13,9 @@ We've seen many interesting use cases appear with this, here are some highlights
- [IPFS PubSub (using libp2p-floodsub) for IoT](https://www.youtube.com/watch?v=qLpM5pBDGiE).
- [Real Time distributed Applications](https://www.youtube.com/watch?v=vQrbxyDPSXg)
+> [!TIP]
+> This example uses `@libp2p/floodsub` as a pubsub implementation - it is not suitable for production use, instead use `@chainsafe/libp2p-gossipsub`
+
## 0. Set up the example
Clone this repo and run `npm install` in the root.
diff --git a/examples/js-libp2p-example-pubsub/package.json b/examples/js-libp2p-example-pubsub/package.json
index 41a0cd4..33a18e9 100644
--- a/examples/js-libp2p-example-pubsub/package.json
+++ b/examples/js-libp2p-example-pubsub/package.json
@@ -28,12 +28,12 @@
"test": "test-node-example test/*"
},
"dependencies": {
- "@chainsafe/libp2p-gossipsub": "^14.1.0",
- "@chainsafe/libp2p-noise": "^16.0.0",
- "@chainsafe/libp2p-yamux": "^7.0.0",
- "@libp2p/identify": "^3.0.1",
- "@libp2p/tcp": "^10.0.0",
- "libp2p": "^2.0.0",
+ "@chainsafe/libp2p-noise": "^17.0.0",
+ "@chainsafe/libp2p-yamux": "^8.0.0",
+ "@libp2p/floodsub": "^11.0.1",
+ "@libp2p/identify": "^4.0.1",
+ "@libp2p/tcp": "^11.0.1",
+ "libp2p": "^3.0.2",
"uint8arrays": "^5.1.0"
},
"devDependencies": {
diff --git a/examples/js-libp2p-example-transports/2.js b/examples/js-libp2p-example-transports/2.js
index 9acf08b..086b889 100644
--- a/examples/js-libp2p-example-transports/2.js
+++ b/examples/js-libp2p-example-transports/2.js
@@ -3,9 +3,8 @@
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { tcp } from '@libp2p/tcp'
-import { pipe } from 'it-pipe'
-import toBuffer from 'it-to-buffer'
import { createLibp2p } from 'libp2p'
+import { Uint8ArrayList } from 'uint8arraylist'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
@@ -37,17 +36,15 @@ const [node1, node2] = await Promise.all([
printAddrs(node1, '1')
printAddrs(node2, '2')
-node2.handle('/print', async ({ stream }) => {
- const result = await pipe(
- stream,
- async function * (source) {
- for await (const list of source) {
- yield list.subarray()
- }
- },
- toBuffer
- )
- console.log(uint8ArrayToString(result))
+node2.handle('/print', async (stream) => {
+ const bufs = new Uint8ArrayList()
+
+ stream.addEventListener('message', (evt) => {
+ bufs.append(evt.data)
+ })
+ stream.addEventListener('remoteCloseWrite', () => {
+ console.log(uint8ArrayToString(bufs.subarray()))
+ })
})
await node1.peerStore.patch(node2.peerId, {
@@ -55,7 +52,5 @@ await node1.peerStore.patch(node2.peerId, {
})
const stream = await node1.dialProtocol(node2.peerId, '/print')
-await pipe(
- ['Hello', ' ', 'p2p', ' ', 'world', '!'].map(str => uint8ArrayFromString(str)),
- stream
-)
+;['Hello', ' ', 'p2p', ' ', 'world', '!'].map(str => stream.send(uint8ArrayFromString(str)))
+await stream.close()
diff --git a/examples/js-libp2p-example-transports/3.js b/examples/js-libp2p-example-transports/3.js
index 7e87d84..de18850 100644
--- a/examples/js-libp2p-example-transports/3.js
+++ b/examples/js-libp2p-example-transports/3.js
@@ -4,7 +4,6 @@ import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { tcp } from '@libp2p/tcp'
import { webSockets } from '@libp2p/websockets'
-import { pipe } from 'it-pipe'
import { createLibp2p } from 'libp2p'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
@@ -31,15 +30,10 @@ function printAddrs (node, number) {
node.getMultiaddrs().forEach((ma) => console.log(ma.toString()))
}
-function print ({ stream }) {
- pipe(
- stream,
- async function (source) {
- for await (const msg of source) {
- console.log(uint8ArrayToString(msg.subarray()))
- }
- }
- )
+function print (stream) {
+ stream.addEventListener('message', (evt) => {
+ console.log(uint8ArrayToString(evt.data.subarray()))
+ })
}
const [node1, node2, node3] = await Promise.all([
@@ -68,17 +62,11 @@ await node3.peerStore.patch(node1.peerId, {
// node 1 (TCP) dials to node 2 (TCP+WebSockets)
const stream = await node1.dialProtocol(node2.peerId, '/print')
-await pipe(
- [uint8ArrayFromString('node 1 dialed to node 2 successfully')],
- stream
-)
+stream.send(uint8ArrayFromString('node 1 dialed to node 2 successfully'))
// node 2 (TCP+WebSockets) dials to node 3 (WebSockets)
const stream2 = await node2.dialProtocol(node3.peerId, '/print')
-await pipe(
- [uint8ArrayFromString('node 2 dialed to node 3 successfully')],
- stream2
-)
+stream2.send(uint8ArrayFromString('node 2 dialed to node 3 successfully'))
// node 3 (listening WebSockets) can dial node 1 (TCP)
try {
diff --git a/examples/js-libp2p-example-transports/4.js b/examples/js-libp2p-example-transports/4.js
index da32820..32025a5 100644
--- a/examples/js-libp2p-example-transports/4.js
+++ b/examples/js-libp2p-example-transports/4.js
@@ -5,10 +5,25 @@ import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { tcp } from '@libp2p/tcp'
import { webSockets } from '@libp2p/websockets'
-import { pipe } from 'it-pipe'
import { createLibp2p } from 'libp2p'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
+import {
+ setGlobalDispatcher,
+ Agent
+} from 'undici'
+
+// allow self-signed certificates
+setGlobalDispatcher(new Agent({
+ connect: {
+ rejectUnauthorized: false
+ }
+}))
+
+process.on('uncaughtException', (err) => {
+ console.error(err.error)
+ process.exit(1)
+})
const createNode = async (addresses = []) => {
if (!Array.isArray(addresses)) {
@@ -43,19 +58,14 @@ function printAddrs (node, number) {
node.getMultiaddrs().forEach((ma) => console.log(ma.toString()))
}
-function print ({ stream }) {
- pipe(
- stream,
- async function (source) {
- for await (const msg of source) {
- console.log(uint8ArrayToString(msg.subarray()))
- }
- }
- )
+function print (stream) {
+ stream.addEventListener('message', (evt) => {
+ console.log(uint8ArrayToString(evt.data.subarray()))
+ })
}
const [node1, node2] = await Promise.all([
- createNode('/ip4/127.0.0.1/tcp/10000/wss'),
+ createNode('/ip4/127.0.0.1/tcp/10000/tls/ws'),
createNode([])
])
@@ -69,7 +79,4 @@ const targetAddr = node1.getMultiaddrs()[0]
// node 2 (Secure WebSockets) dials to node 1 (Secure Websockets)
const stream = await node2.dialProtocol(targetAddr, '/print')
-await pipe(
- [uint8ArrayFromString('node 2 dialed to node 1 successfully')],
- stream
-)
+stream.send(uint8ArrayFromString('node 2 dialed to node 1 successfully'))
diff --git a/examples/js-libp2p-example-transports/package.json b/examples/js-libp2p-example-transports/package.json
index 86e6512..ab0f0f4 100644
--- a/examples/js-libp2p-example-transports/package.json
+++ b/examples/js-libp2p-example-transports/package.json
@@ -16,14 +16,14 @@
"test": "test-node-example test/*"
},
"dependencies": {
- "@chainsafe/libp2p-noise": "^16.0.0",
- "@chainsafe/libp2p-yamux": "^7.0.0",
- "@libp2p/tcp": "^10.0.0",
- "@libp2p/websockets": "^9.1.0",
- "it-pipe": "^3.0.1",
- "it-to-buffer": "^4.0.2",
- "libp2p": "^2.0.0",
- "uint8arrays": "^5.1.0"
+ "@chainsafe/libp2p-noise": "^17.0.0",
+ "@chainsafe/libp2p-yamux": "^8.0.0",
+ "@libp2p/tcp": "^11.0.1",
+ "@libp2p/websockets": "^10.0.1",
+ "libp2p": "^3.0.2",
+ "uint8arraylist": "^2.4.8",
+ "uint8arrays": "^5.1.0",
+ "undici": "^7.16.0"
},
"devDependencies": {
"test-ipfs-example": "^1.1.0"
diff --git a/examples/js-libp2p-example-webrtc-private-to-private/index.js b/examples/js-libp2p-example-webrtc-private-to-private/index.js
index 1eb1952..c6c5d01 100644
--- a/examples/js-libp2p-example-webrtc-private-to-private/index.js
+++ b/examples/js-libp2p-example-webrtc-private-to-private/index.js
@@ -3,16 +3,14 @@ import { yamux } from '@chainsafe/libp2p-yamux'
import { circuitRelayTransport } from '@libp2p/circuit-relay-v2'
import { identify, identifyPush } from '@libp2p/identify'
import { ping } from '@libp2p/ping'
+import { byteStream } from '@libp2p/utils'
import { webRTC } from '@libp2p/webrtc'
import { webSockets } from '@libp2p/websockets'
-import * as filters from '@libp2p/websockets/filters'
-import { multiaddr, protocols } from '@multiformats/multiaddr'
-import { byteStream } from 'it-byte-stream'
+import { multiaddr } from '@multiformats/multiaddr'
+import { WebRTC } from '@multiformats/multiaddr-matcher'
import { createLibp2p } from 'libp2p'
import { fromString, toString } from 'uint8arrays'
-const WEBRTC_CODE = protocols('webrtc').code
-
const output = document.getElementById('output')
const sendSection = document.getElementById('send-section')
const appendOutput = (line) => {
@@ -32,9 +30,7 @@ const node = await createLibp2p({
]
},
transports: [
- webSockets({
- filter: filters.all
- }),
+ webSockets(),
webRTC(),
circuitRelayTransport()
],
@@ -62,7 +58,7 @@ function updateConnList () {
// Update connections list
const connListEls = node.getConnections()
.map((connection) => {
- if (connection.remoteAddr.protoCodes().includes(WEBRTC_CODE)) {
+ if (WebRTC.matches(connection.remoteAddr)) {
ma = connection.remoteAddr
sendSection.style.display = 'block'
}
@@ -84,7 +80,7 @@ node.addEventListener('connection:close', (event) => {
node.addEventListener('self:peer:update', (event) => {
// Update multiaddrs list, only show WebRTC addresses
const multiaddrs = node.getMultiaddrs()
- .filter(ma => isWebrtc(ma))
+ .filter(ma => WebRTC.matches(ma))
.map((ma) => {
const el = document.createElement('li')
el.textContent = ma.toString()
@@ -93,7 +89,7 @@ node.addEventListener('self:peer:update', (event) => {
document.getElementById('multiaddrs').replaceChildren(...multiaddrs)
})
-node.handle(CHAT_PROTOCOL, async ({ stream }) => {
+node.handle(CHAT_PROTOCOL, async (stream) => {
chatStream = byteStream(stream)
while (true) {
@@ -102,10 +98,6 @@ node.handle(CHAT_PROTOCOL, async ({ stream }) => {
}
})
-const isWebrtc = (ma) => {
- return ma.protoCodes().includes(WEBRTC_CODE)
-}
-
window.connect.onclick = async () => {
ma = multiaddr(window.peer.value)
appendOutput(`Dialing '${ma}'`)
@@ -113,7 +105,7 @@ window.connect.onclick = async () => {
const signal = AbortSignal.timeout(5000)
try {
- if (isWebrtc(ma)) {
+ if (WebRTC.matches(ma)) {
const rtt = await node.services.ping.ping(ma, {
signal
})
diff --git a/examples/js-libp2p-example-webrtc-private-to-private/package.json b/examples/js-libp2p-example-webrtc-private-to-private/package.json
index df804f2..34379d4 100644
--- a/examples/js-libp2p-example-webrtc-private-to-private/package.json
+++ b/examples/js-libp2p-example-webrtc-private-to-private/package.json
@@ -12,16 +12,18 @@
"test": "npm run build && test-browser-example test"
},
"dependencies": {
- "@chainsafe/libp2p-noise": "^16.0.0",
- "@chainsafe/libp2p-yamux": "^7.0.0",
- "@libp2p/circuit-relay-v2": "^3.0.0",
- "@libp2p/identify": "^3.0.1",
- "@libp2p/ping": "^2.0.1",
- "@libp2p/webrtc": "^5.0.0",
- "@libp2p/websockets": "^9.0.0",
- "@multiformats/multiaddr": "^12.0.0",
- "it-pushable": "^3.2.0",
- "libp2p": "^2.0.0",
+ "@chainsafe/libp2p-noise": "^17.0.0",
+ "@chainsafe/libp2p-yamux": "^8.0.0",
+ "@libp2p/circuit-relay-v2": "^4.0.1",
+ "@libp2p/identify": "^4.0.1",
+ "@libp2p/ping": "^3.0.1",
+ "@libp2p/utils": "^7.0.1",
+ "@libp2p/webrtc": "^6.0.3",
+ "@libp2p/websockets": "^10.0.1",
+ "@multiformats/multiaddr": "^13.0.1",
+ "@multiformats/multiaddr-matcher": "^3.0.1",
+ "libp2p": "^3.0.2",
+ "uint8arrays": "^5.1.0",
"vite": "^6.0.3"
},
"devDependencies": {
diff --git a/examples/js-libp2p-example-webrtc-private-to-private/relay.js b/examples/js-libp2p-example-webrtc-private-to-private/relay.js
index 059ba3d..f6a81b8 100644
--- a/examples/js-libp2p-example-webrtc-private-to-private/relay.js
+++ b/examples/js-libp2p-example-webrtc-private-to-private/relay.js
@@ -5,7 +5,6 @@ import { yamux } from '@chainsafe/libp2p-yamux'
import { circuitRelayServer } from '@libp2p/circuit-relay-v2'
import { identify } from '@libp2p/identify'
import { webSockets } from '@libp2p/websockets'
-import * as filters from '@libp2p/websockets/filters'
import { createLibp2p } from 'libp2p'
const server = await createLibp2p({
@@ -13,9 +12,7 @@ const server = await createLibp2p({
listen: ['/ip4/127.0.0.1/tcp/0/ws']
},
transports: [
- webSockets({
- filter: filters.all
- })
+ webSockets()
],
connectionEncrypters: [noise()],
streamMuxers: [yamux()],
diff --git a/examples/js-libp2p-example-webrtc-private-to-private/test/index.spec.js b/examples/js-libp2p-example-webrtc-private-to-private/test/index.spec.js
index 2e16bea..4727383 100644
--- a/examples/js-libp2p-example-webrtc-private-to-private/test/index.spec.js
+++ b/examples/js-libp2p-example-webrtc-private-to-private/test/index.spec.js
@@ -1,10 +1,8 @@
-/* eslint-disable no-console */
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { circuitRelayServer } from '@libp2p/circuit-relay-v2'
import { identify } from '@libp2p/identify'
import { webSockets } from '@libp2p/websockets'
-import * as filters from '@libp2p/websockets/filters'
import { createLibp2p } from 'libp2p'
import { setup, expect } from 'test-ipfs-example/browser'
@@ -28,9 +26,7 @@ async function spawnRelay () {
listen: ['/ip4/127.0.0.1/tcp/0/ws']
},
transports: [
- webSockets({
- filter: filters.all
- })
+ webSockets()
],
connectionEncrypters: [noise()],
streamMuxers: [yamux()],
@@ -49,7 +45,6 @@ test.describe('browser to browser example:', () => {
let relayNode
let relayNodeAddr
- // eslint-disable-next-line no-empty-pattern
test.beforeAll(async ({ servers }, testInfo) => {
testInfo.setTimeout(5 * 60_000)
const r = await spawnRelay()
diff --git a/examples/js-libp2p-example-webrtc-private-to-public/.github/pull_request_template.md b/examples/js-libp2p-example-webrtc-private-to-public/.github/pull_request_template.md
new file mode 100644
index 0000000..accc1b8
--- /dev/null
+++ b/examples/js-libp2p-example-webrtc-private-to-public/.github/pull_request_template.md
@@ -0,0 +1,17 @@
+# ⚠️ IMPORTANT ⚠️
+
+# Please do not create a Pull Request for this repository
+
+The contents of this repository are automatically synced from the parent [js-libp2p Examples Project](https://github.com/libp2p/js-libp2p-examples) so any changes made to the standalone repository will be lost after the next sync.
+
+Please open a PR against [js-libp2p Examples](https://github.com/libp2p/js-libp2p-examples) instead.
+
+## Contributing
+
+Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.
+
+1. Fork the [js-libp2p Examples Project](https://github.com/libp2p/js-libp2p-examples)
+2. Create your Feature Branch (`git checkout -b feature/amazing-example`)
+3. Commit your Changes (`git commit -a -m 'feat: add some amazing example'`)
+4. Push to the Branch (`git push origin feature/amazing-example`)
+5. Open a Pull Request
diff --git a/examples/js-libp2p-example-webrtc-private-to-public/.github/workflows/sync.yml b/examples/js-libp2p-example-webrtc-private-to-public/.github/workflows/sync.yml
new file mode 100644
index 0000000..78f6c8d
--- /dev/null
+++ b/examples/js-libp2p-example-webrtc-private-to-public/.github/workflows/sync.yml
@@ -0,0 +1,19 @@
+name: pull
+
+on:
+ workflow_dispatch
+
+jobs:
+ sync:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Pull from another repository
+ uses: ipfs-examples/actions-pull-directory-from-repo@main
+ with:
+ source-repo: libp2p/js-libp2p-examples
+ source-folder-path: examples/${{ github.event.repository.name }}
+ source-branch: main
+ target-branch: main
+ git-username: github-actions
+ git-email: github-actions@github.com
diff --git a/examples/js-libp2p-example-webrtc-private-to-public/LICENSE b/examples/js-libp2p-example-webrtc-private-to-public/LICENSE
new file mode 100644
index 0000000..20ce483
--- /dev/null
+++ b/examples/js-libp2p-example-webrtc-private-to-public/LICENSE
@@ -0,0 +1,4 @@
+This project is dual licensed under MIT and Apache-2.0.
+
+MIT: https://www.opensource.org/licenses/mit
+Apache-2.0: https://www.apache.org/licenses/license-2.0
diff --git a/examples/js-libp2p-example-webrtc-private-to-public/LICENSE-APACHE b/examples/js-libp2p-example-webrtc-private-to-public/LICENSE-APACHE
new file mode 100644
index 0000000..14478a3
--- /dev/null
+++ b/examples/js-libp2p-example-webrtc-private-to-public/LICENSE-APACHE
@@ -0,0 +1,5 @@
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
diff --git a/examples/js-libp2p-example-webrtc-private-to-public/LICENSE-MIT b/examples/js-libp2p-example-webrtc-private-to-public/LICENSE-MIT
new file mode 100644
index 0000000..72dc60d
--- /dev/null
+++ b/examples/js-libp2p-example-webrtc-private-to-public/LICENSE-MIT
@@ -0,0 +1,19 @@
+The MIT License (MIT)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/examples/js-libp2p-example-webrtc-private-to-public/README.md b/examples/js-libp2p-example-webrtc-private-to-public/README.md
new file mode 100644
index 0000000..b609c63
--- /dev/null
+++ b/examples/js-libp2p-example-webrtc-private-to-public/README.md
@@ -0,0 +1,47 @@
+# @libp2p/example-webrtc-browser-to-server
+
+[](http://libp2p.io/)
+[](https://discuss.libp2p.io)
+[](https://codecov.io/gh/libp2p/js-libp2p-examples)
+[](https://github.com/libp2p/js-libp2p-examples/actions/workflows/ci.yml?query=branch%3Amain)
+
+This example leverages the [vite bundler](https://vitejs.dev/) to compile and serve the libp2p code in the browser. You can use other bundlers such as Webpack, but we will not be covering them here.
+
+## Running the Server
+
+To run the Go LibP2P WebRTC server:
+
+```console
+npm run server
+```
+
+Copy the multiaddress from the output.
+
+## Running the Example
+
+In a separate console tab, install dependencies and start the Vite server:
+
+```shell
+npm i && npm run start
+```
+
+The browser window will automatically open.
+Using the copied multiaddress from the Go server, paste it into the `Server MultiAddress` input and click the `Connect` button.
+Once the peer is connected, click the message section will appear. Enter a message and click the `Send` button.
+
+The output should look like:
+
+```text
+Dialing /ip4/10.0.1.5/udp/54375/webrtc/certhash/uEiADy8JubdWrAzseyzfXFyCpdRN02eWZg86tjCrTCA5dbQ/p2p/12D3KooWEG7N4bnZfFBNZE7WG6xm2P4Sr6sonMwyD4HCAqApEthb
+Peer connected '/ip4/10.0.1.5/udp/54375/webrtc/certhash/uEiADy8JubdWrAzseyzfXFyCpdRN02eWZg86tjCrTCA5dbQ/p2p/12D3KooWEG7N4bnZfFBNZE7WG6xm2P4Sr6sonMwyD4HCAqApEthb'
+Sending message 'hello'
+Received message 'hello'
+```
+
+## 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/)
+- Check out the [general libp2p documentation](https://docs.libp2p.io) for tips, how-tos and more
+- Read the [libp2p specs](https://github.com/libp2p/specs)
+- Ask a question on the [js-libp2p discussion board](https://github.com/libp2p/js-libp2p/discussions)
diff --git a/examples/js-libp2p-example-webrtc-private-to-public/index.html b/examples/js-libp2p-example-webrtc-private-to-public/index.html
new file mode 100644
index 0000000..24ff11f
--- /dev/null
+++ b/examples/js-libp2p-example-webrtc-private-to-public/index.html
@@ -0,0 +1,41 @@
+
+
+
+
+
+ js-libp2p WebRTC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/js-libp2p-example-webrtc-private-to-public/index.js b/examples/js-libp2p-example-webrtc-private-to-public/index.js
new file mode 100644
index 0000000..4192fdb
--- /dev/null
+++ b/examples/js-libp2p-example-webrtc-private-to-public/index.js
@@ -0,0 +1,52 @@
+import { webRTCDirect } from '@libp2p/webrtc'
+import { multiaddr } from '@multiformats/multiaddr'
+import { createLibp2p } from 'libp2p'
+import { fromString, toString } from 'uint8arrays'
+
+let stream
+const output = document.getElementById('output')
+const sendSection = document.getElementById('send-section')
+const appendOutput = (line) => {
+ const div = document.createElement('div')
+ div.appendChild(document.createTextNode(line))
+ output.append(div)
+}
+const clean = (line) => line.replaceAll('\n', '')
+
+const node = await createLibp2p({
+ transports: [webRTCDirect()],
+ connectionGater: {
+ denyDialMultiaddr: () => {
+ // by default we refuse to dial local addresses from the browser since they
+ // are usually sent by remote peers broadcasting undialable multiaddrs but
+ // here we are explicitly connecting to a local node so do not deny dialing
+ // any discovered address
+ return false
+ }
+ }
+})
+
+await node.start()
+
+node.addEventListener('peer:connect', (connection) => {
+ appendOutput(`Peer connected '${node.getConnections().map(c => c.remoteAddr.toString())}'`)
+ sendSection.style.display = 'block'
+})
+
+window.connect.onclick = async () => {
+ const ma = multiaddr(window.peer.value)
+
+ appendOutput(`Dialing '${ma}'`)
+ stream = await node.dialProtocol(ma, '/echo/1.0.0')
+
+ stream.addEventListener('message', (evt) => {
+ const response = toString(evt.data.subarray())
+ appendOutput(`Received message '${clean(response)}'`)
+ })
+}
+
+window.send.onclick = async () => {
+ const message = `${window.message.value}\n`
+ appendOutput(`Sending message '${clean(message)}'`)
+ stream.send(fromString(message))
+}
diff --git a/examples/js-libp2p-example-webrtc-private-to-public/package.json b/examples/js-libp2p-example-webrtc-private-to-public/package.json
new file mode 100644
index 0000000..fc91576
--- /dev/null
+++ b/examples/js-libp2p-example-webrtc-private-to-public/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "@libp2p/example-webrtc-private-to-public",
+ "version": "1.0.0",
+ "description": "Connect a browser to a server over WebRTC",
+ "type": "module",
+ "scripts": {
+ "start": "vite",
+ "build": "vite build",
+ "server": "node ./server.js",
+ "test:chrome": "npm run build && playwright test tests",
+ "test:firefox": "npm run build && playwright test --browser firefox tests",
+ "test": "npm run build && test-browser-example test"
+ },
+ "dependencies": {
+ "@libp2p/webrtc": "^6.0.3",
+ "@multiformats/multiaddr": "^13.0.1",
+ "libp2p": "^3.0.2",
+ "uint8arrays": "^5.1.0",
+ "vite": "^6.0.3"
+ },
+ "devDependencies": {
+ "@multiformats/multiaddr-matcher": "^3.0.1",
+ "test-ipfs-example": "^1.0.0"
+ }
+}
diff --git a/examples/js-libp2p-example-webrtc-private-to-public/server.js b/examples/js-libp2p-example-webrtc-private-to-public/server.js
new file mode 100644
index 0000000..ec0184d
--- /dev/null
+++ b/examples/js-libp2p-example-webrtc-private-to-public/server.js
@@ -0,0 +1,33 @@
+/* eslint-disable no-console */
+
+import { webRTCDirect } from '@libp2p/webrtc'
+import { createLibp2p } from 'libp2p'
+
+const node = await createLibp2p({
+ addresses: {
+ listen: [
+ '/ip4/127.0.0.1/udp/0/webrtc-direct'
+ ]
+ },
+ transports: [webRTCDirect()]
+})
+
+await node.start()
+
+node.handle('/echo/1.0.0', (stream) => {
+ stream.addEventListener('message', (evt) => {
+ stream.send(evt.data)
+ })
+ stream.addEventListener('remoteCloseWrite', () => {
+ stream.close()
+ .catch(err => {
+ stream.abort(err)
+ })
+ })
+})
+
+console.info('Server listening on')
+
+node.getMultiaddrs().forEach(ma => {
+ console.info(ma.toString())
+})
diff --git a/examples/js-libp2p-example-webrtc-private-to-public/test/index.spec.js b/examples/js-libp2p-example-webrtc-private-to-public/test/index.spec.js
new file mode 100644
index 0000000..c01e9b4
--- /dev/null
+++ b/examples/js-libp2p-example-webrtc-private-to-public/test/index.spec.js
@@ -0,0 +1,85 @@
+import { spawn } from 'child_process'
+import { multiaddr } from '@multiformats/multiaddr'
+import { WebRTCDirect } from '@multiformats/multiaddr-matcher'
+import { setup, expect } from 'test-ipfs-example/browser'
+
+// Setup
+const test = setup()
+
+async function spawnServer () {
+ const server = spawn('node', [
+ 'server.js'
+ ], {
+ cwd: '.',
+ killSignal: 'SIGINT'
+ })
+ const serverAddr = await (new Promise(resolve => {
+ server.stdout.on('data', (data) => {
+ data.toString().split('\n')
+ .map(line => line.trim())
+ .forEach(line => {
+ try {
+ if (WebRTCDirect.matches(multiaddr(line))) {
+ resolve(line)
+ }
+ } catch {}
+ })
+ })
+ }))
+ return { server, serverAddr }
+}
+
+test.describe('connect private to public node', () => {
+ // DOM
+ const connectBtn = '#connect'
+ const connectAddr = '#peer'
+ const messageInput = '#message'
+ const sendBtn = '#send'
+ const output = '#output'
+
+ let server
+ let serverAddr
+
+ // eslint-disable-next-line no-empty-pattern
+ test.beforeAll(async ({ }, testInfo) => {
+ testInfo.setTimeout(5 * 60_000)
+ const s = await spawnServer()
+ server = s.server
+ serverAddr = s.serverAddr
+ }, {})
+
+ test.afterAll(() => {
+ server.kill('SIGINT')
+ })
+
+ test.beforeEach(async ({ servers, page }) => {
+ await page.goto(servers[0].url)
+ })
+
+ test('should connect to a private node over webrtc', async ({ page }) => {
+ const message = 'hello'
+
+ // add the go libp2p multiaddress to the input field and submit
+ await page.fill(connectAddr, serverAddr)
+ await page.click(connectBtn)
+
+ // send the relay message to the go libp2p server
+ await page.fill(messageInput, message)
+ await page.click(sendBtn)
+
+ await page.waitForSelector('#output:has(div)')
+
+ // Expected output:
+ //
+ // Dialing '${serverAddr}'
+ // Peer connected '${serverAddr}'
+ // Sending message '${message}'
+ // Received message '${message}'
+
+ await expect(page.locator(output)).toContainText(`Dialing '${serverAddr}'`)
+ await expect(page.locator(output)).toContainText(`Peer connected '${serverAddr}'`)
+
+ await expect(page.locator(output)).toContainText(`Sending message '${message}'`)
+ await expect(page.locator(output)).toContainText(`Received message '${message}'`)
+ })
+})
diff --git a/examples/js-libp2p-example-webrtc-private-to-public/vite.config.js b/examples/js-libp2p-example-webrtc-private-to-public/vite.config.js
new file mode 100644
index 0000000..032cb5b
--- /dev/null
+++ b/examples/js-libp2p-example-webrtc-private-to-public/vite.config.js
@@ -0,0 +1,8 @@
+export default {
+ build: {
+ target: 'es2022'
+ },
+ optimizeDeps: {
+ esbuildOptions: { target: 'es2022', supported: { bigint: true } }
+ }
+}
diff --git a/package.json b/package.json
index 354867e..8b12e19 100644
--- a/package.json
+++ b/package.json
@@ -30,7 +30,7 @@
}
},
"devDependencies": {
- "aegir": "^45.0.8"
+ "aegir": "^47.0.22"
},
"workspaces": [
"examples/*"