@libp2p/webrtc 5.2.24-8484de8a2 → 5.2.24-87bc8d4fb

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.
Files changed (89) hide show
  1. package/README.md +20 -10
  2. package/dist/index.min.js +17 -17
  3. package/dist/index.min.js.map +4 -4
  4. package/dist/src/constants.d.ts +23 -0
  5. package/dist/src/constants.d.ts.map +1 -1
  6. package/dist/src/constants.js +23 -0
  7. package/dist/src/constants.js.map +1 -1
  8. package/dist/src/index.d.ts +22 -12
  9. package/dist/src/index.d.ts.map +1 -1
  10. package/dist/src/index.js +22 -12
  11. package/dist/src/index.js.map +1 -1
  12. package/dist/src/maconn.d.ts +58 -0
  13. package/dist/src/maconn.d.ts.map +1 -0
  14. package/dist/src/maconn.js +56 -0
  15. package/dist/src/maconn.js.map +1 -0
  16. package/dist/src/muxer.d.ts +46 -14
  17. package/dist/src/muxer.d.ts.map +1 -1
  18. package/dist/src/muxer.js +135 -32
  19. package/dist/src/muxer.js.map +1 -1
  20. package/dist/src/private-to-private/initiate-connection.d.ts +3 -2
  21. package/dist/src/private-to-private/initiate-connection.d.ts.map +1 -1
  22. package/dist/src/private-to-private/initiate-connection.js +5 -23
  23. package/dist/src/private-to-private/initiate-connection.js.map +1 -1
  24. package/dist/src/private-to-private/signaling-stream-handler.d.ts +4 -4
  25. package/dist/src/private-to-private/signaling-stream-handler.d.ts.map +1 -1
  26. package/dist/src/private-to-private/signaling-stream-handler.js +6 -10
  27. package/dist/src/private-to-private/signaling-stream-handler.js.map +1 -1
  28. package/dist/src/private-to-private/transport.d.ts +2 -2
  29. package/dist/src/private-to-private/transport.d.ts.map +1 -1
  30. package/dist/src/private-to-private/transport.js +15 -30
  31. package/dist/src/private-to-private/transport.js.map +1 -1
  32. package/dist/src/private-to-private/util.d.ts +1 -3
  33. package/dist/src/private-to-private/util.d.ts.map +1 -1
  34. package/dist/src/private-to-private/util.js +3 -15
  35. package/dist/src/private-to-private/util.js.map +1 -1
  36. package/dist/src/private-to-public/listener.d.ts.map +1 -1
  37. package/dist/src/private-to-public/listener.js +15 -21
  38. package/dist/src/private-to-public/listener.js.map +1 -1
  39. package/dist/src/private-to-public/transport.d.ts.map +1 -1
  40. package/dist/src/private-to-public/transport.js +2 -3
  41. package/dist/src/private-to-public/transport.js.map +1 -1
  42. package/dist/src/private-to-public/utils/connect.d.ts +1 -1
  43. package/dist/src/private-to-public/utils/connect.d.ts.map +1 -1
  44. package/dist/src/private-to-public/utils/connect.js +14 -17
  45. package/dist/src/private-to-public/utils/connect.js.map +1 -1
  46. package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts +4 -4
  47. package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts.map +1 -1
  48. package/dist/src/private-to-public/utils/get-rtcpeerconnection.js +2 -13
  49. package/dist/src/private-to-public/utils/get-rtcpeerconnection.js.map +1 -1
  50. package/dist/src/private-to-public/utils/sdp.d.ts.map +1 -1
  51. package/dist/src/private-to-public/utils/sdp.js +13 -25
  52. package/dist/src/private-to-public/utils/sdp.js.map +1 -1
  53. package/dist/src/private-to-public/utils/stun-listener.js +1 -1
  54. package/dist/src/private-to-public/utils/stun-listener.js.map +1 -1
  55. package/dist/src/stream.d.ts +26 -13
  56. package/dist/src/stream.d.ts.map +1 -1
  57. package/dist/src/stream.js +166 -64
  58. package/dist/src/stream.js.map +1 -1
  59. package/dist/src/util.d.ts +1 -3
  60. package/dist/src/util.d.ts.map +1 -1
  61. package/dist/src/util.js +0 -19
  62. package/dist/src/util.js.map +1 -1
  63. package/dist/src/webrtc/index.d.ts +1 -1
  64. package/dist/src/webrtc/index.d.ts.map +1 -1
  65. package/dist/src/webrtc/index.js +1 -1
  66. package/dist/src/webrtc/index.js.map +1 -1
  67. package/package.json +29 -26
  68. package/src/constants.ts +28 -0
  69. package/src/index.ts +22 -12
  70. package/src/maconn.ts +101 -0
  71. package/src/muxer.ts +166 -43
  72. package/src/private-to-private/initiate-connection.ts +8 -30
  73. package/src/private-to-private/signaling-stream-handler.ts +9 -12
  74. package/src/private-to-private/transport.ts +17 -33
  75. package/src/private-to-private/util.ts +4 -21
  76. package/src/private-to-public/listener.ts +15 -22
  77. package/src/private-to-public/transport.ts +2 -3
  78. package/src/private-to-public/utils/connect.ts +15 -18
  79. package/src/private-to-public/utils/get-rtcpeerconnection.ts +4 -16
  80. package/src/private-to-public/utils/sdp.ts +13 -29
  81. package/src/private-to-public/utils/stun-listener.ts +1 -1
  82. package/src/stream.ts +194 -74
  83. package/src/util.ts +1 -22
  84. package/src/webrtc/index.ts +1 -1
  85. package/dist/src/rtcpeerconnection-to-conn.d.ts +0 -12
  86. package/dist/src/rtcpeerconnection-to-conn.d.ts.map +0 -1
  87. package/dist/src/rtcpeerconnection-to-conn.js +0 -43
  88. package/dist/src/rtcpeerconnection-to-conn.js.map +0 -1
  89. package/src/rtcpeerconnection-to-conn.ts +0 -62
