libp2p 0.44.0 → 0.45.0

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.
Files changed (188) hide show
  1. package/dist/index.min.js +30 -30
  2. package/dist/src/address-manager/index.d.ts +8 -4
  3. package/dist/src/address-manager/index.d.ts.map +1 -1
  4. package/dist/src/address-manager/index.js +37 -6
  5. package/dist/src/address-manager/index.js.map +1 -1
  6. package/dist/src/address-manager/utils.d.ts +2 -0
  7. package/dist/src/address-manager/utils.d.ts.map +1 -0
  8. package/dist/src/address-manager/utils.js +12 -0
  9. package/dist/src/address-manager/utils.js.map +1 -0
  10. package/dist/src/autonat/constants.d.ts +16 -2
  11. package/dist/src/autonat/constants.d.ts.map +1 -1
  12. package/dist/src/autonat/constants.js +16 -2
  13. package/dist/src/autonat/constants.js.map +1 -1
  14. package/dist/src/autonat/index.d.ts +12 -33
  15. package/dist/src/autonat/index.d.ts.map +1 -1
  16. package/dist/src/autonat/index.js +36 -30
  17. package/dist/src/autonat/index.js.map +1 -1
  18. package/dist/src/circuit-relay/server/advert-service.d.ts.map +1 -1
  19. package/dist/src/circuit-relay/server/advert-service.js +2 -2
  20. package/dist/src/circuit-relay/server/advert-service.js.map +1 -1
  21. package/dist/src/circuit-relay/server/index.d.ts.map +1 -1
  22. package/dist/src/circuit-relay/server/index.js +10 -3
  23. package/dist/src/circuit-relay/server/index.js.map +1 -1
  24. package/dist/src/circuit-relay/transport/discovery.d.ts.map +1 -1
  25. package/dist/src/circuit-relay/transport/discovery.js +4 -2
  26. package/dist/src/circuit-relay/transport/discovery.js.map +1 -1
  27. package/dist/src/circuit-relay/transport/index.d.ts +3 -0
  28. package/dist/src/circuit-relay/transport/index.d.ts.map +1 -1
  29. package/dist/src/circuit-relay/transport/index.js +6 -4
  30. package/dist/src/circuit-relay/transport/index.js.map +1 -1
  31. package/dist/src/circuit-relay/transport/listener.d.ts.map +1 -1
  32. package/dist/src/circuit-relay/transport/listener.js +30 -26
  33. package/dist/src/circuit-relay/transport/listener.js.map +1 -1
  34. package/dist/src/circuit-relay/transport/reservation-store.d.ts +5 -4
  35. package/dist/src/circuit-relay/transport/reservation-store.d.ts.map +1 -1
  36. package/dist/src/circuit-relay/transport/reservation-store.js +37 -30
  37. package/dist/src/circuit-relay/transport/reservation-store.js.map +1 -1
  38. package/dist/src/components.d.ts +6 -63
  39. package/dist/src/components.d.ts.map +1 -1
  40. package/dist/src/components.js +60 -164
  41. package/dist/src/components.js.map +1 -1
  42. package/dist/src/config/connection-gater.browser.d.ts +8 -0
  43. package/dist/src/config/connection-gater.browser.d.ts.map +1 -0
  44. package/dist/src/config/connection-gater.browser.js +27 -0
  45. package/dist/src/config/connection-gater.browser.js.map +1 -0
  46. package/dist/src/config/connection-gater.d.ts +6 -0
  47. package/dist/src/config/connection-gater.d.ts.map +1 -0
  48. package/dist/src/config/connection-gater.js +18 -0
  49. package/dist/src/config/connection-gater.js.map +1 -0
  50. package/dist/src/config.d.ts +2 -1
  51. package/dist/src/config.d.ts.map +1 -1
  52. package/dist/src/config.js +0 -62
  53. package/dist/src/config.js.map +1 -1
  54. package/dist/src/connection-manager/auto-dial.d.ts +3 -0
  55. package/dist/src/connection-manager/auto-dial.d.ts.map +1 -1
  56. package/dist/src/connection-manager/auto-dial.js +36 -13
  57. package/dist/src/connection-manager/auto-dial.js.map +1 -1
  58. package/dist/src/connection-manager/connection-pruner.d.ts +4 -0
  59. package/dist/src/connection-manager/connection-pruner.d.ts.map +1 -1
  60. package/dist/src/connection-manager/connection-pruner.js +23 -8
  61. package/dist/src/connection-manager/connection-pruner.js.map +1 -1
  62. package/dist/src/connection-manager/dial-queue.d.ts +2 -1
  63. package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
  64. package/dist/src/connection-manager/dial-queue.js +36 -14
  65. package/dist/src/connection-manager/dial-queue.js.map +1 -1
  66. package/dist/src/connection-manager/index.d.ts +8 -7
  67. package/dist/src/connection-manager/index.d.ts.map +1 -1
  68. package/dist/src/connection-manager/index.js +23 -34
  69. package/dist/src/connection-manager/index.js.map +1 -1
  70. package/dist/src/content-routing/index.d.ts +0 -10
  71. package/dist/src/content-routing/index.d.ts.map +1 -1
  72. package/dist/src/content-routing/index.js +7 -42
  73. package/dist/src/content-routing/index.js.map +1 -1
  74. package/dist/src/content-routing/utils.d.ts.map +1 -1
  75. package/dist/src/content-routing/utils.js +3 -1
  76. package/dist/src/content-routing/utils.js.map +1 -1
  77. package/dist/src/fetch/index.d.ts +13 -35
  78. package/dist/src/fetch/index.d.ts.map +1 -1
  79. package/dist/src/fetch/index.js +7 -9
  80. package/dist/src/fetch/index.js.map +1 -1
  81. package/dist/src/identify/identify.d.ts +53 -0
  82. package/dist/src/identify/identify.d.ts.map +1 -0
  83. package/dist/src/identify/identify.js +405 -0
  84. package/dist/src/identify/identify.js.map +1 -0
  85. package/dist/src/identify/index.d.ts +12 -58
  86. package/dist/src/identify/index.d.ts.map +1 -1
  87. package/dist/src/identify/index.js +5 -388
  88. package/dist/src/identify/index.js.map +1 -1
  89. package/dist/src/index.d.ts +13 -68
  90. package/dist/src/index.d.ts.map +1 -1
  91. package/dist/src/index.js +2 -1
  92. package/dist/src/index.js.map +1 -1
  93. package/dist/src/insecure/index.js.map +1 -1
  94. package/dist/src/libp2p.d.ts +11 -42
  95. package/dist/src/libp2p.d.ts.map +1 -1
  96. package/dist/src/libp2p.js +137 -196
  97. package/dist/src/libp2p.js.map +1 -1
  98. package/dist/src/peer-routing.d.ts +1 -38
  99. package/dist/src/peer-routing.d.ts.map +1 -1
  100. package/dist/src/peer-routing.js +0 -59
  101. package/dist/src/peer-routing.js.map +1 -1
  102. package/dist/src/ping/constants.d.ts +4 -0
  103. package/dist/src/ping/constants.d.ts.map +1 -1
  104. package/dist/src/ping/constants.js +10 -0
  105. package/dist/src/ping/constants.js.map +1 -1
  106. package/dist/src/ping/index.d.ts +10 -27
  107. package/dist/src/ping/index.d.ts.map +1 -1
  108. package/dist/src/ping/index.js +18 -21
  109. package/dist/src/ping/index.js.map +1 -1
  110. package/dist/src/registrar.d.ts +5 -2
  111. package/dist/src/registrar.d.ts.map +1 -1
  112. package/dist/src/registrar.js +27 -25
  113. package/dist/src/registrar.js.map +1 -1
  114. package/dist/src/transport-manager.d.ts +11 -4
  115. package/dist/src/transport-manager.d.ts.map +1 -1
  116. package/dist/src/transport-manager.js +19 -10
  117. package/dist/src/transport-manager.js.map +1 -1
  118. package/dist/src/upgrader.d.ts +15 -10
  119. package/dist/src/upgrader.d.ts.map +1 -1
  120. package/dist/src/upgrader.js +39 -48
  121. package/dist/src/upgrader.js.map +1 -1
  122. package/dist/src/upnp-nat/index.d.ts +42 -0
  123. package/dist/src/upnp-nat/index.d.ts.map +1 -0
  124. package/dist/src/{nat-manager.js → upnp-nat/index.js} +11 -7
  125. package/dist/src/upnp-nat/index.js.map +1 -0
  126. package/dist/src/version.d.ts +1 -1
  127. package/dist/src/version.d.ts.map +1 -1
  128. package/dist/src/version.js +1 -1
  129. package/dist/src/version.js.map +1 -1
  130. package/dist/typedoc-urls.json +25 -10
  131. package/package.json +61 -45
  132. package/src/address-manager/index.ts +50 -8
  133. package/src/address-manager/utils.ts +14 -0
  134. package/src/autonat/constants.ts +17 -2
  135. package/src/autonat/index.ts +53 -45
  136. package/src/circuit-relay/server/advert-service.ts +2 -2
  137. package/src/circuit-relay/server/index.ts +11 -3
  138. package/src/circuit-relay/transport/discovery.ts +5 -3
  139. package/src/circuit-relay/transport/index.ts +9 -4
  140. package/src/circuit-relay/transport/listener.ts +38 -28
  141. package/src/circuit-relay/transport/reservation-store.ts +34 -20
  142. package/src/components.ts +71 -234
  143. package/src/config/connection-gater.browser.ts +31 -0
  144. package/src/config/connection-gater.ts +19 -0
  145. package/src/config.ts +3 -64
  146. package/src/connection-manager/auto-dial.ts +44 -15
  147. package/src/connection-manager/connection-pruner.ts +28 -8
  148. package/src/connection-manager/dial-queue.ts +41 -21
  149. package/src/connection-manager/index.ts +31 -43
  150. package/src/content-routing/index.ts +7 -55
  151. package/src/content-routing/utils.ts +3 -1
  152. package/src/fetch/index.ts +51 -14
  153. package/src/identify/identify.ts +518 -0
  154. package/src/identify/index.ts +17 -507
  155. package/src/index.ts +14 -77
  156. package/src/insecure/index.ts +4 -4
  157. package/src/libp2p.ts +139 -260
  158. package/src/peer-routing.ts +1 -101
  159. package/src/ping/constants.ts +11 -0
  160. package/src/ping/index.ts +32 -28
  161. package/src/registrar.ts +31 -27
  162. package/src/transport-manager.ts +27 -13
  163. package/src/upgrader.ts +62 -58
  164. package/src/{nat-manager.ts → upnp-nat/index.ts} +16 -17
  165. package/src/version.ts +1 -1
  166. package/dist/src/dht/dht-content-routing.d.ts +0 -17
  167. package/dist/src/dht/dht-content-routing.d.ts.map +0 -1
  168. package/dist/src/dht/dht-content-routing.js +0 -32
  169. package/dist/src/dht/dht-content-routing.js.map +0 -1
  170. package/dist/src/dht/dht-peer-routing.d.ts +0 -15
  171. package/dist/src/dht/dht-peer-routing.d.ts.map +0 -1
  172. package/dist/src/dht/dht-peer-routing.js +0 -26
  173. package/dist/src/dht/dht-peer-routing.js.map +0 -1
  174. package/dist/src/dht/dummy-dht.d.ts +0 -20
  175. package/dist/src/dht/dummy-dht.d.ts.map +0 -1
  176. package/dist/src/dht/dummy-dht.js +0 -46
  177. package/dist/src/dht/dummy-dht.js.map +0 -1
  178. package/dist/src/nat-manager.d.ts +0 -74
  179. package/dist/src/nat-manager.d.ts.map +0 -1
  180. package/dist/src/nat-manager.js.map +0 -1
  181. package/dist/src/peer-record-updater.d.ts +0 -24
  182. package/dist/src/peer-record-updater.d.ts.map +0 -1
  183. package/dist/src/peer-record-updater.js +0 -44
  184. package/dist/src/peer-record-updater.js.map +0 -1
  185. package/src/dht/dht-content-routing.ts +0 -44
  186. package/src/dht/dht-peer-routing.ts +0 -36
  187. package/src/dht/dummy-dht.ts +0 -60
  188. package/src/peer-record-updater.ts +0 -65
