@waku/core 0.0.33-f599932.0 → 0.0.34-09108d9.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 (93) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/bundle/base_protocol-Bp5a9PNG.js +152 -0
  3. package/bundle/{index-BVysxsMu.js → index-G1eRBjeI.js} +136 -215
  4. package/bundle/index.js +1963 -621
  5. package/bundle/lib/base_protocol.js +2 -2
  6. package/bundle/lib/message/version_0.js +2 -2
  7. package/bundle/{version_0-C5ObpJ_0.js → version_0-DJZG2fB2.js} +285 -41
  8. package/dist/.tsbuildinfo +1 -1
  9. package/dist/index.d.ts +2 -5
  10. package/dist/index.js +2 -5
  11. package/dist/index.js.map +1 -1
  12. package/dist/lib/base_protocol.d.ts +3 -23
  13. package/dist/lib/base_protocol.js +3 -51
  14. package/dist/lib/base_protocol.js.map +1 -1
  15. package/dist/lib/connection_manager/connection_manager.d.ts +118 -0
  16. package/dist/lib/{connection_manager.js → connection_manager/connection_manager.js} +136 -36
  17. package/dist/lib/connection_manager/connection_manager.js.map +1 -0
  18. package/dist/lib/connection_manager/index.d.ts +1 -0
  19. package/dist/lib/connection_manager/index.js +2 -0
  20. package/dist/lib/connection_manager/index.js.map +1 -0
  21. package/dist/lib/{keep_alive_manager.d.ts → connection_manager/keep_alive_manager.d.ts} +4 -2
  22. package/dist/lib/{keep_alive_manager.js → connection_manager/keep_alive_manager.js} +2 -2
  23. package/dist/lib/connection_manager/keep_alive_manager.js.map +1 -0
  24. package/dist/lib/connection_manager/utils.d.ts +7 -0
  25. package/dist/lib/connection_manager/utils.js +22 -0
  26. package/dist/lib/connection_manager/utils.js.map +1 -0
  27. package/dist/lib/filter/filter.d.ts +18 -0
  28. package/dist/lib/filter/filter.js +209 -0
  29. package/dist/lib/filter/filter.js.map +1 -0
  30. package/dist/lib/filter/index.d.ts +1 -19
  31. package/dist/lib/filter/index.js +1 -211
  32. package/dist/lib/filter/index.js.map +1 -1
  33. package/dist/lib/light_push/index.d.ts +1 -15
  34. package/dist/lib/light_push/index.js +1 -143
  35. package/dist/lib/light_push/index.js.map +1 -1
  36. package/dist/lib/light_push/light_push.d.ts +15 -0
  37. package/dist/lib/light_push/light_push.js +144 -0
  38. package/dist/lib/light_push/light_push.js.map +1 -0
  39. package/dist/lib/light_push/utils.d.ts +0 -2
  40. package/dist/lib/light_push/utils.js +8 -16
  41. package/dist/lib/light_push/utils.js.map +1 -1
  42. package/dist/lib/metadata/index.d.ts +1 -3
  43. package/dist/lib/metadata/index.js +1 -118
  44. package/dist/lib/metadata/index.js.map +1 -1
  45. package/dist/lib/metadata/metadata.d.ts +3 -0
  46. package/dist/lib/metadata/metadata.js +119 -0
  47. package/dist/lib/metadata/metadata.js.map +1 -0
  48. package/dist/lib/store/index.d.ts +1 -9
  49. package/dist/lib/store/index.js +1 -82
  50. package/dist/lib/store/index.js.map +1 -1
  51. package/dist/lib/store/store.d.ts +9 -0
  52. package/dist/lib/store/store.js +83 -0
  53. package/dist/lib/store/store.js.map +1 -0
  54. package/dist/lib/stream_manager/stream_manager.d.ts +13 -10
  55. package/dist/lib/stream_manager/stream_manager.js +88 -58
  56. package/dist/lib/stream_manager/stream_manager.js.map +1 -1
  57. package/dist/lib/stream_manager/utils.d.ts +1 -1
  58. package/dist/lib/stream_manager/utils.js +5 -17
  59. package/dist/lib/stream_manager/utils.js.map +1 -1
  60. package/package.json +1 -1
  61. package/src/index.ts +2 -7
  62. package/src/lib/base_protocol.ts +3 -82
  63. package/src/lib/{connection_manager.ts → connection_manager/connection_manager.ts} +168 -63
  64. package/src/lib/connection_manager/index.ts +1 -0
  65. package/src/lib/{keep_alive_manager.ts → connection_manager/keep_alive_manager.ts} +7 -3
  66. package/src/lib/connection_manager/utils.ts +25 -0
  67. package/src/lib/filter/filter.ts +315 -0
  68. package/src/lib/filter/index.ts +1 -323
  69. package/src/lib/light_push/index.ts +1 -188
  70. package/src/lib/light_push/light_push.ts +188 -0
  71. package/src/lib/light_push/utils.ts +12 -20
  72. package/src/lib/metadata/index.ts +1 -182
  73. package/src/lib/metadata/metadata.ts +182 -0
  74. package/src/lib/store/index.ts +1 -136
  75. package/src/lib/store/store.ts +136 -0
  76. package/src/lib/stream_manager/stream_manager.ts +125 -69
  77. package/src/lib/stream_manager/utils.ts +5 -17
  78. package/bundle/base_protocol-CS0EDeEY.js +0 -260
  79. package/dist/lib/connection_manager.d.ts +0 -62
  80. package/dist/lib/connection_manager.js.map +0 -1
  81. package/dist/lib/filterPeers.d.ts +0 -13
  82. package/dist/lib/filterPeers.js +0 -38
  83. package/dist/lib/filterPeers.js.map +0 -1
  84. package/dist/lib/health_manager.d.ts +0 -14
  85. package/dist/lib/health_manager.js +0 -70
  86. package/dist/lib/health_manager.js.map +0 -1
  87. package/dist/lib/keep_alive_manager.js.map +0 -1
  88. package/dist/lib/wait_for_remote_peer.d.ts +0 -22
  89. package/dist/lib/wait_for_remote_peer.js +0 -142
  90. package/dist/lib/wait_for_remote_peer.js.map +0 -1
  91. package/src/lib/filterPeers.ts +0 -51
  92. package/src/lib/health_manager.ts +0 -90
  93. package/src/lib/wait_for_remote_peer.ts +0 -200
