Umbrel support (#141)
* Don't require BTC core connection * Docker: Don't clone, but use local repo * Add GitHub workflows * Allow to overwrite hostname * chore: update dependencies * Get tor URL from env
This commit is contained in:
parent
76b289b652
commit
f0493d595f
@ -3,7 +3,7 @@
|
||||
"plugins": [
|
||||
"prettier"
|
||||
],
|
||||
"extends": ["prettier"],
|
||||
"extends": ["plugin:prettier/recommended"],
|
||||
"rules": {
|
||||
"prettier/prettier": [
|
||||
"warn",
|
||||
|
54
.github/workflows/push.yml
vendored
Normal file
54
.github/workflows/push.yml
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
name: Build on push
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
env:
|
||||
DOCKER_CLI_EXPERIMENTAL: enabled
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build image
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform:
|
||||
- linux/amd64
|
||||
- linux/arm64
|
||||
steps:
|
||||
- name: Checkout project
|
||||
uses: actions/checkout@v2
|
||||
|
||||
|
||||
- name: Set env variables
|
||||
run: echo "BRANCH=$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//-/g')" >> $GITHUB_ENV
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
id: qemu
|
||||
|
||||
- name: Setup Docker buildx action
|
||||
uses: docker/setup-buildx-action@v1
|
||||
id: buildx
|
||||
|
||||
- name: Show available Docker buildx platforms
|
||||
run: echo ${{ steps.buildx.outputs.platforms }}
|
||||
|
||||
|
||||
- name: Run Docker buildx
|
||||
run: |
|
||||
docker buildx build \
|
||||
--cache-from "type=local,src=/tmp/.buildx-cache" \
|
||||
--cache-to "type=local,dest=/tmp/.buildx-cache" \
|
||||
--platform ${{matrix.platform}} \
|
||||
--tag ${{ secrets.DOCKER_CONTAINER_USERNAME }}/lndhub:$BRANCH \
|
||||
--output "type=registry" ./
|
62
.github/workflows/tag.yml
vendored
Normal file
62
.github/workflows/tag.yml
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
name: Build on push
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v[0-9]+.[0-9]+.[0-9]+
|
||||
- v[0-9]+.[0-9]+.[0-9]+-*
|
||||
|
||||
env:
|
||||
DOCKER_CLI_EXPERIMENTAL: enabled
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build image
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform:
|
||||
- linux/amd64
|
||||
- linux/arm64
|
||||
steps:
|
||||
- name: Checkout project
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set env variables
|
||||
run: echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
id: qemu
|
||||
|
||||
- name: Setup Docker buildx action
|
||||
uses: docker/setup-buildx-action@v1
|
||||
id: buildx
|
||||
|
||||
- name: Show available Docker buildx platforms
|
||||
run: echo ${{ steps.buildx.outputs.platforms }}
|
||||
|
||||
|
||||
- name: Run Docker buildx
|
||||
run: |
|
||||
docker buildx build \
|
||||
--cache-from "type=local,src=/tmp/.buildx-cache" \
|
||||
--cache-to "type=local,dest=/tmp/.buildx-cache" \
|
||||
--platform ${{matrix.platform}} \
|
||||
--tag ${{ secrets.DOCKER_CONTAINER_USERNAME }}/lndhub:$TAG \
|
||||
--output "type=registry" ./
|
||||
- name: Run Docker buildx
|
||||
run: |
|
||||
docker buildx build \
|
||||
--cache-from "type=local,src=/tmp/.buildx-cache" \
|
||||
--cache-to "type=local,dest=/tmp/.buildx-cache" \
|
||||
--platform ${{matrix.platform}} \
|
||||
--tag ${{ secrets.DOCKER_CONTAINER_USERNAME }}/lndhub:latest \
|
||||
--output "type=registry" ./
|
23
Dockerfile
23
Dockerfile
@ -6,19 +6,26 @@ RUN adduser --disabled-password \
|
||||
--gecos "" \
|
||||
"lndhub"
|
||||
|
||||
FROM node:buster-slim AS builder
|
||||
FROM node:12-buster-slim AS builder
|
||||
|
||||
# These packages are required for building LNDHub
|
||||
RUN apt-get update && apt-get -y install git python3
|
||||
|
||||
# TODO: Switch to official images once my PR is merged
|
||||
RUN git clone https://github.com/AaronDewes/LndHub.git -b update-dependencies /lndhub
|
||||
RUN apt-get update && apt-get -y install python3
|
||||
|
||||
WORKDIR /lndhub
|
||||
|
||||
# Copy 'package-lock.json' and 'package.json'
|
||||
COPY package.json package-lock.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm i
|
||||
|
||||
FROM node:buster-slim
|
||||
# Copy project files and folders to the current working directory
|
||||
COPY . .
|
||||
|
||||
# Delete git data as it's not needed inside the container
|
||||
RUN rm -rf .git
|
||||
|
||||
FROM node:12-buster-slim
|
||||
|
||||
# Create a specific user so LNDHub doesn't run as root
|
||||
COPY --from=perms /etc/group /etc/passwd /etc/shadow /etc/
|
||||
@ -26,12 +33,8 @@ COPY --from=perms /etc/group /etc/passwd /etc/shadow /etc/
|
||||
# Copy LNDHub with installed modules from builder
|
||||
COPY --from=builder /lndhub /lndhub
|
||||
|
||||
# Delete git data as it's not needed inside the container
|
||||
RUN rm -rf .git
|
||||
|
||||
# Create logs folder and ensure permissions are set correctly
|
||||
RUN mkdir /lndhub/logs && chown -R lndhub:lndhub /lndhub
|
||||
|
||||
USER lndhub
|
||||
|
||||
ENV PORT=3000
|
||||
|
10
bitcoin.js
10
bitcoin.js
@ -2,6 +2,10 @@
|
||||
const config = require('./config');
|
||||
let jayson = require('jayson/promise');
|
||||
let url = require('url');
|
||||
let rpc = url.parse(config.bitcoind.rpc);
|
||||
rpc.timeout = 15000;
|
||||
module.exports = jayson.client.http(rpc);
|
||||
if (config.bitcoind) {
|
||||
let rpc = url.parse(config.bitcoind.rpc);
|
||||
rpc.timeout = 15000;
|
||||
module.exports = jayson.client.http(rpc);
|
||||
} else {
|
||||
module.exports = {};
|
||||
}
|
||||
|
79
btc-decoder.js
Normal file
79
btc-decoder.js
Normal file
@ -0,0 +1,79 @@
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
const classify = require('bitcoinjs-lib/src/classify');
|
||||
|
||||
const decodeFormat = (tx) => ({
|
||||
txid: tx.getId(),
|
||||
version: tx.version,
|
||||
locktime: tx.locktime,
|
||||
});
|
||||
|
||||
const decodeInput = function (tx) {
|
||||
const result = [];
|
||||
tx.ins.forEach(function (input, n) {
|
||||
result.push({
|
||||
txid: input.hash.reverse().toString('hex'),
|
||||
n: input.index,
|
||||
script: bitcoin.script.toASM(input.script),
|
||||
sequence: input.sequence,
|
||||
});
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
const decodeOutput = function (tx, network) {
|
||||
const format = function (out, n, network) {
|
||||
const vout = {
|
||||
satoshi: out.value,
|
||||
value: (1e-8 * out.value).toFixed(8),
|
||||
n: n,
|
||||
scriptPubKey: {
|
||||
asm: bitcoin.script.toASM(out.script),
|
||||
hex: out.script.toString('hex'),
|
||||
type: classify.output(out.script),
|
||||
addresses: [],
|
||||
},
|
||||
};
|
||||
switch (vout.scriptPubKey.type) {
|
||||
case 'pubkeyhash':
|
||||
case 'scripthash':
|
||||
vout.scriptPubKey.addresses.push(bitcoin.address.fromOutputScript(out.script, network));
|
||||
break;
|
||||
case 'witnesspubkeyhash':
|
||||
case 'witnessscripthash':
|
||||
const data = bitcoin.script.decompile(out.script)[1];
|
||||
vout.scriptPubKey.addresses.push(bitcoin.address.toBech32(data, 0, network.bech32));
|
||||
break;
|
||||
}
|
||||
return vout;
|
||||
};
|
||||
|
||||
const result = [];
|
||||
tx.outs.forEach(function (out, n) {
|
||||
result.push(format(out, n, network));
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
class TxDecoder {
|
||||
constructor(rawTx, network = bitcoin.networks.bitcoin) {
|
||||
this.tx = bitcoin.Transaction.fromHex(rawTx);
|
||||
this.format = decodeFormat(this.tx);
|
||||
this.inputs = decodeInput(this.tx);
|
||||
this.outputs = decodeOutput(this.tx, network);
|
||||
}
|
||||
|
||||
decode() {
|
||||
const result = {};
|
||||
const self = this;
|
||||
Object.keys(self.format).forEach(function (key) {
|
||||
result[key] = self.format[key];
|
||||
});
|
||||
result.outputs = self.outputs;
|
||||
result.inputs = self.inputs;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.decodeRawHex = (rawTx, network = bitcoin.networks.bitcoin) => {
|
||||
return new TxDecoder(rawTx, network).decode();
|
||||
};
|
@ -3,6 +3,8 @@ import { Lock } from './Lock';
|
||||
var crypto = require('crypto');
|
||||
var lightningPayReq = require('bolt11');
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import { decodeRawHex } from '../btc-decoder';
|
||||
const config = require('../config');
|
||||
|
||||
// static cache:
|
||||
let _invoice_ispaid_cache = {};
|
||||
@ -114,11 +116,11 @@ export class User {
|
||||
}
|
||||
|
||||
let self = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
self._lightning.newAddress({ type: 0 }, async function(err, response) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
self._lightning.newAddress({ type: 0 }, async function (err, response) {
|
||||
if (err) return reject('LND failure when trying to generate new address');
|
||||
await self.addAddress(response.address);
|
||||
self._bitcoindrpc.request('importaddress', [response.address, response.address, false]);
|
||||
if (config.bitcoind) self._bitcoindrpc.request('importaddress', [response.address, response.address, false]);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
@ -126,7 +128,7 @@ export class User {
|
||||
|
||||
async watchAddress(address) {
|
||||
if (!address) return;
|
||||
return this._bitcoindrpc.request('importaddress', [address, address, false]);
|
||||
if (config.bitcoind) return this._bitcoindrpc.request('importaddress', [address, address, false]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -304,7 +306,10 @@ export class User {
|
||||
_invoice_ispaid_cache[invoice.payment_hash] = paymentHashPaidAmountSat;
|
||||
}
|
||||
|
||||
invoice.amt = (paymentHashPaidAmountSat && parseInt(paymentHashPaidAmountSat) > decoded.satoshis) ? parseInt(paymentHashPaidAmountSat) : decoded.satoshis;
|
||||
invoice.amt =
|
||||
paymentHashPaidAmountSat && parseInt(paymentHashPaidAmountSat) > decoded.satoshis
|
||||
? parseInt(paymentHashPaidAmountSat)
|
||||
: decoded.satoshis;
|
||||
invoice.expire_time = 3600 * 24;
|
||||
// ^^^default; will keep for now. if we want to un-hardcode it - it should be among tags (`expire_time`)
|
||||
invoice.timestamp = decoded.timestamp;
|
||||
@ -326,12 +331,7 @@ export class User {
|
||||
* @returns {Promise<Array>}
|
||||
*/
|
||||
async getTxs() {
|
||||
let addr = await this.getAddress();
|
||||
if (!addr) {
|
||||
await this.generateAddress();
|
||||
addr = await this.getAddress();
|
||||
}
|
||||
if (!addr) throw new Error('cannot get transactions: no onchain address assigned to user');
|
||||
const addr = await this.getOrGenerateAddress();
|
||||
let txs = await this._listtransactions();
|
||||
txs = txs.result;
|
||||
let result = [];
|
||||
@ -402,17 +402,22 @@ export class User {
|
||||
}
|
||||
|
||||
try {
|
||||
let txs = await this._bitcoindrpc.request('listtransactions', ['*', 100500, 0, true]);
|
||||
// now, compacting response a bit
|
||||
let ret = { result: [] };
|
||||
for (const tx of txs.result) {
|
||||
ret.result.push({
|
||||
category: tx.category,
|
||||
amount: tx.amount,
|
||||
confirmations: tx.confirmations,
|
||||
address: tx.address,
|
||||
time: tx.time,
|
||||
});
|
||||
if (config.bitcoind) {
|
||||
let txs = await this._bitcoindrpc.request('listtransactions', ['*', 100500, 0, true]);
|
||||
// now, compacting response a bit
|
||||
for (const tx of txs.result) {
|
||||
ret.result.push({
|
||||
category: tx.category,
|
||||
amount: tx.amount,
|
||||
confirmations: tx.confirmations,
|
||||
address: tx.address,
|
||||
time: tx.time,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
let txs = await this._getChainTransactions();
|
||||
ret.result.push(...txs);
|
||||
}
|
||||
_listtransactions_cache = JSON.stringify(ret);
|
||||
_listtransactions_cache_expiry_ts = +new Date() + 5 * 60 * 1000; // 5 min
|
||||
@ -426,18 +431,42 @@ export class User {
|
||||
}
|
||||
}
|
||||
|
||||
async _getChainTransactions() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this._lightning.getTransactions({}, (err, data) => {
|
||||
if (err) return reject(err);
|
||||
const { transactions } = data;
|
||||
const outTxns = [];
|
||||
// on lightning incoming transactions have no labels
|
||||
// for now filter out known labels to reduce transactions
|
||||
transactions
|
||||
.filter((tx) => tx.label !== 'external' && !tx.label.includes('openchannel'))
|
||||
.map((tx) => {
|
||||
const decodedTx = decodeRawHex(tx.raw_tx_hex);
|
||||
decodedTx.outputs.forEach((vout) =>
|
||||
outTxns.push({
|
||||
// mark all as received, since external is filtered out
|
||||
category: 'receive',
|
||||
confirmations: tx.num_confirmations,
|
||||
amount: Number(vout.value),
|
||||
address: vout.scriptPubKey.addresses[0],
|
||||
time: tx.time_stamp,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
resolve(outTxns);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returning onchain txs for user's address that are less than 3 confs
|
||||
*
|
||||
* @returns {Promise<Array>}
|
||||
*/
|
||||
async getPendingTxs() {
|
||||
let addr = await this.getAddress();
|
||||
if (!addr) {
|
||||
await this.generateAddress();
|
||||
addr = await this.getAddress();
|
||||
}
|
||||
if (!addr) throw new Error('cannot get transactions: no onchain address assigned to user');
|
||||
const addr = await this.getOrGenerateAddress();
|
||||
let txs = await this._listtransactions();
|
||||
txs = txs.result;
|
||||
let result = [];
|
||||
@ -556,6 +585,16 @@ export class User {
|
||||
return result;
|
||||
}
|
||||
|
||||
async getOrGenerateAddress() {
|
||||
let addr = await this.getAddress();
|
||||
if (!addr) {
|
||||
await this.generateAddress();
|
||||
addr = await this.getAddress();
|
||||
}
|
||||
if (!addr) throw new Error('cannot get transactions: no onchain address assigned to user');
|
||||
return addr;
|
||||
}
|
||||
|
||||
_hash(string) {
|
||||
return crypto.createHash('sha256').update(string).digest().toString('hex');
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ const config = require('../config');
|
||||
let express = require('express');
|
||||
let router = express.Router();
|
||||
let logger = require('../utils/logger');
|
||||
const MIN_BTC_BLOCK = 670000;
|
||||
console.log('using config', JSON.stringify(config));
|
||||
|
||||
var Redis = require('ioredis');
|
||||
@ -19,17 +20,19 @@ let lightning = require('../lightning');
|
||||
let identity_pubkey = false;
|
||||
// ###################### SMOKE TESTS ########################
|
||||
|
||||
bitcoinclient.request('getblockchaininfo', false, function (err, info) {
|
||||
if (info && info.result && info.result.blocks) {
|
||||
if (info.result.chain === 'mainnet' && info.result.blocks < 550000) {
|
||||
console.error('bitcoind is not caught up');
|
||||
process.exit(1);
|
||||
if (config.bitcoind) {
|
||||
bitcoinclient.request('getblockchaininfo', false, function (err, info) {
|
||||
if (info && info.result && info.result.blocks) {
|
||||
if (info.result.chain === 'mainnet' && info.result.blocks < MIN_BTC_BLOCK && !config.forceStart) {
|
||||
console.error('bitcoind is not caught up');
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
console.error('bitcoind failure:', err, info);
|
||||
process.exit(2);
|
||||
}
|
||||
} else {
|
||||
console.error('bitcoind failure:', err, info);
|
||||
process.exit(2);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
lightning.getInfo({}, function (err, info) {
|
||||
if (err) {
|
||||
@ -39,7 +42,7 @@ lightning.getInfo({}, function (err, info) {
|
||||
}
|
||||
if (info) {
|
||||
console.info(info);
|
||||
if (!info.synced_to_chain) {
|
||||
if (!info.synced_to_chain && !config.forceStart) {
|
||||
console.error('lnd not synced');
|
||||
// process.exit(4);
|
||||
}
|
||||
@ -70,7 +73,10 @@ const subscribeInvoicesCallCallback = async function (response) {
|
||||
return;
|
||||
}
|
||||
let invoice = new Invo(redis, bitcoinclient, lightning);
|
||||
await invoice._setIsPaymentHashPaidInDatabase(LightningInvoiceSettledNotification.hash, LightningInvoiceSettledNotification.amt_paid_sat || 1);
|
||||
await invoice._setIsPaymentHashPaidInDatabase(
|
||||
LightningInvoiceSettledNotification.hash,
|
||||
LightningInvoiceSettledNotification.amt_paid_sat || 1,
|
||||
);
|
||||
const user = new User(redis, bitcoinclient, lightning);
|
||||
user._userid = await user.getUseridByPaymentHash(LightningInvoiceSettledNotification.hash);
|
||||
await user.clearBalanceCache();
|
||||
@ -469,7 +475,7 @@ router.get('/checkrouteinvoice', async function (req, res) {
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/queryroutes/:source/:dest/:amt', async function(req, res) {
|
||||
router.get('/queryroutes/:source/:dest/:amt', async function (req, res) {
|
||||
logger.log('/queryroutes', [req.id]);
|
||||
|
||||
let request = {
|
||||
@ -477,7 +483,7 @@ router.get('/queryroutes/:source/:dest/:amt', async function(req, res) {
|
||||
amt: req.params.amt,
|
||||
source_pub_key: req.params.source,
|
||||
};
|
||||
lightning.queryRoutes(request, function(err, response) {
|
||||
lightning.queryRoutes(request, function (err, response) {
|
||||
console.log(JSON.stringify(response, null, 2));
|
||||
res.send(response);
|
||||
});
|
||||
|
@ -1,10 +1,10 @@
|
||||
let express = require('express');
|
||||
let router = express.Router();
|
||||
let fs = require('fs');
|
||||
let mustache = require('mustache');
|
||||
let lightning = require('../lightning');
|
||||
let logger = require('../utils/logger');
|
||||
var qr = require('qr-image');
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const fs = require('fs');
|
||||
const mustache = require('mustache');
|
||||
const lightning = require('../lightning');
|
||||
const logger = require('../utils/logger');
|
||||
const qr = require('qr-image');
|
||||
|
||||
let lightningGetInfo = {};
|
||||
let lightningListChannels = {};
|
||||
@ -92,7 +92,11 @@ router.get('/', function (req, res) {
|
||||
});
|
||||
|
||||
router.get('/qr', function (req, res) {
|
||||
const url = "bluewallet:setlndhuburl?url=" + encodeURIComponent(req.protocol + '://' + req.headers.host);
|
||||
let host = req.headers.host;
|
||||
if (process.env.TOR_URL) {
|
||||
host = process.env.TOR_URL;
|
||||
}
|
||||
const url = 'bluewallet:setlndhuburl?url=' + encodeURIComponent(req.protocol + '://' + host);
|
||||
var code = qr.image(url, { type: 'png' });
|
||||
res.setHeader('Content-type', 'image/png');
|
||||
code.pipe(res);
|
||||
|
@ -8,7 +8,7 @@ const loaderOptions = {
|
||||
longs: String,
|
||||
enums: String,
|
||||
defaults: true,
|
||||
oneofs: true
|
||||
oneofs: true,
|
||||
};
|
||||
const packageDefinition = protoLoader.loadSync('rpc.proto', loaderOptions);
|
||||
var lnrpc = grpc.loadPackageDefinition(packageDefinition).lnrpc;
|
||||
|
8904
package-lock.json
generated
8904
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
29
package.json
29
package.json
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "LndHub",
|
||||
"name": "lndhub",
|
||||
"version": "1.2.2",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
@ -12,24 +12,25 @@
|
||||
"author": "Igor Korsakov <overtorment@gmail.com>",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/cli": "^7.12.10",
|
||||
"@babel/core": "^7.12.10",
|
||||
"@babel/eslint-parser": "^7.12.1",
|
||||
"@babel/node": "^7.12.10",
|
||||
"@babel/preset-env": "^7.12.11",
|
||||
"@babel/register": "^7.12.10",
|
||||
"@grpc/grpc-js": "^1.2.2",
|
||||
"@babel/cli": "^7.13.0",
|
||||
"@babel/core": "^7.13.1",
|
||||
"@babel/eslint-parser": "^7.13.4",
|
||||
"@babel/node": "^7.13.0",
|
||||
"@babel/preset-env": "^7.13.5",
|
||||
"@babel/register": "^7.13.0",
|
||||
"@grpc/grpc-js": "^1.2.8",
|
||||
"@grpc/proto-loader": "^0.5.6",
|
||||
"bignumber.js": "^9.0.1",
|
||||
"bitcoinjs-lib": "^5.2.0",
|
||||
"bolt11": "^1.2.7",
|
||||
"core-js": "^3.8.1",
|
||||
"eslint": "^7.19.0",
|
||||
"eslint-config-prettier": "^7.1.0",
|
||||
"eslint-plugin-prettier": "^3.3.0",
|
||||
"core-js": "^3.9.0",
|
||||
"eslint": "^7.20.0",
|
||||
"eslint-config-prettier": "^8.0.0",
|
||||
"eslint-plugin-prettier": "^3.3.1",
|
||||
"express": "^4.17.1",
|
||||
"express-rate-limit": "^5.2.3",
|
||||
"express-rate-limit": "^5.2.6",
|
||||
"frisbee": "^3.1.4",
|
||||
"ioredis": "^4.19.4",
|
||||
"ioredis": "^4.22.0",
|
||||
"jayson": "^3.4.4",
|
||||
"morgan": "^1.10.0",
|
||||
"mustache": "^4.1.0",
|
||||
|
@ -13,45 +13,45 @@ const important_channels = {
|
||||
name: 'coingate.com',
|
||||
uri: '0242a4ae0c5bef18048fbecf995094b74bfb0f7391418d71ed394784373f41e4f3@3.124.63.44:9735',
|
||||
},
|
||||
// '0254ff808f53b2f8c45e74b70430f336c6c76ba2f4af289f48d6086ae6e60462d3': {
|
||||
// name: 'bitrefill thor',
|
||||
// uri: '0254ff808f53b2f8c45e74b70430f336c6c76ba2f4af289f48d6086ae6e60462d3@52.30.63.2:9735',
|
||||
// wumbo: 1,
|
||||
// },
|
||||
// '0254ff808f53b2f8c45e74b70430f336c6c76ba2f4af289f48d6086ae6e60462d3': {
|
||||
// name: 'bitrefill thor',
|
||||
// uri: '0254ff808f53b2f8c45e74b70430f336c6c76ba2f4af289f48d6086ae6e60462d3@52.30.63.2:9735',
|
||||
// wumbo: 1,
|
||||
// },
|
||||
'030c3f19d742ca294a55c00376b3b355c3c90d61c6b6b39554dbc7ac19b141c14f': {
|
||||
name: 'bitrefill 2',
|
||||
uri: '030c3f19d742ca294a55c00376b3b355c3c90d61c6b6b39554dbc7ac19b141c14f@52.50.244.44:9735',
|
||||
wumbo: 1,
|
||||
},
|
||||
// '025f1456582e70c4c06b61d5c8ed3ce229e6d0db538be337a2dc6d163b0ebc05a5': {
|
||||
// name: 'paywithmoon.com',
|
||||
// uri: '025f1456582e70c4c06b61d5c8ed3ce229e6d0db538be337a2dc6d163b0ebc05a5@52.86.210.65:9735',
|
||||
// },
|
||||
// '0279c22ed7a068d10dc1a38ae66d2d6461e269226c60258c021b1ddcdfe4b00bc4': {
|
||||
// name: 'ln1.satoshilabs.com',
|
||||
// uri: '0279c22ed7a068d10dc1a38ae66d2d6461e269226c60258c021b1ddcdfe4b00bc4@157.230.28.160:9735',
|
||||
// },
|
||||
// '02004c625d622245606a1ea2c1c69cfb4516b703b47945a3647713c05fe4aaeb1c': {
|
||||
// name: 'LivingRoomOfSatoshi',
|
||||
// uri: '02004c625d622245606a1ea2c1c69cfb4516b703b47945a3647713c05fe4aaeb1c@172.81.178.151:9735',
|
||||
// },
|
||||
// '025f1456582e70c4c06b61d5c8ed3ce229e6d0db538be337a2dc6d163b0ebc05a5': {
|
||||
// name: 'paywithmoon.com',
|
||||
// uri: '025f1456582e70c4c06b61d5c8ed3ce229e6d0db538be337a2dc6d163b0ebc05a5@52.86.210.65:9735',
|
||||
// },
|
||||
// '0279c22ed7a068d10dc1a38ae66d2d6461e269226c60258c021b1ddcdfe4b00bc4': {
|
||||
// name: 'ln1.satoshilabs.com',
|
||||
// uri: '0279c22ed7a068d10dc1a38ae66d2d6461e269226c60258c021b1ddcdfe4b00bc4@157.230.28.160:9735',
|
||||
// },
|
||||
// '02004c625d622245606a1ea2c1c69cfb4516b703b47945a3647713c05fe4aaeb1c': {
|
||||
// name: 'LivingRoomOfSatoshi',
|
||||
// uri: '02004c625d622245606a1ea2c1c69cfb4516b703b47945a3647713c05fe4aaeb1c@172.81.178.151:9735',
|
||||
// },
|
||||
'02816caed43171d3c9854e3b0ab2cf0c42be086ff1bd4005acc2a5f7db70d83774': {
|
||||
name: 'ln.pizza aka fold',
|
||||
uri: '02816caed43171d3c9854e3b0ab2cf0c42be086ff1bd4005acc2a5f7db70d83774@35.238.153.25:9735',
|
||||
wumbo: 1,
|
||||
},
|
||||
// '0331f80652fb840239df8dc99205792bba2e559a05469915804c08420230e23c7c': {
|
||||
// name: 'LightningPowerUsers.com',
|
||||
// uri: '0331f80652fb840239df8dc99205792bba2e559a05469915804c08420230e23c7c@34.200.181.109:9735',
|
||||
// },
|
||||
// '033d8656219478701227199cbd6f670335c8d408a92ae88b962c49d4dc0e83e025': {
|
||||
// name: 'bfx-lnd0',
|
||||
// uri: '033d8656219478701227199cbd6f670335c8d408a92ae88b962c49d4dc0e83e025@34.65.85.39:9735',
|
||||
// },
|
||||
// '037f990e61acee8a7697966afd29dd88f3b1f8a7b14d625c4f8742bd952003a590': {
|
||||
// name: 'fixedfloat.com',
|
||||
// uri: '037f990e61acee8a7697966afd29dd88f3b1f8a7b14d625c4f8742bd952003a590@185.5.53.91:9735',
|
||||
// },
|
||||
// '0331f80652fb840239df8dc99205792bba2e559a05469915804c08420230e23c7c': {
|
||||
// name: 'LightningPowerUsers.com',
|
||||
// uri: '0331f80652fb840239df8dc99205792bba2e559a05469915804c08420230e23c7c@34.200.181.109:9735',
|
||||
// },
|
||||
// '033d8656219478701227199cbd6f670335c8d408a92ae88b962c49d4dc0e83e025': {
|
||||
// name: 'bfx-lnd0',
|
||||
// uri: '033d8656219478701227199cbd6f670335c8d408a92ae88b962c49d4dc0e83e025@34.65.85.39:9735',
|
||||
// },
|
||||
// '037f990e61acee8a7697966afd29dd88f3b1f8a7b14d625c4f8742bd952003a590': {
|
||||
// name: 'fixedfloat.com',
|
||||
// uri: '037f990e61acee8a7697966afd29dd88f3b1f8a7b14d625c4f8742bd952003a590@185.5.53.91:9735',
|
||||
// },
|
||||
'03c2abfa93eacec04721c019644584424aab2ba4dff3ac9bdab4e9c97007491dda': {
|
||||
name: 'tippin.me',
|
||||
uri: '03c2abfa93eacec04721c019644584424aab2ba4dff3ac9bdab4e9c97007491dda@157.245.68.47:9735',
|
||||
|
Loading…
Reference in New Issue
Block a user