From a238420d7f48ff783c13834d9152153c43c73ccb Mon Sep 17 00:00:00 2001 From: nymkappa Date: Wed, 6 Jul 2022 11:58:06 +0200 Subject: [PATCH] Merge Lightning backend into Mempool backend --- backend/mempool-config.sample.json | 9 + backend/package.json | 1 + .../bitcoin/bitcoin-api-abstract-factory.ts | 1 + backend/src/api/bitcoin/bitcoin-api.ts | 14 +- .../src/api/bitcoin/esplora-api.interface.ts | 6 +- backend/src/api/bitcoin/esplora-api.ts | 5 + backend/src/api/database-migration.ts | 87 +- .../src/api/explorer/channels.api.ts | 2 +- .../src/api/explorer/channels.routes.ts | 12 +- .../src/api/explorer/general.routes.ts | 24 +- .../src/api/explorer/nodes.api.ts | 14 - .../src/api/explorer/nodes.routes.ts | 24 +- backend/src/api/explorer/statistics.api.ts | 32 + .../lightning-api-abstract-factory.ts | 0 .../api/lightning/lightning-api-factory.ts | 2 +- .../api/lightning/lightning-api.interface.ts | 0 .../src/api/lightning/lnd/lnd-api.ts | 9 +- backend/src/config.ts | 26 +- backend/src/index.ts | 18 + .../src/tasks/lightning}/node-sync.service.ts | 50 +- .../tasks/lightning}/stats-updater.service.ts | 28 +- frontend/proxy.conf.local.js | 6 +- .../app/lightning/lightning-api.service.ts | 30 +- frontend/src/app/services/api.service.ts | 4 +- lightning-backend/.gitignore | 48 - lightning-backend/mempool-config.sample.json | 38 - lightning-backend/package-lock.json | 3291 ----------------- lightning-backend/package.json | 25 - .../bitcoin/bitcoin-api-abstract-factory.ts | 25 - .../src/api/bitcoin/bitcoin-api-factory.ts | 15 - .../src/api/bitcoin/bitcoin-api.interface.ts | 175 - .../src/api/bitcoin/bitcoin-api.ts | 313 -- .../src/api/bitcoin/bitcoin-client.ts | 12 - .../src/api/bitcoin/esplora-api.interface.ts | 172 - .../src/api/bitcoin/esplora-api.ts | 84 - .../src/api/bitcoin/rpc-api/commands.ts | 92 - .../src/api/bitcoin/rpc-api/index.ts | 61 - .../src/api/bitcoin/rpc-api/jsonrpc.ts | 162 - .../src/api/explorer/statistics.api.ts | 17 - lightning-backend/src/config.ts | 110 - lightning-backend/src/database-migration.ts | 260 -- lightning-backend/src/database.ts | 51 - lightning-backend/src/index.ts | 23 - lightning-backend/src/logger.ts | 145 - lightning-backend/src/server.ts | 40 - lightning-backend/tsconfig.json | 22 - lightning-backend/tslint.json | 137 - 47 files changed, 298 insertions(+), 5424 deletions(-) rename {lightning-backend => backend}/src/api/explorer/channels.api.ts (99%) rename {lightning-backend => backend}/src/api/explorer/channels.routes.ts (85%) rename {lightning-backend => backend}/src/api/explorer/general.routes.ts (58%) rename {lightning-backend => backend}/src/api/explorer/nodes.api.ts (86%) rename {lightning-backend => backend}/src/api/explorer/nodes.routes.ts (65%) create mode 100644 backend/src/api/explorer/statistics.api.ts rename {lightning-backend => backend}/src/api/lightning/lightning-api-abstract-factory.ts (100%) rename {lightning-backend => backend}/src/api/lightning/lightning-api-factory.ts (88%) rename {lightning-backend => backend}/src/api/lightning/lightning-api.interface.ts (100%) rename {lightning-backend => backend}/src/api/lightning/lnd/lnd-api.ts (79%) rename {lightning-backend/src/tasks => backend/src/tasks/lightning}/node-sync.service.ts (92%) rename {lightning-backend/src/tasks => backend/src/tasks/lightning}/stats-updater.service.ts (85%) delete mode 100644 lightning-backend/.gitignore delete mode 100644 lightning-backend/mempool-config.sample.json delete mode 100644 lightning-backend/package-lock.json delete mode 100644 lightning-backend/package.json delete mode 100644 lightning-backend/src/api/bitcoin/bitcoin-api-abstract-factory.ts delete mode 100644 lightning-backend/src/api/bitcoin/bitcoin-api-factory.ts delete mode 100644 lightning-backend/src/api/bitcoin/bitcoin-api.interface.ts delete mode 100644 lightning-backend/src/api/bitcoin/bitcoin-api.ts delete mode 100644 lightning-backend/src/api/bitcoin/bitcoin-client.ts delete mode 100644 lightning-backend/src/api/bitcoin/esplora-api.interface.ts delete mode 100644 lightning-backend/src/api/bitcoin/esplora-api.ts delete mode 100644 lightning-backend/src/api/bitcoin/rpc-api/commands.ts delete mode 100644 lightning-backend/src/api/bitcoin/rpc-api/index.ts delete mode 100644 lightning-backend/src/api/bitcoin/rpc-api/jsonrpc.ts delete mode 100644 lightning-backend/src/api/explorer/statistics.api.ts delete mode 100644 lightning-backend/src/config.ts delete mode 100644 lightning-backend/src/database-migration.ts delete mode 100644 lightning-backend/src/database.ts delete mode 100644 lightning-backend/src/index.ts delete mode 100644 lightning-backend/src/logger.ts delete mode 100644 lightning-backend/src/server.ts delete mode 100644 lightning-backend/tsconfig.json delete mode 100644 lightning-backend/tslint.json diff --git a/backend/mempool-config.sample.json b/backend/mempool-config.sample.json index eedbf3e4c..9fe8ca36a 100644 --- a/backend/mempool-config.sample.json +++ b/backend/mempool-config.sample.json @@ -66,6 +66,15 @@ "ENABLED": false, "DATA_PATH": "/bisq/statsnode-data/btc_mainnet/db" }, + "LIGHTNING": { + "ENABLED": false, + "BACKEND": "lnd" + }, + "LND_NODE_AUTH": { + "TLS_CERT_PATH": "tls.cert", + "MACAROON_PATH": "admin.macaroon", + "SOCKET": "localhost:10009" + }, "SOCKS5PROXY": { "ENABLED": false, "USE_ONION": true, diff --git a/backend/package.json b/backend/package.json index d3fb90e21..d2d14fb0a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -37,6 +37,7 @@ "bolt07": "^1.8.1", "crypto-js": "^4.0.0", "express": "^4.18.0", + "ln-service": "^53.17.4", "mysql2": "2.3.3", "node-worker-threads-pool": "^1.5.1", "socks-proxy-agent": "~7.0.0", diff --git a/backend/src/api/bitcoin/bitcoin-api-abstract-factory.ts b/backend/src/api/bitcoin/bitcoin-api-abstract-factory.ts index 9802bcd71..f3f7011dd 100644 --- a/backend/src/api/bitcoin/bitcoin-api-abstract-factory.ts +++ b/backend/src/api/bitcoin/bitcoin-api-abstract-factory.ts @@ -13,6 +13,7 @@ export interface AbstractBitcoinApi { $getAddressTransactions(address: string, lastSeenTxId: string): Promise; $getAddressPrefix(prefix: string): string[]; $sendRawTransaction(rawTransaction: string): Promise; + $getOutspend(txId: string, vout: number): Promise; $getOutspends(txId: string): Promise; $getBatchedOutspends(txId: string[]): Promise; } diff --git a/backend/src/api/bitcoin/bitcoin-api.ts b/backend/src/api/bitcoin/bitcoin-api.ts index 7309256bd..3152954c1 100644 --- a/backend/src/api/bitcoin/bitcoin-api.ts +++ b/backend/src/api/bitcoin/bitcoin-api.ts @@ -130,6 +130,16 @@ class BitcoinApi implements AbstractBitcoinApi { return this.bitcoindClient.sendRawTransaction(rawTransaction); } + async $getOutspend(txId: string, vout: number): Promise { + const txOut = await this.bitcoindClient.getTxOut(txId, vout, false); + return { + spent: txOut === null, + status: { + confirmed: true, + } + }; + } + async $getOutspends(txId: string): Promise { const outSpends: IEsploraApi.Outspend[] = []; const tx = await this.$getRawTransaction(txId, true, false); @@ -195,7 +205,9 @@ class BitcoinApi implements AbstractBitcoinApi { sequence: vin.sequence, txid: vin.txid || '', vout: vin.vout || 0, - witness: vin.txinwitness, + witness: vin.txinwitness || [], + inner_redeemscript_asm: '', + inner_witnessscript_asm: '', }; }); diff --git a/backend/src/api/bitcoin/esplora-api.interface.ts b/backend/src/api/bitcoin/esplora-api.interface.ts index f825c60f9..39f8cfd6f 100644 --- a/backend/src/api/bitcoin/esplora-api.interface.ts +++ b/backend/src/api/bitcoin/esplora-api.interface.ts @@ -25,10 +25,10 @@ export namespace IEsploraApi { is_coinbase: boolean; scriptsig: string; scriptsig_asm: string; - inner_redeemscript_asm?: string; - inner_witnessscript_asm?: string; + inner_redeemscript_asm: string; + inner_witnessscript_asm: string; sequence: any; - witness?: string[]; + witness: string[]; prevout: Vout | null; // Elements is_pegin?: boolean; diff --git a/backend/src/api/bitcoin/esplora-api.ts b/backend/src/api/bitcoin/esplora-api.ts index 007b4131c..e8eee343a 100644 --- a/backend/src/api/bitcoin/esplora-api.ts +++ b/backend/src/api/bitcoin/esplora-api.ts @@ -66,6 +66,11 @@ class ElectrsApi implements AbstractBitcoinApi { throw new Error('Method not implemented.'); } + $getOutspend(txId: string, vout: number): Promise { + return axios.get(config.ESPLORA.REST_API_URL + '/tx/' + txId + '/outspend/' + vout, this.axiosConfig) + .then((response) => response.data); + } + $getOutspends(txId: string): Promise { return axios.get(config.ESPLORA.REST_API_URL + '/tx/' + txId + '/outspends', this.axiosConfig) .then((response) => response.data); diff --git a/backend/src/api/database-migration.ts b/backend/src/api/database-migration.ts index c4107e426..85a10b34b 100644 --- a/backend/src/api/database-migration.ts +++ b/backend/src/api/database-migration.ts @@ -4,7 +4,7 @@ import logger from '../logger'; import { Common } from './common'; class DatabaseMigration { - private static currentVersion = 24; + private static currentVersion = 25; private queryTimeout = 120000; private statisticsAddedIndexed = false; private uniqueLogs: string[] = []; @@ -248,6 +248,15 @@ class DatabaseMigration { await this.$executeQuery('DROP TABLE IF EXISTS `blocks_audits`'); await this.$executeQuery(this.getCreateBlocksAuditsTableQuery(), await this.$checkIfTableExists('blocks_audits')); } + + if (databaseSchemaVersion < 25 && isBitcoin === true) { + await this.$executeQuery(`INSERT INTO state VALUES('last_node_stats', 0, '1970-01-01');`); + await this.$executeQuery(this.getCreateLightningStatisticsQuery(), await this.$checkIfTableExists('lightning_stats')); + await this.$executeQuery(this.getCreateNodesQuery(), await this.$checkIfTableExists('nodes')); + await this.$executeQuery(this.getCreateChannelsQuery(), await this.$checkIfTableExists('channels')); + await this.$executeQuery(this.getCreateNodesStatsQuery(), await this.$checkIfTableExists('node_stats')); + } + } catch (e) { throw e; } @@ -569,6 +578,82 @@ class DatabaseMigration { adjustment float NOT NULL, PRIMARY KEY (height), INDEX (time) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`; + } + + private getCreateLightningStatisticsQuery(): string { + return `CREATE TABLE IF NOT EXISTS lightning_stats ( + id int(11) NOT NULL AUTO_INCREMENT, + added datetime NOT NULL, + channel_count int(11) NOT NULL, + node_count int(11) NOT NULL, + total_capacity double unsigned NOT NULL, + PRIMARY KEY (id) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`; + } + + private getCreateNodesQuery(): string { + return `CREATE TABLE IF NOT EXISTS nodes ( + public_key varchar(66) NOT NULL, + first_seen datetime NOT NULL, + updated_at datetime NOT NULL, + alias varchar(200) CHARACTER SET utf8mb4 NOT NULL, + color varchar(200) NOT NULL, + sockets text DEFAULT NULL, + PRIMARY KEY (public_key), + KEY alias (alias(10)) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`; + } + + private getCreateChannelsQuery(): string { + return `CREATE TABLE IF NOT EXISTS channels ( + id bigint(11) unsigned NOT NULL, + short_id varchar(15) NOT NULL DEFAULT '', + capacity bigint(20) unsigned NOT NULL, + transaction_id varchar(64) NOT NULL, + transaction_vout int(11) NOT NULL, + updated_at datetime DEFAULT NULL, + created datetime DEFAULT NULL, + status int(11) NOT NULL DEFAULT 0, + closing_transaction_id varchar(64) DEFAULT NULL, + closing_date datetime DEFAULT NULL, + closing_reason int(11) DEFAULT NULL, + node1_public_key varchar(66) NOT NULL, + node1_base_fee_mtokens bigint(20) unsigned DEFAULT NULL, + node1_cltv_delta int(11) DEFAULT NULL, + node1_fee_rate bigint(11) DEFAULT NULL, + node1_is_disabled tinyint(1) DEFAULT NULL, + node1_max_htlc_mtokens bigint(20) unsigned DEFAULT NULL, + node1_min_htlc_mtokens bigint(20) DEFAULT NULL, + node1_updated_at datetime DEFAULT NULL, + node2_public_key varchar(66) NOT NULL, + node2_base_fee_mtokens bigint(20) unsigned DEFAULT NULL, + node2_cltv_delta int(11) DEFAULT NULL, + node2_fee_rate bigint(11) DEFAULT NULL, + node2_is_disabled tinyint(1) DEFAULT NULL, + node2_max_htlc_mtokens bigint(20) unsigned DEFAULT NULL, + node2_min_htlc_mtokens bigint(20) unsigned DEFAULT NULL, + node2_updated_at datetime DEFAULT NULL, + PRIMARY KEY (id), + KEY node1_public_key (node1_public_key), + KEY node2_public_key (node2_public_key), + KEY status (status), + KEY short_id (short_id), + KEY transaction_id (transaction_id), + KEY closing_transaction_id (closing_transaction_id) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`; + } + + private getCreateNodesStatsQuery(): string { + return `CREATE TABLE IF NOT EXISTS node_stats ( + id int(11) unsigned NOT NULL AUTO_INCREMENT, + public_key varchar(66) NOT NULL DEFAULT '', + added date NOT NULL, + capacity bigint(20) unsigned NOT NULL DEFAULT 0, + channels int(11) unsigned NOT NULL DEFAULT 0, + PRIMARY KEY (id), + UNIQUE KEY added (added,public_key), + KEY public_key (public_key) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`; } diff --git a/lightning-backend/src/api/explorer/channels.api.ts b/backend/src/api/explorer/channels.api.ts similarity index 99% rename from lightning-backend/src/api/explorer/channels.api.ts rename to backend/src/api/explorer/channels.api.ts index c72f93257..67d2d38e0 100644 --- a/lightning-backend/src/api/explorer/channels.api.ts +++ b/backend/src/api/explorer/channels.api.ts @@ -38,7 +38,7 @@ class ChannelsApi { public async $getClosedChannelsWithoutReason(): Promise { try { - const query = `SELECT * FROM channels WHERE status = 2 AND closing_reason IS NULL`; + const query = `SELECT * FROM channels WHERE status = 2 AND closing_reason IS NULL AND closing_transaction_id != ''`; const [rows]: any = await DB.query(query); return rows; } catch (e) { diff --git a/lightning-backend/src/api/explorer/channels.routes.ts b/backend/src/api/explorer/channels.routes.ts similarity index 85% rename from lightning-backend/src/api/explorer/channels.routes.ts rename to backend/src/api/explorer/channels.routes.ts index ff9d166f9..6735b7502 100644 --- a/lightning-backend/src/api/explorer/channels.routes.ts +++ b/backend/src/api/explorer/channels.routes.ts @@ -1,16 +1,16 @@ import config from '../../config'; -import { Express, Request, Response } from 'express'; +import { Application, Request, Response } from 'express'; import channelsApi from './channels.api'; class ChannelsRoutes { constructor() { } - public initRoutes(app: Express) { + public initRoutes(app: Application) { app - .get(config.MEMPOOL.API_URL_PREFIX + 'channels/txids', this.$getChannelsByTransactionIds) - .get(config.MEMPOOL.API_URL_PREFIX + 'channels/search/:search', this.$searchChannelsById) - .get(config.MEMPOOL.API_URL_PREFIX + 'channels/:short_id', this.$getChannel) - .get(config.MEMPOOL.API_URL_PREFIX + 'channels', this.$getChannelsForNode) + .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/channels/txids', this.$getChannelsByTransactionIds) + .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/channels/search/:search', this.$searchChannelsById) + .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/channels/:short_id', this.$getChannel) + .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/channels', this.$getChannelsForNode) ; } diff --git a/lightning-backend/src/api/explorer/general.routes.ts b/backend/src/api/explorer/general.routes.ts similarity index 58% rename from lightning-backend/src/api/explorer/general.routes.ts rename to backend/src/api/explorer/general.routes.ts index d6154bdc1..26897cb79 100644 --- a/lightning-backend/src/api/explorer/general.routes.ts +++ b/backend/src/api/explorer/general.routes.ts @@ -1,16 +1,17 @@ import config from '../../config'; -import { Express, Request, Response } from 'express'; +import { Application, Request, Response } from 'express'; import nodesApi from './nodes.api'; import channelsApi from './channels.api'; import statisticsApi from './statistics.api'; -class GeneralRoutes { +class GeneralLightningRoutes { constructor() { } - public initRoutes(app: Express) { + public initRoutes(app: Application) { app - .get(config.MEMPOOL.API_URL_PREFIX + 'search', this.$searchNodesAndChannels) - .get(config.MEMPOOL.API_URL_PREFIX + 'statistics', this.$getStatistics) - ; + .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/search', this.$searchNodesAndChannels) + .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/statistics/latest', this.$getGeneralStats) + .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/statistics', this.$getStatistics) + ; } private async $searchNodesAndChannels(req: Request, res: Response) { @@ -38,6 +39,15 @@ class GeneralRoutes { res.status(500).send(e instanceof Error ? e.message : e); } } + + private async $getGeneralStats(req: Request, res: Response) { + try { + const statistics = await statisticsApi.$getLatestStatistics(); + res.json(statistics); + } catch (e) { + res.status(500).send(e instanceof Error ? e.message : e); + } + } } -export default new GeneralRoutes(); +export default new GeneralLightningRoutes(); diff --git a/lightning-backend/src/api/explorer/nodes.api.ts b/backend/src/api/explorer/nodes.api.ts similarity index 86% rename from lightning-backend/src/api/explorer/nodes.api.ts rename to backend/src/api/explorer/nodes.api.ts index 4c80c7f2d..1bf9ce12d 100644 --- a/lightning-backend/src/api/explorer/nodes.api.ts +++ b/backend/src/api/explorer/nodes.api.ts @@ -46,20 +46,6 @@ class NodesApi { } } - public async $getLatestStatistics(): Promise { - try { - const [rows]: any = await DB.query(`SELECT * FROM statistics ORDER BY id DESC LIMIT 1`); - const [rows2]: any = await DB.query(`SELECT * FROM statistics ORDER BY id DESC LIMIT 1 OFFSET 72`); - return { - latest: rows[0], - previous: rows2[0], - }; - } catch (e) { - logger.err('$getLatestStatistics error: ' + (e instanceof Error ? e.message : e)); - throw e; - } - } - public async $searchNodeByPublicKeyOrAlias(search: string) { try { const searchStripped = search.replace('%', '') + '%'; diff --git a/lightning-backend/src/api/explorer/nodes.routes.ts b/backend/src/api/explorer/nodes.routes.ts similarity index 65% rename from lightning-backend/src/api/explorer/nodes.routes.ts rename to backend/src/api/explorer/nodes.routes.ts index e21617f45..6c79c8201 100644 --- a/lightning-backend/src/api/explorer/nodes.routes.ts +++ b/backend/src/api/explorer/nodes.routes.ts @@ -1,17 +1,16 @@ import config from '../../config'; -import { Express, Request, Response } from 'express'; +import { Application, Request, Response } from 'express'; import nodesApi from './nodes.api'; class NodesRoutes { constructor() { } - public initRoutes(app: Express) { + public initRoutes(app: Application) { app - .get(config.MEMPOOL.API_URL_PREFIX + 'statistics/latest', this.$getGeneralStats) - .get(config.MEMPOOL.API_URL_PREFIX + 'nodes/search/:search', this.$searchNode) - .get(config.MEMPOOL.API_URL_PREFIX + 'nodes/top', this.$getTopNodes) - .get(config.MEMPOOL.API_URL_PREFIX + 'nodes/:public_key/statistics', this.$getHistoricalNodeStats) - .get(config.MEMPOOL.API_URL_PREFIX + 'nodes/:public_key', this.$getNode) - ; + .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/nodes/search/:search', this.$searchNode) + .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/nodes/top', this.$getTopNodes) + .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/nodes/:public_key/statistics', this.$getHistoricalNodeStats) + .get(config.MEMPOOL.API_URL_PREFIX + 'lightning/nodes/:public_key', this.$getNode) + ; } private async $searchNode(req: Request, res: Response) { @@ -45,15 +44,6 @@ class NodesRoutes { } } - private async $getGeneralStats(req: Request, res: Response) { - try { - const statistics = await nodesApi.$getLatestStatistics(); - res.json(statistics); - } catch (e) { - res.status(500).send(e instanceof Error ? e.message : e); - } - } - private async $getTopNodes(req: Request, res: Response) { try { const topCapacityNodes = await nodesApi.$getTopCapacityNodes(); diff --git a/backend/src/api/explorer/statistics.api.ts b/backend/src/api/explorer/statistics.api.ts new file mode 100644 index 000000000..5dd4609b5 --- /dev/null +++ b/backend/src/api/explorer/statistics.api.ts @@ -0,0 +1,32 @@ +import logger from '../../logger'; +import DB from '../../database'; + +class StatisticsApi { + public async $getStatistics(): Promise { + try { + const query = `SELECT UNIX_TIMESTAMP(added) AS added, channel_count, node_count, total_capacity FROM lightning_stats ORDER BY id DESC`; + const [rows]: any = await DB.query(query); + return rows; + } catch (e) { + logger.err('$getStatistics error: ' + (e instanceof Error ? e.message : e)); + throw e; + } + } + + public async $getLatestStatistics(): Promise { + try { + const [rows]: any = await DB.query(`SELECT * FROM lightning_stats ORDER BY id DESC LIMIT 1`); + const [rows2]: any = await DB.query(`SELECT * FROM lightning_stats ORDER BY id DESC LIMIT 1 OFFSET 72`); + return { + latest: rows[0], + previous: rows2[0], + }; + } catch (e) { + logger.err('$getLatestStatistics error: ' + (e instanceof Error ? e.message : e)); + throw e; + } + } + +} + +export default new StatisticsApi(); diff --git a/lightning-backend/src/api/lightning/lightning-api-abstract-factory.ts b/backend/src/api/lightning/lightning-api-abstract-factory.ts similarity index 100% rename from lightning-backend/src/api/lightning/lightning-api-abstract-factory.ts rename to backend/src/api/lightning/lightning-api-abstract-factory.ts diff --git a/lightning-backend/src/api/lightning/lightning-api-factory.ts b/backend/src/api/lightning/lightning-api-factory.ts similarity index 88% rename from lightning-backend/src/api/lightning/lightning-api-factory.ts rename to backend/src/api/lightning/lightning-api-factory.ts index e2a730650..ab551095c 100644 --- a/lightning-backend/src/api/lightning/lightning-api-factory.ts +++ b/backend/src/api/lightning/lightning-api-factory.ts @@ -3,7 +3,7 @@ import { AbstractLightningApi } from './lightning-api-abstract-factory'; import LndApi from './lnd/lnd-api'; function lightningApiFactory(): AbstractLightningApi { - switch (config.MEMPOOL.BACKEND) { + switch (config.LIGHTNING.BACKEND) { case 'lnd': default: return new LndApi(); diff --git a/lightning-backend/src/api/lightning/lightning-api.interface.ts b/backend/src/api/lightning/lightning-api.interface.ts similarity index 100% rename from lightning-backend/src/api/lightning/lightning-api.interface.ts rename to backend/src/api/lightning/lightning-api.interface.ts diff --git a/lightning-backend/src/api/lightning/lnd/lnd-api.ts b/backend/src/api/lightning/lnd/lnd-api.ts similarity index 79% rename from lightning-backend/src/api/lightning/lnd/lnd-api.ts rename to backend/src/api/lightning/lnd/lnd-api.ts index 57f225101..87c182a42 100644 --- a/lightning-backend/src/api/lightning/lnd/lnd-api.ts +++ b/backend/src/api/lightning/lnd/lnd-api.ts @@ -8,14 +8,17 @@ import logger from '../../../logger'; class LndApi implements AbstractLightningApi { private lnd: any; constructor() { + if (!config.LIGHTNING.ENABLED) { + return; + } try { - const tls = fs.readFileSync(config.LN_NODE_AUTH.TLS_CERT_PATH).toString('base64'); - const macaroon = fs.readFileSync(config.LN_NODE_AUTH.MACAROON_PATH).toString('base64'); + const tls = fs.readFileSync(config.LND_NODE_AUTH.TLS_CERT_PATH).toString('base64'); + const macaroon = fs.readFileSync(config.LND_NODE_AUTH.MACAROON_PATH).toString('base64'); const { lnd } = lnService.authenticatedLndGrpc({ cert: tls, macaroon: macaroon, - socket: config.LN_NODE_AUTH.SOCKET, + socket: config.LND_NODE_AUTH.SOCKET, }); this.lnd = lnd; diff --git a/backend/src/config.ts b/backend/src/config.ts index 44864d3b9..acc0b30a0 100644 --- a/backend/src/config.ts +++ b/backend/src/config.ts @@ -27,6 +27,15 @@ interface IConfig { ESPLORA: { REST_API_URL: string; }; + LIGHTNING: { + ENABLED: boolean; + BACKEND: 'lnd' | 'cln' | 'ldk'; + }; + LND_NODE_AUTH: { + TLS_CERT_PATH: string; + MACAROON_PATH: string; + SOCKET: string; + }; ELECTRUM: { HOST: string; PORT: number; @@ -158,6 +167,15 @@ const defaults: IConfig = { 'ENABLED': false, 'DATA_PATH': '/bisq/statsnode-data/btc_mainnet/db' }, + 'LIGHTNING': { + 'ENABLED': false, + 'BACKEND': 'lnd' + }, + 'LND_NODE_AUTH': { + 'TLS_CERT_PATH': '', + 'MACAROON_PATH': '', + 'SOCKET': 'localhost:10009', + }, 'SOCKS5PROXY': { 'ENABLED': false, 'USE_ONION': true, @@ -166,11 +184,11 @@ const defaults: IConfig = { 'USERNAME': '', 'PASSWORD': '' }, - "PRICE_DATA_SERVER": { + 'PRICE_DATA_SERVER': { 'TOR_URL': 'http://wizpriceje6q5tdrxkyiazsgu7irquiqjy2dptezqhrtu7l2qelqktid.onion/getAllMarketPrices', 'CLEARNET_URL': 'https://price.bisq.wiz.biz/getAllMarketPrices' }, - "EXTERNAL_DATA_SERVER": { + 'EXTERNAL_DATA_SERVER': { 'MEMPOOL_API': 'https://mempool.space/api/v1', 'MEMPOOL_ONION': 'http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/api/v1', 'LIQUID_API': 'https://liquid.network/api/v1', @@ -190,6 +208,8 @@ class Config implements IConfig { SYSLOG: IConfig['SYSLOG']; STATISTICS: IConfig['STATISTICS']; BISQ: IConfig['BISQ']; + LIGHTNING: IConfig['LIGHTNING']; + LND_NODE_AUTH: IConfig['LND_NODE_AUTH']; SOCKS5PROXY: IConfig['SOCKS5PROXY']; PRICE_DATA_SERVER: IConfig['PRICE_DATA_SERVER']; EXTERNAL_DATA_SERVER: IConfig['EXTERNAL_DATA_SERVER']; @@ -205,6 +225,8 @@ class Config implements IConfig { this.SYSLOG = configs.SYSLOG; this.STATISTICS = configs.STATISTICS; this.BISQ = configs.BISQ; + this.LIGHTNING = configs.LIGHTNING; + this.LND_NODE_AUTH = configs.LND_NODE_AUTH; this.SOCKS5PROXY = configs.SOCKS5PROXY; this.PRICE_DATA_SERVER = configs.PRICE_DATA_SERVER; this.EXTERNAL_DATA_SERVER = configs.EXTERNAL_DATA_SERVER; diff --git a/backend/src/index.ts b/backend/src/index.ts index ff0209294..74d6fb3da 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -29,6 +29,11 @@ import poolsUpdater from './tasks/pools-updater'; import indexer from './indexer'; import priceUpdater from './tasks/price-updater'; import BlocksAuditsRepository from './repositories/BlocksAuditsRepository'; +import nodeSyncService from './tasks/lightning/node-sync.service'; +import lightningStatsUpdater from './tasks/lightning/stats-updater.service'; +import nodesRoutes from './api/explorer/nodes.routes'; +import channelsRoutes from './api/explorer/channels.routes'; +import generalLightningRoutes from './api/explorer/general.routes'; class Server { private wss: WebSocket.Server | undefined; @@ -130,6 +135,13 @@ class Server { bisqMarkets.startBisqService(); } + if (config.LIGHTNING.ENABLED) { + nodeSyncService.$startService() + .then(() => { + lightningStatsUpdater.$startService(); + }); + } + this.server.listen(config.MEMPOOL.HTTP_PORT, () => { if (worker) { logger.info(`Mempool Server worker #${process.pid} started`); @@ -362,6 +374,12 @@ class Server { .get(config.MEMPOOL.API_URL_PREFIX + 'liquid/pegs/month', routes.$getElementsPegsByMonth) ; } + + if (config.LIGHTNING.ENABLED) { + generalLightningRoutes.initRoutes(this.app); + nodesRoutes.initRoutes(this.app); + channelsRoutes.initRoutes(this.app); + } } } diff --git a/lightning-backend/src/tasks/node-sync.service.ts b/backend/src/tasks/lightning/node-sync.service.ts similarity index 92% rename from lightning-backend/src/tasks/node-sync.service.ts rename to backend/src/tasks/lightning/node-sync.service.ts index 095e9eeac..c8b7f8c4c 100644 --- a/lightning-backend/src/tasks/node-sync.service.ts +++ b/backend/src/tasks/lightning/node-sync.service.ts @@ -1,13 +1,13 @@ import { chanNumber } from 'bolt07'; -import DB from '../database'; -import logger from '../logger'; -import lightningApi from '../api/lightning/lightning-api-factory'; -import { ILightningApi } from '../api/lightning/lightning-api.interface'; -import channelsApi from '../api/explorer/channels.api'; -import bitcoinClient from '../api/bitcoin/bitcoin-client'; -import bitcoinApi from '../api/bitcoin/bitcoin-api-factory'; -import config from '../config'; -import { IEsploraApi } from '../api/bitcoin/esplora-api.interface'; +import DB from '../../database'; +import logger from '../../logger'; +import channelsApi from '../../api/explorer/channels.api'; +import bitcoinClient from '../../api/bitcoin/bitcoin-client'; +import bitcoinApi from '../../api/bitcoin/bitcoin-api-factory'; +import config from '../../config'; +import { IEsploraApi } from '../../api/bitcoin/esplora-api.interface'; +import lightningApi from '../../api/lightning/lightning-api-factory'; +import { ILightningApi } from '../../api/lightning/lightning-api.interface'; class NodeSyncService { constructor() {} @@ -15,43 +15,36 @@ class NodeSyncService { public async $startService() { logger.info('Starting node sync service'); - await this.$updateNodes(); + await this.$runUpdater(); setInterval(async () => { - await this.$updateNodes(); + await this.$runUpdater(); }, 1000 * 60 * 60); } - private async $updateNodes() { + private async $runUpdater() { try { + logger.info(`Updating nodes and channels...`); + const networkGraph = await lightningApi.$getNetworkGraph(); for (const node of networkGraph.nodes) { await this.$saveNode(node); } - logger.debug(`Nodes updated`); + logger.info(`Nodes updated.`); await this.$setChannelsInactive(); for (const channel of networkGraph.channels) { await this.$saveChannel(channel); } - logger.debug(`Channels updated`); + logger.info(`Channels updated.`); await this.$findInactiveNodesAndChannels(); - logger.debug(`Inactive channels scan complete`); - await this.$lookUpCreationDateFromChain(); - logger.debug(`Channel creation dates scan complete`); - await this.$updateNodeFirstSeen(); - logger.debug(`Node first seen dates scan complete`); - await this.$scanForClosedChannels(); - logger.debug(`Closed channels scan complete`); - await this.$runClosedChannelsForensics(); - logger.debug(`Closed channels forensics scan complete`); } catch (e) { logger.err('$updateNodes() error: ' + (e instanceof Error ? e.message : e)); @@ -80,18 +73,21 @@ class NodeSyncService { await DB.query(query, params); } } + logger.info(`Node first seen dates scan complete.`); } catch (e) { logger.err('$updateNodeFirstSeen() error: ' + (e instanceof Error ? e.message : e)); } } private async $lookUpCreationDateFromChain() { + logger.info(`Running channel creation date lookup...`); try { const channels = await channelsApi.$getChannelsWithoutCreatedDate(); for (const channel of channels) { const transaction = await bitcoinClient.getRawTransaction(channel.transaction_id, 1); await DB.query(`UPDATE channels SET created = FROM_UNIXTIME(?) WHERE channels.id = ?`, [transaction.blocktime, channel.id]); } + logger.info(`Channel creation dates scan complete.`); } catch (e) { logger.err('$setCreationDateFromChain() error: ' + (e instanceof Error ? e.message : e)); } @@ -99,6 +95,8 @@ class NodeSyncService { // Looking for channels whos nodes are inactive private async $findInactiveNodesAndChannels(): Promise { + logger.info(`Running inactive channels scan...`); + try { // @ts-ignore const [channels]: [ILightningApi.Channel[]] = await DB.query(`SELECT channels.id FROM channels WHERE channels.status = 1 AND ((SELECT COUNT(*) FROM nodes WHERE nodes.public_key = channels.node1_public_key) = 0 OR (SELECT COUNT(*) FROM nodes WHERE nodes.public_key = channels.node2_public_key) = 0)`); @@ -106,6 +104,7 @@ class NodeSyncService { for (const channel of channels) { await this.$updateChannelStatus(channel.id, 0); } + logger.info(`Inactive channels scan complete.`); } catch (e) { logger.err('$findInactiveNodesAndChannels() error: ' + (e instanceof Error ? e.message : e)); } @@ -113,6 +112,7 @@ class NodeSyncService { private async $scanForClosedChannels(): Promise { try { + logger.info(`Starting closed channels scan...`); const channels = await channelsApi.$getChannelsByStatus(0); for (const channel of channels) { const spendingTx = await bitcoinApi.$getOutspend(channel.transaction_id, channel.transaction_vout); @@ -125,6 +125,7 @@ class NodeSyncService { } } } + logger.info(`Closed channels scan complete.`); } catch (e) { logger.err('$scanForClosedChannels() error: ' + (e instanceof Error ? e.message : e)); } @@ -140,8 +141,8 @@ class NodeSyncService { if (!config.ESPLORA.REST_API_URL) { return; } - try { + logger.info(`Started running closed channel forensics...`); const channels = await channelsApi.$getClosedChannelsWithoutReason(); for (const channel of channels) { let reason = 0; @@ -186,6 +187,7 @@ class NodeSyncService { await DB.query(`UPDATE channels SET closing_reason = ? WHERE id = ?`, [reason, channel.id]); } } + logger.info(`Closed channels forensics scan complete.`); } catch (e) { logger.err('$runClosedChannelsForensics() error: ' + (e instanceof Error ? e.message : e)); } diff --git a/lightning-backend/src/tasks/stats-updater.service.ts b/backend/src/tasks/lightning/stats-updater.service.ts similarity index 85% rename from lightning-backend/src/tasks/stats-updater.service.ts rename to backend/src/tasks/lightning/stats-updater.service.ts index 150851a81..83b9973d4 100644 --- a/lightning-backend/src/tasks/stats-updater.service.ts +++ b/backend/src/tasks/lightning/stats-updater.service.ts @@ -1,7 +1,6 @@ - -import DB from '../database'; -import logger from '../logger'; -import lightningApi from '../api/lightning/lightning-api-factory'; +import logger from "../../logger"; +import DB from "../../database"; +import lightningApi from "../../api/lightning/lightning-api-factory"; class LightningStatsUpdater { constructor() {} @@ -29,6 +28,8 @@ class LightningStatsUpdater { } private async $logNodeStatsDaily() { + logger.info(`Running daily node stats update...`); + const currentDate = new Date().toISOString().split('T')[0]; try { const [state]: any = await DB.query(`SELECT string FROM state WHERE name = 'last_node_stats'`); @@ -52,7 +53,7 @@ class LightningStatsUpdater { node.channels_count_left + node.channels_count_right]); } await DB.query(`UPDATE state SET string = ? WHERE name = 'last_node_stats'`, [currentDate]); - logger.debug('Daily node stats has updated.'); + logger.info('Daily node stats has updated.'); } catch (e) { logger.err('$logNodeStatsDaily() error: ' + (e instanceof Error ? e.message : e)); } @@ -60,9 +61,11 @@ class LightningStatsUpdater { // We only run this on first launch private async $populateHistoricalData() { + logger.info(`Running historical stats population...`); + const startTime = '2018-01-13'; try { - const [rows]: any = await DB.query(`SELECT COUNT(*) FROM statistics`); + const [rows]: any = await DB.query(`SELECT COUNT(*) FROM lightning_stats`); // Only store once per day if (rows[0]['COUNT(*)'] > 0) { return; @@ -86,7 +89,7 @@ class LightningStatsUpdater { channelsCount++; } - const query = `INSERT INTO statistics( + const query = `INSERT INTO lightning_stats( added, channel_count, node_count, @@ -117,7 +120,7 @@ class LightningStatsUpdater { nodeCount++; } - const query = `UPDATE statistics SET node_count = ? WHERE added = FROM_UNIXTIME(?)`; + const query = `UPDATE lightning_stats SET node_count = ? WHERE added = FROM_UNIXTIME(?)`; await DB.query(query, [ nodeCount, @@ -128,13 +131,15 @@ class LightningStatsUpdater { date.setDate(date.getDate() + 1); } - logger.debug('Historical stats populated.'); + logger.info('Historical stats populated.'); } catch (e) { logger.err('$populateHistoricalData() error: ' + (e instanceof Error ? e.message : e)); } } private async $logLightningStatsDaily() { + logger.info(`Running lightning daily stats log...`); + const currentDate = new Date().toISOString().split('T')[0]; try { const [state]: any = await DB.query(`SELECT string FROM state WHERE name = 'last_node_stats'`); @@ -151,7 +156,7 @@ class LightningStatsUpdater { } } - const query = `INSERT INTO statistics( + const query = `INSERT INTO lightning_stats( added, channel_count, node_count, @@ -164,8 +169,9 @@ class LightningStatsUpdater { networkGraph.nodes.length, total_capacity, ]); + logger.info(`Lightning daily stats done.`); } catch (e) { - logger.err('$logLightningStats() error: ' + (e instanceof Error ? e.message : e)); + logger.err('$logLightningStatsDaily() error: ' + (e instanceof Error ? e.message : e)); } } } diff --git a/frontend/proxy.conf.local.js b/frontend/proxy.conf.local.js index 9be0ed770..b2fb1bb27 100644 --- a/frontend/proxy.conf.local.js +++ b/frontend/proxy.conf.local.js @@ -103,13 +103,13 @@ if (configContent && configContent.BASE_MODULE === 'bisq') { PROXY_CONFIG.push(...[ { - context: ['/lightning/api/v1/**'], - target: `http://localhost:8899`, + context: ['/testnet/api/v1/lightning/**'], + target: `http://localhost:8999`, secure: false, changeOrigin: true, proxyTimeout: 30000, pathRewrite: { - "^/lightning/api": "/api" + "^/testnet": "" }, }, { diff --git a/frontend/src/app/lightning/lightning-api.service.ts b/frontend/src/app/lightning/lightning-api.service.ts index 5a6e63305..7157c9bd7 100644 --- a/frontend/src/app/lightning/lightning-api.service.ts +++ b/frontend/src/app/lightning/lightning-api.service.ts @@ -1,23 +1,33 @@ import { Injectable } from '@angular/core'; import { HttpClient, HttpParams } from '@angular/common/http'; import { Observable } from 'rxjs'; - -const API_BASE_URL = '/lightning/api/v1'; +import { StateService } from '../services/state.service'; @Injectable({ providedIn: 'root' }) export class LightningApiService { + private apiBasePath = ''; // network path is /testnet, etc. or '' for mainnet + constructor( private httpClient: HttpClient, - ) { } + private stateService: StateService, + ) { + this.apiBasePath = ''; // assume mainnet by default + this.stateService.networkChanged$.subscribe((network) => { + if (network === 'bisq' && !this.stateService.env.BISQ_SEPARATE_BACKEND) { + network = ''; + } + this.apiBasePath = network ? '/' + network : ''; + }); + } getNode$(publicKey: string): Observable { - return this.httpClient.get(API_BASE_URL + '/nodes/' + publicKey); + return this.httpClient.get(this.apiBasePath + '/api/v1/lightning/nodes/' + publicKey); } getChannel$(shortId: string): Observable { - return this.httpClient.get(API_BASE_URL + '/channels/' + shortId); + return this.httpClient.get(this.apiBasePath + '/api/v1/lightning/channels/' + shortId); } getChannelsByNodeId$(publicKey: string, index: number = 0, status = 'open'): Observable { @@ -27,22 +37,22 @@ export class LightningApiService { .set('status', status) ; - return this.httpClient.get(API_BASE_URL + '/channels', { params, observe: 'response' }); + return this.httpClient.get(this.apiBasePath + '/api/v1/lightning/channels', { params, observe: 'response' }); } getLatestStatistics$(): Observable { - return this.httpClient.get(API_BASE_URL + '/statistics/latest'); + return this.httpClient.get(this.apiBasePath + '/api/v1/lightning/statistics/latest'); } listNodeStats$(publicKey: string): Observable { - return this.httpClient.get(API_BASE_URL + '/nodes/' + publicKey + '/statistics'); + return this.httpClient.get(this.apiBasePath + '/api/v1/lightning/nodes/' + publicKey + '/statistics'); } listTopNodes$(): Observable { - return this.httpClient.get(API_BASE_URL + '/nodes/top'); + return this.httpClient.get(this.apiBasePath + '/api/v1/lightning/nodes/top'); } listStatistics$(): Observable { - return this.httpClient.get(API_BASE_URL + '/statistics'); + return this.httpClient.get(this.apiBasePath + '/api/v1/lightning/statistics'); } } diff --git a/frontend/src/app/services/api.service.ts b/frontend/src/app/services/api.service.ts index f728e64d4..ddeb538d9 100644 --- a/frontend/src/app/services/api.service.ts +++ b/frontend/src/app/services/api.service.ts @@ -237,12 +237,12 @@ export class ApiService { txIds.forEach((txId: string) => { params = params.append('txId[]', txId); }); - return this.httpClient.get<{ inputs: any[], outputs: any[] }>(this.apiBaseUrl + this.apiBasePath + '/lightning/api/v1/channels/txids/', { params }); + return this.httpClient.get<{ inputs: any[], outputs: any[] }>(this.apiBaseUrl + this.apiBasePath + '/api/v1/lightning/channels/txids/', { params }); } lightningSearch$(searchText: string): Observable { let params = new HttpParams().set('searchText', searchText); - return this.httpClient.get(this.apiBaseUrl + this.apiBasePath + '/lightning/api/v1/search', { params }); + return this.httpClient.get(this.apiBaseUrl + this.apiBasePath + '/api/v1/lightning/search', { params }); } } diff --git a/lightning-backend/.gitignore b/lightning-backend/.gitignore deleted file mode 100644 index 3a41effef..000000000 --- a/lightning-backend/.gitignore +++ /dev/null @@ -1,48 +0,0 @@ -# See http://help.github.com/ignore-files/ for more about ignoring files. - -# production config and external assets -*.json -!mempool-config.sample.json -!package.json -!package-lock.json -!tslint.json -!tsconfig.json - -# compiled output -/dist -/tmp - -# dependencies -/node_modules - -# IDEs and editors -/.idea -.project -.classpath -.c9/ -*.launch -.settings/ - -# IDE - VSCode -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json - -# misc -/.sass-cache -/connect.lock -/coverage/* -/libpeerconnection.log -npm-debug.log -testem.log -/typings - -# e2e -/e2e/*.js -/e2e/*.map - -#System Files -.DS_Store -Thumbs.db diff --git a/lightning-backend/mempool-config.sample.json b/lightning-backend/mempool-config.sample.json deleted file mode 100644 index 2a2d3d6a9..000000000 --- a/lightning-backend/mempool-config.sample.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "MEMPOOL": { - "NETWORK": "mainnet", - "BACKEND": "lnd", - "HTTP_PORT": 8899, - "API_URL_PREFIX": "/api/v1/", - "STDOUT_LOG_MIN_PRIORITY": "debug" - }, - "ESPLORA": { - "REST_API_URL": "" - }, - "SYSLOG": { - "ENABLED": false, - "HOST": "127.0.0.1", - "PORT": 514, - "MIN_PRIORITY": "info", - "FACILITY": "local7" - }, - "LN_NODE_AUTH": { - "TLS_CERT_PATH": "", - "MACAROON_PATH": "", - "SOCKET": "localhost:10009" - }, - "CORE_RPC": { - "HOST": "127.0.0.1", - "PORT": 8332, - "USERNAME": "mempool", - "PASSWORD": "mempool" - }, - "DATABASE": { - "HOST": "127.0.0.1", - "PORT": 3306, - "SOCKET": "/var/run/mysql/mysql.sock", - "DATABASE": "lightning", - "USERNAME": "root", - "PASSWORD": "root" - } -} diff --git a/lightning-backend/package-lock.json b/lightning-backend/package-lock.json deleted file mode 100644 index 38a1a4571..000000000 --- a/lightning-backend/package-lock.json +++ /dev/null @@ -1,3291 +0,0 @@ -{ - "name": "lightning-backend", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "lightning-backend", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "axios": "^0.27.2", - "express": "^4.17.3", - "ln-service": "^53.11.0", - "mysql2": "^2.3.3", - "typescript": "^4.6.3" - }, - "devDependencies": { - "@types/express": "^4.17.13", - "@types/node": "^17.0.24" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" - }, - "node_modules/@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/caseless": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", - "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" - }, - "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "node_modules/@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" - }, - "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" - }, - "node_modules/@types/node": { - "version": "17.0.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", - "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" - }, - "node_modules/@types/request": { - "version": "2.48.8", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.8.tgz", - "integrity": "sha512-whjk1EDJPcAR2kYHRbFl/lKeeKYTi05A15K9bnLInCVroNDCtXce57xKdI0/rQaA3K+6q0eFyUBPmqfSndUZdQ==", - "dependencies": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.0" - } - }, - "node_modules/@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/tough-cookie": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", - "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==" - }, - "node_modules/@types/ws": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", - "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "node_modules/async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" - }, - "node_modules/asyncjs-util": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/asyncjs-util/-/asyncjs-util-1.2.9.tgz", - "integrity": "sha512-U9imS8ehJA6DPNdBdvoLcIRDFh7yzI9J93CC8/2obk8gUSIy8KKhmCqYe+3NlISJhxLLi8aWmVL1Gkb3dz1xhg==", - "dependencies": { - "async": "3.2.3" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "node_modules/axios/node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "dependencies": { - "safe-buffer": "5.1.2" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/basic-auth/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/bech32": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", - "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" - }, - "node_modules/bip174": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bip174/-/bip174-2.0.1.tgz", - "integrity": "sha512-i3X26uKJOkDTAalYAp0Er+qGMDhrbbh2o93/xiPyAN2s25KrClSpe3VXo/7mNJoqA5qfko8rLS2l3RWZgYmjKQ==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/bitcoin-ops": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/bitcoin-ops/-/bitcoin-ops-1.4.1.tgz", - "integrity": "sha512-pef6gxZFztEhaE9RY9HmWVmiIHqCb2OyS4HPKkpc6CIiiOa3Qmuoylxc5P2EkU3w+5eTSifI9SEZC88idAIGow==" - }, - "node_modules/bitcoinjs-lib": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-6.0.1.tgz", - "integrity": "sha512-x/7D4jDj/MMkmO6t3p2CSDXTqpwZ/jRsRiJDmaiXabrR9XRo7jwby8HRn7EyK1h24rKFFI7vI0ay4czl6bDOZQ==", - "dependencies": { - "bech32": "^2.0.0", - "bip174": "^2.0.1", - "bs58check": "^2.1.2", - "create-hash": "^1.1.0", - "typeforce": "^1.11.3", - "varuint-bitcoin": "^1.1.2", - "wif": "^2.0.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/bolt07": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/bolt07/-/bolt07-1.8.1.tgz", - "integrity": "sha512-vgh796VOdJBunZZZX0YuW1DmkS9SbW93rCLPOmWPsAHS/mStEs4+5d0KM1bYX6QBHshY9ecg4kgJaB18jrZsIA==", - "dependencies": { - "bn.js": "5.2.0" - } - }, - "node_modules/bolt09": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/bolt09/-/bolt09-0.2.2.tgz", - "integrity": "sha512-m533YWZ/R/p1buxEK/19v94Ay1vS1PJNwfP30BCVj6l96NGpOa9t40HYuMpoX+xFYwOx8kZs+GGTb9TbJund0w==", - "engines": { - "node": ">=10.4.0" - } - }, - "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/cbor": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", - "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", - "dependencies": { - "nofilter": "^3.1.0" - }, - "engines": { - "node": ">=12.19" - } - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/denque": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", - "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "node_modules/ecpair": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ecpair/-/ecpair-2.0.1.tgz", - "integrity": "sha512-iT3wztQMeE/nDTlfnAg8dAFUfBS7Tq2BXzq3ae6L+pWgFU0fQ3l0woTzdTBrJV3OxBjxbzjq8EQhAbEmJNWFSw==", - "dependencies": { - "randombytes": "^2.1.0", - "typeforce": "^1.18.0", - "wif": "^2.0.6" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", - "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.19.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.4.2", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.9.7", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", - "setprototypeof": "1.2.0", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "dependencies": { - "is-property": "^1.0.2" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/invoices": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/invoices/-/invoices-2.0.5.tgz", - "integrity": "sha512-097isfZK3qaDJXQOEqTr3IfnrFZnGCAsbyqWNHAESdG12vBC39dprZWFwPLtnv7I8exhJG6WFFlaC51qaJan/w==", - "dependencies": { - "bech32": "2.0.0", - "bitcoinjs-lib": "6.0.1", - "bn.js": "5.2.0", - "bolt07": "1.8.1", - "bolt09": "0.2.2", - "tiny-secp256k1": "2.2.1" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" - }, - "node_modules/lightning": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/lightning/-/lightning-5.10.1.tgz", - "integrity": "sha512-dIrN4vPzmzq9DaMD6c+9DqQwJCMl1lOleWrhIrv+HIpzq6rdNJvUXaVJOFz1OV8P3zy2Q3+s9VxnzeN70ee+ow==", - "dependencies": { - "@grpc/grpc-js": "1.6.2", - "@grpc/proto-loader": "0.6.9", - "@types/express": "4.17.13", - "@types/node": "17.0.23", - "@types/request": "2.48.8", - "@types/ws": "8.5.3", - "async": "3.2.3", - "asyncjs-util": "1.2.9", - "bitcoinjs-lib": "6.0.1", - "bn.js": "5.2.0", - "body-parser": "1.20.0", - "bolt07": "1.8.1", - "bolt09": "0.2.3", - "cbor": "8.1.0", - "ecpair": "2.0.1", - "express": "4.17.3", - "invoices": "2.0.5", - "psbt": "2.0.1", - "tiny-secp256k1": "2.2.1", - "type-fest": "2.12.2" - }, - "engines": { - "node": ">=12.20" - } - }, - "node_modules/lightning/node_modules/@grpc/grpc-js": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.2.tgz", - "integrity": "sha512-9+89Ne1K8F9u86T+l1yIV2DS+dWHYVK61SsDZN4MFTFehOOaJ4rHxa1cW8Lwdn2/6tOx7N3+SY/vfcjztOHopA==", - "dependencies": { - "@grpc/proto-loader": "^0.6.4", - "@types/node": ">=12.12.47" - }, - "engines": { - "node": "^8.13.0 || >=10.10.0" - } - }, - "node_modules/lightning/node_modules/@grpc/proto-loader": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.9.tgz", - "integrity": "sha512-UlcCS8VbsU9d3XTXGiEVFonN7hXk+oMXZtoHHG2oSA1/GcDP1q6OUgs20PzHDGizzyi8ufGSUDlk3O2NyY7leg==", - "dependencies": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^6.10.0", - "yargs": "^16.2.0" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/lightning/node_modules/@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" - }, - "node_modules/lightning/node_modules/body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/lightning/node_modules/bolt09": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/bolt09/-/bolt09-0.2.3.tgz", - "integrity": "sha512-xEt5GE6pXB8wMIWHAoyF28k0Yt2rFqIou1LCyIeNadAOQhu/F7GTjZwreFwLl07YYkhOH23avewRt5PD8JnKKg==", - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/lightning/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/lightning/node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/lightning/node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/lightning/node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/lightning/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/lightning/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/lightning/node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/lightning/node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/lightning/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ln-service": { - "version": "53.11.0", - "resolved": "https://registry.npmjs.org/ln-service/-/ln-service-53.11.0.tgz", - "integrity": "sha512-qdsgLRFGdn8+zfSDgbGw584fS2QQromxp4VRXzj9nk3qveTD6IwBjaEhC1xtY73MQCHQ3ALkWVn3aYMoy5erFw==", - "dependencies": { - "bolt07": "1.8.1", - "cors": "2.8.5", - "express": "4.17.3", - "invoices": "2.0.5", - "lightning": "5.10.1", - "macaroon": "3.0.4", - "morgan": "1.10.0", - "ws": "8.5.0" - }, - "engines": { - "node": ">=12.20" - } - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" - }, - "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/macaroon": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/macaroon/-/macaroon-3.0.4.tgz", - "integrity": "sha512-Tja2jvupseKxltPZbu5RPSz2Pgh6peYA3O46YCTcYL8PI1VqtGwDqRhGfP8pows26xx9wTiygk+en62Bq+Y8JA==", - "dependencies": { - "sjcl": "^1.0.6", - "tweetnacl": "^1.0.0", - "tweetnacl-util": "^0.15.0" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/morgan": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", - "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", - "dependencies": { - "basic-auth": "~2.0.1", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-finished": "~2.3.0", - "on-headers": "~1.0.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/morgan/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/morgan/node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/morgan/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/mysql2": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", - "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", - "dependencies": { - "denque": "^2.0.1", - "generate-function": "^2.3.1", - "iconv-lite": "^0.6.3", - "long": "^4.0.0", - "lru-cache": "^6.0.0", - "named-placeholders": "^1.1.2", - "seq-queue": "^0.0.5", - "sqlstring": "^2.3.2" - }, - "engines": { - "node": ">= 8.0" - } - }, - "node_modules/mysql2/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/named-placeholders": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", - "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", - "dependencies": { - "lru-cache": "^4.1.3" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/named-placeholders/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/named-placeholders/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", - "engines": { - "node": ">=12.19" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "node_modules/protobufjs": { - "version": "6.11.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", - "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/psbt": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/psbt/-/psbt-2.0.1.tgz", - "integrity": "sha512-4s5DSXDJ9xAYjuRJXf8rEuqs+Leyl11TE3y98xzlhMJN2UYXSLkAW1KSUdm/gdu1cSTcdcicIFZscNXmxFko+w==", - "dependencies": { - "bip66": "1.1.5", - "bitcoin-ops": "1.4.1", - "bitcoinjs-lib": "6.0.1", - "bn.js": "5.2.0", - "pushdata-bitcoin": "1.0.1", - "varuint-bitcoin": "1.1.2" - }, - "engines": { - "node": ">=12.20" - } - }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "node_modules/pushdata-bitcoin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pushdata-bitcoin/-/pushdata-bitcoin-1.0.1.tgz", - "integrity": "sha1-FZMdPNlnreUiBvUjqnMxrvfUOvc=", - "dependencies": { - "bitcoin-ops": "^1.3.0" - } - }, - "node_modules/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "1.8.1", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/seq-queue": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", - "integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=" - }, - "node_modules/serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/sjcl": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/sjcl/-/sjcl-1.0.8.tgz", - "integrity": "sha512-LzIjEQ0S0DpIgnxMEayM1rq9aGwGRG4OnZhCdjx7glTaJtf4zRfpg87ImfjSJjoW9vKpagd82McDOwbRT5kQKQ==", - "engines": { - "node": "*" - } - }, - "node_modules/sqlstring": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", - "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tiny-secp256k1": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-2.2.1.tgz", - "integrity": "sha512-/U4xfVqnVxJXN4YVsru0E6t5wVncu2uunB8+RVR40fYUxkKYUPS10f+ePQZgFBoE/Jbf9H1NBveupF2VmB58Ng==", - "dependencies": { - "uint8array-tools": "0.0.7" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "node_modules/tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" - }, - "node_modules/type-fest": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.12.2.tgz", - "integrity": "sha512-qt6ylCGpLjZ7AaODxbpyBZSs9fCI9SkL3Z9q2oxMBQhs/uyY+VD8jHA8ULCGmWQJlBgqvO3EJeAngOHD8zQCrQ==", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typeforce": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", - "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" - }, - "node_modules/typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/uint8array-tools": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/uint8array-tools/-/uint8array-tools-0.0.7.tgz", - "integrity": "sha512-vrrNZJiusLWoFWBqz5Y5KMCgP9W9hnjZHzZiZRT8oNAkq3d5Z5Oe76jAvVVSRh4U8GGR90N2X1dWtrhvx6L8UQ==", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/varuint-bitcoin": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz", - "integrity": "sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw==", - "dependencies": { - "safe-buffer": "^5.1.1" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/wif": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", - "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=", - "dependencies": { - "bs58check": "<3.0.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "engines": { - "node": ">=10" - } - } - }, - "dependencies": { - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" - }, - "@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/caseless": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", - "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" - }, - "@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" - }, - "@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" - }, - "@types/node": { - "version": "17.0.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", - "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==" - }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" - }, - "@types/request": { - "version": "2.48.8", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.8.tgz", - "integrity": "sha512-whjk1EDJPcAR2kYHRbFl/lKeeKYTi05A15K9bnLInCVroNDCtXce57xKdI0/rQaA3K+6q0eFyUBPmqfSndUZdQ==", - "requires": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.0" - } - }, - "@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@types/tough-cookie": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", - "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==" - }, - "@types/ws": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", - "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", - "requires": { - "@types/node": "*" - } - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" - }, - "asyncjs-util": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/asyncjs-util/-/asyncjs-util-1.2.9.tgz", - "integrity": "sha512-U9imS8ehJA6DPNdBdvoLcIRDFh7yzI9J93CC8/2obk8gUSIy8KKhmCqYe+3NlISJhxLLi8aWmVL1Gkb3dz1xhg==", - "requires": { - "async": "3.2.3" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "requires": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - }, - "dependencies": { - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - } - } - }, - "base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "requires": { - "safe-buffer": "5.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "bech32": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", - "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" - }, - "bip174": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bip174/-/bip174-2.0.1.tgz", - "integrity": "sha512-i3X26uKJOkDTAalYAp0Er+qGMDhrbbh2o93/xiPyAN2s25KrClSpe3VXo/7mNJoqA5qfko8rLS2l3RWZgYmjKQ==" - }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "bitcoin-ops": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/bitcoin-ops/-/bitcoin-ops-1.4.1.tgz", - "integrity": "sha512-pef6gxZFztEhaE9RY9HmWVmiIHqCb2OyS4HPKkpc6CIiiOa3Qmuoylxc5P2EkU3w+5eTSifI9SEZC88idAIGow==" - }, - "bitcoinjs-lib": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-6.0.1.tgz", - "integrity": "sha512-x/7D4jDj/MMkmO6t3p2CSDXTqpwZ/jRsRiJDmaiXabrR9XRo7jwby8HRn7EyK1h24rKFFI7vI0ay4czl6bDOZQ==", - "requires": { - "bech32": "^2.0.0", - "bip174": "^2.0.1", - "bs58check": "^2.1.2", - "create-hash": "^1.1.0", - "typeforce": "^1.11.3", - "varuint-bitcoin": "^1.1.2", - "wif": "^2.0.1" - } - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "bolt07": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/bolt07/-/bolt07-1.8.1.tgz", - "integrity": "sha512-vgh796VOdJBunZZZX0YuW1DmkS9SbW93rCLPOmWPsAHS/mStEs4+5d0KM1bYX6QBHshY9ecg4kgJaB18jrZsIA==", - "requires": { - "bn.js": "5.2.0" - } - }, - "bolt09": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/bolt09/-/bolt09-0.2.2.tgz", - "integrity": "sha512-m533YWZ/R/p1buxEK/19v94Ay1vS1PJNwfP30BCVj6l96NGpOa9t40HYuMpoX+xFYwOx8kZs+GGTb9TbJund0w==" - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "cbor": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", - "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", - "requires": { - "nofilter": "^3.1.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "denque": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", - "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "ecpair": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ecpair/-/ecpair-2.0.1.tgz", - "integrity": "sha512-iT3wztQMeE/nDTlfnAg8dAFUfBS7Tq2BXzq3ae6L+pWgFU0fQ3l0woTzdTBrJV3OxBjxbzjq8EQhAbEmJNWFSw==", - "requires": { - "randombytes": "^2.1.0", - "typeforce": "^1.18.0", - "wif": "^2.0.6" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", - "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.19.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.4.2", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.9.7", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", - "setprototypeof": "1.2.0", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" - }, - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "requires": { - "is-property": "^1.0.2" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "invoices": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/invoices/-/invoices-2.0.5.tgz", - "integrity": "sha512-097isfZK3qaDJXQOEqTr3IfnrFZnGCAsbyqWNHAESdG12vBC39dprZWFwPLtnv7I8exhJG6WFFlaC51qaJan/w==", - "requires": { - "bech32": "2.0.0", - "bitcoinjs-lib": "6.0.1", - "bn.js": "5.2.0", - "bolt07": "1.8.1", - "bolt09": "0.2.2", - "tiny-secp256k1": "2.2.1" - } - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" - }, - "lightning": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/lightning/-/lightning-5.10.1.tgz", - "integrity": "sha512-dIrN4vPzmzq9DaMD6c+9DqQwJCMl1lOleWrhIrv+HIpzq6rdNJvUXaVJOFz1OV8P3zy2Q3+s9VxnzeN70ee+ow==", - "requires": { - "@grpc/grpc-js": "1.6.2", - "@grpc/proto-loader": "0.6.9", - "@types/express": "4.17.13", - "@types/node": "17.0.23", - "@types/request": "2.48.8", - "@types/ws": "8.5.3", - "async": "3.2.3", - "asyncjs-util": "1.2.9", - "bitcoinjs-lib": "6.0.1", - "bn.js": "5.2.0", - "body-parser": "1.20.0", - "bolt07": "1.8.1", - "bolt09": "0.2.3", - "cbor": "8.1.0", - "ecpair": "2.0.1", - "express": "4.17.3", - "invoices": "2.0.5", - "psbt": "2.0.1", - "tiny-secp256k1": "2.2.1", - "type-fest": "2.12.2" - }, - "dependencies": { - "@grpc/grpc-js": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.2.tgz", - "integrity": "sha512-9+89Ne1K8F9u86T+l1yIV2DS+dWHYVK61SsDZN4MFTFehOOaJ4rHxa1cW8Lwdn2/6tOx7N3+SY/vfcjztOHopA==", - "requires": { - "@grpc/proto-loader": "^0.6.4", - "@types/node": ">=12.12.47" - } - }, - "@grpc/proto-loader": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.9.tgz", - "integrity": "sha512-UlcCS8VbsU9d3XTXGiEVFonN7hXk+oMXZtoHHG2oSA1/GcDP1q6OUgs20PzHDGizzyi8ufGSUDlk3O2NyY7leg==", - "requires": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^6.10.0", - "yargs": "^16.2.0" - } - }, - "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" - }, - "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - } - }, - "bolt09": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/bolt09/-/bolt09-0.2.3.tgz", - "integrity": "sha512-xEt5GE6pXB8wMIWHAoyF28k0Yt2rFqIou1LCyIeNadAOQhu/F7GTjZwreFwLl07YYkhOH23avewRt5PD8JnKKg==" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - } - } - }, - "ln-service": { - "version": "53.11.0", - "resolved": "https://registry.npmjs.org/ln-service/-/ln-service-53.11.0.tgz", - "integrity": "sha512-qdsgLRFGdn8+zfSDgbGw584fS2QQromxp4VRXzj9nk3qveTD6IwBjaEhC1xtY73MQCHQ3ALkWVn3aYMoy5erFw==", - "requires": { - "bolt07": "1.8.1", - "cors": "2.8.5", - "express": "4.17.3", - "invoices": "2.0.5", - "lightning": "5.10.1", - "macaroon": "3.0.4", - "morgan": "1.10.0", - "ws": "8.5.0" - } - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "macaroon": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/macaroon/-/macaroon-3.0.4.tgz", - "integrity": "sha512-Tja2jvupseKxltPZbu5RPSz2Pgh6peYA3O46YCTcYL8PI1VqtGwDqRhGfP8pows26xx9wTiygk+en62Bq+Y8JA==", - "requires": { - "sjcl": "^1.0.6", - "tweetnacl": "^1.0.0", - "tweetnacl-util": "^0.15.0" - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "morgan": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", - "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", - "requires": { - "basic-auth": "~2.0.1", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-finished": "~2.3.0", - "on-headers": "~1.0.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "mysql2": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", - "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", - "requires": { - "denque": "^2.0.1", - "generate-function": "^2.3.1", - "iconv-lite": "^0.6.3", - "long": "^4.0.0", - "lru-cache": "^6.0.0", - "named-placeholders": "^1.1.2", - "seq-queue": "^0.0.5", - "sqlstring": "^2.3.2" - }, - "dependencies": { - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } - } - }, - "named-placeholders": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", - "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", - "requires": { - "lru-cache": "^4.1.3" - }, - "dependencies": { - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - } - } - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "protobufjs": { - "version": "6.11.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", - "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - } - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "psbt": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/psbt/-/psbt-2.0.1.tgz", - "integrity": "sha512-4s5DSXDJ9xAYjuRJXf8rEuqs+Leyl11TE3y98xzlhMJN2UYXSLkAW1KSUdm/gdu1cSTcdcicIFZscNXmxFko+w==", - "requires": { - "bip66": "1.1.5", - "bitcoin-ops": "1.4.1", - "bitcoinjs-lib": "6.0.1", - "bn.js": "5.2.0", - "pushdata-bitcoin": "1.0.1", - "varuint-bitcoin": "1.1.2" - } - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "pushdata-bitcoin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pushdata-bitcoin/-/pushdata-bitcoin-1.0.1.tgz", - "integrity": "sha1-FZMdPNlnreUiBvUjqnMxrvfUOvc=", - "requires": { - "bitcoin-ops": "^1.3.0" - } - }, - "qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==" - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", - "requires": { - "bytes": "3.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "1.8.1", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "seq-queue": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", - "integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=" - }, - "serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.2" - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "sjcl": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/sjcl/-/sjcl-1.0.8.tgz", - "integrity": "sha512-LzIjEQ0S0DpIgnxMEayM1rq9aGwGRG4OnZhCdjx7glTaJtf4zRfpg87ImfjSJjoW9vKpagd82McDOwbRT5kQKQ==" - }, - "sqlstring": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", - "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==" - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "tiny-secp256k1": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-2.2.1.tgz", - "integrity": "sha512-/U4xfVqnVxJXN4YVsru0E6t5wVncu2uunB8+RVR40fYUxkKYUPS10f+ePQZgFBoE/Jbf9H1NBveupF2VmB58Ng==", - "requires": { - "uint8array-tools": "0.0.7" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" - }, - "type-fest": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.12.2.tgz", - "integrity": "sha512-qt6ylCGpLjZ7AaODxbpyBZSs9fCI9SkL3Z9q2oxMBQhs/uyY+VD8jHA8ULCGmWQJlBgqvO3EJeAngOHD8zQCrQ==" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typeforce": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", - "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" - }, - "typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==" - }, - "uint8array-tools": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/uint8array-tools/-/uint8array-tools-0.0.7.tgz", - "integrity": "sha512-vrrNZJiusLWoFWBqz5Y5KMCgP9W9hnjZHzZiZRT8oNAkq3d5Z5Oe76jAvVVSRh4U8GGR90N2X1dWtrhvx6L8UQ==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "varuint-bitcoin": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz", - "integrity": "sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw==", - "requires": { - "safe-buffer": "^5.1.1" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "wif": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", - "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=", - "requires": { - "bs58check": "<3.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", - "requires": {} - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" - } - } -} diff --git a/lightning-backend/package.json b/lightning-backend/package.json deleted file mode 100644 index a44c9d82f..000000000 --- a/lightning-backend/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "lightning-backend", - "version": "1.0.0", - "description": "Backend for the Mempool Lightning Explorer", - "license": "AGPL-3.0", - "main": "index.ts", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "tsc": "./node_modules/typescript/bin/tsc", - "build": "npm run tsc", - "start": "node --max-old-space-size=2048 dist/index.js" - }, - "author": "", - "devDependencies": { - "@types/express": "^4.17.13", - "@types/node": "^17.0.24" - }, - "dependencies": { - "axios": "^0.27.2", - "express": "^4.17.3", - "ln-service": "^53.11.0", - "mysql2": "^2.3.3", - "typescript": "^4.6.3" - } -} diff --git a/lightning-backend/src/api/bitcoin/bitcoin-api-abstract-factory.ts b/lightning-backend/src/api/bitcoin/bitcoin-api-abstract-factory.ts deleted file mode 100644 index cd60843f3..000000000 --- a/lightning-backend/src/api/bitcoin/bitcoin-api-abstract-factory.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { IEsploraApi } from './esplora-api.interface'; - -export interface AbstractBitcoinApi { - $getRawMempool(): Promise; - $getRawTransaction(txId: string, skipConversion?: boolean, addPrevout?: boolean, lazyPrevouts?: boolean): Promise; - $getBlockHeightTip(): Promise; - $getTxIdsForBlock(hash: string): Promise; - $getBlockHash(height: number): Promise; - $getBlockHeader(hash: string): Promise; - $getBlock(hash: string): Promise; - $getAddress(address: string): Promise; - $getAddressTransactions(address: string, lastSeenTxId: string): Promise; - $getAddressPrefix(prefix: string): string[]; - $sendRawTransaction(rawTransaction: string): Promise; - $getOutspend(txId: string, vout: number): Promise; - $getOutspends(txId: string): Promise; - $getBatchedOutspends(txId: string[]): Promise; -} -export interface BitcoinRpcCredentials { - host: string; - port: number; - user: string; - pass: string; - timeout: number; -} diff --git a/lightning-backend/src/api/bitcoin/bitcoin-api-factory.ts b/lightning-backend/src/api/bitcoin/bitcoin-api-factory.ts deleted file mode 100644 index 3ae598ac2..000000000 --- a/lightning-backend/src/api/bitcoin/bitcoin-api-factory.ts +++ /dev/null @@ -1,15 +0,0 @@ -import config from '../../config'; -import { AbstractBitcoinApi } from './bitcoin-api-abstract-factory'; -import EsploraApi from './esplora-api'; -import BitcoinApi from './bitcoin-api'; -import bitcoinClient from './bitcoin-client'; - -function bitcoinApiFactory(): AbstractBitcoinApi { - if (config.ESPLORA.REST_API_URL) { - return new EsploraApi(); - } else { - return new BitcoinApi(bitcoinClient); - } -} - -export default bitcoinApiFactory(); diff --git a/lightning-backend/src/api/bitcoin/bitcoin-api.interface.ts b/lightning-backend/src/api/bitcoin/bitcoin-api.interface.ts deleted file mode 100644 index 54d666794..000000000 --- a/lightning-backend/src/api/bitcoin/bitcoin-api.interface.ts +++ /dev/null @@ -1,175 +0,0 @@ -export namespace IBitcoinApi { - export interface MempoolInfo { - loaded: boolean; // (boolean) True if the mempool is fully loaded - size: number; // (numeric) Current tx count - bytes: number; // (numeric) Sum of all virtual transaction sizes as defined in BIP 141. - usage: number; // (numeric) Total memory usage for the mempool - total_fee: number; // (numeric) Total fees of transactions in the mempool - maxmempool: number; // (numeric) Maximum memory usage for the mempool - mempoolminfee: number; // (numeric) Minimum fee rate in BTC/kB for tx to be accepted. - minrelaytxfee: number; // (numeric) Current minimum relay fee for transactions - } - - export interface RawMempool { [txId: string]: MempoolEntry; } - - export interface MempoolEntry { - vsize: number; // (numeric) virtual transaction size as defined in BIP 141. - weight: number; // (numeric) transaction weight as defined in BIP 141. - time: number; // (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT - height: number; // (numeric) block height when transaction entered pool - descendantcount: number; // (numeric) number of in-mempool descendant transactions (including this one) - descendantsize: number; // (numeric) virtual transaction size of in-mempool descendants (including this one) - ancestorcount: number; // (numeric) number of in-mempool ancestor transactions (including this one) - ancestorsize: number; // (numeric) virtual transaction size of in-mempool ancestors (including this one) - wtxid: string; // (string) hash of serialized transactionumber; including witness data - fees: { - base: number; // (numeric) transaction fee in BTC - modified: number; // (numeric) transaction fee with fee deltas used for mining priority in BTC - ancestor: number; // (numeric) modified fees (see above) of in-mempool ancestors (including this one) in BTC - descendant: number; // (numeric) modified fees (see above) of in-mempool descendants (including this one) in BTC - }; - depends: string[]; // (string) parent transaction id - spentby: string[]; // (array) unconfirmed transactions spending outputs from this transaction - 'bip125-replaceable': boolean; // (boolean) Whether this transaction could be replaced due to BIP125 (replace-by-fee) - } - - export interface Block { - hash: string; // (string) the block hash (same as provided) - confirmations: number; // (numeric) The number of confirmations, or -1 if the block is not on the main chain - size: number; // (numeric) The block size - strippedsize: number; // (numeric) The block size excluding witness data - weight: number; // (numeric) The block weight as defined in BIP 141 - height: number; // (numeric) The block height or index - version: number; // (numeric) The block version - versionHex: string; // (string) The block version formatted in hexadecimal - merkleroot: string; // (string) The merkle root - tx: Transaction[]; - time: number; // (numeric) The block time expressed in UNIX epoch time - mediantime: number; // (numeric) The median block time expressed in UNIX epoch time - nonce: number; // (numeric) The nonce - bits: string; // (string) The bits - difficulty: number; // (numeric) The difficulty - chainwork: string; // (string) Expected number of hashes required to produce the chain up to this block (in hex) - nTx: number; // (numeric) The number of transactions in the block - previousblockhash: string; // (string) The hash of the previous block - nextblockhash: string; // (string) The hash of the next block - } - - export interface Transaction { - in_active_chain: boolean; // (boolean) Whether specified block is in the active chain or not - hex: string; // (string) The serialized, hex-encoded data for 'txid' - txid: string; // (string) The transaction id (same as provided) - hash: string; // (string) The transaction hash (differs from txid for witness transactions) - size: number; // (numeric) The serialized transaction size - vsize: number; // (numeric) The virtual transaction size (differs from size for witness transactions) - weight: number; // (numeric) The transaction's weight (between vsize*4-3 and vsize*4) - version: number; // (numeric) The version - locktime: number; // (numeric) The lock time - vin: Vin[]; - vout: Vout[]; - blockhash: string; // (string) the block hash - confirmations: number; // (numeric) The confirmations - blocktime: number; // (numeric) The block time expressed in UNIX epoch time - time: number; // (numeric) Same as blocktime - } - - export interface VerboseBlock extends Block { - tx: VerboseTransaction[]; // The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 "tx" result - } - - export interface VerboseTransaction extends Transaction { - fee?: number; // (numeric) The transaction fee in BTC, omitted if block undo data is not available - } - - export interface Vin { - txid?: string; // (string) The transaction id - vout?: number; // (string) - scriptSig?: { // (json object) The script - asm: string; // (string) asm - hex: string; // (string) hex - }; - sequence: number; // (numeric) The script sequence number - txinwitness?: string[]; // (string) hex-encoded witness data - coinbase?: string; - is_pegin?: boolean; // (boolean) Elements peg-in - } - - export interface Vout { - value: number; // (numeric) The value in BTC - n: number; // (numeric) index - asset?: string; // (string) Elements asset id - scriptPubKey: { // (json object) - asm: string; // (string) the asm - hex: string; // (string) the hex - reqSigs?: number; // (numeric) The required sigs - type: string; // (string) The type, eg 'pubkeyhash' - address?: string; // (string) bitcoin address - addresses?: string[]; // (string) bitcoin addresses - pegout_chain?: string; // (string) Elements peg-out chain - pegout_addresses?: string[]; // (string) Elements peg-out addresses - }; - } - - export interface AddressInformation { - isvalid: boolean; // (boolean) If the address is valid or not. If not, this is the only property returned. - isvalid_parent?: boolean; // (boolean) Elements only - address: string; // (string) The bitcoin address validated - scriptPubKey: string; // (string) The hex-encoded scriptPubKey generated by the address - isscript: boolean; // (boolean) If the key is a script - iswitness: boolean; // (boolean) If the address is a witness - witness_version?: number; // (numeric, optional) The version number of the witness program - witness_program: string; // (string, optional) The hex value of the witness program - confidential_key?: string; // (string) Elements only - unconfidential?: string; // (string) Elements only - } - - export interface ChainTips { - height: number; // (numeric) height of the chain tip - hash: string; // (string) block hash of the tip - branchlen: number; // (numeric) zero for main chain, otherwise length of branch connecting the tip to the main chain - status: 'invalid' | 'headers-only' | 'valid-headers' | 'valid-fork' | 'active'; - } - - export interface BlockchainInfo { - chain: number; // (string) current network name as defined in BIP70 (main, test, regtest) - blocks: number; // (numeric) the current number of blocks processed in the server - headers: number; // (numeric) the current number of headers we have validated - bestblockhash: string, // (string) the hash of the currently best block - difficulty: number; // (numeric) the current difficulty - mediantime: number; // (numeric) median time for the current best block - verificationprogress: number; // (numeric) estimate of verification progress [0..1] - initialblockdownload: boolean; // (bool) (debug information) estimate of whether this node is in Initial Block Download mode. - chainwork: string // (string) total amount of work in active chain, in hexadecimal - size_on_disk: number; // (numeric) the estimated size of the block and undo files on disk - pruned: number; // (boolean) if the blocks are subject to pruning - pruneheight: number; // (numeric) lowest-height complete block stored (only present if pruning is enabled) - automatic_pruning: number; // (boolean) whether automatic pruning is enabled (only present if pruning is enabled) - prune_target_size: number; // (numeric) the target size used by pruning (only present if automatic pruning is enabled) - softforks: SoftFork[]; // (array) status of softforks in progress - bip9_softforks: { [name: string]: Bip9SoftForks[] } // (object) status of BIP9 softforks in progress - warnings: string; // (string) any network and blockchain warnings. - } - - interface SoftFork { - id: string; // (string) name of softfork - version: number; // (numeric) block version - reject: { // (object) progress toward rejecting pre-softfork blocks - status: boolean; // (boolean) true if threshold reached - }, - } - interface Bip9SoftForks { - status: number; // (string) one of defined, started, locked_in, active, failed - bit: number; // (numeric) the bit (0-28) in the block version field used to signal this softfork (only for started status) - startTime: number; // (numeric) the minimum median time past of a block at which the bit gains its meaning - timeout: number; // (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in - since: number; // (numeric) height of the first block to which the status applies - statistics: { // (object) numeric statistics about BIP9 signalling for a softfork (only for started status) - period: number; // (numeric) the length in blocks of the BIP9 signalling period - threshold: number; // (numeric) the number of blocks with the version bit set required to activate the feature - elapsed: number; // (numeric) the number of blocks elapsed since the beginning of the current period - count: number; // (numeric) the number of blocks with the version bit set in the current period - possible: boolean; // (boolean) returns false if there are not enough blocks left in this period to pass activation threshold - } - } - -} diff --git a/lightning-backend/src/api/bitcoin/bitcoin-api.ts b/lightning-backend/src/api/bitcoin/bitcoin-api.ts deleted file mode 100644 index d8fa07e80..000000000 --- a/lightning-backend/src/api/bitcoin/bitcoin-api.ts +++ /dev/null @@ -1,313 +0,0 @@ -import * as bitcoinjs from 'bitcoinjs-lib'; -import { AbstractBitcoinApi } from './bitcoin-api-abstract-factory'; -import { IBitcoinApi } from './bitcoin-api.interface'; -import { IEsploraApi } from './esplora-api.interface'; - -class BitcoinApi implements AbstractBitcoinApi { - protected bitcoindClient: any; - - constructor(bitcoinClient: any) { - this.bitcoindClient = bitcoinClient; - } - - $getAddressPrefix(prefix: string): string[] { - throw new Error('Method not implemented.'); - } - - $getBlock(hash: string): Promise { - throw new Error('Method not implemented.'); - } - - $getRawTransaction(txId: string, skipConversion = false, addPrevout = false, lazyPrevouts = false): Promise { - return this.bitcoindClient.getRawTransaction(txId, true) - .then((transaction: IBitcoinApi.Transaction) => { - if (skipConversion) { - transaction.vout.forEach((vout) => { - vout.value = Math.round(vout.value * 100000000); - }); - return transaction; - } - return this.$convertTransaction(transaction, addPrevout, lazyPrevouts); - }) - .catch((e: Error) => { - throw e; - }); - } - - $getBlockHeightTip(): Promise { - return this.bitcoindClient.getChainTips() - .then((result: IBitcoinApi.ChainTips[]) => { - return result.find(tip => tip.status === 'active')!.height; - }); - } - - $getTxIdsForBlock(hash: string): Promise { - return this.bitcoindClient.getBlock(hash, 1) - .then((rpcBlock: IBitcoinApi.Block) => rpcBlock.tx); - } - - $getRawBlock(hash: string): Promise { - return this.bitcoindClient.getBlock(hash, 0); - } - - $getBlockHash(height: number): Promise { - return this.bitcoindClient.getBlockHash(height); - } - - $getBlockHeader(hash: string): Promise { - return this.bitcoindClient.getBlockHeader(hash, false); - } - - $getAddress(address: string): Promise { - throw new Error('Method getAddress not supported by the Bitcoin RPC API.'); - } - - $getAddressTransactions(address: string, lastSeenTxId: string): Promise { - throw new Error('Method getAddressTransactions not supported by the Bitcoin RPC API.'); - } - - $getRawMempool(): Promise { - return this.bitcoindClient.getRawMemPool(); - } - - $sendRawTransaction(rawTransaction: string): Promise { - return this.bitcoindClient.sendRawTransaction(rawTransaction); - } - - async $getOutspend(txId: string, vout: number): Promise { - const txOut = await this.bitcoindClient.getTxOut(txId, vout, false); - return { - spent: txOut === null, - status: { - confirmed: true, - } - }; - } - - async $getOutspends(txId: string): Promise { - const outSpends: IEsploraApi.Outspend[] = []; - const tx = await this.$getRawTransaction(txId, true, false); - for (let i = 0; i < tx.vout.length; i++) { - if (tx.status && tx.status.block_height === 0) { - outSpends.push({ - spent: false - }); - } else { - const txOut = await this.bitcoindClient.getTxOut(txId, i); - outSpends.push({ - spent: txOut === null, - }); - } - } - return outSpends; - } - - async $getBatchedOutspends(txId: string[]): Promise { - const outspends: IEsploraApi.Outspend[][] = []; - for (const tx of txId) { - const outspend = await this.$getOutspends(tx); - outspends.push(outspend); - } - return outspends; - } - - $getEstimatedHashrate(blockHeight: number): Promise { - // 120 is the default block span in Core - return this.bitcoindClient.getNetworkHashPs(120, blockHeight); - } - - protected async $convertTransaction(transaction: IBitcoinApi.Transaction, addPrevout: boolean, lazyPrevouts = false): Promise { - let esploraTransaction: IEsploraApi.Transaction = { - txid: transaction.txid, - version: transaction.version, - locktime: transaction.locktime, - size: transaction.size, - weight: transaction.weight, - fee: 0, - vin: [], - vout: [], - status: { confirmed: false }, - }; - - esploraTransaction.vout = transaction.vout.map((vout) => { - return { - value: Math.round(vout.value * 100000000), - scriptpubkey: vout.scriptPubKey.hex, - scriptpubkey_address: vout.scriptPubKey && vout.scriptPubKey.address ? vout.scriptPubKey.address - : vout.scriptPubKey.addresses ? vout.scriptPubKey.addresses[0] : '', - scriptpubkey_asm: vout.scriptPubKey.asm ? this.convertScriptSigAsm(vout.scriptPubKey.hex) : '', - scriptpubkey_type: this.translateScriptPubKeyType(vout.scriptPubKey.type), - }; - }); - - // @ts-ignore - esploraTransaction.vin = transaction.vin.map((vin) => { - return { - is_coinbase: !!vin.coinbase, - prevout: null, - scriptsig: vin.scriptSig && vin.scriptSig.hex || vin.coinbase || '', - scriptsig_asm: vin.scriptSig && this.convertScriptSigAsm(vin.scriptSig.hex) || '', - sequence: vin.sequence, - txid: vin.txid || '', - vout: vin.vout || 0, - witness: vin.txinwitness, - }; - }); - - if (transaction.confirmations) { - esploraTransaction.status = { - confirmed: true, - block_height: -1, - block_hash: transaction.blockhash, - block_time: transaction.blocktime, - }; - } - - if (addPrevout) { - esploraTransaction = await this.$calculateFeeFromInputs(esploraTransaction, false, lazyPrevouts); - } else if (!transaction.confirmations) { - // esploraTransaction = await this.$appendMempoolFeeData(esploraTransaction); - } - - return esploraTransaction; - } - - private translateScriptPubKeyType(outputType: string): string { - const map = { - 'pubkey': 'p2pk', - 'pubkeyhash': 'p2pkh', - 'scripthash': 'p2sh', - 'witness_v0_keyhash': 'v0_p2wpkh', - 'witness_v0_scripthash': 'v0_p2wsh', - 'witness_v1_taproot': 'v1_p2tr', - 'nonstandard': 'nonstandard', - 'multisig': 'multisig', - 'nulldata': 'op_return' - }; - - if (map[outputType]) { - return map[outputType]; - } else { - return 'unknown'; - } - } - - private async $calculateFeeFromInputs(transaction: IEsploraApi.Transaction, addPrevout: boolean, lazyPrevouts: boolean): Promise { - if (transaction.vin[0].is_coinbase) { - transaction.fee = 0; - return transaction; - } - let totalIn = 0; - - for (let i = 0; i < transaction.vin.length; i++) { - if (lazyPrevouts && i > 12) { - transaction.vin[i].lazy = true; - continue; - } - const innerTx = await this.$getRawTransaction(transaction.vin[i].txid, false, false); - transaction.vin[i].prevout = innerTx.vout[transaction.vin[i].vout]; - this.addInnerScriptsToVin(transaction.vin[i]); - totalIn += innerTx.vout[transaction.vin[i].vout].value; - } - if (lazyPrevouts && transaction.vin.length > 12) { - transaction.fee = -1; - } else { - const totalOut = transaction.vout.reduce((p, output) => p + output.value, 0); - transaction.fee = parseFloat((totalIn - totalOut).toFixed(8)); - } - return transaction; - } - - private convertScriptSigAsm(hex: string): string { - const buf = Buffer.from(hex, 'hex'); - - const b: string[] = []; - - let i = 0; - while (i < buf.length) { - const op = buf[i]; - if (op >= 0x01 && op <= 0x4e) { - i++; - let push: number; - if (op === 0x4c) { - push = buf.readUInt8(i); - b.push('OP_PUSHDATA1'); - i += 1; - } else if (op === 0x4d) { - push = buf.readUInt16LE(i); - b.push('OP_PUSHDATA2'); - i += 2; - } else if (op === 0x4e) { - push = buf.readUInt32LE(i); - b.push('OP_PUSHDATA4'); - i += 4; - } else { - push = op; - b.push('OP_PUSHBYTES_' + push); - } - - const data = buf.slice(i, i + push); - if (data.length !== push) { - break; - } - - b.push(data.toString('hex')); - i += data.length; - } else { - if (op === 0x00) { - b.push('OP_0'); - } else if (op === 0x4f) { - b.push('OP_PUSHNUM_NEG1'); - } else if (op === 0xb1) { - b.push('OP_CLTV'); - } else if (op === 0xb2) { - b.push('OP_CSV'); - } else if (op === 0xba) { - b.push('OP_CHECKSIGADD'); - } else { - const opcode = bitcoinjs.script.toASM([ op ]); - if (opcode && op < 0xfd) { - if (/^OP_(\d+)$/.test(opcode)) { - b.push(opcode.replace(/^OP_(\d+)$/, 'OP_PUSHNUM_$1')); - } else { - b.push(opcode); - } - } else { - b.push('OP_RETURN_' + op); - } - } - i += 1; - } - } - - return b.join(' '); - } - - private addInnerScriptsToVin(vin: IEsploraApi.Vin): void { - if (!vin.prevout) { - return; - } - - if (vin.prevout.scriptpubkey_type === 'p2sh') { - const redeemScript = vin.scriptsig_asm.split(' ').reverse()[0]; - vin.inner_redeemscript_asm = this.convertScriptSigAsm(redeemScript); - if (vin.witness && vin.witness.length > 2) { - const witnessScript = vin.witness[vin.witness.length - 1]; - vin.inner_witnessscript_asm = this.convertScriptSigAsm(witnessScript); - } - } - - if (vin.prevout.scriptpubkey_type === 'v0_p2wsh' && vin.witness) { - const witnessScript = vin.witness[vin.witness.length - 1]; - vin.inner_witnessscript_asm = this.convertScriptSigAsm(witnessScript); - } - - if (vin.prevout.scriptpubkey_type === 'v1_p2tr' && vin.witness && vin.witness.length > 1) { - const witnessScript = vin.witness[vin.witness.length - 2]; - vin.inner_witnessscript_asm = this.convertScriptSigAsm(witnessScript); - } - } - -} - -export default BitcoinApi; diff --git a/lightning-backend/src/api/bitcoin/bitcoin-client.ts b/lightning-backend/src/api/bitcoin/bitcoin-client.ts deleted file mode 100644 index 43e76a041..000000000 --- a/lightning-backend/src/api/bitcoin/bitcoin-client.ts +++ /dev/null @@ -1,12 +0,0 @@ -import config from '../../config'; -const bitcoin = require('./rpc-api/index'); - -const nodeRpcCredentials: any = { - host: config.CORE_RPC.HOST, - port: config.CORE_RPC.PORT, - user: config.CORE_RPC.USERNAME, - pass: config.CORE_RPC.PASSWORD, - timeout: 60000, -}; - -export default new bitcoin.Client(nodeRpcCredentials); diff --git a/lightning-backend/src/api/bitcoin/esplora-api.interface.ts b/lightning-backend/src/api/bitcoin/esplora-api.interface.ts deleted file mode 100644 index 39f8cfd6f..000000000 --- a/lightning-backend/src/api/bitcoin/esplora-api.interface.ts +++ /dev/null @@ -1,172 +0,0 @@ -export namespace IEsploraApi { - export interface Transaction { - txid: string; - version: number; - locktime: number; - size: number; - weight: number; - fee: number; - vin: Vin[]; - vout: Vout[]; - status: Status; - hex?: string; - } - - export interface Recent { - txid: string; - fee: number; - vsize: number; - value: number; - } - - export interface Vin { - txid: string; - vout: number; - is_coinbase: boolean; - scriptsig: string; - scriptsig_asm: string; - inner_redeemscript_asm: string; - inner_witnessscript_asm: string; - sequence: any; - witness: string[]; - prevout: Vout | null; - // Elements - is_pegin?: boolean; - issuance?: Issuance; - // Custom - lazy?: boolean; - } - - interface Issuance { - asset_id: string; - is_reissuance: string; - asset_blinding_nonce: string; - asset_entropy: string; - contract_hash: string; - assetamount?: number; - assetamountcommitment?: string; - tokenamount?: number; - tokenamountcommitment?: string; - } - - export interface Vout { - scriptpubkey: string; - scriptpubkey_asm: string; - scriptpubkey_type: string; - scriptpubkey_address: string; - value: number; - // Elements - valuecommitment?: number; - asset?: string; - pegout?: Pegout; - } - - interface Pegout { - genesis_hash: string; - scriptpubkey: string; - scriptpubkey_asm: string; - scriptpubkey_address: string; - } - - export interface Status { - confirmed: boolean; - block_height?: number; - block_hash?: string; - block_time?: number; - } - - export interface Block { - id: string; - height: number; - version: number; - timestamp: number; - bits: number; - nonce: number; - difficulty: number; - merkle_root: string; - tx_count: number; - size: number; - weight: number; - previousblockhash: string; - } - - export interface Address { - address: string; - chain_stats: ChainStats; - mempool_stats: MempoolStats; - electrum?: boolean; - } - - export interface ChainStats { - funded_txo_count: number; - funded_txo_sum: number; - spent_txo_count: number; - spent_txo_sum: number; - tx_count: number; - } - - export interface MempoolStats { - funded_txo_count: number; - funded_txo_sum: number; - spent_txo_count: number; - spent_txo_sum: number; - tx_count: number; - } - - export interface Outspend { - spent: boolean; - txid?: string; - vin?: number; - status?: Status; - } - - export interface Asset { - asset_id: string; - issuance_txin: IssuanceTxin; - issuance_prevout: IssuancePrevout; - reissuance_token: string; - contract_hash: string; - status: Status; - chain_stats: AssetStats; - mempool_stats: AssetStats; - } - - export interface AssetExtended extends Asset { - name: string; - ticker: string; - precision: number; - entity: Entity; - version: number; - issuer_pubkey: string; - } - - export interface Entity { - domain: string; - } - - interface IssuanceTxin { - txid: string; - vin: number; - } - - interface IssuancePrevout { - txid: string; - vout: number; - } - - interface AssetStats { - tx_count: number; - issuance_count: number; - issued_amount: number; - burned_amount: number; - has_blinded_issuances: boolean; - reissuance_tokens: number; - burned_reissuance_tokens: number; - peg_in_count: number; - peg_in_amount: number; - peg_out_count: number; - peg_out_amount: number; - burn_count: number; - } - -} diff --git a/lightning-backend/src/api/bitcoin/esplora-api.ts b/lightning-backend/src/api/bitcoin/esplora-api.ts deleted file mode 100644 index 6ed48a0f8..000000000 --- a/lightning-backend/src/api/bitcoin/esplora-api.ts +++ /dev/null @@ -1,84 +0,0 @@ -import config from '../../config'; -import axios, { AxiosRequestConfig } from 'axios'; -import { AbstractBitcoinApi } from './bitcoin-api-abstract-factory'; -import { IEsploraApi } from './esplora-api.interface'; - -class ElectrsApi implements AbstractBitcoinApi { - axiosConfig: AxiosRequestConfig = { - timeout: 10000, - }; - - constructor() { } - - $getRawMempool(): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/mempool/txids', this.axiosConfig) - .then((response) => response.data); - } - - $getRawTransaction(txId: string): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/tx/' + txId, this.axiosConfig) - .then((response) => response.data); - } - - $getBlockHeightTip(): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/blocks/tip/height', this.axiosConfig) - .then((response) => response.data); - } - - $getTxIdsForBlock(hash: string): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/block/' + hash + '/txids', this.axiosConfig) - .then((response) => response.data); - } - - $getBlockHash(height: number): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/block-height/' + height, this.axiosConfig) - .then((response) => response.data); - } - - $getBlockHeader(hash: string): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/block/' + hash + '/header', this.axiosConfig) - .then((response) => response.data); - } - - $getBlock(hash: string): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/block/' + hash, this.axiosConfig) - .then((response) => response.data); - } - - $getAddress(address: string): Promise { - throw new Error('Method getAddress not implemented.'); - } - - $getAddressTransactions(address: string, txId?: string): Promise { - throw new Error('Method getAddressTransactions not implemented.'); - } - - $getAddressPrefix(prefix: string): string[] { - throw new Error('Method not implemented.'); - } - - $sendRawTransaction(rawTransaction: string): Promise { - throw new Error('Method not implemented.'); - } - - $getOutspend(txId: string, vout: number): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/tx/' + txId + '/outspend/' + vout, this.axiosConfig) - .then((response) => response.data); - } - - $getOutspends(txId: string): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/tx/' + txId + '/outspends', this.axiosConfig) - .then((response) => response.data); - } - - async $getBatchedOutspends(txId: string[]): Promise { - const outspends: IEsploraApi.Outspend[][] = []; - for (const tx of txId) { - const outspend = await this.$getOutspends(tx); - outspends.push(outspend); - } - return outspends; - } -} - -export default ElectrsApi; diff --git a/lightning-backend/src/api/bitcoin/rpc-api/commands.ts b/lightning-backend/src/api/bitcoin/rpc-api/commands.ts deleted file mode 100644 index ea9bd7bf0..000000000 --- a/lightning-backend/src/api/bitcoin/rpc-api/commands.ts +++ /dev/null @@ -1,92 +0,0 @@ -module.exports = { - addMultiSigAddress: 'addmultisigaddress', - addNode: 'addnode', // bitcoind v0.8.0+ - backupWallet: 'backupwallet', - createMultiSig: 'createmultisig', - createRawTransaction: 'createrawtransaction', // bitcoind v0.7.0+ - decodeRawTransaction: 'decoderawtransaction', // bitcoind v0.7.0+ - decodeScript: 'decodescript', - dumpPrivKey: 'dumpprivkey', - dumpWallet: 'dumpwallet', // bitcoind v0.9.0+ - encryptWallet: 'encryptwallet', - estimateFee: 'estimatefee', // bitcoind v0.10.0x - estimatePriority: 'estimatepriority', // bitcoind v0.10.0+ - generate: 'generate', // bitcoind v0.11.0+ - getAccount: 'getaccount', - getAccountAddress: 'getaccountaddress', - getAddedNodeInfo: 'getaddednodeinfo', // bitcoind v0.8.0+ - getAddressesByAccount: 'getaddressesbyaccount', - getBalance: 'getbalance', - getBestBlockHash: 'getbestblockhash', // bitcoind v0.9.0+ - getBlock: 'getblock', - getBlockStats: 'getblockstats', - getBlockFilter: 'getblockfilter', - getBlockchainInfo: 'getblockchaininfo', // bitcoind v0.9.2+ - getBlockCount: 'getblockcount', - getBlockHash: 'getblockhash', - getBlockHeader: 'getblockheader', - getBlockTemplate: 'getblocktemplate', // bitcoind v0.7.0+ - getChainTips: 'getchaintips', // bitcoind v0.10.0+ - getChainTxStats: 'getchaintxstats', - getConnectionCount: 'getconnectioncount', - getDifficulty: 'getdifficulty', - getGenerate: 'getgenerate', - getInfo: 'getinfo', - getMempoolAncestors: 'getmempoolancestors', - getMempoolDescendants: 'getmempooldescendants', - getMempoolEntry: 'getmempoolentry', - getMempoolInfo: 'getmempoolinfo', // bitcoind v0.10+ - getMiningInfo: 'getmininginfo', - getNetTotals: 'getnettotals', - getNetworkInfo: 'getnetworkinfo', // bitcoind v0.9.2+ - getNetworkHashPs: 'getnetworkhashps', // bitcoind v0.9.0+ - getNewAddress: 'getnewaddress', - getPeerInfo: 'getpeerinfo', // bitcoind v0.7.0+ - getRawChangeAddress: 'getrawchangeaddress', // bitcoin v0.9+ - getRawMemPool: 'getrawmempool', // bitcoind v0.7.0+ - getRawTransaction: 'getrawtransaction', // bitcoind v0.7.0+ - getReceivedByAccount: 'getreceivedbyaccount', - getReceivedByAddress: 'getreceivedbyaddress', - getTransaction: 'gettransaction', - getTxOut: 'gettxout', // bitcoind v0.7.0+ - getTxOutProof: 'gettxoutproof', // bitcoind v0.11.0+ - getTxOutSetInfo: 'gettxoutsetinfo', // bitcoind v0.7.0+ - getUnconfirmedBalance: 'getunconfirmedbalance', // bitcoind v0.9.0+ - getWalletInfo: 'getwalletinfo', // bitcoind v0.9.2+ - help: 'help', - importAddress: 'importaddress', // bitcoind v0.10.0+ - importPrivKey: 'importprivkey', - importWallet: 'importwallet', // bitcoind v0.9.0+ - keypoolRefill: 'keypoolrefill', - keyPoolRefill: 'keypoolrefill', - listAccounts: 'listaccounts', - listAddressGroupings: 'listaddressgroupings', // bitcoind v0.7.0+ - listLockUnspent: 'listlockunspent', // bitcoind v0.8.0+ - listReceivedByAccount: 'listreceivedbyaccount', - listReceivedByAddress: 'listreceivedbyaddress', - listSinceBlock: 'listsinceblock', - listTransactions: 'listtransactions', - listUnspent: 'listunspent', // bitcoind v0.7.0+ - lockUnspent: 'lockunspent', // bitcoind v0.8.0+ - move: 'move', - ping: 'ping', // bitcoind v0.9.0+ - prioritiseTransaction: 'prioritisetransaction', // bitcoind v0.10.0+ - sendFrom: 'sendfrom', - sendMany: 'sendmany', - sendRawTransaction: 'sendrawtransaction', // bitcoind v0.7.0+ - sendToAddress: 'sendtoaddress', - setAccount: 'setaccount', - setGenerate: 'setgenerate', - setTxFee: 'settxfee', - signMessage: 'signmessage', - signRawTransaction: 'signrawtransaction', // bitcoind v0.7.0+ - stop: 'stop', - submitBlock: 'submitblock', // bitcoind v0.7.0+ - validateAddress: 'validateaddress', - verifyChain: 'verifychain', // bitcoind v0.9.0+ - verifyMessage: 'verifymessage', - verifyTxOutProof: 'verifytxoutproof', // bitcoind v0.11.0+ - walletLock: 'walletlock', - walletPassphrase: 'walletpassphrase', - walletPassphraseChange: 'walletpassphrasechange' -} diff --git a/lightning-backend/src/api/bitcoin/rpc-api/index.ts b/lightning-backend/src/api/bitcoin/rpc-api/index.ts deleted file mode 100644 index 131e1a048..000000000 --- a/lightning-backend/src/api/bitcoin/rpc-api/index.ts +++ /dev/null @@ -1,61 +0,0 @@ -var commands = require('./commands') -var rpc = require('./jsonrpc') - -// ===----------------------------------------------------------------------===// -// JsonRPC -// ===----------------------------------------------------------------------===// -function Client (opts) { - // @ts-ignore - this.rpc = new rpc.JsonRPC(opts) -} - -// ===----------------------------------------------------------------------===// -// cmd -// ===----------------------------------------------------------------------===// -Client.prototype.cmd = function () { - var args = [].slice.call(arguments) - var cmd = args.shift() - - callRpc(cmd, args, this.rpc) -} - -// ===----------------------------------------------------------------------===// -// callRpc -// ===----------------------------------------------------------------------===// -function callRpc (cmd, args, rpc) { - var fn = args[args.length - 1] - - // If the last argument is a callback, pop it from the args list - if (typeof fn === 'function') { - args.pop() - } else { - fn = function () {} - } - - return rpc.call(cmd, args, function () { - var args = [].slice.call(arguments) - // @ts-ignore - args.unshift(null) - // @ts-ignore - fn.apply(this, args) - }, function (err) { - fn(err) - }) -} - -// ===----------------------------------------------------------------------===// -// Initialize wrappers -// ===----------------------------------------------------------------------===// -(function () { - for (var protoFn in commands) { - (function (protoFn) { - Client.prototype[protoFn] = function () { - var args = [].slice.call(arguments) - return callRpc(commands[protoFn], args, this.rpc) - } - })(protoFn) - } -})() - -// Export! -module.exports.Client = Client; diff --git a/lightning-backend/src/api/bitcoin/rpc-api/jsonrpc.ts b/lightning-backend/src/api/bitcoin/rpc-api/jsonrpc.ts deleted file mode 100644 index 4f7a38baa..000000000 --- a/lightning-backend/src/api/bitcoin/rpc-api/jsonrpc.ts +++ /dev/null @@ -1,162 +0,0 @@ -var http = require('http') -var https = require('https') - -var JsonRPC = function (opts) { - // @ts-ignore - this.opts = opts || {} - // @ts-ignore - this.http = this.opts.ssl ? https : http -} - -JsonRPC.prototype.call = function (method, params) { - return new Promise((resolve, reject) => { - var time = Date.now() - var requestJSON - - if (Array.isArray(method)) { - // multiple rpc batch call - requestJSON = [] - method.forEach(function (batchCall, i) { - requestJSON.push({ - id: time + '-' + i, - method: batchCall.method, - params: batchCall.params - }) - }) - } else { - // single rpc call - requestJSON = { - id: time, - method: method, - params: params - } - } - - // First we encode the request into JSON - requestJSON = JSON.stringify(requestJSON) - - // prepare request options - var requestOptions = { - host: this.opts.host || 'localhost', - port: this.opts.port || 8332, - method: 'POST', - path: '/', - headers: { - 'Host': this.opts.host || 'localhost', - 'Content-Length': requestJSON.length - }, - agent: false, - rejectUnauthorized: this.opts.ssl && this.opts.sslStrict !== false - } - - if (this.opts.ssl && this.opts.sslCa) { - // @ts-ignore - requestOptions.ca = this.opts.sslCa - } - - // use HTTP auth if user and password set - if (this.opts.user && this.opts.pass) { - // @ts-ignore - requestOptions.auth = this.opts.user + ':' + this.opts.pass - } - - // Now we'll make a request to the server - var cbCalled = false - var request = this.http.request(requestOptions) - - // start request timeout timer - var reqTimeout = setTimeout(function () { - if (cbCalled) return - cbCalled = true - request.abort() - var err = new Error('ETIMEDOUT') - // @ts-ignore - err.code = 'ETIMEDOUT' - reject(err) - }, this.opts.timeout || 30000) - - // set additional timeout on socket in case of remote freeze after sending headers - request.setTimeout(this.opts.timeout || 30000, function () { - if (cbCalled) return - cbCalled = true - request.abort() - var err = new Error('ESOCKETTIMEDOUT') - // @ts-ignore - err.code = 'ESOCKETTIMEDOUT' - reject(err) - }) - - request.on('error', function (err) { - if (cbCalled) return - cbCalled = true - clearTimeout(reqTimeout) - reject(err) - }) - - request.on('response', function (response) { - clearTimeout(reqTimeout) - - // We need to buffer the response chunks in a nonblocking way. - var buffer = '' - response.on('data', function (chunk) { - buffer = buffer + chunk - }) - // When all the responses are finished, we decode the JSON and - // depending on whether it's got a result or an error, we call - // emitSuccess or emitError on the promise. - response.on('end', function () { - var err - - if (cbCalled) return - cbCalled = true - - try { - var decoded = JSON.parse(buffer) - } catch (e) { - if (response.statusCode !== 200) { - err = new Error('Invalid params, response status code: ' + response.statusCode) - err.code = -32602 - reject(err) - } else { - err = new Error('Problem parsing JSON response from server') - err.code = -32603 - reject(err) - } - return - } - - if (!Array.isArray(decoded)) { - decoded = [decoded] - } - - // iterate over each response, normally there will be just one - // unless a batch rpc call response is being processed - decoded.forEach(function (decodedResponse, i) { - if (decodedResponse.hasOwnProperty('error') && decodedResponse.error != null) { - if (reject) { - err = new Error(decodedResponse.error.message || '') - if (decodedResponse.error.code) { - err.code = decodedResponse.error.code - } - reject(err) - } - } else if (decodedResponse.hasOwnProperty('result')) { - // @ts-ignore - resolve(decodedResponse.result, response.headers) - } else { - if (reject) { - err = new Error(decodedResponse.error.message || '') - if (decodedResponse.error.code) { - err.code = decodedResponse.error.code - } - reject(err) - } - } - }) - }) - }) - request.end(requestJSON); - }); -} - -module.exports.JsonRPC = JsonRPC diff --git a/lightning-backend/src/api/explorer/statistics.api.ts b/lightning-backend/src/api/explorer/statistics.api.ts deleted file mode 100644 index 620e76fef..000000000 --- a/lightning-backend/src/api/explorer/statistics.api.ts +++ /dev/null @@ -1,17 +0,0 @@ -import logger from '../../logger'; -import DB from '../../database'; - -class StatisticsApi { - public async $getStatistics(): Promise { - try { - const query = `SELECT UNIX_TIMESTAMP(added) AS added, channel_count, node_count, total_capacity FROM statistics ORDER BY id DESC`; - const [rows]: any = await DB.query(query); - return rows; - } catch (e) { - logger.err('$getStatistics error: ' + (e instanceof Error ? e.message : e)); - throw e; - } - } -} - -export default new StatisticsApi(); diff --git a/lightning-backend/src/config.ts b/lightning-backend/src/config.ts deleted file mode 100644 index df821f6fb..000000000 --- a/lightning-backend/src/config.ts +++ /dev/null @@ -1,110 +0,0 @@ -const configFile = require('../mempool-config.json'); - -interface IConfig { - MEMPOOL: { - NETWORK: 'mainnet' | 'testnet' | 'signet'; - BACKEND: 'lnd' | 'cln' | 'ldk'; - HTTP_PORT: number; - API_URL_PREFIX: string; - STDOUT_LOG_MIN_PRIORITY: 'emerg' | 'alert' | 'crit' | 'err' | 'warn' | 'notice' | 'info' | 'debug'; - }; - ESPLORA: { - REST_API_URL: string; - }; - SYSLOG: { - ENABLED: boolean; - HOST: string; - PORT: number; - MIN_PRIORITY: 'emerg' | 'alert' | 'crit' | 'err' | 'warn' | 'notice' | 'info' | 'debug'; - FACILITY: string; - }; - LN_NODE_AUTH: { - TLS_CERT_PATH: string; - MACAROON_PATH: string; - SOCKET: string; - }; - CORE_RPC: { - HOST: string; - PORT: number; - USERNAME: string; - PASSWORD: string; - }; - DATABASE: { - HOST: string, - SOCKET: string, - PORT: number; - DATABASE: string; - USERNAME: string; - PASSWORD: string; - }; -} - -const defaults: IConfig = { - 'MEMPOOL': { - 'NETWORK': 'mainnet', - 'BACKEND': 'lnd', - 'HTTP_PORT': 8999, - 'API_URL_PREFIX': '/api/v1/', - 'STDOUT_LOG_MIN_PRIORITY': 'debug', - }, - 'ESPLORA': { - 'REST_API_URL': 'http://127.0.0.1:3000', - }, - 'SYSLOG': { - 'ENABLED': true, - 'HOST': '127.0.0.1', - 'PORT': 514, - 'MIN_PRIORITY': 'info', - 'FACILITY': 'local7' - }, - 'LN_NODE_AUTH': { - 'TLS_CERT_PATH': '', - 'MACAROON_PATH': '', - 'SOCKET': 'localhost:10009', - }, - 'CORE_RPC': { - 'HOST': '127.0.0.1', - 'PORT': 8332, - 'USERNAME': 'mempool', - 'PASSWORD': 'mempool' - }, - 'DATABASE': { - 'HOST': '127.0.0.1', - 'SOCKET': '', - 'PORT': 3306, - 'DATABASE': 'mempool', - 'USERNAME': 'mempool', - 'PASSWORD': 'mempool' - }, -}; - -class Config implements IConfig { - MEMPOOL: IConfig['MEMPOOL']; - ESPLORA: IConfig['ESPLORA']; - SYSLOG: IConfig['SYSLOG']; - LN_NODE_AUTH: IConfig['LN_NODE_AUTH']; - CORE_RPC: IConfig['CORE_RPC']; - DATABASE: IConfig['DATABASE']; - - constructor() { - const configs = this.merge(configFile, defaults); - this.MEMPOOL = configs.MEMPOOL; - this.ESPLORA = configs.ESPLORA; - this.SYSLOG = configs.SYSLOG; - this.LN_NODE_AUTH = configs.LN_NODE_AUTH; - this.CORE_RPC = configs.CORE_RPC; - this.DATABASE = configs.DATABASE; - } - - merge = (...objects: object[]): IConfig => { - // @ts-ignore - return objects.reduce((prev, next) => { - Object.keys(prev).forEach(key => { - next[key] = { ...next[key], ...prev[key] }; - }); - return next; - }); - } -} - -export default new Config(); diff --git a/lightning-backend/src/database-migration.ts b/lightning-backend/src/database-migration.ts deleted file mode 100644 index ebf149ac9..000000000 --- a/lightning-backend/src/database-migration.ts +++ /dev/null @@ -1,260 +0,0 @@ -import config from './config'; -import DB from './database'; -import logger from './logger'; - -const sleep = (ms: number) => new Promise(res => setTimeout(res, ms)); - -class DatabaseMigration { - private static currentVersion = 1; - private queryTimeout = 120000; - - constructor() { } - /** - * Entry point - */ - public async $initializeOrMigrateDatabase(): Promise { - logger.debug('MIGRATIONS: Running migrations'); - - await this.$printDatabaseVersion(); - - // First of all, if the `state` database does not exist, create it so we can track migration version - if (!await this.$checkIfTableExists('state')) { - logger.debug('MIGRATIONS: `state` table does not exist. Creating it.'); - try { - await this.$createMigrationStateTable(); - } catch (e) { - logger.err('MIGRATIONS: Unable to create `state` table, aborting in 10 seconds. ' + e); - await sleep(10000); - process.exit(-1); - } - logger.debug('MIGRATIONS: `state` table initialized.'); - } - - let databaseSchemaVersion = 0; - try { - databaseSchemaVersion = await this.$getSchemaVersionFromDatabase(); - } catch (e) { - logger.err('MIGRATIONS: Unable to get current database migration version, aborting in 10 seconds. ' + e); - await sleep(10000); - process.exit(-1); - } - - logger.debug('MIGRATIONS: Current state.schema_version ' + databaseSchemaVersion); - logger.debug('MIGRATIONS: Latest DatabaseMigration.version is ' + DatabaseMigration.currentVersion); - if (databaseSchemaVersion >= DatabaseMigration.currentVersion) { - logger.debug('MIGRATIONS: Nothing to do.'); - return; - } - - // Now, create missing tables. Those queries cannot be wrapped into a transaction unfortunately - try { - await this.$createMissingTablesAndIndexes(databaseSchemaVersion); - } catch (e) { - logger.err('MIGRATIONS: Unable to create required tables, aborting in 10 seconds. ' + e); - await sleep(10000); - process.exit(-1); - } - - if (DatabaseMigration.currentVersion > databaseSchemaVersion) { - logger.notice('MIGRATIONS: Upgrading datababse schema'); - try { - await this.$migrateTableSchemaFromVersion(databaseSchemaVersion); - logger.notice(`MIGRATIONS: OK. Database schema have been migrated from version ${databaseSchemaVersion} to ${DatabaseMigration.currentVersion} (latest version)`); - } catch (e) { - logger.err('MIGRATIONS: Unable to migrate database, aborting. ' + e); - } - } - - return; - } - - /** - * Create all missing tables - */ - private async $createMissingTablesAndIndexes(databaseSchemaVersion: number) { - try { - await this.$executeQuery(this.getCreateStatisticsQuery(), await this.$checkIfTableExists('statistics')); - await this.$executeQuery(this.getCreateNodesQuery(), await this.$checkIfTableExists('nodes')); - await this.$executeQuery(this.getCreateChannelsQuery(), await this.$checkIfTableExists('channels')); - await this.$executeQuery(this.getCreateNodesStatsQuery(), await this.$checkIfTableExists('node_stats')); - } catch (e) { - throw e; - } - } - - /** - * Small query execution wrapper to log all executed queries - */ - private async $executeQuery(query: string, silent: boolean = false): Promise { - if (!silent) { - logger.debug('MIGRATIONS: Execute query:\n' + query); - } - return DB.query({ sql: query, timeout: this.queryTimeout }); - } - - /** - * Check if 'table' exists in the database - */ - private async $checkIfTableExists(table: string): Promise { - const query = `SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '${config.DATABASE.DATABASE}' AND TABLE_NAME = '${table}'`; - const [rows] = await DB.query({ sql: query, timeout: this.queryTimeout }); - return rows[0]['COUNT(*)'] === 1; - } - - /** - * Get current database version - */ - private async $getSchemaVersionFromDatabase(): Promise { - const query = `SELECT number FROM state WHERE name = 'schema_version';`; - const [rows] = await this.$executeQuery(query, true); - return rows[0]['number']; - } - - /** - * Create the `state` table - */ - private async $createMigrationStateTable(): Promise { - try { - const query = `CREATE TABLE IF NOT EXISTS state ( - name varchar(25) NOT NULL, - number int(11) NULL, - string varchar(100) NULL, - CONSTRAINT name_unique UNIQUE (name) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`; - await this.$executeQuery(query); - - // Set initial values - await this.$executeQuery(`INSERT INTO state VALUES('schema_version', 0, NULL);`); - await this.$executeQuery(`INSERT INTO state VALUES('last_node_stats', 0, '1970-01-01');`); - } catch (e) { - throw e; - } - } - - /** - * We actually execute the migrations queries here - */ - private async $migrateTableSchemaFromVersion(version: number): Promise { - const transactionQueries: string[] = []; - for (const query of this.getMigrationQueriesFromVersion(version)) { - transactionQueries.push(query); - } - transactionQueries.push(this.getUpdateToLatestSchemaVersionQuery()); - - try { - await this.$executeQuery('START TRANSACTION;'); - for (const query of transactionQueries) { - await this.$executeQuery(query); - } - await this.$executeQuery('COMMIT;'); - } catch (e) { - await this.$executeQuery('ROLLBACK;'); - throw e; - } - } - - /** - * Generate migration queries based on schema version - */ - private getMigrationQueriesFromVersion(version: number): string[] { - const queries: string[] = []; - return queries; - } - - /** - * Save the schema version in the database - */ - private getUpdateToLatestSchemaVersionQuery(): string { - return `UPDATE state SET number = ${DatabaseMigration.currentVersion} WHERE name = 'schema_version';`; - } - - /** - * Print current database version - */ - private async $printDatabaseVersion() { - try { - const [rows] = await this.$executeQuery('SELECT VERSION() as version;', true); - logger.debug(`MIGRATIONS: Database engine version '${rows[0].version}'`); - } catch (e) { - logger.debug(`MIGRATIONS: Could not fetch database engine version. ` + e); - } - } - - private getCreateStatisticsQuery(): string { - return `CREATE TABLE IF NOT EXISTS statistics ( - id int(11) NOT NULL AUTO_INCREMENT, - added datetime NOT NULL, - channel_count int(11) NOT NULL, - node_count int(11) NOT NULL, - total_capacity double unsigned NOT NULL, - PRIMARY KEY (id) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`; - } - - private getCreateNodesQuery(): string { - return `CREATE TABLE IF NOT EXISTS nodes ( - public_key varchar(66) NOT NULL, - first_seen datetime NOT NULL, - updated_at datetime NOT NULL, - alias varchar(200) CHARACTER SET utf8mb4 NOT NULL, - color varchar(200) NOT NULL, - sockets text DEFAULT NULL, - PRIMARY KEY (public_key), - KEY alias (alias(10)) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`; - } - - private getCreateChannelsQuery(): string { - return `CREATE TABLE IF NOT EXISTS channels ( - id bigint(11) unsigned NOT NULL, - short_id varchar(15) NOT NULL DEFAULT '', - capacity bigint(20) unsigned NOT NULL, - transaction_id varchar(64) NOT NULL, - transaction_vout int(11) NOT NULL, - updated_at datetime DEFAULT NULL, - created datetime DEFAULT NULL, - status int(11) NOT NULL DEFAULT 0, - closing_transaction_id varchar(64) DEFAULT NULL, - closing_date datetime DEFAULT NULL, - closing_reason int(11) DEFAULT NULL, - node1_public_key varchar(66) NOT NULL, - node1_base_fee_mtokens bigint(20) unsigned DEFAULT NULL, - node1_cltv_delta int(11) DEFAULT NULL, - node1_fee_rate bigint(11) DEFAULT NULL, - node1_is_disabled tinyint(1) DEFAULT NULL, - node1_max_htlc_mtokens bigint(20) unsigned DEFAULT NULL, - node1_min_htlc_mtokens bigint(20) DEFAULT NULL, - node1_updated_at datetime DEFAULT NULL, - node2_public_key varchar(66) NOT NULL, - node2_base_fee_mtokens bigint(20) unsigned DEFAULT NULL, - node2_cltv_delta int(11) DEFAULT NULL, - node2_fee_rate bigint(11) DEFAULT NULL, - node2_is_disabled tinyint(1) DEFAULT NULL, - node2_max_htlc_mtokens bigint(20) unsigned DEFAULT NULL, - node2_min_htlc_mtokens bigint(20) unsigned DEFAULT NULL, - node2_updated_at datetime DEFAULT NULL, - PRIMARY KEY (id), - KEY node1_public_key (node1_public_key), - KEY node2_public_key (node2_public_key), - KEY status (status), - KEY short_id (short_id), - KEY transaction_id (transaction_id), - KEY closing_transaction_id (closing_transaction_id) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`; - } - - private getCreateNodesStatsQuery(): string { - return `CREATE TABLE IF NOT EXISTS node_stats ( - id int(11) unsigned NOT NULL AUTO_INCREMENT, - public_key varchar(66) NOT NULL DEFAULT '', - added date NOT NULL, - capacity bigint(20) unsigned NOT NULL DEFAULT 0, - channels int(11) unsigned NOT NULL DEFAULT 0, - PRIMARY KEY (id), - UNIQUE KEY added (added,public_key), - KEY public_key (public_key) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`; - } -} - -export default new DatabaseMigration(); diff --git a/lightning-backend/src/database.ts b/lightning-backend/src/database.ts deleted file mode 100644 index 3816154cd..000000000 --- a/lightning-backend/src/database.ts +++ /dev/null @@ -1,51 +0,0 @@ -import config from './config'; -import { createPool, Pool, PoolConnection } from 'mysql2/promise'; -import logger from './logger'; -import { PoolOptions } from 'mysql2/typings/mysql'; - - class DB { - constructor() { - if (config.DATABASE.SOCKET !== '') { - this.poolConfig.socketPath = config.DATABASE.SOCKET; - } else { - this.poolConfig.host = config.DATABASE.HOST; - } - } - private pool: Pool | null = null; - private poolConfig: PoolOptions = { - port: config.DATABASE.PORT, - database: config.DATABASE.DATABASE, - user: config.DATABASE.USERNAME, - password: config.DATABASE.PASSWORD, - connectionLimit: 10, - supportBigNumbers: true, - timezone: '+00:00', - }; - - public async query(query, params?) { - const pool = await this.getPool(); - return pool.query(query, params); - } - - public async checkDbConnection() { - try { - await this.query('SELECT ?', [1]); - logger.info('Database connection established.'); - } catch (e) { - logger.err('Could not connect to database: ' + (e instanceof Error ? e.message : e)); - process.exit(1); - } - } - - private async getPool(): Promise { - if (this.pool === null) { - this.pool = createPool(this.poolConfig); - this.pool.on('connection', function (newConnection: PoolConnection) { - newConnection.query(`SET time_zone='+00:00'`); - }); - } - return this.pool; - } -} - -export default new DB(); diff --git a/lightning-backend/src/index.ts b/lightning-backend/src/index.ts deleted file mode 100644 index fc7a95f2d..000000000 --- a/lightning-backend/src/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -import DB from './database'; -import databaseMigration from './database-migration'; -import statsUpdater from './tasks/stats-updater.service'; -import nodeSyncService from './tasks/node-sync.service'; -import server from './server'; - -class LightningServer { - constructor() { - this.init(); - } - - async init() { - await DB.checkDbConnection(); - await databaseMigration.$initializeOrMigrateDatabase(); - - nodeSyncService.$startService(); - statsUpdater.$startService(); - - server.startServer(); - } -} - -const lightningServer = new LightningServer(); diff --git a/lightning-backend/src/logger.ts b/lightning-backend/src/logger.ts deleted file mode 100644 index 1e2c95ed1..000000000 --- a/lightning-backend/src/logger.ts +++ /dev/null @@ -1,145 +0,0 @@ -import config from './config'; -import * as dgram from 'dgram'; - -class Logger { - static priorities = { - emerg: 0, - alert: 1, - crit: 2, - err: 3, - warn: 4, - notice: 5, - info: 6, - debug: 7 - }; - static facilities = { - kern: 0, - user: 1, - mail: 2, - daemon: 3, - auth: 4, - syslog: 5, - lpr: 6, - news: 7, - uucp: 8, - local0: 16, - local1: 17, - local2: 18, - local3: 19, - local4: 20, - local5: 21, - local6: 22, - local7: 23 - }; - - // @ts-ignore - public emerg: ((msg: string) => void); - // @ts-ignore - public alert: ((msg: string) => void); - // @ts-ignore - public crit: ((msg: string) => void); - // @ts-ignore - public err: ((msg: string) => void); - // @ts-ignore - public warn: ((msg: string) => void); - // @ts-ignore - public notice: ((msg: string) => void); - // @ts-ignore - public info: ((msg: string) => void); - // @ts-ignore - public debug: ((msg: string) => void); - - private name = 'mempool'; - private client: dgram.Socket; - private network: string; - - constructor() { - let prio; - for (prio in Logger.priorities) { - if (true) { - this.addprio(prio); - } - } - this.client = dgram.createSocket('udp4'); - this.network = this.getNetwork(); - } - - private addprio(prio): void { - this[prio] = (function(_this) { - return function(msg) { - return _this.msg(prio, msg); - }; - })(this); - } - - private getNetwork(): string { - if (config.MEMPOOL.NETWORK && config.MEMPOOL.NETWORK !== 'mainnet') { - return config.MEMPOOL.NETWORK; - } - return ''; - } - - private msg(priority, msg) { - let consolemsg, prionum, syslogmsg; - if (typeof msg === 'string' && msg.length > 0) { - while (msg[msg.length - 1].charCodeAt(0) === 10) { - msg = msg.slice(0, msg.length - 1); - } - } - const network = this.network ? ' <' + this.network + '>' : ''; - prionum = Logger.priorities[priority] || Logger.priorities.info; - consolemsg = `${this.ts()} [${process.pid}] ${priority.toUpperCase()}:${network} ${msg}`; - - if (config.SYSLOG.ENABLED && Logger.priorities[priority] <= Logger.priorities[config.SYSLOG.MIN_PRIORITY]) { - syslogmsg = `<${(Logger.facilities[config.SYSLOG.FACILITY] * 8 + prionum)}> ${this.name}[${process.pid}]: ${priority.toUpperCase()}${network} ${msg}`; - this.syslog(syslogmsg); - } - if (Logger.priorities[priority] > Logger.priorities[config.MEMPOOL.STDOUT_LOG_MIN_PRIORITY]) { - return; - } - if (priority === 'warning') { - priority = 'warn'; - } - if (priority === 'debug') { - priority = 'info'; - } - if (priority === 'err') { - priority = 'error'; - } - return (console[priority] || console.error)(consolemsg); - } - - private syslog(msg) { - let msgbuf; - msgbuf = Buffer.from(msg); - this.client.send(msgbuf, 0, msgbuf.length, config.SYSLOG.PORT, config.SYSLOG.HOST, function(err, bytes) { - if (err) { - console.log(err); - } - }); - } - - private leadZero(n: number): number | string { - if (n < 10) { - return '0' + n; - } - return n; - } - - private ts() { - let day, dt, hours, minutes, month, months, seconds; - dt = new Date(); - hours = this.leadZero(dt.getHours()); - minutes = this.leadZero(dt.getMinutes()); - seconds = this.leadZero(dt.getSeconds()); - month = dt.getMonth(); - day = dt.getDate(); - if (day < 10) { - day = ' ' + day; - } - months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; - return months[month] + ' ' + day + ' ' + hours + ':' + minutes + ':' + seconds; - } -} - -export default new Logger(); diff --git a/lightning-backend/src/server.ts b/lightning-backend/src/server.ts deleted file mode 100644 index afee2e070..000000000 --- a/lightning-backend/src/server.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Express, Request, Response, NextFunction } from 'express'; -import * as express from 'express'; -import * as http from 'http'; -import logger from './logger'; -import config from './config'; -import generalRoutes from './api/explorer/general.routes'; -import nodesRoutes from './api/explorer/nodes.routes'; -import channelsRoutes from './api/explorer/channels.routes'; - -class Server { - private server: http.Server | undefined; - private app: Express = express(); - - public startServer() { - this.app - .use((req: Request, res: Response, next: NextFunction) => { - res.setHeader('Access-Control-Allow-Origin', '*'); - next(); - }) - .use(express.urlencoded({ extended: true })) - .use(express.text()) - ; - - this.server = http.createServer(this.app); - - this.server.listen(config.MEMPOOL.HTTP_PORT, () => { - logger.notice(`Mempool Lightning is running on port ${config.MEMPOOL.HTTP_PORT}`); - }); - - this.initRoutes(); - } - - private initRoutes() { - generalRoutes.initRoutes(this.app); - nodesRoutes.initRoutes(this.app); - channelsRoutes.initRoutes(this.app); - } -} - -export default new Server(); diff --git a/lightning-backend/tsconfig.json b/lightning-backend/tsconfig.json deleted file mode 100644 index 8b4cbea2e..000000000 --- a/lightning-backend/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "target": "esnext", - "lib": ["es2019", "dom"], - "strict": true, - "noImplicitAny": false, - "sourceMap": false, - "outDir": "dist", - "moduleResolution": "node", - "typeRoots": [ - "node_modules/@types" - ], - "allowSyntheticDefaultImports": true - }, - "include": [ - "src/**/*.ts" - ], - "exclude": [ - "dist/**" - ] -} \ No newline at end of file diff --git a/lightning-backend/tslint.json b/lightning-backend/tslint.json deleted file mode 100644 index 945512322..000000000 --- a/lightning-backend/tslint.json +++ /dev/null @@ -1,137 +0,0 @@ -{ - "rules": { - "arrow-return-shorthand": true, - "callable-types": true, - "class-name": true, - "comment-format": [ - true, - "check-space" - ], - "curly": true, - "deprecation": { - "severity": "warn" - }, - "eofline": true, - "forin": false, - "import-blacklist": [ - true, - "rxjs", - "rxjs/Rx" - ], - "import-spacing": true, - "indent": [ - true, - "spaces" - ], - "interface-over-type-literal": true, - "label-position": true, - "max-line-length": [ - true, - 140 - ], - "member-access": false, - "member-ordering": [ - true, - { - "order": [ - "static-field", - "instance-field", - "static-method", - "instance-method" - ] - } - ], - "no-arg": true, - "no-bitwise": true, - "no-console": [ - true, - "debug", - "info", - "time", - "timeEnd", - "trace" - ], - "no-construct": true, - "no-debugger": true, - "no-duplicate-super": true, - "no-empty": false, - "no-empty-interface": true, - "no-eval": true, - "no-inferrable-types": false, - "no-misused-new": true, - "no-non-null-assertion": true, - "no-shadowed-variable": true, - "no-string-literal": false, - "no-string-throw": true, - "no-switch-case-fall-through": true, - "no-trailing-whitespace": true, - "no-unnecessary-initializer": true, - "no-unused-expression": true, - "no-use-before-declare": true, - "no-var-keyword": true, - "object-literal-sort-keys": false, - "one-line": [ - true, - "check-open-brace", - "check-catch", - "check-else", - "check-whitespace" - ], - "prefer-const": true, - "quotemark": [ - true, - "single" - ], - "radix": true, - "semicolon": [ - true, - "always" - ], - "triple-equals": [ - true, - "allow-null-check" - ], - "typedef-whitespace": [ - true, - { - "call-signature": "nospace", - "index-signature": "nospace", - "parameter": "nospace", - "property-declaration": "nospace", - "variable-declaration": "nospace" - } - ], - "unified-signatures": true, - "variable-name": false, - "whitespace": [ - true, - "check-branch", - "check-decl", - "check-operator", - "check-separator", - "check-type" - ], - "directive-selector": [ - true, - "attribute", - "app", - "camelCase" - ], - "component-selector": [ - true, - "element", - "app", - "kebab-case" - ], - "no-output-on-prefix": true, - "use-input-property-decorator": true, - "use-output-property-decorator": true, - "use-host-property-decorator": true, - "no-input-rename": true, - "no-output-rename": true, - "use-life-cycle-interface": true, - "use-pipe-transform-interface": true, - "component-class-suffix": true, - "directive-class-suffix": true - } -}