@libp2p/webrtc 1.0.2 → 1.0.3

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.
package/src/transport.ts CHANGED
@@ -6,7 +6,6 @@ import { logger } from '@libp2p/logger'
6
6
  import * as p from '@libp2p/peer-id'
7
7
  import type { Multiaddr } from '@multiformats/multiaddr'
8
8
  import * as multihashes from 'multihashes'
9
- import defer from 'p-defer'
10
9
  import { fromString as uint8arrayFromString } from 'uint8arrays/from-string'
11
10
  import { concat } from 'uint8arrays/concat'
12
11
  import { dataChannelError, inappropriateMultiaddr, unimplemented, invalidArgument } from './error.js'
@@ -22,7 +21,7 @@ const log = logger('libp2p:webrtc:transport')
22
21
  /**
23
22
  * The time to wait, in milliseconds, for the data channel handshake to complete
24
23
  */
25
- const HANDSHAKE_TIMEOUT_MS = 10000
24
+ const HANDSHAKE_TIMEOUT_MS = 10_000
26
25
 
27
26
  /**
28
27
  * Created by converting the hexadecimal protocol code to an integer.
@@ -97,11 +96,11 @@ export class WebRTCTransport implements Transport {
97
96
  * Connect to a peer using a multiaddr
98
97
  */
