@libp2p/webrtc 5.0.26 → 5.0.27-2e35b6055
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/README.md +16 -21
- package/dist/index.min.js +31 -12
- package/dist/src/constants.d.ts +2 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +2 -0
- package/dist/src/constants.js.map +1 -1
- package/dist/src/index.d.ts +33 -21
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +16 -21
- package/dist/src/index.js.map +1 -1
- package/dist/src/maconn.d.ts +1 -0
- package/dist/src/maconn.d.ts.map +1 -1
- package/dist/src/maconn.js +4 -3
- package/dist/src/maconn.js.map +1 -1
- package/dist/src/muxer.d.ts +1 -0
- package/dist/src/muxer.d.ts.map +1 -1
- package/dist/src/muxer.js +2 -2
- package/dist/src/muxer.js.map +1 -1
- package/dist/src/private-to-private/util.d.ts +1 -0
- package/dist/src/private-to-private/util.d.ts.map +1 -1
- package/dist/src/private-to-private/util.js.map +1 -1
- package/dist/src/private-to-public/listener.browser.d.ts +17 -0
- package/dist/src/private-to-public/listener.browser.d.ts.map +1 -0
- package/dist/src/private-to-public/listener.browser.js +13 -0
- package/dist/src/private-to-public/listener.browser.js.map +1 -0
- package/dist/src/private-to-public/listener.d.ts +37 -0
- package/dist/src/private-to-public/listener.d.ts.map +1 -0
- package/dist/src/private-to-public/listener.js +175 -0
- package/dist/src/private-to-public/listener.js.map +1 -0
- package/dist/src/private-to-public/pb/message.d.ts.map +1 -0
- package/dist/src/private-to-public/pb/message.js.map +1 -0
- package/dist/src/private-to-public/transport.d.ts +10 -11
- package/dist/src/private-to-public/transport.d.ts.map +1 -1
- package/dist/src/private-to-public/transport.js +28 -155
- package/dist/src/private-to-public/transport.js.map +1 -1
- package/dist/src/private-to-public/utils/connect.d.ts +27 -0
- package/dist/src/private-to-public/utils/connect.d.ts.map +1 -0
- package/dist/src/private-to-public/utils/connect.js +142 -0
- package/dist/src/private-to-public/utils/connect.js.map +1 -0
- package/dist/src/private-to-public/utils/generate-certificates.browser.d.ts +2 -0
- package/dist/src/private-to-public/utils/generate-certificates.browser.d.ts.map +1 -0
- package/dist/src/private-to-public/utils/generate-certificates.browser.js +4 -0
- package/dist/src/private-to-public/utils/generate-certificates.browser.js.map +1 -0
- package/dist/src/private-to-public/utils/generate-certificates.d.ts +8 -0
- package/dist/src/private-to-public/utils/generate-certificates.d.ts.map +1 -0
- package/dist/src/private-to-public/utils/generate-certificates.js +39 -0
- package/dist/src/private-to-public/utils/generate-certificates.js.map +1 -0
- package/dist/src/private-to-public/utils/generate-noise-prologue.d.ts +7 -0
- package/dist/src/private-to-public/utils/generate-noise-prologue.d.ts.map +1 -0
- package/dist/src/private-to-public/utils/generate-noise-prologue.js +22 -0
- package/dist/src/private-to-public/utils/generate-noise-prologue.js.map +1 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.browser.d.ts +2 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.browser.d.ts.map +1 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.browser.js +20 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.browser.js.map +1 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts +19 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts.map +1 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.js +86 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.js.map +1 -0
- package/dist/src/private-to-public/utils/sdp.d.ts +36 -0
- package/dist/src/private-to-public/utils/sdp.d.ts.map +1 -0
- package/dist/src/private-to-public/{sdp.js → utils/sdp.js} +72 -57
- package/dist/src/private-to-public/utils/sdp.js.map +1 -0
- package/dist/src/private-to-public/utils/stun-listener.d.ts +15 -0
- package/dist/src/private-to-public/utils/stun-listener.d.ts.map +1 -0
- package/dist/src/private-to-public/utils/stun-listener.js +79 -0
- package/dist/src/private-to-public/utils/stun-listener.js.map +1 -0
- package/dist/src/stream.d.ts +2 -0
- package/dist/src/stream.d.ts.map +1 -1
- package/dist/src/stream.js +56 -12
- package/dist/src/stream.js.map +1 -1
- package/dist/src/util.d.ts +4 -0
- package/dist/src/util.d.ts.map +1 -1
- package/dist/src/util.js +7 -1
- package/dist/src/util.js.map +1 -1
- package/dist/src/webrtc/index.d.ts +2 -1
- package/dist/src/webrtc/index.d.ts.map +1 -1
- package/dist/src/webrtc/index.js +1 -1
- package/dist/src/webrtc/index.js.map +1 -1
- package/package.json +22 -11
- package/src/constants.ts +4 -0
- package/src/index.ts +35 -21
- package/src/maconn.ts +5 -3
- package/src/muxer.ts +3 -2
- package/src/private-to-private/util.ts +1 -0
- package/src/private-to-public/listener.browser.ts +28 -0
- package/src/private-to-public/listener.ts +233 -0
- package/src/private-to-public/transport.ts +39 -182
- package/src/private-to-public/utils/connect.ts +192 -0
- package/src/private-to-public/utils/generate-certificates.browser.ts +3 -0
- package/src/private-to-public/utils/generate-certificates.ts +51 -0
- package/src/private-to-public/utils/generate-noise-prologue.ts +26 -0
- package/src/private-to-public/utils/get-rtcpeerconnection.browser.ts +22 -0
- package/src/private-to-public/utils/get-rtcpeerconnection.ts +108 -0
- package/src/private-to-public/utils/sdp.ts +174 -0
- package/src/private-to-public/utils/stun-listener.ts +104 -0
- package/src/stream.ts +68 -15
- package/src/util.ts +11 -1
- package/src/webrtc/index.ts +2 -1
- package/dist/src/pb/message.d.ts.map +0 -1
- package/dist/src/pb/message.js.map +0 -1
- package/dist/src/private-to-public/options.d.ts +0 -6
- package/dist/src/private-to-public/options.d.ts.map +0 -1
- package/dist/src/private-to-public/options.js +0 -2
- package/dist/src/private-to-public/options.js.map +0 -1
- package/dist/src/private-to-public/sdp.d.ts +0 -31
- package/dist/src/private-to-public/sdp.d.ts.map +0 -1
- package/dist/src/private-to-public/sdp.js.map +0 -1
- package/dist/src/private-to-public/util.d.ts +0 -2
- package/dist/src/private-to-public/util.d.ts.map +0 -1
- package/dist/src/private-to-public/util.js +0 -3
- package/dist/src/private-to-public/util.js.map +0 -1
- package/dist/typedoc-urls.json +0 -12
- package/src/private-to-public/options.ts +0 -4
- package/src/private-to-public/sdp.ts +0 -159
- package/src/private-to-public/util.ts +0 -2
- /package/dist/src/{pb → private-to-public/pb}/message.d.ts +0 -0
- /package/dist/src/{pb → private-to-public/pb}/message.js +0 -0
- /package/src/{pb → private-to-public/pb}/message.proto +0 -0
- /package/src/{pb → private-to-public/pb}/message.ts +0 -0
@@ -1,7 +1,8 @@
|
|
1
|
-
import {
|
2
|
-
import type {
|
3
|
-
import type {
|
4
|
-
import type { CreateListenerOptions, Transport, Listener, ComponentLogger, Connection, CounterGroup, Metrics, PeerId, PrivateKey } from '@libp2p/interface';
|
1
|
+
import { serviceCapabilities, transportSymbol } from '@libp2p/interface';
|
2
|
+
import type { DataChannelOptions, TransportCertificate } from '../index.js';
|
3
|
+
import type { WebRTCDialEvents } from '../private-to-private/transport.js';
|
4
|
+
import type { CreateListenerOptions, Transport, Listener, ComponentLogger, Connection, CounterGroup, Metrics, PeerId, DialTransportOptions, PrivateKey } from '@libp2p/interface';
|
5
|
+
import type { TransportManager } from '@libp2p/interface-internal';
|
5
6
|
import type { Multiaddr } from '@multiformats/multiaddr';
|
6
7
|
/**
|
7
8
|
* Created by converting the hexadecimal protocol code to an integer.
|
@@ -23,6 +24,7 @@ export interface WebRTCDirectTransportComponents {
|
|
23
24
|
privateKey: PrivateKey;
|
24
25
|
metrics?: Metrics;
|
25
26
|
logger: ComponentLogger;
|
27
|
+
transportManager: TransportManager;
|
26
28
|
}
|
27
29
|
export interface WebRTCMetrics {
|
28
30
|
dialerEvents: CounterGroup;
|
@@ -30,6 +32,8 @@ export interface WebRTCMetrics {
|
|
30
32
|
export interface WebRTCTransportDirectInit {
|
31
33
|
rtcConfiguration?: RTCConfiguration | (() => RTCConfiguration | Promise<RTCConfiguration>);
|
32
34
|
dataChannel?: DataChannelOptions;
|
35
|
+
certificates?: TransportCertificate[];
|
36
|
+
useLibjuice?: boolean;
|
33
37
|
}
|
34
38
|
export declare class WebRTCDirectTransport implements Transport {
|
35
39
|
private readonly log;
|
@@ -43,7 +47,7 @@ export declare class WebRTCDirectTransport implements Transport {
|
|
43
47
|
/**
|
44
48
|
* Dial a given multiaddr
|
45
49
|
*/
|
46
|
-
dial(ma: Multiaddr, options:
|
50
|
+
dial(ma: Multiaddr, options: DialTransportOptions<WebRTCDialEvents>): Promise<Connection>;
|
47
51
|
/**
|
48
52
|
* Create transport listeners no supported by browsers
|
49
53
|
*/
|
@@ -59,11 +63,6 @@ export declare class WebRTCDirectTransport implements Transport {
|
|
59
63
|
/**
|
60
64
|
* Connect to a peer using a multiaddr
|
61
65
|
*/
|
62
|
-
_connect(ma: Multiaddr, options:
|
63
|
-
/**
|
64
|
-
* Generate a noise prologue from the peer connection's certificate.
|
65
|
-
* noise prologue = bytes('libp2p-webrtc-noise:') + noise-responder fingerprint + noise-initiator fingerprint
|
66
|
-
*/
|
67
|
-
private generateNoisePrologue;
|
66
|
+
_connect(ma: Multiaddr, options: DialTransportOptions<WebRTCDialEvents>): Promise<Connection>;
|
68
67
|
}
|
69
68
|
//# sourceMappingURL=transport.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../src/private-to-public/transport.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../src/private-to-public/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AASxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAC3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAA;AAC1E,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAU,UAAU,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACzL,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAOxD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,MAAwC,CAAA;AAElE;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,MAAmC,CAAA;AAE/D;;GAEG;AACH,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,UAAU,CAAA;IACtB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,eAAe,CAAA;IACvB,gBAAgB,EAAE,gBAAgB,CAAA;CACnC;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,YAAY,CAAA;CAC3B;AAED,MAAM,WAAW,yBAAyB;IACxC,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAA;IAC1F,WAAW,CAAC,EAAE,kBAAkB,CAAA;IAChC,YAAY,CAAC,EAAE,oBAAoB,EAAE,CAAA;IACrC,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,qBAAa,qBAAsB,YAAW,SAAS;IACrD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiC;IAC5D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA2B;gBAEnC,UAAU,EAAE,+BAA+B,EAAE,IAAI,GAAE,yBAA8B;IAe9F,QAAQ,CAAC,CAAC,eAAe,CAAC,QAAO;IAEjC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,2BAA0B;IAEvD,QAAQ,CAAC,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAEvC;IAED;;OAEG;IACG,IAAI,CAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,oBAAoB,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IAOhG;;OAEG;IACH,cAAc,CAAE,OAAO,EAAE,qBAAqB,GAAG,QAAQ;IAOzD;;OAEG;IACH,YAAY,CAAE,UAAU,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE;IAInD;;OAEG;IACH,UAAU,CAAE,UAAU,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE;IAIjD;;OAEG;IACG,QAAQ,CAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,oBAAoB,CAAC,gBAAgB,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;CAgCrG"}
|
@@ -1,19 +1,12 @@
|
|
1
|
-
import {
|
2
|
-
import { transportSymbol, serviceCapabilities, InvalidParametersError } from '@libp2p/interface';
|
1
|
+
import { serviceCapabilities, transportSymbol } from '@libp2p/interface';
|
3
2
|
import { peerIdFromString } from '@libp2p/peer-id';
|
4
3
|
import { protocols } from '@multiformats/multiaddr';
|
5
4
|
import { WebRTCDirect } from '@multiformats/multiaddr-matcher';
|
6
|
-
import
|
7
|
-
import {
|
8
|
-
import {
|
9
|
-
import {
|
10
|
-
import {
|
11
|
-
import { DataChannelMuxerFactory } from '../muxer.js';
|
12
|
-
import { createStream } from '../stream.js';
|
13
|
-
import { getRtcConfiguration, isFirefox } from '../util.js';
|
14
|
-
import { RTCPeerConnection } from '../webrtc/index.js';
|
15
|
-
import * as sdp from './sdp.js';
|
16
|
-
import { genUfrag } from './util.js';
|
5
|
+
import { raceSignal } from 'race-signal';
|
6
|
+
import { genUfrag } from '../util.js';
|
7
|
+
import { WebRTCDirectListener } from './listener.js';
|
8
|
+
import { connect } from './utils/connect.js';
|
9
|
+
import { createDialerRTCPeerConnection } from './utils/get-rtcpeerconnection.js';
|
17
10
|
/**
|
18
11
|
* The time to wait, in milliseconds, for the data channel handshake to complete
|
19
12
|
*/
|
@@ -57,6 +50,7 @@ export class WebRTCDirectTransport {
|
|
57
50
|
* Dial a given multiaddr
|
58
51
|
*/
|
59
52
|
async dial(ma, options) {
|
53
|
+
options?.signal?.throwIfAborted();
|
60
54
|
const rawConn = await this._connect(ma, options);
|
61
55
|
this.log('dialing address: %a', ma);
|
62
56
|
return rawConn;
|
@@ -65,7 +59,10 @@ export class WebRTCDirectTransport {
|
|
65
59
|
* Create transport listeners no supported by browsers
|
66
60
|
*/
|
67
61
|
createListener(options) {
|
68
|
-
|
62
|
+
return new WebRTCDirectListener(this.components, {
|
63
|
+
...this.init,
|
64
|
+
...options
|
65
|
+
});
|
69
66
|
}
|
70
67
|
/**
|
71
68
|
* Filter check for all Multiaddrs that this transport can listen on
|
@@ -83,158 +80,34 @@ export class WebRTCDirectTransport {
|
|
83
80
|
* Connect to a peer using a multiaddr
|
84
81
|
*/
|
85
82
|
async _connect(ma, options) {
|
86
|
-
|
87
|
-
const signal = controller.signal;
|
88
|
-
let remotePeer;
|
83
|
+
let theirPeerId;
|
89
84
|
const remotePeerString = ma.getPeerId();
|
90
85
|
if (remotePeerString != null) {
|
91
|
-
|
86
|
+
theirPeerId = peerIdFromString(remotePeerString);
|
92
87
|
}
|
93
|
-
const
|
94
|
-
//
|
95
|
-
|
96
|
-
// was not supported in Chromium). We use the same hash function as found in the
|
97
|
-
// multiaddr if it is supported.
|
98
|
-
const certificate = await RTCPeerConnection.generateCertificate({
|
99
|
-
name: 'ECDSA',
|
100
|
-
namedCurve: 'P-256',
|
101
|
-
hash: sdp.toSupportedHashFunction(remoteCerthash.code)
|
102
|
-
});
|
103
|
-
const peerConnection = new RTCPeerConnection({
|
104
|
-
...(await getRtcConfiguration(this.init.rtcConfiguration)),
|
105
|
-
certificates: [certificate]
|
106
|
-
});
|
88
|
+
const ufrag = genUfrag();
|
89
|
+
// https://github.com/libp2p/specs/blob/master/webrtc/webrtc-direct.md#browser-to-public-server
|
90
|
+
const peerConnection = await createDialerRTCPeerConnection('client', ufrag, typeof this.init.rtcConfiguration === 'function' ? await this.init.rtcConfiguration() : this.init.rtcConfiguration ?? {});
|
107
91
|
try {
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
const dataChannelOpenPromise = new Promise((resolve, reject) => {
|
112
|
-
const handshakeDataChannel = peerConnection.createDataChannel('', { negotiated: true, id: 0 });
|
113
|
-
const handshakeTimeout = setTimeout(() => {
|
114
|
-
const error = `Data channel was never opened: state: ${handshakeDataChannel.readyState}`;
|
115
|
-
this.log.error(error);
|
116
|
-
this.metrics?.dialerEvents.increment({ open_error: true });
|
117
|
-
reject(new DataChannelError('data', error));
|
118
|
-
}, HANDSHAKE_TIMEOUT_MS);
|
119
|
-
handshakeDataChannel.onopen = (_) => {
|
120
|
-
clearTimeout(handshakeTimeout);
|
121
|
-
resolve(handshakeDataChannel);
|
122
|
-
};
|
123
|
-
// ref: https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/error_event
|
124
|
-
handshakeDataChannel.onerror = (event) => {
|
125
|
-
clearTimeout(handshakeTimeout);
|
126
|
-
const errorTarget = event.target?.toString() ?? 'not specified';
|
127
|
-
const error = `Error opening a data channel for handshaking: ${errorTarget}`;
|
128
|
-
this.log.error(error);
|
129
|
-
// NOTE: We use unknown error here but this could potentially be considered a reset by some standards.
|
130
|
-
this.metrics?.dialerEvents.increment({ unknown_error: true });
|
131
|
-
reject(new DataChannelError('data', error));
|
132
|
-
};
|
133
|
-
});
|
134
|
-
const ufrag = 'libp2p+webrtc+v1/' + genUfrag(32);
|
135
|
-
// Create offer and munge sdp with ufrag == pwd. This allows the remote to
|
136
|
-
// respond to STUN messages without performing an actual SDP exchange.
|
137
|
-
// This is because it can infer the passwd field by reading the USERNAME
|
138
|
-
// attribute of the STUN message.
|
139
|
-
const offerSdp = await peerConnection.createOffer();
|
140
|
-
const mungedOfferSdp = sdp.munge(offerSdp, ufrag);
|
141
|
-
await peerConnection.setLocalDescription(mungedOfferSdp);
|
142
|
-
// construct answer sdp from multiaddr and ufrag
|
143
|
-
const answerSdp = sdp.fromMultiAddr(ma, ufrag);
|
144
|
-
await peerConnection.setRemoteDescription(answerSdp);
|
145
|
-
// wait for peerconnection.onopen to fire, or for the datachannel to open
|
146
|
-
const handshakeDataChannel = await dataChannelOpenPromise;
|
147
|
-
// Do noise handshake.
|
148
|
-
// Set the Noise Prologue to libp2p-webrtc-noise:<FINGERPRINTS> before starting the actual Noise handshake.
|
149
|
-
// <FINGERPRINTS> is the concatenation of the of the two TLS fingerprints of A and B in their multihash byte representation, sorted in ascending order.
|
150
|
-
const fingerprintsPrologue = this.generateNoisePrologue(peerConnection, remoteCerthash.code, ma);
|
151
|
-
// Since we use the default crypto interface and do not use a static key or early data,
|
152
|
-
// we pass in undefined for these parameters.
|
153
|
-
const connectionEncrypter = noise({ prologueBytes: fingerprintsPrologue })(this.components);
|
154
|
-
const wrappedChannel = createStream({
|
155
|
-
channel: handshakeDataChannel,
|
156
|
-
direction: 'inbound',
|
92
|
+
return await raceSignal(connect(peerConnection, ufrag, {
|
93
|
+
role: 'client',
|
94
|
+
log: this.log,
|
157
95
|
logger: this.components.logger,
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
...wrappedChannel,
|
162
|
-
sink: wrappedChannel.sink.bind(wrappedChannel),
|
163
|
-
source: (async function* () {
|
164
|
-
for await (const list of wrappedChannel.source) {
|
165
|
-
for (const buf of list) {
|
166
|
-
yield buf;
|
167
|
-
}
|
168
|
-
}
|
169
|
-
}())
|
170
|
-
};
|
171
|
-
// Creating the connection before completion of the noise
|
172
|
-
// handshake ensures that the stream opening callback is set up
|
173
|
-
const maConn = new WebRTCMultiaddrConnection(this.components, {
|
174
|
-
peerConnection,
|
96
|
+
metrics: this.components.metrics,
|
97
|
+
events: this.metrics?.dialerEvents,
|
98
|
+
signal: options.signal ?? AbortSignal.timeout(HANDSHAKE_TIMEOUT_MS),
|
175
99
|
remoteAddr: ma,
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
peerConnection.addEventListener(eventListeningName, () => {
|
183
|
-
switch (peerConnection.connectionState) {
|
184
|
-
case 'failed':
|
185
|
-
case 'disconnected':
|
186
|
-
case 'closed':
|
187
|
-
maConn.close().catch((err) => {
|
188
|
-
this.log.error('error closing connection', err);
|
189
|
-
}).finally(() => {
|
190
|
-
// Remove the event listener once the connection is closed
|
191
|
-
controller.abort();
|
192
|
-
});
|
193
|
-
break;
|
194
|
-
default:
|
195
|
-
break;
|
196
|
-
}
|
197
|
-
}, { signal });
|
198
|
-
// Track opened peer connection
|
199
|
-
this.metrics?.dialerEvents.increment({ peer_connection: true });
|
200
|
-
const muxerFactory = new DataChannelMuxerFactory(this.components, {
|
201
|
-
peerConnection,
|
202
|
-
metrics: this.metrics?.dialerEvents,
|
203
|
-
dataChannelOptions: this.init.dataChannel
|
204
|
-
});
|
205
|
-
// For outbound connections, the remote is expected to start the noise handshake.
|
206
|
-
// Therefore, we need to secure an inbound noise connection from the remote.
|
207
|
-
await connectionEncrypter.secureInbound(wrappedDuplex, {
|
208
|
-
signal,
|
209
|
-
remotePeer
|
210
|
-
});
|
211
|
-
return await options.upgrader.upgradeOutbound(maConn, { skipProtection: true, skipEncryption: true, muxerFactory });
|
100
|
+
dataChannel: this.init.dataChannel,
|
101
|
+
upgrader: options.upgrader,
|
102
|
+
peerId: this.components.peerId,
|
103
|
+
remotePeerId: theirPeerId,
|
104
|
+
privateKey: this.components.privateKey
|
105
|
+
}), options.signal);
|
212
106
|
}
|
213
107
|
catch (err) {
|
214
108
|
peerConnection.close();
|
215
109
|
throw err;
|
216
110
|
}
|
217
111
|
}
|
218
|
-
/**
|
219
|
-
* Generate a noise prologue from the peer connection's certificate.
|
220
|
-
* noise prologue = bytes('libp2p-webrtc-noise:') + noise-responder fingerprint + noise-initiator fingerprint
|
221
|
-
*/
|
222
|
-
generateNoisePrologue(pc, hashCode, ma) {
|
223
|
-
if (pc.getConfiguration().certificates?.length === 0) {
|
224
|
-
throw new InvalidParametersError('no local certificate');
|
225
|
-
}
|
226
|
-
const localFingerprint = sdp.getLocalFingerprint(pc, {
|
227
|
-
log: this.log
|
228
|
-
});
|
229
|
-
if (localFingerprint == null) {
|
230
|
-
throw new InvalidParametersError('no local fingerprint found');
|
231
|
-
}
|
232
|
-
const localFpString = localFingerprint.trim().toLowerCase().replaceAll(':', '');
|
233
|
-
const localFpArray = uint8arrayFromString(localFpString, 'hex');
|
234
|
-
const local = Digest.create(hashCode, localFpArray);
|
235
|
-
const remote = sdp.mbdecoder.decode(sdp.certhash(ma));
|
236
|
-
const prefix = uint8arrayFromString('libp2p-webrtc-noise:');
|
237
|
-
return concat([prefix, local.bytes, remote]);
|
238
|
-
}
|
239
112
|
}
|
240
113
|
//# sourceMappingURL=transport.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/private-to-public/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/private-to-public/transport.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import type { DirectRTCPeerConnection } from './get-rtcpeerconnection.js';
|
2
|
+
import type { DataChannelOptions } from '../../index.js';
|
3
|
+
import type { ComponentLogger, Connection, CounterGroup, Logger, Metrics, PeerId, PrivateKey, Upgrader } from '@libp2p/interface';
|
4
|
+
import type { Multiaddr } from '@multiformats/multiaddr';
|
5
|
+
export interface ConnectOptions {
|
6
|
+
log: Logger;
|
7
|
+
logger: ComponentLogger;
|
8
|
+
metrics?: Metrics;
|
9
|
+
events?: CounterGroup;
|
10
|
+
remoteAddr: Multiaddr;
|
11
|
+
role: 'client' | 'server';
|
12
|
+
dataChannel?: DataChannelOptions;
|
13
|
+
upgrader: Upgrader;
|
14
|
+
peerId: PeerId;
|
15
|
+
remotePeerId?: PeerId;
|
16
|
+
signal: AbortSignal;
|
17
|
+
privateKey: PrivateKey;
|
18
|
+
}
|
19
|
+
export interface ClientOptions extends ConnectOptions {
|
20
|
+
role: 'client';
|
21
|
+
}
|
22
|
+
export interface ServerOptions extends ConnectOptions {
|
23
|
+
role: 'server';
|
24
|
+
}
|
25
|
+
export declare function connect(peerConnection: DirectRTCPeerConnection, ufrag: string, options: ClientOptions): Promise<Connection>;
|
26
|
+
export declare function connect(peerConnection: DirectRTCPeerConnection, ufrag: string, options: ServerOptions): Promise<void>;
|
27
|
+
//# sourceMappingURL=connect.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../../../src/private-to-public/utils/connect.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAA;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACjI,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAExD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,eAAe,CAAA;IACvB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,UAAU,EAAE,SAAS,CAAA;IACrB,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAA;IACzB,WAAW,CAAC,EAAE,kBAAkB,CAAA;IAChC,QAAQ,EAAE,QAAQ,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,EAAE,WAAW,CAAA;IACnB,UAAU,EAAE,UAAU,CAAA;CACvB;AAED,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,IAAI,EAAE,QAAQ,CAAA;CACf;AAED,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,IAAI,EAAE,QAAQ,CAAA;CACf;AAID,wBAAsB,OAAO,CAAE,cAAc,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;AACnI,wBAAsB,OAAO,CAAE,cAAc,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA"}
|
@@ -0,0 +1,142 @@
|
|
1
|
+
import { noise } from '@chainsafe/libp2p-noise';
|
2
|
+
import { raceEvent } from 'race-event';
|
3
|
+
import { WebRTCTransportError } from '../../error.js';
|
4
|
+
import { WebRTCMultiaddrConnection } from '../../maconn.js';
|
5
|
+
import { DataChannelMuxerFactory } from '../../muxer.js';
|
6
|
+
import { createStream } from '../../stream.js';
|
7
|
+
import { isFirefox } from '../../util.js';
|
8
|
+
import { generateNoisePrologue } from './generate-noise-prologue.js';
|
9
|
+
import * as sdp from './sdp.js';
|
10
|
+
const CONNECTION_STATE_CHANGE_EVENT = isFirefox ? 'iceconnectionstatechange' : 'connectionstatechange';
|
11
|
+
export async function connect(peerConnection, ufrag, options) {
|
12
|
+
// create data channel for running the noise handshake. Once the data
|
13
|
+
// channel is opened, the remote will initiate the noise handshake. This
|
14
|
+
// is used to confirm the identity of the peer.
|
15
|
+
const handshakeDataChannel = peerConnection.createDataChannel('', { negotiated: true, id: 0 });
|
16
|
+
if (options.role === 'client') {
|
17
|
+
// the client has to set the local offer before the remote answer
|
18
|
+
// Create offer and munge sdp with ufrag == pwd. This allows the remote to
|
19
|
+
// respond to STUN messages without performing an actual SDP exchange.
|
20
|
+
// This is because it can infer the passwd field by reading the USERNAME
|
21
|
+
// attribute of the STUN message.
|
22
|
+
options.log.trace('client creating local offer');
|
23
|
+
const offerSdp = await peerConnection.createOffer();
|
24
|
+
options.log.trace('client created local offer %s', offerSdp.sdp);
|
25
|
+
const mungedOfferSdp = sdp.munge(offerSdp, ufrag);
|
26
|
+
options.log.trace('client setting local offer %s', mungedOfferSdp.sdp);
|
27
|
+
await peerConnection.setLocalDescription(mungedOfferSdp);
|
28
|
+
const answerSdp = sdp.serverAnswerFromMultiaddr(options.remoteAddr, ufrag);
|
29
|
+
options.log.trace('client setting server description %s', answerSdp.sdp);
|
30
|
+
await peerConnection.setRemoteDescription(answerSdp);
|
31
|
+
}
|
32
|
+
else {
|
33
|
+
// the server has to set the remote offer before the local answer
|
34
|
+
const offerSdp = sdp.clientOfferFromMultiAddr(options.remoteAddr, ufrag);
|
35
|
+
options.log.trace('server setting client %s %s', offerSdp.type, offerSdp.sdp);
|
36
|
+
await peerConnection.setRemoteDescription(offerSdp);
|
37
|
+
// Create offer and munge sdp with ufrag == pwd. This allows the remote to
|
38
|
+
// respond to STUN messages without performing an actual SDP exchange.
|
39
|
+
// This is because it can infer the passwd field by reading the USERNAME
|
40
|
+
// attribute of the STUN message.
|
41
|
+
options.log.trace('server creating local answer');
|
42
|
+
const answerSdp = await peerConnection.createAnswer();
|
43
|
+
options.log.trace('server created local answer');
|
44
|
+
const mungedAnswerSdp = sdp.munge(answerSdp, ufrag);
|
45
|
+
options.log.trace('server setting local description %s', answerSdp.sdp);
|
46
|
+
await peerConnection.setLocalDescription(mungedAnswerSdp);
|
47
|
+
}
|
48
|
+
options.log.trace('%s wait for handshake channel to open', options.role);
|
49
|
+
await raceEvent(handshakeDataChannel, 'open', options.signal);
|
50
|
+
options.log.trace('%s handshake channel opened', options.role);
|
51
|
+
if (options.role === 'server') {
|
52
|
+
// now that the connection has been opened, add the remote's certhash to
|
53
|
+
// it's multiaddr so we can complete the noise handshake
|
54
|
+
const remoteFingerprint = peerConnection.remoteFingerprint()?.value ?? '';
|
55
|
+
options.remoteAddr = options.remoteAddr.encapsulate(sdp.fingerprint2Ma(remoteFingerprint));
|
56
|
+
}
|
57
|
+
// Do noise handshake.
|
58
|
+
// Set the Noise Prologue to libp2p-webrtc-noise:<FINGERPRINTS> before
|
59
|
+
// starting the actual Noise handshake.
|
60
|
+
// <FINGERPRINTS> is the concatenation of the of the two TLS fingerprints
|
61
|
+
// of A (responder) and B (initiator) in their byte representation.
|
62
|
+
const localFingerprint = sdp.getFingerprintFromSdp(peerConnection.localDescription?.sdp);
|
63
|
+
if (localFingerprint == null) {
|
64
|
+
throw new WebRTCTransportError('Could not get fingerprint from local description sdp');
|
65
|
+
}
|
66
|
+
options.log.trace('%s performing noise handshake', options.role);
|
67
|
+
const noisePrologue = generateNoisePrologue(localFingerprint, options.remoteAddr, options.role);
|
68
|
+
// Since we use the default crypto interface and do not use a static key
|
69
|
+
// or early data, we pass in undefined for these parameters.
|
70
|
+
const connectionEncrypter = noise({ prologueBytes: noisePrologue })(options);
|
71
|
+
const wrappedChannel = createStream({
|
72
|
+
channel: handshakeDataChannel,
|
73
|
+
direction: 'inbound',
|
74
|
+
logger: options.logger,
|
75
|
+
...(options.dataChannel ?? {})
|
76
|
+
});
|
77
|
+
const wrappedDuplex = {
|
78
|
+
...wrappedChannel,
|
79
|
+
sink: wrappedChannel.sink.bind(wrappedChannel),
|
80
|
+
source: (async function* () {
|
81
|
+
for await (const list of wrappedChannel.source) {
|
82
|
+
for (const buf of list) {
|
83
|
+
yield buf;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}())
|
87
|
+
};
|
88
|
+
// Creating the connection before completion of the noise
|
89
|
+
// handshake ensures that the stream opening callback is set up
|
90
|
+
const maConn = new WebRTCMultiaddrConnection(options, {
|
91
|
+
peerConnection,
|
92
|
+
remoteAddr: options.remoteAddr,
|
93
|
+
timeline: {
|
94
|
+
open: Date.now()
|
95
|
+
},
|
96
|
+
metrics: options.events
|
97
|
+
});
|
98
|
+
peerConnection.addEventListener(CONNECTION_STATE_CHANGE_EVENT, () => {
|
99
|
+
switch (peerConnection.connectionState) {
|
100
|
+
case 'failed':
|
101
|
+
case 'disconnected':
|
102
|
+
case 'closed':
|
103
|
+
maConn.close().catch((err) => {
|
104
|
+
options.log.error('error closing connection', err);
|
105
|
+
});
|
106
|
+
break;
|
107
|
+
default:
|
108
|
+
break;
|
109
|
+
}
|
110
|
+
});
|
111
|
+
// Track opened peer connection
|
112
|
+
options.events?.increment({ peer_connection: true });
|
113
|
+
const muxerFactory = new DataChannelMuxerFactory(options, {
|
114
|
+
peerConnection,
|
115
|
+
metrics: options.events,
|
116
|
+
dataChannelOptions: options.dataChannel
|
117
|
+
});
|
118
|
+
if (options.role === 'client') {
|
119
|
+
// For outbound connections, the remote is expected to start the noise handshake.
|
120
|
+
// Therefore, we need to secure an inbound noise connection from the remote.
|
121
|
+
options.log.trace('%s secure inbound', options.role);
|
122
|
+
await connectionEncrypter.secureInbound(wrappedDuplex, {
|
123
|
+
remotePeer: options.remotePeerId
|
124
|
+
});
|
125
|
+
options.log.trace('%s upgrade outbound', options.role);
|
126
|
+
return options.upgrader.upgradeOutbound(maConn, { skipProtection: true, skipEncryption: true, muxerFactory });
|
127
|
+
}
|
128
|
+
// For inbound connections, we are expected to start the noise handshake.
|
129
|
+
// Therefore, we need to secure an outbound noise connection from the remote.
|
130
|
+
options.log.trace('%s secure outbound', options.role);
|
131
|
+
const result = await connectionEncrypter.secureOutbound(wrappedDuplex, {
|
132
|
+
remotePeer: options.remotePeerId
|
133
|
+
});
|
134
|
+
maConn.remoteAddr = maConn.remoteAddr.encapsulate(`/p2p/${result.remotePeer}`);
|
135
|
+
options.log.trace('%s upgrade inbound', options.role);
|
136
|
+
await options.upgrader.upgradeInbound(maConn, {
|
137
|
+
skipProtection: true,
|
138
|
+
skipEncryption: true,
|
139
|
+
muxerFactory
|
140
|
+
});
|
141
|
+
}
|
142
|
+
//# sourceMappingURL=connect.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/connect.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"generate-certificates.browser.d.ts","sourceRoot":"","sources":["../../../../src/private-to-public/utils/generate-certificates.browser.ts"],"names":[],"mappings":"AAAA,wBAAsB,+BAA+B,IAAK,OAAO,CAAC,GAAG,CAAC,CAErE"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"generate-certificates.browser.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/generate-certificates.browser.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,+BAA+B;IACnD,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;AACpC,CAAC"}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import type { TransportCertificate } from '../..';
|
2
|
+
export interface GenerateTransportCertificateOptions {
|
3
|
+
days: number;
|
4
|
+
start?: Date;
|
5
|
+
extensions?: any[];
|
6
|
+
}
|
7
|
+
export declare function generateTransportCertificate(keyPair: CryptoKeyPair, options: GenerateTransportCertificateOptions): Promise<TransportCertificate>;
|
8
|
+
//# sourceMappingURL=generate-certificates.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"generate-certificates.d.ts","sourceRoot":"","sources":["../../../../src/private-to-public/utils/generate-certificates.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAA;AAOjD,MAAM,WAAW,mCAAmC;IAClD,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,UAAU,CAAC,EAAE,GAAG,EAAE,CAAA;CACnB;AAED,wBAAsB,4BAA4B,CAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,mCAAmC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAgCvJ"}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import { Crypto } from '@peculiar/webcrypto';
|
2
|
+
import * as x509 from '@peculiar/x509';
|
3
|
+
import { base64url } from 'multiformats/bases/base64';
|
4
|
+
import { sha256 } from 'multiformats/hashes/sha2';
|
5
|
+
import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
|
6
|
+
const crypto = new Crypto();
|
7
|
+
x509.cryptoProvider.set(crypto);
|
8
|
+
const ONE_DAY_MS = 86400000;
|
9
|
+
export async function generateTransportCertificate(keyPair, options) {
|
10
|
+
const notBefore = options.start ?? new Date();
|
11
|
+
notBefore.setMilliseconds(0);
|
12
|
+
const notAfter = new Date(notBefore.getTime() + (options.days * ONE_DAY_MS));
|
13
|
+
notAfter.setMilliseconds(0);
|
14
|
+
const cert = await x509.X509CertificateGenerator.createSelfSigned({
|
15
|
+
serialNumber: (BigInt(Math.random().toString().replace('.', '')) * 100000n).toString(16),
|
16
|
+
name: 'CN=ca.com, C=US, L=CA, O=example, ST=CA',
|
17
|
+
notBefore,
|
18
|
+
notAfter,
|
19
|
+
signingAlgorithm: {
|
20
|
+
name: 'ECDSA'
|
21
|
+
},
|
22
|
+
keys: keyPair,
|
23
|
+
extensions: [
|
24
|
+
new x509.BasicConstraintsExtension(false, undefined, true)
|
25
|
+
]
|
26
|
+
});
|
27
|
+
const exported = await crypto.subtle.exportKey('pkcs8', keyPair.privateKey);
|
28
|
+
const privateKeyPem = [
|
29
|
+
'-----BEGIN PRIVATE KEY-----',
|
30
|
+
...uint8ArrayToString(new Uint8Array(exported), 'base64pad').split(/(.{64})/).filter(Boolean),
|
31
|
+
'-----END PRIVATE KEY-----'
|
32
|
+
].join('\n');
|
33
|
+
return {
|
34
|
+
privateKey: privateKeyPem,
|
35
|
+
pem: cert.toString('pem'),
|
36
|
+
certhash: base64url.encode((await sha256.digest(new Uint8Array(cert.rawData))).bytes)
|
37
|
+
};
|
38
|
+
}
|
39
|
+
//# sourceMappingURL=generate-certificates.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"generate-certificates.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/generate-certificates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAA;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AACjD,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAGtE,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;AAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;AAE/B,MAAM,UAAU,GAAG,QAAQ,CAAA;AAQ3B,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAE,OAAsB,EAAE,OAA4C;IACtH,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,IAAI,EAAE,CAAA;IAC7C,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;IAC5B,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,UAAU,CAAC,CAAC,CAAA;IAC5E,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;IAE3B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC,gBAAgB,CAAC;QAChE,YAAY,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxF,IAAI,EAAE,yCAAyC;QAC/C,SAAS;QACT,QAAQ;QACR,gBAAgB,EAAE;YAChB,IAAI,EAAE,OAAO;SACd;QACD,IAAI,EAAE,OAAO;QACb,UAAU,EAAE;YACV,IAAI,IAAI,CAAC,yBAAyB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC;SAC3D;KACF,CAAC,CAAA;IAEF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;IAC3E,MAAM,aAAa,GAAG;QACpB,6BAA6B;QAC7B,GAAG,kBAAkB,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QAC7F,2BAA2B;KAC5B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAEZ,OAAO;QACL,UAAU,EAAE,aAAa;QACzB,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QACzB,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;KACtF,CAAA;AACH,CAAC"}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
import type { Multiaddr } from '@multiformats/multiaddr';
|
2
|
+
/**
|
3
|
+
* Generate a noise prologue from the peer connection's certificate.
|
4
|
+
* noise prologue = bytes('libp2p-webrtc-noise:') + noise-server fingerprint + noise-client fingerprint
|
5
|
+
*/
|
6
|
+
export declare function generateNoisePrologue(localFingerprint: string, remoteAddr: Multiaddr, role: 'client' | 'server'): Uint8Array;
|
7
|
+
//# sourceMappingURL=generate-noise-prologue.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"generate-noise-prologue.d.ts","sourceRoot":"","sources":["../../../../src/private-to-public/utils/generate-noise-prologue.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAIxD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAE,gBAAgB,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAY7H"}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import * as Digest from 'multiformats/hashes/digest';
|
2
|
+
import { sha256 } from 'multiformats/hashes/sha2';
|
3
|
+
import { concat } from 'uint8arrays/concat';
|
4
|
+
import { fromString as uint8arrayFromString } from 'uint8arrays/from-string';
|
5
|
+
import * as sdp from './sdp.js';
|
6
|
+
const PREFIX = uint8arrayFromString('libp2p-webrtc-noise:');
|
7
|
+
/**
|
8
|
+
* Generate a noise prologue from the peer connection's certificate.
|
9
|
+
* noise prologue = bytes('libp2p-webrtc-noise:') + noise-server fingerprint + noise-client fingerprint
|
10
|
+
*/
|
11
|
+
export function generateNoisePrologue(localFingerprint, remoteAddr, role) {
|
12
|
+
const localFpString = localFingerprint.trim().toLowerCase().replaceAll(':', '');
|
13
|
+
const localFpArray = uint8arrayFromString(localFpString, 'hex');
|
14
|
+
const local = Digest.create(sha256.code, localFpArray);
|
15
|
+
const remote = sdp.mbdecoder.decode(sdp.certhash(remoteAddr));
|
16
|
+
const byteLength = PREFIX.byteLength + local.bytes.byteLength + remote.byteLength;
|
17
|
+
if (role === 'server') {
|
18
|
+
return concat([PREFIX, remote, local.bytes], byteLength);
|
19
|
+
}
|
20
|
+
return concat([PREFIX, local.bytes, remote], byteLength);
|
21
|
+
}
|
22
|
+
//# sourceMappingURL=generate-noise-prologue.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"generate-noise-prologue.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/generate-noise-prologue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,4BAA4B,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,UAAU,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC5E,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAG/B,MAAM,MAAM,GAAG,oBAAoB,CAAC,sBAAsB,CAAC,CAAA;AAE3D;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAE,gBAAwB,EAAE,UAAqB,EAAE,IAAyB;IAC/G,MAAM,aAAa,GAAG,gBAAgB,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;IAC/E,MAAM,YAAY,GAAG,oBAAoB,CAAC,aAAa,EAAE,KAAK,CAAC,CAAA;IAC/D,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;IACtD,MAAM,MAAM,GAAe,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAA;IACzE,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAA;IAEjF,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,CAAA;IAC1D,CAAC;IAED,OAAO,MAAM,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,UAAU,CAAC,CAAA;AAC1D,CAAC"}
|
@@ -0,0 +1,2 @@
|
|
1
|
+
export declare function createDialerRTCPeerConnection(role: 'client' | 'server', ufrag: string, rtcConfiguration?: RTCConfiguration | (() => RTCConfiguration | Promise<RTCConfiguration>), certificate?: RTCCertificate): Promise<RTCPeerConnection>;
|
2
|
+
//# sourceMappingURL=get-rtcpeerconnection.browser.d.ts.map
|