package/src/libp2p.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { logger } from '@libp2p/logger'
2
2
  import type { AbortOptions } from '@libp2p/interfaces'
3
3
  import { EventEmitter, CustomEvent } from '@libp2p/interfaces/events'
4
- import { Startable, isStartable } from '@libp2p/interfaces/startable'
5
4
  import { isMultiaddr, Multiaddr } from '@multiformats/multiaddr'
6
5
  import { MemoryDatastore } from 'datastore-core/memory'
7
6
  import { DefaultPeerRouting } from './peer-routing.js'
@@ -13,251 +12,195 @@ import { DefaultKeyChain } from '@libp2p/keychain'
13
12
  import { DefaultTransportManager } from './transport-manager.js'
14
13
  import { DefaultUpgrader } from './upgrader.js'
15
14
  import { DefaultRegistrar } from './registrar.js'
16
- import { IdentifyService } from './identify/index.js'
17
- import { FetchService } from './fetch/index.js'
18
- import { PingService } from './ping/index.js'
19
- import { NatManager } from './nat-manager.js'
20
- import { PeerRecordUpdater } from './peer-record-updater.js'
21
- import { DHTPeerRouting } from './dht/dht-peer-routing.js'
22
15
  import { PersistentPeerStore } from '@libp2p/peer-store'
