@libp2p/webrtc 4.0.21 → 4.0.22-330a5ed72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,20 +3,168 @@
3
3
  *
4
4
  * A [libp2p transport](https://docs.libp2p.io/concepts/transports/overview/) based on [WebRTC datachannels](https://webrtc.org/).
5
5
  *
6
- * @example
6
+ * [WebRTC](https://www.w3.org/TR/webrtc/) is a specification that allows real-time communication between nodes - it's commonly used in browser video conferencing applications but it also provides a reliable data transport mechanism called [data channels](https://www.w3.org/TR/webrtc/#peer-to-peer-data-api) which libp2p uses to facilitate [protocol streams](https://docs.libp2p.io/concepts/multiplex/overview/) between peers.
7
+ *
8
+ * There are two transports exposed by this module, [webRTC](https://github.com/libp2p/specs/blob/master/webrtc/webrtc.md) and [webRTCDirect](https://github.com/libp2p/specs/blob/master/webrtc/webrtc-direct.md).
9
+ *
10
+ * ## WebRTC vs WebRTC Direct
11
+ *
12
+ * The connection establishment phase of WebRTC involves a handshake using [SDP](https://en.wikipedia.org/wiki/Session_Description_Protocol) during which two peers will exchange information such as open ports, network addresses and required capabilities.
13
+ *
14
+ * A third party is usually necessary to carry out this handshake, forwarding messages between the two peers until they can make a direct connection between themselves.
15
+ *
16
+ * The WebRTC transport uses libp2p [Circuit Relay](https://docs.libp2p.io/concepts/nat/circuit-relay/)s to forward SDP messages. Once a direct connection is formed the relay plays no further part in the exchange.
17
+ *
18
+ * WebRTC Direct uses a technique known as [SDP munging](https://webrtchacks.com/not-a-guide-to-sdp-munging/) to skip the handshake step, instead encoding enough information in the connection request that the responder can derive what would have been in the handshake messages and so requires no third parties to establish a connection.
19
+ *
20
+ * A WebRTC Direct multiaddr also includes a certhash of the target peer - this is used to allow opening a connection to the remote, which would otherwise be denied due to use of a self-signed certificate.
21
+ *
22
+ * In both cases, once the connection is established a [Noise handshake](https://noiseprotocol.org/noise.html) is carried out to ensure that the remote peer has the private key that corresponds to the public key that makes up their PeerId, giving you both encryption and authentication.
23
+ *
24
+ * ## Support
25
+ *
26
+ * WebRTC is supported in both Node.js and browsers.
27
+ *
28
+ * At the time of writing, WebRTC Direct is dial-only in browsers and not supported in Node.js at all.
29
+ *
30
+ * Support in Node.js is possible but PRs will need to be opened to [libdatachannel](https://github.com/paullouisageneau/libdatachannel) and the appropriate APIs exposed in [node-datachannel](https://github.com/murat-dogan/node-datachannel).
31
+ *
32
+ * For both WebRTC and WebRTC Direct, support is arriving soon in go-libp2p but they are unsupported in rust-libp2p.
33
+ *
34
+ * See the WebRTC section of https://connectivity.libp2p.io for more information.
35
+ *
36
+ * @example WebRTC
37
+ *
38
+ * WebRTC requires use of a relay to connect two nodes. The listener first discovers a relay server and makes a reservation, then the dialer can connect via the relayed address.
39
+ *
40
+ * ```TypeScript
41
+ * import { noise } from '@chainsafe/libp2p-noise'
42
+ * import { yamux } from '@chainsafe/libp2p-yamux'
43
+ * import { echo } from '@libp2p/echo'
44
+ * import { circuitRelayTransport, circuitRelayServer } from '@libp2p/circuit-relay-v2'
45
+ * import { identify } from '@libp2p/identify'
46
+ * import { webRTC } from '@libp2p/webrtc'
47
+ * import { webSockets } from '@libp2p/websockets'
48
+ * import * as filters from '@libp2p/websockets/filters'
49
+ * import { WebRTC } from '@multiformats/multiaddr-matcher'
50
+ * import delay from 'delay'
51
+ * import { pipe } from 'it-pipe'
52
+ * import { createLibp2p } from 'libp2p'
53
+ * import type { Multiaddr } from '@multiformats/multiaddr'
54
+ *
55
+ * // the relay server listens on a transport dialable by the listener and the
56
+ * // dialer, and has a relay service configured
57
+ * const relay = await createLibp2p({
58
+ * addresses: {
59
+ * listen: ['/ip4/127.0.0.1/tcp/0/ws']
60
+ * },
61
+ * transports: [
62
+ * webSockets({filter: filters.all})
63
+ * ],
64
+ * connectionEncryption: [noise()],
65
+ * streamMuxers: [yamux()],
66
+ * services: {
67
+ * identify: identify(),
68
+ * relay: circuitRelayServer()
69
+ * }
70
+ * })
71
+ *
72
+ * // the listener has a WebSocket transport to dial the relay, a Circuit Relay
73
+ * // transport to make a reservation, and a WebRTC transport to accept incoming
74
+ * // WebRTC connections
75
+ * const listener = await createLibp2p({
76
+ * addresses: {
77
+ * listen: ['/webrtc']
78
+ * },
79
+ * transports: [
80
+ * webSockets({filter: filters.all}),
81
+ * webRTC(),
82
+ * circuitRelayTransport({
83
+ * discoverRelays: 1
84
+ * })
85
+ * ],
86
+ * connectionEncryption: [noise()],
87
+ * streamMuxers: [yamux()],
88
+ * services: {
89
+ * identify: identify(),
90
+ * echo: echo()
91
+ * }
92
+ * })
93
+ *
94
+ * // the listener dials the relay (or discovers a public relay via some other
95
+ * // method)
96
+ * await listener.dial(relay.getMultiaddrs(), {
97
+ * signal: AbortSignal.timeout(5000)
98
+ * })
99
+ *
100
+ * let webRTCMultiaddr: Multiaddr | undefined
101
+ *
102
+ * // wait for the listener to make a reservation on the relay
103
+ * while (true) {
104
+ * webRTCMultiaddr = listener.getMultiaddrs().find(ma => WebRTC.matches(ma))
105
+ *
106
+ * if (webRTCMultiaddr != null) {
107
+ * break
108
+ * }
109
+ *
110
+ * // try again later
111
+ * await delay(1000)
112
+ * }
113
+ *
114
+ * // the listener has Circuit Relay, WebSocket and WebRTC transports to dial
115
+ * // the listener via the relay, complete the SDP handshake and establish a
116
+ * // direct WebRTC connection
117
+ * const dialer = await createLibp2p({
118
+ * transports: [
119
+ * webSockets({filter: filters.all}),
120
+ * webRTC(),
121
+ * circuitRelayTransport()
122
+ * ],
123
+ * connectionEncryption: [noise()],
124
+ * streamMuxers: [yamux()],
125
+ * services: {
126
+ * identify: identify(),
127
+ * echo: echo()
128
+ * }
129
+ * })
130
+ *
131
+ * // dial the listener and open an echo protocol stream
132
+ * const stream = await dialer.dialProtocol(webRTCMultiaddr, dialer.services.echo.protocol, {
133
+ * signal: AbortSignal.timeout(5000)
134
+ * })
135
+ *
136
+ * // we can now stop the relay
137
+ * await relay.stop()
138
+ *
139
+ * // send/receive some data from the remote peer via a direct connection
140
+ * await pipe(
141
+ * [new TextEncoder().encode('hello world')],
142
+ * stream,
143
+ * async source => {
144
+ * for await (const buf of source) {
145
+ * console.info(new TextDecoder().decode(buf.subarray()))
146
+ * }
147
+ * }
148
+ * )
149
+ * ```
150
+ *
151
+ * @example WebRTC Direct
152
+ *
153
+ * At the time of writing WebRTC Direct is dial-only in browsers and unsupported in Node.js.
154
+ *
155
+ * The only implementation that supports a WebRTC Direct listener is go-libp2p and it's not yet enabled by default.
7
156
  *
8
157
  * ```TypeScript
9
158
  * import { createLibp2p } from 'libp2p'
10
159
  * import { noise } from '@chainsafe/libp2p-noise'
11
160
  * import { multiaddr } from '@multiformats/multiaddr'
12
- * import first from 'it-first'
13
161
  * import { pipe } from 'it-pipe'
14
162
  * import { fromString, toString } from 'uint8arrays'
15
- * import { webRTC } from '@libp2p/webrtc'
163
+ * import { webRTCDirect } from '@libp2p/webrtc'
16
164
  *
17
165
  * const node = await createLibp2p({
18
166
  * transports: [
19
- * webRTC()
167
+ * webRTCDirect()
20
168
  * ],
21
169
  * connectionEncryption: [
22
170
  * noise()
@@ -25,7 +173,8 @@
25
173
  *
26
174
  * await node.start()
27
175
  *
28
- * const ma = multiaddr('/ip4/0.0.0.0/udp/56093/webrtc/certhash/uEiByaEfNSLBexWBNFZy_QB1vAKEj7JAXDizRs4_SnTflsQ')
176
+ * // this multiaddr corresponds to a remote node running a WebRTC Direct listener
177
+ * const ma = multiaddr('/ip4/0.0.0.0/udp/56093/webrtc-direct/certhash/uEiByaEfNSLBexWBNFZy_QB1vAKEj7JAXDizRs4_SnTflsQ')
29
178
  * const stream = await node.dialProtocol(ma, '/my-protocol/1.0.0', {
30
179
  * signal: AbortSignal.timeout(10_000)
31
180
  * })
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAGH,OAAO,EAAyB,KAAK,yBAAyB,EAAE,KAAK,+BAA+B,EAAE,MAAM,kCAAkC,CAAA;AAC9I,OAAO,KAAK,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAA;AACvG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAElD,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAE1B;;;;OAIG;IACH,6BAA6B,CAAC,EAAE,MAAM,CAAA;IAEtC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;GAOG;AACH,iBAAS,YAAY,CAAE,IAAI,CAAC,EAAE,yBAAyB,GAAG,CAAC,UAAU,EAAE,+BAA+B,KAAK,SAAS,CAEnH;AAED;;;;;;;;GAQG;AACH,iBAAS,MAAM,CAAE,IAAI,CAAC,EAAE,mBAAmB,GAAG,CAAC,UAAU,EAAE,yBAAyB,KAAK,SAAS,CAEjG;AAED,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+LG;AAGH,OAAO,EAAyB,KAAK,yBAAyB,EAAE,KAAK,+BAA+B,EAAE,MAAM,kCAAkC,CAAA;AAC9I,OAAO,KAAK,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAA;AACvG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAElD,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IAEvB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAE1B;;;;OAIG;IACH,6BAA6B,CAAC,EAAE,MAAM,CAAA;IAEtC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;GAOG;AACH,iBAAS,YAAY,CAAE,IAAI,CAAC,EAAE,yBAAyB,GAAG,CAAC,UAAU,EAAE,+BAA+B,KAAK,SAAS,CAEnH;AAED;;;;;;;;GAQG;AACH,iBAAS,MAAM,CAAE,IAAI,CAAC,EAAE,mBAAmB,GAAG,CAAC,UAAU,EAAE,yBAAyB,KAAK,SAAS,CAEjG;AAED,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAA"}
package/dist/src/index.js CHANGED
@@ -3,20 +3,168 @@
3
3
  *
4
4
  * A [libp2p transport](https://docs.libp2p.io/concepts/transports/overview/) based on [WebRTC datachannels](https://webrtc.org/).
5
5
  *
6
- * @example
6
+ * [WebRTC](https://www.w3.org/TR/webrtc/) is a specification that allows real-time communication between nodes - it's commonly used in browser video conferencing applications but it also provides a reliable data transport mechanism called [data channels](https://www.w3.org/TR/webrtc/#peer-to-peer-data-api) which libp2p uses to facilitate [protocol streams](https://docs.libp2p.io/concepts/multiplex/overview/) between peers.
7
+ *
8
+ * There are two transports exposed by this module, [webRTC](https://github.com/libp2p/specs/blob/master/webrtc/webrtc.md) and [webRTCDirect](https://github.com/libp2p/specs/blob/master/webrtc/webrtc-direct.md).
9
+ *
10
+ * ## WebRTC vs WebRTC Direct
11
+ *
12
+ * The connection establishment phase of WebRTC involves a handshake using [SDP](https://en.wikipedia.org/wiki/Session_Description_Protocol) during which two peers will exchange information such as open ports, network addresses and required capabilities.
13
+ *
14
+ * A third party is usually necessary to carry out this handshake, forwarding messages between the two peers until they can make a direct connection between themselves.
15
+ *
16
+ * The WebRTC transport uses libp2p [Circuit Relay](https://docs.libp2p.io/concepts/nat/circuit-relay/)s to forward SDP messages. Once a direct connection is formed the relay plays no further part in the exchange.
17
+ *
18
+ * WebRTC Direct uses a technique known as [SDP munging](https://webrtchacks.com/not-a-guide-to-sdp-munging/) to skip the handshake step, instead encoding enough information in the connection request that the responder can derive what would have been in the handshake messages and so requires no third parties to establish a connection.
19
+ *
20
+ * A WebRTC Direct multiaddr also includes a certhash of the target peer - this is used to allow opening a connection to the remote, which would otherwise be denied due to use of a self-signed certificate.
21
+ *
22
+ * In both cases, once the connection is established a [Noise handshake](https://noiseprotocol.org/noise.html) is carried out to ensure that the remote peer has the private key that corresponds to the public key that makes up their PeerId, giving you both encryption and authentication.
23
+ *
24
+ * ## Support
25
+ *
26
+ * WebRTC is supported in both Node.js and browsers.
27
+ *
28
+ * At the time of writing, WebRTC Direct is dial-only in browsers and not supported in Node.js at all.
29
+ *
30
+ * Support in Node.js is possible but PRs will need to be opened to [libdatachannel](https://github.com/paullouisageneau/libdatachannel) and the appropriate APIs exposed in [node-datachannel](https://github.com/murat-dogan/node-datachannel).
31
+ *
32
+ * For both WebRTC and WebRTC Direct, support is arriving soon in go-libp2p but they are unsupported in rust-libp2p.
33
+ *
34
+ * See the WebRTC section of https://connectivity.libp2p.io for more information.
35
+ *
36
+ * @example WebRTC
37
+ *
38
+ * WebRTC requires use of a relay to connect two nodes. The listener first discovers a relay server and makes a reservation, then the dialer can connect via the relayed address.
39
+ *
40
+ * ```TypeScript
41
+ * import { noise } from '@chainsafe/libp2p-noise'
42
+ * import { yamux } from '@chainsafe/libp2p-yamux'
43
+ * import { echo } from '@libp2p/echo'
44
+ * import { circuitRelayTransport, circuitRelayServer } from '@libp2p/circuit-relay-v2'
45
+ * import { identify } from '@libp2p/identify'
46
+ * import { webRTC } from '@libp2p/webrtc'
47
+ * import { webSockets } from '@libp2p/websockets'
48
+ * import * as filters from '@libp2p/websockets/filters'
49
+ * import { WebRTC } from '@multiformats/multiaddr-matcher'
50
+ * import delay from 'delay'
51
+ * import { pipe } from 'it-pipe'
52
+ * import { createLibp2p } from 'libp2p'
53
+ * import type { Multiaddr } from '@multiformats/multiaddr'
54
+ *
55
+ * // the relay server listens on a transport dialable by the listener and the
56
+ * // dialer, and has a relay service configured
57
+ * const relay = await createLibp2p({
58
+ * addresses: {
59
+ * listen: ['/ip4/127.0.0.1/tcp/0/ws']
60
+ * },
61
+ * transports: [
62
+ * webSockets({filter: filters.all})
63
+ * ],
64
+ * connectionEncryption: [noise()],
65
+ * streamMuxers: [yamux()],
66
+ * services: {
67
+ * identify: identify(),
68
+ * relay: circuitRelayServer()
69
+ * }
70
+ * })
71
+ *
72
+ * // the listener has a WebSocket transport to dial the relay, a Circuit Relay
73
+ * // transport to make a reservation, and a WebRTC transport to accept incoming
74
+ * // WebRTC connections
75
+ * const listener = await createLibp2p({
76
+ * addresses: {
77
+ * listen: ['/webrtc']
78
+ * },
79
+ * transports: [
80
+ * webSockets({filter: filters.all}),
81
+ * webRTC(),
82
+ * circuitRelayTransport({
83
+ * discoverRelays: 1
84
+ * })
85
+ * ],
86
+ * connectionEncryption: [noise()],
87
+ * streamMuxers: [yamux()],
88
+ * services: {
89
+ * identify: identify(),
90
+ * echo: echo()
91
+ * }
92
+ * })
93
+ *
94
+ * // the listener dials the relay (or discovers a public relay via some other
95
+ * // method)
96
+ * await listener.dial(relay.getMultiaddrs(), {
97
+ * signal: AbortSignal.timeout(5000)
98
+ * })
99
+ *
100
+ * let webRTCMultiaddr: Multiaddr | undefined
101
+ *
102
+ * // wait for the listener to make a reservation on the relay
103
+ * while (true) {
104
+ * webRTCMultiaddr = listener.getMultiaddrs().find(ma => WebRTC.matches(ma))
105
+ *
106
+ * if (webRTCMultiaddr != null) {
107
+ * break
108
+ * }
109
+ *
110
+ * // try again later
111
+ * await delay(1000)
112
+ * }
113
+ *
114
+ * // the listener has Circuit Relay, WebSocket and WebRTC transports to dial
115
+ * // the listener via the relay, complete the SDP handshake and establish a
116
+ * // direct WebRTC connection
117
+ * const dialer = await createLibp2p({
118
+ * transports: [
119
+ * webSockets({filter: filters.all}),
120
+ * webRTC(),
121
+ * circuitRelayTransport()
122
+ * ],
123
+ * connectionEncryption: [noise()],
124
+ * streamMuxers: [yamux()],
125
+ * services: {
126
+ * identify: identify(),
127
+ * echo: echo()
128
+ * }
129
+ * })
130
+ *
131
+ * // dial the listener and open an echo protocol stream
132
+ * const stream = await dialer.dialProtocol(webRTCMultiaddr, dialer.services.echo.protocol, {
133
+ * signal: AbortSignal.timeout(5000)
134
+ * })
135
+ *
136
+ * // we can now stop the relay
137
+ * await relay.stop()
138
+ *
139
+ * // send/receive some data from the remote peer via a direct connection
140
+ * await pipe(
141
+ * [new TextEncoder().encode('hello world')],
142
+ * stream,
143
+ * async source => {
144
+ * for await (const buf of source) {
145
+ * console.info(new TextDecoder().decode(buf.subarray()))
146
+ * }
147
+ * }
148
+ * )
149
+ * ```
150
+ *
151
+ * @example WebRTC Direct
152
+ *
153
+ * At the time of writing WebRTC Direct is dial-only in browsers and unsupported in Node.js.
154
+ *
155
+ * The only implementation that supports a WebRTC Direct listener is go-libp2p and it's not yet enabled by default.
7
156
  *
8
157
  * ```TypeScript
9
158
  * import { createLibp2p } from 'libp2p'
10
159
  * import { noise } from '@chainsafe/libp2p-noise'
11
160
  * import { multiaddr } from '@multiformats/multiaddr'
12
- * import first from 'it-first'
13
161
  * import { pipe } from 'it-pipe'
14
162
  * import { fromString, toString } from 'uint8arrays'
15
- * import { webRTC } from '@libp2p/webrtc'
163
+ * import { webRTCDirect } from '@libp2p/webrtc'
16
164
  *
17
165
  * const node = await createLibp2p({
18
166
  * transports: [
19
- * webRTC()
167
+ * webRTCDirect()
20
168
  * ],
21
169
  * connectionEncryption: [
22
170
  * noise()
@@ -25,7 +173,8 @@
25
173
  *
26
174
  * await node.start()
27
175
  *
28
- * const ma = multiaddr('/ip4/0.0.0.0/udp/56093/webrtc/certhash/uEiByaEfNSLBexWBNFZy_QB1vAKEj7JAXDizRs4_SnTflsQ')
176
+ * // this multiaddr corresponds to a remote node running a WebRTC Direct listener
177
+ * const ma = multiaddr('/ip4/0.0.0.0/udp/56093/webrtc-direct/certhash/uEiByaEfNSLBexWBNFZy_QB1vAKEj7JAXDizRs4_SnTflsQ')
29
178
  * const stream = await node.dialProtocol(ma, '/my-protocol/1.0.0', {
30
179
  * signal: AbortSignal.timeout(10_000)
31
180
  * })
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAE,qBAAqB,EAAwE,MAAM,kCAAkC,CAAA;AA4C9I;;;;;;;GAOG;AACH,SAAS,YAAY,CAAE,IAAgC;IACrD,OAAO,CAAC,UAA2C,EAAE,EAAE,CAAC,IAAI,qBAAqB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;AACrG,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,MAAM,CAAE,IAA0B;IACzC,OAAO,CAAC,UAAqC,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;AACzF,CAAC;AAED,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+LG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAA;AACnE,OAAO,EAAE,qBAAqB,EAAwE,MAAM,kCAAkC,CAAA;AA4C9I;;;;;;;GAOG;AACH,SAAS,YAAY,CAAE,IAAgC;IACrD,OAAO,CAAC,UAA2C,EAAE,EAAE,CAAC,IAAI,qBAAqB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;AACrG,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,MAAM,CAAE,IAA0B;IACzC,OAAO,CAAC,UAAqC,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;AACzF,CAAC;AAED,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/webrtc",
3
- "version": "4.0.21",
3
+ "version": "4.0.22-330a5ed72",
4
4
  "description": "A libp2p transport using WebRTC connections",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/transport-webrtc#readme",
@@ -51,10 +51,10 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "@chainsafe/libp2p-noise": "^15.0.0",
54
- "@libp2p/interface": "^1.1.4",
55
- "@libp2p/interface-internal": "^1.0.9",
56
- "@libp2p/peer-id": "^4.0.7",
57
- "@libp2p/utils": "^5.2.6",
54
+ "@libp2p/interface": "1.1.4-330a5ed72",
55
+ "@libp2p/interface-internal": "1.0.9-330a5ed72",
56
+ "@libp2p/peer-id": "4.0.7-330a5ed72",
57
+ "@libp2p/utils": "5.2.6-330a5ed72",
58
58
  "@multiformats/mafmt": "^12.1.6",
59
59
  "@multiformats/multiaddr": "^12.1.14",
60
60
  "@multiformats/multiaddr-matcher": "^1.1.2",
@@ -77,11 +77,11 @@
77
77
  },
78
78
  "devDependencies": {
79
79
  "@chainsafe/libp2p-yamux": "^6.0.2",
80
- "@libp2p/circuit-relay-v2": "^1.0.16",
81
- "@libp2p/interface-compliance-tests": "^5.3.2",
82
- "@libp2p/logger": "^4.0.7",
83
- "@libp2p/peer-id-factory": "^4.0.7",
84
- "@libp2p/websockets": "^8.0.16",
80
+ "@libp2p/circuit-relay-v2": "1.0.16-330a5ed72",
81
+ "@libp2p/interface-compliance-tests": "5.3.2-330a5ed72",
82
+ "@libp2p/logger": "4.0.7-330a5ed72",
83
+ "@libp2p/peer-id-factory": "4.0.7-330a5ed72",
84
+ "@libp2p/websockets": "8.0.16-330a5ed72",
85
85
  "@types/sinon": "^17.0.3",
86
86
  "aegir": "^42.2.4",
87
87
  "delay": "^6.0.0",
@@ -91,7 +91,7 @@
91
91
  "it-pair": "^2.0.6",
92
92
  "it-pipe": "^3.0.1",
93
93
  "it-to-buffer": "^4.0.5",
94
- "libp2p": "^1.3.0",
94
+ "libp2p": "1.3.0-330a5ed72",
95
95
  "p-retry": "^6.2.0",
96
96
  "protons": "^7.5.0",
97
97
  "sinon": "^17.0.1",
package/src/index.ts CHANGED
@@ -3,20 +3,168 @@
3
3
  *
4
4
  * A [libp2p transport](https://docs.libp2p.io/concepts/transports/overview/) based on [WebRTC datachannels](https://webrtc.org/).
5
5
  *
6
- * @example
6
+ * [WebRTC](https://www.w3.org/TR/webrtc/) is a specification that allows real-time communication between nodes - it's commonly used in browser video conferencing applications but it also provides a reliable data transport mechanism called [data channels](https://www.w3.org/TR/webrtc/#peer-to-peer-data-api) which libp2p uses to facilitate [protocol streams](https://docs.libp2p.io/concepts/multiplex/overview/) between peers.
7
+ *
8
+ * There are two transports exposed by this module, [webRTC](https://github.com/libp2p/specs/blob/master/webrtc/webrtc.md) and [webRTCDirect](https://github.com/libp2p/specs/blob/master/webrtc/webrtc-direct.md).
9
+ *
10
+ * ## WebRTC vs WebRTC Direct
11
+ *
12
+ * The connection establishment phase of WebRTC involves a handshake using [SDP](https://en.wikipedia.org/wiki/Session_Description_Protocol) during which two peers will exchange information such as open ports, network addresses and required capabilities.
13
+ *
14
+ * A third party is usually necessary to carry out this handshake, forwarding messages between the two peers until they can make a direct connection between themselves.
15
+ *
16
+ * The WebRTC transport uses libp2p [Circuit Relay](https://docs.libp2p.io/concepts/nat/circuit-relay/)s to forward SDP messages. Once a direct connection is formed the relay plays no further part in the exchange.
17
+ *
18
+ * WebRTC Direct uses a technique known as [SDP munging](https://webrtchacks.com/not-a-guide-to-sdp-munging/) to skip the handshake step, instead encoding enough information in the connection request that the responder can derive what would have been in the handshake messages and so requires no third parties to establish a connection.
19
+ *
20
+ * A WebRTC Direct multiaddr also includes a certhash of the target peer - this is used to allow opening a connection to the remote, which would otherwise be denied due to use of a self-signed certificate.
21
+ *
22
+ * In both cases, once the connection is established a [Noise handshake](https://noiseprotocol.org/noise.html) is carried out to ensure that the remote peer has the private key that corresponds to the public key that makes up their PeerId, giving you both encryption and authentication.
23
+ *
24
+ * ## Support
25
+ *
26
+ * WebRTC is supported in both Node.js and browsers.
27
+ *
28
+ * At the time of writing, WebRTC Direct is dial-only in browsers and not supported in Node.js at all.
29
+ *
30
+ * Support in Node.js is possible but PRs will need to be opened to [libdatachannel](https://github.com/paullouisageneau/libdatachannel) and the appropriate APIs exposed in [node-datachannel](https://github.com/murat-dogan/node-datachannel).
31
+ *
32
+ * For both WebRTC and WebRTC Direct, support is arriving soon in go-libp2p but they are unsupported in rust-libp2p.
33
+ *
34
+ * See the WebRTC section of https://connectivity.libp2p.io for more information.
35
+ *
36
+ * @example WebRTC
37
+ *
38
+ * WebRTC requires use of a relay to connect two nodes. The listener first discovers a relay server and makes a reservation, then the dialer can connect via the relayed address.
39
+ *
40
+ * ```TypeScript
41
+ * import { noise } from '@chainsafe/libp2p-noise'
42
+ * import { yamux } from '@chainsafe/libp2p-yamux'
43
+ * import { echo } from '@libp2p/echo'
44
+ * import { circuitRelayTransport, circuitRelayServer } from '@libp2p/circuit-relay-v2'
45
+ * import { identify } from '@libp2p/identify'
46
+ * import { webRTC } from '@libp2p/webrtc'
47
+ * import { webSockets } from '@libp2p/websockets'
48
+ * import * as filters from '@libp2p/websockets/filters'
49
+ * import { WebRTC } from '@multiformats/multiaddr-matcher'
50
+ * import delay from 'delay'
51
+ * import { pipe } from 'it-pipe'
52
+ * import { createLibp2p } from 'libp2p'
53
+ * import type { Multiaddr } from '@multiformats/multiaddr'
54
+ *
55
+ * // the relay server listens on a transport dialable by the listener and the
56
+ * // dialer, and has a relay service configured
57
+ * const relay = await createLibp2p({
58
+ * addresses: {
59
+ * listen: ['/ip4/127.0.0.1/tcp/0/ws']
60
+ * },
61
+ * transports: [
62
+ * webSockets({filter: filters.all})
63
+ * ],
64
+ * connectionEncryption: [noise()],
65
+ * streamMuxers: [yamux()],
66
+ * services: {
67
+ * identify: identify(),
68
+ * relay: circuitRelayServer()
69
+ * }
70
+ * })
71
+ *
72
+ * // the listener has a WebSocket transport to dial the relay, a Circuit Relay
73
+ * // transport to make a reservation, and a WebRTC transport to accept incoming
74
+ * // WebRTC connections
75
+ * const listener = await createLibp2p({
76
+ * addresses: {
77
+ * listen: ['/webrtc']
78
+ * },
79
+ * transports: [
80
+ * webSockets({filter: filters.all}),
81
+ * webRTC(),
82
+ * circuitRelayTransport({
83
+ * discoverRelays: 1
84
+ * })
85
+ * ],
86
+ * connectionEncryption: [noise()],
87
+ * streamMuxers: [yamux()],
88
+ * services: {
89
+ * identify: identify(),
90
+ * echo: echo()
91
+ * }
92
+ * })
93
+ *
94
+ * // the listener dials the relay (or discovers a public relay via some other
95
+ * // method)
96
+ * await listener.dial(relay.getMultiaddrs(), {
97
+ * signal: AbortSignal.timeout(5000)
98
+ * })
99
+ *
100
+ * let webRTCMultiaddr: Multiaddr | undefined
101
+ *
102
+ * // wait for the listener to make a reservation on the relay
103
+ * while (true) {
104
+ * webRTCMultiaddr = listener.getMultiaddrs().find(ma => WebRTC.matches(ma))
105
+ *
106
+ * if (webRTCMultiaddr != null) {
107
+ * break
108
+ * }
109
+ *
110
+ * // try again later
111
+ * await delay(1000)
112
+ * }
113
+ *
114
+ * // the listener has Circuit Relay, WebSocket and WebRTC transports to dial
115
+ * // the listener via the relay, complete the SDP handshake and establish a
116
+ * // direct WebRTC connection
117
+ * const dialer = await createLibp2p({
118
+ * transports: [
119
+ * webSockets({filter: filters.all}),
120
+ * webRTC(),
121
+ * circuitRelayTransport()
122
+ * ],
123
+ * connectionEncryption: [noise()],
124
+ * streamMuxers: [yamux()],
125
+ * services: {
126
+ * identify: identify(),
127
+ * echo: echo()
128
+ * }
129
+ * })
130
+ *
131
+ * // dial the listener and open an echo protocol stream
132
+ * const stream = await dialer.dialProtocol(webRTCMultiaddr, dialer.services.echo.protocol, {
133
+ * signal: AbortSignal.timeout(5000)
134
+ * })
135
+ *
136
+ * // we can now stop the relay
137
+ * await relay.stop()
138
+ *
139
+ * // send/receive some data from the remote peer via a direct connection
140
+ * await pipe(
141
+ * [new TextEncoder().encode('hello world')],
142
+ * stream,
143
+ * async source => {
144
+ * for await (const buf of source) {
145
+ * console.info(new TextDecoder().decode(buf.subarray()))
146
+ * }
147
+ * }
148
+ * )
149
+ * ```
150
+ *
151
+ * @example WebRTC Direct
152
+ *
153
+ * At the time of writing WebRTC Direct is dial-only in browsers and unsupported in Node.js.
154
+ *
155
+ * The only implementation that supports a WebRTC Direct listener is go-libp2p and it's not yet enabled by default.
7
156
  *
8
157
  * ```TypeScript
9
158
  * import { createLibp2p } from 'libp2p'
10
159
  * import { noise } from '@chainsafe/libp2p-noise'
11
160
  * import { multiaddr } from '@multiformats/multiaddr'
12
- * import first from 'it-first'
13
161
  * import { pipe } from 'it-pipe'
14
162
  * import { fromString, toString } from 'uint8arrays'
15
- * import { webRTC } from '@libp2p/webrtc'
163
+ * import { webRTCDirect } from '@libp2p/webrtc'
16
164
  *
17
165
  * const node = await createLibp2p({
18
166
  * transports: [
19
- * webRTC()
167
+ * webRTCDirect()
20
168
  * ],
21
169
  * connectionEncryption: [
22
170
  * noise()
@@ -25,7 +173,8 @@
25
173
  *
26
174
  * await node.start()
27
175
  *
28
- * const ma = multiaddr('/ip4/0.0.0.0/udp/56093/webrtc/certhash/uEiByaEfNSLBexWBNFZy_QB1vAKEj7JAXDizRs4_SnTflsQ')
176
+ * // this multiaddr corresponds to a remote node running a WebRTC Direct listener
177
+ * const ma = multiaddr('/ip4/0.0.0.0/udp/56093/webrtc-direct/certhash/uEiByaEfNSLBexWBNFZy_QB1vAKEj7JAXDizRs4_SnTflsQ')
29
178
  * const stream = await node.dialProtocol(ma, '/my-protocol/1.0.0', {
30
179
  * signal: AbortSignal.timeout(10_000)
31
180
  * })
@@ -1,8 +0,0 @@
1
- {
2
- "DataChannelOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.DataChannelOptions.html",
3
- ".:DataChannelOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.DataChannelOptions.html",
4
- "webRTC": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTC.html",
5
- ".:webRTC": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTC.html",
6
- "webRTCDirect": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTCDirect.html",
7
- ".:webRTCDirect": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTCDirect.html"
8
- }