add scoped credentials, fix issues in swap out, telegram

This commit is contained in:
Alex Bosworth 2020-10-17 09:09:06 -07:00
parent 631f3a4c77
commit ce05e7aaa2
No known key found for this signature in database
GPG key ID: E80D2F3F311FD87E
15 changed files with 422 additions and 509 deletions

View file

@ -1,5 +1,15 @@
# Versions
## Version 6.4.0
- `accounting`: Improve the speed and reduce the backend burden of getting payment records
- `credentials`: Allow exporting credentials without spending privileges: `--nospend`
- `credentials`: Allow exporting credentials with read-only privileges: `--readonly`
- `delete-payments-history`: Add "hidden" command to allow deleting all payment records
- `increase-inbound-liquidity`: Fix issue when attempting without a specified API key
- `telegram`: Improve automatic recovery in situations where errors are encountered
- `telegram`: Reveal unverified "from" public key when receiving keysends with invalid signatures
## Version 6.3.2
- `increase-inbound-liquidity`: Backup on-chain recovery to safeguard swap completion

24
bos
View file

@ -9,6 +9,7 @@ const {statSync} = require('fs');
const {unlink} = require('fs');
const {writeFile} = require('fs');
const {deletePayments} = require('ln-service');
const fetch = require('node-fetch');
const {findKey} = require('ln-sync');
const inquirer = require('inquirer');
@ -369,12 +370,14 @@ prog
});
})
// Export LND credentials from the standard
// Export LND credentials
.command('credentials', 'Export local credentials')
.help('Output encrypted remote access credentials. Use with "nodes --add"')
.option('--cleartext', 'Output remote access credentials without encryption')
.option('--days <days>', 'Expiration days for credentials', INT, 365)
.option('--node <node_name>', 'Get credentials for a saved node')
.option('--nospend', 'Credentials do not include spending privileges')
.option('--readonly', 'Credentials only include read permissions')
.action((args, options, logger) => {
return new Promise((resolve, reject) => {
return getCredentials({
@ -382,6 +385,8 @@ prog
ask: (n, cbk) => inquirer.prompt([n]).then(res => cbk(res)),
expire_days: options.days,
is_cleartext: options.cleartext,
is_nospend: options.nospend,
is_readonly: options.readonly,
node: options.node,
},
returnObject({logger, reject, resolve}));
@ -408,6 +413,23 @@ prog
});
})
// Delete all payments
.command('delete-payments-history', 'Delete all records of past payments')
.visible(false)
.option('--node <node_name>', 'Node to delete all past payments on')
.action((args, options, logger) => {
return new Promise(async (resolve, reject) => {
try {
return deletePayments({
lnd: (await authenticatedLnd({logger, node: options.node})).lnd,
},
returnObject({logger, reject, resolve}));
} catch (err) {
return reject(err);
}
});
})
// Encrypt a message
.command('encrypt', 'Encrypt data using the node key')
.visible(false)

View file