99
98
  async _connect (ma: Multiaddr, options: WebRTCDialOptions): Promise<Connection> {
100
- const rps = ma.getPeerId()
101
-
102
- if (rps === null) {
99
+ const remotePeerString = ma.getPeerId()
100
+ if (remotePeerString === null) {
103
101
  throw inappropriateMultiaddr("we need to have the remote's PeerId")
104
102
  }
103
+ const theirPeerId = p.peerIdFromString(remotePeerString)
105
104
 
106
105
  const remoteCerthash = sdp.decodeCerthash(sdp.certhash(ma))
107
106
 
@@ -119,31 +118,32 @@ export class WebRTCTransport implements Transport {
119
118
  // create data channel for running the noise handshake. Once the data channel is opened,
120
119
  // the remote will initiate the noise handshake. This is used to confirm the identity of
121
120
  // the peer.
122
- const dataChannelOpenPromise = defer()
123
- const handshakeDataChannel = peerConnection.createDataChannel('handshake', { negotiated: true, id: 0 })
124
- const handhsakeTimeout = setTimeout(() => {
125
- const error = `Data channel was never opened: state: ${handshakeDataChannel.readyState}`
126
- log.error(error)
127
- dataChannelOpenPromise.reject(dataChannelError('data', error))
128
- }, HANDSHAKE_TIMEOUT_MS)
129
-
130
- handshakeDataChannel.onopen = (_) => {
131
- clearTimeout(handhsakeTimeout)
132
- dataChannelOpenPromise.resolve()
133
- }
121
+ const dataChannelOpenPromise = new Promise<RTCDataChannel>((resolve, reject) => {
122
+ const handshakeDataChannel = peerConnection.createDataChannel('', { negotiated: true, id: 0 })
123
+ const handshakeTimeout = setTimeout(() => {
124
+ const error = `Data channel was never opened: state: ${handshakeDataChannel.readyState}`
125
+ log.error(error)
126
+ reject(dataChannelError('data', error))
127
+ }, HANDSHAKE_TIMEOUT_MS)
128
+
129
+ handshakeDataChannel.onopen = (_) => {
130
+ clearTimeout(handshakeTimeout)
131
+ resolve(handshakeDataChannel)
132
+ }
134
133
 
135
- // ref: https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/error_event
136
- handshakeDataChannel.onerror = (event: Event) => {
137
- clearTimeout(handhsakeTimeout)
138
- const errorTarget = event.target?.toString() ?? 'not specified'
139
- const error = `Error opening a data channel for handshaking: ${errorTarget}`
140
- log.error(error)
141
- dataChannelOpenPromise.reject(dataChannelError('data', error))
142
- }
134
+ // ref: https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/error_event
135
+ handshakeDataChannel.onerror = (event: Event) => {
136
+ clearTimeout(handshakeTimeout)
137
+ const errorTarget = event.target?.toString() ?? 'not specified'
138
+ const error = `Error opening a data channel for handshaking: ${errorTarget}`
139
+ log.error(error)
140
+ reject(dataChannelError('data', error))
141
+ }
142
+ })
143
143
 
144
144
  const ufrag = 'libp2p+webrtc+v1/' + genUfrag(32)
145
145
 
146
- // Create offer and munge sdp with ufrag = pwd. This allows the remote to
146
+ // Create offer and munge sdp with ufrag == pwd. This allows the remote to
147
147
  // respond to STUN messages without performing an actual SDP exchange.
148
148
  // This is because it can infer the passwd field by reading the USERNAME
149
149
  // attribute of the STUN message.
@@ -156,23 +156,23 @@ export class WebRTCTransport implements Transport {
156
156
  await peerConnection.setRemoteDescription(answerSdp)
157
157
 
158
158
  // wait for peerconnection.onopen to fire, or for the datachannel to open
159
- await dataChannelOpenPromise.promise
159
+ const handshakeDataChannel = await dataChannelOpenPromise
160
160
 
161
161
  const myPeerId = this.components.peerId
162
- const theirPeerId = p.peerIdFromString(rps)
163
162
 
164
163
  // Do noise handshake.
165
164
  // Set the Noise Prologue to libp2p-webrtc-noise:<FINGERPRINTS> before starting the actual Noise handshake.
166
165
  // <FINGERPRINTS> is the concatenation of the of the two TLS fingerprints of A and B in their multihash byte representation, sorted in ascending order.
167
- const fingerprintsPrologue = this.generateNoisePrologue(peerConnection, remoteCerthash.name, ma)
166
+ const fingerprintsPrologue = this.generateNoisePrologue(peerConnection, remoteCerthash.code, ma)
168
167
 
169
168
  // Since we use the default crypto interface and do not use a static key or early data,
170
169
  // we pass in undefined for these parameters.
171
- const noiseInit = { staticNoiseKey: undefined, extensions: undefined, crypto: undefined, prologueBytes: fingerprintsPrologue }
172
- const noise = Noise(noiseInit)()
173
- const wrappedChannel = new WebRTCStream({ channel: handshakeDataChannel, stat: { direction: 'outbound', timeline: { open: 1 } } })
170
+ const noise = Noise({ prologueBytes: fingerprintsPrologue })()
171
+
172
+ const wrappedChannel = new WebRTCStream({ channel: handshakeDataChannel, stat: { direction: 'inbound', timeline: { open: 1 } } })
174
173
  const wrappedDuplex = {
175
174
  ...wrappedChannel,
175
+ sink: wrappedChannel.sink.bind(wrappedChannel),
176
176
  source: {
177
177
  [Symbol.asyncIterator]: async function * () {
178
178
  for await (const list of wrappedChannel.source) {
@@ -205,7 +205,7 @@ export class WebRTCTransport implements Transport {
205
205
  * Generate a noise prologue from the peer connection's certificate.
206
206
  * noise prologue = bytes('libp2p-webrtc-noise:') + noise-responder fingerprint + noise-initiator fingerprint
207
207
  */
208
- private generateNoisePrologue (pc: RTCPeerConnection, hashName: multihashes.HashName, ma: Multiaddr): Uint8Array {
208
+ private generateNoisePrologue (pc: RTCPeerConnection, hashCode: multihashes.HashCode, ma: Multiaddr): Uint8Array {
209
209
  if (pc.getConfiguration().certificates?.length === 0) {
210
210
  throw invalidArgument('no local certificate')
211
211
  }
@@ -224,7 +224,7 @@ export class WebRTCTransport implements Transport {
224
224
 
225
225
  const localFpString = localFingerprint.value.replace(/:/g, '')
226
226
  const localFpArray = uint8arrayFromString(localFpString, 'hex')
227
- const local = multihashes.encode(localFpArray, multihashes.names[hashName])
227
+ const local = multihashes.encode(localFpArray, hashCode)
228
228
  const remote: Uint8Array = sdp.mbdecoder.decode(sdp.certhash(ma))
229
229
  const prefix = uint8arrayFromString('libp2p-webrtc-noise:')
230
230