@waku/core 0.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/CHANGELOG.md +614 -0
- package/README.md +56 -0
- package/bundle/browser-1e1a2f27.js +722 -0
- package/bundle/crypto-8551d579.js +2585 -0
- package/bundle/crypto-b00764b7.js +1772 -0
- package/bundle/enr-564d4a51.js +20785 -0
- package/bundle/enr-9fc5eed8.js +20786 -0
- package/bundle/enr-f6e82a53.js +20785 -0
- package/bundle/events-158407bb.js +1929 -0
- package/bundle/events-fcbda4dc.js +76 -0
- package/bundle/index-02d21809.js +20 -0
- package/bundle/index-0a4bdddc.js +2976 -0
- package/bundle/index-2ae915be.js +1854 -0
- package/bundle/index-64ce43f0.js +69 -0
- package/bundle/index-691c0be6.js +4059 -0
- package/bundle/index-a013a259.js +20 -0
- package/bundle/index-ba42b4fc.js +862 -0
- package/bundle/index.js +13428 -0
- package/bundle/lib/enr.js +8 -0
- package/bundle/lib/peer_discovery_dns.js +5018 -0
- package/bundle/lib/peer_discovery_static_list.js +75 -0
- package/bundle/lib/predefined_bootstrap_nodes.js +59 -0
- package/bundle/lib/utils.js +1 -0
- package/bundle/lib/wait_for_remote_peer.js +327 -0
- package/bundle/lib/waku_message/topic_only_message.js +4 -0
- package/bundle/lib/waku_message/version_0.js +4 -0
- package/bundle/lib/waku_message/version_1.js +463 -0
- package/bundle/message-e2db79d7.js +8393 -0
- package/bundle/multiaddr_to_peer_info-c406b1e1.js +19 -0
- package/bundle/multiaddr_to_peer_info-fd1de516.js +19 -0
- package/bundle/random_subset-75d1c511.js +26 -0
- package/bundle/topic_only_message-34f36fa6.js +82 -0
- package/bundle/utils-9a3221f2.js +815 -0
- package/bundle/version_0-e6fe440c.js +317 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/constants.d.ts +4 -0
- package/dist/lib/constants.js +5 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/crypto.d.ts +34 -0
- package/dist/lib/crypto.js +79 -0
- package/dist/lib/crypto.js.map +1 -0
- package/dist/lib/enr/constants.d.ts +4 -0
- package/dist/lib/enr/constants.js +8 -0
- package/dist/lib/enr/constants.js.map +1 -0
- package/dist/lib/enr/enr.d.ts +90 -0
- package/dist/lib/enr/enr.js +432 -0
- package/dist/lib/enr/enr.js.map +1 -0
- package/dist/lib/enr/index.d.ts +5 -0
- package/dist/lib/enr/index.js +6 -0
- package/dist/lib/enr/index.js.map +1 -0
- package/dist/lib/enr/keypair/index.d.ts +8 -0
- package/dist/lib/enr/keypair/index.js +53 -0
- package/dist/lib/enr/keypair/index.js.map +1 -0
- package/dist/lib/enr/keypair/secp256k1.d.ts +13 -0
- package/dist/lib/enr/keypair/secp256k1.js +57 -0
- package/dist/lib/enr/keypair/secp256k1.js.map +1 -0
- package/dist/lib/enr/keypair/types.d.ts +13 -0
- package/dist/lib/enr/keypair/types.js +7 -0
- package/dist/lib/enr/keypair/types.js.map +1 -0
- package/dist/lib/enr/multiaddr_from_fields.d.ts +2 -0
- package/dist/lib/enr/multiaddr_from_fields.js +8 -0
- package/dist/lib/enr/multiaddr_from_fields.js.map +1 -0
- package/dist/lib/enr/multiaddrs_codec.d.ts +3 -0
- package/dist/lib/enr/multiaddrs_codec.js +32 -0
- package/dist/lib/enr/multiaddrs_codec.js.map +1 -0
- package/dist/lib/enr/types.d.ts +8 -0
- package/dist/lib/enr/types.js +3 -0
- package/dist/lib/enr/types.js.map +1 -0
- package/dist/lib/enr/v4.d.ts +3 -0
- package/dist/lib/enr/v4.js +14 -0
- package/dist/lib/enr/v4.js.map +1 -0
- package/dist/lib/enr/waku2_codec.d.ts +8 -0
- package/dist/lib/enr/waku2_codec.js +36 -0
- package/dist/lib/enr/waku2_codec.js.map +1 -0
- package/dist/lib/group_by.d.ts +3 -0
- package/dist/lib/group_by.js +13 -0
- package/dist/lib/group_by.js.map +1 -0
- package/dist/lib/multiaddr_to_peer_info.d.ts +3 -0
- package/dist/lib/multiaddr_to_peer_info.js +15 -0
- package/dist/lib/multiaddr_to_peer_info.js.map +1 -0
- package/dist/lib/peer_discovery_dns/dns.d.ts +48 -0
- package/dist/lib/peer_discovery_dns/dns.js +158 -0
- package/dist/lib/peer_discovery_dns/dns.js.map +1 -0
- package/dist/lib/peer_discovery_dns/dns_over_https.d.ts +32 -0
- package/dist/lib/peer_discovery_dns/dns_over_https.js +87 -0
- package/dist/lib/peer_discovery_dns/dns_over_https.js.map +1 -0
- package/dist/lib/peer_discovery_dns/enrtree.d.ts +33 -0
- package/dist/lib/peer_discovery_dns/enrtree.js +76 -0
- package/dist/lib/peer_discovery_dns/enrtree.js.map +1 -0
- package/dist/lib/peer_discovery_dns/fetch_nodes.d.ts +14 -0
- package/dist/lib/peer_discovery_dns/fetch_nodes.js +133 -0
- package/dist/lib/peer_discovery_dns/fetch_nodes.js.map +1 -0
- package/dist/lib/peer_discovery_dns/index.d.ts +30 -0
- package/dist/lib/peer_discovery_dns/index.js +54 -0
- package/dist/lib/peer_discovery_dns/index.js.map +1 -0
- package/dist/lib/peer_discovery_static_list.d.ts +44 -0
- package/dist/lib/peer_discovery_static_list.js +72 -0
- package/dist/lib/peer_discovery_static_list.js.map +1 -0
- package/dist/lib/predefined_bootstrap_nodes.d.ts +35 -0
- package/dist/lib/predefined_bootstrap_nodes.js +56 -0
- package/dist/lib/predefined_bootstrap_nodes.js.map +1 -0
- package/dist/lib/push_or_init_map.d.ts +1 -0
- package/dist/lib/push_or_init_map.js +9 -0
- package/dist/lib/push_or_init_map.js.map +1 -0
- package/dist/lib/random_subset.d.ts +4 -0
- package/dist/lib/random_subset.js +25 -0
- package/dist/lib/random_subset.js.map +1 -0
- package/dist/lib/select_connection.d.ts +2 -0
- package/dist/lib/select_connection.js +19 -0
- package/dist/lib/select_connection.js.map +1 -0
- package/dist/lib/select_peer.d.ts +15 -0
- package/dist/lib/select_peer.js +59 -0
- package/dist/lib/select_peer.js.map +1 -0
- package/dist/lib/to_proto_message.d.ts +3 -0
- package/dist/lib/to_proto_message.js +11 -0
- package/dist/lib/to_proto_message.js.map +1 -0
- package/dist/lib/utils.d.ts +22 -0
- package/dist/lib/utils.js +40 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/wait_for_remote_peer.d.ts +22 -0
- package/dist/lib/wait_for_remote_peer.js +113 -0
- package/dist/lib/wait_for_remote_peer.js.map +1 -0
- package/dist/lib/waku.d.ts +61 -0
- package/dist/lib/waku.js +174 -0
- package/dist/lib/waku.js.map +1 -0
- package/dist/lib/waku_filter/filter_rpc.d.ts +25 -0
- package/dist/lib/waku_filter/filter_rpc.js +44 -0
- package/dist/lib/waku_filter/filter_rpc.js.map +1 -0
- package/dist/lib/waku_filter/index.d.ts +50 -0
- package/dist/lib/waku_filter/index.js +181 -0
- package/dist/lib/waku_filter/index.js.map +1 -0
- package/dist/lib/waku_light_push/index.d.ts +38 -0
- package/dist/lib/waku_light_push/index.js +83 -0
- package/dist/lib/waku_light_push/index.js.map +1 -0
- package/dist/lib/waku_light_push/push_rpc.d.ts +11 -0
- package/dist/lib/waku_light_push/push_rpc.js +31 -0
- package/dist/lib/waku_light_push/push_rpc.js.map +1 -0
- package/dist/lib/waku_message/constants.d.ts +12 -0
- package/dist/lib/waku_message/constants.js +10 -0
- package/dist/lib/waku_message/constants.js.map +1 -0
- package/dist/lib/waku_message/ecies.d.ts +17 -0
- package/dist/lib/waku_message/ecies.js +126 -0
- package/dist/lib/waku_message/ecies.js.map +1 -0
- package/dist/lib/waku_message/symmetric.d.ts +3 -0
- package/dist/lib/waku_message/symmetric.js +18 -0
- package/dist/lib/waku_message/symmetric.js.map +1 -0
- package/dist/lib/waku_message/topic_only_message.d.ts +15 -0
- package/dist/lib/waku_message/topic_only_message.js +31 -0
- package/dist/lib/waku_message/topic_only_message.js.map +1 -0
- package/dist/lib/waku_message/version_0.d.ts +26 -0
- package/dist/lib/waku_message/version_0.js +96 -0
- package/dist/lib/waku_message/version_0.js.map +1 -0
- package/dist/lib/waku_message/version_1.d.ts +93 -0
- package/dist/lib/waku_message/version_1.js +325 -0
- package/dist/lib/waku_message/version_1.js.map +1 -0
- package/dist/lib/waku_relay/constants.d.ts +63 -0
- package/dist/lib/waku_relay/constants.js +67 -0
- package/dist/lib/waku_relay/constants.js.map +1 -0
- package/dist/lib/waku_relay/index.d.ts +65 -0
- package/dist/lib/waku_relay/index.js +111 -0
- package/dist/lib/waku_relay/index.js.map +1 -0
- package/dist/lib/waku_store/history_rpc.d.ts +27 -0
- package/dist/lib/waku_store/history_rpc.js +71 -0
- package/dist/lib/waku_store/history_rpc.js.map +1 -0
- package/dist/lib/waku_store/index.d.ts +126 -0
- package/dist/lib/waku_store/index.js +218 -0
- package/dist/lib/waku_store/index.js.map +1 -0
- package/dist/proto/filter.d.ts +65 -0
- package/dist/proto/filter.js +425 -0
- package/dist/proto/filter.js.map +1 -0
- package/dist/proto/light_push.d.ts +57 -0
- package/dist/proto/light_push.js +369 -0
- package/dist/proto/light_push.js.map +1 -0
- package/dist/proto/message.d.ts +29 -0
- package/dist/proto/message.js +215 -0
- package/dist/proto/message.js.map +1 -0
- package/dist/proto/store.d.ts +104 -0
- package/dist/proto/store.js +602 -0
- package/dist/proto/store.js.map +1 -0
- package/dist/proto/topic_only_message.d.ts +10 -0
- package/dist/proto/topic_only_message.js +46 -0
- package/dist/proto/topic_only_message.js.map +1 -0
- package/package.json +292 -0
- package/src/index.ts +33 -0
- package/src/lib/constants.ts +4 -0
- package/src/lib/crypto.ts +100 -0
- package/src/lib/enr/constants.ts +10 -0
- package/src/lib/enr/enr.ts +516 -0
- package/src/lib/enr/index.ts +5 -0
- package/src/lib/enr/keypair/index.ts +76 -0
- package/src/lib/enr/keypair/secp256k1.ts +69 -0
- package/src/lib/enr/keypair/types.ts +14 -0
- package/src/lib/enr/multiaddr_from_fields.ts +18 -0
- package/src/lib/enr/multiaddrs_codec.ts +50 -0
- package/src/lib/enr/types.ts +11 -0
- package/src/lib/enr/v4.ts +22 -0
- package/src/lib/enr/waku2_codec.ts +39 -0
- package/src/lib/group_by.ts +14 -0
- package/src/lib/multiaddr_to_peer_info.ts +17 -0
- package/src/lib/peer_discovery_dns/dns.ts +223 -0
- package/src/lib/peer_discovery_dns/dns_over_https.ts +98 -0
- package/src/lib/peer_discovery_dns/enrtree.ts +123 -0
- package/src/lib/peer_discovery_dns/fetch_nodes.ts +180 -0
- package/src/lib/peer_discovery_dns/index.ts +84 -0
- package/src/lib/peer_discovery_static_list.ts +118 -0
- package/src/lib/predefined_bootstrap_nodes.ts +72 -0
- package/src/lib/push_or_init_map.ts +13 -0
- package/src/lib/random_subset.ts +30 -0
- package/src/lib/select_connection.ts +24 -0
- package/src/lib/select_peer.ts +77 -0
- package/src/lib/to_proto_message.ts +15 -0
- package/src/lib/utils.ts +50 -0
- package/src/lib/wait_for_remote_peer.ts +151 -0
- package/src/lib/waku.ts +258 -0
- package/src/lib/waku_filter/filter_rpc.ts +57 -0
- package/src/lib/waku_filter/index.ts +291 -0
- package/src/lib/waku_light_push/index.ts +137 -0
- package/src/lib/waku_light_push/push_rpc.ts +39 -0
- package/src/lib/waku_message/constants.ts +10 -0
- package/src/lib/waku_message/ecies.ts +194 -0
- package/src/lib/waku_message/symmetric.ts +33 -0
- package/src/lib/waku_message/topic_only_message.ts +40 -0
- package/src/lib/waku_message/version_0.ts +121 -0
- package/src/lib/waku_message/version_1.ts +457 -0
- package/src/lib/waku_relay/constants.ts +77 -0
- package/src/lib/waku_relay/index.ts +189 -0
- package/src/lib/waku_store/history_rpc.ts +94 -0
- package/src/lib/waku_store/index.ts +372 -0
- package/src/proto/filter.ts +602 -0
- package/src/proto/light_push.ts +526 -0
- package/src/proto/message.ts +304 -0
- package/src/proto/store.ts +844 -0
- package/src/proto/topic_only_message.ts +67 -0
@@ -0,0 +1,151 @@
|
|
1
|
+
import { PeerProtocolsChangeData } from "@libp2p/interface-peer-store";
|
2
|
+
import type { PointToPointProtocol, Relay, Waku } from "@waku/interfaces";
|
3
|
+
import { Protocols } from "@waku/interfaces";
|
4
|
+
import debug from "debug";
|
5
|
+
import { pEvent } from "p-event";
|
6
|
+
|
7
|
+
import { FilterCodec } from "./waku_filter";
|
8
|
+
import { LightPushCodec } from "./waku_light_push";
|
9
|
+
import { StoreCodec } from "./waku_store";
|
10
|
+
|
11
|
+
const log = debug("waku:wait-for-remote-peer");
|
12
|
+
|
13
|
+
/**
|
14
|
+
* Wait for a remote peer to be ready given the passed protocols.
|
15
|
+
* Must be used after attempting to connect to nodes, using
|
16
|
+
* {@link index.waku.WakuNode.dial} or a bootstrap method with
|
17
|
+
* {@link lib/create_waku.createLightNode}.
|
18
|
+
*
|
19
|
+
* If the passed protocols is a GossipSub protocol, then it resolves only once
|
20
|
+
* a peer is in a mesh, to help ensure that other peers will send and receive
|
21
|
+
* message to us.
|
22
|
+
*
|
23
|
+
* @param waku The Waku Node
|
24
|
+
* @param protocols The protocols that need to be enabled by remote peers.
|
25
|
+
* @param timeoutMs A timeout value in milliseconds..
|
26
|
+
*
|
27
|
+
* @returns A promise that **resolves** if all desired protocols are fulfilled by
|
28
|
+
* remote nodes, **rejects** if the timeoutMs is reached.
|
29
|
+
* @throws If passing a protocol that is not mounted
|
30
|
+
* @default Wait for remote peers with protocols enabled locally and no time out is applied.
|
31
|
+
*/
|
32
|
+
export async function waitForRemotePeer(
|
33
|
+
waku: Waku,
|
34
|
+
protocols?: Protocols[],
|
35
|
+
timeoutMs?: number
|
36
|
+
): Promise<void> {
|
37
|
+
protocols = protocols ?? getEnabledProtocols(waku);
|
38
|
+
|
39
|
+
if (!waku.isStarted()) return Promise.reject("Waku node is not started");
|
40
|
+
|
41
|
+
const promises = [];
|
42
|
+
|
43
|
+
if (protocols.includes(Protocols.Relay)) {
|
44
|
+
if (!waku.relay)
|
45
|
+
throw new Error("Cannot wait for Relay peer: protocol not mounted");
|
46
|
+
promises.push(waitForGossipSubPeerInMesh(waku.relay));
|
47
|
+
}
|
48
|
+
|
49
|
+
if (protocols.includes(Protocols.Store)) {
|
50
|
+
if (!waku.store)
|
51
|
+
throw new Error("Cannot wait for Store peer: protocol not mounted");
|
52
|
+
promises.push(waitForConnectedPeer(waku.store, [StoreCodec]));
|
53
|
+
}
|
54
|
+
|
55
|
+
if (protocols.includes(Protocols.LightPush)) {
|
56
|
+
if (!waku.lightPush)
|
57
|
+
throw new Error("Cannot wait for LightPush peer: protocol not mounted");
|
58
|
+
promises.push(waitForConnectedPeer(waku.lightPush, [LightPushCodec]));
|
59
|
+
}
|
60
|
+
|
61
|
+
if (protocols.includes(Protocols.Filter)) {
|
62
|
+
if (!waku.filter)
|
63
|
+
throw new Error("Cannot wait for Filter peer: protocol not mounted");
|
64
|
+
promises.push(waitForConnectedPeer(waku.filter, [FilterCodec]));
|
65
|
+
}
|
66
|
+
|
67
|
+
if (timeoutMs) {
|
68
|
+
await rejectOnTimeout(
|
69
|
+
Promise.all(promises),
|
70
|
+
timeoutMs,
|
71
|
+
"Timed out waiting for a remote peer."
|
72
|
+
);
|
73
|
+
} else {
|
74
|
+
await Promise.all(promises);
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
/**
|
79
|
+
* Wait for a peer with the given protocol to be connected.
|
80
|
+
*/
|
81
|
+
async function waitForConnectedPeer(
|
82
|
+
waku: PointToPointProtocol,
|
83
|
+
codecs: string[]
|
84
|
+
): Promise<void> {
|
85
|
+
const peers = await waku.peers();
|
86
|
+
|
87
|
+
if (peers.length) {
|
88
|
+
log(`${codecs} peer found: `, peers[0].id.toString());
|
89
|
+
return;
|
90
|
+
}
|
91
|
+
|
92
|
+
await new Promise<void>((resolve) => {
|
93
|
+
const cb = (evt: CustomEvent<PeerProtocolsChangeData>): void => {
|
94
|
+
for (const codec of codecs) {
|
95
|
+
if (evt.detail.protocols.includes(codec)) {
|
96
|
+
log("Resolving for", codec, evt.detail.protocols);
|
97
|
+
waku.libp2p.peerStore.removeEventListener("change:protocols", cb);
|
98
|
+
resolve();
|
99
|
+
break;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
};
|
103
|
+
waku.libp2p.peerStore.addEventListener("change:protocols", cb);
|
104
|
+
});
|
105
|
+
}
|
106
|
+
|
107
|
+
/**
|
108
|
+
* Wait for a peer with the given protocol to be connected and in the gossipsub
|
109
|
+
* mesh.
|
110
|
+
*/
|
111
|
+
async function waitForGossipSubPeerInMesh(waku: Relay): Promise<void> {
|
112
|
+
let peers = waku.getMeshPeers();
|
113
|
+
|
114
|
+
while (peers.length == 0) {
|
115
|
+
await pEvent(waku, "gossipsub:heartbeat");
|
116
|
+
peers = waku.getMeshPeers();
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
const awaitTimeout = (ms: number, rejectReason: string): Promise<void> =>
|
121
|
+
new Promise((_resolve, reject) => setTimeout(() => reject(rejectReason), ms));
|
122
|
+
|
123
|
+
async function rejectOnTimeout<T>(
|
124
|
+
promise: Promise<T>,
|
125
|
+
timeoutMs: number,
|
126
|
+
rejectReason: string
|
127
|
+
): Promise<void> {
|
128
|
+
await Promise.race([promise, awaitTimeout(timeoutMs, rejectReason)]);
|
129
|
+
}
|
130
|
+
|
131
|
+
function getEnabledProtocols(waku: Waku): Protocols[] {
|
132
|
+
const protocols = [];
|
133
|
+
|
134
|
+
if (waku.relay) {
|
135
|
+
protocols.push(Protocols.Relay);
|
136
|
+
}
|
137
|
+
|
138
|
+
if (waku.filter) {
|
139
|
+
protocols.push(Protocols.Filter);
|
140
|
+
}
|
141
|
+
|
142
|
+
if (waku.store) {
|
143
|
+
protocols.push(Protocols.Store);
|
144
|
+
}
|
145
|
+
|
146
|
+
if (waku.lightPush) {
|
147
|
+
protocols.push(Protocols.LightPush);
|
148
|
+
}
|
149
|
+
|
150
|
+
return protocols;
|
151
|
+
}
|
package/src/lib/waku.ts
ADDED
@@ -0,0 +1,258 @@
|
|
1
|
+
import type { Stream } from "@libp2p/interface-connection";
|
2
|
+
import type { PeerId } from "@libp2p/interface-peer-id";
|
3
|
+
import type { PubSub } from "@libp2p/interface-pubsub";
|
4
|
+
import { peerIdFromString } from "@libp2p/peer-id";
|
5
|
+
import type { Multiaddr } from "@multiformats/multiaddr";
|
6
|
+
import { multiaddr } from "@multiformats/multiaddr";
|
7
|
+
import type { Waku } from "@waku/interfaces";
|
8
|
+
import { Protocols } from "@waku/interfaces";
|
9
|
+
import debug from "debug";
|
10
|
+
import type { Libp2p } from "libp2p";
|
11
|
+
|
12
|
+
import { FilterCodec, WakuFilter } from "./waku_filter";
|
13
|
+
import { LightPushCodec, WakuLightPush } from "./waku_light_push";
|
14
|
+
import { EncoderV0 } from "./waku_message/version_0";
|
15
|
+
import { WakuRelay } from "./waku_relay";
|
16
|
+
import { RelayCodecs, RelayPingContentTopic } from "./waku_relay/constants";
|
17
|
+
import * as relayConstants from "./waku_relay/constants";
|
18
|
+
import { StoreCodec, WakuStore } from "./waku_store";
|
19
|
+
|
20
|
+
export const DefaultPingKeepAliveValueSecs = 0;
|
21
|
+
export const DefaultRelayKeepAliveValueSecs = 5 * 60;
|
22
|
+
|
23
|
+
const log = debug("waku:waku");
|
24
|
+
|
25
|
+
export interface WakuOptions {
|
26
|
+
/**
|
27
|
+
* Set keep alive frequency in seconds: Waku will send a `/ipfs/ping/1.0.0`
|
28
|
+
* request to each peer after the set number of seconds. Set to 0 to disable.
|
29
|
+
*
|
30
|
+
* @default {@link DefaultPingKeepAliveValueSecs}
|
31
|
+
*/
|
32
|
+
pingKeepAlive?: number;
|
33
|
+
/**
|
34
|
+
* Set keep alive frequency in seconds: Waku will send a ping message over
|
35
|
+
* relay to each peer after the set number of seconds. Set to 0 to disable.
|
36
|
+
*
|
37
|
+
* @default {@link DefaultRelayKeepAliveValueSecs}
|
38
|
+
*/
|
39
|
+
relayKeepAlive?: number;
|
40
|
+
}
|
41
|
+
|
42
|
+
export class WakuNode implements Waku {
|
43
|
+
public libp2p: Libp2p;
|
44
|
+
public relay?: WakuRelay;
|
45
|
+
public store?: WakuStore;
|
46
|
+
public filter?: WakuFilter;
|
47
|
+
public lightPush?: WakuLightPush;
|
48
|
+
|
49
|
+
private pingKeepAliveTimers: {
|
50
|
+
[peer: string]: ReturnType<typeof setInterval>;
|
51
|
+
};
|
52
|
+
private relayKeepAliveTimers: {
|
53
|
+
[peer: string]: ReturnType<typeof setInterval>;
|
54
|
+
};
|
55
|
+
|
56
|
+
constructor(
|
57
|
+
options: WakuOptions,
|
58
|
+
libp2p: Libp2p,
|
59
|
+
store?: WakuStore,
|
60
|
+
lightPush?: WakuLightPush,
|
61
|
+
filter?: WakuFilter
|
62
|
+
) {
|
63
|
+
this.libp2p = libp2p;
|
64
|
+
this.store = store;
|
65
|
+
this.filter = filter;
|
66
|
+
this.lightPush = lightPush;
|
67
|
+
|
68
|
+
if (isWakuRelay(libp2p.pubsub)) {
|
69
|
+
this.relay = libp2p.pubsub;
|
70
|
+
}
|
71
|
+
|
72
|
+
log(
|
73
|
+
"Waku node created",
|
74
|
+
this.libp2p.peerId.toString(),
|
75
|
+
`relay: ${!!this.relay}, store: ${!!this.store}, light push: ${!!this
|
76
|
+
.lightPush}, filter: ${!!this.filter}`
|
77
|
+
);
|
78
|
+
|
79
|
+
this.pingKeepAliveTimers = {};
|
80
|
+
this.relayKeepAliveTimers = {};
|
81
|
+
|
82
|
+
const pingKeepAlive =
|
83
|
+
options.pingKeepAlive || DefaultPingKeepAliveValueSecs;
|
84
|
+
const relayKeepAlive = this.relay
|
85
|
+
? options.relayKeepAlive || DefaultRelayKeepAliveValueSecs
|
86
|
+
: 0;
|
87
|
+
|
88
|
+
libp2p.connectionManager.addEventListener("peer:connect", (evt) => {
|
89
|
+
this.startKeepAlive(evt.detail.remotePeer, pingKeepAlive, relayKeepAlive);
|
90
|
+
});
|
91
|
+
|
92
|
+
/**
|
93
|
+
* NOTE: Event is not being emitted on closing nor losing a connection.
|
94
|
+
* @see https://github.com/libp2p/js-libp2p/issues/939
|
95
|
+
* @see https://github.com/status-im/js-waku/issues/252
|
96
|
+
*
|
97
|
+
* >This event will be triggered anytime we are disconnected from another peer,
|
98
|
+
* >regardless of the circumstances of that disconnection.
|
99
|
+
* >If we happen to have multiple connections to a peer,
|
100
|
+
* >this event will **only** be triggered when the last connection is closed.
|
101
|
+
* @see https://github.com/libp2p/js-libp2p/blob/bad9e8c0ff58d60a78314077720c82ae331cc55b/doc/API.md?plain=1#L2100
|
102
|
+
*/
|
103
|
+
libp2p.connectionManager.addEventListener("peer:disconnect", (evt) => {
|
104
|
+
this.stopKeepAlive(evt.detail.remotePeer);
|
105
|
+
});
|
106
|
+
}
|
107
|
+
|
108
|
+
/**
|
109
|
+
* Dials to the provided peer.
|
110
|
+
*
|
111
|
+
* @param peer The peer to dial
|
112
|
+
* @param protocols Waku protocols we expect from the peer; Default to Relay
|
113
|
+
*/
|
114
|
+
async dial(
|
115
|
+
peer: PeerId | Multiaddr,
|
116
|
+
protocols?: Protocols[]
|
117
|
+
): Promise<Stream> {
|
118
|
+
const _protocols = protocols ?? [Protocols.Relay];
|
119
|
+
|
120
|
+
const codecs: string[] = [];
|
121
|
+
if (_protocols.includes(Protocols.Relay)) {
|
122
|
+
RelayCodecs.forEach((codec) => codecs.push(codec));
|
123
|
+
}
|
124
|
+
if (_protocols.includes(Protocols.Store)) {
|
125
|
+
codecs.push(StoreCodec);
|
126
|
+
}
|
127
|
+
if (_protocols.includes(Protocols.LightPush)) {
|
128
|
+
codecs.push(LightPushCodec);
|
129
|
+
}
|
130
|
+
if (_protocols.includes(Protocols.Filter)) {
|
131
|
+
codecs.push(FilterCodec);
|
132
|
+
}
|
133
|
+
|
134
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
135
|
+
// @ts-ignore: new Multiaddr is not backward compatible
|
136
|
+
return this.libp2p.dialProtocol(peer, codecs);
|
137
|
+
}
|
138
|
+
|
139
|
+
/**
|
140
|
+
* Add peer to address book, it will be auto-dialed in the background.
|
141
|
+
*/
|
142
|
+
async addPeerToAddressBook(
|
143
|
+
peerId: PeerId | string,
|
144
|
+
multiaddrs: Multiaddr[] | string[]
|
145
|
+
): Promise<void> {
|
146
|
+
let peer;
|
147
|
+
if (typeof peerId === "string") {
|
148
|
+
peer = peerIdFromString(peerId);
|
149
|
+
} else {
|
150
|
+
peer = peerId;
|
151
|
+
}
|
152
|
+
const addresses = multiaddrs.map((addr: Multiaddr | string) => {
|
153
|
+
if (typeof addr === "string") {
|
154
|
+
return multiaddr(addr);
|
155
|
+
} else {
|
156
|
+
return addr;
|
157
|
+
}
|
158
|
+
});
|
159
|
+
await this.libp2p.peerStore.addressBook.set(peer, addresses);
|
160
|
+
}
|
161
|
+
|
162
|
+
async start(): Promise<void> {
|
163
|
+
await this.libp2p.start();
|
164
|
+
}
|
165
|
+
|
166
|
+
async stop(): Promise<void> {
|
167
|
+
this.stopAllKeepAlives();
|
168
|
+
await this.libp2p.stop();
|
169
|
+
}
|
170
|
+
|
171
|
+
isStarted(): boolean {
|
172
|
+
return this.libp2p.isStarted();
|
173
|
+
}
|
174
|
+
|
175
|
+
/**
|
176
|
+
* Return the local multiaddr with peer id on which libp2p is listening.
|
177
|
+
*
|
178
|
+
* @throws if libp2p is not listening on localhost.
|
179
|
+
*/
|
180
|
+
getLocalMultiaddrWithID(): string {
|
181
|
+
const localMultiaddr = this.libp2p
|
182
|
+
.getMultiaddrs()
|
183
|
+
.find((addr) => addr.toString().match(/127\.0\.0\.1/));
|
184
|
+
if (!localMultiaddr || localMultiaddr.toString() === "") {
|
185
|
+
throw "Not listening on localhost";
|
186
|
+
}
|
187
|
+
return localMultiaddr + "/p2p/" + this.libp2p.peerId.toString();
|
188
|
+
}
|
189
|
+
|
190
|
+
private startKeepAlive(
|
191
|
+
peerId: PeerId,
|
192
|
+
pingPeriodSecs: number,
|
193
|
+
relayPeriodSecs: number
|
194
|
+
): void {
|
195
|
+
// Just in case a timer already exist for this peer
|
196
|
+
this.stopKeepAlive(peerId);
|
197
|
+
|
198
|
+
const peerIdStr = peerId.toString();
|
199
|
+
|
200
|
+
if (pingPeriodSecs !== 0) {
|
201
|
+
this.pingKeepAliveTimers[peerIdStr] = setInterval(() => {
|
202
|
+
this.libp2p.ping(peerId).catch((e) => {
|
203
|
+
log(`Ping failed (${peerIdStr})`, e);
|
204
|
+
});
|
205
|
+
}, pingPeriodSecs * 1000);
|
206
|
+
}
|
207
|
+
|
208
|
+
const relay = this.relay;
|
209
|
+
if (relay && relayPeriodSecs !== 0) {
|
210
|
+
const encoder = new EncoderV0(RelayPingContentTopic);
|
211
|
+
this.relayKeepAliveTimers[peerIdStr] = setInterval(() => {
|
212
|
+
log("Sending Waku Relay ping message");
|
213
|
+
relay
|
214
|
+
.send(encoder, { payload: new Uint8Array() })
|
215
|
+
.catch((e) => log("Failed to send relay ping", e));
|
216
|
+
}, relayPeriodSecs * 1000);
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
private stopKeepAlive(peerId: PeerId): void {
|
221
|
+
const peerIdStr = peerId.toString();
|
222
|
+
|
223
|
+
if (this.pingKeepAliveTimers[peerIdStr]) {
|
224
|
+
clearInterval(this.pingKeepAliveTimers[peerIdStr]);
|
225
|
+
delete this.pingKeepAliveTimers[peerIdStr];
|
226
|
+
}
|
227
|
+
|
228
|
+
if (this.relayKeepAliveTimers[peerIdStr]) {
|
229
|
+
clearInterval(this.relayKeepAliveTimers[peerIdStr]);
|
230
|
+
delete this.relayKeepAliveTimers[peerIdStr];
|
231
|
+
}
|
232
|
+
}
|
233
|
+
|
234
|
+
private stopAllKeepAlives(): void {
|
235
|
+
for (const timer of [
|
236
|
+
...Object.values(this.pingKeepAliveTimers),
|
237
|
+
...Object.values(this.relayKeepAliveTimers),
|
238
|
+
]) {
|
239
|
+
clearInterval(timer);
|
240
|
+
}
|
241
|
+
|
242
|
+
this.pingKeepAliveTimers = {};
|
243
|
+
this.relayKeepAliveTimers = {};
|
244
|
+
}
|
245
|
+
}
|
246
|
+
|
247
|
+
function isWakuRelay(pubsub: PubSub): pubsub is WakuRelay {
|
248
|
+
if (pubsub) {
|
249
|
+
try {
|
250
|
+
return pubsub.multicodecs.includes(
|
251
|
+
relayConstants.RelayCodecs[relayConstants.RelayCodecs.length - 1]
|
252
|
+
);
|
253
|
+
// Exception is expected if `libp2p` was not instantiated with pubsub
|
254
|
+
// eslint-disable-next-line no-empty
|
255
|
+
} catch (e) {}
|
256
|
+
}
|
257
|
+
return false;
|
258
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
import { v4 as uuid } from "uuid";
|
2
|
+
|
3
|
+
import * as proto from "../../proto/filter";
|
4
|
+
|
5
|
+
export type ContentFilter = {
|
6
|
+
contentTopic: string;
|
7
|
+
};
|
8
|
+
|
9
|
+
/**
|
10
|
+
* FilterRPC represents a message conforming to the Waku Filter protocol
|
11
|
+
*/
|
12
|
+
export class FilterRPC {
|
13
|
+
public constructor(public proto: proto.FilterRPC) {}
|
14
|
+
|
15
|
+
static createRequest(
|
16
|
+
topic: string,
|
17
|
+
contentFilters: ContentFilter[],
|
18
|
+
requestId?: string,
|
19
|
+
subscribe = true
|
20
|
+
): FilterRPC {
|
21
|
+
return new FilterRPC({
|
22
|
+
requestId: requestId || uuid(),
|
23
|
+
request: {
|
24
|
+
subscribe,
|
25
|
+
topic,
|
26
|
+
contentFilters,
|
27
|
+
},
|
28
|
+
push: undefined,
|
29
|
+
});
|
30
|
+
}
|
31
|
+
|
32
|
+
/**
|
33
|
+
*
|
34
|
+
* @param bytes Uint8Array of bytes from a FilterRPC message
|
35
|
+
* @returns FilterRPC
|
36
|
+
*/
|
37
|
+
static decode(bytes: Uint8Array): FilterRPC {
|
38
|
+
const res = proto.FilterRPC.decode(bytes);
|
39
|
+
return new FilterRPC(res);
|
40
|
+
}
|
41
|
+
|
42
|
+
/**
|
43
|
+
* Encode the current FilterRPC request to bytes
|
44
|
+
* @returns Uint8Array
|
45
|
+
*/
|
46
|
+
encode(): Uint8Array {
|
47
|
+
return proto.FilterRPC.encode(this.proto);
|
48
|
+
}
|
49
|
+
|
50
|
+
get push(): proto.MessagePush | undefined {
|
51
|
+
return this.proto.push;
|
52
|
+
}
|
53
|
+
|
54
|
+
get requestId(): string | undefined {
|
55
|
+
return this.proto.requestId;
|
56
|
+
}
|
57
|
+
}
|