@@ -1,19 +1,20 @@
1
- import { pbStream } from '@libp2p/utils'
2
1
  import { multiaddr } from '@multiformats/multiaddr'
2
+ import { pbStream } from 'it-protobuf-stream'
3
3
  import { SDPHandshakeFailedError } from '../error.js'
4
4
  import { RTCSessionDescription } from '../webrtc/index.js'
5
5
  import { Message } from './pb/message.js'
6
- import { getConnectionState, getRemotePeer, readCandidatesUntilConnected } from './util.js'
6
+ import { getConnectionState, readCandidatesUntilConnected } from './util.js'
7
7
  import type { RTCPeerConnection } from '../webrtc/index.js'
8
- import type { AbortOptions, Connection, Logger, PeerId, Stream } from '@libp2p/interface'
8
+ import type { Logger, IncomingStreamData } from '@libp2p/interface'
9
9
  import type { Multiaddr } from '@multiformats/multiaddr'
10
10
 
11
- export interface IncomingStreamOptions extends AbortOptions {
11
+ export interface IncomingStreamOpts extends IncomingStreamData {
12
12
  peerConnection: RTCPeerConnection
13
+ signal: AbortSignal
13
14
  log: Logger
14
15
  }
15
16
 
16
- export async function handleIncomingStream (stream: Stream, connection: Connection, { peerConnection, signal, log }: IncomingStreamOptions): Promise<{ remoteAddress: Multiaddr, remotePeer: PeerId }> {
17
+ export async function handleIncomingStream ({ peerConnection, stream, signal, connection, log }: IncomingStreamOpts): Promise<{ remoteAddress: Multiaddr }> {
17
18
  log.trace('new inbound signaling stream')
18
19
 
19
20
  const messageStream = pbStream(stream).pb(Message)
@@ -36,7 +37,7 @@ export async function handleIncomingStream (stream: Stream, connection: Connecti
36
37
  signal
37
38
  })
38
39
  .catch(err => {
39
- log.error('error sending ICE candidate - %e', err)
40
+ log.error('error sending ICE candidate', err)
40
41
  })
41
42
  }
42
43
 
@@ -100,13 +101,9 @@ export async function handleIncomingStream (stream: Stream, connection: Connecti
100
101
  }
101
102
  }
102
103
 
103
- const remotePeer = getRemotePeer(connection.remoteAddr)
104
- const remoteAddress = multiaddr(`/webrtc/p2p/${remotePeer}`)
104
+ const remoteAddress = multiaddr(`/webrtc/p2p/${connection.remoteAddr.getPeerId()}`)
105
105
 
106
106
  log.trace('recipient connected to remote address %s', remoteAddress)
107
107
 
108
- return {
109
- remoteAddress,
110
- remotePeer
111
- }
108
+ return { remoteAddress }
112
109
  }
@@ -4,16 +4,15 @@ import { multiaddr } from '@multiformats/multiaddr'
4
4
  import { WebRTC } from '@multiformats/multiaddr-matcher'
5
5
  import { setMaxListeners } from 'main-event'
6
6
  import { SIGNALING_PROTOCOL } from '../constants.js'
7
+ import { WebRTCMultiaddrConnection } from '../maconn.js'
7
8
  import { DataChannelMuxerFactory } from '../muxer.js'
8
- import { toMultiaddrConnection } from '../rtcpeerconnection-to-conn.ts'
9
9
  import { getRtcConfiguration } from '../util.js'
10
10
  import { RTCPeerConnection } from '../webrtc/index.js'
