libp2p 2.7.3 → 2.7.4-22e62d00f
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 +30 -1
- package/dist/index.min.js +20 -15
- package/dist/src/connection-manager/dial-queue.d.ts +1 -0
- package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
- package/dist/src/connection-manager/dial-queue.js +103 -71
- package/dist/src/connection-manager/dial-queue.js.map +1 -1
- package/dist/src/errors.d.ts +5 -2
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +12 -6
- package/dist/src/errors.js.map +1 -1
- package/dist/src/transport-manager.d.ts +1 -0
- package/dist/src/transport-manager.d.ts.map +1 -1
- package/dist/src/transport-manager.js +70 -26
- package/dist/src/transport-manager.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.d.ts.map +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/package.json +10 -10
- package/src/connection-manager/dial-queue.ts +119 -75
- package/src/errors.ts +13 -6
- package/src/transport-manager.ts +94 -26
- package/src/version.ts +1 -1
- package/dist/typedoc-urls.json +0 -21
|
@@ -203,7 +203,7 @@ export class DialQueue {
|
|
|
203
203
|
|
|
204
204
|
options.onProgress?.(new CustomProgressEvent('dial-queue:add-to-dial-queue'))
|
|
205
205
|
return this.queue.add(async (options) => {
|
|
206
|
-
options
|
|
206
|
+
options.onProgress?.(new CustomProgressEvent('dial-queue:start-dial'))
|
|
207
207
|
// create abort conditions - need to do this before `calculateMultiaddrs` as
|
|
208
208
|
// we may be about to resolve a dns addr which can time out
|
|
209
209
|
const signal = anySignal([
|
|
@@ -212,103 +212,145 @@ export class DialQueue {
|
|
|
212
212
|
])
|
|
213
213
|
setMaxListeners(Infinity, signal)
|
|
214
214
|
|
|
215
|
-
let addrsToDial: Address[]
|
|
216
|
-
|
|
217
215
|
try {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
216
|
+
return await this.dialPeer(options, signal)
|
|
217
|
+
} finally {
|
|
218
|
+
// clean up abort signals/controllers
|
|
219
|
+
signal.clear()
|
|
220
|
+
}
|
|
221
|
+
}, {
|
|
222
|
+
peerId,
|
|
223
|
+
priority: options.priority ?? DEFAULT_DIAL_PRIORITY,
|
|
224
|
+
multiaddrs: new Set(multiaddrs.map(ma => ma.toString())),
|
|
225
|
+
signal: options.signal ?? AbortSignal.timeout(this.dialTimeout),
|
|
226
|
+
onProgress: options.onProgress
|
|
227
|
+
})
|
|
228
|
+
}
|
|
224
229
|
|
|
225
|
-
|
|
230
|
+
private async dialPeer (options: DialQueueJobOptions, signal: AbortSignal): Promise<Connection> {
|
|
231
|
+
const peerId = options.peerId
|
|
232
|
+
const multiaddrs = options.multiaddrs
|
|
233
|
+
const failedMultiaddrs = new Set<string>()
|
|
226
234
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
235
|
+
// if we have no multiaddrs, only a peer id, set a flag so we will look the
|
|
236
|
+
// peer up in the peer routing to obtain multiaddrs
|
|
237
|
+
let forcePeerLookup = options.multiaddrs.size === 0
|
|
238
|
+
|
|
239
|
+
let dialed = 0
|
|
240
|
+
let dialIteration = 0
|
|
241
|
+
const errors: Error[] = []
|
|
242
|
+
|
|
243
|
+
this.log('starting dial to %p', peerId)
|
|
244
|
+
|
|
245
|
+
// repeat this operation in case addresses are added to the dial while we
|
|
246
|
+
// resolve multiaddrs, etc
|
|
247
|
+
while (forcePeerLookup || multiaddrs.size > 0) {
|
|
248
|
+
dialIteration++
|
|
249
|
+
|
|
250
|
+
// only perform peer lookup once
|
|
251
|
+
forcePeerLookup = false
|
|
252
|
+
|
|
253
|
+
// the addresses we will dial
|
|
254
|
+
const addrsToDial: Address[] = []
|
|
255
|
+
|
|
256
|
+
// copy the addresses into a new set
|
|
257
|
+
const addrs = new Set(options.multiaddrs)
|
|
258
|
+
|
|
259
|
+
// empty the old set - subsequent dial attempts for the same peer id may
|
|
260
|
+
// add more addresses to try
|
|
261
|
+
multiaddrs.clear()
|
|
262
|
+
|
|
263
|
+
this.log('calculating addrs to dial %p from %s', peerId, [...addrs])
|
|
264
|
+
|
|
265
|
+
// load addresses from address book, resolve and dnsaddrs, filter
|
|
266
|
+
// undialables, add peer IDs, etc
|
|
267
|
+
const calculatedAddrs = await this.calculateMultiaddrs(peerId, addrs, {
|
|
268
|
+
...options,
|
|
269
|
+
signal
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
for (const addr of calculatedAddrs) {
|
|
273
|
+
// skip any addresses we have previously failed to dial
|
|
274
|
+
if (failedMultiaddrs.has(addr.multiaddr.toString())) {
|
|
275
|
+
this.log.trace('skipping previously failed multiaddr %a while dialing %p', addr.multiaddr, peerId)
|
|
276
|
+
continue
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
addrsToDial.push(addr)
|
|
233
280
|
}
|
|
234
281
|
|
|
235
|
-
|
|
236
|
-
let dialed = 0
|
|
237
|
-
const errors: Error[] = []
|
|
282
|
+
this.log('%s dial to %p with %s', dialIteration === 1 ? 'starting' : 'continuing', peerId, addrsToDial.map(ma => ma.multiaddr.toString()))
|
|
238
283
|
|
|
239
|
-
|
|
240
|
-
if (dialed === this.maxPeerAddrsToDial) {
|
|
241
|
-
this.log('dialed maxPeerAddrsToDial (%d) addresses for %p, not trying any others', dialed, peerId)
|
|
284
|
+
options?.onProgress?.(new CustomProgressEvent<Address[]>('dial-queue:calculated-addresses', addrsToDial))
|
|
242
285
|
|
|
243
|
-
|
|
244
|
-
|
|
286
|
+
for (const address of addrsToDial) {
|
|
287
|
+
if (dialed === this.maxPeerAddrsToDial) {
|
|
288
|
+
this.log('dialed maxPeerAddrsToDial (%d) addresses for %p, not trying any others', dialed, options.peerId)
|
|
245
289
|
|
|
246
|
-
|
|
290
|
+
throw new DialError('Peer had more than maxPeerAddrsToDial')
|
|
291
|
+
}
|
|
247
292
|
|
|
293
|
+
dialed++
|
|
294
|
+
|
|
295
|
+
try {
|
|
296
|
+
// try to dial the address
|
|
297
|
+
const conn = await this.components.transportManager.dial(address.multiaddr, {
|
|
298
|
+
...options,
|
|
299
|
+
signal
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
this.log('dial to %a succeeded', address.multiaddr)
|
|
303
|
+
|
|
304
|
+
// record the successful dial and the address
|
|
248
305
|
try {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
306
|
+
await this.components.peerStore.merge(conn.remotePeer, {
|
|
307
|
+
multiaddrs: [
|
|
308
|
+
conn.remoteAddr
|
|
309
|
+
],
|
|
310
|
+
metadata: {
|
|
311
|
+
[LAST_DIAL_SUCCESS_KEY]: uint8ArrayFromString(Date.now().toString())
|
|
312
|
+
}
|
|
252
313
|
})
|
|
314
|
+
} catch (err: any) {
|
|
315
|
+
this.log.error('could not update last dial failure key for %p', peerId, err)
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// dial successful, return the connection
|
|
319
|
+
return conn
|
|
320
|
+
} catch (err: any) {
|
|
321
|
+
this.log.error('dial failed to %a', address.multiaddr, err)
|
|
253
322
|
|
|
254
|
-
|
|
323
|
+
// ensure we don't dial it again in this attempt
|
|
324
|
+
failedMultiaddrs.add(address.multiaddr.toString())
|
|
255
325
|
|
|
256
|
-
|
|
326
|
+
if (peerId != null) {
|
|
327
|
+
// record the failed dial
|
|
257
328
|
try {
|
|
258
|
-
await this.components.peerStore.merge(
|
|
259
|
-
multiaddrs: [
|
|
260
|
-
conn.remoteAddr
|
|
261
|
-
],
|
|
329
|
+
await this.components.peerStore.merge(peerId, {
|
|
262
330
|
metadata: {
|
|
263
|
-
[
|
|
331
|
+
[LAST_DIAL_FAILURE_KEY]: uint8ArrayFromString(Date.now().toString())
|
|
264
332
|
}
|
|
265
333
|
})
|
|
266
334
|
} catch (err: any) {
|
|
267
335
|
this.log.error('could not update last dial failure key for %p', peerId, err)
|
|
268
336
|
}
|
|
337
|
+
}
|
|
269
338
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if (peerId != null) {
|
|
275
|
-
// record the failed dial
|
|
276
|
-
try {
|
|
277
|
-
await this.components.peerStore.merge(peerId, {
|
|
278
|
-
metadata: {
|
|
279
|
-
[LAST_DIAL_FAILURE_KEY]: uint8ArrayFromString(Date.now().toString())
|
|
280
|
-
}
|
|
281
|
-
})
|
|
282
|
-
} catch (err: any) {
|
|
283
|
-
this.log.error('could not update last dial failure key for %p', peerId, err)
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// the user/dial timeout/shutdown controller signal aborted
|
|
288
|
-
if (signal.aborted) {
|
|
289
|
-
throw new TimeoutError(err.message)
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
errors.push(err)
|
|
339
|
+
// the user/dial timeout/shutdown controller signal aborted
|
|
340
|
+
if (signal.aborted) {
|
|
341
|
+
throw new TimeoutError(err.message)
|
|
293
342
|
}
|
|
294
|
-
}
|
|
295
343
|
|
|
296
|
-
|
|
297
|
-
throw errors[0]
|
|
344
|
+
errors.push(err)
|
|
298
345
|
}
|
|
299
|
-
|
|
300
|
-
throw new AggregateError(errors, 'All multiaddr dials failed')
|
|
301
|
-
} finally {
|
|
302
|
-
// clean up abort signals/controllers
|
|
303
|
-
signal.clear()
|
|
304
346
|
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (errors.length === 1) {
|
|
350
|
+
throw errors[0]
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
throw new AggregateError(errors, 'All multiaddr dials failed')
|
|
312
354
|
}
|
|
313
355
|
|
|
314
356
|
// eslint-disable-next-line complexity
|
|
@@ -358,8 +400,10 @@ export class DialQueue {
|
|
|
358
400
|
isCertified: false
|
|
359
401
|
})))
|
|
360
402
|
} catch (err: any) {
|
|
361
|
-
if (err.name
|
|
362
|
-
this.log
|
|
403
|
+
if (err.name === 'NoPeerRoutersError') {
|
|
404
|
+
this.log('no peer routers configured', peerId)
|
|
405
|
+
} else {
|
|
406
|
+
this.log.error('looking up multiaddrs for %p in the peer routing failed - %e', peerId, err)
|
|
363
407
|
}
|
|
364
408
|
}
|
|
365
409
|
}
|
package/src/errors.ts
CHANGED
|
@@ -59,17 +59,24 @@ export class DialDeniedError extends Error {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
export class
|
|
63
|
-
constructor (message = 'No
|
|
62
|
+
export class UnsupportedListenAddressError extends Error {
|
|
63
|
+
constructor (message = 'No transport was configured to listen on this address') {
|
|
64
64
|
super(message)
|
|
65
|
-
this.name = '
|
|
65
|
+
this.name = 'UnsupportedListenAddressError'
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export class UnsupportedListenAddressesError extends Error {
|
|
70
|
+
constructor (message = 'Configured listen addresses could not be listened on') {
|
|
71
|
+
super(message)
|
|
72
|
+
this.name = 'UnsupportedListenAddressesError'
|
|
66
73
|
}
|
|
67
74
|
}
|
|
68
75
|
|
|
69
|
-
export class
|
|
70
|
-
constructor (message = 'No
|
|
76
|
+
export class NoValidAddressesError extends Error {
|
|
77
|
+
constructor (message = 'No valid addresses') {
|
|
71
78
|
super(message)
|
|
72
|
-
this.name = '
|
|
79
|
+
this.name = 'NoValidAddressesError'
|
|
73
80
|
}
|
|
74
81
|
}
|
|
75
82
|
|
package/src/transport-manager.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { FaultTolerance, InvalidParametersError, NotStartedError } from '@libp2p/interface'
|
|
2
2
|
import { trackedMap } from '@libp2p/utils/tracked-map'
|
|
3
|
+
import { IP4, IP6 } from '@multiformats/multiaddr-matcher'
|
|
3
4
|
import { CustomProgressEvent } from 'progress-events'
|
|
4
|
-
import {
|
|
5
|
+
import { TransportUnavailableError, UnsupportedListenAddressError, UnsupportedListenAddressesError } from './errors.js'
|
|
5
6
|
import type { Libp2pEvents, ComponentLogger, Logger, Connection, TypedEventTarget, Metrics, Startable, Listener, Transport, Upgrader } from '@libp2p/interface'
|
|
6
7
|
import type { AddressManager, TransportManager, TransportManagerDialOptions } from '@libp2p/interface-internal'
|
|
7
8
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
@@ -18,6 +19,17 @@ export interface DefaultTransportManagerComponents {
|
|
|
18
19
|
logger: ComponentLogger
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
interface IPStats {
|
|
23
|
+
success: number
|
|
24
|
+
attempts: number
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface ListenStats {
|
|
28
|
+
errors: Map<string, Error>
|
|
29
|
+
ipv4: IPStats
|
|
30
|
+
ipv6: IPStats
|
|
31
|
+
}
|
|
32
|
+
|
|
21
33
|
export class DefaultTransportManager implements TransportManager, Startable {
|
|
22
34
|
private readonly log: Logger
|
|
23
35
|
private readonly components: DefaultTransportManagerComponents
|
|
@@ -192,11 +204,28 @@ export class DefaultTransportManager implements TransportManager, Startable {
|
|
|
192
204
|
return
|
|
193
205
|
}
|
|
194
206
|
|
|
195
|
-
|
|
207
|
+
// track IPv4/IPv6 results - if we succeed on IPv4 but all IPv6 attempts
|
|
208
|
+
// fail then we are probably on a network without IPv6 support
|
|
209
|
+
const listenStats: ListenStats = {
|
|
210
|
+
errors: new Map(),
|
|
211
|
+
ipv4: {
|
|
212
|
+
success: 0,
|
|
213
|
+
attempts: 0
|
|
214
|
+
},
|
|
215
|
+
ipv6: {
|
|
216
|
+
success: 0,
|
|
217
|
+
attempts: 0
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
addrs.forEach(ma => {
|
|
222
|
+
listenStats.errors.set(ma.toString(), new UnsupportedListenAddressError())
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
const tasks: Array<Promise<void>> = []
|
|
196
226
|
|
|
197
227
|
for (const [key, transport] of this.transports.entries()) {
|
|
198
228
|
const supportedAddrs = transport.listenFilter(addrs)
|
|
199
|
-
const tasks = []
|
|
200
229
|
|
|
201
230
|
// For each supported multiaddr, create a listener
|
|
202
231
|
for (const addr of supportedAddrs) {
|
|
@@ -231,36 +260,75 @@ export class DefaultTransportManager implements TransportManager, Startable {
|
|
|
231
260
|
})
|
|
232
261
|
})
|
|
233
262
|
|
|
263
|
+
// track IPv4/IPv6 support
|
|
264
|
+
if (IP4.matches(addr)) {
|
|
265
|
+
listenStats.ipv4.attempts++
|
|
266
|
+
} else if (IP6.matches(addr)) {
|
|
267
|
+
listenStats.ipv6.attempts++
|
|
268
|
+
}
|
|
269
|
+
|
|
234
270
|
// We need to attempt to listen on everything
|
|
235
|
-
tasks.push(
|
|
271
|
+
tasks.push(
|
|
272
|
+
listener.listen(addr)
|
|
273
|
+
.then(() => {
|
|
274
|
+
listenStats.errors.delete(addr.toString())
|
|
275
|
+
|
|
276
|
+
if (IP4.matches(addr)) {
|
|
277
|
+
listenStats.ipv4.success++
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (IP6.matches(addr)) {
|
|
281
|
+
listenStats.ipv6.success++
|
|
282
|
+
}
|
|
283
|
+
}, (err) => {
|
|
284
|
+
this.log.error('transport %s could not listen on address %a - %e', key, addr, err)
|
|
285
|
+
listenStats.errors.set(addr.toString(), err)
|
|
286
|
+
throw err
|
|
287
|
+
})
|
|
288
|
+
)
|
|
236
289
|
}
|
|
290
|
+
}
|
|
237
291
|
|
|
238
|
-
|
|
239
|
-
if (tasks.length === 0) {
|
|
240
|
-
couldNotListen.push(key)
|
|
241
|
-
continue
|
|
242
|
-
}
|
|
292
|
+
const results = await Promise.allSettled(tasks)
|
|
243
293
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
// listening on remote addresses as they may be offline. We could then potentially
|
|
248
|
-
// just wait for any (`p-any`) listener to succeed on each transport before returning
|
|
249
|
-
const isListening = results.find(r => r.status === 'fulfilled')
|
|
250
|
-
if ((isListening == null) && this.faultTolerance !== FaultTolerance.NO_FATAL) {
|
|
251
|
-
throw new NoValidAddressesError(`Transport (${key}) could not listen on any available address`)
|
|
252
|
-
}
|
|
294
|
+
// listening on all addresses, all good
|
|
295
|
+
if (results.length > 0 && results.every(res => res.status === 'fulfilled')) {
|
|
296
|
+
return
|
|
253
297
|
}
|
|
254
298
|
|
|
255
|
-
//
|
|
256
|
-
//
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
299
|
+
// detect lack of IPv6 support on the current network - if we tried to
|
|
300
|
+
// listen on IPv4 and IPv6 addresses, and all IPv4 addresses succeeded but
|
|
301
|
+
// all IPv6 addresses fail, then we can assume there's no IPv6 here
|
|
302
|
+
if (this.ipv6Unsupported(listenStats)) {
|
|
303
|
+
this.log('all IPv4 addresses succeed but all IPv6 failed')
|
|
304
|
+
return
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if (this.faultTolerance === FaultTolerance.NO_FATAL) {
|
|
308
|
+
// ok to be dial-only
|
|
309
|
+
this.log('failed to listen on any address but fault tolerance allows this')
|
|
310
|
+
return
|
|
263
311
|
}
|
|
312
|
+
|
|
313
|
+
// if a configured address was not able to be listened on, throw an error
|
|
314
|
+
throw new UnsupportedListenAddressesError(`Some configured addresses failed to be listened on, you may need to remove one or more listen addresses from your configuration or set \`transportManager.faultTolerance\` to NO_FATAL:\n${
|
|
315
|
+
[...listenStats.errors.entries()].map(([addr, err]) => {
|
|
316
|
+
return `
|
|
317
|
+
${addr}: ${`${err.stack ?? err}`.split('\n').join('\n ')}
|
|
318
|
+
`
|
|
319
|
+
}).join('')
|
|
320
|
+
}`)
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
private ipv6Unsupported (listenStats: ListenStats): boolean {
|
|
324
|
+
if (listenStats.ipv4.attempts === 0 || listenStats.ipv6.attempts === 0) {
|
|
325
|
+
return false
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const allIpv4Succeeded = listenStats.ipv4.attempts === listenStats.ipv4.success
|
|
329
|
+
const allIpv6Failed = listenStats.ipv6.success === 0
|
|
330
|
+
|
|
331
|
+
return allIpv4Succeeded && allIpv6Failed
|
|
264
332
|
}
|
|
265
333
|
|
|
266
334
|
/**
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = '2.7.
|
|
1
|
+
export const version = '2.7.4-22e62d00f'
|
|
2
2
|
export const name = 'js-libp2p'
|
package/dist/typedoc-urls.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"AddressFilter": "https://libp2p.github.io/js-libp2p/interfaces/libp2p.index.AddressFilter.html",
|
|
3
|
-
"AddressManagerInit": "https://libp2p.github.io/js-libp2p/interfaces/libp2p.index.AddressManagerInit.html",
|
|
4
|
-
"ConnectionManagerInit": "https://libp2p.github.io/js-libp2p/interfaces/libp2p.index.ConnectionManagerInit.html",
|
|
5
|
-
"ConnectionMonitorInit": "https://libp2p.github.io/js-libp2p/interfaces/libp2p.index.ConnectionMonitorInit.html",
|
|
6
|
-
"Libp2pInit": "https://libp2p.github.io/js-libp2p/interfaces/libp2p.index.Libp2pInit.html",
|
|
7
|
-
".:Libp2pInit": "https://libp2p.github.io/js-libp2p/interfaces/libp2p.index.Libp2pInit.html",
|
|
8
|
-
"TransportManagerInit": "https://libp2p.github.io/js-libp2p/interfaces/libp2p.index.TransportManagerInit.html",
|
|
9
|
-
"Libp2pOptions": "https://libp2p.github.io/js-libp2p/types/libp2p.index.Libp2pOptions.html",
|
|
10
|
-
".:Libp2pOptions": "https://libp2p.github.io/js-libp2p/types/libp2p.index.Libp2pOptions.html",
|
|
11
|
-
"ServiceFactoryMap": "https://libp2p.github.io/js-libp2p/types/libp2p.index.ServiceFactoryMap.html",
|
|
12
|
-
".:ServiceFactoryMap": "https://libp2p.github.io/js-libp2p/types/libp2p.index.ServiceFactoryMap.html",
|
|
13
|
-
"createLibp2p": "https://libp2p.github.io/js-libp2p/functions/libp2p.index.createLibp2p.html",
|
|
14
|
-
".:createLibp2p": "https://libp2p.github.io/js-libp2p/functions/libp2p.index.createLibp2p.html",
|
|
15
|
-
"userAgent": "https://libp2p.github.io/js-libp2p/functions/libp2p.user_agent.userAgent.html",
|
|
16
|
-
"./user-agent:userAgent": "https://libp2p.github.io/js-libp2p/functions/libp2p.user_agent.userAgent.html",
|
|
17
|
-
"name": "https://libp2p.github.io/js-libp2p/variables/libp2p.version.name.html",
|
|
18
|
-
"./version:name": "https://libp2p.github.io/js-libp2p/variables/libp2p.version.name.html",
|
|
19
|
-
"version": "https://libp2p.github.io/js-libp2p/variables/libp2p.version.version.html",
|
|
20
|
-
"./version:version": "https://libp2p.github.io/js-libp2p/variables/libp2p.version.version.html"
|
|
21
|
-
}
|