mirror of
https://github.com/alexbosworth/balanceofsatoshis.git
synced 2026-08-13 12:33:37 +02:00
add fund-dev command, add peer specificity to chart fees earned
This commit is contained in:
parent
5cb765439b
commit
d5d911b8b5
16 changed files with 742 additions and 87 deletions
|
|
@ -1,5 +1,10 @@
|
|||
# Versions
|
||||
|
||||
## Version 5.4.0
|
||||
|
||||
- `chart-fees-earned`: Add `via` argument to show only fees related to a peer
|
||||
- Add `fund-dev`: method to fund Bitcoin and Lightning development efforts
|
||||
|
||||
## Version 5.3.1
|
||||
|
||||
- Add `chart-fees-earned` to show a chart of fees earned
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@ bos find "query"
|
|||
# Output a summarized version of peers forwarded towards
|
||||
bos forwards
|
||||
|
||||
# Fund people related to Bitcoin and Lightning efforts
|
||||
bos fund-dev
|
||||
|
||||
# Send a gift of some tokens to a directly connected peer
|
||||
bos gift "pubkey" "amount"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
const shuffle = require('./shuffle');
|
||||
const sortBy = require('./sort_by');
|
||||
|
||||
module.exports = {sortBy};
|
||||
module.exports = {shuffle, sortBy};
|
||||
|
|
|
|||
25
arrays/shuffle.js
Normal file
25
arrays/shuffle.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
const {floor} = Math;
|
||||
const {random} = Math;
|
||||
|
||||
/** Shuffle array
|
||||
|
||||
{
|
||||
array: [<Element Object>]
|
||||
}
|
||||
|
||||
@returns
|
||||
{
|
||||
shuffled: [<Shuffled Element Object>]
|
||||
}
|
||||
*/
|
||||
module.exports = ({array}) => {
|
||||
const shuffle = array.slice();
|
||||
|
||||
for (let i = shuffle.length - 1; !!i; i--) {
|
||||
const j = floor(random() * (i + 1));
|
||||
|
||||
[shuffle[i], shuffle[j]] = [shuffle[j], shuffle[i]];
|
||||
}
|
||||
|
||||
return {shuffled: shuffle};
|
||||
};
|
||||
32
bos
32
bos
|
|
@ -18,6 +18,7 @@ const {adjustSavedNodes} = require('./nodes');
|
|||
const {authenticatedLnd} = require('./lnd');
|
||||
const {exchanges} = require('./fiat');
|
||||
const {findRecord} = require('./lnd');
|
||||
const {fundDev} = require('./wallets');
|
||||
const {getAccountingReport} = require('./balances');
|
||||
const {getBalance} = require('./balances');
|
||||
const {getCertValidityDays} = require('./lnd');
|
||||
|
|
@ -231,6 +232,7 @@ prog
|
|||
|
||||
// Show a chart of fees earned
|
||||
.command('chart-fees-earned', 'Get a chart of earned routing fees')
|
||||
.argument('[via_peer]', 'Routing fees earned via a specified peer')
|
||||
.help('Show the routing fees earned')
|
||||
.option('--days <days>', 'Chart fees over the past number of days', INT, 60)
|
||||
.option('--node <node_name>', 'Get fee earnings chart for saved node')
|
||||
|
|
@ -240,6 +242,7 @@ prog
|
|||
return getFeesChart({
|
||||
days: options.days,
|
||||
lnd: (await authenticatedLnd({logger, node: options.node})).lnd,
|
||||
via: args.viaPeer,
|
||||
},
|
||||
returnChart({logger, reject, resolve, data: 'fees'}));
|
||||
} catch (err) {
|
||||
|
|
@ -335,6 +338,33 @@ prog
|
|||
});
|
||||
})
|
||||
|
||||
// Help with funding
|
||||
.command('fund-dev', 'Fund people related to Bitcoin and Lightning efforts')
|
||||
.help('Send some sats (805 default) to a worthy individual. For the cause!')
|
||||
.help('Someone will be automatically chosen if no @handle specified')
|
||||
.help('Nominate worthiness via GitHub issues, include proof of your support')
|
||||
.option('--amount <amount>', 'Choose amount to send', INT, 805)
|
||||
.option('--dryrun', 'Show what would happen without actually sending funds')
|
||||
.option('--node <node_name>', 'Saved node to give funds from')
|
||||
.option('--twitter-handle <nick>', 'Specifically support someone')
|
||||
.action(async (args, options, logger) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
return fundDev({
|
||||
logger,
|
||||
request,
|
||||
is_dry_run: options.dryrun,
|
||||
lnd: (await authenticatedLnd({logger, node: options.node})).lnd,
|
||||
to_twitter_account: options.twitterHandle,
|
||||
tokens: options.amount,
|
||||
},
|
||||
returnObject({logger, reject, resolve}));
|
||||
} catch (err) {
|
||||
return reject(err);
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// Give a peer some tokens
|
||||
.command('gift', 'Give a direct peer some free funds off-chain')
|
||||
.help('Send some funds to a connected peer')
|
||||
|
|
@ -672,7 +702,7 @@ prog
|
|||
.option('--budget <amount>', 'Spending amount to allow', INT, 0)
|
||||
.option('--connect <connect_code>', 'Connection code', INT)
|
||||
.option('--node <node_name>', 'Node to connect to Telegram', REPEATABLE)
|
||||
.action(async (args, options, logger) => {
|
||||
.action((args, options, logger) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const nodes = flatten([options.node].filter(n => !!n)).map(node => {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ const reserveRatio = 0.01;
|
|||
lnd: <Authenticated LND gRPC API Object>
|
||||
logger: <Winston Logger Object>
|
||||
[max_fee]: <Maximum Fee Tokens Number>
|
||||
[node]: <Node Name String>
|
||||
[out_through]: <Out through peer with Public Key Hex String>
|
||||
[request]: <Payment Request String>
|
||||
[tokens]: <Tokens Number>
|
||||
|
|
|
|||
188
package-lock.json
generated
188
package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "balanceofsatoshis",
|
||||
"version": "5.3.1",
|
||||
"version": "5.4.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
@ -14,12 +14,12 @@
|
|||
}
|
||||
},
|
||||
"@babel/generator": {
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.2.tgz",
|
||||
"integrity": "sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ==",
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz",
|
||||
"integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.7.2",
|
||||
"@babel/types": "^7.7.4",
|
||||
"jsesc": "^2.5.1",
|
||||
"lodash": "^4.17.13",
|
||||
"source-map": "^0.5.0"
|
||||
|
|
@ -34,32 +34,32 @@
|
|||
}
|
||||
},
|
||||
"@babel/helper-function-name": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz",
|
||||
"integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==",
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz",
|
||||
"integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-get-function-arity": "^7.7.0",
|
||||
"@babel/template": "^7.7.0",
|
||||
"@babel/types": "^7.7.0"
|
||||
"@babel/helper-get-function-arity": "^7.7.4",
|
||||
"@babel/template": "^7.7.4",
|
||||
"@babel/types": "^7.7.4"
|
||||
}
|
||||
},
|
||||
"@babel/helper-get-function-arity": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz",
|
||||
"integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==",
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz",
|
||||
"integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.7.0"
|
||||
"@babel/types": "^7.7.4"
|
||||
}
|
||||
},
|
||||
"@babel/helper-split-export-declaration": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz",
|
||||
"integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==",
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz",
|
||||
"integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.7.0"
|
||||
"@babel/types": "^7.7.4"
|
||||
}
|
||||
},
|
||||
"@babel/highlight": {
|
||||
|
|
@ -105,43 +105,43 @@
|
|||
}
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz",
|
||||
"integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==",
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.4.tgz",
|
||||
"integrity": "sha512-jIwvLO0zCL+O/LmEJQjWA75MQTWwx3c3u2JOTDK5D3/9egrWRRA0/0hk9XXywYnXZVVpzrBYeIQTmhwUaePI9g==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/runtime": {
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.2.tgz",
|
||||
"integrity": "sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw==",
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.4.tgz",
|
||||
"integrity": "sha512-r24eVUUr0QqNZa+qrImUk8fn5SPhHq+IfYvIoIMg0do3GdK9sMdiLKP3GYVVaxpPKORgm8KRKaNTEhAjgIpLMw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.13.2"
|
||||
}
|
||||
},
|
||||
"@babel/template": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz",
|
||||
"integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==",
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz",
|
||||
"integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"@babel/parser": "^7.7.0",
|
||||
"@babel/types": "^7.7.0"
|
||||
"@babel/parser": "^7.7.4",
|
||||
"@babel/types": "^7.7.4"
|
||||
}
|
||||
},
|
||||
"@babel/traverse": {
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.2.tgz",
|
||||
"integrity": "sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw==",
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz",
|
||||
"integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.5.5",
|
||||
"@babel/generator": "^7.7.2",
|
||||
"@babel/helper-function-name": "^7.7.0",
|
||||
"@babel/helper-split-export-declaration": "^7.7.0",
|
||||
"@babel/parser": "^7.7.2",
|
||||
"@babel/types": "^7.7.2",
|
||||
"@babel/generator": "^7.7.4",
|
||||
"@babel/helper-function-name": "^7.7.4",
|
||||
"@babel/helper-split-export-declaration": "^7.7.4",
|
||||
"@babel/parser": "^7.7.4",
|
||||
"@babel/types": "^7.7.4",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0",
|
||||
"lodash": "^4.17.13"
|
||||
|
|
@ -165,9 +165,9 @@
|
|||
}
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz",
|
||||
"integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==",
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
|
||||
"integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esutils": "^2.0.2",
|
||||
|
|
@ -675,9 +675,9 @@
|
|||
}
|
||||
},
|
||||
"bolt07": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/bolt07/-/bolt07-1.4.3.tgz",
|
||||
"integrity": "sha512-ZZ3agtRbgEpYF+TSlUi+W0jP/0sv1DBxHD9Ii+diwaSWd13NSwpqiiNAKRzxSXnnec6/8nP+Mz+X0Mo0UjQ/Sg==",
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/bolt07/-/bolt07-1.4.4.tgz",
|
||||
"integrity": "sha512-1jn3ef9lhhcd4uC9JcOHQXtFgOMuN8AEBMRnWNO/zTVOOkl0zLKEkv30PrBfwdr0i/OAIEbhTHIR/2PCGLVfxQ==",
|
||||
"requires": {
|
||||
"bn.js": "5.0.0"
|
||||
},
|
||||
|
|
@ -1500,6 +1500,12 @@
|
|||
"integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==",
|
||||
"dev": true
|
||||
},
|
||||
"diff-frag": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/diff-frag/-/diff-frag-1.0.1.tgz",
|
||||
"integrity": "sha512-6/v2PC/6UTGcWPPetb9acL8foberUg/CtPdALeJUdD1B/weHNvzftoo00gYznqHGRhHEbykUGzqfG9RWOSr5yw==",
|
||||
"dev": true
|
||||
},
|
||||
"dot-prop": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
|
||||
|
|
@ -2038,6 +2044,16 @@
|
|||
"safe-compare": "1.1.4",
|
||||
"secp256k1": "3.7.1",
|
||||
"ws": "7.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"bolt07": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/bolt07/-/bolt07-1.4.3.tgz",
|
||||
"integrity": "sha512-ZZ3agtRbgEpYF+TSlUi+W0jP/0sv1DBxHD9Ii+diwaSWd13NSwpqiiNAKRzxSXnnec6/8nP+Mz+X0Mo0UjQ/Sg==",
|
||||
"requires": {
|
||||
"bn.js": "5.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3298,12 +3314,59 @@
|
|||
"json2csv": "4.5.4",
|
||||
"ln-service": "47.4.0",
|
||||
"request": "2.88.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"bn.js": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.0.0.tgz",
|
||||
"integrity": "sha512-bVwDX8AF+72fIUNuARelKAlQUNtPOfG2fRxorbVvFk4zpHbqLrPdOGfVg5vrKwVzLLePqPBiATaOZNELQzmS0A=="
|
||||
},
|
||||
"bolt07": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/bolt07/-/bolt07-1.4.3.tgz",
|
||||
"integrity": "sha512-ZZ3agtRbgEpYF+TSlUi+W0jP/0sv1DBxHD9Ii+diwaSWd13NSwpqiiNAKRzxSXnnec6/8nP+Mz+X0Mo0UjQ/Sg==",
|
||||
"requires": {
|
||||
"bn.js": "5.0.0"
|
||||
}
|
||||
},
|
||||
"ln-service": {
|
||||
"version": "47.4.0",
|
||||
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-47.4.0.tgz",
|
||||
"integrity": "sha512-uWT9AyXhK1vuVO+WxktZUBaD1zhrxs9L2XXH0/+ofKH5P+jm13Mt23nU0uY6E9Ad/iBpOYil7hDBrvtWbRA8TA==",
|
||||
"requires": {
|
||||
"@datastructures-js/priority-queue": "1.0.2",
|
||||
"@grpc/proto-loader": "0.5.3",
|
||||
"async": "3.1.0",
|
||||
"asyncjs-util": "1.1.2",
|
||||
"basicauth-middleware": "3.1.0",
|
||||
"bech32": "1.1.3",
|
||||
"bitcoinjs-lib": "5.1.6",
|
||||
"bn.js": "5.0.0",
|
||||
"body-parser": "1.19.0",
|
||||
"bolt07": "1.4.3",
|
||||
"compression": "1.7.4",
|
||||
"cors": "2.8.5",
|
||||
"dotenv": "8.2.0",
|
||||
"express": "4.17.1",
|
||||
"grpc": "1.24.2",
|
||||
"is-base64": "1.0.0",
|
||||
"is-hex": "1.1.3",
|
||||
"lodash": "4.17.15",
|
||||
"macaroon": "3.0.4",
|
||||
"morgan": "1.9.1",
|
||||
"promptly": "3.0.3",
|
||||
"request": "2.88.0",
|
||||
"safe-compare": "1.1.4",
|
||||
"secp256k1": "3.7.1",
|
||||
"ws": "7.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ln-service": {
|
||||
"version": "47.4.0",
|
||||
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-47.4.0.tgz",
|
||||
"integrity": "sha512-uWT9AyXhK1vuVO+WxktZUBaD1zhrxs9L2XXH0/+ofKH5P+jm13Mt23nU0uY6E9Ad/iBpOYil7hDBrvtWbRA8TA==",
|
||||
"version": "47.5.0",
|
||||
"resolved": "https://registry.npmjs.org/ln-service/-/ln-service-47.5.0.tgz",
|
||||
"integrity": "sha512-VS6iqEv4ScP1c/AhO7cSWcYtR4ixAyESVrhJBY7FzyyPGvnixXiEYe7aggFbChvODiyEgmBON1giUaMB2R8JlQ==",
|
||||
"requires": {
|
||||
"@datastructures-js/priority-queue": "1.0.2",
|
||||
"@grpc/proto-loader": "0.5.3",
|
||||
|
|
@ -3314,7 +3377,7 @@
|
|||
"bitcoinjs-lib": "5.1.6",
|
||||
"bn.js": "5.0.0",
|
||||
"body-parser": "1.19.0",
|
||||
"bolt07": "1.4.3",
|
||||
"bolt07": "1.4.4",
|
||||
"compression": "1.7.4",
|
||||
"cors": "2.8.5",
|
||||
"dotenv": "8.2.0",
|
||||
|
|
@ -4475,9 +4538,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.1.tgz",
|
||||
"integrity": "sha512-+j3UVImywlkdEOzjNCk379mEqqUEmHgCmUDQkmVVwDkBVopfk/TqrBrr8ZfKZSnCqW/sgyuACFVjBwoB5Mw56A==",
|
||||
"version": "1.12.2",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.2.tgz",
|
||||
"integrity": "sha512-cAVTI2VLHWYsGOirfeYVVQ7ZDejtQ9fp4YhYckWDEkFfqbVjaT11iM8k6xSAfGFMM+gDpZjMnFssPu8we+mqFw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-parse": "^1.0.6"
|
||||
|
|
@ -5020,9 +5083,9 @@
|
|||
}
|
||||
},
|
||||
"tap": {
|
||||
"version": "14.9.2",
|
||||
"resolved": "https://registry.npmjs.org/tap/-/tap-14.9.2.tgz",
|
||||
"integrity": "sha512-Fyy/sjsw4eb+Hnphin4oMtDtKxmrob/vrnaIDv/F3thFFQjQFqMg8xf45zRFGHxUfezlrO6KsH8TpWNlTDINfA==",
|
||||
"version": "14.10.1",
|
||||
"resolved": "https://registry.npmjs.org/tap/-/tap-14.10.1.tgz",
|
||||
"integrity": "sha512-GsjAtKf9WKe2Cj5/5OckVdwyz4kv4pjlidDPpNY32ikR6rkBnicU/gxwckXvV/pQ5uTDx+od6XqmVAB7ityXWg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"async-hook-domain": "^1.1.2",
|
||||
|
|
@ -5058,8 +5121,8 @@
|
|||
"tap-mocha-reporter": "^5.0.0",
|
||||
"tap-parser": "^10.0.1",
|
||||
"tap-yaml": "^1.0.0",
|
||||
"tcompare": "^2.3.0",
|
||||
"treport": "^0.4.2",
|
||||
"tcompare": "^3.0.0",
|
||||
"treport": "^0.5.0",
|
||||
"trivial-deferred": "^1.0.1",
|
||||
"ts-node": "^8.3.0",
|
||||
"typescript": "^3.6.3",
|
||||
|
|
@ -5959,7 +6022,7 @@
|
|||
"dev": true
|
||||
},
|
||||
"treport": {
|
||||
"version": "0.4.2",
|
||||
"version": "0.5.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
|
@ -6159,10 +6222,13 @@
|
|||
}
|
||||
},
|
||||
"tcompare": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/tcompare/-/tcompare-2.3.0.tgz",
|
||||
"integrity": "sha512-fAfA73uFtFGybWGt4+IYT6UPLYVZQ4NfsP+IXEZGY0vh8e2IF7LVKafcQNMRBLqP0wzEA65LM9Tqj+FSmO8GLw==",
|
||||
"dev": true
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tcompare/-/tcompare-3.0.0.tgz",
|
||||
"integrity": "sha512-lRD40wHaBoVvmcCT0L7qJmR+jBl1nVP0WxbMYyOtsFza+SXD9aiRVir9aWogdQwNzY6ZwOvwDp5vg3XWQGOIVQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"diff-frag": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"telegraf": {
|
||||
"version": "3.33.3",
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
"bitcoin-ops": "1.4.1",
|
||||
"bitcoinjs-lib": "5.1.6",
|
||||
"bolt03": "1.2.1",
|
||||
"bolt07": "1.4.3",
|
||||
"bolt07": "1.4.4",
|
||||
"caporal": "1.3.0",
|
||||
"cbor": "5.0.1",
|
||||
"cert-info": "1.5.1",
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
"ini": "1.3.5",
|
||||
"inquirer": "7.0.0",
|
||||
"ln-accounting": "3.1.6",
|
||||
"ln-service": "47.4.0",
|
||||
"ln-service": "47.5.0",
|
||||
"moment": "2.24.0",
|
||||
"qrcode-terminal": "0.12.0",
|
||||
"request": "2.88.0",
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
},
|
||||
"description": "Lightning balance CLI",
|
||||
"devDependencies": {
|
||||
"tap": "14.9.2"
|
||||
"tap": "14.10.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.12.0"
|
||||
|
|
@ -61,5 +61,5 @@
|
|||
"scripts": {
|
||||
"test": "tap test/arrays/*.js test/balances/*.js test/chain/*.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/telegram/*.js"
|
||||
},
|
||||
"version": "5.3.1"
|
||||
"version": "5.4.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
const {plot} = require('asciichart');
|
||||
|
||||
const height = 15;
|
||||
const padding = '\n ';
|
||||
const newLine = '\n';
|
||||
const padLen = (lineLen, desc) => (Math.max(0, lineLen - desc.length) + 3) / 2;
|
||||
|
||||
/** Return an output result to a logger in a promise
|
||||
|
||||
|
|
@ -25,11 +26,23 @@ module.exports = ({data, logger, reject, resolve}) => {
|
|||
return reject();
|
||||
}
|
||||
|
||||
const chart = plot(res[data], {height});
|
||||
|
||||
const [line] = chart.split(newLine);
|
||||
|
||||
if (!!res.title) {
|
||||
const padding = ' '.repeat(padLen(line.length, res.title));
|
||||
|
||||
logger.info(`${newLine}${padding}${res.title}`);
|
||||
}
|
||||
|
||||
logger.info(String());
|
||||
logger.info(plot(res[data], {height}));
|
||||
|
||||
if (!!res.description) {
|
||||
logger.info(`${padding}${res.description}`);
|
||||
const padding = ' '.repeat(padLen(line.length, res.description));
|
||||
|
||||
logger.info(`${newLine}${padding}${res.description}`);
|
||||
}
|
||||
|
||||
logger.info(String());
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
const asyncAuto = require('async/auto');
|
||||
const {getForwards} = require('ln-service');
|
||||
const {getNode} = require('ln-service');
|
||||
const moment = require('moment');
|
||||
const {returnResult} = require('asyncjs-util');
|
||||
|
||||
|
|
@ -9,21 +10,25 @@ const hoursPerDay = 24;
|
|||
const limit = 99999;
|
||||
const minChartDays = 4;
|
||||
const maxChartDays = 90;
|
||||
const notFound = -1;
|
||||
const uniq = arr => Array.from(new Set(arr));
|
||||
|
||||
/** Get data for fees chart
|
||||
|
||||
{
|
||||
days: <Fees Earned Over Days Count Number>
|
||||
lnd: <Authenticated LND gRPC API Object>
|
||||
via: <Via Public Key Hex String>
|
||||
}
|
||||
|
||||
@returns via cbk or Promise
|
||||
{
|
||||
description: <Chart Description String>
|
||||
fees: [<Earned Fee Tokens Number>]
|
||||
title: <Chart Title String>
|
||||
}
|
||||
*/
|
||||
module.exports = ({days, lnd}, cbk) => {
|
||||
module.exports = ({days, lnd, via}, cbk) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
return asyncAuto({
|
||||
// Check arguments
|
||||
|
|
@ -39,6 +44,11 @@ module.exports = ({days, lnd}, cbk) => {
|
|||
return cbk();
|
||||
},
|
||||
|
||||
// Get node details
|
||||
getNode: ['validate', ({}, cbk) => {
|
||||
return !via ? cbk() : getNode({lnd, public_key: via}, cbk);
|
||||
}],
|
||||
|
||||
// Segment measure
|
||||
measure: ['validate', ({}, cbk) => {
|
||||
if (days > maxChartDays) {
|
||||
|
|
@ -66,10 +76,31 @@ module.exports = ({days, lnd}, cbk) => {
|
|||
cbk);
|
||||
}],
|
||||
|
||||
// Total earnings
|
||||
totalEarned: ['getForwards', ({getForwards}, cbk) => {
|
||||
const {forwards} = getForwards;
|
||||
// Filter the forwards
|
||||
forwards: ['getForwards', 'getNode', ({getForwards, getNode}, cbk) => {
|
||||
if (!via) {
|
||||
return cbk(null, getForwards.forwards);
|
||||
}
|
||||
|
||||
const channelIds = uniq(getNode.channels.map(({id}) => id));
|
||||
|
||||
const forwards = getForwards.forwards.filter(forward => {
|
||||
if (channelIds.indexOf(forward.incoming_channel) !== notFound) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (channelIds.indexOf(forward.outgoing_channel) !== notFound) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
return cbk(null, forwards);
|
||||
}],
|
||||
|
||||
// Total earnings
|
||||
totalEarned: ['forwards', ({forwards}, cbk) => {
|
||||
return cbk(null, forwards.reduce((sum, {fee}) => sum + fee, Number()));
|
||||
}],
|
||||
|
||||
|
|
@ -89,15 +120,15 @@ module.exports = ({days, lnd}, cbk) => {
|
|||
|
||||
// Fees earned
|
||||
fees: [
|
||||
'getForwards',
|
||||
'forwards',
|
||||
'measure',
|
||||
'segments',
|
||||
({getForwards, measure, segments}, cbk) =>
|
||||
({forwards, measure, segments}, cbk) =>
|
||||
{
|
||||
const fees = [...Array(segments)].map((_, i) => {
|
||||
const segment = moment().subtract(i, measure);
|
||||
|
||||
const segmentForwards = getForwards.forwards.filter(forward => {
|
||||
const segmentForwards = forwards.filter(forward => {
|
||||
const forwardDate = moment(forward.created_at);
|
||||
|
||||
if (segment.year() !== forwardDate.year()) {
|
||||
|
|
@ -132,16 +163,32 @@ module.exports = ({days, lnd}, cbk) => {
|
|||
'totalEarned',
|
||||
({fees, measure, start, totalEarned}, cbk) =>
|
||||
{
|
||||
const feesEarned = `Fees earned in ${fees.length} ${measure}s`;
|
||||
const since = `since ${start.calendar()}`;
|
||||
const duration = `Earned in ${fees.length} ${measure}s`;
|
||||
const earned = (totalEarned / 1e8).toFixed(8);
|
||||
const since = `since ${start.calendar().toLowerCase()}`;
|
||||
|
||||
return cbk(null, `${feesEarned} ${since}. Total: ${earned}`);
|
||||
return cbk(null, `${duration} ${since}. Total: ${earned}`);
|
||||
}],
|
||||
|
||||
// Summary title of the fees earned
|
||||
title: ['getNode', ({getNode}, cbk) => {
|
||||
const title = 'Routing fees earned';
|
||||
|
||||
if (!via) {
|
||||
return cbk(null, title);
|
||||
}
|
||||
|
||||
return cbk(null, `${title} via ${getNode.alias}`);
|
||||
}],
|
||||
|
||||
// Earnings
|
||||
earnings: ['description', 'fees', ({description, fees}, cbk) => {
|
||||
return cbk(null, {description, fees});
|
||||
earnings: [
|
||||
'description',
|
||||
'fees',
|
||||
'title',
|
||||
({description, fees, title}, cbk) =>
|
||||
{
|
||||
return cbk(null, {description, fees, title});
|
||||
}],
|
||||
},
|
||||
returnResult({reject, resolve, of: 'earnings'}, cbk));
|
||||
|
|
|
|||
50
test/lnd/test_lnd_directory.js
Normal file
50
test/lnd/test_lnd_directory.js
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
const {test} = require('tap');
|
||||
|
||||
const lndDirectory = require('./../../lnd/lnd_directory');
|
||||
|
||||
const tests = [
|
||||
{
|
||||
args: {},
|
||||
description: 'Operating system methods are required',
|
||||
error: 'ExpectedOperatingSytemMethodsToDetermineLndDirectory',
|
||||
},
|
||||
{
|
||||
args: {os: {}},
|
||||
description: 'Homedir method is required',
|
||||
error: 'ExpectedHomedirFunctionToDetermineLndDirectory',
|
||||
},
|
||||
{
|
||||
args: {os: {homedir: () => 'homedir'}},
|
||||
description: 'Platform method is required',
|
||||
error: 'ExpectedPlatformFunctionToDetermineLndDirectory',
|
||||
},
|
||||
{
|
||||
args: {os: {homedir: () => 'homedir', platform: () => 'darwin'}},
|
||||
description: 'Mac directory is returned',
|
||||
expected: {path: 'homedir/Library/Application Support/Lnd'},
|
||||
},
|
||||
{
|
||||
args: {os: {homedir: () => 'homedir', platform: () => 'win32'}},
|
||||
description: 'Windows directory is returned',
|
||||
expected: {path: 'homedir/Lnd'},
|
||||
},
|
||||
{
|
||||
args: {os: {homedir: () => 'homedir', platform: () => 'linux'}},
|
||||
description: 'Linux directory is returned',
|
||||
expected: {path: 'homedir/.lnd'},
|
||||
},
|
||||
];
|
||||
|
||||
tests.forEach(({args, description, error, expected}) => {
|
||||
return test(description, async ({end, equal, throws}) => {
|
||||
if (!!error) {
|
||||
throws(() => lndDirectory(args), new Error(error), 'Got expected error');
|
||||
} else {
|
||||
const {path} = await lndDirectory(args);
|
||||
|
||||
equal(path, expected.path, 'Got expected path');
|
||||
}
|
||||
|
||||
return end();
|
||||
});
|
||||
});
|
||||
|
|
@ -21,12 +21,12 @@ const tests = [
|
|||
args: {data: 'elements'},
|
||||
description: 'Data returns a chart and description',
|
||||
expected: [
|
||||
'',
|
||||
'\n title\n',
|
||||
' 3.00 ┤ ╭ \n 2.87 ┤ │ \n 2.73 ┤ │ \n 2.60 ┤ │ \n 2.47 ┤ │ \n 2.33 ┤ │ \n 2.20 ┤ │ \n 2.07 ┤ │ \n 1.93 ┤╭╯ \n 1.80 ┤│ \n 1.67 ┤│ \n 1.53 ┤│ \n 1.40 ┤│ \n 1.27 ┤│ \n 1.13 ┤│ \n 1.00 ┼╯ ',
|
||||
'\n description',
|
||||
'\n description',
|
||||
'',
|
||||
],
|
||||
res: {description: 'description', elements: [1,2,3]},
|
||||
res: {description: 'description', elements: [1,2,3], title: 'title'},
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ tests.forEach(({args, description, error, expected, res}) => {
|
|||
logger,
|
||||
data: args.data,
|
||||
resolve: () => {
|
||||
deepIs(loggedInfo, expected, 'Got expected info');
|
||||
deepIs(loggedInfo.join('\n'), expected.join('\n'), 'Got expected info');
|
||||
|
||||
return end();
|
||||
},
|
||||
|
|
|
|||
62
test/routing/test_get_fees_chart.js
Normal file
62
test/routing/test_get_fees_chart.js
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
const {test} = require('tap');
|
||||
|
||||
const {getFeesChart} = require('./../../routing');
|
||||
|
||||
const tests = [
|
||||
{
|
||||
args: {},
|
||||
description: 'Days duration is required to get fees chart',
|
||||
error: [400, 'ExpectedNumberOfDaysToGetFeesOverForChart'],
|
||||
},
|
||||
{
|
||||
args: {days: 1},
|
||||
description: 'LND is required to get fees chart',
|
||||
error: [400, 'ExpectedLndToGetFeesChart'],
|
||||
},
|
||||
{
|
||||
args: {
|
||||
days: 1,
|
||||
lnd: {
|
||||
default: {
|
||||
forwardingHistory: ({}, cbk) => cbk(null, {
|
||||
forwarding_events: [],
|
||||
last_offset_index: '0',
|
||||
}),
|
||||
getNodeInfo: ({}, cbk) => cbk(null, {
|
||||
channels: [],
|
||||
node: {
|
||||
addresses: [],
|
||||
alias: 'alias',
|
||||
color: '#000000',
|
||||
last_update: '1',
|
||||
pub_key: 'a',
|
||||
},
|
||||
num_channels: 1,
|
||||
total_capacity: '1',
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
description: 'Fee earnings chart data is returned',
|
||||
expected: {
|
||||
fees: '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0',
|
||||
title: 'Routing fees earned',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
tests.forEach(({args, description, error, expected}) => {
|
||||
return test(description, async ({end, equal, rejects}) => {
|
||||
if (!!error) {
|
||||
rejects(getFeesChart(args), error, 'Got expected error');
|
||||
} else {
|
||||
const {description, fees, title} = await getFeesChart(args);
|
||||
|
||||
equal(!!description, true, 'Got description');
|
||||
equal(fees.join(','), expected.fees, 'Got expected fees');
|
||||
equal(title, expected.title, 'Got expected title');
|
||||
}
|
||||
|
||||
return end();
|
||||
});
|
||||
});
|
||||
250
wallets/fund_dev.js
Normal file
250
wallets/fund_dev.js
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
const {stringify} = require('querystring');
|
||||
const {URL} = require('url');
|
||||
|
||||
const asyncAuto = require('async/auto');
|
||||
const {parsePaymentRequest} = require('ln-service');
|
||||
const {payViaPaymentRequest} = require('ln-service');
|
||||
const {returnResult} = require('asyncjs-util');
|
||||
|
||||
const {accounts} = require('./funding');
|
||||
const {getExchangeRates} = require('./../fiat');
|
||||
const {probeDestination} = require('./../network');
|
||||
const {shuffle} = require('./../arrays');
|
||||
|
||||
const baseUrl = 'https://github.com/alexbosworth/balanceofsatoshis/issues/new';
|
||||
const centsPerDollar = 100;
|
||||
const centsPrecision = 3;
|
||||
const currency = 'USD';
|
||||
const daysPerMonth = 30;
|
||||
const delayMs = 1000;
|
||||
const maxFee = 1337;
|
||||
const maxPathfindingTimeMs = 1000 * 60 * 10;
|
||||
const mtokensPerToken = BigInt(1e3);
|
||||
const satsPerBtc = 1e8;
|
||||
const tippinApi = 'https://api.tippin.me/v1/public/addinvoice';
|
||||
|
||||
/** Send some money to a worthy tippin.me receiver
|
||||
|
||||
{
|
||||
[is_dry_run]: <Avoid Actually Sending Money Bool>
|
||||
lnd: <Authenticated LND gRPC API Object>
|
||||
logger: <Winston Logger Object>
|
||||
request: <Request Function>
|
||||
[to_twitter_account]: <Send Money to Twitter Account String>
|
||||
tokens: <Send Tokens Number>
|
||||
}
|
||||
|
||||
@returns via cbk or Promise
|
||||
{
|
||||
[payment]: {
|
||||
proof: <Preimage Hex String>
|
||||
routing_fee: <Routing Fee Tokens Number>
|
||||
sent: <Tokens Number>
|
||||
}
|
||||
}
|
||||
*/
|
||||
module.exports = (args, cbk) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
return asyncAuto({
|
||||
// Check arguments
|
||||
validate: cbk => {
|
||||
if (!args.lnd) {
|
||||
return cbk([400, 'ExpectedLndToFundDev']);
|
||||
}
|
||||
|
||||
if (!args.logger) {
|
||||
return cbk([400, 'ExpectedLoggerToFundDev']);
|
||||
}
|
||||
|
||||
if (!args.request) {
|
||||
return cbk([400, 'ExpectedRequestFunctionToFundDev']);
|
||||
}
|
||||
|
||||
if (!args.tokens) {
|
||||
return cbk([400, 'ExpectedTokensToFundDev']);
|
||||
}
|
||||
|
||||
return cbk();
|
||||
},
|
||||
|
||||
// Get exchange rate
|
||||
getRate: ['validate', ({}, cbk) => getExchangeRates({symbols: []}, cbk)],
|
||||
|
||||
// Select a recipient
|
||||
recipient: ['validate', ({}, cbk) => {
|
||||
// Exit early when a @name was specified
|
||||
if (/^@.*/.test(args.to_twitter_account)) {
|
||||
return cbk(null, args.to_twitter_account.slice('@'.length));
|
||||
}
|
||||
|
||||
// Exit early when a url is specified
|
||||
if (/^https:\/\/twitter\.com\/.*/.test(args.to_twitter_account)) {
|
||||
const {pathname} = new URL(args.to_twitter_account);
|
||||
|
||||
return cbk(null, pathname.slice('/'.length));
|
||||
}
|
||||
|
||||
// Exit early when a username was specified
|
||||
if (!!args.to_twitter_account) {
|
||||
return cbk(null, args.to_twitter_account);
|
||||
}
|
||||
|
||||
const [lucky] = shuffle({array: accounts}).shuffled;
|
||||
|
||||
return cbk(null, lucky.twitter_username);
|
||||
}],
|
||||
|
||||
// Request an invoice for the recipient
|
||||
getRequest: ['getRate', 'recipient', ({getRate, recipient}, cbk) => {
|
||||
const {tickers} = getRate;
|
||||
|
||||
const [{rate}] = tickers;
|
||||
|
||||
const fiat = args.tokens / satsPerBtc * rate / centsPerDollar;
|
||||
|
||||
const monthly = (fiat * daysPerMonth).toFixed(centsPrecision);
|
||||
|
||||
args.logger.info({
|
||||
will_fund: `https://twitter.com/@${recipient}`,
|
||||
amount_to_send: args.tokens,
|
||||
amount_to_send_fiat: `$${fiat.toFixed(centsPrecision)} ${currency}`,
|
||||
if_daily_monthly_amount: `$${monthly} ${currency}`,
|
||||
});
|
||||
|
||||
return args.request({
|
||||
json: true,
|
||||
url: `${tippinApi}/${recipient}/${args.tokens}`,
|
||||
},
|
||||
(err, r, invoice) => {
|
||||
if (!!err) {
|
||||
return cbk([503, 'UnexpectedErrorContactingTippinMeApi', {err}]);
|
||||
}
|
||||
|
||||
if (!r) {
|
||||
return cbk([503, 'UnexpectedLackOfResponseFromTippinMeApi']);
|
||||
}
|
||||
|
||||
if (!!invoice && !!invoice.error) {
|
||||
return cbk([503, 'TippinMeInvoiceFailed', {err: invoice.message}]);
|
||||
}
|
||||
|
||||
if (!invoice || !invoice.lnreq) {
|
||||
return cbk([503, 'UnexpectedResponseFromTippinMeApi']);
|
||||
}
|
||||
|
||||
const request = invoice.lnreq;
|
||||
|
||||
try {
|
||||
parsePaymentRequest({request});
|
||||
} catch (err) {
|
||||
return cbk([503, 'FailedToPraseTippinMePaymentRequest']);
|
||||
}
|
||||
|
||||
if (parsePaymentRequest({request}).tokens !== args.tokens) {
|
||||
return cbk([503, 'UnexpectedTokensValueFromTippinMeRequest']);
|
||||
}
|
||||
|
||||
return cbk(null, request);
|
||||
});
|
||||
}],
|
||||
|
||||
// Delay execution
|
||||
delay: ['getRequest', ({}, cbk) => setTimeout(cbk, delayMs)],
|
||||
|
||||
// Probe
|
||||
probe: ['delay', 'getRequest', ({getRequest}, cbk) => {
|
||||
args.logger.info({checking_route_to_send: args.tokens});
|
||||
|
||||
return probeDestination({
|
||||
lnd: args.lnd,
|
||||
logger: args.logger,
|
||||
request: getRequest,
|
||||
},
|
||||
cbk);
|
||||
}],
|
||||
|
||||
// Pay
|
||||
pay: ['getRequest', 'probe', ({getRequest}, cbk) => {
|
||||
if (!!args.is_dry_run) {
|
||||
return cbk();
|
||||
}
|
||||
|
||||
return payViaPaymentRequest({
|
||||
lnd: args.lnd,
|
||||
max_fee: maxFee,
|
||||
pathfinding_timeout: maxPathfindingTimeMs,
|
||||
request: getRequest,
|
||||
},
|
||||
cbk);
|
||||
}],
|
||||
|
||||
// Get a shortened champion URL
|
||||
championUrl: [
|
||||
'getRequest',
|
||||
'pay',
|
||||
'recipient',
|
||||
({getRequest, pay, recipient}, cbk) =>
|
||||
{
|
||||
if (!pay) {
|
||||
return cbk();
|
||||
}
|
||||
|
||||
const body = [
|
||||
`I champion https://twitter.com/${recipient}!`,
|
||||
'',
|
||||
`+${args.tokens}`,
|
||||
'',
|
||||
`${getRequest} ${pay.secret}`,
|
||||
];
|
||||
|
||||
const issueTemplate = {
|
||||
body: body.join('\n'),
|
||||
title: `Champion Funding Recipient: @${recipient}`,
|
||||
};
|
||||
|
||||
return args.request({
|
||||
form: {url: `${baseUrl}?${stringify(issueTemplate)}`},
|
||||
method: 'POST',
|
||||
url: 'https://git.io',
|
||||
},
|
||||
(err, r) => {
|
||||
if (!!err) {
|
||||
args.logger.error({err});
|
||||
|
||||
return cbk();
|
||||
}
|
||||
|
||||
if (!r || !r.headers.location) {
|
||||
args.logger.error({err: [503, 'ExpectedChampionLocationHeader']});
|
||||
|
||||
return cbk();
|
||||
}
|
||||
|
||||
return cbk(null, r.headers.location);
|
||||
});
|
||||
}],
|
||||
|
||||
// Final result
|
||||
result: [
|
||||
'championUrl',
|
||||
'pay',
|
||||
'recipient',
|
||||
({championUrl, pay, recipient}, cbk) =>
|
||||
{
|
||||
if (!pay) {
|
||||
return cbk(null, {});
|
||||
}
|
||||
|
||||
return cbk(null, {
|
||||
payment: {
|
||||
recipient: `https://twitter.com/${recipient}`,
|
||||
funded: args.tokens,
|
||||
routing_fee: Number(BigInt(pay.fee_mtokens) / mtokensPerToken),
|
||||
champion_this_recipient: championUrl,
|
||||
},
|
||||
});
|
||||
}],
|
||||
},
|
||||
returnResult({reject, resolve, of: 'result'}, cbk));
|
||||
});
|
||||
};
|
||||
103
wallets/funding.json
Normal file
103
wallets/funding.json
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
{
|
||||
"accounts": [
|
||||
{
|
||||
"twitter_username": "8bitgomes"
|
||||
},
|
||||
{
|
||||
"twitter_username": "actuallycarlakc"
|
||||
},
|
||||
{
|
||||
"twitter_username": "alexbosworth"
|
||||
},
|
||||
{
|
||||
"twitter_username": "benthecarman"
|
||||
},
|
||||
{
|
||||
"twitter_username": "bitconner"
|
||||
},
|
||||
{
|
||||
"twitter_username": "blockstream"
|
||||
},
|
||||
{
|
||||
"twitter_username": "breez_tech"
|
||||
},
|
||||
{
|
||||
"twitter_username": "eiprol"
|
||||
},
|
||||
{
|
||||
"twitter_username": "fiatjaf"
|
||||
},
|
||||
{
|
||||
"twitter_username": "fulmolightning"
|
||||
},
|
||||
{
|
||||
"twitter_username": "gugol"
|
||||
},
|
||||
{
|
||||
"twitter_username": "jackmallers"
|
||||
},
|
||||
{
|
||||
"twitter_username": "jamaljsr"
|
||||
},
|
||||
{
|
||||
"twitter_username": "joostjgr"
|
||||
},
|
||||
{
|
||||
"twitter_username": "juscamarena"
|
||||
},
|
||||
{
|
||||
"twitter_username": "lightninginabox"
|
||||
},
|
||||
{
|
||||
"twitter_username": "lightningk0ala"
|
||||
},
|
||||
{
|
||||
"twitter_username": "ln_zap"
|
||||
},
|
||||
{
|
||||
"twitter_username": "mrfelton"
|
||||
},
|
||||
{
|
||||
"twitter_username": "negrunch"
|
||||
},
|
||||
{
|
||||
"twitter_username": "niftynei"
|
||||
},
|
||||
{
|
||||
"twitter_username": "pierre_rochard"
|
||||
},
|
||||
{
|
||||
"twitter_username": "provoost"
|
||||
},
|
||||
{
|
||||
"twitter_username": "renepickhardt"
|
||||
},
|
||||
{
|
||||
"twitter_username": "roquerrt"
|
||||
},
|
||||
{
|
||||
"twitter_username": "rusty_twit"
|
||||
},
|
||||
{
|
||||
"twitter_username": "snyke"
|
||||
},
|
||||
{
|
||||
"twitter_username": "stadicus3000"
|
||||
},
|
||||
{
|
||||
"twitter_username": "starkness"
|
||||
},
|
||||
{
|
||||
"twitter_username": "stepansnigirev"
|
||||
},
|
||||
{
|
||||
"twitter_username": "wbobeirne"
|
||||
},
|
||||
{
|
||||
"twitter_username": "whiteyhat"
|
||||
},
|
||||
{
|
||||
"twitter_username": "zeusln"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
const fundDev = require('./fund_dev');
|
||||
const getReport = require('./get_report');
|
||||
const unlockWallet = require('./unlock_wallet');
|
||||
|
||||
module.exports = {getReport, unlockWallet};
|
||||
module.exports = {fundDev, getReport, unlockWallet};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue