feat!: update to libp2p-v3 (#84)
Updates all deps to the latest versions BREAKING CHANGE: use with libp2p@v3 only
Alex Potsides committed
Jan 16, 2026 at 12:10 UTC
a92ce3e1b51555657d3465205c9c6b3216bc6ae3
18 files changed
+107
-90
.github/dependabot.yml
+3
-4
@@ -1,8 +1,7 @@
1
version: 2
2
updates:
3
- package-ecosystem: npm
4
- directories:
5
- - "/"
4
+ directory: "/"
5
schedule:
6
interval: daily
7
time: "10:00"
@@ -11,14 +10,14 @@ updates:
10
prefix: "deps"
11
prefix-development: "chore"
12
groups:
14
- interplanetary-deps: # group all deps that should be updated when Helia deps need updated
13
+ interplanetary-deps: # Helia/libp2p deps
14
patterns:
15
- "*helia*"
16
- "*libp2p*"
17
- "*multiformats*"
18
- "*blockstore*"
19
- "*datastore*"
21
- kubo-deps: # group kubo, kubo-rpc-client, and ipfsd-ctl updates
20
+ kubo-deps: # kubo deps
21
patterns:
22
- "*kubo*"
23
- "ipfsd-ctl"
.github/workflows/semantic-pull-request.yml
+1
-1
@@ -9,4 +9,4 @@ on:
9
10
jobs:
11
main:
12
- uses: pl-strflt/.github/.github/workflows/reusable-semantic-pull-request.yml@v0.3
12
+ uses: ipdxco/unified-github-workflows/.github/workflows/reusable-semantic-pull-request.yml@v1
.github/workflows/stale.yml
+1
-1
@@ -1,4 +1,4 @@
1
-name: Close Stale Issues
1
+name: Close and mark stale issue
2
3
on:
4
schedule:
packages/libp2p-devtools/package.json
+13
-13
@@ -139,25 +139,25 @@
139
"release": "aegir release"
140
},
141
"dependencies": {
142
- "@ipshipyard/libp2p-inspector-metrics": "^1.0.1",
143
- "@ipshipyard/libp2p-inspector-ui": "^1.0.1",
144
- "@libp2p/interface": "^2.10.2",
142
+ "@ipshipyard/libp2p-inspector-metrics": "^1.0.0",
143
+ "@ipshipyard/libp2p-inspector-ui": "^1.0.0",
144
+ "@libp2p/interface": "^3.1.0",
145
"it-pipe": "^3.0.1",
146
"it-pushable": "^3.2.3",
147
- "it-rpc": "^1.1.0",
147
+ "it-rpc": "^1.2.1",
148
"it-stream-types": "^2.0.2",
149
- "multiformats": "^13.3.6",
150
- "react": "^19.1.0",
151
- "react-dom": "^19.1.0",
152
- "react-syntax-highlighter": "^15.6.1",
149
+ "multiformats": "^13.4.2",
150
+ "react": "^19.2.3",
151
+ "react-dom": "^19.2.3",
152
+ "react-syntax-highlighter": "^16.1.0",
153
"uint8arrays": "^5.1.0"
154
},
155
"devDependencies": {
156
- "@types/chrome": "^0.0.323",
157
- "@types/react": "^19.1.5",
158
- "@types/react-dom": "^19.1.5",
156
+ "@types/chrome": "^0.1.33",
157
+ "@types/react": "^19.2.8",
158
+ "@types/react-dom": "^19.2.3",
159
"@types/react-syntax-highlighter": "^15.5.13",
160
- "aegir": "^47.0.13",
161
- "web-ext": "^8.9.0"
160
+ "aegir": "^47.0.25",
161
+ "web-ext": "^9.2.0"
162
}
163
}
packages/libp2p-inspector-metrics/package.json
+15
-14
@@ -135,30 +135,31 @@
135
"release": "aegir release"
136
},
137
"dependencies": {
138
- "@libp2p/identify": "^3.0.32",
139
- "@libp2p/interface": "^2.10.2",
140
- "@libp2p/interface-internal": "^2.3.14",
141
- "@libp2p/logger": "^5.1.18",
142
- "@libp2p/peer-id": "^5.1.5",
143
- "@libp2p/ping": "^2.0.32",
144
- "@libp2p/simple-metrics": "^1.3.12",
145
- "@libp2p/utils": "^6.6.5",
146
- "@multiformats/multiaddr": "^12.4.0",
147
- "cborg": "^4.2.11",
138
+ "@libp2p/gossipsub": "^15.0.11",
139
+ "@libp2p/identify": "^4.0.9",
140
+ "@libp2p/interface": "^3.1.0",
141
+ "@libp2p/interface-internal": "^3.0.9",
142
+ "@libp2p/logger": "^6.2.2",
143
+ "@libp2p/peer-id": "^6.0.4",
144
+ "@libp2p/ping": "^3.0.9",
145
+ "@libp2p/simple-metrics": "^2.0.9",
146
+ "@libp2p/utils": "^7.0.9",
147
+ "@multiformats/multiaddr": "^13.0.1",
148
+ "cborg": "^4.3.2",
149
"dns-packet": "^5.6.1",
150
"it-length-prefixed": "^10.0.1",
151
"it-pipe": "^3.0.1",
152
"it-pushable": "^3.2.3",
152
- "it-rpc": "^1.1.0",
153
+ "it-rpc": "^1.2.1",
154
"multicast-dns": "^7.2.5",
154
- "multiformats": "^13.3.6",
155
+ "multiformats": "^13.4.2",
156
"progress-events": "^1.0.1",
157
"stream-to-it": "^1.0.1",
158
"uint8arrays": "^5.1.0"
159
},
160
"devDependencies": {
160
- "@libp2p/crypto": "^5.1.4",
161
- "aegir": "^47.0.13",
161
+ "@libp2p/crypto": "^5.1.13",
162
+ "aegir": "^47.0.25",
163
"sinon-ts": "^2.0.0"
164
},
165
"browser": {
packages/libp2p-inspector-metrics/src/index.ts
+3
-3
@@ -31,7 +31,7 @@ import { getPeers } from './utils/get-peers.js'
31
import { getSelf } from './utils/get-self.js'
32
import type { Messages } from './messages/index.js'
33
import type { InspectorRPC } from './rpc/index.js'
34
-import type { ComponentLogger, Connection, Libp2pEvents, Logger, Metrics, MultiaddrConnection, PeerId, PeerStore, Stream, ContentRouting, PeerRouting, TypedEventTarget, Startable, NodeInfo } from '@libp2p/interface'
34
+import type { ComponentLogger, Libp2pEvents, Logger, Metrics, MultiaddrConnection, PeerId, PeerStore, Stream, ContentRouting, PeerRouting, TypedEventTarget, Startable, NodeInfo } from '@libp2p/interface'
35
import type { TransportManager, Registrar, ConnectionManager, AddressManager } from '@libp2p/interface-internal'
36
import type { Pushable } from 'it-pushable'
37
import type { RPC } from 'it-rpc'
@@ -213,8 +213,8 @@ class InspectorMetrics implements Metrics, Startable {
213
this.simpleMetrics.trackMultiaddrConnection(maConn)
214
}
215
216
- trackProtocolStream (stream: Stream, connection: Connection): void {
217
- this.simpleMetrics.trackProtocolStream(stream, connection)
216
+ trackProtocolStream (stream: Stream): void {
217
+ this.simpleMetrics.trackProtocolStream(stream)
218
}
219
220
registerMetric (name: any, options: any): any {
packages/libp2p-inspector-metrics/src/messages/messages.ts
+2
-4
@@ -1,7 +1,6 @@
1
import { createServer } from 'node:net'
2
import { start, stop, TypedEventEmitter } from '@libp2p/interface'
3
-import { getThinWaistAddresses } from '@libp2p/utils/get-thin-waist-addresses'
4
-import { isPrivate } from '@libp2p/utils/multiaddr/is-private'
3
+import { getThinWaistAddresses, isPrivate } from '@libp2p/utils'
4
import { multiaddr } from '@multiformats/multiaddr'
5
import { encode, decode } from 'it-length-prefixed'
6
import { pushable } from 'it-pushable'
@@ -99,8 +98,7 @@ class MDNSPortAdvertisement {
98
99
function toMultiaddrs (addr: string | AddressInfo): Multiaddr[] {
100
if (typeof addr === 'string') {
102
- // TODO: wrap with encodeURIComponent https://github.com/multiformats/multiaddr/pull/174
103
- return [multiaddr(`/unix/${addr}`)]
101
+ return [multiaddr(`/unix/${encodeURIComponent(addr)}`)]
102
}
103
104
const { family, address, port } = addr
packages/libp2p-inspector-metrics/src/rpc/index.ts
+3
-4
@@ -2,7 +2,7 @@ import { cidCodec } from './codecs/cid.js'
2
import { customProgressEventCodec } from './codecs/custom-progress-event.js'
3
import { multiaddrCodec } from './codecs/multiaddr.js'
4
import { peerIdCodec } from './codecs/peer-id.js'
5
-import type { ContentRouting, PeerId, PeerRouting, AbortOptions, IdentifyResult, Direction, ConnectionTimeline, ConnectionStatus, ConnectionLimits } from '@libp2p/interface'
5
+import type { ContentRouting, PeerId, PeerRouting, AbortOptions, IdentifyResult, ConnectionStatus, ConnectionLimits, MultiaddrConnectionTimeline, MessageStreamDirection } from '@libp2p/interface'
6
import type { OpenConnectionOptions } from '@libp2p/interface-internal'
7
import type { Multiaddr } from '@multiformats/multiaddr'
8
import type { ValueCodec } from 'it-rpc'
@@ -51,9 +51,8 @@ export interface Connection {
51
id: string
52
remoteAddr: Multiaddr
53
remotePeer: PeerId
54
- tags: string[]
55
- direction: Direction
56
- timeline: ConnectionTimeline
54
+ direction: MessageStreamDirection
55
+ timeline: MultiaddrConnectionTimeline
56
multiplexer?: string
57
encryption?: string
58
status: ConnectionStatus
packages/libp2p-inspector-metrics/src/rpc/rpc.ts
-1
@@ -57,7 +57,6 @@ export function metricsRpc (components: InspectorMetricsComponents): MetricsRPC
57
id: conn.id,
58
remoteAddr: conn.remoteAddr,
59
remotePeer: conn.remotePeer,
60
- tags: conn.tags,
60
direction: conn.direction,
61
timeline: conn.timeline,
62
multiplexer: conn.multiplexer,
packages/libp2p-inspector-metrics/src/utils/get-pubsub.ts
+15
-4
@@ -1,10 +1,21 @@
1
-import { InvalidParametersError, isPubSub } from '@libp2p/interface'
2
-import type { PubSub } from '@libp2p/interface'
1
+import { InvalidParametersError } from '@libp2p/interface'
2
+import type { GossipSub } from '@libp2p/gossipsub'
3
4
-export function getPubSub (component: string, components: any): PubSub {
4
+function isGossipSub (obj?: any): obj is GossipSub {
5
+ if (obj == null) {
6
+ return false
7
+ }
8
+
9
+ return typeof obj.publish === 'function' &&
10
+ typeof obj.getSubscribers === 'function' &&
11
+ typeof obj.unsubscribe === 'function' &&
12
+ typeof obj.subscribe === 'function'
13
+}
14
+
15
+export function getPubSub (component: string, components: any): GossipSub {
16
const pubsub = components[component]
17
7
- if (!isPubSub(pubsub)) {
18
+ if (!isGossipSub(pubsub)) {
19
throw new InvalidParametersError(`Component ${component} did not implement the PubSub interface`)
20
}
21
packages/libp2p-inspector-ui/package.json
+12
-11
@@ -153,23 +153,24 @@
153
"release": "aegir release"
154
},
155
"dependencies": {
156
- "@ipshipyard/libp2p-inspector-metrics": "^1.0.1",
157
- "@libp2p/interface": "^2.10.2",
158
- "@libp2p/peer-id": "^5.1.5",
159
- "@multiformats/multiaddr": "^12.4.0",
160
- "@multiformats/multiaddr-matcher": "^1.7.2",
161
- "multiformats": "^13.3.6",
156
+ "@ipshipyard/libp2p-inspector-metrics": "^1.0.0",
157
+ "@libp2p/gossipsub": "^15.0.11",
158
+ "@libp2p/interface": "^3.1.0",
159
+ "@libp2p/peer-id": "^6.0.4",
160
+ "@multiformats/multiaddr": "^13.0.1",
161
+ "@multiformats/multiaddr-matcher": "^3.0.1",
162
+ "multiformats": "^13.4.2",
163
"react-icons": "^5.5.0",
164
"uint8arrays": "^5.1.0"
165
},
166
"devDependencies": {
166
- "@types/react": "^19.1.5",
167
- "@types/react-dom": "^19.1.5",
168
- "aegir": "^47.0.13",
167
+ "@types/react": "^19.2.8",
168
+ "@types/react-dom": "^19.2.3",
169
+ "aegir": "^47.0.25",
170
"fast-glob": "^3.3.3"
171
},
172
"peerDependencies": {
172
- "react": "^19.1.0",
173
- "react-dom": "^19.1.0"
173
+ "react": "^19.2.3",
174
+ "react-dom": "^19.2.3"
175
}
176
}
packages/libp2p-inspector-ui/src/panels/multiaddr-list.tsx
+2
-2
@@ -1,6 +1,6 @@
1
import './multiaddr-list.css'
2
import { multiaddr } from '@multiformats/multiaddr'
3
-import { WebRTC, WebSockets, WebSocketsSecure, WebTransport, Circuit, QUIC, QUICV1, TCP, WebRTCDirect } from '@multiformats/multiaddr-matcher'
3
+import { WebRTC, WebSockets, WebSocketsSecure, WebTransport, Circuit, QUIC, QUIC_V1, TCP, WebRTCDirect } from '@multiformats/multiaddr-matcher'
4
import { useContext } from 'react'
5
import certifiedMultiaddr from '../../public/img/multiaddr-certified.svg'
6
import uncertifiedMultiaddr from '../../public/img/multiaddr-uncertified.svg'
@@ -31,7 +31,7 @@ function TransportIcon ({ multiaddr }: TransportIconProps): ReactElement {
31
src = websocketTransport
32
} else if (WebTransport.matches(multiaddr)) {
33
src = webtransportTransport
34
- } else if (QUIC.matches(multiaddr) || QUICV1.matches(multiaddr)) {
34
+ } else if (QUIC.matches(multiaddr) || QUIC_V1.matches(multiaddr)) {
35
src = quicTransport
36
} else if (TCP.matches(multiaddr)) {
37
src = tcpTransport
packages/libp2p-inspector-ui/src/panels/node.tsx
+1
-1
@@ -43,7 +43,7 @@ export function Node ({ id, addresses, protocols, metadata }: NodeProps): ReactE
43
addresses={addresses.map(address => {
44
let multiaddr = address.multiaddr
45
46
- if (multiaddr.getPeerId() == null) {
46
+ if (multiaddr.getComponents().some(c => c.name === 'p2p') === false) {
47
multiaddr = multiaddr.encapsulate(`/p2p/${id}`)
48
}
49
packages/libp2p-inspector-ui/src/panels/pubsub/index.tsx
+1
-1
@@ -5,7 +5,7 @@ import { Panel } from '../panel.js'
5
import { SmallError, SmallSuccess } from '../status.js'
6
import { TextInput } from '../text-input.js'
7
import type { MetricsRPC } from '@ipshipyard/libp2p-inspector-metrics'
8
-import type { Message } from '@libp2p/interface'
8
+import type { Message } from '@libp2p/gossipsub'
9
import type { ReactElement } from 'react'
10
11
export interface PubSubProps {
packages/libp2p-inspector/package.json
+19
-19
@@ -139,35 +139,35 @@
139
"release": "aegir release"
140
},
141
"dependencies": {
142
- "@ipshipyard/libp2p-inspector-metrics": "^1.0.1",
143
- "@ipshipyard/libp2p-inspector-ui": "^1.0.1",
144
- "@libp2p/interface": "^2.10.2",
145
- "@libp2p/peer-id": "^5.1.5",
146
- "@libp2p/utils": "^6.6.5",
147
- "@multiformats/multiaddr": "^12.4.0",
142
+ "@ipshipyard/libp2p-inspector-metrics": "^1.0.0",
143
+ "@ipshipyard/libp2p-inspector-ui": "^1.0.0",
144
+ "@libp2p/interface": "^3.1.0",
145
+ "@libp2p/peer-id": "^6.0.4",
146
+ "@libp2p/utils": "^7.0.9",
147
+ "@multiformats/multiaddr": "^13.0.1",
148
"@types/multicast-dns": "^7.2.4",
149
- "electron": "^36.3.1",
149
+ "electron": "^40.0.0",
150
"it-length-prefixed": "^10.0.1",
151
"it-pipe": "^3.0.1",
152
"it-pushable": "^3.2.3",
153
- "it-rpc": "^1.1.0",
153
+ "it-rpc": "^1.2.1",
154
"multicast-dns": "^7.2.5",
155
- "multiformats": "^13.3.6",
156
- "race-signal": "^1.1.3",
157
- "react": "^19.1.0",
158
- "react-dom": "^19.1.0",
155
+ "multiformats": "^13.4.2",
156
+ "race-signal": "^2.0.0",
157
+ "react": "^19.2.3",
158
+ "react-dom": "^19.2.3",
159
"react-icons": "^5.5.0",
160
"stream-to-it": "^1.0.1",
161
"uint8arrays": "^5.1.0"
162
},
163
"devDependencies": {
164
- "@libp2p/webrtc": "^5.2.15",
165
- "@playwright/test": "^1.52.0",
166
- "@types/react": "^19.1.5",
167
- "@types/react-dom": "^19.1.5",
168
- "aegir": "^47.0.13",
164
+ "@libp2p/webrtc": "^6.0.10",
165
+ "@playwright/test": "^1.57.0",
166
+ "@types/react": "^19.2.8",
167
+ "@types/react-dom": "^19.2.3",
168
+ "aegir": "^47.0.25",
169
"fast-glob": "^3.3.3",
170
- "libp2p": "^2.8.8",
171
- "playwright-core": "^1.52.0"
170
+ "libp2p": "^3.1.2",
171
+ "playwright-core": "^1.57.0"
172
}
173
}
packages/libp2p-inspector/src/main/discovery.ts
+1
-1
@@ -1,5 +1,5 @@
1
import { peerIdFromString } from '@libp2p/peer-id'
2
-import { repeatingTask } from '@libp2p/utils/repeating-task'
2
+import { repeatingTask } from '@libp2p/utils'
3
import { multiaddr } from '@multiformats/multiaddr'
4
import multicastDNS from 'multicast-dns'
5
import { Target } from './target.js'
packages/libp2p-inspector/src/main/target.ts
+11
-2
@@ -1,6 +1,7 @@
1
import { createConnection } from 'node:net'
2
import { SOURCE_CLIENT } from '@ipshipyard/libp2p-inspector-metrics'
3
-import { Queue } from '@libp2p/utils/queue'
3
+import { InvalidParametersError } from '@libp2p/interface'
4
+import { getNetConfig, Queue } from '@libp2p/utils'
5
import { encode, decode } from 'it-length-prefixed'
6
import { pushable } from 'it-pushable'
7
import { base64 } from 'multiformats/bases/base64'
@@ -105,8 +106,16 @@ export class Target {
106
107
private async _openConnection (ma: Multiaddr, options?: AbortOptions): Promise<void> {
108
const result = Promise.withResolvers<void>()
109
+ const config = getNetConfig(ma)
110
109
- const socket = createConnection(ma.toOptions(), () => {
111
+ if (config.port == null) {
112
+ throw new InvalidParametersError('Port was missing from multiaddr')
113
+ }
114
+
115
+ const socket = createConnection({
116
+ host: config.host,
117
+ port: config.port
118
+ }, () => {
119
this.source = pushable()
120
121
const duplexSocket = duplex(socket)
packages/libp2p-inspector/test/fixtures/get-libp2p.ts
+4
-4
@@ -1,11 +1,10 @@
1
import { inspectorMetrics } from '@ipshipyard/libp2p-inspector-metrics'
2
-import { mergeOptions } from '@libp2p/utils/merge-options'
2
import { webRTCDirect } from '@libp2p/webrtc'
3
import { createLibp2p } from 'libp2p'
4
import type { Libp2p, Libp2pOptions } from 'libp2p'
5
6
export function getLibp2p (config: Libp2pOptions = {}): Promise<Libp2p> {
8
- return createLibp2p(mergeOptions({
7
+ return createLibp2p({
8
metrics: inspectorMetrics(),
9
addresses: {
10
listen: [
@@ -14,6 +13,7 @@ export function getLibp2p (config: Libp2pOptions = {}): Promise<Libp2p> {
13
},
14
transports: [
15
webRTCDirect()
17
- ]
18
- }, config))
16
+ ],
17
+ ...config
18
+ })
19
}