11
11
  import { initiateConnection } from './initiate-connection.js'
12
12
  import { WebRTCPeerListener } from './listener.js'
13
13
  import { handleIncomingStream } from './signaling-stream-handler.js'
14
- import { getRemotePeer } from './util.ts'
15
14
  import type { DataChannelOptions } from '../index.js'
16
- import type { OutboundConnectionUpgradeEvents, CreateListenerOptions, DialTransportOptions, Transport, Listener, Upgrader, ComponentLogger, Logger, Connection, PeerId, CounterGroup, Metrics, Startable, OpenConnectionProgressEvents, Libp2pEvents, MultiaddrConnection, Stream } from '@libp2p/interface'
15
+ import type { OutboundConnectionUpgradeEvents, CreateListenerOptions, DialTransportOptions, Transport, Listener, Upgrader, ComponentLogger, Logger, Connection, PeerId, CounterGroup, Metrics, Startable, OpenConnectionProgressEvents, IncomingStreamData, Libp2pEvents } from '@libp2p/interface'
17
16
  import type { Registrar, ConnectionManager, TransportManager } from '@libp2p/interface-internal'
18
17
  import type { Multiaddr } from '@multiformats/multiaddr'
19
18
  import type { TypedEventTarget } from 'main-event'
@@ -116,13 +115,13 @@ export class WebRTCTransport implements Transport<WebRTCDialEvents>, Startable {
116
115
  }
117
116
 