@ -1,7 +1,8 @@
const asyncAuto = require('async/auto');
const asyncMap = require('async/map');
const {getNode} = require('ln-service');
const {green} = require('colorette');
const {gray} = require('colorette');
const {greenBright} = require('colorette');
const {returnResult} = require('asyncjs-util');
const describeConfidence = require('./describe_confidence');
@ -90,22 +91,24 @@ module.exports = ({lnd, route}, cbk) => {
const path = route.hops.map((hop, i, hops) => {
const {alias} = getAliases.find(n => n.id === hop.public_key);
const {channel} = hop;
const isFinal = i === hops.length - 1;
const feeMtokens = !i ? hop.fee_mtokens : hops[i - 1].fee_mtokens;
const forwarder = `${alias} ${hop.public_key}`.trim();
const feeMtokens = isFinal ? hops[i-1].fee_mtokens : hop.fee_mtokens;
const forwarder = `${greenBright(alias)} ${hop.public_key}`.trim();
const feeRate = effectiveFeeRate(feeMtokens, hop.forward_mtokens);
const rate = formatFeeRate({rate: feeRate}).display;
const forward = `${green(forwarder)}. Hop fee rate ${rate}`;
const forward = `${forwarder}. Fee rate: ${rate}`;
if (!i) {
return [`${hop.channel} ${description || String()}`, forward];
return [`${gray(channel)} ${description || String()}`, forward];
} else if (i === hops.length - [i].length) {
return [`${hop.channel}`];
return [`${gray(channel)}`];
} else {
return [`${hop.channel}`, forward];
return [`${gray(channel)}`, forward];
}
});

28
lnd/constants.json Normal file
View file

@ -0,0 +1,28 @@
{
"noSpendPerms": [
"address:read",
"address:write",
"info:read",
"info:write",
"invoices:read",
"invoices:write",
"macaroon:read",
"message:read",
"offchain:read",
"onchain:read",
"peers:read",
"peers:write",
"signer:read"
],
"permissionEntities": [
"address",
"info",
"invoices",
"macaroon",
"message",
"offchain",
"onchain",
"peers",
"signer"
]
}

View file

@ -1,5 +1,6 @@
const asyncAuto = require('async/auto');
const {encode} = require('cbor');
const {grantAccess} = require('ln-service');
const moment = require('moment');
const {returnResult} = require('asyncjs-util');
@ -12,6 +13,8 @@ const {pemAsDer} = require('./../encryption');
ask: <Inquirer Function> ({message, name, type}, cbk) => {}
[expire_days]: <Expire Access in Days Number>
is_cleartext: <Export Clear Credential Components Bool>
is_nospend: <Restrict Credentials To Non-Spending Permissions Bool>
is_readonly: <Restrict Credentials To Read-Only Permissions Bool>
logger: <Winston Logger Object> ({info}) => ()
[node]: <Node Name String>
}
@ -75,6 +78,8 @@ module.exports = (args, cbk) => {
return lndCredentials({
expiry,
key,
is_nospend: args.is_nospend,
is_readonly: args.is_readonly,
logger: args.logger,
node: args.node,
},

View file

@ -6,6 +6,8 @@ const {readFile} = require('fs');
const {spawn} = require('child_process');
const asyncAuto = require('async/auto');
const {authenticatedLndGrpc} = require('ln-service');
const {grantAccess} = require('ln-service');
const {restrictMacaroon} = require('ln-service');
const {returnResult} = require('asyncjs-util');
@ -15,6 +17,8 @@ const getCert = require('./get_cert');
const getMacaroon = require('./get_macaroon');
const {getSavedCredentials} = require('./../nodes');
const getSocket = require('./get_socket');
const {noSpendPerms} = require('./constants');
const {permissionEntities} = require('./constants');
const config = 'config.json';
const defaultNodeName = process.env.BOS_DEFAULT_SAVED_NODE;
@ -22,12 +26,15 @@ const fs = {getFile: readFile};
const home = '.bos';
const os = {homedir, platform};
const {parse} = JSON;
const readPerms = permissionEntities.map(entity => `${entity}:read`);
const socket = 'localhost:10009';
/** LND credentials
{
[expiry]: <Credential Expiration Date ISO 8601 Date String>
[is_nospend]: <Restrict Credentials To Non-Spending Permissions Bool>
[is_readonly]: <Restrict Credentials To Read-Only Permissions Bool>
[key]: <Encrypt to Public Key DER Hex String>
[logger]: <Winston Logger Object>
[node]: <Node Name String> // Defaults to default local mainnet node creds
@ -42,13 +49,13 @@ const socket = 'localhost:10009';
socket: <Socket String>
}
*/
module.exports = ({expiry, logger, key, node}, cbk) => {
module.exports = (args, cbk) => {
return new Promise((resolve, reject) => {
return asyncAuto({
// Figure out which node the credentials are for
forNode: cbk => {
if (!!node) {
return cbk(null, node);
if (!!args.node) {
return cbk(null, args.node);
}
if (!!defaultNodeName) {
@ -129,8 +136,8 @@ module.exports = ({expiry, logger, key, node}, cbk) => {
const cipher = credentials.encrypted_macaroon;
if (!!logger) {
logger.info({decrypt_credentials_for: forNode});
if (!!args.logger) {
args.logger.info({decrypt_credentials_for: forNode});
}
return decryptCiphertext({cipher, spawn}, (err, res) => {
@ -172,37 +179,60 @@ module.exports = ({expiry, logger, key, node}, cbk) => {
// Macaroon with restriction
macaroon: ['credentials', ({credentials}, cbk) => {
if (!expiry) {
if (!args.expiry) {
return cbk(null, credentials.macaroon);
}
const {macaroon} = restrictMacaroon({
expires_at: expiry,
expires_at: args.expiry,
macaroon: credentials.macaroon,
});
return cbk(null, macaroon);
}],
// Get read-only macaroon if necessary
restrictMacaroon: [
'credentials',
'macaroon',
({credentials, macaroon}, cbk) =>
{
// Exit early when readonly credentials are not requested
if (!args.is_readonly && !args.is_nospend) {
return cbk(null, {macaroon});
}
const {lnd} = authenticatedLndGrpc({
macaroon,
cert: credentials.cert,
socket: credentials.socket,
});
const permissions = !!args.is_readonly ? readPerms : noSpendPerms;
return grantAccess({lnd, permissions}, cbk);
}],
// Final credentials with encryption applied
finalCredentials: [
'credentials',
'getSocket',
'macaroon',
({credentials, getSocket, macaroon}, cbk) =>
'restrictMacaroon',
({credentials, getSocket, restrictMacaroon}, cbk) =>
{
// Exit early when the credentials are not encrypted
if (!key) {
if (!args.key) {
return cbk(null, {
macaroon,
macaroon: restrictMacaroon.macaroon,
cert: credentials.cert,
socket: credentials.socket,
});
}
const macaroonData = Buffer.from(macaroon, 'base64');
const macaroonData = Buffer.from(restrictMacaroon.macaroon, 'base64');
const {pem} = derAsPem({key: args.key});
const encrypted = publicEncrypt(derAsPem({key}).pem, macaroonData);
const encrypted = publicEncrypt(pem, macaroonData);
return cbk(null, {
cert: credentials.cert,

View file

@ -6,6 +6,7 @@ const {subscribeToProbe} = require('ln-service');
const {subscribeToProbeForRoute} = require('ln-service');
const {describeConfidence} = require('./../display');
const {describeRoute} = require('./../display');
const {now} = Date;
const minutesAsMs = minutes => 1000 * 60 * minutes;
@ -192,51 +193,12 @@ module.exports = (args, cbk) => {
});
// Log probing attempts
sub.on('probing', ({route}) => {
sub.on('probing', async ({route}) => {
attemptedPaths.push(route);
return asyncMapSeries(route.hops, (hop, cbk) => {
return getNode({
is_omitting_channels: true,
lnd: args.lnd,
public_key: hop.public_key,
},
(err, node) => {
// Ignore errors, not all nodes may be in the graph
const alias = (!!err || !node || !node.alias) ? '' : node.alias;
const {description} = await describeRoute({route, lnd: args.lnd});
const towards = `${alias} ${hop.public_key}`;
return cbk(null, {towards, channel: hop.channel, fee: hop.fee});
});
},
(err, path) => {
if (!!err) {
return args.logger.error(err);
}
const {confidence} = route;
const {description} = describeConfidence({confidence});
const evaluating = path
.map((n, i) => {
const nextHop = path[i + 1];
if (!nextHop) {
return;
}
return `${n.channel} ${n.towards}. Hop fee: ${n.fee}`;
})
.filter(n => !!n);
return args.logger.info({
evaluating: !!evaluating.length ? evaluating : undefined,
confidence: description || undefined,
potential_fee: route.fee,
});
});
return args.logger.info({evaluating: description});
});
return;

View file

@ -35,6 +35,7 @@ const interrogationSeparator = ' and \n ';
const {isArray} = Array;
const isHex = n => !!n && !(n.length % 2) && /^[0-9A-F]*$/i.test(n);
const makeId = () => randomBytes(32).toString('hex');
const peerAddedDelayMs = 1000 * 5;
const per = (a, b) => (a / b).toFixed(2);
const times = 10;
const tokAsBigUnit = tokens => (tokens / 1e8).toFixed(8);
@ -208,7 +209,7 @@ module.exports = (args, cbk) => {
return cbk([503, 'FailedToConnectToPeer', ({peer: key})]);
}
return cbk(null, true);
return setTimeout(() => cbk(null, true), peerAddedDelayMs);
});
},
cbk);

598
package-lock.json generated
View file

@ -1,6 +1,6 @@
{
"name": "balanceofsatoshis",
"version": "6.3.2",
"version": "6.4.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -65,12 +65,12 @@
}
},
"@babel/generator": {
"version": "7.11.6",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.6.tgz",
"integrity": "sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA==",
"version": "7.12.1",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.1.tgz",
"integrity": "sha512-DB+6rafIdc9o72Yc3/Ph5h+6hUjeOp66pF0naQBgUFFuPqzQwIlPTm3xZR7YNvduIMtkDIj2t21LSQwnbCrXvg==",
"dev": true,
"requires": {
"@babel/types": "^7.11.5",
"@babel/types": "^7.12.1",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
},
@ -182,9 +182,9 @@
}
},
"@babel/parser": {
"version": "7.11.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz",
"integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==",
"version": "7.12.3",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.3.tgz",
"integrity": "sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw==",
"dev": true
},
"@babel/template": {
@ -199,17 +199,17 @@
}
},
"@babel/traverse": {
"version": "7.11.5",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.5.tgz",
"integrity": "sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==",
"version": "7.12.1",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.1.tgz",
"integrity": "sha512-MA3WPoRt1ZHo2ZmoGKNqi20YnPt0B1S0GTZEPhhd+hw2KGUzBlHuVunj6K4sNuK+reEvyiPwtp0cpaqLzJDmAw==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.10.4",
"@babel/generator": "^7.11.5",
"@babel/generator": "^7.12.1",
"@babel/helper-function-name": "^7.10.4",
"@babel/helper-split-export-declaration": "^7.11.0",
"@babel/parser": "^7.11.5",
"@babel/types": "^7.11.5",
"@babel/parser": "^7.12.1",
"@babel/types": "^7.12.1",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.19"
@ -233,9 +233,9 @@
}
},
"@babel/types": {
"version": "7.11.5",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz",
"integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==",
"version": "7.12.1",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.1.tgz",
"integrity": "sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.10.4",
@ -355,9 +355,9 @@
}
},
"@types/bytebuffer": {
"version": "5.0.41",
"resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.41.tgz",
"integrity": "sha512-Mdrv4YcaHvpkx25ksqqFaezktx3yZRcd51GZY0rY/9avyaqZdiT/GiWRhfrJhMpgzXqTOSHgGvsumGxJFNiZZA==",
"version": "5.0.42",
"resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.42.tgz",
"integrity": "sha512-lEgKojWUAc/MG2t649oZS5AfYFP2xRNPoDuwDBlBMjHXd8MaGPgFgtCXUK7inZdBOygmVf10qxc1Us8GXC96aw==",
"requires": {
"@types/long": "*",
"@types/node": "*"
@ -388,9 +388,9 @@
}
},
"ajv": {
"version": "6.12.5",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz",
"integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==",
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@ -1153,9 +1153,9 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
},
"chokidar": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz",
"integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==",
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz",
"integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==",
"dev": true,
"requires": {
"anymatch": "~3.1.1",
@ -1165,7 +1165,7 @@
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.4.0"
"readdirp": "~3.5.0"
}
},
"chownr": {
@ -1321,9 +1321,9 @@
}
},
"commander": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-6.1.0.tgz",
"integrity": "sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA=="
},
"commondir": {
"version": "1.0.1",
@ -1939,18 +1939,18 @@
"dev": true
},
"flow-parser": {
"version": "0.135.0",
"resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.135.0.tgz",
"integrity": "sha512-ev8SvmG+XU9D6WgHVezP4kY3Myr1tJvTUTEi7mbhhj+rn889K7YXdakte6oqXNLIJYJ2f5Fuw18zXTVa1NO8Kw==",
"version": "0.136.0",
"resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.136.0.tgz",
"integrity": "sha512-PB2vYAqmz+dRikpx8TpNgRtBsyemP+7oQa0BcPZWnGABlJlB2WgJc/Lx0HeEPOUxDO/TxBbPaIHsffEIL9M6BQ==",
"dev": true
},
"flow-remove-types": {
"version": "2.135.0",
"resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.135.0.tgz",
"integrity": "sha512-l/9INhkrrTD+91k35P0eiF94E1cOpjfd86WVVqRwQRjamjSwTKKgu7MDLel3DGmBB09I2AXv7IjacNiwt0yc1g==",
"version": "2.136.0",
"resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.136.0.tgz",
"integrity": "sha512-VLmnyCbIx2thjuyidNeAMltxzpFxpFtx+6b0pYlpDz4O338HZPziRSDd2ytpk0/xRFbGrys38pscbmW3UbZtJw==",
"dev": true,
"requires": {
"flow-parser": "^0.135.0",
"flow-parser": "^0.136.0",
"pirates": "^3.0.2",
"vlq": "^0.2.1"
}
@ -2129,6 +2129,28 @@
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
"integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ=="
},
"ln-service": {
"version": "49.14.0",
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-49.14.0.tgz",
"integrity": "sha512-01CoIfdo1vRQfc3siVGAZEDaKv3IrAwpjLLCtOa8aYxIwjQN+a7YC4GIBysbxiOaF0E+eZZIGz8Y76U7zWHhEQ==",
"requires": {
"@datastructures-js/priority-queue": "4.1.2",
"async": "3.2.0",
"asyncjs-util": "1.2.3",
"bitcoinjs-lib": "5.2.0",
"bn.js": "5.1.3",
"bolt07": "1.6.0",
"bolt09": "0.1.2",
"cors": "2.8.5",
"express": "4.17.1",
"invoices": "1.1.4",
"is-base64": "1.1.0",
"lightning": "2.0.54",
"macaroon": "3.0.4",
"morgan": "1.10.0",
"ws": "7.3.1"
}
}
}
},
@ -2958,11 +2980,11 @@
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
"json2csv": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json2csv/-/json2csv-5.0.1.tgz",
"integrity": "sha512-QFMifUX1y8W2tKi2TwZpnzf2rHdZvzdmgZUMEMDF46F90f4a9mUeWfx/qg4kzXSZYJYc3cWA5O+eLXk5lj9g8g==",
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/json2csv/-/json2csv-5.0.3.tgz",
"integrity": "sha512-e3gEZU/4fp8CVQMHlwT77RayAR7nylCzCYN7jTIbPTEqk0oTaE8GTcBudLgXrHt4ltOs9SAsbveMJT0YK/QUSg==",
"requires": {
"commander": "^5.0.0",
"commander": "^6.1.0",
"jsonparse": "^1.3.1",
"lodash.get": "^4.4.2"
}
@ -3043,33 +3065,6 @@
"psbt": "1.1.5"
},
"dependencies": {
"bn.js": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
"integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ=="
}
}
},
"ln-accounting": {
"version": "4.1.10",
"resolved": "https://registry.npmjs.org/ln-accounting/-/ln-accounting-4.1.10.tgz",
"integrity": "sha512-9PgMSZ06ZQE3jjGphVqgZ6zGOvsxLdSK/KJyPEra/0+/ggsf/96j/4df3GWq5Sqs3uvOWlAqU7xrkIupbMmokg==",
"requires": {
"async": "3.2.0",
"asyncjs-util": "1.2.3",
"goldengate": "7.0.2",
"json2csv": "5.0.1",
"ln-service": "49.10.0"
},
"dependencies": {
"@datastructures-js/priority-queue": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/@datastructures-js/priority-queue/-/priority-queue-4.1.1.tgz",
"integrity": "sha512-2i9+/23VjcJRZrPRoQtuQwL8lMy/FVoRTMurZAV+1x0lZxCJjUUo8m83SC0ndCycFmiNjxdWVns/vsHWtj4bpQ==",
"requires": {
"@datastructures-js/heap": "^2.0.0"
}
},
"bip174": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/bip174/-/bip174-1.0.1.tgz",
@ -3080,59 +3075,17 @@
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
"integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ=="
},
"bolt07": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/bolt07/-/bolt07-1.5.2.tgz",
"integrity": "sha512-P7LNOnBLtRYe0v30JvVR2xVvWWNrUt4IZ19njFRJb1NMhEx2xe+O0G7x4WZTWB7bHPAdkfR76l9F7jEVxizjlQ==",
"psbt": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/psbt/-/psbt-1.1.5.tgz",
"integrity": "sha512-NqVxxE78qG6dwnxpwR61niEaE5znUhOJOjjoGVsw4deX4OjE72py8wsEsCLuG7Yma7FsjhN58cmsMb2TqvoEGA==",
"requires": {
"bn.js": "5.1.2"
},
"dependencies": {
"bn.js": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz",
"integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA=="
}
}
},
"bolt09": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/bolt09/-/bolt09-0.1.1.tgz",
"integrity": "sha512-BX1LjpvU7qLyv8LRpYsq7p6fM2SiECWtfwjzx2/cStT0YFJhS74qFw5CfivoRz6ZEg3W7g1Exrv0tmDRkKeBkA=="
},
"goldengate": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/goldengate/-/goldengate-7.0.2.tgz",
"integrity": "sha512-ION2SoSTsePG9boPyREvPbH0f3bz9ZnYfUUaZsgPlEwj+od7+vGvHTQRdEvg3hl4Yod2U+gxNG7SpMHsY9Yuaw==",
"requires": {
"@grpc/proto-loader": "0.5.5",
"@mitmaro/http-authorization-header": "1.0.0",
"async": "3.2.0",
"asyncjs-util": "1.2.3",
"bip65": "1.0.3",
"bip68": "1.0.4",
"bip66": "1.1.5",
"bitcoin-ops": "1.4.1",
"bitcoinjs-lib": "5.2.0",
"bn.js": "5.1.3",
"cbor": "5.1.0",
"grpc": "1.24.3",
"ln-service": "49.10.0",
"macaroon": "3.0.4",
"bitcoinjs-lib": "5.1.10",
"bn.js": "5.1.2",
"pushdata-bitcoin": "1.0.1",
"varuint-bitcoin": "1.1.2"
}
},
"invoices": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/invoices/-/invoices-1.1.3.tgz",
"integrity": "sha512-+RZmDmgVXvn6hAzGUqdl+1q8lEm9Th5XO/yg2aAIHpxhBc+BrrdCaMjjsk+weoZp9jm6LA92Dt2bzo+4ou1SVw==",
"requires": {
"bech32": "1.1.4",
"bitcoinjs-lib": "5.1.10",
"bn.js": "5.1.3",
"bolt07": "1.5.2",
"bolt09": "0.1.1",
"secp256k1": "4.0.2"
},
"dependencies": {
"bitcoinjs-lib": {
@ -3156,13 +3109,37 @@
"varuint-bitcoin": "^1.0.4",
"wif": "^2.0.1"
}
},
"bn.js": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz",
"integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA=="
}
}
}
}
},
"ln-accounting": {
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/ln-accounting/-/ln-accounting-4.1.11.tgz",
"integrity": "sha512-3m6TAmzzhoti2Sshq4GZXOmYDsUu1j6leroTWP9kX1VvO6aYXKZmNhaL02xN64R+2toYeinZpISJWfxBhOJl+Q==",
"requires": {
"async": "3.2.0",
"asyncjs-util": "1.2.3",
"goldengate": "7.1.0",
"json2csv": "5.0.3",
"ln-service": "49.14.1"
},
"dependencies": {
"bn.js": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
"integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ=="
},
"lightning": {
"version": "2.0.44",
"resolved": "https://registry.npmjs.org/lightning/-/lightning-2.0.44.tgz",
"integrity": "sha512-Xi8C0FmxIZ1Pg23JlXRoXc7ELEtskiWI7jfcdr1oYWpVlNxUJKc4ALrUMofqo+EXaoHhtEvc6byyHtxuNl6iLw==",
"version": "2.0.55",
"resolved": "https://registry.npmjs.org/lightning/-/lightning-2.0.55.tgz",
"integrity": "sha512-BvO6UblGDT2qyKEmkyk6PizixtynzsCY6xMnnuM9/0DOMLh7qO+vdJzYGZCgFs5EzQUyghJf2urV045l9AwAnA==",
"requires": {
"@grpc/proto-loader": "0.5.5",
"async": "3.2.0",
@ -3170,31 +3147,32 @@
"bitcoinjs-lib": "5.2.0",
"bn.js": "5.1.3",
"body-parser": "1.19.0",
"bolt07": "1.5.2",
"bolt09": "0.1.1",
"bolt07": "1.6.0",
"bolt09": "0.1.2",
"cbor": "5.1.0",
"express": "4.17.1",
"grpc": "1.24.3",
"invoices": "1.1.3"
"invoices": "1.1.4",
"psbt": "1.1.6"
}
},
"ln-service": {
"version": "49.10.0",
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-49.10.0.tgz",
"integrity": "sha512-XK3gFc+Qowy9SquJ37UUktn61dlyoAR/4eN6eV2WPSY4DaSahZ/Xwe9j3ljXnZjTL5FClNzAfPwAhS/ljrgbhw==",
"version": "49.14.1",
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-49.14.1.tgz",
"integrity": "sha512-VvKMOhpnvPp8NvPbcS2pGk/UwyEZO8jzcbOtflCqLTTuClw7a4pEGQwpPeVCDTD6V+BGVOnZ75OL93OOw+/xuQ==",
"requires": {
"@datastructures-js/priority-queue": "4.1.1",
"@datastructures-js/priority-queue": "4.1.2",
"async": "3.2.0",
"asyncjs-util": "1.2.3",
"bitcoinjs-lib": "5.2.0",
"bn.js": "5.1.3",
"bolt07": "1.5.2",
"bolt09": "0.1.1",
"bolt07": "1.6.0",
"bolt09": "0.1.2",
"cors": "2.8.5",
"express": "4.17.1",
"invoices": "1.1.3",
"invoices": "1.1.4",
"is-base64": "1.1.0",
"lightning": "2.0.44",
"lightning": "2.0.55",
"macaroon": "3.0.4",
"morgan": "1.10.0",
"ws": "7.3.1"
@ -3203,9 +3181,9 @@
}
},
"ln-service": {
"version": "49.14.0",
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-49.14.0.tgz",
"integrity": "sha512-01CoIfdo1vRQfc3siVGAZEDaKv3IrAwpjLLCtOa8aYxIwjQN+a7YC4GIBysbxiOaF0E+eZZIGz8Y76U7zWHhEQ==",
"version": "49.14.2",
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-49.14.2.tgz",
"integrity": "sha512-ppLCXAcVl/xMbu+Be9qIyGw2Gzmb4yoeW63adGsTCk7iXxtYg4wl89krem5a8gD/iIIINvv8/Llh7CWXmlzHnQ==",
"requires": {
"@datastructures-js/priority-queue": "4.1.2",
"async": "3.2.0",
@ -3218,7 +3196,7 @@
"express": "4.17.1",
"invoices": "1.1.4",
"is-base64": "1.1.0",
"lightning": "2.0.54",
"lightning": "2.0.55",
"macaroon": "3.0.4",
"morgan": "1.10.0",
"ws": "7.3.1"
@ -3228,6 +3206,26 @@
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
"integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ=="
},
"lightning": {
"version": "2.0.55",
"resolved": "https://registry.npmjs.org/lightning/-/lightning-2.0.55.tgz",
"integrity": "sha512-BvO6UblGDT2qyKEmkyk6PizixtynzsCY6xMnnuM9/0DOMLh7qO+vdJzYGZCgFs5EzQUyghJf2urV045l9AwAnA==",
"requires": {
"@grpc/proto-loader": "0.5.5",
"async": "3.2.0",
"asyncjs-util": "1.2.3",
"bitcoinjs-lib": "5.2.0",
"bn.js": "5.1.3",
"body-parser": "1.19.0",
"bolt07": "1.6.0",
"bolt09": "0.1.2",
"cbor": "5.1.0",
"express": "4.17.1",
"grpc": "1.24.3",
"invoices": "1.1.4",
"psbt": "1.1.6"
}
}
}
},
@ -3273,145 +3271,29 @@
}
},
"ln-telegram": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/ln-telegram/-/ln-telegram-1.1.0.tgz",
"integrity": "sha512-BGW814yCavm/ghA8INX/5cbB977QOi3tp1jyv+u/9vNExaL42bwU1v6nyJZ9ZkyWpYu8HJGev08khzlaxPEC7Q==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/ln-telegram/-/ln-telegram-3.0.2.tgz",
"integrity": "sha512-ZoAG/c9KAwIgN7u4BYaHDWGp5L82NDDrcVyBx/KCdbPc8lT+JsPmhRYZNLcyId5/xmJjW0G4cWjg0WgPyWNSUA==",
"requires": {
"@alexbosworth/request": "2.88.3",
"async": "3.2.0",
"asyncjs-util": "1.2.3",
"goldengate": "7.0.2",
"goldengate": "7.1.0",
"invoices": "1.1.4",
"ln-service": "49.12.0",
"ln-service": "49.14.1",
"ln-sync": "0.3.0",
"table": "6.0.3"
},
"dependencies": {
"@datastructures-js/priority-queue": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/@datastructures-js/priority-queue/-/priority-queue-4.1.1.tgz",
"integrity": "sha512-2i9+/23VjcJRZrPRoQtuQwL8lMy/FVoRTMurZAV+1x0lZxCJjUUo8m83SC0ndCycFmiNjxdWVns/vsHWtj4bpQ==",
"requires": {
"@datastructures-js/heap": "^2.0.0"
}
},
"bip174": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/bip174/-/bip174-1.0.1.tgz",
"integrity": "sha512-Mq2aFs1TdMfxBpYPg7uzjhsiXbAtoVq44TNjEWtvuZBiBgc3m7+n55orYMtTAxdg7jWbL4DtH0MKocJER4xERQ=="
},
"bn.js": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
"integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ=="
},
"bolt07": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/bolt07/-/bolt07-1.5.2.tgz",
"integrity": "sha512-P7LNOnBLtRYe0v30JvVR2xVvWWNrUt4IZ19njFRJb1NMhEx2xe+O0G7x4WZTWB7bHPAdkfR76l9F7jEVxizjlQ==",
"requires": {
"bn.js": "5.1.2"
},
"dependencies": {
"bn.js": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz",
"integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA=="
}
}
},
"bolt09": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/bolt09/-/bolt09-0.1.1.tgz",
"integrity": "sha512-BX1LjpvU7qLyv8LRpYsq7p6fM2SiECWtfwjzx2/cStT0YFJhS74qFw5CfivoRz6ZEg3W7g1Exrv0tmDRkKeBkA=="
},
"goldengate": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/goldengate/-/goldengate-7.0.2.tgz",
"integrity": "sha512-ION2SoSTsePG9boPyREvPbH0f3bz9ZnYfUUaZsgPlEwj+od7+vGvHTQRdEvg3hl4Yod2U+gxNG7SpMHsY9Yuaw==",
"requires": {
"@grpc/proto-loader": "0.5.5",
"@mitmaro/http-authorization-header": "1.0.0",
"async": "3.2.0",
"asyncjs-util": "1.2.3",
"bip65": "1.0.3",
"bip68": "1.0.4",
"bitcoin-ops": "1.4.1",
"bitcoinjs-lib": "5.2.0",
"bn.js": "5.1.3",
"cbor": "5.1.0",
"grpc": "1.24.3",
"ln-service": "49.10.0",
"macaroon": "3.0.4",
"pushdata-bitcoin": "1.0.1",
"varuint-bitcoin": "1.1.2"
},
"dependencies": {
"invoices": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/invoices/-/invoices-1.1.3.tgz",
"integrity": "sha512-+RZmDmgVXvn6hAzGUqdl+1q8lEm9Th5XO/yg2aAIHpxhBc+BrrdCaMjjsk+weoZp9jm6LA92Dt2bzo+4ou1SVw==",
"requires": {
"bech32": "1.1.4",
"bitcoinjs-lib": "5.1.10",
"bn.js": "5.1.3",
"bolt07": "1.5.2",
"bolt09": "0.1.1",
"secp256k1": "4.0.2"
},
"dependencies": {
"bitcoinjs-lib": {
"version": "5.1.10",
"resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-5.1.10.tgz",
"integrity": "sha512-CesUqtBtnYc+SOMsYN9jWQWhdohW1MpklUkF7Ukn4HiAyN6yxykG+cIJogfRt6x5xcgH87K1Q+Mnoe/B+du1Iw==",
"requires": {
"bech32": "^1.1.2",
"bip174": "^1.0.1",
"bip32": "^2.0.4",
"bip66": "^1.1.0",
"bitcoin-ops": "^1.4.0",
"bs58check": "^2.0.0",
"create-hash": "^1.1.0",
"create-hmac": "^1.1.3",
"merkle-lib": "^2.0.10",
"pushdata-bitcoin": "^1.0.1",
"randombytes": "^2.0.1",
"tiny-secp256k1": "^1.1.1",
"typeforce": "^1.11.3",
"varuint-bitcoin": "^1.0.4",
"wif": "^2.0.1"
}
}
}
},
"ln-service": {
"version": "49.10.0",
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-49.10.0.tgz",
"integrity": "sha512-XK3gFc+Qowy9SquJ37UUktn61dlyoAR/4eN6eV2WPSY4DaSahZ/Xwe9j3ljXnZjTL5FClNzAfPwAhS/ljrgbhw==",
"requires": {
"@datastructures-js/priority-queue": "4.1.1",
"async": "3.2.0",
"asyncjs-util": "1.2.3",
"bitcoinjs-lib": "5.2.0",
"bn.js": "5.1.3",
"bolt07": "1.5.2",
"bolt09": "0.1.1",
"cors": "2.8.5",
"express": "4.17.1",
"invoices": "1.1.3",
"is-base64": "1.1.0",
"lightning": "2.0.44",
"macaroon": "3.0.4",
"morgan": "1.10.0",
"ws": "7.3.1"
}
}
}
},
"lightning": {
"version": "2.0.44",
"resolved": "https://registry.npmjs.org/lightning/-/lightning-2.0.44.tgz",
"integrity": "sha512-Xi8C0FmxIZ1Pg23JlXRoXc7ELEtskiWI7jfcdr1oYWpVlNxUJKc4ALrUMofqo+EXaoHhtEvc6byyHtxuNl6iLw==",
"version": "2.0.55",
"resolved": "https://registry.npmjs.org/lightning/-/lightning-2.0.55.tgz",
"integrity": "sha512-BvO6UblGDT2qyKEmkyk6PizixtynzsCY6xMnnuM9/0DOMLh7qO+vdJzYGZCgFs5EzQUyghJf2urV045l9AwAnA==",
"requires": {
"@grpc/proto-loader": "0.5.5",
"async": "3.2.0",
@ -3419,57 +3301,19 @@
"bitcoinjs-lib": "5.2.0",
"bn.js": "5.1.3",
"body-parser": "1.19.0",
"bolt07": "1.5.2",
"bolt09": "0.1.1",
"bolt07": "1.6.0",
"bolt09": "0.1.2",
"cbor": "5.1.0",
"express": "4.17.1",
"grpc": "1.24.3",
"invoices": "1.1.3"
},
"dependencies": {
"invoices": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/invoices/-/invoices-1.1.3.tgz",
"integrity": "sha512-+RZmDmgVXvn6hAzGUqdl+1q8lEm9Th5XO/yg2aAIHpxhBc+BrrdCaMjjsk+weoZp9jm6LA92Dt2bzo+4ou1SVw==",
"requires": {
"bech32": "1.1.4",
"bitcoinjs-lib": "5.1.10",
"bn.js": "5.1.3",
"bolt07": "1.5.2",
"bolt09": "0.1.1",
"secp256k1": "4.0.2"
},
"dependencies": {
"bitcoinjs-lib": {
"version": "5.1.10",
"resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-5.1.10.tgz",
"integrity": "sha512-CesUqtBtnYc+SOMsYN9jWQWhdohW1MpklUkF7Ukn4HiAyN6yxykG+cIJogfRt6x5xcgH87K1Q+Mnoe/B+du1Iw==",
"requires": {
"bech32": "^1.1.2",
"bip174": "^1.0.1",
"bip32": "^2.0.4",
"bip66": "^1.1.0",
"bitcoin-ops": "^1.4.0",
"bs58check": "^2.0.0",
"create-hash": "^1.1.0",
"create-hmac": "^1.1.3",
"merkle-lib": "^2.0.10",
"pushdata-bitcoin": "^1.0.1",
"randombytes": "^2.0.1",
"tiny-secp256k1": "^1.1.1",
"typeforce": "^1.11.3",
"varuint-bitcoin": "^1.0.4",
"wif": "^2.0.1"
}
}
}
}
"invoices": "1.1.4",
"psbt": "1.1.6"
}
},
"ln-service": {
"version": "49.12.0",
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-49.12.0.tgz",
"integrity": "sha512-giGNeXH/d2vpzny9HdxTp7DSHN+gnL2Qz8U4RHW5sIOOdc4dXR4E/G1H5cpKovX0Ix4IuQ8FlyvwwXwMHPJHEw==",
"version": "49.14.1",
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-49.14.1.tgz",
"integrity": "sha512-VvKMOhpnvPp8NvPbcS2pGk/UwyEZO8jzcbOtflCqLTTuClw7a4pEGQwpPeVCDTD6V+BGVOnZ75OL93OOw+/xuQ==",
"requires": {
"@datastructures-js/priority-queue": "4.1.2",
"async": "3.2.0",
@ -3482,52 +3326,10 @@
"express": "4.17.1",
"invoices": "1.1.4",
"is-base64": "1.1.0",
"lightning": "2.0.50",
"lightning": "2.0.55",
"macaroon": "3.0.4",
"morgan": "1.10.0",
"ws": "7.3.1"
},
"dependencies": {
"@datastructures-js/priority-queue": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/@datastructures-js/priority-queue/-/priority-queue-4.1.2.tgz",
"integrity": "sha512-S4fXJcsPdqEp2bbKZlH7suSiZ0lqmIs8n5BXqQXB+7/lA9LSK/Ng0hIehTjgETfe7n3g4ZVLoyjEUWHEbHJFdQ==",
"requires": {
"@datastructures-js/heap": "^2.0.0"
}
},
"bolt07": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/bolt07/-/bolt07-1.6.0.tgz",
"integrity": "sha512-c+o1FdDxsmrCmrcqW6YRpk/dHDXk3frqHd1552b0JMXM2Kp6K74dbj74vioeYYUTzwyXB3zZFh9g2OZBg3JcYQ==",
"requires": {
"bn.js": "5.1.3"
}
},
"bolt09": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/bolt09/-/bolt09-0.1.2.tgz",
"integrity": "sha512-UcjCWM5w0ncmeLy+L1ghgWBmFUD7F+tvYpYw/pi1PLXMhRJ10gHFbPjzX2CTMsU0ICb8CisIFBsd16DWaUd4FA=="
},
"lightning": {
"version": "2.0.50",
"resolved": "https://registry.npmjs.org/lightning/-/lightning-2.0.50.tgz",
"integrity": "sha512-vLD7N0OH5prJ+Ebt0lYestUuVKRmqMapH00jK+SR8IxIxzT6JM/KpMSJNWujUkP6yRSwBPF7QSUrIf/U1nk/FQ==",
"requires": {
"@grpc/proto-loader": "0.5.5",
"async": "3.2.0",
"asyncjs-util": "1.2.3",
"bitcoinjs-lib": "5.2.0",
"bn.js": "5.1.3",
"body-parser": "1.19.0",
"bolt07": "1.6.0",
"bolt09": "0.1.2",
"cbor": "5.1.0",
"express": "4.17.1",
"grpc": "1.24.3",
"invoices": "1.1.4"
}
}
}
}
}
@ -3862,9 +3664,9 @@
"integrity": "sha1-SJYrGeFp/R38JAs/HnMXYnu8R9s="
},
"nan": {
"version": "2.14.1",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
"integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
"version": "2.14.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ=="
},
"napi-build-utils": {
"version": "1.0.2",
@ -4621,6 +4423,35 @@
"bolt07": "1.6.0",
"invoices": "1.1.4",
"ln-service": "49.14.0"
},
"dependencies": {
"bn.js": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
"integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ=="
},
"ln-service": {
"version": "49.14.0",
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-49.14.0.tgz",
"integrity": "sha512-01CoIfdo1vRQfc3siVGAZEDaKv3IrAwpjLLCtOa8aYxIwjQN+a7YC4GIBysbxiOaF0E+eZZIGz8Y76U7zWHhEQ==",
"requires": {
"@datastructures-js/priority-queue": "4.1.2",
"async": "3.2.0",
"asyncjs-util": "1.2.3",
"bitcoinjs-lib": "5.2.0",
"bn.js": "5.1.3",
"bolt07": "1.6.0",
"bolt09": "0.1.2",
"cors": "2.8.5",
"express": "4.17.1",
"invoices": "1.1.4",
"is-base64": "1.1.0",
"lightning": "2.0.54",
"macaroon": "3.0.4",
"morgan": "1.10.0",
"ws": "7.3.1"
}
}
}
},
"process-nextick-args": {
@ -4660,9 +4491,9 @@
},
"dependencies": {
"@types/node": {
"version": "13.13.24",
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.24.tgz",
"integrity": "sha512-ry1JlHIVcmQFNq5KWgdEo1NVu7qFDi+vQPknWWDCc05cekTLVr2y0FHAKXTfv4OLWw+GOzdVe8eFWPoYEdk05w=="
"version": "13.13.26",
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.26.tgz",
"integrity": "sha512-+48LLqolaKj/WnIY1crfLseaGQMIDISBy3PTXVOZ7w/PBaRUv+H8t94++atzfoBAvorbUYz6Xq9vh1fHrg33ig=="
}
}
},
@ -4676,49 +4507,22 @@
}
},
"psbt": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/psbt/-/psbt-1.1.5.tgz",
"integrity": "sha512-NqVxxE78qG6dwnxpwR61niEaE5znUhOJOjjoGVsw4deX4OjE72py8wsEsCLuG7Yma7FsjhN58cmsMb2TqvoEGA==",
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/psbt/-/psbt-1.1.6.tgz",
"integrity": "sha512-snms+l+yUEDeYJWJrjIBrYqYseVpuO0jp/wjG6Mkcmhahcs58kswFoL+z4cmKgv11P64BYoIzmUgQBHJC+KxOw==",
"requires": {
"bip66": "1.1.5",
"bitcoin-ops": "1.4.1",
"bitcoinjs-lib": "5.1.10",
"bn.js": "5.1.2",
"bitcoinjs-lib": "5.2.0",
"bn.js": "5.1.3",
"pushdata-bitcoin": "1.0.1",
"varuint-bitcoin": "1.1.2"
},
"dependencies": {
"bip174": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/bip174/-/bip174-1.0.1.tgz",
"integrity": "sha512-Mq2aFs1TdMfxBpYPg7uzjhsiXbAtoVq44TNjEWtvuZBiBgc3m7+n55orYMtTAxdg7jWbL4DtH0MKocJER4xERQ=="
},
"bitcoinjs-lib": {
"version": "5.1.10",
"resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-5.1.10.tgz",
"integrity": "sha512-CesUqtBtnYc+SOMsYN9jWQWhdohW1MpklUkF7Ukn4HiAyN6yxykG+cIJogfRt6x5xcgH87K1Q+Mnoe/B+du1Iw==",
"requires": {
"bech32": "^1.1.2",
"bip174": "^1.0.1",
"bip32": "^2.0.4",
"bip66": "^1.1.0",
"bitcoin-ops": "^1.4.0",
"bs58check": "^2.0.0",
"create-hash": "^1.1.0",
"create-hmac": "^1.1.3",
"merkle-lib": "^2.0.10",
"pushdata-bitcoin": "^1.0.1",
"randombytes": "^2.0.1",
"tiny-secp256k1": "^1.1.1",
"typeforce": "^1.11.3",
"varuint-bitcoin": "^1.0.4",
"wif": "^2.0.1"
}
},
"bn.js": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz",
"integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA=="
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
"integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ=="
}
}
},
@ -4809,9 +4613,9 @@
}
},
"react": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz",
"integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==",
"version": "16.14.0",
"resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz",
"integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==",
"dev": true,
"requires": {
"loose-envify": "^1.1.0",
@ -4857,9 +4661,9 @@
}
},
"readdirp": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz",
"integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==",
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
"integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
"dev": true,
"requires": {
"picomatch": "^2.2.1"
@ -6924,9 +6728,9 @@
}
},
"tslib": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz",
"integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw=="
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"tunnel-agent": {
"version": "0.6.0",

View file

@ -30,14 +30,14 @@
"ini": "1.3.5",
"inquirer": "7.3.3",
"invoices": "1.1.4",
"ln-accounting": "4.1.10",
"ln-service": "49.14.0",
"ln-accounting": "4.1.11",
"ln-service": "49.14.2",
"ln-sync": "0.3.0",
"ln-telegram": "1.1.0",
"ln-telegram": "3.0.2",
"moment": "2.29.1",
"node-fetch": "2.6.1",
"probing": "1.3.0",
"psbt": "1.1.5",
"psbt": "1.1.6",
"qrcode-terminal": "0.12.0",
"sanitize-filename": "1.6.3",
"stats-lite": "2.2.0",
@ -73,5 +73,5 @@
"postpublish": "docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t alexbosworth/balanceofsatoshis --push .",
"test": "tap test/arrays/*.js test/balances/*.js test/chain/*.js test/display/*.js test/encryption/*.js test/fiat/*.js test/lnd/*.js test/network/*.js test/nodes/*.js test/responses/*.js test/routing/*.js test/swaps/*.js test/wallets/*.js"
},
"version": "6.3.2"
"version": "6.4.0"
}

