UNPKG

xud

Version:
222 lines 11.1 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ClientStatus = exports.PaymentState = void 0; const events_1 = require("events"); const utils_1 = require("../utils/utils"); var ClientStatus; (function (ClientStatus) { /** The starting status before a client has initialized. */ ClientStatus[ClientStatus["NotInitialized"] = 0] = "NotInitialized"; /** The client has been initialized but has not attempted to connect to the server yet. */ ClientStatus[ClientStatus["Initialized"] = 1] = "Initialized"; /** The client is permanently disabled. */ ClientStatus[ClientStatus["Disabled"] = 2] = "Disabled"; /** The server cannot be reached or is not responding properly. */ ClientStatus[ClientStatus["Disconnected"] = 3] = "Disconnected"; /** The server is reachable and operational. */ ClientStatus[ClientStatus["ConnectionVerified"] = 4] = "ConnectionVerified"; /** The server is reachable but is not ready pending completion of blockchain or network sync. */ ClientStatus[ClientStatus["OutOfSync"] = 5] = "OutOfSync"; /** The server is reachable but needs to be unlocked before it accepts calls. */ ClientStatus[ClientStatus["WaitingUnlock"] = 6] = "WaitingUnlock"; /** The server has been unlocked, but its status has not been verified yet. */ ClientStatus[ClientStatus["Unlocked"] = 7] = "Unlocked"; /** The client could not be initialized due to faulty configuration. */ ClientStatus[ClientStatus["Misconfigured"] = 8] = "Misconfigured"; /** The server is reachable but hold invoices are not supported. */ ClientStatus[ClientStatus["NoHoldInvoiceSupport"] = 9] = "NoHoldInvoiceSupport"; })(ClientStatus || (ClientStatus = {})); exports.ClientStatus = ClientStatus; var PaymentState; (function (PaymentState) { PaymentState[PaymentState["Succeeded"] = 0] = "Succeeded"; PaymentState[PaymentState["Failed"] = 1] = "Failed"; PaymentState[PaymentState["Pending"] = 2] = "Pending"; })(PaymentState = exports.PaymentState || (exports.PaymentState = {})); /** * A base class to represent an external swap client such as lnd or connext. */ let SwapClient = /** @class */ (() => { class SwapClient extends events_1.EventEmitter { constructor(logger, disable) { super(); this.logger = logger; this.disable = disable; this.status = ClientStatus.NotInitialized; this.verifyConnectionWithTimeout = () => { // don't wait longer than the allotted time for the connection to // be verified to prevent initialization from hanging return new Promise((resolve, reject) => { const verifyTimeout = setTimeout(() => { // we could not verify the connection within the allotted time this.logger.info(`could not verify connection within initialization time limit of ${SwapClient.INITIALIZATION_TIME_LIMIT}`); this.setStatus(ClientStatus.Disconnected); resolve(); }, SwapClient.INITIALIZATION_TIME_LIMIT); this.verifyConnection().then(() => { clearTimeout(verifyTimeout); resolve(); }).catch(reject); }); }; this.init = () => __awaiter(this, void 0, void 0, function* () { // up front checks before initializing client if (this.disable) { this.setStatus(ClientStatus.Disabled); return; } if (!this.isNotInitialized() && !this.isMisconfigured()) { // we only initialize from NotInitialized or Misconfigured status this.logger.warn(`can not init in ${this.status} status`); return; } // client specific initialization yield this.initSpecific(); // check to make sure that the client wasn't disabled in the initSpecific routine if (this.isNotInitialized()) { // final steps to complete initialization this.setStatus(ClientStatus.Initialized); this.setTimers(); this.emit('initialized'); yield this.verifyConnectionWithTimeout(); } }); this.setConnected = (newIdentifier, newUris) => __awaiter(this, void 0, void 0, function* () { // we wait briefly to update the capacities for this swap client then proceed to set status to connected yield Promise.race([this.updateCapacity(), utils_1.setTimeoutPromise(SwapClient.CAPACITY_REFRESH_INTERVAL)]); this.setStatus(ClientStatus.ConnectionVerified); this.emit('connectionVerified', { newIdentifier, newUris, }); }); this.setStatus = (newStatus) => { if (this.status === newStatus) { return; } let validStatusTransition; switch (newStatus) { case ClientStatus.Disabled: case ClientStatus.Misconfigured: case ClientStatus.Initialized: // these statuses can only be set on a client that has not been initialized validStatusTransition = this.isNotInitialized(); break; case ClientStatus.Unlocked: // this status can only be set on a client that is waiting unlock validStatusTransition = this.isWaitingUnlock(); break; case ClientStatus.ConnectionVerified: case ClientStatus.Disconnected: case ClientStatus.WaitingUnlock: case ClientStatus.OutOfSync: case ClientStatus.NoHoldInvoiceSupport: // these statuses can only be set on an operational, initialized client validStatusTransition = this.isOperational(); break; case ClientStatus.NotInitialized: // this is the starting status and cannot be reassigned validStatusTransition = false; break; } if (validStatusTransition) { this.logger.info(`new status: ${ClientStatus[newStatus]}`); this.status = newStatus; } else { this.logger.error(`cannot set status to ${ClientStatus[newStatus]} from ${ClientStatus[this.status]}`); } }; this.updateCapacityTimerCallback = () => __awaiter(this, void 0, void 0, function* () { if (this.isConnected()) { yield this.updateCapacity(); } }); this.reconnectionTimerCallback = () => __awaiter(this, void 0, void 0, function* () { if (this.status === ClientStatus.Disconnected || this.status === ClientStatus.OutOfSync || this.status === ClientStatus.WaitingUnlock || this.status === ClientStatus.Unlocked) { try { yield this.verifyConnection(); } catch (err) { this.logger.debug(`reconnectionTimer errored with ${err}`); } } if (this.reconnectionTimer) { this.reconnectionTimer.refresh(); } }); this.setTimers = () => { if (!this.updateCapacityTimer) { this.updateCapacityTimer = setInterval(this.updateCapacityTimerCallback, SwapClient.CAPACITY_REFRESH_INTERVAL); } if (!this.reconnectionTimer) { this.reconnectionTimer = setTimeout(this.reconnectionTimerCallback, SwapClient.RECONNECT_INTERVAL); } }; } isConnected() { return this.status === ClientStatus.ConnectionVerified; } isDisabled() { return this.status === ClientStatus.Disabled; } isMisconfigured() { return this.status === ClientStatus.Misconfigured; } /** * Returns `true` if the client is enabled and configured properly. */ isOperational() { return !this.isDisabled() && !this.isMisconfigured() && !this.isNotInitialized(); } isDisconnected() { return this.status === ClientStatus.Disconnected; } isWaitingUnlock() { return this.status === ClientStatus.WaitingUnlock; } isNotInitialized() { return this.status === ClientStatus.NotInitialized; } isOutOfSync() { return this.status === ClientStatus.OutOfSync; } hasNoInvoiceSupport() { return this.status === ClientStatus.NoHoldInvoiceSupport; } /** Ends all connections, subscriptions, and timers for for this client. */ close() { this.disconnect(); if (this.reconnectionTimer) { clearTimeout(this.reconnectionTimer); this.reconnectionTimer = undefined; } if (this.updateCapacityTimer) { clearInterval(this.updateCapacityTimer); this.updateCapacityTimer = undefined; } this.removeAllListeners(); } } /** Time in milliseconds between attempts to recheck connectivity to the client. */ SwapClient.RECONNECT_INTERVAL = 5000; /** The maximum amount of time we will wait for the connection to be verified during initialization. */ SwapClient.INITIALIZATION_TIME_LIMIT = 5000; /** Time in milliseconds between updating the maximum outbound capacity. */ SwapClient.CAPACITY_REFRESH_INTERVAL = 3000; return SwapClient; })(); exports.default = SwapClient; //# sourceMappingURL=SwapClient.js.map