@@ -1,323 +1 @@
1
- import type { Peer, Stream } from "@libp2p/interface";
2
- import type { IncomingStreamData } from "@libp2p/interface-internal";
3
- import {
4
- type ContentTopic,
5
- type CoreProtocolResult,
6
- type IBaseProtocolCore,
7
- type Libp2p,
8
- ProtocolError,
9
- type PubsubTopic
10
- } from "@waku/interfaces";
11
- import { WakuMessage } from "@waku/proto";
12
- import { Logger } from "@waku/utils";
13
- import all from "it-all";
14
- import * as lp from "it-length-prefixed";
15
- import { pipe } from "it-pipe";
16
- import { Uint8ArrayList } from "uint8arraylist";
17
-
18
- import { BaseProtocol } from "../base_protocol.js";
19
-
20
- import {
21
- FilterPushRpc,
22
- FilterSubscribeResponse,
23
- FilterSubscribeRpc
24
- } from "./filter_rpc.js";
25
-
26
- const log = new Logger("filter:v2");
27
-
28
- export const FilterCodecs = {
29
- SUBSCRIBE: "/vac/waku/filter-subscribe/2.0.0-beta1",
30
- PUSH: "/vac/waku/filter-push/2.0.0-beta1"
31
- };
32
-
33
- export class FilterCore extends BaseProtocol implements IBaseProtocolCore {
34
- public constructor(
35
- private handleIncomingMessage: (
36
- pubsubTopic: PubsubTopic,
37
- wakuMessage: WakuMessage,
38
- peerIdStr: string
39
- ) => Promise<void>,
40
- private handleError: (error: Error) => Promise<void>,
41
- public readonly pubsubTopics: PubsubTopic[],
42
- libp2p: Libp2p
43
- ) {
44
- super(FilterCodecs.SUBSCRIBE, libp2p.components, log, pubsubTopics);
45
-
46
- libp2p
47
- .handle(FilterCodecs.PUSH, this.onRequest.bind(this), {
48
- maxInboundStreams: 100
49
- })
50
- .catch((e) => {
51
- log.error("Failed to register ", FilterCodecs.PUSH, e);
52
- });
53
- }
54
-
55
- public async subscribe(
56
- pubsubTopic: PubsubTopic,
57
- peer: Peer,
58
- contentTopics: ContentTopic[]
59
- ): Promise<CoreProtocolResult> {
60
- const stream = await this.getStream(peer);
61
-
62
- const request = FilterSubscribeRpc.createSubscribeRequest(
63
- pubsubTopic,
64
- contentTopics
65
- );
66
-
67
- let res: Uint8ArrayList[] | undefined;
68
- try {
69
- res = await pipe(
70
- [request.encode()],
71
- lp.encode,
72
- stream,
73
- lp.decode,
74
- async (source) => await all(source)
75
- );
76
- } catch (error) {
77
- log.error("Failed to send subscribe request", error);
78
- return {
79
- success: null,
80
- failure: {
81
- error: ProtocolError.GENERIC_FAIL,
82
- peerId: peer.id
83
- }
84
- };
85
- }
86
-
87
- const { statusCode, requestId, statusDesc } =
88
- FilterSubscribeResponse.decode(res[0].slice());
89
-
90
- if (statusCode < 200 || statusCode >= 300) {
91
- log.error(
92
- `Filter subscribe request ${requestId} failed with status code ${statusCode}: ${statusDesc}`
93
- );
94
- return {
95
- failure: {
96
- error: ProtocolError.REMOTE_PEER_REJECTED,
97
- peerId: peer.id
98
- },
99
- success: null
100
- };
101
- }
102
-
103
- return {
104
- failure: null,
105
- success: peer.id
106
- };
107
- }
108
-
109
- public async unsubscribe(
110
- pubsubTopic: PubsubTopic,
111
- peer: Peer,
112
- contentTopics: ContentTopic[]
113
- ): Promise<CoreProtocolResult> {
114
- let stream: Stream | undefined;
115
- try {
116
- stream = await this.getStream(peer);
117
- } catch (error) {
118
- log.error(
119
- `Failed to get a stream for remote peer${peer.id.toString()}`,
120
- error
121
- );
122
- return {
123
- success: null,
124
- failure: {
125
- error: ProtocolError.NO_STREAM_AVAILABLE,
126
- peerId: peer.id
127
- }
128
- };
129
- }
130
-
131
- const unsubscribeRequest = FilterSubscribeRpc.createUnsubscribeRequest(
132
- pubsubTopic,
133
- contentTopics
134
- );
135
-
136
- try {
137
- await pipe([unsubscribeRequest.encode()], lp.encode, stream.sink);
138
- } catch (error) {
139
- log.error("Failed to send unsubscribe request", error);
140
- return {
141
- success: null,
142
- failure: {
143
- error: ProtocolError.GENERIC_FAIL,
144
- peerId: peer.id
145
- }
146
- };
147
- }
148
-
149
- return {
150
- success: peer.id,
151
- failure: null
152
- };
153
- }
154
-
155
- public async unsubscribeAll(
156
- pubsubTopic: PubsubTopic,
157
- peer: Peer
158
- ): Promise<CoreProtocolResult> {
159
- const stream = await this.getStream(peer);
160
-
161
- const request = FilterSubscribeRpc.createUnsubscribeAllRequest(pubsubTopic);
162
-
163
- const res = await pipe(
164
- [request.encode()],
165
- lp.encode,
166
- stream,
167
- lp.decode,
168
- async (source) => await all(source)
169
- );
170
-
171
- if (!res || !res.length) {
172
- return {
173
- failure: {
174
- error: ProtocolError.NO_RESPONSE,
175
- peerId: peer.id
176
- },
177
- success: null
178
- };
179
- }
180
-
181
- const { statusCode, requestId, statusDesc } =
182
- FilterSubscribeResponse.decode(res[0].slice());
183
-
184
- if (statusCode < 200 || statusCode >= 300) {
185
- log.error(
186
- `Filter unsubscribe all request ${requestId} failed with status code ${statusCode}: ${statusDesc}`
187
- );
188
- return {
189
- failure: {
190
- error: ProtocolError.REMOTE_PEER_REJECTED,
191
- peerId: peer.id
192
- },
193
- success: null
194
- };
195
- }
196
-
197
- return {
198
- failure: null,
199
- success: peer.id
200
- };
201
- }
202
-
203
- public async ping(peer: Peer): Promise<CoreProtocolResult> {
204
- let stream: Stream | undefined;
205
- try {
206
- stream = await this.getStream(peer);
207
- } catch (error) {
208
- log.error(
209
- `Failed to get a stream for remote peer${peer.id.toString()}`,
210
- error
211
- );
212
- return {
213
- success: null,
214
- failure: {
215
- error: ProtocolError.NO_STREAM_AVAILABLE,
216
- peerId: peer.id
217
- }
218
- };
219
- }
220
-
221
- const request = FilterSubscribeRpc.createSubscriberPingRequest();
222
-
223
- let res: Uint8ArrayList[] | undefined;
224
- try {
225
- res = await pipe(
226
- [request.encode()],
227
- lp.encode,
228
- stream,
229
- lp.decode,
230
- async (source) => await all(source)
231
- );
232
- } catch (error) {
233
- log.error("Failed to send ping request", error);
234
- return {
235
- success: null,
236
- failure: {
237
- error: ProtocolError.GENERIC_FAIL,
238
- peerId: peer.id
239
- }
240
- };
241
- }
242
-
243
- if (!res || !res.length) {
244
- return {
245
- success: null,
246
- failure: {
247
- error: ProtocolError.NO_RESPONSE,
248
- peerId: peer.id
249
- }
250
- };
251
- }
252
-
253
- const { statusCode, requestId, statusDesc } =
254
- FilterSubscribeResponse.decode(res[0].slice());
255
-
256
- if (statusCode < 200 || statusCode >= 300) {
257
- log.error(
258
- `Filter ping request ${requestId} failed with status code ${statusCode}: ${statusDesc}`
259
- );
260
- return {
261
- success: null,
262
- failure: {
263
- error: ProtocolError.REMOTE_PEER_REJECTED,
264
- peerId: peer.id
265
- }
266
- };
267
- }
268
- return {
269
- success: peer.id,
270
- failure: null
271
- };
272
- }
273
-
274
- private onRequest(streamData: IncomingStreamData): void {
275
- const { connection, stream } = streamData;
276
- const { remotePeer } = connection;
277
- log.info(`Received message from ${remotePeer.toString()}`);
278
- try {
279
- pipe(stream, lp.decode, async (source) => {
280
- for await (const bytes of source) {
281
- const response = FilterPushRpc.decode(bytes.slice());
282
-
283
- const { pubsubTopic, wakuMessage } = response;
284
-
285
- if (!wakuMessage) {
286
- log.error("Received empty message");
287
- return;
288
- }
289
-
290
- if (!pubsubTopic) {
291
- log.error("Pubsub topic missing from push message");
292
- return;
293
- }
294
-
295
- await this.handleIncomingMessage(
296
- pubsubTopic,
297
- wakuMessage,
298
- connection.remotePeer.toString()
299
- );
300
- }
301
- }).then(
302
- () => {
303
- log.info("Receiving pipe closed.");
304
- },
305
- async (e) => {
306
- log.error(
307
- "Error with receiving pipe",
308
- e,
309
- " -- ",
310
- "on peer ",
311
- connection.remotePeer.toString(),
312
- " -- ",
313
- "stream ",
314
- stream
315
- );
316
- await this.handleError(e);
317
- }
318
- );
319
- } catch (e) {
320
- log.error("Error decoding message", e);
321
- }
322
- }
323
- }
1
+ export { FilterCodecs, FilterCore } from "./filter.js";
@@ -1,188 +1 @@
1
- import type { Peer, Stream } from "@libp2p/interface";
2
- import {
3
- type CoreProtocolResult,
4
- type IBaseProtocolCore,
5
- type IEncoder,
6
- type IMessage,
7
- type Libp2p,
8
- ProtocolError,
9
- PubsubTopic,
10
- type ThisOrThat
11
- } from "@waku/interfaces";
12
- import { PushResponse } from "@waku/proto";
13
- import { isMessageSizeUnderCap } from "@waku/utils";
14
- import { Logger } from "@waku/utils";
15
- import all from "it-all";
16
- import * as lp from "it-length-prefixed";
17
- import { pipe } from "it-pipe";
18
- import { Uint8ArrayList } from "uint8arraylist";
19
-
20
- import { BaseProtocol } from "../base_protocol.js";
21
-
22
- import { PushRpc } from "./push_rpc.js";
23
- import { isRLNResponseError, matchRLNErrorMessage } from "./utils.js";
24
-
25
- const log = new Logger("light-push");
26
-
27
- export const LightPushCodec = "/vac/waku/lightpush/2.0.0-beta1";
28
- export { PushResponse };
29
-
30
- type PreparePushMessageResult = ThisOrThat<"query", PushRpc>;
31
-
32
- /**
33
- * Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/).
34
- */
35
- export class LightPushCore extends BaseProtocol implements IBaseProtocolCore {
36
- public constructor(
37
- public readonly pubsubTopics: PubsubTopic[],
38
- libp2p: Libp2p
39
- ) {
40
- super(LightPushCodec, libp2p.components, log, pubsubTopics);
41
- }
42
-
43
- private async preparePushMessage(
44
- encoder: IEncoder,
45
- message: IMessage
46
- ): Promise<PreparePushMessageResult> {
47
- try {
48
- if (!message.payload || message.payload.length === 0) {
49
- log.error("Failed to send waku light push: payload is empty");
50
- return { query: null, error: ProtocolError.EMPTY_PAYLOAD };
51
- }
52
-
53
- if (!(await isMessageSizeUnderCap(encoder, message))) {
54
- log.error("Failed to send waku light push: message is bigger than 1MB");
55
- return { query: null, error: ProtocolError.SIZE_TOO_BIG };
56
- }
57
-
58
- const protoMessage = await encoder.toProtoObj(message);
59
- if (!protoMessage) {
60
- log.error("Failed to encode to protoMessage, aborting push");
61
- return {
62
- query: null,
63
- error: ProtocolError.ENCODE_FAILED
64
- };
65
- }
66
-
67
- const query = PushRpc.createRequest(protoMessage, encoder.pubsubTopic);
68
- return { query, error: null };
69
- } catch (error) {
70
- log.error("Failed to prepare push message", error);
71
-
72
- return {
73
- query: null,
74
- error: ProtocolError.GENERIC_FAIL
75
- };
76
- }
77
- }
78
-
79
- public async send(
80
- encoder: IEncoder,
81
- message: IMessage,
82
- peer: Peer
83
- ): Promise<CoreProtocolResult> {
84
- const { query, error: preparationError } = await this.preparePushMessage(
85
- encoder,
86
- message
87
- );
88
-
89
- if (preparationError || !query) {
90
- return {
91
- success: null,
92
- failure: {
93
- error: preparationError,
94
- peerId: peer.id
95
- }
96
- };
97
- }
98
-
99
- let stream: Stream;
100
- try {
101
- stream = await this.getStream(peer);
102
- } catch (error) {
103
- log.error("Failed to get stream", error);
104
- return {
105
- success: null,
106
- failure: {
107
- error: ProtocolError.NO_STREAM_AVAILABLE,
108
- peerId: peer.id
109
- }
110
- };
111
- }
112
-
113
- let res: Uint8ArrayList[] | undefined;
114
- try {
115
- res = await pipe(
116
- [query.encode()],
117
- lp.encode,
118
- stream,
119
- lp.decode,
120
- async (source) => await all(source)
121
- );
122
- } catch (err) {
123
- log.error("Failed to send waku light push request", err);
124
- return {
125
- success: null,
126
- failure: {
127
- error: ProtocolError.GENERIC_FAIL,
128
- peerId: peer.id
129
- }
130
- };
131
- }
132
-
133
- const bytes = new Uint8ArrayList();
134
- res.forEach((chunk) => {
135
- bytes.append(chunk);
136
- });
137
-
138
- let response: PushResponse | undefined;
139
- try {
140
- response = PushRpc.decode(bytes).response;
141
- } catch (err) {
142
- log.error("Failed to decode push reply", err);
143
- return {
144
- success: null,
145
- failure: {
146
- error: ProtocolError.DECODE_FAILED,
147
- peerId: peer.id
148
- }
149
- };
150
- }
151
-
152
- if (!response) {
153
- log.error("Remote peer fault: No response in PushRPC");
154
- return {
155
- success: null,
156
- failure: {
157
- error: ProtocolError.NO_RESPONSE,
158
- peerId: peer.id
159
- }
160
- };
161
- }
162
-
163
- if (isRLNResponseError(response.info)) {
164
- const rlnErrorCase = matchRLNErrorMessage(response.info!);
165
- log.error("Remote peer rejected the message: ", rlnErrorCase);
166
- return {
167
- success: null,
168
- failure: {
169
- error: rlnErrorCase,
170
- peerId: peer.id
171
- }
172
- };
173
- }
174
-
175
- if (!response.isSuccess) {
176
- log.error("Remote peer rejected the message: ", response.info);
177
- return {
178
- success: null,
179
- failure: {
180
- error: ProtocolError.REMOTE_PEER_REJECTED,
181
- peerId: peer.id
182
- }
183
- };
184
- }
185
-
186
- return { success: peer.id, failure: null };
187
- }
188
- }
1
+ export { LightPushCore, LightPushCodec, PushResponse } from "./light_push.js";
@@ -0,0 +1,188 @@
1
+ import type { PeerId, Stream } from "@libp2p/interface";
2
+ import {
3
+ type CoreProtocolResult,
4
+ type IBaseProtocolCore,
5
+ type IEncoder,
6
+ type IMessage,
7
+ type Libp2p,
8
+ ProtocolError,
9
+ PubsubTopic,
10
+ type ThisOrThat
11
+ } from "@waku/interfaces";
12
+ import { PushResponse } from "@waku/proto";
13
+ import { isMessageSizeUnderCap } from "@waku/utils";
14
+ import { Logger } from "@waku/utils";
15
+ import all from "it-all";
16
+ import * as lp from "it-length-prefixed";
17
+ import { pipe } from "it-pipe";
18
+ import { Uint8ArrayList } from "uint8arraylist";
19
+
20
+ import { BaseProtocol } from "../base_protocol.js";
21
+
22
+ import { PushRpc } from "./push_rpc.js";
23
+ import { isRLNResponseError } from "./utils.js";
24
+
25
+ const log = new Logger("light-push");
26
+
27
+ export const LightPushCodec = "/vac/waku/lightpush/2.0.0-beta1";
28
+ export { PushResponse };
29
+
30
+ type PreparePushMessageResult = ThisOrThat<"query", PushRpc>;
31
+
32
+ /**
33
+ * Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/).
34
+ */
35
+ export class LightPushCore extends BaseProtocol implements IBaseProtocolCore {
36
+ public constructor(
37
+ public readonly pubsubTopics: PubsubTopic[],
38
+ libp2p: Libp2p
39
+ ) {
40
+ super(LightPushCodec, libp2p.components, pubsubTopics);
41
+ }
42
+
43
+ private async preparePushMessage(
44
+ encoder: IEncoder,
45
+ message: IMessage
46
+ ): Promise<PreparePushMessageResult> {
47
+ try {
48
+ if (!message.payload || message.payload.length === 0) {
49
+ log.error("Failed to send waku light push: payload is empty");
50
+ return { query: null, error: ProtocolError.EMPTY_PAYLOAD };
51
+ }
52
+
53
+ if (!(await isMessageSizeUnderCap(encoder, message))) {
54
+ log.error("Failed to send waku light push: message is bigger than 1MB");
55
+ return { query: null, error: ProtocolError.SIZE_TOO_BIG };
56
+ }
57
+
58
+ const protoMessage = await encoder.toProtoObj(message);
59
+ if (!protoMessage) {
60
+ log.error("Failed to encode to protoMessage, aborting push");
61
+ return {
62
+ query: null,
63
+ error: ProtocolError.ENCODE_FAILED
64
+ };
65
+ }
66
+
67
+ const query = PushRpc.createRequest(protoMessage, encoder.pubsubTopic);
68
+ return { query, error: null };
69
+ } catch (error) {
70
+ log.error("Failed to prepare push message", error);
71
+
72
+ return {
73
+ query: null,
74
+ error: ProtocolError.GENERIC_FAIL
75
+ };
76
+ }
77
+ }
78
+
79
+ public async send(
80
+ encoder: IEncoder,
81
+ message: IMessage,
82
+ peerId: PeerId
83
+ ): Promise<CoreProtocolResult> {
84
+ const { query, error: preparationError } = await this.preparePushMessage(
85
+ encoder,
86
+ message
87
+ );
88
+
89
+ if (preparationError || !query) {
90
+ return {
91
+ success: null,
92
+ failure: {
93
+ error: preparationError,
94
+ peerId
95
+ }
96
+ };
97
+ }
98
+
99
+ let stream: Stream;
100
+ try {
101
+ stream = await this.getStream(peerId);
102
+ } catch (error) {
103
+ log.error("Failed to get stream", error);
104
+ return {
105
+ success: null,
106
+ failure: {
107
+ error: ProtocolError.NO_STREAM_AVAILABLE,
108
+ peerId: peerId
109
+ }
110
+ };
111
+ }
112
+
113
+ let res: Uint8ArrayList[] | undefined;
114
+ try {
115
+ res = await pipe(
116
+ [query.encode()],
117
+ lp.encode,
118
+ stream,
119
+ lp.decode,
120
+ async (source) => await all(source)
121
+ );
122
+ } catch (err) {
123
+ // can fail only because of `stream` abortion
124
+ log.error("Failed to send waku light push request", err);
125
+ return {
126
+ success: null,
127
+ failure: {
128
+ error: ProtocolError.STREAM_ABORTED,
129
+ peerId: peerId
130
+ }
131
+ };
132
+ }
133
+
134
+ const bytes = new Uint8ArrayList();
135
+ res.forEach((chunk) => {
136
+ bytes.append(chunk);
137
+ });
138
+
139
+ let response: PushResponse | undefined;
140
+ try {
141
+ response = PushRpc.decode(bytes).response;
142
+ } catch (err) {
143
+ log.error("Failed to decode push reply", err);
144
+ return {
145
+ success: null,
146
+ failure: {
147
+ error: ProtocolError.DECODE_FAILED,
148
+ peerId: peerId
149
+ }
150
+ };
151
+ }
152
+
153
+ if (!response) {
154
+ log.error("Remote peer fault: No response in PushRPC");
155
+ return {
156
+ success: null,
157
+ failure: {
158
+ error: ProtocolError.NO_RESPONSE,
159
+ peerId: peerId
160
+ }
161
+ };
162
+ }
163
+
164
+ if (isRLNResponseError(response.info)) {
165
+ log.error("Remote peer fault: RLN generation");
166
+ return {
167
+ success: null,
168
+ failure: {
169
+ error: ProtocolError.RLN_PROOF_GENERATION,
170
+ peerId: peerId
171
+ }
172
+ };
173
+ }
174
+
175
+ if (!response.isSuccess) {
176
+ log.error("Remote peer rejected the message: ", response.info);
177
+ return {
178
+ success: null,
179
+ failure: {
180
+ error: ProtocolError.REMOTE_PEER_REJECTED,
181
+ peerId: peerId
182
+ }
183
+ };
184
+ }
185
+
186
+ return { success: peerId, failure: null };
187
+ }
188
+ }