@libp2p/identify 1.0.21-9d13a2f6a → 1.0.21
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 +1 -24
- package/dist/index.min.js +3 -3
- package/dist/src/consts.d.ts +0 -2
- package/dist/src/consts.d.ts.map +1 -1
- package/dist/src/consts.js +0 -4
- package/dist/src/consts.js.map +1 -1
- package/dist/src/identify.d.ts +40 -3
- package/dist/src/identify.d.ts.map +1 -1
- package/dist/src/identify.js +334 -14
- package/dist/src/identify.js.map +1 -1
- package/dist/src/index.d.ts +17 -75
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +9 -28
- package/dist/src/index.js.map +1 -1
- package/dist/typedoc-urls.json +12 -0
- package/package.json +9 -10
- package/src/consts.ts +0 -6
- package/src/identify.ts +404 -16
- package/src/index.ts +20 -81
- package/dist/src/identify-push.d.ts +0 -18
- package/dist/src/identify-push.d.ts.map +0 -1
- package/dist/src/identify-push.js +0 -120
- package/dist/src/identify-push.js.map +0 -1
- package/dist/src/utils.d.ts +0 -53
- package/dist/src/utils.d.ts.map +0 -1
- package/dist/src/utils.js +0 -217
- package/dist/src/utils.js.map +0 -1
- package/src/identify-push.ts +0 -146
- package/src/utils.ts +0 -273
package/src/utils.ts
DELETED
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
import { CodeError } from '@libp2p/interface'
|
|
2
|
-
import { peerIdFromKeys } from '@libp2p/peer-id'
|
|
3
|
-
import { RecordEnvelope, PeerRecord } from '@libp2p/peer-record'
|
|
4
|
-
import { type Multiaddr, multiaddr } from '@multiformats/multiaddr'
|
|
5
|
-
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
|
|
6
|
-
import { isNode, isBrowser, isWebWorker, isElectronMain, isElectronRenderer, isReactNative } from 'wherearewe'
|
|
7
|
-
import { IDENTIFY_PROTOCOL_VERSION, MAX_IDENTIFY_MESSAGE_SIZE, MAX_PUSH_CONCURRENCY } from './consts.js'
|
|
8
|
-
import type { IdentifyComponents, IdentifyInit } from './index.js'
|
|
9
|
-
import type { Identify as IdentifyMessage } from './pb/message.js'
|
|
10
|
-
import type { Libp2pEvents, IdentifyResult, SignedPeerRecord, Logger, Connection, TypedEventTarget, Peer, PeerData, PeerStore, NodeInfo, Startable, PeerId, IncomingStreamData } from '@libp2p/interface'
|
|
11
|
-
import type { AddressManager, Registrar } from '@libp2p/interface-internal'
|
|
12
|
-
|
|
13
|
-
export const defaultValues = {
|
|
14
|
-
protocolPrefix: 'ipfs',
|
|
15
|
-
timeout: 5000,
|
|
16
|
-
maxInboundStreams: 1,
|
|
17
|
-
maxOutboundStreams: 1,
|
|
18
|
-
maxObservedAddresses: 10,
|
|
19
|
-
maxMessageSize: MAX_IDENTIFY_MESSAGE_SIZE,
|
|
20
|
-
runOnConnectionOpen: true,
|
|
21
|
-
runOnSelfUpdate: true,
|
|
22
|
-
runOnTransientConnection: true,
|
|
23
|
-
concurrency: MAX_PUSH_CONCURRENCY
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Takes the `addr` and converts it to a Multiaddr if possible
|
|
28
|
-
*/
|
|
29
|
-
export function getCleanMultiaddr (addr: Uint8Array | string | null | undefined): Multiaddr | undefined {
|
|
30
|
-
if (addr != null && addr.length > 0) {
|
|
31
|
-
try {
|
|
32
|
-
return multiaddr(addr)
|
|
33
|
-
} catch {
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function getAgentVersion (nodeInfo: NodeInfo, agentVersion?: string): string {
|
|
40
|
-
if (agentVersion != null) {
|
|
41
|
-
return agentVersion
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
agentVersion = `${nodeInfo.name}/${nodeInfo.version}`
|
|
45
|
-
// Append user agent version to default AGENT_VERSION depending on the environment
|
|
46
|
-
if (isNode || isElectronMain) {
|
|
47
|
-
agentVersion += ` UserAgent=${globalThis.process.version}`
|
|
48
|
-
} else if (isBrowser || isWebWorker || isElectronRenderer || isReactNative) {
|
|
49
|
-
agentVersion += ` UserAgent=${globalThis.navigator.userAgent}`
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return agentVersion
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export async function consumeIdentifyMessage (peerStore: PeerStore, events: TypedEventTarget<Libp2pEvents>, log: Logger, connection: Connection, message: IdentifyMessage): Promise<IdentifyResult> {
|
|
56
|
-
log('received identify from %p', connection.remotePeer)
|
|
57
|
-
|
|
58
|
-
if (message == null) {
|
|
59
|
-
throw new CodeError('message was null or undefined', 'ERR_INVALID_MESSAGE')
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const peer: PeerData = {}
|
|
63
|
-
|
|
64
|
-
if (message.listenAddrs.length > 0) {
|
|
65
|
-
peer.addresses = message.listenAddrs.map(buf => ({
|
|
66
|
-
isCertified: false,
|
|
67
|
-
multiaddr: multiaddr(buf)
|
|
68
|
-
}))
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (message.protocols.length > 0) {
|
|
72
|
-
peer.protocols = message.protocols
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (message.publicKey != null) {
|
|
76
|
-
peer.publicKey = message.publicKey
|
|
77
|
-
|
|
78
|
-
const peerId = await peerIdFromKeys(message.publicKey)
|
|
79
|
-
|
|
80
|
-
if (!peerId.equals(connection.remotePeer)) {
|
|
81
|
-
throw new CodeError('public key did not match remote PeerId', 'ERR_INVALID_PUBLIC_KEY')
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
let output: SignedPeerRecord | undefined
|
|
86
|
-
|
|
87
|
-
// if the peer record has been sent, prefer the addresses in the record as they are signed by the remote peer
|
|
88
|
-
if (message.signedPeerRecord != null) {
|
|
89
|
-
log('received signedPeerRecord from %p', connection.remotePeer)
|
|
90
|
-
|
|
91
|
-
let peerRecordEnvelope = message.signedPeerRecord
|
|
92
|
-
const envelope = await RecordEnvelope.openAndCertify(peerRecordEnvelope, PeerRecord.DOMAIN)
|
|
93
|
-
let peerRecord = PeerRecord.createFromProtobuf(envelope.payload)
|
|
94
|
-
|
|
95
|
-
// Verify peerId
|
|
96
|
-
if (!peerRecord.peerId.equals(envelope.peerId)) {
|
|
97
|
-
throw new CodeError('signing key does not match PeerId in the PeerRecord', 'ERR_INVALID_SIGNING_KEY')
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Make sure remote peer is the one sending the record
|
|
101
|
-
if (!connection.remotePeer.equals(peerRecord.peerId)) {
|
|
102
|
-
throw new CodeError('signing key does not match remote PeerId', 'ERR_INVALID_PEER_RECORD_KEY')
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
let existingPeer: Peer | undefined
|
|
106
|
-
|
|
107
|
-
try {
|
|
108
|
-
existingPeer = await peerStore.get(peerRecord.peerId)
|
|
109
|
-
} catch (err: any) {
|
|
110
|
-
if (err.code !== 'ERR_NOT_FOUND') {
|
|
111
|
-
throw err
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (existingPeer != null) {
|
|
116
|
-
// don't lose any existing metadata
|
|
117
|
-
peer.metadata = existingPeer.metadata
|
|
118
|
-
|
|
119
|
-
// if we have previously received a signed record for this peer, compare it to the incoming one
|
|
120
|
-
if (existingPeer.peerRecordEnvelope != null) {
|
|
121
|
-
const storedEnvelope = await RecordEnvelope.createFromProtobuf(existingPeer.peerRecordEnvelope)
|
|
122
|
-
const storedRecord = PeerRecord.createFromProtobuf(storedEnvelope.payload)
|
|
123
|
-
|
|
124
|
-
// ensure seq is greater than, or equal to, the last received
|
|
125
|
-
if (storedRecord.seqNumber >= peerRecord.seqNumber) {
|
|
126
|
-
log('sequence number was lower or equal to existing sequence number - stored: %d received: %d', storedRecord.seqNumber, peerRecord.seqNumber)
|
|
127
|
-
peerRecord = storedRecord
|
|
128
|
-
peerRecordEnvelope = existingPeer.peerRecordEnvelope
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// store the signed record for next time
|
|
134
|
-
peer.peerRecordEnvelope = peerRecordEnvelope
|
|
135
|
-
|
|
136
|
-
// override the stored addresses with the signed multiaddrs
|
|
137
|
-
peer.addresses = peerRecord.multiaddrs.map(multiaddr => ({
|
|
138
|
-
isCertified: true,
|
|
139
|
-
multiaddr
|
|
140
|
-
}))
|
|
141
|
-
|
|
142
|
-
output = {
|
|
143
|
-
seq: peerRecord.seqNumber,
|
|
144
|
-
addresses: peerRecord.multiaddrs
|
|
145
|
-
}
|
|
146
|
-
} else {
|
|
147
|
-
log('%p did not send a signed peer record', connection.remotePeer)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
log('patching %p with', connection.remotePeer, peer)
|
|
151
|
-
await peerStore.patch(connection.remotePeer, peer)
|
|
152
|
-
|
|
153
|
-
if (message.agentVersion != null || message.protocolVersion != null) {
|
|
154
|
-
const metadata: Record<string, Uint8Array> = {}
|
|
155
|
-
|
|
156
|
-
if (message.agentVersion != null) {
|
|
157
|
-
metadata.AgentVersion = uint8ArrayFromString(message.agentVersion)
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (message.protocolVersion != null) {
|
|
161
|
-
metadata.ProtocolVersion = uint8ArrayFromString(message.protocolVersion)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
log('merging %p metadata', connection.remotePeer, metadata)
|
|
165
|
-
await peerStore.merge(connection.remotePeer, {
|
|
166
|
-
metadata
|
|
167
|
-
})
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const result: IdentifyResult = {
|
|
171
|
-
peerId: connection.remotePeer,
|
|
172
|
-
protocolVersion: message.protocolVersion,
|
|
173
|
-
agentVersion: message.agentVersion,
|
|
174
|
-
publicKey: message.publicKey,
|
|
175
|
-
listenAddrs: message.listenAddrs.map(buf => multiaddr(buf)),
|
|
176
|
-
observedAddr: message.observedAddr == null ? undefined : multiaddr(message.observedAddr),
|
|
177
|
-
protocols: message.protocols,
|
|
178
|
-
signedPeerRecord: output,
|
|
179
|
-
connection
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
events.safeDispatchEvent('peer:identify', { detail: result })
|
|
183
|
-
|
|
184
|
-
return result
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
export interface AbstractIdentifyInit extends IdentifyInit {
|
|
188
|
-
protocol: string
|
|
189
|
-
log: Logger
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
export abstract class AbstractIdentify implements Startable {
|
|
193
|
-
public readonly host: {
|
|
194
|
-
protocolVersion: string
|
|
195
|
-
agentVersion: string
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
protected protocol: string
|
|
199
|
-
protected started: boolean
|
|
200
|
-
protected readonly timeout: number
|
|
201
|
-
protected readonly peerId: PeerId
|
|
202
|
-
protected readonly peerStore: PeerStore
|
|
203
|
-
protected readonly registrar: Registrar
|
|
204
|
-
protected readonly addressManager: AddressManager
|
|
205
|
-
private readonly maxInboundStreams: number
|
|
206
|
-
private readonly maxOutboundStreams: number
|
|
207
|
-
protected readonly maxMessageSize: number
|
|
208
|
-
protected readonly maxObservedAddresses: number
|
|
209
|
-
protected readonly events: TypedEventTarget<Libp2pEvents>
|
|
210
|
-
protected readonly runOnTransientConnection: boolean
|
|
211
|
-
protected readonly log: Logger
|
|
212
|
-
|
|
213
|
-
constructor (components: IdentifyComponents, init: AbstractIdentifyInit) {
|
|
214
|
-
this.protocol = init.protocol
|
|
215
|
-
this.started = false
|
|
216
|
-
this.peerId = components.peerId
|
|
217
|
-
this.peerStore = components.peerStore
|
|
218
|
-
this.registrar = components.registrar
|
|
219
|
-
this.addressManager = components.addressManager
|
|
220
|
-
this.events = components.events
|
|
221
|
-
this.log = init.log
|
|
222
|
-
|
|
223
|
-
this.timeout = init.timeout ?? defaultValues.timeout
|
|
224
|
-
this.maxInboundStreams = init.maxInboundStreams ?? defaultValues.maxInboundStreams
|
|
225
|
-
this.maxOutboundStreams = init.maxOutboundStreams ?? defaultValues.maxOutboundStreams
|
|
226
|
-
this.maxMessageSize = init.maxMessageSize ?? defaultValues.maxMessageSize
|
|
227
|
-
this.maxObservedAddresses = init.maxObservedAddresses ?? defaultValues.maxObservedAddresses
|
|
228
|
-
this.runOnTransientConnection = init.runOnTransientConnection ?? defaultValues.runOnTransientConnection
|
|
229
|
-
|
|
230
|
-
// Store self host metadata
|
|
231
|
-
this.host = {
|
|
232
|
-
protocolVersion: `${init.protocolPrefix ?? defaultValues.protocolPrefix}/${IDENTIFY_PROTOCOL_VERSION}`,
|
|
233
|
-
agentVersion: getAgentVersion(components.nodeInfo, init.agentVersion)
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
isStarted (): boolean {
|
|
238
|
-
return this.started
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
async start (): Promise<void> {
|
|
242
|
-
if (this.started) {
|
|
243
|
-
return
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
await this.peerStore.merge(this.peerId, {
|
|
247
|
-
metadata: {
|
|
248
|
-
AgentVersion: uint8ArrayFromString(this.host.agentVersion),
|
|
249
|
-
ProtocolVersion: uint8ArrayFromString(this.host.protocolVersion)
|
|
250
|
-
}
|
|
251
|
-
})
|
|
252
|
-
|
|
253
|
-
await this.registrar.handle(this.protocol, (data) => {
|
|
254
|
-
void this.handleProtocol(data).catch(err => {
|
|
255
|
-
this.log.error(err)
|
|
256
|
-
})
|
|
257
|
-
}, {
|
|
258
|
-
maxInboundStreams: this.maxInboundStreams,
|
|
259
|
-
maxOutboundStreams: this.maxOutboundStreams,
|
|
260
|
-
runOnTransientConnection: this.runOnTransientConnection
|
|
261
|
-
})
|
|
262
|
-
|
|
263
|
-
this.started = true
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
async stop (): Promise<void> {
|
|
267
|
-
await this.registrar.unhandle(this.protocol)
|
|
268
|
-
|
|
269
|
-
this.started = false
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
protected abstract handleProtocol (data: IncomingStreamData): Promise<void>
|
|
273
|
-
}
|