@waku/core 0.0.5 → 0.0.7
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/CHANGELOG.md +51 -3
- package/bundle/index.js +31146 -26342
- package/bundle/lib/message/topic_only_message.js +33 -0
- package/bundle/lib/message/version_0.js +133 -0
- package/bundle/lib/predefined_bootstrap_nodes.js +24 -4
- package/bundle/{message-049c8b67.js → peer_exchange-53df2b11.js} +3579 -1007
- package/dist/index.d.ts +14 -13
- package/dist/index.js +11 -10
- package/dist/index.js.map +1 -1
- package/dist/lib/{waku_filter → filter}/filter_rpc.d.ts +1 -1
- package/dist/lib/{waku_filter → filter}/filter_rpc.js +1 -1
- package/dist/lib/filter/filter_rpc.js.map +1 -0
- package/dist/lib/filter/index.d.ts +25 -0
- package/dist/lib/{waku_filter → filter}/index.js +14 -9
- package/dist/lib/filter/index.js.map +1 -0
- package/dist/lib/light_push/index.d.ts +22 -0
- package/dist/lib/{waku_light_push → light_push}/index.js +14 -9
- package/dist/lib/light_push/index.js.map +1 -0
- package/dist/lib/{waku_light_push → light_push}/push_rpc.d.ts +1 -1
- package/dist/lib/{waku_light_push → light_push}/push_rpc.js +1 -1
- package/dist/lib/light_push/push_rpc.js.map +1 -0
- package/dist/lib/message/topic_only_message.d.ts +16 -0
- package/dist/lib/{waku_message → message}/topic_only_message.js +2 -1
- package/dist/lib/message/topic_only_message.js.map +1 -0
- package/dist/lib/message/version_0.d.ts +54 -0
- package/dist/lib/{waku_message → message}/version_0.js +41 -6
- package/dist/lib/message/version_0.js.map +1 -0
- package/dist/lib/predefined_bootstrap_nodes.d.ts +1 -2
- package/dist/lib/predefined_bootstrap_nodes.js +0 -2
- package/dist/lib/predefined_bootstrap_nodes.js.map +1 -1
- package/dist/lib/{waku_relay → relay}/constants.d.ts +0 -0
- package/dist/lib/{waku_relay → relay}/constants.js +0 -0
- package/dist/lib/relay/constants.js.map +1 -0
- package/dist/lib/relay/index.d.ts +24 -0
- package/dist/lib/{waku_relay → relay}/index.js +9 -6
- package/dist/lib/relay/index.js.map +1 -0
- package/dist/lib/{waku_store → store}/history_rpc.d.ts +1 -1
- package/dist/lib/{waku_store → store}/history_rpc.js +1 -1
- package/dist/lib/store/history_rpc.js.map +1 -0
- package/dist/lib/store/index.d.ts +68 -0
- package/dist/lib/{waku_store → store}/index.js +41 -16
- package/dist/lib/store/index.js.map +1 -0
- package/dist/lib/to_proto_message.d.ts +3 -3
- package/dist/lib/to_proto_message.js +1 -0
- package/dist/lib/to_proto_message.js.map +1 -1
- package/dist/lib/wait_for_remote_peer.js +14 -5
- package/dist/lib/wait_for_remote_peer.js.map +1 -1
- package/dist/lib/waku.d.ts +17 -15
- package/dist/lib/waku.js +49 -41
- package/dist/lib/waku.js.map +1 -1
- package/package.json +28 -31
- package/src/index.ts +25 -14
- package/src/lib/{waku_filter → filter}/filter_rpc.ts +1 -2
- package/src/lib/{waku_filter → filter}/index.ts +51 -30
- package/src/lib/{waku_light_push → light_push}/index.ts +38 -19
- package/src/lib/{waku_light_push → light_push}/push_rpc.ts +1 -2
- package/src/lib/{waku_message → message}/topic_only_message.ts +12 -7
- package/src/lib/{waku_message → message}/version_0.ts +59 -18
- package/src/lib/predefined_bootstrap_nodes.ts +2 -6
- package/src/lib/{waku_relay → relay}/constants.ts +0 -0
- package/src/lib/{waku_relay → relay}/index.ts +30 -26
- package/src/lib/{waku_store → store}/history_rpc.ts +1 -2
- package/src/lib/{waku_store → store}/index.ts +93 -28
- package/src/lib/to_proto_message.ts +5 -5
- package/src/lib/wait_for_remote_peer.ts +19 -7
- package/src/lib/waku.ts +78 -51
- package/bundle/browser-1e1a2f27.js +0 -722
- package/bundle/events-158407bb.js +0 -1929
- package/bundle/index-64ce43f0.js +0 -69
- package/bundle/index-8710041d.js +0 -2962
- package/bundle/index-a67d7136.js +0 -4059
- package/bundle/lib/peer_discovery_static_list.js +0 -89
- package/bundle/lib/wait_for_remote_peer.js +0 -326
- package/bundle/lib/waku_message/topic_only_message.js +0 -3
- package/bundle/lib/waku_message/version_0.js +0 -317
- package/bundle/random_subset-75d1c511.js +0 -26
- package/bundle/topic_only_message-5ad3a869.js +0 -82
- package/dist/lib/multiaddr_to_peer_info.d.ts +0 -3
- package/dist/lib/multiaddr_to_peer_info.js +0 -15
- package/dist/lib/multiaddr_to_peer_info.js.map +0 -1
- package/dist/lib/peer_discovery_static_list.d.ts +0 -44
- package/dist/lib/peer_discovery_static_list.js +0 -72
- package/dist/lib/peer_discovery_static_list.js.map +0 -1
- package/dist/lib/select_connection.d.ts +0 -2
- package/dist/lib/select_connection.js +0 -19
- package/dist/lib/select_connection.js.map +0 -1
- package/dist/lib/select_peer.d.ts +0 -15
- package/dist/lib/select_peer.js +0 -59
- package/dist/lib/select_peer.js.map +0 -1
- package/dist/lib/waku_filter/filter_rpc.js.map +0 -1
- package/dist/lib/waku_filter/index.d.ts +0 -50
- package/dist/lib/waku_filter/index.js.map +0 -1
- package/dist/lib/waku_light_push/index.d.ts +0 -38
- package/dist/lib/waku_light_push/index.js.map +0 -1
- package/dist/lib/waku_light_push/push_rpc.js.map +0 -1
- package/dist/lib/waku_message/topic_only_message.d.ts +0 -15
- package/dist/lib/waku_message/topic_only_message.js.map +0 -1
- package/dist/lib/waku_message/version_0.d.ts +0 -27
- package/dist/lib/waku_message/version_0.js.map +0 -1
- package/dist/lib/waku_relay/constants.js.map +0 -1
- package/dist/lib/waku_relay/index.d.ts +0 -66
- package/dist/lib/waku_relay/index.js.map +0 -1
- package/dist/lib/waku_store/history_rpc.js.map +0 -1
- package/dist/lib/waku_store/index.d.ts +0 -126
- package/dist/lib/waku_store/index.js.map +0 -1
- package/dist/proto/filter.d.ts +0 -65
- package/dist/proto/filter.js +0 -425
- package/dist/proto/filter.js.map +0 -1
- package/dist/proto/light_push.d.ts +0 -57
- package/dist/proto/light_push.js +0 -369
- package/dist/proto/light_push.js.map +0 -1
- package/dist/proto/message.d.ts +0 -29
- package/dist/proto/message.js +0 -215
- package/dist/proto/message.js.map +0 -1
- package/dist/proto/store.d.ts +0 -104
- package/dist/proto/store.js +0 -602
- package/dist/proto/store.js.map +0 -1
- package/dist/proto/topic_only_message.d.ts +0 -10
- package/dist/proto/topic_only_message.js +0 -46
- package/dist/proto/topic_only_message.js.map +0 -1
- package/src/lib/multiaddr_to_peer_info.ts +0 -17
- package/src/lib/peer_discovery_static_list.ts +0 -118
- package/src/lib/select_connection.ts +0 -24
- package/src/lib/select_peer.ts +0 -77
- package/src/proto/filter.ts +0 -602
- package/src/proto/light_push.ts +0 -526
- package/src/proto/message.ts +0 -304
- package/src/proto/store.ts +0 -844
- package/src/proto/topic_only_message.ts +0 -67
@@ -1,22 +1,21 @@
|
|
1
1
|
import type {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
IDecodedMessage,
|
3
|
+
IDecoder,
|
4
|
+
IEncoder,
|
5
|
+
IMessage,
|
6
|
+
IProtoMessage,
|
7
|
+
IRateLimitProof,
|
8
8
|
} from "@waku/interfaces";
|
9
|
+
import { proto_message as proto } from "@waku/proto";
|
9
10
|
import debug from "debug";
|
10
11
|
|
11
|
-
import * as proto from "../../proto/message";
|
12
|
-
|
13
12
|
const log = debug("waku:message:version-0");
|
14
13
|
const OneMillion = BigInt(1_000_000);
|
15
14
|
|
16
15
|
export const Version = 0;
|
17
16
|
export { proto };
|
18
17
|
|
19
|
-
export class
|
18
|
+
export class DecodedMessage implements IDecodedMessage {
|
20
19
|
constructor(protected proto: proto.WakuMessage) {}
|
21
20
|
|
22
21
|
get _rawPayload(): Uint8Array | undefined {
|
@@ -26,6 +25,10 @@ export class MessageV0 implements DecodedMessage {
|
|
26
25
|
return;
|
27
26
|
}
|
28
27
|
|
28
|
+
get ephemeral(): boolean {
|
29
|
+
return Boolean(this.proto.ephemeral);
|
30
|
+
}
|
31
|
+
|
29
32
|
get payload(): Uint8Array | undefined {
|
30
33
|
return this._rawPayload;
|
31
34
|
}
|
@@ -62,19 +65,19 @@ export class MessageV0 implements DecodedMessage {
|
|
62
65
|
return this.proto.version ?? 0;
|
63
66
|
}
|
64
67
|
|
65
|
-
get rateLimitProof():
|
68
|
+
get rateLimitProof(): IRateLimitProof | undefined {
|
66
69
|
return this.proto.rateLimitProof;
|
67
70
|
}
|
68
71
|
}
|
69
72
|
|
70
|
-
export class
|
71
|
-
constructor(public contentTopic: string) {}
|
73
|
+
export class Encoder implements IEncoder {
|
74
|
+
constructor(public contentTopic: string, public ephemeral: boolean = false) {}
|
72
75
|
|
73
|
-
async toWire(message:
|
76
|
+
async toWire(message: IMessage): Promise<Uint8Array> {
|
74
77
|
return proto.WakuMessage.encode(await this.toProtoObj(message));
|
75
78
|
}
|
76
79
|
|
77
|
-
async toProtoObj(message:
|
80
|
+
async toProtoObj(message: IMessage): Promise<IProtoMessage> {
|
78
81
|
const timestamp = message.timestamp ?? new Date();
|
79
82
|
|
80
83
|
return {
|
@@ -83,14 +86,34 @@ export class EncoderV0 implements Encoder {
|
|
83
86
|
contentTopic: this.contentTopic,
|
84
87
|
timestamp: BigInt(timestamp.valueOf()) * OneMillion,
|
85
88
|
rateLimitProof: message.rateLimitProof,
|
89
|
+
ephemeral: this.ephemeral,
|
86
90
|
};
|
87
91
|
}
|
88
92
|
}
|
89
93
|
|
90
|
-
|
94
|
+
/**
|
95
|
+
* Creates an encoder that encode messages without Waku level encryption or signature.
|
96
|
+
*
|
97
|
+
* An encoder is used to encode messages in the [`14/WAKU2-MESSAGE](https://rfc.vac.dev/spec/14/)
|
98
|
+
* format to be sent over the Waku network. The resulting encoder can then be
|
99
|
+
* pass to { @link @waku/interfaces.LightPush.push } or
|
100
|
+
* { @link @waku/interfaces.Relay.send } to automatically encode outgoing
|
101
|
+
* messages.
|
102
|
+
*
|
103
|
+
* @param contentTopic The content topic to set on outgoing messages.
|
104
|
+
* @param ephemeral An optional flag to mark message as ephemeral, ie, not to be stored by Waku Store nodes.
|
105
|
+
*/
|
106
|
+
export function createEncoder(
|
107
|
+
contentTopic: string,
|
108
|
+
ephemeral = false
|
109
|
+
): Encoder {
|
110
|
+
return new Encoder(contentTopic, ephemeral);
|
111
|
+
}
|
112
|
+
|
113
|
+
export class Decoder implements IDecoder<DecodedMessage> {
|
91
114
|
constructor(public contentTopic: string) {}
|
92
115
|
|
93
|
-
fromWireToProtoObj(bytes: Uint8Array): Promise<
|
116
|
+
fromWireToProtoObj(bytes: Uint8Array): Promise<IProtoMessage | undefined> {
|
94
117
|
const protoMessage = proto.WakuMessage.decode(bytes);
|
95
118
|
log("Message decoded", protoMessage);
|
96
119
|
return Promise.resolve({
|
@@ -99,10 +122,13 @@ export class DecoderV0 implements Decoder<MessageV0> {
|
|
99
122
|
version: protoMessage.version ?? undefined,
|
100
123
|
timestamp: protoMessage.timestamp ?? undefined,
|
101
124
|
rateLimitProof: protoMessage.rateLimitProof ?? undefined,
|
125
|
+
ephemeral: protoMessage.ephemeral ?? false,
|
102
126
|
});
|
103
127
|
}
|
104
128
|
|
105
|
-
async fromProtoObj(
|
129
|
+
async fromProtoObj(
|
130
|
+
proto: IProtoMessage
|
131
|
+
): Promise<DecodedMessage | undefined> {
|
106
132
|
// https://github.com/status-im/js-waku/issues/921
|
107
133
|
if (proto.version === undefined) {
|
108
134
|
proto.version = 0;
|
@@ -118,6 +144,21 @@ export class DecoderV0 implements Decoder<MessageV0> {
|
|
118
144
|
return Promise.resolve(undefined);
|
119
145
|
}
|
120
146
|
|
121
|
-
return new
|
147
|
+
return new DecodedMessage(proto);
|
122
148
|
}
|
123
149
|
}
|
150
|
+
|
151
|
+
/**
|
152
|
+
* Creates an decoder that decode messages without Waku level encryption.
|
153
|
+
*
|
154
|
+
* A decoder is used to decode messages from the [14/WAKU2-MESSAGE](https://rfc.vac.dev/spec/14/)
|
155
|
+
* format when received from the Waku network. The resulting decoder can then be
|
156
|
+
* pass to { @link @waku/interfaces.Filter.subscribe } or
|
157
|
+
* { @link @waku/interfaces.Relay.subscribe } to automatically decode incoming
|
158
|
+
* messages.
|
159
|
+
*
|
160
|
+
* @param contentTopic The resulting decoder will only decode messages with this content topic.
|
161
|
+
*/
|
162
|
+
export function createDecoder(contentTopic: string): Decoder {
|
163
|
+
return new Decoder(contentTopic);
|
164
|
+
}
|
@@ -1,7 +1,4 @@
|
|
1
|
-
import
|
2
|
-
import { multiaddr } from "@multiformats/multiaddr";
|
3
|
-
|
4
|
-
import { getPseudoRandomSubset } from "./random_subset";
|
1
|
+
import { getPseudoRandomSubset } from "./random_subset.js";
|
5
2
|
|
6
3
|
export const DefaultWantedNumber = 1;
|
7
4
|
|
@@ -23,7 +20,7 @@ export enum Fleet {
|
|
23
20
|
export function getPredefinedBootstrapNodes(
|
24
21
|
fleet: Fleet = Fleet.Prod,
|
25
22
|
wantedNumber: number = DefaultWantedNumber
|
26
|
-
):
|
23
|
+
): string[] {
|
27
24
|
if (wantedNumber <= 0) {
|
28
25
|
return [];
|
29
26
|
}
|
@@ -42,7 +39,6 @@ export function getPredefinedBootstrapNodes(
|
|
42
39
|
|
43
40
|
nodes = Object.values(nodes) as string[];
|
44
41
|
|
45
|
-
nodes = nodes.map((node: string) => multiaddr(node));
|
46
42
|
return getPseudoRandomSubset(nodes, wantedNumber);
|
47
43
|
}
|
48
44
|
|
File without changes
|
@@ -1,34 +1,32 @@
|
|
1
1
|
import {
|
2
2
|
GossipSub,
|
3
|
+
GossipSubComponents,
|
3
4
|
GossipsubMessage,
|
4
5
|
GossipsubOpts,
|
5
6
|
} from "@chainsafe/libp2p-gossipsub";
|
6
|
-
import {
|
7
|
-
PeerIdStr,
|
8
|
-
TopicStr,
|
9
|
-
} from "@chainsafe/libp2p-gossipsub/dist/src/types";
|
7
|
+
import type { PeerIdStr, TopicStr } from "@chainsafe/libp2p-gossipsub/types";
|
10
8
|
import { SignaturePolicy } from "@chainsafe/libp2p-gossipsub/types";
|
11
9
|
import type {
|
12
10
|
Callback,
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
IDecoder,
|
12
|
+
IEncoder,
|
13
|
+
IMessage,
|
14
|
+
IRelay,
|
17
15
|
SendResult,
|
18
16
|
} from "@waku/interfaces";
|
19
|
-
import {
|
17
|
+
import { IDecodedMessage } from "@waku/interfaces";
|
20
18
|
import debug from "debug";
|
21
19
|
|
22
|
-
import { DefaultPubSubTopic } from "../constants";
|
23
|
-
import {
|
24
|
-
import {
|
20
|
+
import { DefaultPubSubTopic } from "../constants.js";
|
21
|
+
import { TopicOnlyDecoder } from "../message/topic_only_message.js";
|
22
|
+
import { pushOrInitMapSet } from "../push_or_init_map.js";
|
25
23
|
|
26
|
-
import * as constants from "./constants";
|
24
|
+
import * as constants from "./constants.js";
|
27
25
|
|
28
26
|
const log = debug("waku:relay");
|
29
27
|
|
30
|
-
export type Observer<T extends
|
31
|
-
decoder:
|
28
|
+
export type Observer<T extends IDecodedMessage> = {
|
29
|
+
decoder: IDecoder<T>;
|
32
30
|
callback: Callback<T>;
|
33
31
|
};
|
34
32
|
|
@@ -55,9 +53,9 @@ export type CreateOptions = {
|
|
55
53
|
*
|
56
54
|
* @implements {require('libp2p-interfaces/src/pubsub')}
|
57
55
|
*/
|
58
|
-
|
56
|
+
class Relay extends GossipSub implements IRelay {
|
59
57
|
pubSubTopic: string;
|
60
|
-
defaultDecoder:
|
58
|
+
defaultDecoder: IDecoder<IDecodedMessage>;
|
61
59
|
public static multicodec: string = constants.RelayCodecs[0];
|
62
60
|
|
63
61
|
/**
|
@@ -66,13 +64,16 @@ export class WakuRelay extends GossipSub implements Relay {
|
|
66
64
|
*/
|
67
65
|
public observers: Map<string, Set<Observer<any>>>;
|
68
66
|
|
69
|
-
constructor(
|
67
|
+
constructor(
|
68
|
+
components: GossipSubComponents,
|
69
|
+
options?: Partial<CreateOptions>
|
70
|
+
) {
|
70
71
|
options = Object.assign(options ?? {}, {
|
71
72
|
// Ensure that no signature is included nor expected in the messages.
|
72
73
|
globalSignaturePolicy: SignaturePolicy.StrictNoSign,
|
73
74
|
fallbackToFloodsub: false,
|
74
75
|
});
|
75
|
-
super(options);
|
76
|
+
super(components, options);
|
76
77
|
this.multicodecs = constants.RelayCodecs;
|
77
78
|
|
78
79
|
this.observers = new Map();
|
@@ -98,10 +99,7 @@ export class WakuRelay extends GossipSub implements Relay {
|
|
98
99
|
/**
|
99
100
|
* Send Waku message.
|
100
101
|
*/
|
101
|
-
public async send(
|
102
|
-
encoder: Encoder,
|
103
|
-
message: Partial<Message>
|
104
|
-
): Promise<SendResult> {
|
102
|
+
public async send(encoder: IEncoder, message: IMessage): Promise<SendResult> {
|
105
103
|
const msg = await encoder.toWire(message);
|
106
104
|
if (!msg) {
|
107
105
|
log("Failed to encode message, aborting publish");
|
@@ -115,8 +113,8 @@ export class WakuRelay extends GossipSub implements Relay {
|
|
115
113
|
*
|
116
114
|
* @returns Function to delete the observer
|
117
115
|
*/
|
118
|
-
addObserver<T extends
|
119
|
-
decoder:
|
116
|
+
addObserver<T extends IDecodedMessage>(
|
117
|
+
decoder: IDecoder<T>,
|
120
118
|
callback: Callback<T>
|
121
119
|
): () => void {
|
122
120
|
const observer = {
|
@@ -187,4 +185,10 @@ export class WakuRelay extends GossipSub implements Relay {
|
|
187
185
|
}
|
188
186
|
}
|
189
187
|
|
190
|
-
|
188
|
+
Relay.multicodec = constants.RelayCodecs[constants.RelayCodecs.length - 1];
|
189
|
+
|
190
|
+
export function wakuRelay(
|
191
|
+
init: Partial<CreateOptions> = {}
|
192
|
+
): (components: GossipSubComponents) => IRelay {
|
193
|
+
return (components: GossipSubComponents) => new Relay(components, init);
|
194
|
+
}
|
@@ -1,8 +1,7 @@
|
|
1
|
+
import { proto_store as proto } from "@waku/proto";
|
1
2
|
import type { Uint8ArrayList } from "uint8arraylist";
|
2
3
|
import { v4 as uuid } from "uuid";
|
3
4
|
|
4
|
-
import * as proto from "../../proto/store";
|
5
|
-
|
6
5
|
const OneMillion = BigInt(1_000_000);
|
7
6
|
|
8
7
|
export enum PageDirection {
|
@@ -1,21 +1,32 @@
|
|
1
1
|
import type { Connection } from "@libp2p/interface-connection";
|
2
|
+
import type { ConnectionManager } from "@libp2p/interface-connection-manager";
|
2
3
|
import type { PeerId } from "@libp2p/interface-peer-id";
|
3
|
-
import { Peer } from "@libp2p/interface-peer-store";
|
4
|
-
import {
|
4
|
+
import type { Peer, PeerStore } from "@libp2p/interface-peer-store";
|
5
|
+
import { sha256 } from "@noble/hashes/sha256";
|
6
|
+
import { concat, utf8ToBytes } from "@waku/byte-utils";
|
7
|
+
import {
|
8
|
+
Cursor,
|
9
|
+
IDecodedMessage,
|
10
|
+
IDecoder,
|
11
|
+
Index,
|
12
|
+
IStore,
|
13
|
+
} from "@waku/interfaces";
|
14
|
+
import {
|
15
|
+
getPeersForProtocol,
|
16
|
+
selectConnection,
|
17
|
+
selectPeerForProtocol,
|
18
|
+
} from "@waku/libp2p-utils";
|
19
|
+
import { proto_store as proto } from "@waku/proto";
|
5
20
|
import debug from "debug";
|
6
21
|
import all from "it-all";
|
7
22
|
import * as lp from "it-length-prefixed";
|
8
23
|
import { pipe } from "it-pipe";
|
9
|
-
import { Libp2p } from "libp2p";
|
10
24
|
import { Uint8ArrayList } from "uint8arraylist";
|
11
25
|
|
12
|
-
import
|
13
|
-
import {
|
14
|
-
import { selectConnection } from "../select_connection";
|
15
|
-
import { getPeersForProtocol, selectPeerForProtocol } from "../select_peer";
|
16
|
-
import { toProtoMessage } from "../to_proto_message";
|
26
|
+
import { DefaultPubSubTopic } from "../constants.js";
|
27
|
+
import { toProtoMessage } from "../to_proto_message.js";
|
17
28
|
|
18
|
-
import { HistoryRPC, PageDirection, Params } from "./history_rpc";
|
29
|
+
import { HistoryRPC, PageDirection, Params } from "./history_rpc.js";
|
19
30
|
|
20
31
|
import HistoryError = proto.HistoryResponse.HistoryError;
|
21
32
|
|
@@ -27,6 +38,11 @@ export const DefaultPageSize = 10;
|
|
27
38
|
|
28
39
|
export { PageDirection };
|
29
40
|
|
41
|
+
export interface StoreComponents {
|
42
|
+
peerStore: PeerStore;
|
43
|
+
connectionManager: ConnectionManager;
|
44
|
+
}
|
45
|
+
|
30
46
|
export interface CreateOptions {
|
31
47
|
/**
|
32
48
|
* The PubSub Topic to use. Defaults to {@link DefaultPubSubTopic}.
|
@@ -75,6 +91,12 @@ export interface QueryOptions {
|
|
75
91
|
* Retrieve messages with a timestamp within the provided values.
|
76
92
|
*/
|
77
93
|
timeFilter?: TimeFilter;
|
94
|
+
/**
|
95
|
+
* Cursor as an index to start a query from.
|
96
|
+
* The cursor index will be exclusive (i.e. the message at the cursor index will not be included in the result).
|
97
|
+
* If undefined, the query will start from the beginning or end of the history, depending on the page direction.
|
98
|
+
*/
|
99
|
+
cursor?: Cursor;
|
78
100
|
}
|
79
101
|
|
80
102
|
/**
|
@@ -82,10 +104,10 @@ export interface QueryOptions {
|
|
82
104
|
*
|
83
105
|
* The Waku Store protocol can be used to retrieved historical messages.
|
84
106
|
*/
|
85
|
-
|
107
|
+
class Store implements IStore {
|
86
108
|
pubSubTopic: string;
|
87
109
|
|
88
|
-
constructor(public
|
110
|
+
constructor(public components: StoreComponents, options?: CreateOptions) {
|
89
111
|
this.pubSubTopic = options?.pubSubTopic ?? DefaultPubSubTopic;
|
90
112
|
}
|
91
113
|
|
@@ -106,8 +128,8 @@ export class WakuStore {
|
|
106
128
|
* or if an error is encountered when processing the reply,
|
107
129
|
* or if two decoders with the same content topic are passed.
|
108
130
|
*/
|
109
|
-
async queryOrderedCallback<T extends
|
110
|
-
decoders:
|
131
|
+
async queryOrderedCallback<T extends IDecodedMessage>(
|
132
|
+
decoders: IDecoder<T>[],
|
111
133
|
callback: (message: T) => Promise<void | boolean> | boolean | void,
|
112
134
|
options?: QueryOptions
|
113
135
|
): Promise<void> {
|
@@ -155,8 +177,8 @@ export class WakuStore {
|
|
155
177
|
* or if an error is encountered when processing the reply,
|
156
178
|
* or if two decoders with the same content topic are passed.
|
157
179
|
*/
|
158
|
-
async queryCallbackOnPromise<T extends
|
159
|
-
decoders:
|
180
|
+
async queryCallbackOnPromise<T extends IDecodedMessage>(
|
181
|
+
decoders: IDecoder<T>[],
|
160
182
|
callback: (
|
161
183
|
message: Promise<T | undefined>
|
162
184
|
) => Promise<void | boolean> | boolean | void,
|
@@ -193,8 +215,8 @@ export class WakuStore {
|
|
193
215
|
* or if an error is encountered when processing the reply,
|
194
216
|
* or if two decoders with the same content topic are passed.
|
195
217
|
*/
|
196
|
-
async *queryGenerator<T extends
|
197
|
-
decoders:
|
218
|
+
async *queryGenerator<T extends IDecodedMessage>(
|
219
|
+
decoders: IDecoder<T>[],
|
198
220
|
options?: QueryOptions
|
199
221
|
): AsyncGenerator<Promise<T | undefined>[]> {
|
200
222
|
let startTime, endTime;
|
@@ -227,12 +249,12 @@ export class WakuStore {
|
|
227
249
|
);
|
228
250
|
|
229
251
|
log("Querying history with the following options", {
|
230
|
-
peerId: options?.peerId?.toString(),
|
231
252
|
...options,
|
253
|
+
peerId: options?.peerId?.toString(),
|
232
254
|
});
|
233
255
|
|
234
256
|
const res = await selectPeerForProtocol(
|
235
|
-
this.
|
257
|
+
this.components.peerStore,
|
236
258
|
[StoreCodec],
|
237
259
|
options?.peerId
|
238
260
|
);
|
@@ -242,7 +264,9 @@ export class WakuStore {
|
|
242
264
|
}
|
243
265
|
const { peer, protocol } = res;
|
244
266
|
|
245
|
-
const connections = this.
|
267
|
+
const connections = this.components.connectionManager.getConnections(
|
268
|
+
peer.id
|
269
|
+
);
|
246
270
|
const connection = selectConnection(connections);
|
247
271
|
|
248
272
|
if (!connection) throw "Failed to get a connection to the peer";
|
@@ -251,7 +275,8 @@ export class WakuStore {
|
|
251
275
|
connection,
|
252
276
|
protocol,
|
253
277
|
queryOpts,
|
254
|
-
decodersAsMap
|
278
|
+
decodersAsMap,
|
279
|
+
options?.cursor
|
255
280
|
)) {
|
256
281
|
yield messages;
|
257
282
|
}
|
@@ -262,15 +287,20 @@ export class WakuStore {
|
|
262
287
|
* store protocol. Waku may or may not be currently connected to these peers.
|
263
288
|
*/
|
264
289
|
async peers(): Promise<Peer[]> {
|
265
|
-
return getPeersForProtocol(this.
|
290
|
+
return getPeersForProtocol(this.components.peerStore, [StoreCodec]);
|
291
|
+
}
|
292
|
+
|
293
|
+
get peerStore(): PeerStore {
|
294
|
+
return this.components.peerStore;
|
266
295
|
}
|
267
296
|
}
|
268
297
|
|
269
|
-
async function* paginate<T extends
|
298
|
+
async function* paginate<T extends IDecodedMessage>(
|
270
299
|
connection: Connection,
|
271
300
|
protocol: string,
|
272
301
|
queryOpts: Params,
|
273
|
-
decoders: Map<string,
|
302
|
+
decoders: Map<string, IDecoder<T>>,
|
303
|
+
cursor?: Cursor
|
274
304
|
): AsyncGenerator<Promise<T | undefined>[]> {
|
275
305
|
if (
|
276
306
|
queryOpts.contentTopics.toString() !==
|
@@ -281,9 +311,9 @@ async function* paginate<T extends DecodedMessage>(
|
|
281
311
|
);
|
282
312
|
}
|
283
313
|
|
284
|
-
let
|
314
|
+
let currentCursor = cursor;
|
285
315
|
while (true) {
|
286
|
-
queryOpts =
|
316
|
+
queryOpts.cursor = currentCursor;
|
287
317
|
|
288
318
|
const stream = await connection.newStream(protocol);
|
289
319
|
const historyRpcQuery = HistoryRPC.createQuery(queryOpts);
|
@@ -344,8 +374,8 @@ async function* paginate<T extends DecodedMessage>(
|
|
344
374
|
return Promise.resolve(undefined);
|
345
375
|
});
|
346
376
|
|
347
|
-
|
348
|
-
if (typeof
|
377
|
+
const nextCursor = response.pagingInfo?.cursor;
|
378
|
+
if (typeof nextCursor === "undefined") {
|
349
379
|
// If the server does not return cursor then there is an issue,
|
350
380
|
// Need to abort, or we end up in an infinite loop
|
351
381
|
log(
|
@@ -354,6 +384,8 @@ async function* paginate<T extends DecodedMessage>(
|
|
354
384
|
break;
|
355
385
|
}
|
356
386
|
|
387
|
+
currentCursor = nextCursor;
|
388
|
+
|
357
389
|
const responsePageSize = response.pagingInfo?.pageSize;
|
358
390
|
const queryPageSize = historyRpcQuery.query?.pagingInfo?.pageSize;
|
359
391
|
if (
|
@@ -370,3 +402,36 @@ async function* paginate<T extends DecodedMessage>(
|
|
370
402
|
export function isDefined<T>(msg: T | undefined): msg is T {
|
371
403
|
return !!msg;
|
372
404
|
}
|
405
|
+
|
406
|
+
export async function createCursor(
|
407
|
+
message: IDecodedMessage,
|
408
|
+
pubsubTopic: string = DefaultPubSubTopic
|
409
|
+
): Promise<Index> {
|
410
|
+
if (
|
411
|
+
!message ||
|
412
|
+
!message.timestamp ||
|
413
|
+
!message.payload ||
|
414
|
+
!message.contentTopic
|
415
|
+
) {
|
416
|
+
throw new Error("Message is missing required fields");
|
417
|
+
}
|
418
|
+
|
419
|
+
const contentTopicBytes = utf8ToBytes(message.contentTopic);
|
420
|
+
|
421
|
+
const digest = sha256(concat([contentTopicBytes, message.payload]));
|
422
|
+
|
423
|
+
const messageTime = BigInt(message.timestamp.getTime()) * BigInt(1000000);
|
424
|
+
|
425
|
+
return {
|
426
|
+
digest,
|
427
|
+
pubsubTopic,
|
428
|
+
senderTime: messageTime,
|
429
|
+
receivedTime: messageTime,
|
430
|
+
};
|
431
|
+
}
|
432
|
+
|
433
|
+
export function wakuStore(
|
434
|
+
init: Partial<CreateOptions> = {}
|
435
|
+
): (components: StoreComponents) => IStore {
|
436
|
+
return (components: StoreComponents) => new Store(components, init);
|
437
|
+
}
|
@@ -1,15 +1,15 @@
|
|
1
|
-
import {
|
1
|
+
import { IProtoMessage } from "@waku/interfaces";
|
2
|
+
import { WakuMessage as WakuMessageProto } from "@waku/proto";
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
const EmptyMessage: ProtoMessage = {
|
4
|
+
const EmptyMessage: IProtoMessage = {
|
6
5
|
payload: undefined,
|
7
6
|
contentTopic: undefined,
|
8
7
|
version: undefined,
|
9
8
|
timestamp: undefined,
|
10
9
|
rateLimitProof: undefined,
|
10
|
+
ephemeral: undefined,
|
11
11
|
};
|
12
12
|
|
13
|
-
export function toProtoMessage(wire: WakuMessageProto):
|
13
|
+
export function toProtoMessage(wire: WakuMessageProto): IProtoMessage {
|
14
14
|
return { ...EmptyMessage, ...wire };
|
15
15
|
}
|
@@ -1,12 +1,13 @@
|
|
1
1
|
import { PeerProtocolsChangeData } from "@libp2p/interface-peer-store";
|
2
|
-
import type {
|
2
|
+
import type { IRelay, PointToPointProtocol, Waku } from "@waku/interfaces";
|
3
3
|
import { Protocols } from "@waku/interfaces";
|
4
|
+
import { PeerExchangeCodec } from "@waku/peer-exchange";
|
4
5
|
import debug from "debug";
|
5
6
|
import { pEvent } from "p-event";
|
6
7
|
|
7
|
-
import { FilterCodec } from "./
|
8
|
-
import { LightPushCodec } from "./
|
9
|
-
import { StoreCodec } from "./
|
8
|
+
import { FilterCodec } from "./filter/index.js";
|
9
|
+
import { LightPushCodec } from "./light_push/index.js";
|
10
|
+
import { StoreCodec } from "./store/index.js";
|
10
11
|
|
11
12
|
const log = debug("waku:wait-for-remote-peer");
|
12
13
|
|
@@ -64,6 +65,14 @@ export async function waitForRemotePeer(
|
|
64
65
|
promises.push(waitForConnectedPeer(waku.filter, [FilterCodec]));
|
65
66
|
}
|
66
67
|
|
68
|
+
if (protocols.includes(Protocols.PeerExchange)) {
|
69
|
+
if (!waku.peerExchange)
|
70
|
+
throw new Error(
|
71
|
+
"Cannot wait for Peer Exchange peer: protocol not mounted"
|
72
|
+
);
|
73
|
+
promises.push(waitForConnectedPeer(waku.peerExchange, [PeerExchangeCodec]));
|
74
|
+
}
|
75
|
+
|
67
76
|
if (timeoutMs) {
|
68
77
|
await rejectOnTimeout(
|
69
78
|
Promise.all(promises),
|
@@ -94,13 +103,13 @@ async function waitForConnectedPeer(
|
|
94
103
|
for (const codec of codecs) {
|
95
104
|
if (evt.detail.protocols.includes(codec)) {
|
96
105
|
log("Resolving for", codec, evt.detail.protocols);
|
97
|
-
waku.
|
106
|
+
waku.peerStore.removeEventListener("change:protocols", cb);
|
98
107
|
resolve();
|
99
108
|
break;
|
100
109
|
}
|
101
110
|
}
|
102
111
|
};
|
103
|
-
waku.
|
112
|
+
waku.peerStore.addEventListener("change:protocols", cb);
|
104
113
|
});
|
105
114
|
}
|
106
115
|
|
@@ -108,7 +117,7 @@ async function waitForConnectedPeer(
|
|
108
117
|
* Wait for a peer with the given protocol to be connected and in the gossipsub
|
109
118
|
* mesh.
|
110
119
|
*/
|
111
|
-
async function waitForGossipSubPeerInMesh(waku:
|
120
|
+
async function waitForGossipSubPeerInMesh(waku: IRelay): Promise<void> {
|
112
121
|
let peers = waku.getMeshPeers();
|
113
122
|
|
114
123
|
while (peers.length == 0) {
|
@@ -146,6 +155,9 @@ function getEnabledProtocols(waku: Waku): Protocols[] {
|
|
146
155
|
if (waku.lightPush) {
|
147
156
|
protocols.push(Protocols.LightPush);
|
148
157
|
}
|
158
|
+
if (waku.peerExchange) {
|
159
|
+
protocols.push(Protocols.PeerExchange);
|
160
|
+
}
|
149
161
|
|
150
162
|
return protocols;
|
151
163
|
}
|