23
- import { DHTContentRouting } from './dht/dht-content-routing.js'
24
- import { AutonatService } from './autonat/index.js'
25
- import { DefaultComponents } from './components.js'
16
+ import { defaultComponents } from './components.js'
26
17
  import type { Components } from './components.js'
27
18
  import type { PeerId } from '@libp2p/interface-peer-id'
28
19
  import type { Connection, Stream } from '@libp2p/interface-connection'
29
- import type { PeerRouting } from '@libp2p/interface-peer-routing'
30
- import type { ContentRouting } from '@libp2p/interface-content-routing'
31
- import type { PubSub } from '@libp2p/interface-pubsub'
32
- import type { Registrar, StreamHandler, StreamHandlerOptions, Topology } from '@libp2p/interface-registrar'
33
- import type { ConnectionManager } from '@libp2p/interface-connection-manager'
20
+ import type { StreamHandler, StreamHandlerOptions, Topology } from '@libp2p/interface-registrar'
34
21
  import type { PeerInfo } from '@libp2p/interface-peer-info'
35
- import type { Libp2p, Libp2pEvents, Libp2pInit, Libp2pOptions } from './index.js'
36
- import { validateConfig } from './config.js'
37
- import { createEd25519PeerId } from '@libp2p/peer-id-factory'
22
+ import type { Libp2p, Libp2pInit, Libp2pOptions } from './index.js'
38
23
  import type { PeerStore } from '@libp2p/interface-peer-store'
