diff --git a/doc/CONFIGURATION.md b/doc/CONFIGURATION.md index 8df6512f19..92da7af7ff 100644 --- a/doc/CONFIGURATION.md +++ b/doc/CONFIGURATION.md @@ -23,6 +23,7 @@ - [Configuring Dialing](#configuring-dialing) - [Configuring Connection Manager](#configuring-connection-manager) - [Configuring Metrics](#configuring-metrics) + - [Customizing Transports](#customizing-transports) - [Configuration examples](#configuration-examples) ## Overview @@ -499,6 +500,34 @@ const node = await Libp2p.create({ }) ``` +#### Customizing Transports + +Some Transports can be passed additional options when they are created. For example, `libp2p-webrtc-star` accepts an optional, custom `wrtc` implementation. In addition to libp2p passing itself and an `Upgrader` to handle connection upgrading, libp2p will also pass the options, if they are provided, from `config.transport`. + +```js +const Libp2p = require('libp2p') +const WebRTCStar = require('libp2p-webrtc-star') +const MPLEX = require('libp2p-mplex') +const SECIO = require('libp2p-secio') +const wrtc = require('wrtc') + +const transportKey = WebRTCStar.prototype[Symbol.toStringTag] +const node = await Libp2p.create({ + modules: { + transport: [WebRTCStar], + streamMuxer: [MPLEX], + connEncryption: [SECIO] + }, + config: { + transport: { + [transportKey]: { + wrtc // You can use `wrtc` when running in Node.js + } + } + } +}) +``` + ## Configuration examples As libp2p is designed to be a modular networking library, its usage will vary based on individual project needs. We've included links to some existing project configurations for your reference, in case you wish to replicate their configuration: diff --git a/src/config.js b/src/config.js index 6d365c07f8..11b0ce4bb9 100644 --- a/src/config.js +++ b/src/config.js @@ -41,7 +41,8 @@ const DefaultConfig = { enabled: false, active: false } - } + }, + transport: {} } } diff --git a/src/index.js b/src/index.js index 3b39d86d71..7e635aa76b 100644 --- a/src/index.js +++ b/src/index.js @@ -114,10 +114,14 @@ class Libp2p extends EventEmitter { }) this._modules.transport.forEach((Transport) => { - this.transportManager.add(Transport.prototype[Symbol.toStringTag], Transport) + const key = Transport.prototype[Symbol.toStringTag] + const transportOptions = this._config.transport[key] + this.transportManager.add(key, Transport, transportOptions) }) - // TODO: enable relay if enabled - this.transportManager.add(Circuit.prototype[Symbol.toStringTag], Circuit) + + if (this._config.relay.enabled) { + this.transportManager.add(Circuit.prototype[Symbol.toStringTag], Circuit) + } // Attach stream multiplexers if (this._modules.streamMuxer) { diff --git a/src/transport-manager.js b/src/transport-manager.js index d11189ab86..ec7a958146 100644 --- a/src/transport-manager.js +++ b/src/transport-manager.js @@ -26,9 +26,10 @@ class TransportManager { * * @param {String} key * @param {Transport} Transport + * @param {*} transportOptions Additional options to pass to the transport * @returns {void} */ - add (key, Transport) { + add (key, Transport, transportOptions = {}) { log('adding %s', key) if (!key) { throw errCode(new Error(`Transport must have a valid key, was given '${key}'`), codes.ERR_INVALID_KEY) @@ -38,6 +39,7 @@ class TransportManager { } const transport = new Transport({ + ...transportOptions, libp2p: this.libp2p, upgrader: this.upgrader }) diff --git a/test/transports/transport-manager.spec.js b/test/transports/transport-manager.spec.js index ab08fc1759..4e71001e21 100644 --- a/test/transports/transport-manager.spec.js +++ b/test/transports/transport-manager.spec.js @@ -115,6 +115,35 @@ describe('libp2p.transportManager', () => { expect(libp2p.transportManager._transports.size).to.equal(2) }) + it('should be able to customize a transport', () => { + const spy = sinon.spy() + const key = spy.prototype[Symbol.toStringTag] = 'TransportSpy' + const customOptions = { + another: 'value' + } + libp2p = new Libp2p({ + peerInfo, + modules: { + transport: [spy] + }, + config: { + transport: { + [key]: customOptions + } + } + }) + + expect(libp2p.transportManager).to.exist() + // Our transport and circuit relay + expect(libp2p.transportManager._transports.size).to.equal(2) + expect(spy).to.have.property('callCount', 1) + expect(spy.getCall(0)).to.have.deep.property('args', [{ + ...customOptions, + libp2p, + upgrader: libp2p.upgrader + }]) + }) + it('starting and stopping libp2p should start and stop TransportManager', async () => { libp2p = new Libp2p({ peerInfo,