Comparing version 2.3.1-0862522fe to 2.3.1-3650283f7
@@ -50,2 +50,3 @@ import type { ComponentLogger, Libp2pEvents, TypedEventTarget, PeerId, PeerStore } from '@libp2p/interface'; | ||
private readonly ipDomainMappings; | ||
private readonly publicAddressMappings; | ||
/** | ||
@@ -85,3 +86,5 @@ * Responsible for managing the peer addresses. | ||
removeDNSMapping(domain: string): void; | ||
addPublicAddressMapping(internalIp: string, internalPort: number, externalIp: string, externalPort?: number, protocol?: 'tcp' | 'udp'): void; | ||
removePublicAddressMapping(internalIp: string, internalPort: number, externalIp: string, externalPort?: number, protocol?: 'tcp' | 'udp'): void; | ||
} | ||
//# sourceMappingURL=address-manager.d.ts.map |
@@ -24,2 +24,4 @@ import { peerIdFromString } from '@libp2p/peer-id'; | ||
const CODEC_DNS6 = 0x37; | ||
const CODEC_TCP = 0x06; | ||
const CODEC_UDP = 0x0111; | ||
export class AddressManager { | ||
@@ -35,2 +37,3 @@ log; | ||
ipDomainMappings; | ||
publicAddressMappings; | ||
/** | ||
@@ -51,2 +54,3 @@ * Responsible for managing the peer addresses. | ||
this.ipDomainMappings = new Map(); | ||
this.publicAddressMappings = new Map(); | ||
this.announceFilter = init.announceFilter ?? defaultAddressFilter; | ||
@@ -69,7 +73,4 @@ // this method gets called repeatedly on startup when transports start listening so | ||
// record for things like identify | ||
const addrs = this.getAnnounceAddrs() | ||
.concat(this.components.transportManager.getAddrs()) | ||
.concat([...this.observed.entries()] | ||
.filter(([_, metadata]) => metadata.confident) | ||
.map(([str]) => multiaddr(str))).map(ma => { | ||
const addrs = this.getAddresses() | ||
.map(ma => { | ||
// strip our peer id if it is present | ||
@@ -158,6 +159,37 @@ if (ma.getPeerId() === this.components.peerId.toString()) { | ||
.map(([ma]) => multiaddr(ma))); | ||
const mappedMultiaddrs = []; | ||
// add public addresses | ||
const ipMappedMultiaddrs = []; | ||
multiaddrs.forEach(ma => { | ||
const tuples = ma.stringTuples(); | ||
let tuple; | ||
// see if the internal host/port/protocol tuple has been mapped externally | ||
if ((tuples[0][0] === CODEC_IP4 || tuples[0][0] === CODEC_IP6) && tuples[1][0] === CODEC_TCP) { | ||
tuple = `${tuples[0][1]}-${tuples[1][1]}-tcp`; | ||
} | ||
else if ((tuples[0][0] === CODEC_IP4 || tuples[0][0] === CODEC_IP6) && tuples[1][0] === CODEC_UDP) { | ||
tuple = `${tuples[0][1]}-${tuples[1][1]}-udp`; | ||
} | ||
if (tuple == null) { | ||
return; | ||
} | ||
const mappings = this.publicAddressMappings.get(tuple); | ||
if (mappings == null) { | ||
return; | ||
} | ||
mappings.forEach(mapping => { | ||
tuples[0][1] = mapping.externalIp; | ||
tuples[1][1] = `${mapping.externalPort}`; | ||
ipMappedMultiaddrs.push(multiaddr(`/${tuples.map(tuple => { | ||
return [ | ||
protocols(tuple[0]).name, | ||
tuple[1] | ||
].join('/'); | ||
}).join('/')}`)); | ||
}); | ||
}); | ||
multiaddrs = multiaddrs.concat(ipMappedMultiaddrs); | ||
// add ip->domain mappings | ||
const dnsMappedMultiaddrs = []; | ||
for (const ma of multiaddrs) { | ||
const tuples = [...ma.stringTuples()]; | ||
const tuples = ma.stringTuples(); | ||
let mappedIp = false; | ||
@@ -182,3 +214,3 @@ for (const [ip, domain] of this.ipDomainMappings.entries()) { | ||
if (mappedIp) { | ||
mappedMultiaddrs.push(multiaddr(`/${tuples.map(tuple => { | ||
dnsMappedMultiaddrs.push(multiaddr(`/${tuples.map(tuple => { | ||
return [ | ||
@@ -191,3 +223,3 @@ protocols(tuple[0]).name, | ||
} | ||
multiaddrs = multiaddrs.concat(mappedMultiaddrs); | ||
multiaddrs = multiaddrs.concat(dnsMappedMultiaddrs); | ||
// dedupe multiaddrs | ||
@@ -219,4 +251,6 @@ const addrSet = new Set(); | ||
addresses.forEach(ip => { | ||
this.log('add DNS mapping %s to %s', ip, domain); | ||
this.ipDomainMappings.set(ip, domain); | ||
}); | ||
this._updatePeerStoreAddresses(); | ||
} | ||
@@ -226,7 +260,32 @@ removeDNSMapping(domain) { | ||
if (value === domain) { | ||
this.log('remove DNS mapping for %s', domain); | ||
this.ipDomainMappings.delete(key); | ||
} | ||
} | ||
this._updatePeerStoreAddresses(); | ||
} | ||
addPublicAddressMapping(internalIp, internalPort, externalIp, externalPort = internalPort, protocol = 'tcp') { | ||
const key = `${internalIp}-${internalPort}-${protocol}`; | ||
const mappings = this.publicAddressMappings.get(key) ?? []; | ||
mappings.push({ | ||
externalIp, | ||
externalPort | ||
}); | ||
this.publicAddressMappings.set(key, mappings); | ||
this._updatePeerStoreAddresses(); | ||
} | ||
removePublicAddressMapping(internalIp, internalPort, externalIp, externalPort = internalPort, protocol = 'tcp') { | ||
const key = `${internalIp}-${internalPort}-${protocol}`; | ||
const mappings = (this.publicAddressMappings.get(key) ?? []).filter(mapping => { | ||
return mapping.externalIp !== externalIp && mapping.externalPort !== externalPort; | ||
}); | ||
if (mappings.length === 0) { | ||
this.publicAddressMappings.delete(key); | ||
} | ||
else { | ||
this.publicAddressMappings.set(key, mappings); | ||
} | ||
this._updatePeerStoreAddresses(); | ||
} | ||
} | ||
//# sourceMappingURL=address-manager.js.map |
import type { ConnectionGater } from '@libp2p/interface'; | ||
/** | ||
* Returns a connection gater that disallows dialling private addresses by | ||
* default. Browsers are severely limited in their resource usage so don't | ||
* waste time trying to dial undiallable addresses. | ||
* Returns a connection gater that disallows dialling private addresses or | ||
* insecure websockets by default. | ||
* | ||
* Browsers are severely limited in their resource usage so don't waste time | ||
* trying to dial undiallable addresses, and they also print verbose error | ||
* messages when making connections over insecure transports which causes | ||
* confusion. | ||
*/ | ||
export declare function connectionGater(gater?: ConnectionGater): ConnectionGater; | ||
//# sourceMappingURL=connection-gater.browser.d.ts.map |
import { isPrivateIp } from '@libp2p/utils/private-ip'; | ||
import { WebSockets } from '@multiformats/multiaddr-matcher'; | ||
const CODEC_IP4 = 0x04; | ||
const CODEC_IP6 = 0x29; | ||
/** | ||
* Returns a connection gater that disallows dialling private addresses by | ||
* default. Browsers are severely limited in their resource usage so don't | ||
* waste time trying to dial undiallable addresses. | ||
* Returns a connection gater that disallows dialling private addresses or | ||
* insecure websockets by default. | ||
* | ||
* Browsers are severely limited in their resource usage so don't waste time | ||
* trying to dial undiallable addresses, and they also print verbose error | ||
* messages when making connections over insecure transports which causes | ||
* confusion. | ||
*/ | ||
@@ -11,4 +18,9 @@ export function connectionGater(gater = {}) { | ||
denyDialMultiaddr: async (multiaddr) => { | ||
// do not connect to insecure websockets by default | ||
if (WebSockets.matches(multiaddr)) { | ||
return false; | ||
} | ||
const tuples = multiaddr.stringTuples(); | ||
if (tuples[0][0] === 4 || tuples[0][0] === 41) { | ||
// do not connect to private addresses by default | ||
if (tuples[0][0] === CODEC_IP4 || tuples[0][0] === CODEC_IP6) { | ||
return Boolean(isPrivateIp(`${tuples[0][1]}`)); | ||
@@ -15,0 +27,0 @@ } |
import { PeerMap } from '@libp2p/peer-collections'; | ||
import { PriorityQueue, type PriorityQueueJobOptions } from '@libp2p/utils/priority-queue'; | ||
import { type Multiaddr, type Resolver } from '@multiformats/multiaddr'; | ||
import { PriorityQueue } from '@libp2p/utils/priority-queue'; | ||
import type { AddressSorter, ComponentLogger, Connection, ConnectionGater, Metrics, PeerId, PeerStore, PeerRouting, IsDialableOptions, OpenConnectionProgressEvents } from '@libp2p/interface'; | ||
import type { OpenConnectionOptions, TransportManager } from '@libp2p/interface-internal'; | ||
import type { PriorityQueueJobOptions } from '@libp2p/utils/priority-queue'; | ||
import type { DNS } from '@multiformats/dns'; | ||
import type { Multiaddr, Resolver } from '@multiformats/multiaddr'; | ||
import type { ProgressOptions } from 'progress-events'; | ||
@@ -64,3 +65,2 @@ export interface PendingDialTarget { | ||
dial(peerIdOrMultiaddr: PeerId | Multiaddr | Multiaddr[], options?: OpenConnectionOptions): Promise<Connection>; | ||
private createDialAbortController; | ||
private calculateMultiaddrs; | ||
@@ -67,0 +67,0 @@ isDialable(multiaddr: Multiaddr | Multiaddr[], options?: IsDialableOptions): Promise<boolean>; |
@@ -141,3 +141,7 @@ /* eslint-disable max-depth */ | ||
// we may be about to resolve a dns addr which can time out | ||
const signal = this.createDialAbortController(options?.signal); | ||
const signal = anySignal([ | ||
this.shutDownController.signal, | ||
options.signal | ||
]); | ||
setMaxListeners(Infinity, signal); | ||
let addrsToDial; | ||
@@ -226,17 +230,6 @@ try { | ||
multiaddrs: new Set(multiaddrs.map(ma => ma.toString())), | ||
signal: options.signal, | ||
signal: options.signal ?? AbortSignal.timeout(this.dialTimeout), | ||
onProgress: options.onProgress | ||
}); | ||
} | ||
createDialAbortController(userSignal) { | ||
// let any signal abort the dial | ||
const signal = anySignal([ | ||
AbortSignal.timeout(this.dialTimeout), | ||
this.shutDownController.signal, | ||
userSignal | ||
]); | ||
// This emitter gets listened to a lot | ||
setMaxListeners(Infinity, signal); | ||
return signal; | ||
} | ||
// eslint-disable-next-line complexity | ||
@@ -243,0 +236,0 @@ async calculateMultiaddrs(peerId, multiaddrs = new Set(), options = {}) { |
@@ -1,3 +0,3 @@ | ||
export declare const version = "2.3.1-0862522fe"; | ||
export declare const version = "2.3.1-3650283f7"; | ||
export declare const name = "libp2p"; | ||
//# sourceMappingURL=version.d.ts.map |
@@ -1,3 +0,3 @@ | ||
export const version = '2.3.1-0862522fe'; | ||
export const version = '2.3.1-3650283f7'; | ||
export const name = 'libp2p'; | ||
//# sourceMappingURL=version.js.map |
{ | ||
"name": "libp2p", | ||
"version": "2.3.1-0862522fe", | ||
"version": "2.3.1-3650283f7", | ||
"description": "JavaScript implementation of libp2p, a modular peer to peer network stack", | ||
@@ -88,11 +88,11 @@ "license": "Apache-2.0 OR MIT", | ||
"dependencies": { | ||
"@libp2p/crypto": "5.0.7-0862522fe", | ||
"@libp2p/interface": "2.2.1-0862522fe", | ||
"@libp2p/interface-internal": "2.1.1-0862522fe", | ||
"@libp2p/logger": "5.1.4-0862522fe", | ||
"@libp2p/multistream-select": "6.0.9-0862522fe", | ||
"@libp2p/peer-collections": "6.0.12-0862522fe", | ||
"@libp2p/peer-id": "5.0.8-0862522fe", | ||
"@libp2p/peer-store": "11.0.12-0862522fe", | ||
"@libp2p/utils": "6.2.1-0862522fe", | ||
"@libp2p/crypto": "5.0.7-3650283f7", | ||
"@libp2p/interface": "2.2.1-3650283f7", | ||
"@libp2p/interface-internal": "2.1.1-3650283f7", | ||
"@libp2p/logger": "5.1.4-3650283f7", | ||
"@libp2p/multistream-select": "6.0.9-3650283f7", | ||
"@libp2p/peer-collections": "6.0.12-3650283f7", | ||
"@libp2p/peer-id": "5.0.8-3650283f7", | ||
"@libp2p/peer-store": "11.0.12-3650283f7", | ||
"@libp2p/utils": "6.2.1-3650283f7", | ||
"@multiformats/dns": "^1.0.6", | ||
@@ -99,0 +99,0 @@ "@multiformats/multiaddr": "^12.2.3", |
@@ -81,3 +81,10 @@ import { peerIdFromString } from '@libp2p/peer-id' | ||
const CODEC_DNS6 = 0x37 | ||
const CODEC_TCP = 0x06 | ||
const CODEC_UDP = 0x0111 | ||
interface PublicAddressMapping { | ||
externalIp: string | ||
externalPort: number | ||
} | ||
export class AddressManager implements AddressManagerInterface { | ||
@@ -93,2 +100,3 @@ private readonly log: Logger | ||
private readonly ipDomainMappings: Map<string, string> | ||
private readonly publicAddressMappings: Map<string, PublicAddressMapping[]> | ||
@@ -111,2 +119,3 @@ /** | ||
this.ipDomainMappings = new Map() | ||
this.publicAddressMappings = new Map() | ||
this.announceFilter = init.announceFilter ?? defaultAddressFilter | ||
@@ -133,9 +142,4 @@ | ||
// record for things like identify | ||
const addrs = this.getAnnounceAddrs() | ||
.concat(this.components.transportManager.getAddrs()) | ||
.concat( | ||
[...this.observed.entries()] | ||
.filter(([_, metadata]) => metadata.confident) | ||
.map(([str]) => multiaddr(str)) | ||
).map(ma => { | ||
const addrs = this.getAddresses() | ||
.map(ma => { | ||
// strip our peer id if it is present | ||
@@ -246,7 +250,47 @@ if (ma.getPeerId() === this.components.peerId.toString()) { | ||
const mappedMultiaddrs: Multiaddr[] = [] | ||
// add public addresses | ||
const ipMappedMultiaddrs: Multiaddr[] = [] | ||
multiaddrs.forEach(ma => { | ||
const tuples = ma.stringTuples() | ||
let tuple: string | undefined | ||
// see if the internal host/port/protocol tuple has been mapped externally | ||
if ((tuples[0][0] === CODEC_IP4 || tuples[0][0] === CODEC_IP6) && tuples[1][0] === CODEC_TCP) { | ||
tuple = `${tuples[0][1]}-${tuples[1][1]}-tcp` | ||
} else if ((tuples[0][0] === CODEC_IP4 || tuples[0][0] === CODEC_IP6) && tuples[1][0] === CODEC_UDP) { | ||
tuple = `${tuples[0][1]}-${tuples[1][1]}-udp` | ||
} | ||
if (tuple == null) { | ||
return | ||
} | ||
const mappings = this.publicAddressMappings.get(tuple) | ||
if (mappings == null) { | ||
return | ||
} | ||
mappings.forEach(mapping => { | ||
tuples[0][1] = mapping.externalIp | ||
tuples[1][1] = `${mapping.externalPort}` | ||
ipMappedMultiaddrs.push( | ||
multiaddr(`/${ | ||
tuples.map(tuple => { | ||
return [ | ||
protocols(tuple[0]).name, | ||
tuple[1] | ||
].join('/') | ||
}).join('/') | ||
}`) | ||
) | ||
}) | ||
}) | ||
multiaddrs = multiaddrs.concat(ipMappedMultiaddrs) | ||
// add ip->domain mappings | ||
const dnsMappedMultiaddrs: Multiaddr[] = [] | ||
for (const ma of multiaddrs) { | ||
const tuples = [...ma.stringTuples()] | ||
const tuples = ma.stringTuples() | ||
let mappedIp = false | ||
@@ -275,3 +319,3 @@ | ||
if (mappedIp) { | ||
mappedMultiaddrs.push( | ||
dnsMappedMultiaddrs.push( | ||
multiaddr(`/${ | ||
@@ -288,5 +332,4 @@ tuples.map(tuple => { | ||
} | ||
multiaddrs = multiaddrs.concat(dnsMappedMultiaddrs) | ||
multiaddrs = multiaddrs.concat(mappedMultiaddrs) | ||
// dedupe multiaddrs | ||
@@ -328,4 +371,6 @@ const addrSet = new Set<string>() | ||
addresses.forEach(ip => { | ||
this.log('add DNS mapping %s to %s', ip, domain) | ||
this.ipDomainMappings.set(ip, domain) | ||
}) | ||
this._updatePeerStoreAddresses() | ||
} | ||
@@ -336,6 +381,35 @@ | ||
if (value === domain) { | ||
this.log('remove DNS mapping for %s', domain) | ||
this.ipDomainMappings.delete(key) | ||
} | ||
} | ||
this._updatePeerStoreAddresses() | ||
} | ||
addPublicAddressMapping (internalIp: string, internalPort: number, externalIp: string, externalPort: number = internalPort, protocol: 'tcp' | 'udp' = 'tcp'): void { | ||
const key = `${internalIp}-${internalPort}-${protocol}` | ||
const mappings = this.publicAddressMappings.get(key) ?? [] | ||
mappings.push({ | ||
externalIp, | ||
externalPort | ||
}) | ||
this.publicAddressMappings.set(key, mappings) | ||
this._updatePeerStoreAddresses() | ||
} | ||
removePublicAddressMapping (internalIp: string, internalPort: number, externalIp: string, externalPort: number = internalPort, protocol: 'tcp' | 'udp' = 'tcp'): void { | ||
const key = `${internalIp}-${internalPort}-${protocol}` | ||
const mappings = (this.publicAddressMappings.get(key) ?? []).filter(mapping => { | ||
return mapping.externalIp !== externalIp && mapping.externalPort !== externalPort | ||
}) | ||
if (mappings.length === 0) { | ||
this.publicAddressMappings.delete(key) | ||
} else { | ||
this.publicAddressMappings.set(key, mappings) | ||
} | ||
this._updatePeerStoreAddresses() | ||
} | ||
} |
import { isPrivateIp } from '@libp2p/utils/private-ip' | ||
import { WebSockets } from '@multiformats/multiaddr-matcher' | ||
import type { ConnectionGater } from '@libp2p/interface' | ||
import type { Multiaddr } from '@multiformats/multiaddr' | ||
const CODEC_IP4 = 0x04 | ||
const CODEC_IP6 = 0x29 | ||
/** | ||
* Returns a connection gater that disallows dialling private addresses by | ||
* default. Browsers are severely limited in their resource usage so don't | ||
* waste time trying to dial undiallable addresses. | ||
* Returns a connection gater that disallows dialling private addresses or | ||
* insecure websockets by default. | ||
* | ||
* Browsers are severely limited in their resource usage so don't waste time | ||
* trying to dial undiallable addresses, and they also print verbose error | ||
* messages when making connections over insecure transports which causes | ||
* confusion. | ||
*/ | ||
@@ -14,5 +22,11 @@ export function connectionGater (gater: ConnectionGater = {}): ConnectionGater { | ||
denyDialMultiaddr: async (multiaddr: Multiaddr) => { | ||
// do not connect to insecure websockets by default | ||
if (WebSockets.matches(multiaddr)) { | ||
return false | ||
} | ||
const tuples = multiaddr.stringTuples() | ||
if (tuples[0][0] === 4 || tuples[0][0] === 41) { | ||
// do not connect to private addresses by default | ||
if (tuples[0][0] === CODEC_IP4 || tuples[0][0] === CODEC_IP6) { | ||
return Boolean(isPrivateIp(`${tuples[0][1]}`)) | ||
@@ -19,0 +33,0 @@ } |
/* eslint-disable max-depth */ | ||
import { TimeoutError, DialError, setMaxListeners, AbortError } from '@libp2p/interface' | ||
import { PeerMap } from '@libp2p/peer-collections' | ||
import { PriorityQueue, type PriorityQueueJobOptions } from '@libp2p/utils/priority-queue' | ||
import { type Multiaddr, type Resolver, resolvers, multiaddr } from '@multiformats/multiaddr' | ||
import { PriorityQueue } from '@libp2p/utils/priority-queue' | ||
import { resolvers, multiaddr } from '@multiformats/multiaddr' | ||
import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers' | ||
import { Circuit } from '@multiformats/multiaddr-matcher' | ||
import { type ClearableSignal, anySignal } from 'any-signal' | ||
import { anySignal } from 'any-signal' | ||
import { CustomProgressEvent } from 'progress-events' | ||
@@ -26,3 +26,5 @@ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' | ||
import type { OpenConnectionOptions, TransportManager } from '@libp2p/interface-internal' | ||
import type { PriorityQueueJobOptions } from '@libp2p/utils/priority-queue' | ||
import type { DNS } from '@multiformats/dns' | ||
import type { Multiaddr, Resolver } from '@multiformats/multiaddr' | ||
import type { ProgressOptions } from 'progress-events' | ||
@@ -208,3 +210,8 @@ | ||
// we may be about to resolve a dns addr which can time out | ||
const signal = this.createDialAbortController(options?.signal) | ||
const signal = anySignal([ | ||
this.shutDownController.signal, | ||
options.signal | ||
]) | ||
setMaxListeners(Infinity, signal) | ||
let addrsToDial: Address[] | ||
@@ -304,3 +311,3 @@ | ||
multiaddrs: new Set(multiaddrs.map(ma => ma.toString())), | ||
signal: options.signal, | ||
signal: options.signal ?? AbortSignal.timeout(this.dialTimeout), | ||
onProgress: options.onProgress | ||
@@ -310,16 +317,2 @@ }) | ||
private createDialAbortController (userSignal?: AbortSignal): ClearableSignal { | ||
// let any signal abort the dial | ||
const signal = anySignal([ | ||
AbortSignal.timeout(this.dialTimeout), | ||
this.shutDownController.signal, | ||
userSignal | ||
]) | ||
// This emitter gets listened to a lot | ||
setMaxListeners(Infinity, signal) | ||
return signal | ||
} | ||
// eslint-disable-next-line complexity | ||
@@ -326,0 +319,0 @@ private async calculateMultiaddrs (peerId?: PeerId, multiaddrs: Set<string> = new Set<string>(), options: OpenConnectionOptions = {}): Promise<Address[]> { |
@@ -1,2 +0,2 @@ | ||
export const version = '2.3.1-0862522fe' | ||
export const version = '2.3.1-3650283f7' | ||
export const name = 'libp2p' |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
899775
10834
+ Added@libp2p/crypto@5.0.7-3650283f7(transitive)
+ Added@libp2p/interface@2.2.1-3650283f7(transitive)
+ Added@libp2p/interface-internal@2.1.1-3650283f7(transitive)
+ Added@libp2p/logger@5.1.4-3650283f7(transitive)
+ Added@libp2p/multistream-select@6.0.9-3650283f7(transitive)
+ Added@libp2p/peer-collections@6.0.12-3650283f7(transitive)
+ Added@libp2p/peer-id@5.0.8-3650283f7(transitive)
+ Added@libp2p/peer-record@8.0.12-3650283f7(transitive)
+ Added@libp2p/peer-store@11.0.12-3650283f7(transitive)
+ Added@libp2p/utils@6.2.1-3650283f7(transitive)
- Removed@libp2p/crypto@5.0.7-0862522fe(transitive)
- Removed@libp2p/interface@2.2.1-0862522fe(transitive)
- Removed@libp2p/interface-internal@2.1.1-0862522fe(transitive)
- Removed@libp2p/logger@5.1.4-0862522fe(transitive)
- Removed@libp2p/multistream-select@6.0.9-0862522fe(transitive)
- Removed@libp2p/peer-collections@6.0.12-0862522fe(transitive)
- Removed@libp2p/peer-id@5.0.8-0862522fe(transitive)
- Removed@libp2p/peer-record@8.0.12-0862522fe(transitive)
- Removed@libp2p/peer-store@11.0.12-0862522fe(transitive)
- Removed@libp2p/utils@6.2.1-0862522fe(transitive)