chore: enforce access modifiers (#2068)

* feat: introduce eslint flag

* chore: update logger

* chore: update enr

* chore: update core

* chore: update sdk

* chore: update relay

* chore: update discovery

* chore: update message-encryption

* chore: update tests

* chore: fix modifiers

* chore(tests): fix access modifiers

* chore: fix rebase
This commit is contained in:
Danish Arora 2024-07-19 15:58:17 +05:30 committed by GitHub
parent 9b0f1e855a
commit 169a09d552
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
41 changed files with 338 additions and 305 deletions

View File

@ -25,6 +25,7 @@
}] }]
} }
], ],
"@typescript-eslint/explicit-member-accessibility": "error",
"prettier/prettier": [ "prettier/prettier": [
"error", "error",
{ {

View File

@ -25,7 +25,7 @@ export class BaseProtocol implements IBaseProtocolCore {
public readonly removeLibp2pEventListener: Libp2p["removeEventListener"]; public readonly removeLibp2pEventListener: Libp2p["removeEventListener"];
protected streamManager: StreamManager; protected streamManager: StreamManager;
constructor( protected constructor(
public multicodec: string, public multicodec: string,
private components: Libp2pComponents, private components: Libp2pComponents,
private log: Logger, private log: Logger,
@ -82,7 +82,7 @@ export class BaseProtocol implements IBaseProtocolCore {
* @returns A list of peers that support the protocol sorted by latency. * @returns A list of peers that support the protocol sorted by latency.
*/ */
async getPeers( public async getPeers(
{ {
numPeers, numPeers,
maxBootstrapPeers maxBootstrapPeers

View File

@ -8,16 +8,16 @@ import { v4 as uuid } from "uuid";
export class FilterPushRpc { export class FilterPushRpc {
public constructor(public proto: proto.MessagePush) {} public constructor(public proto: proto.MessagePush) {}
static decode(bytes: Uint8Array): FilterPushRpc { public static decode(bytes: Uint8Array): FilterPushRpc {
const res = proto.MessagePush.decode(bytes); const res = proto.MessagePush.decode(bytes);
return new FilterPushRpc(res); return new FilterPushRpc(res);
} }
encode(): Uint8Array { public encode(): Uint8Array {
return proto.MessagePush.encode(this.proto); return proto.MessagePush.encode(this.proto);
} }
get wakuMessage(): WakuMessage | undefined { public get wakuMessage(): WakuMessage | undefined {
return this.proto.wakuMessage; return this.proto.wakuMessage;
} }
@ -25,7 +25,7 @@ export class FilterPushRpc {
* Get the pubsub topic from the FilterPushRpc object. * Get the pubsub topic from the FilterPushRpc object.
* @returns string * @returns string
*/ */
get pubsubTopic(): string | undefined { public get pubsubTopic(): string | undefined {
return this.proto.pubsubTopic; return this.proto.pubsubTopic;
} }
} }
@ -33,7 +33,7 @@ export class FilterPushRpc {
export class FilterSubscribeRpc { export class FilterSubscribeRpc {
public constructor(public proto: proto.FilterSubscribeRequest) {} public constructor(public proto: proto.FilterSubscribeRequest) {}
static createSubscribeRequest( public static createSubscribeRequest(
pubsubTopic: string, pubsubTopic: string,
contentTopics: string[] contentTopics: string[]
): FilterSubscribeRpc { ): FilterSubscribeRpc {
@ -46,7 +46,7 @@ export class FilterSubscribeRpc {
}); });
} }
static createUnsubscribeRequest( public static createUnsubscribeRequest(
pubsubTopic: string, pubsubTopic: string,
contentTopics: string[] contentTopics: string[]
): FilterSubscribeRpc { ): FilterSubscribeRpc {
@ -59,7 +59,9 @@ export class FilterSubscribeRpc {
}); });
} }
static createUnsubscribeAllRequest(pubsubTopic: string): FilterSubscribeRpc { public static createUnsubscribeAllRequest(
pubsubTopic: string
): FilterSubscribeRpc {
return new FilterSubscribeRpc({ return new FilterSubscribeRpc({
requestId: uuid(), requestId: uuid(),
filterSubscribeType: filterSubscribeType:
@ -69,7 +71,7 @@ export class FilterSubscribeRpc {
}); });
} }
static createSubscriberPingRequest(): FilterSubscribeRpc { public static createSubscriberPingRequest(): FilterSubscribeRpc {
return new FilterSubscribeRpc({ return new FilterSubscribeRpc({
requestId: uuid(), requestId: uuid(),
filterSubscribeType: filterSubscribeType:
@ -79,28 +81,28 @@ export class FilterSubscribeRpc {
}); });
} }
static decode(bytes: Uint8Array): FilterSubscribeRpc { public static decode(bytes: Uint8Array): FilterSubscribeRpc {
const res = proto.FilterSubscribeRequest.decode(bytes); const res = proto.FilterSubscribeRequest.decode(bytes);
return new FilterSubscribeRpc(res); return new FilterSubscribeRpc(res);
} }
encode(): Uint8Array { public encode(): Uint8Array {
return proto.FilterSubscribeRequest.encode(this.proto); return proto.FilterSubscribeRequest.encode(this.proto);
} }
get filterSubscribeType(): proto.FilterSubscribeRequest.FilterSubscribeType { public get filterSubscribeType(): proto.FilterSubscribeRequest.FilterSubscribeType {
return this.proto.filterSubscribeType; return this.proto.filterSubscribeType;
} }
get requestId(): string { public get requestId(): string {
return this.proto.requestId; return this.proto.requestId;
} }
get pubsubTopic(): string | undefined { public get pubsubTopic(): string | undefined {
return this.proto.pubsubTopic; return this.proto.pubsubTopic;
} }
get contentTopics(): string[] { public get contentTopics(): string[] {
return this.proto.contentTopics; return this.proto.contentTopics;
} }
} }
@ -108,24 +110,24 @@ export class FilterSubscribeRpc {
export class FilterSubscribeResponse { export class FilterSubscribeResponse {
public constructor(public proto: proto.FilterSubscribeResponse) {} public constructor(public proto: proto.FilterSubscribeResponse) {}
static decode(bytes: Uint8Array): FilterSubscribeResponse { public static decode(bytes: Uint8Array): FilterSubscribeResponse {
const res = proto.FilterSubscribeResponse.decode(bytes); const res = proto.FilterSubscribeResponse.decode(bytes);
return new FilterSubscribeResponse(res); return new FilterSubscribeResponse(res);
} }
encode(): Uint8Array { public encode(): Uint8Array {
return proto.FilterSubscribeResponse.encode(this.proto); return proto.FilterSubscribeResponse.encode(this.proto);
} }
get statusCode(): number { public get statusCode(): number {
return this.proto.statusCode; return this.proto.statusCode;
} }
get statusDesc(): string | undefined { public get statusDesc(): string | undefined {
return this.proto.statusDesc; return this.proto.statusDesc;
} }
get requestId(): string { public get requestId(): string {
return this.proto.requestId; return this.proto.requestId;
} }
} }

View File

@ -32,7 +32,7 @@ export const FilterCodecs = {
}; };
export class FilterCore extends BaseProtocol implements IBaseProtocolCore { export class FilterCore extends BaseProtocol implements IBaseProtocolCore {
constructor( public constructor(
private handleIncomingMessage: ( private handleIncomingMessage: (
pubsubTopic: PubsubTopic, pubsubTopic: PubsubTopic,
wakuMessage: WakuMessage, wakuMessage: WakuMessage,
@ -58,47 +58,7 @@ export class FilterCore extends BaseProtocol implements IBaseProtocolCore {
}); });
} }
private onRequest(streamData: IncomingStreamData): void { public async subscribe(
const { connection, stream } = streamData;
const { remotePeer } = connection;
log.info(`Received message from ${remotePeer.toString()}`);
try {
pipe(stream, lp.decode, async (source) => {
for await (const bytes of source) {
const response = FilterPushRpc.decode(bytes.slice());
const { pubsubTopic, wakuMessage } = response;
if (!wakuMessage) {
log.error("Received empty message");
return;
}
if (!pubsubTopic) {
log.error("Pubsub topic missing from push message");
return;
}
await this.handleIncomingMessage(
pubsubTopic,
wakuMessage,
connection.remotePeer.toString()
);
}
}).then(
() => {
log.info("Receiving pipe closed.");
},
(e) => {
log.error("Error with receiving pipe", e);
}
);
} catch (e) {
log.error("Error decoding message", e);
}
}
async subscribe(
pubsubTopic: PubsubTopic, pubsubTopic: PubsubTopic,
peer: Peer, peer: Peer,
contentTopics: ContentTopic[] contentTopics: ContentTopic[]
@ -152,7 +112,7 @@ export class FilterCore extends BaseProtocol implements IBaseProtocolCore {
}; };
} }
async unsubscribe( public async unsubscribe(
pubsubTopic: PubsubTopic, pubsubTopic: PubsubTopic,
peer: Peer, peer: Peer,
contentTopics: ContentTopic[] contentTopics: ContentTopic[]
@ -198,7 +158,7 @@ export class FilterCore extends BaseProtocol implements IBaseProtocolCore {
}; };
} }
async unsubscribeAll( public async unsubscribeAll(
pubsubTopic: PubsubTopic, pubsubTopic: PubsubTopic,
peer: Peer peer: Peer
): Promise<CoreProtocolResult> { ): Promise<CoreProtocolResult> {
@ -246,7 +206,7 @@ export class FilterCore extends BaseProtocol implements IBaseProtocolCore {
}; };
} }
async ping(peer: Peer): Promise<CoreProtocolResult> { public async ping(peer: Peer): Promise<CoreProtocolResult> {
let stream: Stream | undefined; let stream: Stream | undefined;
try { try {
stream = await this.getStream(peer); stream = await this.getStream(peer);
@ -316,4 +276,44 @@ export class FilterCore extends BaseProtocol implements IBaseProtocolCore {
failure: null failure: null
}; };
} }
private onRequest(streamData: IncomingStreamData): void {
const { connection, stream } = streamData;
const { remotePeer } = connection;
log.info(`Received message from ${remotePeer.toString()}`);
try {
pipe(stream, lp.decode, async (source) => {
for await (const bytes of source) {
const response = FilterPushRpc.decode(bytes.slice());
const { pubsubTopic, wakuMessage } = response;
if (!wakuMessage) {
log.error("Received empty message");
return;
}
if (!pubsubTopic) {
log.error("Pubsub topic missing from push message");
return;
}
await this.handleIncomingMessage(
pubsubTopic,
wakuMessage,
connection.remotePeer.toString()
);
}
}).then(
() => {
log.info("Receiving pipe closed.");
},
(e) => {
log.error("Error with receiving pipe", e);
}
);
} catch (e) {
log.error("Error decoding message", e);
}
}
} }

View File

@ -26,7 +26,11 @@ export class KeepAliveManager {
private relayKeepAliveTimers: Map<PeerId, ReturnType<typeof setInterval>[]> = private relayKeepAliveTimers: Map<PeerId, ReturnType<typeof setInterval>[]> =
new Map(); new Map();
constructor({ options, relay, libp2p }: CreateKeepAliveManagerOptions) { public constructor({
options,
relay,
libp2p
}: CreateKeepAliveManagerOptions) {
this.options = options; this.options = options;
this.relay = relay; this.relay = relay;
this.libp2p = libp2p; this.libp2p = libp2p;

View File

@ -32,7 +32,7 @@ type PreparePushMessageResult = ThisOrThat<"query", PushRpc>;
* Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/). * Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/).
*/ */
export class LightPushCore extends BaseProtocol implements IBaseProtocolCore { export class LightPushCore extends BaseProtocol implements IBaseProtocolCore {
constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) { public constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
super( super(
LightPushCodec, LightPushCodec,
libp2p.components, libp2p.components,
@ -78,7 +78,7 @@ export class LightPushCore extends BaseProtocol implements IBaseProtocolCore {
} }
} }
async send( public async send(
encoder: IEncoder, encoder: IEncoder,
message: IMessage, message: IMessage,
peer: Peer peer: Peer

View File

@ -5,7 +5,7 @@ import { v4 as uuid } from "uuid";
export class PushRpc { export class PushRpc {
public constructor(public proto: proto.PushRpc) {} public constructor(public proto: proto.PushRpc) {}
static createRequest( public static createRequest(
message: proto.WakuMessage, message: proto.WakuMessage,
pubsubTopic: string pubsubTopic: string
): PushRpc { ): PushRpc {
@ -19,20 +19,20 @@ export class PushRpc {
}); });
} }
static decode(bytes: Uint8ArrayList): PushRpc { public static decode(bytes: Uint8ArrayList): PushRpc {
const res = proto.PushRpc.decode(bytes); const res = proto.PushRpc.decode(bytes);
return new PushRpc(res); return new PushRpc(res);
} }
encode(): Uint8Array { public encode(): Uint8Array {
return proto.PushRpc.encode(this.proto); return proto.PushRpc.encode(this.proto);
} }
get query(): proto.PushRequest | undefined { public get query(): proto.PushRequest | undefined {
return this.proto.request; return this.proto.request;
} }
get response(): proto.PushResponse | undefined { public get response(): proto.PushResponse | undefined {
return this.proto.response; return this.proto.response;
} }
} }

View File

@ -20,28 +20,28 @@ export const Version = 0;
export { proto }; export { proto };
export class DecodedMessage implements IDecodedMessage { export class DecodedMessage implements IDecodedMessage {
constructor( public constructor(
public pubsubTopic: string, public pubsubTopic: string,
protected proto: proto.WakuMessage protected proto: proto.WakuMessage
) {} ) {}
get ephemeral(): boolean { public get ephemeral(): boolean {
return Boolean(this.proto.ephemeral); return Boolean(this.proto.ephemeral);
} }
get payload(): Uint8Array { public get payload(): Uint8Array {
return this.proto.payload; return this.proto.payload;
} }
get contentTopic(): string { public get contentTopic(): string {
return this.proto.contentTopic; return this.proto.contentTopic;
} }
get _rawTimestamp(): bigint | undefined { public get _rawTimestamp(): bigint | undefined {
return this.proto.timestamp; return this.proto.timestamp;
} }
get timestamp(): Date | undefined { public get timestamp(): Date | undefined {
// In the case we receive a value that is bigger than JS's max number, // In the case we receive a value that is bigger than JS's max number,
// we catch the error and return undefined. // we catch the error and return undefined.
try { try {
@ -56,23 +56,23 @@ export class DecodedMessage implements IDecodedMessage {
} }
} }
get meta(): Uint8Array | undefined { public get meta(): Uint8Array | undefined {
return this.proto.meta; return this.proto.meta;
} }
get version(): number { public get version(): number {
// https://rfc.vac.dev/spec/14/ // https://rfc.vac.dev/spec/14/
// > If omitted, the value SHOULD be interpreted as version 0. // > If omitted, the value SHOULD be interpreted as version 0.
return this.proto.version ?? 0; return this.proto.version ?? 0;
} }
get rateLimitProof(): IRateLimitProof | undefined { public get rateLimitProof(): IRateLimitProof | undefined {
return this.proto.rateLimitProof; return this.proto.rateLimitProof;
} }
} }
export class Encoder implements IEncoder { export class Encoder implements IEncoder {
constructor( public constructor(
public contentTopic: string, public contentTopic: string,
public ephemeral: boolean = false, public ephemeral: boolean = false,
public pubsubTopic: PubsubTopic, public pubsubTopic: PubsubTopic,
@ -83,11 +83,11 @@ export class Encoder implements IEncoder {
} }
} }
async toWire(message: IMessage): Promise<Uint8Array> { public async toWire(message: IMessage): Promise<Uint8Array> {
return proto.WakuMessage.encode(await this.toProtoObj(message)); return proto.WakuMessage.encode(await this.toProtoObj(message));
} }
async toProtoObj(message: IMessage): Promise<IProtoMessage> { public async toProtoObj(message: IMessage): Promise<IProtoMessage> {
const timestamp = message.timestamp ?? new Date(); const timestamp = message.timestamp ?? new Date();
const protoMessage = { const protoMessage = {
@ -133,7 +133,7 @@ export function createEncoder({
} }
export class Decoder implements IDecoder<DecodedMessage> { export class Decoder implements IDecoder<DecodedMessage> {
constructor( public constructor(
public pubsubTopic: PubsubTopic, public pubsubTopic: PubsubTopic,
public contentTopic: string public contentTopic: string
) { ) {
@ -142,7 +142,9 @@ export class Decoder implements IDecoder<DecodedMessage> {
} }
} }
fromWireToProtoObj(bytes: Uint8Array): Promise<IProtoMessage | undefined> { public fromWireToProtoObj(
bytes: Uint8Array
): Promise<IProtoMessage | undefined> {
const protoMessage = proto.WakuMessage.decode(bytes); const protoMessage = proto.WakuMessage.decode(bytes);
return Promise.resolve({ return Promise.resolve({
payload: protoMessage.payload, payload: protoMessage.payload,
@ -155,7 +157,7 @@ export class Decoder implements IDecoder<DecodedMessage> {
}); });
} }
async fromProtoObj( public async fromProtoObj(
pubsubTopic: string, pubsubTopic: string,
proto: IProtoMessage proto: IProtoMessage
): Promise<DecodedMessage | undefined> { ): Promise<DecodedMessage | undefined> {

View File

@ -23,9 +23,9 @@ export const MetadataCodec = "/vac/waku/metadata/1.0.0";
class Metadata extends BaseProtocol implements IMetadata { class Metadata extends BaseProtocol implements IMetadata {
private libp2pComponents: Libp2pComponents; private libp2pComponents: Libp2pComponents;
handshakesConfirmed: Map<PeerIdStr, ShardInfo> = new Map(); protected handshakesConfirmed: Map<PeerIdStr, ShardInfo> = new Map();
constructor( public constructor(
public shardInfo: ShardInfo, public shardInfo: ShardInfo,
libp2p: Libp2pComponents libp2p: Libp2pComponents
) { ) {
@ -41,40 +41,10 @@ class Metadata extends BaseProtocol implements IMetadata {
}); });
} }
/**
* Handle an incoming metadata request
*/
private async onRequest(streamData: IncomingStreamData): Promise<void> {
try {
const { stream, connection } = streamData;
const encodedShardInfo = proto_metadata.WakuMetadataResponse.encode(
this.shardInfo
);
const encodedResponse = await pipe(
[encodedShardInfo],
lp.encode,
stream,
lp.decode,
async (source) => await all(source)
);
const { error, shardInfo } = this.decodeMetadataResponse(encodedResponse);
if (error) {
return;
}
await this.savePeerShardInfo(connection.remotePeer, shardInfo);
} catch (error) {
log.error("Error handling metadata request", error);
}
}
/** /**
* Make a metadata query to a peer * Make a metadata query to a peer
*/ */
async query(peerId: PeerId): Promise<MetadataQueryResult> { public async query(peerId: PeerId): Promise<MetadataQueryResult> {
const request = proto_metadata.WakuMetadataRequest.encode(this.shardInfo); const request = proto_metadata.WakuMetadataRequest.encode(this.shardInfo);
const peer = await this.peerStore.get(peerId); const peer = await this.peerStore.get(peerId);
@ -135,6 +105,36 @@ class Metadata extends BaseProtocol implements IMetadata {
return await this.query(peerId); return await this.query(peerId);
} }
/**
* Handle an incoming metadata request
*/
private async onRequest(streamData: IncomingStreamData): Promise<void> {
try {
const { stream, connection } = streamData;
const encodedShardInfo = proto_metadata.WakuMetadataResponse.encode(
this.shardInfo
);
const encodedResponse = await pipe(
[encodedShardInfo],
lp.encode,
stream,
lp.decode,
async (source) => await all(source)
);
const { error, shardInfo } = this.decodeMetadataResponse(encodedResponse);
if (error) {
return;
}
await this.savePeerShardInfo(connection.remotePeer, shardInfo);
} catch (error) {
log.error("Error handling metadata request", error);
}
}
private decodeMetadataResponse( private decodeMetadataResponse(
encodedResponse: Uint8ArrayList[] encodedResponse: Uint8ArrayList[]
): MetadataQueryResult { ): MetadataQueryResult {

View File

@ -22,18 +22,18 @@ export interface Params {
export class HistoryRpc { export class HistoryRpc {
private constructor(public readonly proto: proto.HistoryRpc) {} private constructor(public readonly proto: proto.HistoryRpc) {}
get query(): proto.HistoryQuery | undefined { public get query(): proto.HistoryQuery | undefined {
return this.proto.query; return this.proto.query;
} }
get response(): proto.HistoryResponse | undefined { public get response(): proto.HistoryResponse | undefined {
return this.proto.response; return this.proto.response;
} }
/** /**
* Create History Query. * Create History Query.
*/ */
static createQuery(params: Params): HistoryRpc { public static createQuery(params: Params): HistoryRpc {
const contentFilters = params.contentTopics.map((contentTopic) => { const contentFilters = params.contentTopics.map((contentTopic) => {
return { contentTopic }; return { contentTopic };
}); });
@ -69,12 +69,12 @@ export class HistoryRpc {
}); });
} }
decode(bytes: Uint8ArrayList): HistoryRpc { public decode(bytes: Uint8ArrayList): HistoryRpc {
const res = proto.HistoryRpc.decode(bytes); const res = proto.HistoryRpc.decode(bytes);
return new HistoryRpc(res); return new HistoryRpc(res);
} }
encode(): Uint8Array { public encode(): Uint8Array {
return proto.HistoryRpc.encode(this.proto); return proto.HistoryRpc.encode(this.proto);
} }
} }

View File

@ -68,11 +68,11 @@ export interface QueryOptions {
* The Waku Store protocol can be used to retrieved historical messages. * The Waku Store protocol can be used to retrieved historical messages.
*/ */
export class StoreCore extends BaseProtocol implements IStoreCore { export class StoreCore extends BaseProtocol implements IStoreCore {
constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) { public constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
super(StoreCodec, libp2p.components, log, options!.pubsubTopics!, options); super(StoreCodec, libp2p.components, log, options!.pubsubTopics!, options);
} }
async *queryPerPage<T extends IDecodedMessage>( public async *queryPerPage<T extends IDecodedMessage>(
queryOpts: Params, queryOpts: Params,
decoders: Map<string, IDecoder<T>>, decoders: Map<string, IDecoder<T>>,
peer: Peer peer: Peer

View File

@ -13,7 +13,7 @@ export class StreamManager {
private readonly streamPool: Map<string, Promise<Stream | void>>; private readonly streamPool: Map<string, Promise<Stream | void>>;
private readonly log: Logger; private readonly log: Logger;
constructor( public constructor(
public multicodec: string, public multicodec: string,
public getConnections: Libp2p["getConnections"], public getConnections: Libp2p["getConnections"],
public addEventListener: Libp2p["addEventListener"] public addEventListener: Libp2p["addEventListener"]

View File

@ -32,23 +32,23 @@ const errorBranchB = `enrtree-branch:${branchDomainD}`;
* Mocks DNS resolution. * Mocks DNS resolution.
*/ */
class MockDNS implements DnsClient { class MockDNS implements DnsClient {
fqdnRes: Map<string, string[]>; private fqdnRes: Map<string, string[]>;
fqdnThrows: string[]; private fqdnThrows: string[];
constructor() { public constructor() {
this.fqdnRes = new Map(); this.fqdnRes = new Map();
this.fqdnThrows = []; this.fqdnThrows = [];
} }
addRes(fqdn: string, res: string[]): void { public addRes(fqdn: string, res: string[]): void {
this.fqdnRes.set(fqdn, res); this.fqdnRes.set(fqdn, res);
} }
addThrow(fqdn: string): void { public addThrow(fqdn: string): void {
this.fqdnThrows.push(fqdn); this.fqdnThrows.push(fqdn);
} }
resolveTXT(fqdn: string): Promise<string[]> { public resolveTXT(fqdn: string): Promise<string[]> {
if (this.fqdnThrows.includes(fqdn)) throw "Mock DNS throws."; if (this.fqdnThrows.includes(fqdn)) throw "Mock DNS throws.";
const res = this.fqdnRes.get(fqdn); const res = this.fqdnRes.get(fqdn);

View File

@ -37,7 +37,7 @@ export class DnsNodeDiscovery {
* peers encountered by randomized search exceeds the sum of the fields of * peers encountered by randomized search exceeds the sum of the fields of
* @link wantedNodeCapabilityCount plus the @link _errorTolerance factor. * @link wantedNodeCapabilityCount plus the @link _errorTolerance factor.
*/ */
async getPeers( public async getPeers(
enrTreeUrls: string[], enrTreeUrls: string[],
wantedNodeCapabilityCount: Partial<NodeCapabilityCount> wantedNodeCapabilityCount: Partial<NodeCapabilityCount>
): Promise<IEnr[]> { ): Promise<IEnr[]> {
@ -74,7 +74,7 @@ export class DnsNodeDiscovery {
/** /**
* {@inheritDoc getPeers} * {@inheritDoc getPeers}
*/ */
async *getNextPeer( public async *getNextPeer(
enrTreeUrls: string[], enrTreeUrls: string[],
wantedNodeCapabilityCount: Partial<NodeCapabilityCount> wantedNodeCapabilityCount: Partial<NodeCapabilityCount>
): AsyncGenerator<IEnr> { ): AsyncGenerator<IEnr> {

View File

@ -36,7 +36,10 @@ export class PeerDiscoveryDns
private _components: DnsDiscoveryComponents; private _components: DnsDiscoveryComponents;
private _options: DnsDiscOptions; private _options: DnsDiscOptions;
constructor(components: DnsDiscoveryComponents, options: DnsDiscOptions) { public constructor(
components: DnsDiscoveryComponents,
options: DnsDiscOptions
) {
super(); super();
this._started = false; this._started = false;
this._components = components; this._components = components;
@ -49,7 +52,7 @@ export class PeerDiscoveryDns
/** /**
* Start discovery process * Start discovery process
*/ */
async start(): Promise<void> { public async start(): Promise<void> {
log.info("Starting peer discovery via dns"); log.info("Starting peer discovery via dns");
this._started = true; this._started = true;
@ -122,15 +125,15 @@ export class PeerDiscoveryDns
/** /**
* Stop emitting events * Stop emitting events
*/ */
stop(): void { public stop(): void {
this._started = false; this._started = false;
} }
get [symbol](): true { public get [symbol](): true {
return true; return true;
} }
get [Symbol.toStringTag](): string { public get [Symbol.toStringTag](): string {
return "@waku/bootstrap"; return "@waku/bootstrap";
} }
} }

View File

@ -36,7 +36,7 @@ export class DnsOverHttps implements DnsClient {
* *
* @throws if the query fails * @throws if the query fails
*/ */
async resolveTXT(domain: string): Promise<string[]> { public async resolveTXT(domain: string): Promise<string[]> {
let answers; let answers;
try { try {
const res = await query( const res = await query(

View File

@ -26,7 +26,7 @@ export class ENRTree {
* Extracts the branch subdomain referenced by a DNS tree root string after verifying * Extracts the branch subdomain referenced by a DNS tree root string after verifying
* the root record signature with its base32 compressed public key. * the root record signature with its base32 compressed public key.
*/ */
static parseAndVerifyRoot(root: string, publicKey: string): string { public static parseAndVerifyRoot(root: string, publicKey: string): string {
if (!root.startsWith(this.ROOT_PREFIX)) if (!root.startsWith(this.ROOT_PREFIX))
throw new Error( throw new Error(
`ENRTree root entry must start with '${this.ROOT_PREFIX}'` `ENRTree root entry must start with '${this.ROOT_PREFIX}'`
@ -57,7 +57,7 @@ export class ENRTree {
return rootValues.eRoot; return rootValues.eRoot;
} }
static parseRootValues(txt: string): ENRRootValues { public static parseRootValues(txt: string): ENRRootValues {
const matches = txt.match( const matches = txt.match(
/^enrtree-root:v1 e=([^ ]+) l=([^ ]+) seq=(\d+) sig=([^ ]+)$/ /^enrtree-root:v1 e=([^ ]+) l=([^ ]+) seq=(\d+) sig=([^ ]+)$/
); );
@ -86,7 +86,7 @@ export class ENRTree {
* The domain is the starting point for traversing a set of linked DNS TXT records * The domain is the starting point for traversing a set of linked DNS TXT records
* and the public key is used to verify the root entry record * and the public key is used to verify the root entry record
*/ */
static parseTree(tree: string): ENRTreeValues { public static parseTree(tree: string): ENRTreeValues {
if (!tree.startsWith(this.TREE_PREFIX)) if (!tree.startsWith(this.TREE_PREFIX))
throw new Error( throw new Error(
`ENRTree tree entry must start with '${this.TREE_PREFIX}'` `ENRTree tree entry must start with '${this.TREE_PREFIX}'`
@ -112,7 +112,7 @@ export class ENRTree {
* Returns subdomains listed in an ENR branch entry. These in turn lead to * Returns subdomains listed in an ENR branch entry. These in turn lead to
* either further branch entries or ENR records. * either further branch entries or ENR records.
*/ */
static parseBranch(branch: string): string[] { public static parseBranch(branch: string): string[] {
if (!branch.startsWith(this.BRANCH_PREFIX)) if (!branch.startsWith(this.BRANCH_PREFIX))
throw new Error( throw new Error(
`ENRTree branch entry must start with '${this.BRANCH_PREFIX}'` `ENRTree branch entry must start with '${this.BRANCH_PREFIX}'`

View File

@ -35,7 +35,7 @@ export class LocalPeerCacheDiscovery
private isStarted: boolean; private isStarted: boolean;
private peers: LocalStoragePeerInfo[] = []; private peers: LocalStoragePeerInfo[] = [];
constructor( public constructor(
private readonly components: Libp2pComponents, private readonly components: Libp2pComponents,
private readonly options?: LocalPeerCacheDiscoveryOptions private readonly options?: LocalPeerCacheDiscoveryOptions
) { ) {
@ -44,11 +44,11 @@ export class LocalPeerCacheDiscovery
this.peers = this.getPeersFromLocalStorage(); this.peers = this.getPeersFromLocalStorage();
} }
get [Symbol.toStringTag](): string { public get [Symbol.toStringTag](): string {
return "@waku/local-peer-cache-discovery"; return "@waku/local-peer-cache-discovery";
} }
async start(): Promise<void> { public async start(): Promise<void> {
if (this.isStarted) return; if (this.isStarted) return;
log.info("Starting Local Storage Discovery"); log.info("Starting Local Storage Discovery");
@ -86,7 +86,7 @@ export class LocalPeerCacheDiscovery
this.isStarted = true; this.isStarted = true;
} }
stop(): void | Promise<void> { public stop(): void | Promise<void> {
if (!this.isStarted) return; if (!this.isStarted) return;
log.info("Stopping Local Storage Discovery"); log.info("Stopping Local Storage Discovery");
this.components.events.removeEventListener( this.components.events.removeEventListener(
@ -98,7 +98,7 @@ export class LocalPeerCacheDiscovery
this.savePeersToLocalStorage(); this.savePeersToLocalStorage();
} }
handleNewPeers = (event: CustomEvent<IdentifyResult>): void => { public handleNewPeers = (event: CustomEvent<IdentifyResult>): void => {
const { peerId, listenAddrs } = event.detail; const { peerId, listenAddrs } = event.detail;
const websocketMultiaddr = getWsMultiaddrFromMultiaddrs(listenAddrs); const websocketMultiaddr = getWsMultiaddrFromMultiaddrs(listenAddrs);

View File

@ -7,7 +7,9 @@ import type { Uint8ArrayList } from "uint8arraylist";
export class PeerExchangeRPC { export class PeerExchangeRPC {
public constructor(public proto: proto.PeerExchangeRPC) {} public constructor(public proto: proto.PeerExchangeRPC) {}
static createRequest(params: proto.PeerExchangeQuery): PeerExchangeRPC { public static createRequest(
params: proto.PeerExchangeQuery
): PeerExchangeRPC {
const { numPeers } = params; const { numPeers } = params;
return new PeerExchangeRPC({ return new PeerExchangeRPC({
query: { query: {
@ -21,7 +23,7 @@ export class PeerExchangeRPC {
* Encode the current PeerExchangeRPC request to bytes * Encode the current PeerExchangeRPC request to bytes
* @returns Uint8Array * @returns Uint8Array
*/ */
encode(): Uint8Array { public encode(): Uint8Array {
return proto.PeerExchangeRPC.encode(this.proto); return proto.PeerExchangeRPC.encode(this.proto);
} }
@ -29,16 +31,16 @@ export class PeerExchangeRPC {
* Decode the current PeerExchangeRPC request to bytes * Decode the current PeerExchangeRPC request to bytes
* @returns Uint8Array * @returns Uint8Array
*/ */
static decode(bytes: Uint8ArrayList): PeerExchangeRPC { public static decode(bytes: Uint8ArrayList): PeerExchangeRPC {
const res = proto.PeerExchangeRPC.decode(bytes); const res = proto.PeerExchangeRPC.decode(bytes);
return new PeerExchangeRPC(res); return new PeerExchangeRPC(res);
} }
get query(): proto.PeerExchangeQuery | undefined { public get query(): proto.PeerExchangeQuery | undefined {
return this.proto.query; return this.proto.query;
} }
get response(): proto.PeerExchangeResponse | undefined { public get response(): proto.PeerExchangeResponse | undefined {
return this.proto.response; return this.proto.response;
} }
} }

View File

@ -28,14 +28,17 @@ export class WakuPeerExchange extends BaseProtocol implements IPeerExchange {
/** /**
* @param components - libp2p components * @param components - libp2p components
*/ */
constructor(components: Libp2pComponents, pubsubTopics: PubsubTopic[]) { public constructor(
components: Libp2pComponents,
pubsubTopics: PubsubTopic[]
) {
super(PeerExchangeCodec, components, log, pubsubTopics); super(PeerExchangeCodec, components, log, pubsubTopics);
} }
/** /**
* Make a peer exchange query to a peer * Make a peer exchange query to a peer
*/ */
async query( public async query(
params: PeerExchangeQueryParams params: PeerExchangeQueryParams
): Promise<PeerExchangeQueryResult> { ): Promise<PeerExchangeQueryResult> {
const { numPeers } = params; const { numPeers } = params;

View File

@ -82,7 +82,7 @@ export class PeerExchangeDiscovery
); );
}; };
constructor( public constructor(
components: Libp2pComponents, components: Libp2pComponents,
pubsubTopics: PubsubTopic[], pubsubTopics: PubsubTopic[],
options: Options = {} options: Options = {}
@ -97,7 +97,7 @@ export class PeerExchangeDiscovery
/** /**
* Start emitting events * Start emitting events
*/ */
start(): void { public start(): void {
if (this.isStarted) { if (this.isStarted) {
return; return;
} }
@ -114,7 +114,7 @@ export class PeerExchangeDiscovery
/** /**
* Remove event listener * Remove event listener
*/ */
stop(): void { public stop(): void {
if (!this.isStarted) return; if (!this.isStarted) return;
log.info("Stopping peer exchange node discovery"); log.info("Stopping peer exchange node discovery");
this.isStarted = false; this.isStarted = false;
@ -125,11 +125,11 @@ export class PeerExchangeDiscovery
); );
} }
get [symbol](): true { public get [symbol](): true {
return true; return true;
} }
get [Symbol.toStringTag](): string { public get [Symbol.toStringTag](): string {
return "@waku/peer-exchange"; return "@waku/peer-exchange";
} }

View File

@ -7,7 +7,7 @@ import { ENR } from "./enr.js";
import { getPublicKeyFromPeerId } from "./peer_id.js"; import { getPublicKeyFromPeerId } from "./peer_id.js";
export class EnrCreator { export class EnrCreator {
static fromPublicKey( public static fromPublicKey(
publicKey: Uint8Array, publicKey: Uint8Array,
kvs: Record<ENRKey, ENRValue> = {} kvs: Record<ENRKey, ENRValue> = {}
): Promise<ENR> { ): Promise<ENR> {
@ -22,7 +22,7 @@ export class EnrCreator {
}); });
} }
static async fromPeerId( public static async fromPeerId(
peerId: PeerId, peerId: PeerId,
kvs: Record<ENRKey, ENRValue> = {} kvs: Record<ENRKey, ENRValue> = {}
): Promise<ENR> { ): Promise<ENR> {

View File

@ -9,7 +9,7 @@ import { ENR } from "./enr.js";
const log = new Logger("enr:decoder"); const log = new Logger("enr:decoder");
export class EnrDecoder { export class EnrDecoder {
static fromString(encoded: string): Promise<ENR> { public static fromString(encoded: string): Promise<ENR> {
if (!encoded.startsWith(ENR.RECORD_PREFIX)) { if (!encoded.startsWith(ENR.RECORD_PREFIX)) {
throw new Error( throw new Error(
`"string encoded ENR must start with '${ENR.RECORD_PREFIX}'` `"string encoded ENR must start with '${ENR.RECORD_PREFIX}'`
@ -18,7 +18,7 @@ export class EnrDecoder {
return EnrDecoder.fromRLP(fromString(encoded.slice(4), "base64url")); return EnrDecoder.fromRLP(fromString(encoded.slice(4), "base64url"));
} }
static fromRLP(encoded: Uint8Array): Promise<ENR> { public static fromRLP(encoded: Uint8Array): Promise<ENR> {
const decoded = RLP.decode(encoded).map(hexToBytes); const decoded = RLP.decode(encoded).map(hexToBytes);
return fromValues(decoded); return fromValues(decoded);
} }

View File

@ -7,7 +7,7 @@ import { ERR_NO_SIGNATURE, MAX_RECORD_SIZE } from "./constants.js";
import { ENR } from "./enr.js"; import { ENR } from "./enr.js";
export class EnrEncoder { export class EnrEncoder {
static async toValues( public static async toValues(
enr: ENR, enr: ENR,
privateKey?: Uint8Array privateKey?: Uint8Array
): Promise<(ENRKey | ENRValue | number[])[]> { ): Promise<(ENRKey | ENRValue | number[])[]> {
@ -31,7 +31,10 @@ export class EnrEncoder {
return content; return content;
} }
static async toBytes(enr: ENR, privateKey?: Uint8Array): Promise<Uint8Array> { public static async toBytes(
enr: ENR,
privateKey?: Uint8Array
): Promise<Uint8Array> {
const encoded = hexToBytes( const encoded = hexToBytes(
RLP.encode(await EnrEncoder.toValues(enr, privateKey)) RLP.encode(await EnrEncoder.toValues(enr, privateKey))
); );
@ -41,7 +44,10 @@ export class EnrEncoder {
return encoded; return encoded;
} }
static async toString(enr: ENR, privateKey?: Uint8Array): Promise<string> { public static async toString(
enr: ENR,
privateKey?: Uint8Array
): Promise<string> {
return ( return (
ENR.RECORD_PREFIX + ENR.RECORD_PREFIX +
toString(await EnrEncoder.toBytes(enr, privateKey), "base64url") toString(await EnrEncoder.toBytes(enr, privateKey), "base64url")

View File

@ -34,7 +34,7 @@ export class ENR extends RawEnr implements IEnr {
public static readonly RECORD_PREFIX = "enr:"; public static readonly RECORD_PREFIX = "enr:";
public peerId?: PeerId; public peerId?: PeerId;
static async create( public static async create(
kvs: Record<ENRKey, ENRValue> = {}, kvs: Record<ENRKey, ENRValue> = {},
seq: SequenceNumber = BigInt(1), seq: SequenceNumber = BigInt(1),
signature?: Uint8Array signature?: Uint8Array
@ -52,7 +52,7 @@ export class ENR extends RawEnr implements IEnr {
return enr; return enr;
} }
get nodeId(): NodeId | undefined { public get nodeId(): NodeId | undefined {
switch (this.id) { switch (this.id) {
case "v4": case "v4":
return this.publicKey ? v4.nodeId(this.publicKey) : undefined; return this.publicKey ? v4.nodeId(this.publicKey) : undefined;
@ -60,18 +60,18 @@ export class ENR extends RawEnr implements IEnr {
throw new Error(ERR_INVALID_ID); throw new Error(ERR_INVALID_ID);
} }
} }
getLocationMultiaddr: ( public getLocationMultiaddr: (
protocol: TransportProtocol | TransportProtocolPerIpVersion protocol: TransportProtocol | TransportProtocolPerIpVersion
) => Multiaddr | undefined = locationMultiaddrFromEnrFields.bind({}, this); ) => Multiaddr | undefined = locationMultiaddrFromEnrFields.bind({}, this);
get shardInfo(): ShardInfo | undefined { public get shardInfo(): ShardInfo | undefined {
if (this.rs && this.rsv) { if (this.rs && this.rsv) {
log.warn("ENR contains both `rs` and `rsv` fields."); log.warn("ENR contains both `rs` and `rsv` fields.");
} }
return this.rs || this.rsv; return this.rs || this.rsv;
} }
setLocationMultiaddr(multiaddr: Multiaddr): void { public setLocationMultiaddr(multiaddr: Multiaddr): void {
const protoNames = multiaddr.protoNames(); const protoNames = multiaddr.protoNames();
if ( if (
protoNames.length !== 2 && protoNames.length !== 2 &&
@ -95,7 +95,7 @@ export class ENR extends RawEnr implements IEnr {
} }
} }
getAllLocationMultiaddrs(): Multiaddr[] { public getAllLocationMultiaddrs(): Multiaddr[] {
const multiaddrs = []; const multiaddrs = [];
for (const protocol of Object.values(TransportProtocolPerIpVersion)) { for (const protocol of Object.values(TransportProtocolPerIpVersion)) {
@ -115,7 +115,7 @@ export class ENR extends RawEnr implements IEnr {
}); });
} }
get peerInfo(): PeerInfo | undefined { public get peerInfo(): PeerInfo | undefined {
const id = this.peerId; const id = this.peerId;
if (!id) return; if (!id) return;
return { return {
@ -132,7 +132,7 @@ export class ENR extends RawEnr implements IEnr {
* *
* @param protocol * @param protocol
*/ */
getFullMultiaddr( public getFullMultiaddr(
protocol: TransportProtocol | TransportProtocolPerIpVersion protocol: TransportProtocol | TransportProtocolPerIpVersion
): Multiaddr | undefined { ): Multiaddr | undefined {
if (this.peerId) { if (this.peerId) {
@ -147,7 +147,7 @@ export class ENR extends RawEnr implements IEnr {
/** /**
* Returns the full multiaddrs from the `multiaddrs` ENR field. * Returns the full multiaddrs from the `multiaddrs` ENR field.
*/ */
getFullMultiaddrs(): Multiaddr[] { public getFullMultiaddrs(): Multiaddr[] {
if (this.peerId && this.multiaddrs) { if (this.peerId && this.multiaddrs) {
const peerId = this.peerId; const peerId = this.peerId;
return this.multiaddrs.map((ma) => { return this.multiaddrs.map((ma) => {
@ -157,7 +157,7 @@ export class ENR extends RawEnr implements IEnr {
return []; return [];
} }
verify(data: Uint8Array, signature: Uint8Array): boolean { public verify(data: Uint8Array, signature: Uint8Array): boolean {
if (!this.get("id") || this.id !== "v4") { if (!this.get("id") || this.id !== "v4") {
throw new Error(ERR_INVALID_ID); throw new Error(ERR_INVALID_ID);
} }
@ -167,7 +167,10 @@ export class ENR extends RawEnr implements IEnr {
return verifySignature(signature, keccak256(data), this.publicKey); return verifySignature(signature, keccak256(data), this.publicKey);
} }
async sign(data: Uint8Array, privateKey: Uint8Array): Promise<Uint8Array> { public async sign(
data: Uint8Array,
privateKey: Uint8Array
): Promise<Uint8Array> {
switch (this.id) { switch (this.id) {
case "v4": case "v4":
this.signature = await v4.sign(privateKey, data); this.signature = await v4.sign(privateKey, data);

View File

@ -31,19 +31,19 @@ export class RawEnr extends Map<ENRKey, ENRValue> {
this.signature = signature; this.signature = signature;
} }
set(k: ENRKey, v: ENRValue): this { public set(k: ENRKey, v: ENRValue): this {
this.signature = undefined; this.signature = undefined;
this.seq++; this.seq++;
return super.set(k, v); return super.set(k, v);
} }
get id(): string { public get id(): string {
const id = this.get("id"); const id = this.get("id");
if (!id) throw new Error("id not found."); if (!id) throw new Error("id not found.");
return bytesToUtf8(id); return bytesToUtf8(id);
} }
get publicKey(): Uint8Array | undefined { public get publicKey(): Uint8Array | undefined {
switch (this.id) { switch (this.id) {
case "v4": case "v4":
return this.get("secp256k1"); return this.get("secp256k1");
@ -52,63 +52,63 @@ export class RawEnr extends Map<ENRKey, ENRValue> {
} }
} }
get rs(): ShardInfo | undefined { public get rs(): ShardInfo | undefined {
const rs = this.get("rs"); const rs = this.get("rs");
if (!rs) return undefined; if (!rs) return undefined;
return decodeRelayShard(rs); return decodeRelayShard(rs);
} }
get rsv(): ShardInfo | undefined { public get rsv(): ShardInfo | undefined {
const rsv = this.get("rsv"); const rsv = this.get("rsv");
if (!rsv) return undefined; if (!rsv) return undefined;
return decodeRelayShard(rsv); return decodeRelayShard(rsv);
} }
get ip(): string | undefined { public get ip(): string | undefined {
return getStringValue(this, "ip", "ip4"); return getStringValue(this, "ip", "ip4");
} }
set ip(ip: string | undefined) { public set ip(ip: string | undefined) {
setStringValue(this, "ip", "ip4", ip); setStringValue(this, "ip", "ip4", ip);
} }
get tcp(): number | undefined { public get tcp(): number | undefined {
return getNumberAsStringValue(this, "tcp", "tcp"); return getNumberAsStringValue(this, "tcp", "tcp");
} }
set tcp(port: number | undefined) { public set tcp(port: number | undefined) {
setNumberAsStringValue(this, "tcp", "tcp", port); setNumberAsStringValue(this, "tcp", "tcp", port);
} }
get udp(): number | undefined { public get udp(): number | undefined {
return getNumberAsStringValue(this, "udp", "udp"); return getNumberAsStringValue(this, "udp", "udp");
} }
set udp(port: number | undefined) { public set udp(port: number | undefined) {
setNumberAsStringValue(this, "udp", "udp", port); setNumberAsStringValue(this, "udp", "udp", port);
} }
get ip6(): string | undefined { public get ip6(): string | undefined {
return getStringValue(this, "ip6", "ip6"); return getStringValue(this, "ip6", "ip6");
} }
set ip6(ip: string | undefined) { public set ip6(ip: string | undefined) {
setStringValue(this, "ip6", "ip6", ip); setStringValue(this, "ip6", "ip6", ip);
} }
get tcp6(): number | undefined { public get tcp6(): number | undefined {
return getNumberAsStringValue(this, "tcp6", "tcp"); return getNumberAsStringValue(this, "tcp6", "tcp");
} }
set tcp6(port: number | undefined) { public set tcp6(port: number | undefined) {
setNumberAsStringValue(this, "tcp6", "tcp", port); setNumberAsStringValue(this, "tcp6", "tcp", port);
} }
get udp6(): number | undefined { public get udp6(): number | undefined {
return getNumberAsStringValue(this, "udp6", "udp"); return getNumberAsStringValue(this, "udp6", "udp");
} }
set udp6(port: number | undefined) { public set udp6(port: number | undefined) {
setNumberAsStringValue(this, "udp6", "udp", port); setNumberAsStringValue(this, "udp6", "udp", port);
} }
@ -124,7 +124,7 @@ export class RawEnr extends Map<ENRKey, ENRValue> {
* *
* The multiaddresses stored in this field are expected to be location multiaddresses, ie, peer id less. * The multiaddresses stored in this field are expected to be location multiaddresses, ie, peer id less.
*/ */
get multiaddrs(): Multiaddr[] | undefined { public get multiaddrs(): Multiaddr[] | undefined {
const raw = this.get("multiaddrs"); const raw = this.get("multiaddrs");
if (raw) return decodeMultiaddrs(raw); if (raw) return decodeMultiaddrs(raw);
@ -144,14 +144,14 @@ export class RawEnr extends Map<ENRKey, ENRValue> {
* The multiaddresses stored in this field must be location multiaddresses, * The multiaddresses stored in this field must be location multiaddresses,
* ie, without a peer id. * ie, without a peer id.
*/ */
set multiaddrs(multiaddrs: Multiaddr[] | undefined) { public set multiaddrs(multiaddrs: Multiaddr[] | undefined) {
deleteUndefined(this, "multiaddrs", multiaddrs, encodeMultiaddrs); deleteUndefined(this, "multiaddrs", multiaddrs, encodeMultiaddrs);
} }
/** /**
* Get the `waku2` field from ENR. * Get the `waku2` field from ENR.
*/ */
get waku2(): Waku2 | undefined { public get waku2(): Waku2 | undefined {
const raw = this.get("waku2"); const raw = this.get("waku2");
if (raw) return decodeWaku2(raw[0]); if (raw) return decodeWaku2(raw[0]);
@ -161,7 +161,7 @@ export class RawEnr extends Map<ENRKey, ENRValue> {
/** /**
* Set the `waku2` field on the ENR. * Set the `waku2` field on the ENR.
*/ */
set waku2(waku2: Waku2 | undefined) { public set waku2(waku2: Waku2 | undefined) {
deleteUndefined( deleteUndefined(
this, this,
"waku2", "waku2",

View File

@ -11,7 +11,7 @@ export class DecodedMessage
{ {
private readonly _decodedPayload: Uint8Array; private readonly _decodedPayload: Uint8Array;
constructor( public constructor(
pubsubTopic: string, pubsubTopic: string,
proto: proto.WakuMessage, proto: proto.WakuMessage,
decodedPayload: Uint8Array, decodedPayload: Uint8Array,
@ -22,7 +22,7 @@ export class DecodedMessage
this._decodedPayload = decodedPayload; this._decodedPayload = decodedPayload;
} }
get payload(): Uint8Array { public get payload(): Uint8Array {
return this._decodedPayload; return this._decodedPayload;
} }
@ -31,7 +31,7 @@ export class DecodedMessage
* *
* @returns true if the signature matches the public key, false if not or if no signature is present. * @returns true if the signature matches the public key, false if not or if no signature is present.
*/ */
verifySignature(publicKey: Uint8Array): boolean { public verifySignature(publicKey: Uint8Array): boolean {
if (this.signaturePublicKey) { if (this.signaturePublicKey) {
return equals(this.signaturePublicKey, publicKey); return equals(this.signaturePublicKey, publicKey);
} }

View File

@ -33,7 +33,7 @@ export {
const log = new Logger("message-encryption:ecies"); const log = new Logger("message-encryption:ecies");
class Encoder implements IEncoder { class Encoder implements IEncoder {
constructor( public constructor(
public pubsubTopic: PubsubTopic, public pubsubTopic: PubsubTopic,
public contentTopic: string, public contentTopic: string,
private publicKey: Uint8Array, private publicKey: Uint8Array,
@ -46,14 +46,16 @@ class Encoder implements IEncoder {
} }
} }
async toWire(message: IMessage): Promise<Uint8Array | undefined> { public async toWire(message: IMessage): Promise<Uint8Array | undefined> {
const protoMessage = await this.toProtoObj(message); const protoMessage = await this.toProtoObj(message);
if (!protoMessage) return; if (!protoMessage) return;
return WakuMessage.encode(protoMessage); return WakuMessage.encode(protoMessage);
} }
async toProtoObj(message: IMessage): Promise<IProtoMessage | undefined> { public async toProtoObj(
message: IMessage
): Promise<IProtoMessage | undefined> {
const timestamp = message.timestamp ?? new Date(); const timestamp = message.timestamp ?? new Date();
const preparedPayload = await preCipher(message.payload, this.sigPrivKey); const preparedPayload = await preCipher(message.payload, this.sigPrivKey);
@ -121,7 +123,7 @@ export function createEncoder({
} }
class Decoder extends DecoderV0 implements IDecoder<DecodedMessage> { class Decoder extends DecoderV0 implements IDecoder<DecodedMessage> {
constructor( public constructor(
pubsubTopic: PubsubTopic, pubsubTopic: PubsubTopic,
contentTopic: string, contentTopic: string,
private privateKey: Uint8Array private privateKey: Uint8Array
@ -129,7 +131,7 @@ class Decoder extends DecoderV0 implements IDecoder<DecodedMessage> {
super(pubsubTopic, contentTopic); super(pubsubTopic, contentTopic);
} }
async fromProtoObj( public async fromProtoObj(
pubsubTopic: string, pubsubTopic: string,
protoMessage: IProtoMessage protoMessage: IProtoMessage
): Promise<DecodedMessage | undefined> { ): Promise<DecodedMessage | undefined> {

View File

@ -34,7 +34,7 @@ export {
const log = new Logger("message-encryption:symmetric"); const log = new Logger("message-encryption:symmetric");
class Encoder implements IEncoder { class Encoder implements IEncoder {
constructor( public constructor(
public pubsubTopic: PubsubTopic, public pubsubTopic: PubsubTopic,
public contentTopic: string, public contentTopic: string,
private symKey: Uint8Array, private symKey: Uint8Array,
@ -47,14 +47,16 @@ class Encoder implements IEncoder {
} }
} }
async toWire(message: IMessage): Promise<Uint8Array | undefined> { public async toWire(message: IMessage): Promise<Uint8Array | undefined> {
const protoMessage = await this.toProtoObj(message); const protoMessage = await this.toProtoObj(message);
if (!protoMessage) return; if (!protoMessage) return;
return WakuMessage.encode(protoMessage); return WakuMessage.encode(protoMessage);
} }
async toProtoObj(message: IMessage): Promise<IProtoMessage | undefined> { public async toProtoObj(
message: IMessage
): Promise<IProtoMessage | undefined> {
const timestamp = message.timestamp ?? new Date(); const timestamp = message.timestamp ?? new Date();
const preparedPayload = await preCipher(message.payload, this.sigPrivKey); const preparedPayload = await preCipher(message.payload, this.sigPrivKey);
@ -118,7 +120,7 @@ export function createEncoder({
} }
class Decoder extends DecoderV0 implements IDecoder<DecodedMessage> { class Decoder extends DecoderV0 implements IDecoder<DecodedMessage> {
constructor( public constructor(
pubsubTopic: PubsubTopic, pubsubTopic: PubsubTopic,
contentTopic: string, contentTopic: string,
private symKey: Uint8Array private symKey: Uint8Array
@ -126,7 +128,7 @@ class Decoder extends DecoderV0 implements IDecoder<DecodedMessage> {
super(pubsubTopic, contentTopic); super(pubsubTopic, contentTopic);
} }
async fromProtoObj( public async fromProtoObj(
pubsubTopic: string, pubsubTopic: string,
protoMessage: IProtoMessage protoMessage: IProtoMessage
): Promise<DecodedMessage | undefined> { ): Promise<DecodedMessage | undefined> {

View File

@ -59,7 +59,7 @@ class Relay implements IRelay {
*/ */
private observers: Map<PubsubTopic, Map<ContentTopic, Set<unknown>>>; private observers: Map<PubsubTopic, Map<ContentTopic, Set<unknown>>>;
constructor(libp2p: Libp2p, pubsubTopics: PubsubTopic[]) { public constructor(libp2p: Libp2p, pubsubTopics: PubsubTopic[]) {
if (!this.isRelayPubsub(libp2p.services.pubsub)) { if (!this.isRelayPubsub(libp2p.services.pubsub)) {
throw Error( throw Error(
`Failed to initialize Relay. libp2p.pubsub does not support ${Relay.multicodec}` `Failed to initialize Relay. libp2p.pubsub does not support ${Relay.multicodec}`

View File

@ -13,21 +13,23 @@ export class TopicOnlyMessage implements IDecodedMessage {
public meta: undefined; public meta: undefined;
public ephemeral: undefined; public ephemeral: undefined;
constructor( public constructor(
public pubsubTopic: string, public pubsubTopic: string,
private proto: ProtoTopicOnlyMessage private proto: ProtoTopicOnlyMessage
) {} ) {}
get contentTopic(): string { public get contentTopic(): string {
return this.proto.contentTopic; return this.proto.contentTopic;
} }
} }
export class TopicOnlyDecoder implements IDecoder<TopicOnlyMessage> { export class TopicOnlyDecoder implements IDecoder<TopicOnlyMessage> {
pubsubTopic = DefaultPubsubTopic; public pubsubTopic = DefaultPubsubTopic;
public contentTopic = ""; public contentTopic = "";
fromWireToProtoObj(bytes: Uint8Array): Promise<IProtoMessage | undefined> { public fromWireToProtoObj(
bytes: Uint8Array
): Promise<IProtoMessage | undefined> {
const protoMessage = ProtoTopicOnlyMessage.decode(bytes); const protoMessage = ProtoTopicOnlyMessage.decode(bytes);
return Promise.resolve({ return Promise.resolve({
contentTopic: protoMessage.contentTopic, contentTopic: protoMessage.contentTopic,
@ -40,7 +42,7 @@ export class TopicOnlyDecoder implements IDecoder<TopicOnlyMessage> {
}); });
} }
async fromProtoObj( public async fromProtoObj(
pubsubTopic: string, pubsubTopic: string,
proto: IProtoMessage proto: IProtoMessage
): Promise<TopicOnlyMessage | undefined> { ): Promise<TopicOnlyMessage | undefined> {

View File

@ -19,14 +19,14 @@ export class BaseProtocolSDK implements IBaseProtocolSDK {
private maintainPeersIntervalId: ReturnType< private maintainPeersIntervalId: ReturnType<
typeof window.setInterval typeof window.setInterval
> | null = null; > | null = null;
log: Logger; private log: Logger;
private maintainPeersLock = false; private maintainPeersLock = false;
private readonly renewPeersLocker = new RenewPeerLocker( private readonly renewPeersLocker = new RenewPeerLocker(
RENEW_TIME_LOCK_DURATION RENEW_TIME_LOCK_DURATION
); );
constructor( public constructor(
protected core: BaseProtocol, protected core: BaseProtocol,
private connectionManager: ConnectionManager, private connectionManager: ConnectionManager,
options: Options options: Options
@ -39,7 +39,7 @@ export class BaseProtocolSDK implements IBaseProtocolSDK {
void this.startMaintainPeersInterval(maintainPeersInterval); void this.startMaintainPeersInterval(maintainPeersInterval);
} }
get connectedPeers(): Peer[] { public get connectedPeers(): Peer[] {
return this.peers; return this.peers;
} }
@ -237,7 +237,7 @@ export class BaseProtocolSDK implements IBaseProtocolSDK {
class RenewPeerLocker { class RenewPeerLocker {
private readonly peers: Map<string, number> = new Map(); private readonly peers: Map<string, number> = new Map();
constructor(private lockDuration: number) {} public constructor(private lockDuration: number) {}
public lock(id: PeerId): void { public lock(id: PeerId): void {
this.peers.set(id.toString(), Date.now()); this.peers.set(id.toString(), Date.now());

View File

@ -57,8 +57,7 @@ const DEFAULT_SUBSCRIBE_OPTIONS = {
keepAlive: DEFAULT_KEEP_ALIVE keepAlive: DEFAULT_KEEP_ALIVE
}; };
export class SubscriptionManager implements ISubscriptionSDK { export class SubscriptionManager implements ISubscriptionSDK {
private readonly pubsubTopic: PubsubTopic; private readonly receivedMessagesHashStr: string[] = [];
readonly receivedMessagesHashStr: string[] = [];
private keepAliveTimer: number | null = null; private keepAliveTimer: number | null = null;
private readonly receivedMessagesHashes: ReceivedMessageHashes; private readonly receivedMessagesHashes: ReceivedMessageHashes;
private peerFailures: Map<string, number> = new Map(); private peerFailures: Map<string, number> = new Map();
@ -71,8 +70,8 @@ export class SubscriptionManager implements ISubscriptionSDK {
SubscriptionCallback<IDecodedMessage> SubscriptionCallback<IDecodedMessage>
>; >;
constructor( public constructor(
pubsubTopic: PubsubTopic, private readonly pubsubTopic: PubsubTopic,
private protocol: FilterCore, private protocol: FilterCore,
private getPeers: () => Peer[], private getPeers: () => Peer[],
private readonly renewPeer: (peerToDisconnect: PeerId) => Promise<Peer> private readonly renewPeer: (peerToDisconnect: PeerId) => Promise<Peer>
@ -89,7 +88,7 @@ export class SubscriptionManager implements ISubscriptionSDK {
allPeerIdStr.forEach((peerId) => this.missedMessagesByPeer.set(peerId, 0)); allPeerIdStr.forEach((peerId) => this.missedMessagesByPeer.set(peerId, 0));
} }
get messageHashes(): string[] { public get messageHashes(): string[] {
return [...this.receivedMessagesHashes.all]; return [...this.receivedMessagesHashes.all];
} }
@ -249,9 +248,9 @@ export class SubscriptionManager implements ISubscriptionSDK {
} }
} }
async processIncomingMessage( public async processIncomingMessage(
message: WakuMessage, message: WakuMessage,
peerIdStr: string peerIdStr: PeerIdStr
): Promise<void> { ): Promise<void> {
const hashedMessageStr = messageHashStr( const hashedMessageStr = messageHashStr(
this.pubsubTopic, this.pubsubTopic,
@ -419,7 +418,7 @@ class FilterSDK extends BaseProtocolSDK implements IFilterSDK {
private activeSubscriptions = new Map<string, SubscriptionManager>(); private activeSubscriptions = new Map<string, SubscriptionManager>();
constructor( public constructor(
connectionManager: ConnectionManager, connectionManager: ConnectionManager,
libp2p: Libp2p, libp2p: Libp2p,
options?: ProtocolCreateOptions options?: ProtocolCreateOptions
@ -470,7 +469,7 @@ class FilterSDK extends BaseProtocolSDK implements IFilterSDK {
* @param pubsubTopicShardInfo The pubsub topic to subscribe to. * @param pubsubTopicShardInfo The pubsub topic to subscribe to.
* @returns The subscription object. * @returns The subscription object.
*/ */
async createSubscription( public async createSubscription(
pubsubTopicShardInfo: ShardingParams | PubsubTopic, pubsubTopicShardInfo: ShardingParams | PubsubTopic,
options?: ProtocolUseOptions options?: ProtocolUseOptions
): Promise<CreateSubscriptionResult> { ): Promise<CreateSubscriptionResult> {
@ -533,7 +532,7 @@ class FilterSDK extends BaseProtocolSDK implements IFilterSDK {
* This method should not be used directly. * This method should not be used directly.
* Instead, use `createSubscription` to create a new subscription. * Instead, use `createSubscription` to create a new subscription.
*/ */
async subscribe<T extends IDecodedMessage>( public async subscribe<T extends IDecodedMessage>(
decoders: IDecoder<T> | IDecoder<T>[], decoders: IDecoder<T> | IDecoder<T>[],
callback: Callback<T>, callback: Callback<T>,
options: SubscribeOptions = DEFAULT_SUBSCRIBE_OPTIONS options: SubscribeOptions = DEFAULT_SUBSCRIBE_OPTIONS

View File

@ -20,7 +20,7 @@ const log = new Logger("sdk:light-push");
class LightPushSDK extends BaseProtocolSDK implements ILightPushSDK { class LightPushSDK extends BaseProtocolSDK implements ILightPushSDK {
public readonly protocol: LightPushCore; public readonly protocol: LightPushCore;
constructor( public constructor(
connectionManager: ConnectionManager, connectionManager: ConnectionManager,
libp2p: Libp2p, libp2p: Libp2p,
options?: ProtocolCreateOptions options?: ProtocolCreateOptions
@ -32,7 +32,7 @@ class LightPushSDK extends BaseProtocolSDK implements ILightPushSDK {
this.protocol = this.core as LightPushCore; this.protocol = this.core as LightPushCore;
} }
async send( public async send(
encoder: IEncoder, encoder: IEncoder,
message: IMessage, message: IMessage,
_options?: ProtocolUseOptions _options?: ProtocolUseOptions

View File

@ -25,7 +25,7 @@ const log = new Logger("waku:store:protocol");
export class StoreSDK extends BaseProtocolSDK implements IStoreSDK { export class StoreSDK extends BaseProtocolSDK implements IStoreSDK {
public readonly protocol: StoreCore; public readonly protocol: StoreCore;
constructor( public constructor(
connectionManager: ConnectionManager, connectionManager: ConnectionManager,
libp2p: Libp2p, libp2p: Libp2p,
options?: ProtocolCreateOptions options?: ProtocolCreateOptions
@ -58,7 +58,7 @@ export class StoreSDK extends BaseProtocolSDK implements IStoreSDK {
* @throws If no decoders are provided. * @throws If no decoders are provided.
* @throws If no decoders are found for the provided pubsub topic. * @throws If no decoders are found for the provided pubsub topic.
*/ */
async *queryGenerator<T extends IDecodedMessage>( public async *queryGenerator<T extends IDecodedMessage>(
decoders: IDecoder<T>[], decoders: IDecoder<T>[],
options?: waku_store.QueryOptions options?: waku_store.QueryOptions
): AsyncGenerator<Promise<T | undefined>[]> { ): AsyncGenerator<Promise<T | undefined>[]> {
@ -108,7 +108,7 @@ export class StoreSDK extends BaseProtocolSDK implements IStoreSDK {
* or if an error is encountered when processing the reply, * or if an error is encountered when processing the reply,
* or if two decoders with the same content topic are passed. * or if two decoders with the same content topic are passed.
*/ */
async queryWithOrderedCallback<T extends IDecodedMessage>( public async queryWithOrderedCallback<T extends IDecodedMessage>(
decoders: IDecoder<T>[], decoders: IDecoder<T>[],
callback: (message: T) => Promise<void | boolean> | boolean | void, callback: (message: T) => Promise<void | boolean> | boolean | void,
options?: waku_store.QueryOptions options?: waku_store.QueryOptions
@ -135,7 +135,7 @@ export class StoreSDK extends BaseProtocolSDK implements IStoreSDK {
* or if an error is encountered when processing the reply, * or if an error is encountered when processing the reply,
* or if two decoders with the same content topic are passed. * or if two decoders with the same content topic are passed.
*/ */
async queryWithPromiseCallback<T extends IDecodedMessage>( public async queryWithPromiseCallback<T extends IDecodedMessage>(
decoders: IDecoder<T>[], decoders: IDecoder<T>[],
callback: ( callback: (
message: Promise<T | undefined> message: Promise<T | undefined>
@ -154,7 +154,7 @@ export class StoreSDK extends BaseProtocolSDK implements IStoreSDK {
} }
} }
createCursor(message: IDecodedMessage): Cursor { public createCursor(message: IDecodedMessage): Cursor {
if ( if (
!message || !message ||
!message.timestamp || !message.timestamp ||

View File

@ -73,7 +73,7 @@ export class WakuNode implements Waku {
public connectionManager: ConnectionManager; public connectionManager: ConnectionManager;
public readonly pubsubTopics: PubsubTopic[]; public readonly pubsubTopics: PubsubTopic[];
constructor( public constructor(
options: WakuOptions, options: WakuOptions,
libp2p: Libp2p, libp2p: Libp2p,
protocolsEnabled: ProtocolsEnabled protocolsEnabled: ProtocolsEnabled
@ -143,7 +143,7 @@ export class WakuNode implements Waku {
* @param peer The peer to dial * @param peer The peer to dial
* @param protocols Waku protocols we expect from the peer; Defaults to mounted protocols * @param protocols Waku protocols we expect from the peer; Defaults to mounted protocols
*/ */
async dial( public async dial(
peer: PeerId | MultiaddrInput, peer: PeerId | MultiaddrInput,
protocols?: Protocols[] protocols?: Protocols[]
): Promise<Stream> { ): Promise<Stream> {
@ -202,16 +202,16 @@ export class WakuNode implements Waku {
return this.libp2p.dialProtocol(peerId, codecs); return this.libp2p.dialProtocol(peerId, codecs);
} }
async start(): Promise<void> { public async start(): Promise<void> {
await this.libp2p.start(); await this.libp2p.start();
} }
async stop(): Promise<void> { public async stop(): Promise<void> {
this.connectionManager.stop(); this.connectionManager.stop();
await this.libp2p.stop(); await this.libp2p.stop();
} }
async subscribeToContentTopic( public async subscribeToContentTopic(
contentTopic: string, contentTopic: string,
peer: Multiaddr, peer: Multiaddr,
callback: Callback<DecodedMessage> callback: Callback<DecodedMessage>
@ -224,11 +224,11 @@ export class WakuNode implements Waku {
).subscription; ).subscription;
} }
isStarted(): boolean { public isStarted(): boolean {
return this.libp2p.status == "started"; return this.libp2p.status == "started";
} }
isConnected(): boolean { public isConnected(): boolean {
return this.connectionManager.isConnected(); return this.connectionManager.isConnected();
} }
@ -237,7 +237,7 @@ export class WakuNode implements Waku {
* *
* @throws if libp2p is not listening on localhost. * @throws if libp2p is not listening on localhost.
*/ */
getLocalMultiaddrWithID(): string { public getLocalMultiaddrWithID(): string {
const localMultiaddr = this.libp2p const localMultiaddr = this.libp2p
.getMultiaddrs() .getMultiaddrs()
.find((addr) => addr.toString().match(/127\.0\.0\.1/)); .find((addr) => addr.toString().match(/127\.0\.0\.1/));

View File

@ -79,14 +79,14 @@ export default class Dockerode {
return newIp; return newIp;
} }
get container(): Docker.Container | undefined { public get container(): Docker.Container | undefined {
if (!this.containerId) { if (!this.containerId) {
return undefined; return undefined;
} }
return this.docker.getContainer(this.containerId); return this.docker.getContainer(this.containerId);
} }
async startContainer( public async startContainer(
ports: Ports, ports: Ports,
args: Args, args: Args,
logPath: string, logPath: string,
@ -168,7 +168,7 @@ export default class Dockerode {
return container; return container;
} }
async stop(): Promise<void> { public async stop(): Promise<void> {
if (!this.container) { if (!this.container) {
log.error("ContainerId not set"); log.error("ContainerId not set");
} else { } else {

View File

@ -24,7 +24,7 @@ const log = new Logger("test:message-collector");
* that allows for the creation & handling of multiple ServiceNodes * that allows for the creation & handling of multiple ServiceNodes
*/ */
export class ServiceNodesFleet { export class ServiceNodesFleet {
static async createAndRun( public static async createAndRun(
mochaContext: Mocha.Context, mochaContext: Mocha.Context,
pubsubTopics: PubsubTopic[], pubsubTopics: PubsubTopic[],
nodesToCreate: number = 3, nodesToCreate: number = 3,
@ -61,7 +61,7 @@ export class ServiceNodesFleet {
* Convert a [[WakuMessage]] to a [[WakuRelayMessage]]. The latter is used * Convert a [[WakuMessage]] to a [[WakuRelayMessage]]. The latter is used
* by the nwaku JSON-RPC API. * by the nwaku JSON-RPC API.
*/ */
static toMessageRpcQuery(message: { public static toMessageRpcQuery(message: {
payload: Uint8Array; payload: Uint8Array;
contentTopic: string; contentTopic: string;
timestamp?: Date; timestamp?: Date;
@ -86,7 +86,7 @@ export class ServiceNodesFleet {
); );
} }
get type(): "go-waku" | "nwaku" { public get type(): "go-waku" | "nwaku" {
const nodeType = new Set( const nodeType = new Set(
this.nodes.map((node) => { this.nodes.map((node) => {
return node.type; return node.type;
@ -98,12 +98,12 @@ export class ServiceNodesFleet {
return nodeType.values().next().value; return nodeType.values().next().value;
} }
async start(): Promise<void> { public async start(): Promise<void> {
const startPromises = this.nodes.map((node) => node.start()); const startPromises = this.nodes.map((node) => node.start());
await Promise.all(startPromises); await Promise.all(startPromises);
} }
async sendRelayMessage( public async sendRelayMessage(
message: MessageRpcQuery, message: MessageRpcQuery,
pubsubTopic: string = DefaultPubsubTopic pubsubTopic: string = DefaultPubsubTopic
): Promise<boolean> { ): Promise<boolean> {
@ -114,7 +114,7 @@ export class ServiceNodesFleet {
return relayMessages.every((message) => message); return relayMessages.every((message) => message);
} }
async confirmMessageLength(numMessages: number): Promise<void> { public async confirmMessageLength(numMessages: number): Promise<void> {
if (this.strictChecking) { if (this.strictChecking) {
await Promise.all( await Promise.all(
this.nodes.map(async (node) => this.nodes.map(async (node) =>
@ -138,9 +138,9 @@ export class ServiceNodesFleet {
} }
class MultipleNodesMessageCollector { class MultipleNodesMessageCollector {
callback: (msg: DecodedMessage) => void = () => {}; public callback: (msg: DecodedMessage) => void = () => {};
messageList: Array<DecodedMessage> = []; protected messageList: Array<DecodedMessage> = [];
constructor( public constructor(
private messageCollectors: MessageCollector[], private messageCollectors: MessageCollector[],
private relayNodes?: ServiceNode[], private relayNodes?: ServiceNode[],
private strictChecking: boolean = false private strictChecking: boolean = false
@ -151,7 +151,7 @@ class MultipleNodesMessageCollector {
}; };
} }
get count(): number { public get count(): number {
return this.messageList.length; return this.messageList.length;
} }
@ -167,7 +167,7 @@ class MultipleNodesMessageCollector {
} }
} }
getMessage(index: number): MessageRpcResponse | DecodedMessage { public getMessage(index: number): MessageRpcResponse | DecodedMessage {
return this.messageList[index]; return this.messageList[index];
} }
@ -175,7 +175,7 @@ class MultipleNodesMessageCollector {
* Verifies a received message against expected values on all nodes. * Verifies a received message against expected values on all nodes.
* Returns true if any node's collector verifies the message successfully. * Returns true if any node's collector verifies the message successfully.
*/ */
verifyReceivedMessage( public verifyReceivedMessage(
index: number, index: number,
options: { options: {
expectedMessageText: string | Uint8Array | undefined; expectedMessageText: string | Uint8Array | undefined;
@ -212,7 +212,7 @@ class MultipleNodesMessageCollector {
/** /**
* Waits for a total number of messages across all nodes. * Waits for a total number of messages across all nodes.
*/ */
async waitForMessages( public async waitForMessages(
numMessages: number, numMessages: number,
options?: { options?: {
pubsubTopic?: string; pubsubTopic?: string;

View File

@ -19,10 +19,10 @@ const log = new Logger("test:message-collector");
* and offers a way to wait for incoming messages. * and offers a way to wait for incoming messages.
*/ */
export class MessageCollector { export class MessageCollector {
list: Array<MessageRpcResponse | DecodedMessage> = []; public list: Array<MessageRpcResponse | DecodedMessage> = [];
callback: (msg: DecodedMessage) => void = () => {}; public callback: (msg: DecodedMessage) => void = () => {};
constructor(private nwaku?: ServiceNode) { public constructor(private nwaku?: ServiceNode) {
if (!this.nwaku) { if (!this.nwaku) {
this.callback = (msg: DecodedMessage): void => { this.callback = (msg: DecodedMessage): void => {
log.info("Got a message"); log.info("Got a message");
@ -31,15 +31,15 @@ export class MessageCollector {
} }
} }
get count(): number { public get count(): number {
return this.list.length; return this.list.length;
} }
getMessage(index: number): MessageRpcResponse | DecodedMessage { public getMessage(index: number): MessageRpcResponse | DecodedMessage {
return this.list[index]; return this.list[index];
} }
hasMessage(topic: string, text: string): boolean { public hasMessage(topic: string, text: string): boolean {
return this.list.some((message) => { return this.list.some((message) => {
if (message.contentTopic !== topic) { if (message.contentTopic !== topic) {
return false; return false;
@ -55,7 +55,7 @@ export class MessageCollector {
} }
// Type guard to determine if a message is of type MessageRpcResponse // Type guard to determine if a message is of type MessageRpcResponse
isMessageRpcResponse( public isMessageRpcResponse(
message: MessageRpcResponse | DecodedMessage message: MessageRpcResponse | DecodedMessage
): message is MessageRpcResponse { ): message is MessageRpcResponse {
return ( return (
@ -64,7 +64,7 @@ export class MessageCollector {
); );
} }
async waitForMessages( public async waitForMessages(
numMessages: number, numMessages: number,
options?: { options?: {
pubsubTopic?: string; pubsubTopic?: string;
@ -106,7 +106,7 @@ export class MessageCollector {
} }
} }
async waitForMessagesAutosharding( public async waitForMessagesAutosharding(
numMessages: number, numMessages: number,
options?: { options?: {
contentTopic: string; contentTopic: string;
@ -150,7 +150,7 @@ export class MessageCollector {
} }
// Verifies a received message against expected values. // Verifies a received message against expected values.
verifyReceivedMessage( public verifyReceivedMessage(
index: number, index: number,
options: { options: {
expectedMessageText: string | Uint8Array | undefined; expectedMessageText: string | Uint8Array | undefined;

View File

@ -54,7 +54,7 @@ export class ServiceNode {
* Convert a [[WakuMessage]] to a [[WakuRelayMessage]]. The latter is used * Convert a [[WakuMessage]] to a [[WakuRelayMessage]]. The latter is used
* by the nwaku JSON-RPC API. * by the nwaku JSON-RPC API.
*/ */
static toMessageRpcQuery(message: { public static toMessageRpcQuery(message: {
payload: Uint8Array; payload: Uint8Array;
contentTopic: string; contentTopic: string;
timestamp?: Date; timestamp?: Date;
@ -75,23 +75,23 @@ export class ServiceNode {
}; };
} }
constructor(logName: string) { public constructor(logName: string) {
this.logPath = `${LOG_DIR}/wakunode_${logName}.log`; this.logPath = `${LOG_DIR}/wakunode_${logName}.log`;
} }
get type(): "go-waku" | "nwaku" { public get type(): "go-waku" | "nwaku" {
return isGoWaku ? "go-waku" : "nwaku"; return isGoWaku ? "go-waku" : "nwaku";
} }
get nodeType(): "go-waku" | "nwaku" { public get nodeType(): "go-waku" | "nwaku" {
return isGoWaku ? "go-waku" : "nwaku"; return isGoWaku ? "go-waku" : "nwaku";
} }
get containerName(): string | undefined { public get containerName(): string | undefined {
return this.docker?.container?.id; return this.docker?.container?.id;
} }
async start( public async start(
args: Args = {}, args: Args = {},
options: { options: {
retries?: number; retries?: number;
@ -200,7 +200,7 @@ export class ServiceNode {
delete this.docker; delete this.docker;
} }
async waitForLog(msg: string, timeout: number): Promise<void> { public async waitForLog(msg: string, timeout: number): Promise<void> {
return waitForLine(this.logPath, msg, timeout); return waitForLine(this.logPath, msg, timeout);
} }
@ -208,7 +208,7 @@ export class ServiceNode {
* Calls nwaku REST API "/admin/v1/peers" to check for known peers * Calls nwaku REST API "/admin/v1/peers" to check for known peers
* @throws * @throws
*/ */
async peers(): Promise<string[]> { public async peers(): Promise<string[]> {
this.checkProcess(); this.checkProcess();
return this.restCall<string[]>( return this.restCall<string[]>(
@ -222,7 +222,7 @@ export class ServiceNode {
); );
} }
async info(): Promise<RpcInfoResponse> { public async info(): Promise<RpcInfoResponse> {
this.checkProcess(); this.checkProcess();
return this.restCall<RpcInfoResponse>( return this.restCall<RpcInfoResponse>(
@ -233,7 +233,7 @@ export class ServiceNode {
); );
} }
async healthy(): Promise<boolean> { public async healthy(): Promise<boolean> {
this.checkProcess(); this.checkProcess();
return this.restCall<boolean>( return this.restCall<boolean>(
@ -244,7 +244,7 @@ export class ServiceNode {
); );
} }
async ensureSubscriptions( public async ensureSubscriptions(
pubsubTopics: string[] = [DefaultPubsubTopic] pubsubTopics: string[] = [DefaultPubsubTopic]
): Promise<boolean> { ): Promise<boolean> {
return this.restCall<boolean>( return this.restCall<boolean>(
@ -255,7 +255,7 @@ export class ServiceNode {
); );
} }
async messages(pubsubTopic?: string): Promise<MessageRpcResponse[]> { public async messages(pubsubTopic?: string): Promise<MessageRpcResponse[]> {
return this.restCall<MessageRpcResponse[]>( return this.restCall<MessageRpcResponse[]>(
`/relay/v1/messages/${encodeURIComponent(pubsubTopic || this?.args?.pubsubTopic?.[0] || DefaultPubsubTopic)}`, `/relay/v1/messages/${encodeURIComponent(pubsubTopic || this?.args?.pubsubTopic?.[0] || DefaultPubsubTopic)}`,
"GET", "GET",
@ -267,7 +267,7 @@ export class ServiceNode {
); );
} }
async ensureSubscriptionsAutosharding( public async ensureSubscriptionsAutosharding(
contentTopics: string[] contentTopics: string[]
): Promise<boolean> { ): Promise<boolean> {
this.checkProcess(); this.checkProcess();
@ -280,7 +280,7 @@ export class ServiceNode {
); );
} }
async sendMessage( public async sendMessage(
message: MessageRpcQuery, message: MessageRpcQuery,
pubsubTopic?: string pubsubTopic?: string
): Promise<boolean> { ): Promise<boolean> {
@ -298,7 +298,9 @@ export class ServiceNode {
); );
} }
async sendMessageAutosharding(message: MessageRpcQuery): Promise<boolean> { public async sendMessageAutosharding(
message: MessageRpcQuery
): Promise<boolean> {
this.checkProcess(); this.checkProcess();
if (typeof message.timestamp === "undefined") { if (typeof message.timestamp === "undefined") {
@ -313,7 +315,7 @@ export class ServiceNode {
); );
} }
async messagesAutosharding( public async messagesAutosharding(
contentTopic: string contentTopic: string
): Promise<MessageRpcResponse[]> { ): Promise<MessageRpcResponse[]> {
this.checkProcess(); this.checkProcess();
@ -329,13 +331,13 @@ export class ServiceNode {
); );
} }
async getPeerId(): Promise<PeerId> { public async getPeerId(): Promise<PeerId> {
if (this.peerId) return this.peerId; if (this.peerId) return this.peerId;
this.peerId = await this._getPeerId(); this.peerId = await this._getPeerId();
return this.peerId; return this.peerId;
} }
async getMultiaddrWithId(): Promise<Multiaddr> { public async getMultiaddrWithId(): Promise<Multiaddr> {
if (this.multiaddrWithId) return this.multiaddrWithId; if (this.multiaddrWithId) return this.multiaddrWithId;
const peerId = await this.getPeerId(); const peerId = await this.getPeerId();
@ -362,15 +364,15 @@ export class ServiceNode {
return this.peerId; return this.peerId;
} }
get httpUrl(): string { public get httpUrl(): string {
return `http://127.0.0.1:${this.restPort}`; return `http://127.0.0.1:${this.restPort}`;
} }
get pubsubTopics(): string[] { public get pubsubTopics(): string[] {
return this.args?.pubsubTopic ?? []; return this.args?.pubsubTopic ?? [];
} }
async restCall<T>( public async restCall<T>(
endpoint: string, endpoint: string,
method: "GET" | "POST", method: "GET" | "POST",
body: any = null, body: any = null,

View File

@ -7,29 +7,29 @@ export class Logger {
private _warn: Debugger; private _warn: Debugger;
private _error: Debugger; private _error: Debugger;
static createDebugNamespace(level: string, prefix?: string): string { private static createDebugNamespace(level: string, prefix?: string): string {
return prefix ? `${APP_NAME}:${level}:${prefix}` : `${APP_NAME}:${level}`; return prefix ? `${APP_NAME}:${level}:${prefix}` : `${APP_NAME}:${level}`;
} }
constructor(prefix?: string) { public constructor(prefix?: string) {
this._info = debug(Logger.createDebugNamespace("info", prefix)); this._info = debug(Logger.createDebugNamespace("info", prefix));
this._warn = debug(Logger.createDebugNamespace("warn", prefix)); this._warn = debug(Logger.createDebugNamespace("warn", prefix));
this._error = debug(Logger.createDebugNamespace("error", prefix)); this._error = debug(Logger.createDebugNamespace("error", prefix));
} }
get info(): Debugger { public get info(): Debugger {
return this._info; return this._info;
} }
get warn(): Debugger { public get warn(): Debugger {
return this._warn; return this._warn;
} }
get error(): Debugger { public get error(): Debugger {
return this._error; return this._error;
} }
log(level: "info" | "warn" | "error", ...args: unknown[]): void { public log(level: "info" | "warn" | "error", ...args: unknown[]): void {
const logger = this[level] as (...args: unknown[]) => void; const logger = this[level] as (...args: unknown[]) => void;
logger(...args); logger(...args);
} }