@libp2p/daemon-server 0.0.1 → 1.0.1
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/dist/src/dht.d.ts +1 -1
- package/dist/src/dht.d.ts.map +1 -1
- package/dist/src/dht.js +23 -22
- package/dist/src/dht.js.map +1 -1
- package/dist/src/index.d.ts +19 -29
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +131 -123
- package/dist/src/index.js.map +1 -1
- package/dist/src/pubsub.d.ts +1 -1
- package/dist/src/pubsub.d.ts.map +1 -1
- package/dist/src/pubsub.js +44 -22
- package/dist/src/pubsub.js.map +1 -1
- package/dist/src/responses.d.ts +2 -2
- package/dist/src/responses.d.ts.map +1 -1
- package/dist/src/responses.js +5 -3
- package/dist/src/responses.js.map +1 -1
- package/package.json +16 -21
- package/src/dht.ts +24 -24
- package/src/index.ts +172 -164
- package/src/pubsub.ts +46 -27
- package/src/responses.ts +7 -5
- package/dist/src/client.d.ts +0 -26
- package/dist/src/client.d.ts.map +0 -1
- package/dist/src/client.js +0 -43
- package/dist/src/client.js.map +0 -1
- package/dist/src/stream-handler.d.ts +0 -28
- package/dist/src/stream-handler.d.ts.map +0 -1
- package/dist/src/stream-handler.js +0 -47
- package/dist/src/stream-handler.js.map +0 -1
- package/dist/src/util/index.d.ts +0 -13
- package/dist/src/util/index.d.ts.map +0 -1
- package/dist/src/util/index.js +0 -26
- package/dist/src/util/index.js.map +0 -1
- package/src/client.ts +0 -56
- package/src/stream-handler.ts +0 -65
- package/src/util/index.ts +0 -30
package/src/index.ts
CHANGED
|
@@ -1,24 +1,18 @@
|
|
|
1
1
|
/* eslint max-depth: ["error", 6] */
|
|
2
2
|
|
|
3
3
|
import { TCP } from '@libp2p/tcp'
|
|
4
|
-
import { Multiaddr } from '@multiformats/multiaddr'
|
|
4
|
+
import { Multiaddr, protocols } from '@multiformats/multiaddr'
|
|
5
5
|
import { CID } from 'multiformats/cid'
|
|
6
6
|
import * as lp from 'it-length-prefixed'
|
|
7
7
|
import { pipe } from 'it-pipe'
|
|
8
|
-
import { StreamHandler } from '
|
|
9
|
-
import {
|
|
10
|
-
import { passThroughUpgrader } from './util/index.js'
|
|
8
|
+
import { StreamHandler } from '@libp2p/daemon-protocol/stream-handler'
|
|
9
|
+
import { passThroughUpgrader } from '@libp2p/daemon-protocol/upgrader'
|
|
11
10
|
import {
|
|
12
11
|
Request,
|
|
13
12
|
DHTRequest,
|
|
14
13
|
PeerstoreRequest,
|
|
15
14
|
PSRequest,
|
|
16
|
-
StreamInfo
|
|
17
|
-
IRequest,
|
|
18
|
-
IStreamInfo,
|
|
19
|
-
IPSRequest,
|
|
20
|
-
IDHTRequest,
|
|
21
|
-
IPeerstoreRequest
|
|
15
|
+
StreamInfo
|
|
22
16
|
} from '@libp2p/daemon-protocol'
|
|
23
17
|
import type { Listener } from '@libp2p/interfaces/transport'
|
|
24
18
|
import type { Connection, Stream } from '@libp2p/interfaces/connection'
|
|
@@ -30,15 +24,15 @@ import type { PubSub } from '@libp2p/interfaces/pubsub'
|
|
|
30
24
|
import type { PeerStore } from '@libp2p/interfaces/peer-store'
|
|
31
25
|
import { ErrorResponse, OkResponse } from './responses.js'
|
|
32
26
|
import { DHTOperations } from './dht.js'
|
|
33
|
-
import { peerIdFromBytes
|
|
27
|
+
import { peerIdFromBytes } from '@libp2p/peer-id'
|
|
34
28
|
import { PubSubOperations } from './pubsub.js'
|
|
35
29
|
import { logger } from '@libp2p/logger'
|
|
36
30
|
|
|
37
31
|
const LIMIT = 1 << 22 // 4MB
|
|
38
|
-
const log = logger('libp2p:daemon')
|
|
32
|
+
const log = logger('libp2p:daemon-server')
|
|
39
33
|
|
|
40
34
|
export interface OpenStream {
|
|
41
|
-
streamInfo:
|
|
35
|
+
streamInfo: StreamInfo
|
|
42
36
|
connection: Stream
|
|
43
37
|
}
|
|
44
38
|
|
|
@@ -58,24 +52,24 @@ export interface Libp2p {
|
|
|
58
52
|
}
|
|
59
53
|
|
|
60
54
|
export interface DaemonInit {
|
|
61
|
-
multiaddr: Multiaddr
|
|
55
|
+
multiaddr: Multiaddr
|
|
62
56
|
libp2pNode: any
|
|
63
57
|
}
|
|
64
58
|
|
|
65
59
|
export interface Libp2pServer {
|
|
66
60
|
start: () => Promise<void>
|
|
67
61
|
stop: () => Promise<void>
|
|
68
|
-
|
|
62
|
+
getMultiaddr: () => Multiaddr
|
|
69
63
|
}
|
|
70
64
|
|
|
71
65
|
export class Server implements Libp2pServer {
|
|
72
|
-
private multiaddr: Multiaddr
|
|
73
|
-
private libp2p: Libp2p
|
|
74
|
-
private tcp: TCP
|
|
75
|
-
private listener: Listener
|
|
76
|
-
private streamHandlers: Record<string, StreamHandler>
|
|
77
|
-
private dhtOperations?: DHTOperations
|
|
78
|
-
private pubsubOperations?: PubSubOperations
|
|
66
|
+
private readonly multiaddr: Multiaddr
|
|
67
|
+
private readonly libp2p: Libp2p
|
|
68
|
+
private readonly tcp: TCP
|
|
69
|
+
private readonly listener: Listener
|
|
70
|
+
private readonly streamHandlers: Record<string, StreamHandler>
|
|
71
|
+
private readonly dhtOperations?: DHTOperations
|
|
72
|
+
private readonly pubsubOperations?: PubSubOperations
|
|
79
73
|
|
|
80
74
|
constructor (init: DaemonInit) {
|
|
81
75
|
const { multiaddr, libp2pNode } = init
|
|
@@ -102,7 +96,7 @@ export class Server implements Libp2pServer {
|
|
|
102
96
|
/**
|
|
103
97
|
* Connects the daemons libp2p node to the peer provided
|
|
104
98
|
*/
|
|
105
|
-
async connect (request:
|
|
99
|
+
async connect (request: Request): Promise<Connection> {
|
|
106
100
|
if (request.connect == null || request.connect.addrs == null) {
|
|
107
101
|
throw new Error('Invalid request')
|
|
108
102
|
}
|
|
@@ -112,20 +106,20 @@ export class Server implements Libp2pServer {
|
|
|
112
106
|
const peerId = peerIdFromBytes(peer)
|
|
113
107
|
|
|
114
108
|
await this.libp2p.peerStore.addressBook.set(peerId, addrs)
|
|
115
|
-
return this.libp2p.dial(peerId)
|
|
109
|
+
return await this.libp2p.dial(peerId)
|
|
116
110
|
}
|
|
117
111
|
|
|
118
112
|
/**
|
|
119
113
|
* Opens a stream on one of the given protocols to the given peer
|
|
120
114
|
*/
|
|
121
|
-
async openStream (request:
|
|
115
|
+
async openStream (request: Request): Promise<OpenStream> {
|
|
122
116
|
if (request.streamOpen == null || request.streamOpen.proto == null) {
|
|
123
117
|
throw new Error('Invalid request')
|
|
124
118
|
}
|
|
125
119
|
|
|
126
120
|
const { peer, proto } = request.streamOpen
|
|
127
121
|
|
|
128
|
-
const peerId =
|
|
122
|
+
const peerId = peerIdFromBytes(peer)
|
|
129
123
|
|
|
130
124
|
const connection = await this.libp2p.dial(peerId)
|
|
131
125
|
const { stream, protocol } = await connection.newStream(proto)
|
|
@@ -144,11 +138,8 @@ export class Server implements Libp2pServer {
|
|
|
144
138
|
* Sends inbound requests for the given protocol
|
|
145
139
|
* to the unix socket path provided. If an existing handler
|
|
146
140
|
* is registered at the path, it will be overridden.
|
|
147
|
-
*
|
|
148
|
-
* @param {StreamHandlerRequest} request
|
|
149
|
-
* @returns {Promise<void>}
|
|
150
141
|
*/
|
|
151
|
-
async registerStreamHandler (request:
|
|
142
|
+
async registerStreamHandler (request: Request): Promise<void> {
|
|
152
143
|
if (request.streamHandler == null || request.streamHandler.proto == null) {
|
|
153
144
|
throw new Error('Invalid request')
|
|
154
145
|
}
|
|
@@ -158,31 +149,34 @@ export class Server implements Libp2pServer {
|
|
|
158
149
|
const addrString = addr.toString()
|
|
159
150
|
|
|
160
151
|
// If we have a handler, end it
|
|
161
|
-
if (this.streamHandlers[addrString]) {
|
|
162
|
-
this.streamHandlers[addrString].close()
|
|
163
|
-
delete this.streamHandlers[addrString]
|
|
152
|
+
if (this.streamHandlers[addrString] != null) {
|
|
153
|
+
await this.streamHandlers[addrString].close()
|
|
154
|
+
delete this.streamHandlers[addrString] // eslint-disable-line @typescript-eslint/no-dynamic-delete
|
|
164
155
|
}
|
|
165
156
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
157
|
+
await Promise.all(
|
|
158
|
+
protocols.map(async (proto) => {
|
|
159
|
+
// Connect the client socket with the libp2p connection
|
|
160
|
+
await this.libp2p.handle(proto, ({ connection, stream, protocol }) => {
|
|
161
|
+
const message = StreamInfo.encode({
|
|
162
|
+
peer: connection.remotePeer.toBytes(),
|
|
163
|
+
addr: connection.remoteAddr.bytes,
|
|
164
|
+
proto: protocol
|
|
165
|
+
})
|
|
166
|
+
const encodedMessage = lp.encode.single(message)
|
|
167
|
+
|
|
168
|
+
// Tell the client about the new connection
|
|
169
|
+
// And then begin piping the client and peer connection
|
|
170
|
+
void pipe(
|
|
171
|
+
[encodedMessage, stream.source],
|
|
172
|
+
clientConnection,
|
|
173
|
+
stream.sink
|
|
174
|
+
).catch(err => {
|
|
175
|
+
log.error(err)
|
|
176
|
+
})
|
|
177
|
+
})
|
|
184
178
|
})
|
|
185
|
-
|
|
179
|
+
)
|
|
186
180
|
|
|
187
181
|
const clientConnection = await this.tcp.dial(addr, {
|
|
188
182
|
upgrader: passThroughUpgrader
|
|
@@ -191,9 +185,6 @@ export class Server implements Libp2pServer {
|
|
|
191
185
|
|
|
192
186
|
/**
|
|
193
187
|
* Listens for process exit to handle cleanup
|
|
194
|
-
*
|
|
195
|
-
* @private
|
|
196
|
-
* @returns {void}
|
|
197
188
|
*/
|
|
198
189
|
_listen () {
|
|
199
190
|
// listen for graceful termination
|
|
@@ -203,7 +194,9 @@ export class Server implements Libp2pServer {
|
|
|
203
194
|
}
|
|
204
195
|
|
|
205
196
|
_onExit () {
|
|
206
|
-
this.stop({ exit: true })
|
|
197
|
+
void this.stop({ exit: true }).catch(err => {
|
|
198
|
+
log.error(err)
|
|
199
|
+
})
|
|
207
200
|
}
|
|
208
201
|
|
|
209
202
|
/**
|
|
@@ -215,16 +208,18 @@ export class Server implements Libp2pServer {
|
|
|
215
208
|
await this.listener.listen(this.multiaddr)
|
|
216
209
|
}
|
|
217
210
|
|
|
218
|
-
|
|
219
|
-
|
|
211
|
+
getMultiaddr (): Multiaddr {
|
|
212
|
+
const addrs = this.listener.getAddrs()
|
|
213
|
+
|
|
214
|
+
if (addrs.length > 0) {
|
|
215
|
+
return addrs[0]
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
throw new Error('Not started')
|
|
220
219
|
}
|
|
221
220
|
|
|
222
221
|
/**
|
|
223
222
|
* Stops the daemon
|
|
224
|
-
*
|
|
225
|
-
* @param {object} options
|
|
226
|
-
* @param {boolean} options.exit - If the daemon process should exit
|
|
227
|
-
* @returns {Promise<void>}
|
|
228
223
|
*/
|
|
229
224
|
async stop (options = { exit: false }) {
|
|
230
225
|
await this.libp2p.stop()
|
|
@@ -237,7 +232,7 @@ export class Server implements Libp2pServer {
|
|
|
237
232
|
process.removeListener('SIGHUP', this._onExit)
|
|
238
233
|
}
|
|
239
234
|
|
|
240
|
-
async * handlePeerStoreRequest (request:
|
|
235
|
+
async * handlePeerStoreRequest (request: PeerstoreRequest) {
|
|
241
236
|
try {
|
|
242
237
|
switch (request.type) {
|
|
243
238
|
case PeerstoreRequest.Type.GET_PROTOCOLS:
|
|
@@ -245,9 +240,9 @@ export class Server implements Libp2pServer {
|
|
|
245
240
|
throw new Error('Invalid request')
|
|
246
241
|
}
|
|
247
242
|
|
|
248
|
-
const peerId = peerIdFromBytes(request.id)
|
|
249
|
-
const peer = await this.libp2p.peerStore.get(peerId)
|
|
250
|
-
const protos = peer.protocols
|
|
243
|
+
const peerId = peerIdFromBytes(request.id) // eslint-disable-line no-case-declarations
|
|
244
|
+
const peer = await this.libp2p.peerStore.get(peerId) // eslint-disable-line no-case-declarations
|
|
245
|
+
const protos = peer.protocols // eslint-disable-line no-case-declarations
|
|
251
246
|
yield OkResponse({ peerStore: { protos } })
|
|
252
247
|
return
|
|
253
248
|
case PeerstoreRequest.Type.GET_PEER_INFO:
|
|
@@ -256,6 +251,7 @@ export class Server implements Libp2pServer {
|
|
|
256
251
|
throw new Error('ERR_INVALID_REQUEST_TYPE')
|
|
257
252
|
}
|
|
258
253
|
} catch (err: any) {
|
|
254
|
+
log.error(err)
|
|
259
255
|
yield ErrorResponse(err)
|
|
260
256
|
}
|
|
261
257
|
}
|
|
@@ -263,9 +259,9 @@ export class Server implements Libp2pServer {
|
|
|
263
259
|
/**
|
|
264
260
|
* Parses and responds to PSRequests
|
|
265
261
|
*/
|
|
266
|
-
async * handlePubsubRequest (request:
|
|
262
|
+
async * handlePubsubRequest (request: PSRequest) {
|
|
267
263
|
try {
|
|
268
|
-
if (this.libp2p.pubsub == null ||
|
|
264
|
+
if (this.libp2p.pubsub == null || (this.pubsubOperations == null)) {
|
|
269
265
|
throw new Error('PubSub not configured')
|
|
270
266
|
}
|
|
271
267
|
|
|
@@ -291,6 +287,7 @@ export class Server implements Libp2pServer {
|
|
|
291
287
|
throw new Error('ERR_INVALID_REQUEST_TYPE')
|
|
292
288
|
}
|
|
293
289
|
} catch (err: any) {
|
|
290
|
+
log.error(err)
|
|
294
291
|
yield ErrorResponse(err)
|
|
295
292
|
}
|
|
296
293
|
}
|
|
@@ -298,9 +295,9 @@ export class Server implements Libp2pServer {
|
|
|
298
295
|
/**
|
|
299
296
|
* Parses and responds to DHTRequests
|
|
300
297
|
*/
|
|
301
|
-
async * handleDHTRequest (request:
|
|
298
|
+
async * handleDHTRequest (request: DHTRequest) {
|
|
302
299
|
try {
|
|
303
|
-
if (this.libp2p.dht == null ||
|
|
300
|
+
if (this.libp2p.dht == null || (this.dhtOperations == null)) {
|
|
304
301
|
throw new Error('DHT not configured')
|
|
305
302
|
}
|
|
306
303
|
|
|
@@ -358,6 +355,7 @@ export class Server implements Libp2pServer {
|
|
|
358
355
|
throw new Error('ERR_INVALID_REQUEST_TYPE')
|
|
359
356
|
}
|
|
360
357
|
} catch (err: any) {
|
|
358
|
+
log.error(err)
|
|
361
359
|
yield ErrorResponse(err)
|
|
362
360
|
}
|
|
363
361
|
}
|
|
@@ -365,129 +363,137 @@ export class Server implements Libp2pServer {
|
|
|
365
363
|
/**
|
|
366
364
|
* Handles requests for the given connection
|
|
367
365
|
*/
|
|
368
|
-
|
|
369
|
-
const daemon = this
|
|
366
|
+
handleConnection (connection: Connection) {
|
|
367
|
+
const daemon = this // eslint-disable-line @typescript-eslint/no-this-alias
|
|
370
368
|
// @ts-expect-error connection may actually be a maconn?
|
|
371
369
|
const streamHandler = new StreamHandler({ stream: connection, maxLength: LIMIT })
|
|
372
370
|
|
|
373
|
-
|
|
371
|
+
void pipe(
|
|
374
372
|
streamHandler.decoder,
|
|
375
373
|
source => (async function * () {
|
|
376
374
|
let request: Request
|
|
377
375
|
|
|
378
|
-
for await (
|
|
376
|
+
for await (const buf of source) {
|
|
379
377
|
try {
|
|
380
378
|
request = Request.decode(buf)
|
|
381
|
-
} catch (err) {
|
|
382
|
-
yield ErrorResponse(new Error('ERR_INVALID_MESSAGE'))
|
|
383
|
-
continue
|
|
384
|
-
}
|
|
385
379
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
380
|
+
switch (request.type) {
|
|
381
|
+
// Connect to another peer
|
|
382
|
+
case Request.Type.CONNECT: {
|
|
383
|
+
try {
|
|
384
|
+
await daemon.connect(request)
|
|
385
|
+
} catch (err: any) {
|
|
386
|
+
yield ErrorResponse(err)
|
|
387
|
+
break
|
|
388
|
+
}
|
|
389
|
+
yield OkResponse()
|
|
393
390
|
break
|
|
394
391
|
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
392
|
+
// Get the daemon peer id and addresses
|
|
393
|
+
case Request.Type.IDENTIFY: {
|
|
394
|
+
yield OkResponse({
|
|
395
|
+
identify: {
|
|
396
|
+
id: daemon.libp2p.peerId.toBytes(),
|
|
397
|
+
addrs: daemon.libp2p.getMultiaddrs().map(ma => ma.decapsulateCode(protocols('p2p').code)).map(m => m.bytes)
|
|
398
|
+
}
|
|
399
|
+
})
|
|
400
|
+
break
|
|
401
|
+
}
|
|
402
|
+
// Get a list of our current peers
|
|
403
|
+
case Request.Type.LIST_PEERS: {
|
|
404
|
+
const peers = []
|
|
405
|
+
const seen = new Set<string>()
|
|
406
|
+
|
|
407
|
+
for (const connection of daemon.libp2p.getConnections()) {
|
|
408
|
+
const peerId = connection.remotePeer.toString()
|
|
409
|
+
|
|
410
|
+
if (seen.has(peerId)) {
|
|
411
|
+
continue
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
seen.add(peerId)
|
|
415
|
+
|
|
416
|
+
peers.push({
|
|
417
|
+
id: connection.remotePeer.toBytes(),
|
|
418
|
+
addrs: [connection.remoteAddr.bytes]
|
|
419
|
+
})
|
|
404
420
|
}
|
|
405
|
-
})
|
|
406
|
-
break
|
|
407
|
-
}
|
|
408
|
-
// Get a list of our current peers
|
|
409
|
-
case Request.Type.LIST_PEERS: {
|
|
410
|
-
const peers = []
|
|
411
421
|
|
|
412
|
-
|
|
413
|
-
|
|
422
|
+
yield OkResponse({ peers })
|
|
423
|
+
break
|
|
424
|
+
}
|
|
425
|
+
case Request.Type.STREAM_OPEN: {
|
|
426
|
+
let response
|
|
427
|
+
try {
|
|
428
|
+
response = await daemon.openStream(request)
|
|
429
|
+
} catch (err: any) {
|
|
430
|
+
yield ErrorResponse(err)
|
|
431
|
+
break
|
|
432
|
+
}
|
|
414
433
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
434
|
+
// write the response
|
|
435
|
+
yield OkResponse({
|
|
436
|
+
streamInfo: response.streamInfo
|
|
418
437
|
})
|
|
419
|
-
}
|
|
420
438
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
break
|
|
439
|
+
const stream = streamHandler.rest()
|
|
440
|
+
// then pipe the connection to the client
|
|
441
|
+
await pipe(
|
|
442
|
+
stream,
|
|
443
|
+
response.connection,
|
|
444
|
+
stream
|
|
445
|
+
)
|
|
446
|
+
// Exit the iterator, no more requests can come through
|
|
447
|
+
return
|
|
431
448
|
}
|
|
449
|
+
case Request.Type.STREAM_HANDLER: {
|
|
450
|
+
try {
|
|
451
|
+
await daemon.registerStreamHandler(request)
|
|
452
|
+
} catch (err: any) {
|
|
453
|
+
yield ErrorResponse(err)
|
|
454
|
+
break
|
|
455
|
+
}
|
|
432
456
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
streamInfo: response.streamInfo
|
|
436
|
-
})
|
|
437
|
-
|
|
438
|
-
const stream = streamHandler.rest()
|
|
439
|
-
// then pipe the connection to the client
|
|
440
|
-
await pipe(
|
|
441
|
-
stream,
|
|
442
|
-
response.connection,
|
|
443
|
-
stream
|
|
444
|
-
)
|
|
445
|
-
// Exit the iterator, no more requests can come through
|
|
446
|
-
return
|
|
447
|
-
}
|
|
448
|
-
case Request.Type.STREAM_HANDLER: {
|
|
449
|
-
try {
|
|
450
|
-
await daemon.registerStreamHandler(request)
|
|
451
|
-
} catch (err: any) {
|
|
452
|
-
yield ErrorResponse(err)
|
|
457
|
+
// write the response
|
|
458
|
+
yield OkResponse()
|
|
453
459
|
break
|
|
454
460
|
}
|
|
461
|
+
case Request.Type.PEERSTORE: {
|
|
462
|
+
if (request.peerStore == null) {
|
|
463
|
+
yield ErrorResponse(new Error('ERR_INVALID_REQUEST'))
|
|
464
|
+
break
|
|
465
|
+
}
|
|
455
466
|
|
|
456
|
-
|
|
457
|
-
yield OkResponse()
|
|
458
|
-
break
|
|
459
|
-
}
|
|
460
|
-
case Request.Type.PEERSTORE: {
|
|
461
|
-
if (request.peerStore == null) {
|
|
462
|
-
yield ErrorResponse(new Error('ERR_INVALID_REQUEST'))
|
|
467
|
+
yield * daemon.handlePeerStoreRequest(request.peerStore)
|
|
463
468
|
break
|
|
464
469
|
}
|
|
470
|
+
case Request.Type.PUBSUB: {
|
|
471
|
+
if (request.pubsub == null) {
|
|
472
|
+
yield ErrorResponse(new Error('ERR_INVALID_REQUEST'))
|
|
473
|
+
break
|
|
474
|
+
}
|
|
465
475
|
|
|
466
|
-
|
|
467
|
-
break
|
|
468
|
-
}
|
|
469
|
-
case Request.Type.PUBSUB: {
|
|
470
|
-
if (request.pubsub == null) {
|
|
471
|
-
yield ErrorResponse(new Error('ERR_INVALID_REQUEST'))
|
|
476
|
+
yield * daemon.handlePubsubRequest(request.pubsub)
|
|
472
477
|
break
|
|
473
478
|
}
|
|
479
|
+
case Request.Type.DHT: {
|
|
480
|
+
if (request.dht == null) {
|
|
481
|
+
yield ErrorResponse(new Error('ERR_INVALID_REQUEST'))
|
|
482
|
+
break
|
|
483
|
+
}
|
|
474
484
|
|
|
475
|
-
|
|
476
|
-
break
|
|
477
|
-
}
|
|
478
|
-
case Request.Type.DHT: {
|
|
479
|
-
if (request.dht == null) {
|
|
480
|
-
yield ErrorResponse(new Error('ERR_INVALID_REQUEST'))
|
|
485
|
+
yield * daemon.handleDHTRequest(request.dht)
|
|
481
486
|
break
|
|
482
487
|
}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
488
|
+
// Not yet supported or doesn't exist
|
|
489
|
+
default:
|
|
490
|
+
yield ErrorResponse(new Error('ERR_INVALID_REQUEST_TYPE'))
|
|
491
|
+
break
|
|
486
492
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
493
|
+
} catch (err: any) {
|
|
494
|
+
log.error(err)
|
|
495
|
+
yield ErrorResponse(err)
|
|
496
|
+
continue
|
|
491
497
|
}
|
|
492
498
|
}
|
|
493
499
|
})(),
|
|
@@ -496,14 +502,16 @@ export class Server implements Libp2pServer {
|
|
|
496
502
|
streamHandler.write(result)
|
|
497
503
|
}
|
|
498
504
|
}
|
|
499
|
-
)
|
|
505
|
+
).catch(err => {
|
|
506
|
+
log(err)
|
|
507
|
+
})
|
|
500
508
|
}
|
|
501
509
|
}
|
|
502
510
|
|
|
503
511
|
/**
|
|
504
512
|
* Creates a daemon from the provided Daemon Options
|
|
505
513
|
*/
|
|
506
|
-
export const createServer =
|
|
514
|
+
export const createServer = (multiaddr: Multiaddr, libp2pNode: Libp2p): Libp2pServer => {
|
|
507
515
|
const daemon = new Server({
|
|
508
516
|
multiaddr,
|
|
509
517
|
libp2pNode
|
package/src/pubsub.ts
CHANGED
|
@@ -3,17 +3,21 @@
|
|
|
3
3
|
import {
|
|
4
4
|
PSMessage
|
|
5
5
|
} from '@libp2p/daemon-protocol'
|
|
6
|
-
import { OkResponse } from './responses.js'
|
|
6
|
+
import { ErrorResponse, OkResponse } from './responses.js'
|
|
7
7
|
import type { PubSub } from '@libp2p/interfaces/pubsub'
|
|
8
8
|
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
|
|
9
9
|
import { pushable } from 'it-pushable'
|
|
10
|
+
import { CustomEvent } from '@libp2p/interfaces'
|
|
11
|
+
import { logger } from '@libp2p/logger'
|
|
12
|
+
|
|
13
|
+
const log = logger('libp2p:daemon-server:pubsub')
|
|
10
14
|
|
|
11
15
|
export interface PubSubOperationsInit {
|
|
12
16
|
pubsub: PubSub
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
export class PubSubOperations {
|
|
16
|
-
private pubsub: PubSub
|
|
20
|
+
private readonly pubsub: PubSub
|
|
17
21
|
|
|
18
22
|
constructor (init: PubSubOperationsInit) {
|
|
19
23
|
const { pubsub } = init
|
|
@@ -22,36 +26,51 @@ export class PubSubOperations {
|
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
async * getTopics () {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
try {
|
|
30
|
+
yield OkResponse({
|
|
31
|
+
pubsub: {
|
|
32
|
+
topics: this.pubsub.getTopics(),
|
|
33
|
+
peerIDs: []
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
} catch (err: any) {
|
|
37
|
+
log.error(err)
|
|
38
|
+
yield ErrorResponse(err)
|
|
39
|
+
}
|
|
30
40
|
}
|
|
31
41
|
|
|
32
42
|
async * subscribe (topic: string) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
try {
|
|
44
|
+
const onMessage = pushable<Uint8Array>()
|
|
45
|
+
|
|
46
|
+
await this.pubsub.addEventListener(topic, (evt) => {
|
|
47
|
+
const msg = evt.detail
|
|
48
|
+
|
|
49
|
+
onMessage.push(PSMessage.encode({
|
|
50
|
+
from: msg.from.toBytes(),
|
|
51
|
+
data: msg.data,
|
|
52
|
+
seqno: msg.sequenceNumber == null ? undefined : uint8ArrayFromString(msg.sequenceNumber.toString(16).padStart(16, '0'), 'base16'),
|
|
53
|
+
topicIDs: [msg.topic],
|
|
54
|
+
signature: msg.signature,
|
|
55
|
+
key: msg.key
|
|
56
|
+
}))
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
yield OkResponse()
|
|
60
|
+
yield * onMessage
|
|
61
|
+
} catch (err: any) {
|
|
62
|
+
log.error(err)
|
|
63
|
+
yield ErrorResponse(err)
|
|
64
|
+
}
|
|
50
65
|
}
|
|
51
66
|
|
|
52
67
|
async * publish (topic: string, data: Uint8Array) {
|
|
53
|
-
|
|
54
|
-
|
|
68
|
+
try {
|
|
69
|
+
this.pubsub.dispatchEvent(new CustomEvent(topic, { detail: data }))
|
|
70
|
+
yield OkResponse()
|
|
71
|
+
} catch (err: any) {
|
|
72
|
+
log.error(err)
|
|
73
|
+
yield ErrorResponse(err)
|
|
74
|
+
}
|
|
55
75
|
}
|
|
56
|
-
|
|
57
76
|
}
|
package/src/responses.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Response } from '@libp2p/daemon-protocol'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Creates and encodes an OK response
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
export function OkResponse (data?: Partial<Response>): Uint8Array {
|
|
7
7
|
return Response.encode({
|
|
8
8
|
type: Response.Type.OK,
|
|
9
|
+
peers: [],
|
|
9
10
|
...data
|
|
10
|
-
})
|
|
11
|
+
})
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -18,6 +19,7 @@ export function ErrorResponse (err: Error): Uint8Array {
|
|
|
18
19
|
type: Response.Type.ERROR,
|
|
19
20
|
error: {
|
|
20
21
|
msg: err.message
|
|
21
|
-
}
|
|
22
|
-
|
|
22
|
+
},
|
|
23
|
+
peers: []
|
|
24
|
+
})
|
|
23
25
|
}
|