39
- import type { DualDHT } from '@libp2p/interface-dht'
40
24
  import { concat as uint8ArrayConcat } from 'uint8arrays/concat'
41
25
  import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
42
26
  import { CodeError } from '@libp2p/interfaces/errors'
43
- import { unmarshalPublicKey } from '@libp2p/crypto/keys'
44
27
  import type { Metrics } from '@libp2p/interface-metrics'
45
- import { DummyDHT } from './dht/dummy-dht.js'
46
- import { DummyPubSub } from './pubsub/dummy-pubsub.js'
47
28
  import { PeerSet } from '@libp2p/peer-collections'
29
+ import type { KeyChain } from '@libp2p/interface-keychain'
30
+ import type { Libp2pEvents, PendingDial, ServiceMap } from '@libp2p/interface-libp2p'
31
+ import { setMaxListeners } from 'events'
32
+ import { unmarshalPublicKey } from '@libp2p/crypto/keys'
48
33
  import { peerIdFromString } from '@libp2p/peer-id'
49
34
  import type { Datastore } from 'interface-datastore'
50
- import type { KeyChain } from '@libp2p/interface-keychain'
51
35
  import mergeOptions from 'merge-options'
52
- import type { CircuitRelayService } from './circuit-relay/index.js'
36
+ import { createEd25519PeerId } from '@libp2p/peer-id-factory'
37
+ import { validateConfig } from './config.js'
38
+ import { ContentRouting, contentRouting } from '@libp2p/interface-content-routing'
39
+ import { PeerRouting, peerRouting } from '@libp2p/interface-peer-routing'
40
+ import { peerDiscovery } from '@libp2p/interface-peer-discovery'
41
+ import { connectionGater } from './config/connection-gater.js'
53
42
 
54
43
  const log = logger('libp2p')
55
44
 