View file

@ -5,11 +5,11 @@ const {getNetwork} = require('ln-sync');
const {getSwapMacaroon} = require('goldengate');
const {lightningLabsSwapService} = require('goldengate');
const {paidMacaroon} = require('goldengate');
const {payViaPaymentRequest} = require('ln-service');
const {returnResult} = require('asyncjs-util');
const {swapUserId} = require('goldengate');
const decodeSwapApiKey = require('./decode_swap_api_key');
const {probeDestination} = require('./../network');
const bitcoinTestnetNetwork = 'btctestnet';
const bufferFromBase64 = base64 => Buffer.from(base64, 'base64');
@ -24,7 +24,6 @@ const testnetSocket = 'https://balanceofsatoshis.com:11010';
{
fetch: <Fetch Function>
lnd: <Authenticated LND gRPC API Object>
logger: <Winston Logger Object>
[socket]: <Custom Backing Service Socket String>
[token]: <Prepaid Service Token CBOR Encoded String>
}
@ -39,7 +38,7 @@ const testnetSocket = 'https://balanceofsatoshis.com:11010';
token: <Authentication Token Hex String>
}
*/
module.exports = ({fetch, lnd, logger, socket, token}, cbk) => {
module.exports = ({fetch, lnd, socket, token}, cbk) => {
return new Promise((resolve, reject) => {
return asyncAuto({
// Check arguments
@ -52,10 +51,6 @@ module.exports = ({fetch, lnd, logger, socket, token}, cbk) => {
return cbk([400, 'ExpectedLndToGetPaidService']);
}
if (!logger) {
return cbk([400, 'ExpectedLoggerToGetPaidService']);
}
return cbk();
},
@ -122,14 +117,12 @@ module.exports = ({fetch, lnd, logger, socket, token}, cbk) => {
{
// Exit early when there is already a paid service token
if (!!decodeToken) {
return cbk(null, {preimage: decodeToken.preimage});
return cbk(null, {secret: decodeToken.preimage});
}
// Purchase the macaroon
return probeDestination({
return payViaPaymentRequest({
lnd,
logger,
is_real_payment: true,
max_fee: maxRoutingFee,
request: getUnpaidMacaroon.request,
},
@ -146,11 +139,11 @@ module.exports = ({fetch, lnd, logger, socket, token}, cbk) => {
{
const {id} = getUnpaidMacaroon;
const {macaroon} = getUnpaidMacaroon;
const {paid} = payForMacaroon;
const {preimage} = payForMacaroon;
const paid = payForMacaroon.tokens;
const preimage = payForMacaroon.secret;
const {service} = remote;
if (!decodeToken && !paid) {
if (!decodeToken && !preimage) {
return cbk([400, 'FailedToPurchasePaidServiceTokens']);
}

View file

@ -336,7 +336,6 @@ module.exports = (args, cbk) => {
network,
fetch: args.fetch,
lnd: args.lnd,
logger: args.logger,
socket: args.socket,
token: args.api_key,
},

View file

@ -5,6 +5,7 @@ const asyncAuto = require('async/auto');
const asyncEach = require('async/each');
const asyncForever = require('async/forever');
const asyncMap = require('async/map');
const {getForwards} = require('ln-service');
const {getTransactionRecord} = require('ln-sync');
const {getWalletInfo} = require('ln-service');
const {handleBackupCommand} = require('ln-telegram');
@ -16,14 +17,15 @@ const {handleLiquidityCommand} = require('ln-telegram');
const {handleMempoolCommand} = require('ln-telegram');
const {handlePayCommand} = require('ln-telegram');
const inquirer = require('inquirer');
const {notifyOfForwards} = require('ln-telegram');
const {postChainTransaction} = require('ln-telegram');
const {postClosedMessage} = require('ln-telegram');
const {postForwardedPayments} = require('ln-telegram');
const {postOpenMessage} = require('ln-telegram');
const {postSettledInvoice} = require('ln-telegram');
const {postUpdatedBackups} = require('ln-telegram');
const {postUpdatedBackup} = require('ln-telegram');
const {returnResult} = require('asyncjs-util');
const {sendMessage} = require('ln-telegram');
const {subscribeToBackups} = require('ln-service');
const {subscribeToBlocks} = require('goldengate');
const {subscribeToChannels} = require('ln-service');
const {subscribeToInvoices} = require('ln-service');
@ -40,6 +42,7 @@ const fromName = node => `${node.alias} ${node.public_key.substring(0, 8)}`;
const home = '.bos';
const {isArray} = Array;
const isNumber = n => !isNaN(n);
const limit = 99999;
const maxCommandDelayMs = 1000 * 10;
const msSince = epoch => Date.now() - (epoch * 1e3);
const network = 'btc';
@ -68,6 +71,7 @@ module.exports = ({fs, id, lnds, logger, payments, request}, cbk) => {
let connectedId = id;
let isStopped = false;
let paymentsLimit = !payments || !payments.limit ? Number() : payments.limit;
const subscriptions = [];
return new Promise((resolve, reject) => {
return asyncAuto({
@ -371,15 +375,34 @@ module.exports = ({fs, id, lnds, logger, payments, request}, cbk) => {
// Subscribe to backups
backups: ['apiKey', 'getNodes', 'userId', ({apiKey, getNodes}, cbk) => {
return asyncEach(getNodes, (node, cbk) => {
return postUpdatedBackups({
logger,
request,
id: connectedId,
key: apiKey,
lnd: node.lnd,
node: {alias: node.alias, public_key: node.public_key},
},
cbk);
let postBackupTimeoutHandle;
const sub = subscribeToBackups({lnd: node.lnd});
subscriptions.push(sub);
sub.on('backup', ({backup}) => {
// Cancel pending backup notification when there is a new backup
if (!!postBackupTimeoutHandle) {
clearTimeout(postBackupTimeoutHandle);
}
// Time delay backup posting to avoid posting duplicate messages
postBackupTimeoutHandle = setTimeout(() => {
return postUpdatedBackup({
backup,
request,
id: connectedId,
key: apiKey,
node: {alias: node.alias, public_key: node.public_key},
},
err => !!err ? logger.error({post_backup_err: err}) : null);
},
restartSubscriptionTimeMs);
return;
});
sub.on('error', err => cbk([503, 'ErrorInBackupsSub', {err}]));
},
cbk);
}],
@ -394,6 +417,8 @@ module.exports = ({fs, id, lnds, logger, payments, request}, cbk) => {
return asyncEach(getNodes, ({from, lnd}, cbk) => {
const sub = subscribeToChannels({lnd});
subscriptions.push(sub);
sub.on('channel_closed', update => {
return postClosedMessage({
from,
@ -458,13 +483,45 @@ module.exports = ({fs, id, lnds, logger, payments, request}, cbk) => {
// Poll for forwards
forwards: ['apiKey', 'getNodes', 'userId', ({apiKey, getNodes}, cbk) => {
return asyncEach(getNodes, ({from, lnd}, cbk) => {
return postForwardedPayments({
from,
lnd,
request,
id: connectedId,
key: apiKey,
return asyncEach(getNodes, (node, cbk) => {
let after = new Date().toISOString();
const {from} = node;
const {lnd} = node;
return asyncForever(cbk => {
if (isStopped) {
return cbk([503, 'ExpectedNonStoppedBotToReportForwards']);
}
const before = new Date().toISOString();
return getForwards({after, before, limit, lnd}, (err, res) => {
// Exit early and ignore errors
if (!!err) {
return setTimeout(cbk, restartSubscriptionTimeMs);
}
// Push cursor forward
after = before;
// Notify Telegram bot that forwards happened
return notifyOfForwards({
from,
lnd,
request,
forwards: res.forwards,
id: connectedId,
key: apiKey,
node: node.public_key,
},
err => {
if (!!err) {
logger.error({forwards_notify_err: err});
}
return setTimeout(cbk, restartSubscriptionTimeMs);
});
});
},
cbk);
},
@ -476,6 +533,8 @@ module.exports = ({fs, id, lnds, logger, payments, request}, cbk) => {
return asyncEach(getNodes, ({from, lnd}, cbk) => {
const sub = subscribeToInvoices({lnd});
subscriptions.push(sub);
sub.on('invoice_updated', invoice => {
return postSettledInvoice({
from,
@ -518,6 +577,8 @@ module.exports = ({fs, id, lnds, logger, payments, request}, cbk) => {
const sub = subscribeToTransactions({lnd});
const transactions = [];
subscriptions.push(sub);
sub.on('chain_transaction', async transaction => {
const {id} = transaction;
@ -537,14 +598,13 @@ module.exports = ({fs, id, lnds, logger, payments, request}, cbk) => {
return await postChainTransaction({
from,
lnd,
request,
id: connectedId,
key: apiKey,
transaction: record,
});
} catch (err) {
logger.error({chain_tx_err: err});
logger.error({chain_tx_err: err, node: from});
if (!!isFinished) {
return;
@ -583,7 +643,9 @@ module.exports = ({fs, id, lnds, logger, payments, request}, cbk) => {
(err, res) => {
isStopped = true;
return returnResult({reject, resolve})(err, res);
subscriptions.forEach(n => n.removeAllListeners());
return returnResult({reject, resolve}, cbk)(err, res);
});
});
};

View file

@ -16,7 +16,6 @@ const makeArgs = override => {
getInfo: ({}, cbk) => cbk(null, getInfoResponse),
},
},
logger: {},
token: makeToken(Buffer.from(macaroon, 'base64'), Buffer.alloc(1, 1)),
};
@ -31,11 +30,6 @@ const tests = [
description: 'LND object is required',
error: [400, 'ExpectedLndToGetPaidService'],
},
{
args: makeArgs({logger: undefined}),
description: 'Logger object is required',
error: [400, 'ExpectedLoggerToGetPaidService'],
},
{
args: makeArgs({}),
description: 'A paid service object is returned',

View file

@ -2,7 +2,7 @@ const moment = require('moment');
const dollarFormat = cents => (cents / 100).toFixed(2);
const formatAsBigUnit = tokens => (tokens / 1e8).toFixed(8);
const percentFormat = n => (n * 100).toFixed();
const percentFormat = n => isNaN(n) ? '0' : (n * 100).toFixed();
/** Derive report overview