UNPKG

@waku/discovery

Version:

Contains various discovery mechanisms: DNS Discovery (EIP-1459, Peer Exchange, Local Peer Cache Discovery.

93 lines 3.08 kB
import { StreamManager } from "@waku/core"; import { EnrDecoder } from "@waku/enr"; import { ProtocolError } from "@waku/interfaces"; import { isDefined } from "@waku/utils"; import { Logger } from "@waku/utils"; import all from "it-all"; import * as lp from "it-length-prefixed"; import { pipe } from "it-pipe"; import { Uint8ArrayList } from "uint8arraylist"; import { PeerExchangeRPC } from "./rpc.js"; export const PeerExchangeCodec = "/vac/waku/peer-exchange/2.0.0-alpha1"; const log = new Logger("peer-exchange"); /** * Implementation of the Peer Exchange protocol (https://rfc.vac.dev/spec/34/) */ export class WakuPeerExchange { components; streamManager; /** * @param components - libp2p components */ constructor(components) { this.components = components; this.streamManager = new StreamManager(PeerExchangeCodec, components); } /** * Make a peer exchange query to a peer */ async query(params) { const { numPeers, peerId } = params; const rpcQuery = PeerExchangeRPC.createRequest({ numPeers: BigInt(numPeers) }); const peer = await this.components.peerStore.get(peerId); if (!peer) { return { peerInfos: null, error: ProtocolError.NO_PEER_AVAILABLE }; } let stream; try { stream = await this.streamManager.getStream(peerId); } catch (err) { log.error("Failed to get stream", err); return { peerInfos: null, error: ProtocolError.NO_STREAM_AVAILABLE }; } const res = await pipe([rpcQuery.encode()], lp.encode, stream, lp.decode, async (source) => await all(source)); try { const bytes = new Uint8ArrayList(); res.forEach((chunk) => { bytes.append(chunk); }); const { response } = PeerExchangeRPC.decode(bytes); if (!response) { log.error("PeerExchangeRPC message did not contains a `response` field"); return { peerInfos: null, error: ProtocolError.EMPTY_PAYLOAD }; } const peerInfos = await Promise.all(response.peerInfos .map((peerInfo) => peerInfo.enr) .filter(isDefined) .map(async (enr) => { return { ENR: await EnrDecoder.fromRLP(enr) }; })); return { peerInfos, error: null }; } catch (err) { log.error("Failed to decode push reply", err); return { peerInfos: null, error: ProtocolError.DECODE_FAILED }; } } } /** * * @returns A function that creates a new peer exchange protocol */ export function wakuPeerExchange() { return (components) => new WakuPeerExchange(components); } //# sourceMappingURL=waku_peer_exchange.js.map