56
- export type PendingDialStatus = 'queued' | 'active' | 'error' | 'success'
57
-
58
- export interface PendingDial {
59
- id: string
60
- status: PendingDialStatus
61
- peerId?: PeerId
62
- multiaddrs: Multiaddr[]
63
- }
64
-
65
- export class Libp2pNode extends EventEmitter<Libp2pEvents> implements Libp2p {
45
+ export class Libp2pNode<T extends ServiceMap = {}> extends EventEmitter<Libp2pEvents> implements Libp2p<T> {
66
46
  public peerId: PeerId
67
- public dht: DualDHT
68
- public pubsub: PubSub
69
- public identifyService: IdentifyService
70
- public circuitService?: CircuitRelayService
71
- public fetchService: FetchService
72
- public pingService: PingService
73
- public autonatService: AutonatService
74
- public components: Components
75
47
  public peerStore: PeerStore
76
48
  public contentRouting: ContentRouting
77
49
  public peerRouting: PeerRouting
78
50
  public keychain: KeyChain
79
- public connectionManager: ConnectionManager
80
- public registrar: Registrar
81
51
  public metrics?: Metrics
52
+ public services: T
82
53
 
83
- private started: boolean
84
- private readonly services: Startable[]
54
+ public components: Components
55
+ #started: boolean
85
56
 
86
- constructor (init: Libp2pInit) {
57
+ constructor (init: Libp2pInit<T>) {
87
58
  super()
88
59
 
89
- this.started = false
60
+ // event bus - components can listen to this emitter to be notified of system events
61
+ // and also cause them to be emitted
62
+ const events = new EventEmitter<Libp2pEvents>()
63
+ const originalDispatch = events.dispatchEvent.bind(events)
64
+ events.dispatchEvent = (evt: any) => {
65
+ const internalResult = originalDispatch(evt)
66
+ const externalResult = this.dispatchEvent(
67
+ new CustomEvent(evt.type, { detail: evt.detail })
68
+ )
69
+
70
+ return internalResult || externalResult
71
+ }
72
+
73
+ try {
74
+ // This emitter gets listened to a lot
75
+ setMaxListeners?.(Infinity, events)
76
+ } catch {}
77
+
78
+ this.#started = false
90
79
  this.peerId = init.peerId
91
- const components = this.components = new DefaultComponents({
80
+ // @ts-expect-error {} may not be of type T
81
+ this.services = {}
82
+ const components = this.components = defaultComponents({
92
83
  peerId: init.peerId,
84
+ events,
93
85
  datastore: init.datastore ?? new MemoryDatastore(),
94
- connectionGater: {
95
- denyDialPeer: async () => await Promise.resolve(false),
96
- denyDialMultiaddr: async () => await Promise.resolve(false),
97
- denyInboundConnection: async () => await Promise.resolve(false),
98
- denyOutboundConnection: async () => await Promise.resolve(false),
99
- denyInboundEncryptedConnection: async () => await Promise.resolve(false),
100
- denyOutboundEncryptedConnection: async () => await Promise.resolve(false),
101
- denyInboundUpgradedConnection: async () => await Promise.resolve(false),
102
- denyOutboundUpgradedConnection: async () => await Promise.resolve(false),
103
- filterMultiaddrForPeer: async () => await Promise.resolve(true),
104
- ...init.connectionGater
105
- }
86
+ connectionGater: connectionGater(init.connectionGater)
106
87
  })
107
- components.peerStore = new PersistentPeerStore(components, {
88
+
89
+ this.peerStore = this.configureComponent('peerStore', new PersistentPeerStore(components, {
108
90
  addressFilter: this.components.connectionGater.filterMultiaddrForPeer,
109
91
  ...init.peerStore
110
- })
111
-
112
- this.services = [
113
- components
114
- ]
92
+ }))
115
93
 
116
94
  // Create Metrics
117
95
  if (init.metrics != null) {
118
- this.metrics = this.components.metrics = this.configureComponent(init.metrics(this.components))
96
+ this.metrics = this.configureComponent('metrics', init.metrics(this.components))
119
97
  }
120
98
 
121
- this.peerStore = this.components.peerStore
122
-
123
- this.peerStore.addEventListener('peer', evt => {
124
- const { detail: peerData } = evt
125
-
126
- this.dispatchEvent(new CustomEvent<PeerInfo>('peer:discovery', { detail: peerData }))
99
+ components.events.addEventListener('peer:update', evt => {
100
+ // if there was no peer previously in the peer store this is a new peer
101
+ if (evt.detail.previous == null) {
102
+ this.safeDispatchEvent('peer:discovery', { detail: evt.detail.peer })
103
+ }
127
104
  })
128
105
 
129
106
  // Set up connection protector if configured
130
107
  if (init.connectionProtector != null) {
131
- this.components.connectionProtector = init.connectionProtector(components)
108
+ this.configureComponent('connectionProtector', init.connectionProtector(components))
132
109
  }
133
110
 
134
111
  // Set up the Upgrader
135
112
  this.components.upgrader = new DefaultUpgrader(this.components, {
136
- connectionEncryption: (init.connectionEncryption ?? []).map(fn => this.configureComponent(fn(this.components))),
137
- muxers: (init.streamMuxers ?? []).map(fn => this.configureComponent(fn(this.components))),
113
+ connectionEncryption: (init.connectionEncryption ?? []).map((fn, index) => this.configureComponent(`connection-encryption-${index}`, fn(this.components))),
114
+ muxers: (init.streamMuxers ?? []).map((fn, index) => this.configureComponent(`stream-muxers-${index}`, fn(this.components))),
138
115
  inboundUpgradeTimeout: init.connectionManager.inboundUpgradeTimeout
139
116
  })
140
117
 
141
118
  // Setup the transport manager
142
- this.components.transportManager = new DefaultTransportManager(this.components, init.transportManager)
119
+ this.configureComponent('transportManager', new DefaultTransportManager(this.components, init.transportManager))
143
120
 
144
121
  // Create the Connection Manager
145
- this.connectionManager = this.components.connectionManager = new DefaultConnectionManager(this.components, init.connectionManager)
146
-
147
- // forward connection manager events
148
- this.components.connectionManager.addEventListener('peer:disconnect', (event) => {
149
- this.dispatchEvent(new CustomEvent<Connection>('peer:disconnect', { detail: event.detail }))
150
- })
151
- this.components.connectionManager.addEventListener('peer:connect', (event) => {
152
- this.dispatchEvent(new CustomEvent<Connection>('peer:connect', { detail: event.detail }))
153
- })
122
+ this.configureComponent('connectionManager', new DefaultConnectionManager(this.components, init.connectionManager))
154
123
 
155
124
  // Create the Registrar
156
- this.registrar = this.components.registrar = new DefaultRegistrar(this.components)
125
+ this.configureComponent('registrar', new DefaultRegistrar(this.components))
157
126
 
158
127
  // Addresses {listen, announce, noAnnounce}
159
- this.components.addressManager = new DefaultAddressManager(this.components, init.addresses)
160
-
161
- // update our peer record when addresses change
162
- this.configureComponent(new PeerRecordUpdater(this.components))
128
+ this.configureComponent('addressManager', new DefaultAddressManager(this.components, init.addresses))
163
129
 
164
130
  // Create keychain
165
131
  const keychainOpts = DefaultKeyChain.generateOptions()
166
- this.keychain = this.configureComponent(new DefaultKeyChain(this.components, {
132
+ this.keychain = this.configureComponent('keyChain', new DefaultKeyChain(this.components, {
167
133
  ...keychainOpts,
168
134
  ...init.keychain
169
135
  }))
170
136
 
171
- // Create the Nat Manager
172
- this.services.push(new NatManager(this.components, init.nat))
173
-
174
- // Add the identify service
175
- this.identifyService = new IdentifyService(this.components, {
176
- ...init.identify
177
- })
178
- this.configureComponent(this.identifyService)
179
-
180
- // dht provided components (peerRouting, contentRouting, dht)
181
- if (init.dht != null) {
182
- this.dht = this.components.dht = init.dht(this.components)
183
- } else {
184
- this.dht = new DummyDHT()
185
- }
186
-
187
- // Create pubsub if provided
188
- if (init.pubsub != null) {
189
- this.pubsub = this.components.pubsub = init.pubsub(this.components)
190
- } else {
191
- this.pubsub = new DummyPubSub()
192
- }
193
-
194
- // Attach remaining APIs
195
- // peer and content routing will automatically get modules from _modules and _dht
196
-
197
- const peerRouters: PeerRouting[] = (init.peerRouters ?? []).map(fn => this.configureComponent(fn(this.components)))
198
-
199
- if (init.dht != null) {
200
- // add dht to routers
201
- peerRouters.push(this.configureComponent(new DHTPeerRouting(this.dht)))
202
-
203
- // use dht for peer discovery
204
- this.dht.addEventListener('peer', (evt) => {
205
- this.onDiscoveryPeer(evt)
206
- })
207
- }
208
-
209
- this.peerRouting = this.components.peerRouting = this.configureComponent(new DefaultPeerRouting(this.components, {
210
- ...init.peerRouting,
137
+ // Peer routers
138
+ const peerRouters: PeerRouting[] = (init.peerRouters ?? []).map((fn, index) => this.configureComponent(`peer-router-${index}`, fn(this.components)))
139
+ this.peerRouting = this.components.peerRouting = this.configureComponent('peerRouting', new DefaultPeerRouting(this.components, {
211
140
  routers: peerRouters
212
141
  }))
213
142
 
214
- const contentRouters: ContentRouting[] = (init.contentRouters ?? []).map(fn => this.configureComponent(fn(this.components)))
215
-
216
- if (init.dht != null) {
217
- // add dht to routers
218
- contentRouters.push(this.configureComponent(new DHTContentRouting(this.dht)))
219
- }
220
-
221
- this.contentRouting = this.components.contentRouting = this.configureComponent(new CompoundContentRouting(this.components, {
143
+ // Content routers
144
+ const contentRouters: ContentRouting[] = (init.contentRouters ?? []).map((fn, index) => this.configureComponent(`content-router-${index}`, fn(this.components)))
145
+ this.contentRouting = this.components.contentRouting = this.configureComponent('contentRouting', new CompoundContentRouting(this.components, {
222
146
  routers: contentRouters
223
147
  }))
224
148
 
225
- this.fetchService = this.configureComponent(new FetchService(this.components, {
226
- ...init.fetch
227
- }))
228
-
229
- this.pingService = this.configureComponent(new PingService(this.components, {
230
- ...init.ping
231
- }))
232
-
233
- this.autonatService = this.configureComponent(new AutonatService(this.components, {
234
- ...init.autonat
235
- }))
236
-
237
- if (init.relay != null) {
238
- this.circuitService = this.configureComponent(init.relay(this.components))
239
- }
240
-
241
149
  // Discovery modules
242
- for (const fn of init.peerDiscovery ?? []) {
243
- const service = this.configureComponent(fn(this.components))
150
+ ;(init.peerDiscovery ?? []).forEach((fn, index) => {
151
+ const service = this.configureComponent(`peer-discovery-${index}`, fn(this.components))
244
152
 
245
153
  service.addEventListener('peer', (evt) => {
246
- this.onDiscoveryPeer(evt)
154
+ this.#onDiscoveryPeer(evt)
247
155
  })
248
- }
156
+ })
249
157
 
250
158
  // Transport modules
251
- init.transports.forEach((fn) => {
252
- this.components.transportManager.add(this.configureComponent(fn(this.components)))
159
+ init.transports.forEach((fn, index) => {
160
+ this.components.transportManager.add(this.configureComponent(`transport-${index}`, fn(this.components)))
253
161
  })
162
+
163
+ // User defined modules
164
+ if (init.services != null) {
165
+ for (const name of Object.keys(init.services)) {
166
+ const createService = init.services[name]
167
+ const service: any = createService(this.components)
168
+
169
+ if (service == null) {
170
+ log.error('service factory %s returned null or undefined instance', name)
171
+ continue
172
+ }
173
+
174
+ this.services[name as keyof T] = service
175
+ this.configureComponent(name, service)
176
+
177
+ if (service[contentRouting] != null) {
178
+ log('registering service %s for content routing', name)
179
+ contentRouters.push(service[contentRouting])
180
+ }
181
+
182
+ if (service[peerRouting] != null) {
183
+ log('registering service %s for peer routing', name)
184
+ peerRouters.push(service[peerRouting])
185
+ }
186
+
187
+ if (service[peerDiscovery] != null) {
188
+ log('registering service %s for peer discovery', name)
189
+ service[peerDiscovery].addEventListener('peer', (evt: CustomEvent<PeerInfo>) => {
190
+ this.#onDiscoveryPeer(evt)
191
+ })
192
+ }
193
+ }
194
+ }
254
195
  }
255
196
 
256
- private configureComponent <T> (component: T): T {
257
- if (isStartable(component)) {
258
- this.services.push(component)
197
+ private configureComponent <T> (name: string, component: T): T {
198
+ if (component == null) {
199
+ log.error('component %s was null or undefined', name)
259
200
  }
260
201
 
202
+ this.components[name] = component
203
+
261
204
  return component
262
205
  }
263
206
 
@@ -265,11 +208,11 @@ export class Libp2pNode extends EventEmitter<Libp2pEvents> implements Libp2p {
265
208
  * Starts the libp2p node and all its subsystems
266
209
  */
267
210
  async start (): Promise<void> {
268
- if (this.started) {
211
+ if (this.#started) {
269
212
  return
270
213
  }
271
214
 
272
- this.started = true
215
+ this.#started = true
273
216
 
274
217
  log('libp2p is starting')
275
218
 
@@ -281,27 +224,9 @@ export class Libp2pNode extends EventEmitter<Libp2pEvents> implements Libp2p {
281
224
  }
282
225
 
283
226
  try {
284
- await Promise.all(
285
- this.services.map(async service => {
286
- if (service.beforeStart != null) {
287
- await service.beforeStart()
288
- }
289
- })
290
- )
291
-
292
- // start any startables
293
- await Promise.all(
294
- this.services.map(async service => { await service.start() })
295
- )
296
-
297
- await Promise.all(
298
- this.services.map(async service => {
299
- if (service.afterStart != null) {
300
- await service.afterStart()
301
- }
302
- })
303
- )
304
-
227
+ await this.components.beforeStart?.()
228
+ await this.components.start()
229
+ await this.components.afterStart?.()
305
230
  log('libp2p has started')
306
231
  } catch (err: any) {
307
232
  log.error('An error occurred starting libp2p', err)
@@ -314,39 +239,23 @@ export class Libp2pNode extends EventEmitter<Libp2pEvents> implements Libp2p {
314
239
  * Stop the libp2p node by closing its listeners and open connections
315
240
  */
316
241
  async stop (): Promise<void> {
317
- if (!this.started) {
242
+ if (!this.#started) {
318
243
  return
319
244
  }
320
245
 
321
246
  log('libp2p is stopping')
322
247
 
323
- this.started = false
324
-
325
- await Promise.all(
326
- this.services.map(async service => {
327
- if (service.beforeStop != null) {
328
- await service.beforeStop()
329
- }
330
- })
331
- )
332
-
333
- await Promise.all(
334
- this.services.map(async service => { await service.stop() })
335
- )
248
+ this.#started = false
336
249
 
337
- await Promise.all(
338
- this.services.map(async service => {
339
- if (service.afterStop != null) {
340
- await service.afterStop()
341
- }
342
- })
343
- )
250
+ await this.components.beforeStop?.()
251
+ await this.components.stop()
252
+ await this.components.afterStop?.()
344
253
 
345
254
  log('libp2p has stopped')
346
255
  }
347
256
 
348
257
  isStarted (): boolean {
349
- return this.started
258
+ return this.#started
350
259
  }
351
260
 
352
261
  getConnections (peerId?: PeerId): Connection[] {
@@ -415,12 +324,8 @@ export class Libp2pNode extends EventEmitter<Libp2pEvents> implements Libp2p {
415
324
 
416
325
  const peerInfo = await this.peerStore.get(peer)
417
326
 
418
- if (peerInfo.pubKey != null) {
419
- return peerInfo.pubKey
420
- }
421
-
422
- if (this.dht == null) {
423
- throw new CodeError('Public key was not in the peer store and the DHT is not enabled', codes.ERR_NO_ROUTERS_AVAILABLE)
327
+ if (peerInfo.id.publicKey != null) {
328
+ return peerInfo.id.publicKey
424
329
  }
425
330
 
426
331
  const peerKey = uint8ArrayConcat([
@@ -428,38 +333,16 @@ export class Libp2pNode extends EventEmitter<Libp2pEvents> implements Libp2p {
428
333
  peer.multihash.digest
429
334
  ])
430
335
 
431
- // search the dht
432
- for await (const event of this.dht.get(peerKey, options)) {
433
- if (event.name === 'VALUE') {
434
- const key = unmarshalPublicKey(event.value)
435
-
436
- await this.peerStore.keyBook.set(peer, event.value)
437
-
438
- return key.bytes
439
- }
440
- }
441
-
442
- throw new CodeError(`Node not responding with its public key: ${peer.toString()}`, codes.ERR_INVALID_RECORD)
443
- }
336
+ // search any available content routing methods
337
+ const bytes = await this.contentRouting.get(peerKey, options)
338
+ // ensure the returned key is valid
339
+ unmarshalPublicKey(bytes)
444
340
 
445
- async fetch (peer: PeerId | Multiaddr, key: string, options: AbortOptions = {}): Promise<Uint8Array | null> {
446
- if (isMultiaddr(peer)) {
447
- const peerId = peerIdFromString(peer.getPeerId() ?? '')
448
- await this.components.peerStore.addressBook.add(peerId, [peer])
449
- peer = peerId
450
- }
451
-
452
- return await this.fetchService.fetch(peer, key, options)
453
- }
454
-
455
- async ping (peer: PeerId | Multiaddr, options: AbortOptions = {}): Promise<number> {
456
- if (isMultiaddr(peer)) {
457
- const peerId = peerIdFromString(peer.getPeerId() ?? '')
458
- await this.components.peerStore.addressBook.add(peerId, [peer])
459
- peer = peerId
460
- }
341
+ await this.peerStore.patch(peer, {
342
+ publicKey: bytes
343
+ })
461
344
 
462
- return await this.pingService.ping(peer, options)
345
+ return bytes
463
346
  }
464
347
 
465
348
  async handle (protocols: string | string[], handler: StreamHandler, options?: StreamHandlerOptions): Promise<void> {
@@ -487,18 +370,18 @@ export class Libp2pNode extends EventEmitter<Libp2pEvents> implements Libp2p {
487
370
  }
488
371
 
489
372
  async register (protocol: string, topology: Topology): Promise<string> {
490
- return await this.registrar.register(protocol, topology)
373
+ return await this.components.registrar.register(protocol, topology)
491
374
  }
492
375
 
493
376
  unregister (id: string): void {
494
- this.registrar.unregister(id)
377
+ this.components.registrar.unregister(id)
495
378
  }
496
379
 
497
380
  /**
498
381
  * Called whenever peer discovery services emit `peer` events and adds peers
499
382
  * to the peer store.
500
383
  */
501
- onDiscoveryPeer (evt: CustomEvent<PeerInfo>): void {
384
+ #onDiscoveryPeer (evt: CustomEvent<PeerInfo>): void {
502
385
  const { detail: peer } = evt
503
386
 
504
387
  if (peer.id.toString() === this.peerId.toString()) {
@@ -506,15 +389,11 @@ export class Libp2pNode extends EventEmitter<Libp2pEvents> implements Libp2p {
506
389
  return
507
390
  }
508
391
 
509
- if (peer.multiaddrs.length > 0) {
510
- void this.components.peerStore.addressBook.add(peer.id, peer.multiaddrs).catch(err => { log.error(err) })
511
- }
512
-
513
- if (peer.protocols.length > 0) {
514
- void this.components.peerStore.protoBook.set(peer.id, peer.protocols).catch(err => { log.error(err) })
515
- }
516
-
517
- this.dispatchEvent(new CustomEvent<PeerInfo>('peer:discovery', { detail: peer }))
392
+ void this.components.peerStore.merge(peer.id, {
393
+ multiaddrs: peer.multiaddrs,
394
+ protocols: peer.protocols
395
+ })
396
+ .catch(err => { log.error(err) })
518
397
  }
519
398
  }
520
399
 
@@ -522,7 +401,7 @@ export class Libp2pNode extends EventEmitter<Libp2pEvents> implements Libp2p {
522
401
  * Returns a new Libp2pNode instance - this exposes more of the internals than the
523
402
  * libp2p interface and is useful for testing and debugging.
524
403
  */
525
- export async function createLibp2pNode (options: Libp2pOptions): Promise<Libp2pNode> {
404
+ export async function createLibp2pNode <T extends ServiceMap = {}> (options: Libp2pOptions<T>): Promise<Libp2pNode<T>> {
526
405
  if (options.peerId == null) {
527
406
  const datastore = options.datastore as Datastore | undefined
528
407