UNPKG

@node-lightning/graph

Version:
116 lines 4.88 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GraphManager = void 0; const wire_1 = require("@node-lightning/wire"); const events_1 = require("events"); const channel_from_message_1 = require("./deserialize/channel-from-message"); const channel_settings_from_message_1 = require("./deserialize/channel-settings-from-message"); const graph_1 = require("./graph"); const graph_error_1 = require("./graph-error"); const node_1 = require("./node"); /** * GraphManager is a facade around a Graph object. It converts in-bound * gossip messages from the wire into a graph representation. Channels * can also be removed by monitoring the block chain via a chainmon object. */ class GraphManager extends events_1.EventEmitter { constructor(gossipManager, graph = new graph_1.Graph()) { super(); this.graph = graph; this.gossipEmitter = gossipManager; this.gossipEmitter.on("message", this._onMessage.bind(this)); } /** * Closes channel via the outpoint * @param outpoint */ removeChannel(outpoint) { const outpointStr = outpoint.toString(); for (const channel of this.graph.channels.values()) { if (outpointStr === channel?.channelPoint?.toString()) { this.graph.removeChannel(channel); this.emit("channel_closed", channel); return; } } } _onMessage(msg) { // channel_announcement messages are processed by: // First ensuring that we don't already have a duplicate channel. // We then check to see if we need to insert node // references. Inserting temporary node's is required because we // may receieve a channel_announcement without ever receiving // node_announcement messages. if (isChannelAnnouncment(msg)) { const channel = channel_from_message_1.channelFromMessage(msg); // abort processing if the channel already exists if (this.graph.getChannel(msg.shortChannelId)) { return; } // construct node1 if required if (!this.graph.getNode(msg.nodeId1)) { const node1 = new node_1.Node(); node1.nodeId = msg.nodeId1; this.graph.addNode(node1); this.emit("node", node1); } // construct node2 if required if (!this.graph.getNode(msg.nodeId2)) { const node2 = new node_1.Node(); node2.nodeId = msg.nodeId2; this.graph.addNode(node2); this.emit("node", node2); } // finally attach the channel this.graph.addChannel(channel); this.emit("channel", channel); return; } // channel_update messages are processed by: // * looking for the existing channel, if it doesn't then an error is thrown. // * updating the existing channel // The GossipFilter in Wire should ensure that channel_announcement messages // are always transmitted prior to channel_update messages being announced. if (isChannelUpdate(msg)) { // first validate we have a channel const channel = this.graph.getChannel(msg.shortChannelId); if (!channel) { this.emit("error", new graph_error_1.ChannelNotFoundError(msg.shortChannelId)); return; } // construct the settings and update the channel const settings = channel_settings_from_message_1.channelSettingsFromMessage(msg); channel.updateSettings(settings); this.emit("channel_update", channel, settings); return; } // node_announcement messages are processed by: // * finding or creating the node (if it doesn't exist) // * updating the node with values from the announcement if (isNodeAnnouncement(msg)) { let node = this.graph.getNode(msg.nodeId); if (!node) { node = new node_1.Node(); node.nodeId = msg.nodeId; this.graph.addNode(node); } node.features = msg.features; node.lastUpdate = msg.timestamp; node.alias = msg.alias; node.rgbColor = msg.rgbColor; node.addresses = msg.addresses; this.emit("node", node); } } } exports.GraphManager = GraphManager; function isChannelAnnouncment(msg) { return msg.type === wire_1.MessageType.ChannelAnnouncement; } function isChannelUpdate(msg) { return msg.type === wire_1.MessageType.ChannelUpdate; } function isNodeAnnouncement(msg) { return msg.type === wire_1.MessageType.NodeAnnouncement; } //# sourceMappingURL=graph-manager.js.map