118
117
  async start (): Promise<void> {
119
- await this.components.registrar.handle(SIGNALING_PROTOCOL, (stream: Stream, connection: Connection) => {
118
+ await this.components.registrar.handle(SIGNALING_PROTOCOL, (data: IncomingStreamData) => {
120
119
  // ensure we don't try to upgrade forever
121
120
  const signal = this.components.upgrader.createInboundAbortSignal(this.shutdownController.signal)
122
121
 
123
- this._onProtocol(stream, connection, signal)
122
+ this._onProtocol(data, signal)
124
123
  .catch(err => {
125
- this.log.error('failed to handle incoming connect from %p', connection.remotePeer, err)
124
+ this.log.error('failed to handle incoming connect from %p', data.connection.remotePeer, err)
126
125
  })
127
126
  .finally(() => {
128
127
  signal.clear()
@@ -181,18 +180,16 @@ export class WebRTCTransport implements Transport<WebRTCDialEvents>, Startable {
181
180
  onProgress: options.onProgress
182
181
  })
183
182
 
184
- const webRTCConn = toMultiaddrConnection({
183
+ const webRTCConn = new WebRTCMultiaddrConnection(this.components, {
185
184
  peerConnection,
185
+ timeline: { open: Date.now() },
186
186
  remoteAddr: remoteAddress,
187
- metrics: this.metrics?.dialerEvents,
188
- direction: 'outbound',
189
- log: this.components.logger.forComponent('libp2p:webrtc:connection')
187
+ metrics: this.metrics?.dialerEvents
190
188
  })
191
189
 
192
190
  const connection = await options.upgrader.upgradeOutbound(webRTCConn, {
193
191
  skipProtection: true,
194
192
  skipEncryption: true,
195
- remotePeer: getRemotePeer(ma),
196
193
  muxerFactory,
197
194
  onProgress: options.onProgress,
198
195
  signal: options.signal
@@ -204,29 +201,18 @@ export class WebRTCTransport implements Transport<WebRTCDialEvents>, Startable {
204
201
  return connection
205
202
  }
206
203
 
207
- async _onProtocol (stream: Stream, connection: Connection, signal: AbortSignal): Promise<void> {
204
+ async _onProtocol ({ connection, stream }: IncomingStreamData, signal: AbortSignal): Promise<void> {
208
205
  const peerConnection = new RTCPeerConnection(await getRtcConfiguration(this.init.rtcConfiguration))
209
-
210
- // make sure C++ peer connection is garbage collected
211
- // https://github.com/murat-dogan/node-datachannel/issues/366#issuecomment-3228453155
212
- peerConnection.addEventListener('connectionstatechange', () => {
213
- switch (peerConnection.connectionState) {
214
- case 'closed':
215
- peerConnection.close()
216
- break
217
- default:
218
- break
219
- }
220
- })
221
- const muxerFactory = new DataChannelMuxerFactory({
222
- // @ts-expect-error https://github.com/murat-dogan/node-datachannel/pull/370
206
+ const muxerFactory = new DataChannelMuxerFactory(this.components, {
223
207
  peerConnection,
224
208
  dataChannelOptions: this.init.dataChannel
225
209
  })
226
210
 
227
211
  try {
228
- const { remoteAddress, remotePeer } = await handleIncomingStream(stream, connection, {
212
+ const { remoteAddress } = await handleIncomingStream({
229
213
  peerConnection,
214
+ connection,
215
+ stream,
230
216
  signal,
231
217
  log: this.log
232
218
  })
@@ -236,18 +222,16 @@ export class WebRTCTransport implements Transport<WebRTCDialEvents>, Startable {
236
222
  signal
237
223
  })
238
224
 
239
- const webRTCConn = toMultiaddrConnection({
225
+ const webRTCConn = new WebRTCMultiaddrConnection(this.components, {
240
226
  peerConnection,
227
+ timeline: { open: (new Date()).getTime() },
241
228
  remoteAddr: remoteAddress,
242
- metrics: this.metrics?.listenerEvents,
243
- direction: 'inbound',
244
- log: this.components.logger.forComponent('libp2p:webrtc:connection')
229
+ metrics: this.metrics?.listenerEvents
245
230
  })
246
231
 
247
232
  await this.components.upgrader.upgradeInbound(webRTCConn, {
248
233
  skipEncryption: true,
249
234
  skipProtection: true,
250
- remotePeer,
251
235
  muxerFactory,
252
236
  signal
253
237
  })
@@ -263,7 +247,7 @@ export class WebRTCTransport implements Transport<WebRTCDialEvents>, Startable {
263
247
  }
264
248
  }
265
249
 
266
- private _closeOnShutdown (pc: RTCPeerConnection, webRTCConn: MultiaddrConnection): void {
250
+ private _closeOnShutdown (pc: RTCPeerConnection, webRTCConn: WebRTCMultiaddrConnection): void {
267
251
  // close the connection on shut down
268
252
  const shutDownListener = (): void => {
269
253
  webRTCConn.close()
@@ -1,13 +1,12 @@
1
- import { ConnectionFailedError, InvalidMessageError, InvalidMultiaddrError } from '@libp2p/interface'
2
- import { peerIdFromString } from '@libp2p/peer-id'
1
+ import { ConnectionFailedError, InvalidMessageError } from '@libp2p/interface'
2
+ import pDefer from 'p-defer'
3
3
  import { CustomProgressEvent } from 'progress-events'
4
4
  import { isFirefox } from '../util.js'
5
5
  import { RTCIceCandidate } from '../webrtc/index.js'
6
6
  import { Message } from './pb/message.js'
7
7
  import type { WebRTCDialEvents } from './transport.js'
8
8
  import type { RTCPeerConnection } from '../webrtc/index.js'
9
- import type { AbortOptions, LoggerOptions, PeerId, Stream } from '@libp2p/interface'
10
- import type { Multiaddr } from '@multiformats/multiaddr'
9
+ import type { AbortOptions, LoggerOptions, Stream } from '@libp2p/interface'
11
10
  import type { MessageStream } from 'it-protobuf-stream'
12
11
  import type { DeferredPromise } from 'p-defer'
13
12
  import type { ProgressOptions } from 'progress-events'
@@ -18,7 +17,7 @@ export interface ReadCandidatesOptions extends AbortOptions, LoggerOptions, Prog
18
17
 
19
18
  export const readCandidatesUntilConnected = async (pc: RTCPeerConnection, stream: MessageStream<Message, Stream>, options: ReadCandidatesOptions): Promise<void> => {
20
19
  try {
21
- const connectedPromise = Promise.withResolvers<void>()
20
+ const connectedPromise: DeferredPromise<void> = pDefer()
22
21
  resolveOnConnected(pc, connectedPromise)
23
22
 
24
23
  // read candidates until we are connected or we reach the end of the stream
@@ -95,19 +94,3 @@ function resolveOnConnected (pc: RTCPeerConnection, promise: DeferredPromise<voi
95
94
  }
96
95
  }
97
96
  }
98
-
99
- export function getRemotePeer (ma: Multiaddr): PeerId {
100
- let remotePeer: PeerId | undefined
101
-
102
- for (const component of ma.getComponents()) {
103
- if (component.name === 'p2p') {
104
- remotePeer = peerIdFromString(component.value ?? '')
105
- }
106
- }
107
-
108
- if (remotePeer == null) {
109
- throw new InvalidMultiaddrError('Remote peerId must be present in multiaddr')
110
- }
111
-
112
- return remotePeer
113
- }
@@ -1,11 +1,12 @@
1
1
  import { isIPv4 } from '@chainsafe/is-ip'
2
2
  import { InvalidParametersError } from '@libp2p/interface'
3
- import { getNetConfig, getThinWaistAddresses } from '@libp2p/utils'
4
- import { CODE_CERTHASH, CODE_WEBRTC_DIRECT, multiaddr } from '@multiformats/multiaddr'
3
+ import { getThinWaistAddresses } from '@libp2p/utils/get-thin-waist-addresses'
4
+ import { multiaddr, fromStringTuples } from '@multiformats/multiaddr'
5
5
  import { WebRTCDirect } from '@multiformats/multiaddr-matcher'
6
6
  import getPort from 'get-port'
7
7
  import { TypedEventEmitter, setMaxListeners } from 'main-event'
8
8
  import pWaitFor from 'p-wait-for'
9
+ import { CODEC_CERTHASH, CODEC_WEBRTC_DIRECT } from '../constants.js'
9
10
  import { connect } from './utils/connect.js'
10
11
  import { createDialerRTCPeerConnection } from './utils/get-rtcpeerconnection.js'
11
12
  import { stunListener } from './utils/stun-listener.js'
@@ -93,11 +94,7 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
93
94
  }
94
95
 
95
96
  async listen (ma: Multiaddr): Promise<void> {
96
- const { host, port, type, protocol } = getNetConfig(ma)
97
-
98
- if (port == null || protocol !== 'udp' || (type !== 'ip4' && type !== 'ip6')) {
99
- throw new InvalidParametersError(`Multiaddr ${ma} was not an IPv4 or IPv6 address or was missing a UDP port`)
100
- }
97
+ const { host, port, family } = ma.toOptions()
101
98
 
102
99
  let udpMuxServer: UDPMuxServer | undefined
103
100
 
@@ -109,7 +106,7 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
109
106
  udpMuxServer = UDP_MUX_LISTENERS.find(s => s.port === port)
110
107
 
111
108
  // make sure the port is free for the given family
112
- if (udpMuxServer != null && ((udpMuxServer.isIPv4 && type === 'ip4') || (udpMuxServer.isIPv6 && type === 'ip6'))) {
109
+ if (udpMuxServer != null && ((udpMuxServer.isIPv4 && family === 4) || (udpMuxServer.isIPv6 && family === 6))) {
113
110
  throw new InvalidParametersError(`There is already a listener for ${host}:${port}`)
114
111
  }
115
112
 
@@ -122,13 +119,13 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
122
119
  // start the mux server if we don't have one already
123
120
  if (udpMuxServer == null) {
124
121
  this.log('starting UDP mux server on %s:%p', host, port)
125
- udpMuxServer = this.startUDPMuxServer(host, port, type === 'ip4' ? 4 : 6)
122
+ udpMuxServer = this.startUDPMuxServer(host, port, family)
126
123
  UDP_MUX_LISTENERS.push(udpMuxServer)
127
124
  }
128
125
 
129
- if (type === 'ip4') {
126
+ if (family === 4) {
130
127
  udpMuxServer.isIPv4 = true
131
- } else if (type === 'ip6') {
128
+ } else if (family === 6) {
132
129
  udpMuxServer.isIPv6 = true
133
130
  }
134
131
 
@@ -208,7 +205,7 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
208
205
  metrics: this.components.metrics,
209
206
  events: this.metrics?.listenerEvents,
210
207
  signal,
211
- remoteAddr: multiaddr(`/ip${isIPv4(remoteHost) ? 4 : 6}/${remoteHost}/udp/${remotePort}/webrtc-direct`),
208
+ remoteAddr: multiaddr(`/ip${isIPv4(remoteHost) ? 4 : 6}/${remoteHost}/udp/${remotePort}`),
212
209
  dataChannel: this.init.dataChannel,
213
210
  upgrader: this.init.upgrader,
214
211
  peerId: this.components.peerId,
@@ -241,23 +238,19 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
241
238
  }
242
239
 
243
240
  // add the certhash if it is missing
244
- const components = ma.getComponents()
241
+ const tuples = ma.stringTuples()
245
242
 
246
- for (let j = 0; j < components.length; j++) {
247
- if (components[j].code !== CODE_WEBRTC_DIRECT) {
243
+ for (let j = 0; j < tuples.length; j++) {
244
+ if (tuples[j][0] !== CODEC_WEBRTC_DIRECT) {
248
245
  continue
249
246
  }
250
247
 
251
248
  const certhashIndex = j + 1
252
249
 
253
- if (components[certhashIndex] == null || components[certhashIndex].code !== CODE_CERTHASH) {
254
- components.splice(certhashIndex, 0, {
255
- code: CODE_CERTHASH,
256
- name: 'certhash',
257
- value: this.certificate?.certhash
258
- })
250
+ if (tuples[certhashIndex] == null || tuples[certhashIndex][0] !== CODEC_CERTHASH) {
251
+ tuples.splice(certhashIndex, 0, [CODEC_CERTHASH, this.certificate?.certhash])
259
252
 
260
- ma = multiaddr(components)
253
+ ma = fromStringTuples(tuples)
261
254
  multiaddrs[i] = ma
262
255
  }
263
256
  }
@@ -1,7 +1,6 @@
1
1
  import { generateKeyPair, privateKeyToCryptoKeyPair } from '@libp2p/crypto/keys'
2
2
  import { InvalidParametersError, NotFoundError, NotStartedError, serviceCapabilities, transportSymbol } from '@libp2p/interface'
3
3
  import { peerIdFromString } from '@libp2p/peer-id'
4
- import { CODE_P2P } from '@multiformats/multiaddr'
5
4
  import { WebRTCDirect } from '@multiformats/multiaddr-matcher'
6
5
  import { BasicConstraintsExtension, X509Certificate, X509CertificateGenerator } from '@peculiar/x509'
7
6
  import { Key } from 'interface-datastore'
@@ -165,7 +164,7 @@ export class WebRTCDirectTransport implements Transport, Startable {
165
164
  options.signal.throwIfAborted()
166
165
 
167
166
  let theirPeerId: PeerId | undefined
168
- const remotePeerString = ma.getComponents().findLast(c => c.code === CODE_P2P)?.value
167
+ const remotePeerString = ma.getPeerId()
169
168
  if (remotePeerString != null) {
170
169
  theirPeerId = peerIdFromString(remotePeerString)
171
170
  }
@@ -187,7 +186,7 @@ export class WebRTCDirectTransport implements Transport, Startable {
187
186
  dataChannel: this.init.dataChannel,
188
187
  upgrader: options.upgrader,
189
188
  peerId: this.components.peerId,
190
- remotePeer: theirPeerId,
189
+ remotePeerId: theirPeerId,
191
190
  privateKey: this.components.privateKey
192
191
  })
193
192
  } catch (err) {
@@ -1,8 +1,8 @@
1
- import { noise } from '@libp2p/noise'
2
- import { pEvent } from 'p-event'
1
+ import { noise } from '@chainsafe/libp2p-noise'
2
+ import { raceEvent } from 'race-event'
3
3
  import { WebRTCTransportError } from '../../error.js'
4
+ import { WebRTCMultiaddrConnection } from '../../maconn.js'
4
5
  import { DataChannelMuxerFactory } from '../../muxer.js'
5
- import { toMultiaddrConnection } from '../../rtcpeerconnection-to-conn.ts'
6
6
  import { createStream } from '../../stream.js'
7
7
  import { isFirefox } from '../../util.js'
8
8
  import { generateNoisePrologue } from './generate-noise-prologue.js'
@@ -22,7 +22,7 @@ export interface ConnectOptions {
22
22
  dataChannel?: DataChannelOptions
23
23
  upgrader: Upgrader
24
24
  peerId: PeerId
25
- remotePeer?: PeerId
25
+ remotePeerId?: PeerId
26
26
  signal: AbortSignal
27
27
  privateKey: PrivateKey
28
28
  }
@@ -83,7 +83,7 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
83
83
 
84
84
  if (handshakeDataChannel.readyState !== 'open') {
85
85
  options.log.trace('%s wait for handshake channel to open, starting status %s', options.role, handshakeDataChannel.readyState)
86
- await pEvent(handshakeDataChannel, 'open', options)
86
+ await raceEvent(handshakeDataChannel, 'open', options.signal)
87
87
  }
88
88
 
89
89
  options.log.trace('%s handshake channel opened', options.role)
@@ -116,19 +116,20 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
116
116
  const handshakeStream = createStream({
117
117
  channel: handshakeDataChannel,
118
118
  direction: 'outbound',
119
- isHandshake: true,
119
+ handshake: true,
120
120
  log: options.log,
121
121
  ...(options.dataChannel ?? {})
122
122
  })
123
123
 
124
124
  // Creating the connection before completion of the noise
125
125
  // handshake ensures that the stream opening callback is set up
126
- const maConn = toMultiaddrConnection({
126
+ const maConn = new WebRTCMultiaddrConnection(options, {
127
127
  peerConnection,
128
128
  remoteAddr: options.remoteAddr,
129
- metrics: options.events,
130
- direction: options.role === 'client' ? 'outbound' : 'inbound',
131
- log: options.logger.forComponent('libp2p:webrtc-direct:connection')
129
+ timeline: {
130
+ open: Date.now()
131
+ },
132
+ metrics: options.events
132
133
  })
133
134
 
134
135
  peerConnection.addEventListener(CONNECTION_STATE_CHANGE_EVENT, () => {
@@ -149,8 +150,7 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
149
150
  // Track opened peer connection
150
151
  options.events?.increment({ peer_connection: true })
151
152
 
152
- const muxerFactory = new DataChannelMuxerFactory({
153
- // @ts-expect-error https://github.com/murat-dogan/node-datachannel/pull/370
153
+ const muxerFactory = new DataChannelMuxerFactory(options, {
154
154
  peerConnection,
155
155
  metrics: options.events,
156
156
  dataChannelOptions: options.dataChannel
@@ -161,8 +161,8 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
161
161
  // handshake. Therefore, we need to secure an inbound noise connection
162
162
  // from the server.
163
163
  options.log.trace('%s secure inbound', options.role)
164
- const result = await connectionEncrypter.secureInbound(handshakeStream, {
165
- remotePeer: options.remotePeer,
164
+ await connectionEncrypter.secureInbound(handshakeStream, {
165
+ remotePeer: options.remotePeerId,
166
166
  signal: options.signal,
167
167
  skipStreamMuxerNegotiation: true
168
168
  })
@@ -171,7 +171,6 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
171
171
  return await options.upgrader.upgradeOutbound(maConn, {
172
172
  skipProtection: true,
173
173
  skipEncryption: true,
174
- remotePeer: result.remotePeer,
175
174
  muxerFactory,
176
175
  signal: options.signal
177
176
  })
@@ -182,7 +181,7 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
182
181
  // the client.
183
182
  options.log.trace('%s secure outbound', options.role)
184
183
  const result = await connectionEncrypter.secureOutbound(handshakeStream, {
185
- remotePeer: options.remotePeer,
184
+ remotePeer: options.remotePeerId,
186
185
  signal: options.signal,
187
186
  skipStreamMuxerNegotiation: true
188
187
  })
@@ -194,13 +193,11 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
194
193
  await options.upgrader.upgradeInbound(maConn, {
195
194
  skipProtection: true,
196
195
  skipEncryption: true,
197
- remotePeer: result.remotePeer,
198
196
  muxerFactory,
199
197
  signal: options.signal
200
198
  })
201
199
  } catch (err) {
202
200
  handshakeDataChannel.close()
203
- peerConnection.close()
204
201
 
205
202
  throw err
206
203
  }
@@ -1,10 +1,10 @@
1
+ import { PeerConnection } from '@ipshipyard/node-datachannel'
2
+ import { RTCPeerConnection } from '@ipshipyard/node-datachannel/polyfill'
1
3
  import { Crypto } from '@peculiar/webcrypto'
2
- import { PeerConnection } from 'node-datachannel'
3
- import { RTCPeerConnection } from 'node-datachannel/polyfill'
4
4
  import { DEFAULT_ICE_SERVERS, MAX_MESSAGE_SIZE } from '../../constants.js'
5
5
  import { generateTransportCertificate } from './generate-certificates.js'
6
6
  import type { TransportCertificate } from '../../index.js'
7
- import type { CertificateFingerprint } from 'node-datachannel'
7
+ import type { CertificateFingerprint } from '@ipshipyard/node-datachannel'
8
8
 
9
9
  const crypto = new Crypto()
10
10
 
@@ -14,7 +14,7 @@ interface DirectRTCPeerConnectionInit extends RTCConfiguration {
14
14
  }
15
15
 
16
16
  export class DirectRTCPeerConnection extends RTCPeerConnection {
17
- private peerConnection: PeerConnection
17
+ private readonly peerConnection: PeerConnection
18
18
  private readonly ufrag: string
19
19
 
20
20
  constructor (init: DirectRTCPeerConnectionInit) {
@@ -22,18 +22,6 @@ export class DirectRTCPeerConnection extends RTCPeerConnection {
22
22
 
23
23
  this.peerConnection = init.peerConnection
24
24
  this.ufrag = init.ufrag
25
-
26
- // make sure C++ peer connection is garbage collected
27
- // https://github.com/murat-dogan/node-datachannel/issues/366#issuecomment-3228453155
28
- this.addEventListener('connectionstatechange', () => {
29
- switch (this.connectionState) {
30
- case 'closed':
31
- this.peerConnection.close()
32
- break
33
- default:
34
- break
35
- }
36
- })
37
25
  }
38
26
 
39
27
  async createOffer (): Promise<globalThis.RTCSessionDescriptionInit | any> {
@@ -1,11 +1,10 @@
1
1
  import { InvalidParametersError } from '@libp2p/interface'
2
- import { getNetConfig } from '@libp2p/utils'
3
- import { CODE_CERTHASH, multiaddr } from '@multiformats/multiaddr'
2
+ import { multiaddr } from '@multiformats/multiaddr'
4
3
  import { base64url } from 'multiformats/bases/base64'
5
4
  import { bases, digest } from 'multiformats/basics'
6
5
  import * as Digest from 'multiformats/hashes/digest'
7
6
  import { sha256 } from 'multiformats/hashes/sha2'
8
- import { MAX_MESSAGE_SIZE } from '../../constants.js'
7
+ import { CODEC_CERTHASH, MAX_MESSAGE_SIZE } from '../../constants.js'
9
8
  import { InvalidFingerprintError, UnsupportedHashAlgorithmError } from '../../error.js'
10
9
  import type { Multiaddr } from '@multiformats/multiaddr'
11
10
  import type { MultihashDigest } from 'multiformats/hashes/interface'
@@ -28,8 +27,8 @@ export function getFingerprintFromSdp (sdp: string | undefined): string | undefi
28
27
 
29
28
  // Extract the certhash from a multiaddr
30
29
  export function certhash (ma: Multiaddr): string {
31
- const components = ma.getComponents()
32
- const certhash = components.find(c => c.code === CODE_CERTHASH)?.value
30
+ const tups = ma.stringTuples()
31
+ const certhash = tups.filter((tup) => tup[0] === CODEC_CERTHASH).map((tup) => tup[1])[0]
33
32
 
34
33
  if (certhash === undefined || certhash === '') {
35
34
  throw new InvalidParametersError(`Couldn't find a certhash component of multiaddr: ${ma.toString()}`)
@@ -101,20 +100,15 @@ export function toSupportedHashFunction (code: number): 'sha-1' | 'sha-256' | 's
101
100
  * ice-lite mode and DTLS active mode.
102
101
  */
103
102
  export function serverAnswerFromMultiaddr (ma: Multiaddr, ufrag: string): RTCSessionDescriptionInit {
104
- const { host, port, type } = getNetConfig(ma)
105
-
106
- if (type !== 'ip4' && type !== 'ip6') {
107
- throw new InvalidParametersError(`Multiaddr ${ma} was not an IPv4 or IPv6 address`)
108
- }
109
-
103
+ const { host, port, family } = ma.toOptions()
110
104
  const fingerprint = ma2Fingerprint(ma)
111
105
  const sdp = `v=0
112
- o=- 0 0 IN IP${type === 'ip4' ? 4 : 6} ${host}
106
+ o=- 0 0 IN IP${family} ${host}
113
107
  s=-
114
108
  t=0 0
115
109
  a=ice-lite
116
110
  m=application ${port} UDP/DTLS/SCTP webrtc-datachannel
117
- c=IN IP${type === 'ip4' ? 4 : 6} ${host}
111
+ c=IN IP${family} ${host}
118
112
  a=mid:0
119
113
  a=ice-options:ice2
120
114
  a=ice-ufrag:${ufrag}
@@ -137,16 +131,11 @@ a=end-of-candidates
137
131
  * Create an offer SDP message from a multiaddr
138
132
  */
139
133
  export function clientOfferFromMultiAddr (ma: Multiaddr, ufrag: string): RTCSessionDescriptionInit {
140
- const { host, port, type } = getNetConfig(ma)
141
-
142
- if (type !== 'ip4' && type !== 'ip6') {
143
- throw new InvalidParametersError(`Multiaddr ${ma} was not an IPv4 or IPv6 address`)
144
- }
145
-
134
+ const { host, port, family } = ma.toOptions()
146
135
  const sdp = `v=0
147
- o=- 0 0 IN IP${type === 'ip4' ? 4 : 6} ${host}
136
+ o=- 0 0 IN IP${family} ${host}
148
137
  s=-
149
- c=IN IP${type === 'ip4' ? 4 : 6} ${host}
138
+ c=IN IP${family} ${host}
150
139
  t=0 0
151
140
  a=ice-options:ice2,trickle
152
141
  m=application ${port} UDP/DTLS/SCTP webrtc-datachannel
@@ -177,13 +166,8 @@ export function munge (desc: RTCSessionDescriptionInit, ufrag: string): RTCSessi
177
166
 
178
167
  const lineBreak = desc.sdp.includes('\r\n') ? '\r\n' : '\n'
179
168
 
180
- try {
181
- desc.sdp = desc.sdp
182
- .replace(/\na=ice-ufrag:[^\n]*\n/, '\na=ice-ufrag:' + ufrag + lineBreak)
183
- .replace(/\na=ice-pwd:[^\n]*\n/, '\na=ice-pwd:' + ufrag + lineBreak)
184
- } catch {
185
- // fails under Node.js
186
- }
187
-
169
+ desc.sdp = desc.sdp
170
+ .replace(/\na=ice-ufrag:[^\n]*\n/, '\na=ice-ufrag:' + ufrag + lineBreak)
171
+ .replace(/\na=ice-pwd:[^\n]*\n/, '\na=ice-pwd:' + ufrag + lineBreak)
188
172
  return desc
189
173
  }
@@ -1,5 +1,5 @@
1
1
  import { isIPv4 } from '@chainsafe/is-ip'
2
- import { IceUdpMuxListener } from 'node-datachannel'
2
+ import { IceUdpMuxListener } from '@ipshipyard/node-datachannel'
3
3
  import type { Logger } from '@libp2p/interface'
4
4
  import type { AddressInfo } from 'node:net'
5
5