Started work on the next version of tipbot.

This commit is contained in:
filipnyquist 2018-07-02 15:43:16 +02:00
parent 4aa3681f53
commit b0df0addbf
11 changed files with 958 additions and 1756 deletions

91
.gitignore vendored
View file

@ -1,21 +1,76 @@
# Created by http://www.gitignore.io
### Node ###
lib-cov
lcov.info
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
pids
# Logs
logs
results
build
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
.idea/
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
node_modules
config/config.yml
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless
# Configurations
default.json

View file

@ -1 +0,0 @@
/lib/

20
LICENSE
View file

@ -1,20 +0,0 @@
Copyright (c) 2014 unek <unekpl@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -1,74 +0,0 @@
This is a fork of node-tip-bot-twitter, an open-source node.js twitter bot for tipping with altcoins.
In particular, this fork is for [LBC](https://lbry.io/). LBRY.io, the network behind it, describes
itself as:
```
...a free, open, and community-run digital marketplace.
You own your data. You control the network. Indeed, you are the network.
Hollywood films, college lessons, amazing streamers and more are on the first media network ruled by you.
```
If you want to get started with LBRY.io, go to https://lbry.io/get. If you wish to set up your own twitter
tip bot, it may be more beneficial to start with the [original node-tip-bot-twitter](https://github.com/gameunits/node-tip-bot-twitter).
# Installation
To install node-tip-bot simply clone this repo and install dependencies:
```bash
git clone https://github.com/gameunits/node-tip-bot-twitter
cd node-tip-bot-twitter
npm install
```
After installation proceed to the configuration.
# Configuration
To configure, copy the `config/config.sample.yml` file to `config/config.yml`.
## twitter
Create an application at dev.twitter.com and fill in your keys.
* **consumer_key: ''
* **consumer_secret: ''
* **access_token_key: ''
* **access_token_secret: ''
## log
Logging settings.
* **file** - file to log to. Set to `false` to disable logging to file.
## rpc
JSON RPC API connection info.
* **host** - JSON RPC API hostname
* **port** - API port (by default 1337)
* **user** - API username
* **pass** - API password (keep that secure)
## coin
Basic coin settings.
* **withdrawal_fee** - fee charged on withdraw to cover up txfee, the rest goes to bot's wallet.
* **min_withdraw** - minimum amount of coins to withdraw
* **min_confirmations** - minimum amount of confirmations needed to tip/withdraw coins
* **min_tip** - minimum amount of coins to tip
# How to run it?
Before running the bot, you have to be running your coin daemon with JSON-RPC API enabled. To enable, add this to your coin daemon configuration file (eg. `~/.gameunits/gameunits.conf`):
```ini
server=1
daemon=1
rpcuser=<your username>
rpcpassword=<your super secret password>
rpcallowip=<your bot's ip address or just 127.0.0.1 if hosted on the same machine>
```
To run the bot simply use `node bin/tipbot` or `npm start`.
## Commands
Commands are executed by placing gameunits <command> <arguments> in a tweet.
| **Command** | **Arguments** | **Description**
|-------------|-------------------|--------------------------------------------------------------------
| `balance` | | displays your current wallet balance
| `address` | | displays address where you can send your funds to the tip bot
| `withdraw` | `<address>` | withdraws your whole wallet balance to specified address
| `tip` | `<nick> <amount>` | sends the specified amount of coins to the specified nickname
| `help` | | displays configured help message (by default similiar to this one)
| `terms` | | displays terms and conditions for using the tip bot

View file

@ -1,325 +0,0 @@
const winston = require('winston'),
fs = require('fs'),
yaml = require('js-yaml'),
coind = require('node-gameunits');
const Twitter = require('twitter');
// check if the config file exists
if (!fs.existsSync('./config/config.yml')) {
winston.error("Configuration file doesn't exist! Please read the README.md file first.");
process.exit(1);
}
// load settings
const settings = yaml.load(fs.readFileSync('./config/config.yml', 'utf-8'));
// load winston's cli defaults
winston.cli();
// write logs to file
if (settings.log.file) {
winston.add(winston.transports.File, {
filename: settings.log.file,
level: 'debug'
});
}
// connect to coin json-rpc
winston.info('Connecting to coind...');
let coin = coind({
host: settings.rpc.host,
port: settings.rpc.port,
user: settings.rpc.user,
pass: settings.rpc.pass
});
// checking if we are connected.
coin.getBalance(function (err, balance) {
if (err) {
winston.error('Could not connect to %s RPC API! ', settings.coin.full_name, err);
process.exit(1);
return;
}
var balance = typeof balance == 'object' ? balance.result : balance;
winston.info('Connected to JSON RPC API. Current total balance is %d' + settings.coin.short_name, balance);
});
// connect to twitter
winston.info('Connecting to Twitter');
var client = new Twitter({
consumer_key: settings.twitter.consumer_key,
consumer_secret: settings.twitter.consumer_secret,
access_token_key: settings.twitter.access_token_key,
access_token_secret: settings.twitter.access_token_secret
});
//
client.get('followers/ids', function (error, tweets, response) {
if (error) {
console.log(error);
}
winston.info('Connected to Twitter. Followers:' + tweets.ids.length);
});
// basic handlers
var locks = [];
function makeid() {
var text = '';
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i = 0; i < 5; i++) text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
function replytweet(to, replyid, themessage) {
winston.info('Preparing tweet' + '@' + to + ' :' + themessage);
var newtweet = '@' + to + ' ' + themessage + ' \nMsg_ID:(' + makeid() + ')';
winston.info('' + '@' + to + ' :' + newtweet);
client.post('statuses/update', {
status: newtweet,
in_reply_to_status_id: replyid
}, function (error, params, response) {
if (error) {
console.log(error);
//throw error;
}
console.log('Tweeting');
});
}
function getAddress(nickname, callback) {
winston.debug('Requesting address for %s', nickname);
coin.send('getaccountaddress', settings.rpc.prefix + nickname.toLowerCase(), function (err, address) {
if (err) {
winston.error('Something went wrong while getting address. ' + err);
callback(err);
return false;
}
callback(false, address);
});
}
String.prototype.expand = function (values) {
var global = {
nick: settings.twitter.twittername
};
return this.replace(/%([a-zA-Z_]+)%/g, function (str, variable) {
return typeof values[variable] == 'undefined' ? (typeof settings.coin[variable] == 'undefined' ? (typeof global[variable] == 'undefined' ? str : global[variable]) : settings.coin[variable]) : values[variable];
});
};
client.stream('statuses/filter', {track: settings.twitter.twitterkeyword}, function (stream) {
stream.on('error', function (error) {
winston.error('Something went wrong with the twitter streaming api.');
winston.error(error);
});
stream.on('end', function (reason) {
winston.error('Twitter streaming api failed with');
winston.error(reason);
});
stream.on('data', function (tweet) {
console.log('@' + tweet.user.screen_name + '|' + tweet.text);
if (tweet.text.substring(0, 2) === 'RT') {
console.log('Retweet Ingrored');
return;
}
var regex = new RegExp('(' + settings.twitter.twitterkeyword + ')(\\s)([a-zA-Z]+)', 'i');
var match = tweet.text.match(regex);
if (match == null) return;
var command = match[3];
var from = tweet.user.screen_name;
var msg = tweet.txt;
var message = tweet.text;
var replyid = tweet.id_str;
if (command == 'help' || command == 'terms') {
for (var i = 0; i < settings.messages[command].length; i++) {
replytweet(from, replyid, settings.messages[command][i].expand({}));
}
return;
}
switch (command) {
case 'tip':
var regex = new RegExp('(' + settings.twitter.twitterkeyword + ')(\\s)([a-zA-Z]+)(\\s)(\\@)(.+)(\\s)(.+)', 'i'); //Uglyfix
var match = tweet.text.match(regex);
console.log('tip');
console.log(match[0] + ',' + match[1] + ',' + match[2] + ',' + match[3] + ',' + match[4] + ',' + match[5] + ',' + match[6] + ',' + match[7] + ',' + match[8]);
if (match == null || match.length < 3) {
replytweet(from, replyid, 'Usage: nameofbot tip <twitterhandle> <amount>');
return;
}
var to = match[6];
var amount = Number(match[8]);
console.log('To:' + amount);
// lock
if (locks.hasOwnProperty(from.toLowerCase()) && locks[from.toLowerCase()]) return;
locks[from.toLowerCase()] = true;
if (isNaN(amount)) {
locks[from.toLowerCase()] = null;
replytweet(from, replyid, settings.messages.invalid_amount.expand({name: from, amount: match[8]}));
return;
}
if (to.toLowerCase() == from.toLowerCase()) {
locks[from.toLowerCase()] = null;
replytweet(from, replyid, settings.messages.tip_self.expand({name: from}));
return;
}
if (amount < settings.coin.min_tip) {
locks[from.toLowerCase()] = null;
replytweet(from, replyid, settings.messages.tip_too_small.expand({
from: from,
to: to,
amount: amount
}));
return;
}
// check balance with min. 5 confirmations
coin.getBalance(settings.rpc.prefix + from.toLowerCase(), settings.coin.min_confirmations, function (err, balance) {
if (err) {
locks[from.toLowerCase()] = null;
winston.error('Error in tip command.', err);
replytweet(from, replyid, settings.messages.error.expand({name: from}));
return;
}
var balance = typeof balance == 'object' ? balance.result : balance;
if (balance >= amount) {
coin.send('move', settings.rpc.prefix + from.toLowerCase(), settings.rpc.prefix + to.toLowerCase(), amount, function (err, reply) {
locks[from.toLowerCase()] = null;
if (err || !reply) {
winston.error('Error in tip command', err);
replytweet(from, replyid, settings.messages.error.expand({name: from}));
return;
}
winston.info('%s tipped %s %d%s', from, to, amount, settings.coin.short_name);
replytweet(from, replyid, settings.messages.tipped.expand({
from: from,
to: to,
amount: amount
}));
});
} else {
locks[from.toLowerCase()] = null;
winston.info('%s tried to tip %s %d, but has only %d', from, to, amount, balance);
replytweet(from, replyid, settings.messages.no_funds.expand({
name: from,
balance: balance,
short: amount - balance,
amount: amount
}));
}
});
break;
case 'deposit':
case 'address':
console.log('adress');
var user = from.toLowerCase();
getAddress(user, function (err, address) {
if (err) {
winston.error('Error in address command', err);
replytweet(from, replyid, settings.messages.error.expand({name: from}));
return;
}
replytweet(from, replyid, settings.messages.deposit_address.expand({name: user, address: address}));
});
break;
case 'balance':
console.log('balance');
var user = from.toLowerCase();
coin.getBalance(settings.rpc.prefix + user, settings.coin.min_confirmations, function (err, balance) {
if (err) {
winston.error('Error in balance command', err);
replytweet(from, replyid, settings.messages.error.expand({name: from}));
return;
}
var balance = typeof balance == 'object' ? balance.result : balance;
coin.getBalance(settings.rpc.prefix + user, 0, function (err, unconfirmed_balance) {
if (err) {
winston.error('Error in balance command', err);
replytweet(from, replyid, settings.messages.balance.expand({balance: balance, name: user}));
return;
}
var unconfirmed_balance = typeof unconfirmed_balance == 'object' ? unconfirmed_balance.result : unconfirmed_balance;
replytweet(from, replyid, settings.messages.balance_unconfirmed.expand({
balance: balance,
name: user,
unconfirmed: unconfirmed_balance - balance
}));
});
});
break;
case 'withdraw':
console.log('withdrawl');
var user = from.toLowerCase();
var match = message.match(/.?withdraw (\S+)$/);
if (match == null) {
replytweet(from, replyid, 'Usage: withdraw <' + settings.coin.full_name + ' address>');
return;
}
var address = match[1];
coin.validateAddress(address, function (err, reply) {
if (err) {
winston.error('Error in withdraw command', err);
replytweet(from, replyid, settings.messages.error.expand({name: from}));
return;
}
if (reply.isvalid) {
coin.getBalance(settings.rpc.prefix + from.toLowerCase(), settings.coin.min_confirmations, function (err, balance) {
if (err) {
winston.error('Error in withdraw command', err);
replytweet(from, replyid, settings.messages.error.expand({name: from}));
return;
}
var balance = typeof balance == 'object' ? balance.result : balance;
if (balance < settings.coin.min_withdraw) {
winston.warn('%s tried to withdraw %d, but min is set to %d', from, balance, settings.coin.min_withdraw);
replytweet(from, replyid, settings.messages.withdraw_too_small.expand({
name: from,
balance: balance
}));
return;
}
coin.sendFrom(settings.rpc.prefix + from.toLowerCase(), address, balance - settings.coin.withdrawal_fee, function (err, reply) {
if (err) {
winston.error('Error in withdraw command', err);
replytweet(from, replyid, settings.messages.error.expand({name: from}));
return;
}
var values = {
name: from,
address: address,
balance: balance,
amount: balance - settings.coin.withdrawal_fee,
transaction: reply
};
for (var i = 0; i < settings.messages.withdraw_success.length; i++) {
var msg = settings.messages.withdraw_success[i];
replytweet(from, replyid, msg.expand(values));
}
// transfer the rest (withdrawal fee - txfee) to bots wallet
coin.getBalance(settings.rpc.prefix + from.toLowerCase(), function (err, balance) {
if (err) {
winston.error('Something went wrong while transferring fees', err);
return;
}
var balance = typeof balance == 'object' ? balance.result : balance;
// moves the rest to bot's wallet
coin.move(settings.rpc.prefix + from.toLowerCase(), settings.rpc.prefix + settings.twitter.twittername.toLowerCase(), balance);
});
});
});
} else {
winston.warn('%s tried to withdraw to an invalid address', from);
replytweet(from, replyid, settings.messages.invalid_address.expand({
address: address,
name: from
}));
}
});
break;
default:
winston.warn('Invalid Command' + command);
replytweet(from, replyid, 'Invalid command. Tweet "@LBC_TipBot lbryian help" for list of commands or see reply below');
break;
}
});
});

View file

@ -1,80 +0,0 @@
twitter:
consumer_key: ''
consumer_secret: ''
access_token_key: ''
access_token_secret: ''
twittername: ''
twitterkeyword: 'gameunitsbot'
log:
file: tipbot.log
rpc:
host: localhost
port: 1337
user: gameunitsrpc
pass: pass
prefix: ''
coin:
withdrawal_fee: 1
min_withdraw: 1
min_confirmations: 10
min_tip: 0.1
min_rain: 1
short_name: ' UNITS'
full_name: Gameunits
webadmin:
enabled: false
port: 8080
users:
unek: supersecretpassword
admintwo: password
commands:
help:
pm: true
channel: false
tip:
pm: true
channel: true
balance:
pm: true
channel: false
withdraw:
pm: true
channel: false
address:
pm: true
channel: false
terms:
pm: true
channel: false
rain:
pm: false
channel: true
rain_on_last_active: 0 # amount in seconds. rain tips will fall only on users active within x seconds. leave 0 for no such behavior.
messages:
error: 'Sorry %name%, something went wrong.'
no_funds: "Sorry %name%, you don't have enough funds (you're %short%%short_name% short)"
not_identified: '%name%: You need to be identified with NickServ to tip.'
tipped: ' Tipped @%to% %amount%%short_name%! "tweet @%nick% gameunits help" to claim.'
balance: '%name% has %balance%%short_name%.'
balance_unconfirmed: '%name% has %balance%%short_name% (unconfirmed: %unconfirmed%%short_name%)'
deposit_address: Your deposit address %address%
withdraw_too_small: 'Sorry %name%, you need to withdraw at least %min_withdraw%%short_name% (you have %balance%%short_name%)'
invalid_address: 'Sorry %name%, the address you specified is invalid (%address%).'
tip_too_small: 'Sorry %from%, your tip to %to% (%amount%%short_name%) is too small (min. %min_tip%%short_name%).'
tip_self: "Sorry %name%, you can't tip yourself!"
invalid_amount: 'Sorry %name%, "%amount%" is not a correct amount.'
withdraw_success:
- '%name%: %amount%%short_name% has been withdrawn from your account to %address%'
- 'You have been charged %withdrawal_fee%%short_name% withdrawal fee.'
- 'Transaction %transaction% completed.'
help:
- 'You can use following commands:'
- 'balance - displays your current wallet balance'
- 'address - displays %full_name% your depositaddress'
- 'withdraw <%full_name% address> - withdraws your whole wallet balance to specified address (minus %withdrawal_fee%%short_name% withdrawal fee)'
- 'tip <nick> <amount> - sends the specified amount of %full_name% to nickname'
- 'terms - displays terms and conditions for using %nick%'
- 'payout - How can I withdraw my Gameunits from tipbot ? Just Download Gameunits client from : http://gameunits.org/#downloads'
terms:
- 'There are no fees to use %nick%, with the exception of %withdrawal_fee%%short_name% fee on withdrawals.'
- 'In no event shall %nick% be responsible in the event of lost, stolen or misdirected funds.'

View file

@ -0,0 +1,13 @@
{
"twitter": {
"consumer_key": "****",
"consumer_secret": "****",
"access_token": "****",
"access_token_secret": "****"
},
"lbrycrd": {
"username": "lbry",
"password": "lbry",
"port": 9245
}
}

209
index.js Normal file
View file

@ -0,0 +1,209 @@
const Twit = require("twit");
const config = require("config");
const winston = require("winston");
require("winston-daily-rotate-file");
const Client = require("bitcoin-core");
const lbry = new Client({
version: "0.12.0",
username: config.get("lbrycrd.username"),
password: config.get("lbrycrd.password"),
port: config.get("lbrycrd.port")
});
const logger = winston.createLogger({
level: "info",
format: winston.format.json(),
transports: [
new winston.transports.DailyRotateFile({
filename: "tipbot-%DATE%.log",
dirname: "./logs",
datePattern: "YYYY-MM-DD-HH",
zippedArchive: true,
maxSize: "20m",
maxFiles: "14d"
}),
new winston.transports.Console({
format: winston.format.simple(),
level: "debug"
})
]
});
const T = new Twit({
consumer_key: config.get("twitter.consumer_key"),
consumer_secret: config.get("twitter.consumer_secret"),
access_token: config.get("twitter.access_token"),
access_token_secret: config.get("twitter.access_token_secret"),
timeout_ms: 60 * 1000, // optional HTTP request timeout to apply to all requests.
strictSSL: true // optional - requires SSL certificates to be valid.
});
var stream = T.stream("statuses/filter", { track: "@devlbctipbot" });
logger.info("Started LBRY twitter tipbot.");
stream.on("tweet", function(tweet) {
let msg = checkTrunc(tweet);
msg = msg.slice(msg.indexOf("@devlbctipbot")).split(" ");
checkTweet(tweet, msg);
});
function checkTweet(tweet, msg) {
switch (msg[1]) {
case "help":
doHelp(tweet, msg);
break;
case "balance":
doBalance(tweet, msg);
break;
case "deposit":
doDeposit(tweet, msg);
break;
case "withdraw":
doWithdraw(tweet, msg);
break;
case "tip":
doTip(tweet, msg);
break;
}
}
async function doHelp(tweet, msg) {
try {
let post = await T.post("statuses/update", {
status:
"All commands should be called with @ devlbctipbot \n" +
"help - Shows this command. \n" +
"balance - Get your balance. \n" +
"deposit - Get address for your deposits. \n" +
"withdraw ADDRESS AMOUNT - Withdraw AMOUNT credits to ADDRESS. \n" +
"tip USER AMOUNT - Tip USER AMOUNT.",
in_reply_to_status_id: tweet.id_str
});
logger.info(
`Sent help to ${tweet.user.screen_name}, tweet id: ${tweet.id_str}`
);
} catch (e) {
logger.error(e);
}
}
async function doBalance(tweet, msg) {
try {
const balance = await lbry.getBalance(tweet.user.id_str, 3);
const post = await T.post("statuses/update", {
status: `You have ${balance} LBC.`,
in_reply_to_status_id: tweet.id_str
});
logger.info(
`Sent balance command to ${tweet.user.screen_name}, tweet id: ${
tweet.id_str
}`
);
} catch (e) {
logger.error(e);
}
}
async function doDeposit(tweet, msg) {
try {
const post = await T.post("statuses/update", {
status: `Your deposit address is ${await getAddress(tweet.user.id_str)}.`,
in_reply_to_status_id: tweet.id_str
});
logger.info(
`Sent deposit address to ${tweet.user.screen_name}, tweet id: ${
tweet.id_str
}`
);
} catch (e) {
logger.error(e);
}
}
async function doWithdraw(tweet, msg) {
if (msg.length < 4) return doHelp(tweet, msg);
let address = msg[2];
let amount = getValidatedAmount(msg[3]);
if (amount === null) {
return await T.post("statuses/update", {
status: `I don´t know how to withdraw that many credits...`,
in_reply_to_status_id: tweet.id_str
});
}
let txId = await lbry.sendFrom(tweet.user.id_str, address, amount);
await T.post("statuses/update", {
status: `You withdrew ${amount} LBC to ${address}. \n${txLink(txId)}`,
in_reply_to_status_id: tweet.id_str
});
logger.info(
`User ${
tweet.user.screen_name
} withdraw ${amount} LBC to ${address}, tweet id: ${tweet.id_str}`
);
try {
} catch (e) {
logger.error(e);
}
}
async function doTip(tweet, msg) {
try {
if (msg.length < 3) {
return doHelp(tweet, msg);
}
const amount = getValidatedAmount(msg[3]);
if (amount === null) {
return await T.post("statuses/update", {
status: `I don´t know how to tip that many credits...`,
in_reply_to_status_id: tweet.id_str
});
}
const userToTip = userToTip(tweet, msg);
const userToTipAddress = getAddress(userToTip);
if (userToTip === null) {
return await T.post("statuses/update", {
status: `I could not find that user...`,
in_reply_to_status_id: tweet.id_str
});
}
const txId = await lbry.sendFrom(
tweet.user.id_str,
userToTipAddress,
Number(amount),
null,
null
);
logger.info(
`@${tweet.user.screen_name}(${tweet.user.id_str}) tipped ${
msg[2]
}(${userToTip}) ${amount} LBC.`
);
} catch (e) {
logger.error(e);
}
}
async function getAddress(userId) {
try {
let uAddresses = await lbry.getAddressesByAccount(userId);
if (uAddresses.length > 0) return uAddresses[0];
let nAddress = await lbry.getNewAddress(userId);
return nAddress;
} catch (e) {
logger.error(e);
}
}
function userToTip(tweet, msg) {
const username = msg[2];
const users = tweet.entities.user_mentions;
return users.find(u => `@${u.screen_name}` === username).id_str;
}
function getValidatedAmount(amount) {
amount = amount.trim();
if (amount.toLowerCase().endsWith("lbc")) {
amount = amount.substring(0, amount.length - 3);
}
return amount.match(/^[0-9]+(\.[0-9]+)?$/) ? amount : null;
}
function txLink(txId) {
return `https://explorer.lbry.io/tx/${txId}`;
}
function checkTrunc(tweet) {
if (tweet.truncated) return tweet.extended_tweet.full_text;
return tweet.text;
}

1198
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,45 +1,17 @@
{
"name": "node-tip-bot-twitter",
"version": "1.0.2",
"description": "node.js based tipping bot for any coin",
"main": "bin/tipbot",
"dependencies": {
"express": "^3.21.2",
"js-yaml": "^3.11.0",
"node-gameunits": "^0.3.5",
"twitter": "^1.7.1",
"winston": "^2.4.2"
"bitcoin-core": "^2.0.0",
"config": "^1.30.0",
"twit": "^2.2.11",
"winston": "3",
"winston-daily-rotate-file": "^3.2.3"
},
"devDependencies": {
"prettier": "^1.12.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node bin/tipbot",
"prettier": "prettier --write \"{bot,.}/**/*.{js,json}\" --single-quote --print-width 240",
"build": "babel bot -d dist",
"prod": "babel bot -d dist & node dist/bot.js",
"lint": "prettier --write \"{bot,.}/**/*.{js,json}\" --single-quote --print-width 240",
"precommit": "prettier --write \"{bot,.}/**/*.{js,json}\" --single-quote --print-width 240"
},
"repository": {
"type": "git",
"url": "http://github.com/gameunits/node-tip-bot"
},
"author": "gameunits",
"name": "lbry-twitter-tipbot",
"version": "1.0.0",
"description": "A twitter tipbot for LBRY",
"main": "index.js",
"repository": "https://github.com/lbryio/twitter-tipbot/",
"author": "filipnyquist <filip@lbry.io>",
"license": "MIT",
"bugs": {
"url": "https://github.com/gameunits/node-tip-bot/issues"
},
"homepage": "https://github.com/gameunits/node-tip-bot",
"keywords": [
"gameunits",
"bitcoin",
"litecoin",
"altcoin",
"tip",
"tipbot",
"irc",
"bot"
]
"private": false
}

651
yarn.lock Normal file
View file

@ -0,0 +1,651 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@uphold/request-logger@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@uphold/request-logger/-/request-logger-2.0.0.tgz#c585c0bdb94210198945c6597e4fe23d6e63e084"
dependencies:
uuid "^3.0.1"
ajv@^5.1.0:
version "5.5.2"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
dependencies:
co "^4.6.0"
fast-deep-equal "^1.0.0"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
asn1@~0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
async@^2.6.0:
version "2.6.1"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610"
dependencies:
lodash "^4.17.10"
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
aws4@^1.6.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
bcrypt-pbkdf@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
dependencies:
tweetnacl "^0.14.3"
bignumber.js@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-4.1.0.tgz#db6f14067c140bd46624815a7916c92d9b6c24b1"
bitcoin-core@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/bitcoin-core/-/bitcoin-core-2.0.0.tgz#defcd4b3bfb6738ea88051b5fe5a944e32c09df0"
dependencies:
"@uphold/request-logger" "^2.0.0"
bluebird "^3.4.1"
debugnyan "^1.0.0"
json-bigint "^0.2.0"
lodash "^4.0.0"
request "^2.53.0"
semver "^5.1.0"
standard-error "^1.1.0"
bluebird@^3.1.5, bluebird@^3.4.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
bunyan@^1.8.1:
version "1.8.12"
resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.12.tgz#f150f0f6748abdd72aeae84f04403be2ef113797"
optionalDependencies:
dtrace-provider "~0.8"
moment "^2.10.6"
mv "~2"
safe-json-stringify "~1"
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
color-convert@^0.5.0:
version "0.5.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-0.5.3.tgz#bdb6c69ce660fadffe0b0007cc447e1b9f7282bd"
color-name@^1.0.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
color-string@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991"
dependencies:
color-name "^1.0.0"
color@0.8.x:
version "0.8.0"
resolved "https://registry.yarnpkg.com/color/-/color-0.8.0.tgz#890c07c3fd4e649537638911cf691e5458b6fca5"
dependencies:
color-convert "^0.5.0"
color-string "^0.3.0"
colornames@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/colornames/-/colornames-0.0.2.tgz#d811fd6c84f59029499a8ac4436202935b92be31"
colors@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.0.tgz#5f20c9fef6945cb1134260aab33bfbdc8295e04e"
colorspace@1.0.x:
version "1.0.1"
resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.0.1.tgz#c99c796ed31128b9876a52e1ee5ee03a4a719749"
dependencies:
color "0.8.x"
text-hex "0.0.x"
combined-stream@1.0.6, combined-stream@~1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818"
dependencies:
delayed-stream "~1.0.0"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
config@^1.30.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/config/-/config-1.30.0.tgz#1d60a9f35348a13c175798d384e81a5a16c3ba6e"
dependencies:
json5 "0.4.0"
os-homedir "1.0.2"
core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
cycle@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2"
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
dependencies:
assert-plus "^1.0.0"
debug@^2.2.0:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
dependencies:
ms "2.0.0"
debugnyan@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/debugnyan/-/debugnyan-1.0.0.tgz#90386d5ebc2c63588f17f272be5c2a93b7665d83"
dependencies:
bunyan "^1.8.1"
debug "^2.2.0"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
diagnostics@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/diagnostics/-/diagnostics-1.1.0.tgz#e1090900b49523e8527be20f081275205f2ae36a"
dependencies:
colorspace "1.0.x"
enabled "1.0.x"
kuler "0.0.x"
dtrace-provider@~0.8:
version "0.8.7"
resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.7.tgz#dc939b4d3e0620cfe0c1cd803d0d2d7ed04ffd04"
dependencies:
nan "^2.10.0"
ecc-jsbn@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
dependencies:
jsbn "~0.1.0"
enabled@1.0.x:
version "1.0.2"
resolved "https://registry.yarnpkg.com/enabled/-/enabled-1.0.2.tgz#965f6513d2c2d1c5f4652b64a2e3396467fc2f93"
dependencies:
env-variable "0.0.x"
env-variable@0.0.x:
version "0.0.4"
resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.4.tgz#0d6280cf507d84242befe35a512b5ae4be77c54e"
extend@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
extsprintf@^1.2.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
fast-deep-equal@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
fast-safe-stringify@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.4.tgz#4fe828718aa61dbcf9119c3c24e79cc4dea973b2"
fecha@^2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd"
file-stream-rotator@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/file-stream-rotator/-/file-stream-rotator-0.2.1.tgz#0d6fea1a9a7aba25a87cfd31b6e269e44e8f0af2"
dependencies:
moment "^2.11.2"
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
form-data@~2.3.1:
version "2.3.2"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099"
dependencies:
asynckit "^0.4.0"
combined-stream "1.0.6"
mime-types "^2.1.12"
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
dependencies:
assert-plus "^1.0.0"
glob@^6.0.1:
version "6.0.4"
resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
dependencies:
inflight "^1.0.4"
inherits "2"
minimatch "2 || 3"
once "^1.3.0"
path-is-absolute "^1.0.0"
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
har-validator@~5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
dependencies:
ajv "^5.1.0"
har-schema "^2.0.0"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
json-bigint@^0.2.0:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-0.2.3.tgz#118d7f6ff1d38659f19f94cf73e64a75a3f988a8"
dependencies:
bignumber.js "^4.0.0"
json-schema-traverse@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
json5@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.4.0.tgz#054352e4c4c80c86c0923877d449de176a732c8d"
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
dependencies:
assert-plus "1.0.0"
extsprintf "1.3.0"
json-schema "0.2.3"
verror "1.10.0"
kuler@0.0.x:
version "0.0.0"
resolved "https://registry.yarnpkg.com/kuler/-/kuler-0.0.0.tgz#b66bb46b934e550f59d818848e0abba4f7f5553c"
dependencies:
colornames "0.0.2"
lodash@^4.0.0, lodash@^4.17.10:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
logform@^1.6.0, logform@^1.9.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/logform/-/logform-1.9.1.tgz#58b29d7b11c332456d7a217e17b48a13ad69d60a"
dependencies:
colors "^1.2.1"
fast-safe-stringify "^2.0.4"
fecha "^2.3.3"
ms "^2.1.1"
triple-beam "^1.2.0"
mime-db@~1.33.0:
version "1.33.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
mime-types@^2.1.12, mime-types@~2.1.17:
version "2.1.18"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
dependencies:
mime-db "~1.33.0"
mime@^1.3.4:
version "1.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
"minimatch@2 || 3":
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
brace-expansion "^1.1.7"
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
mkdirp@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
dependencies:
minimist "0.0.8"
moment@^2.10.6, moment@^2.11.2:
version "2.22.2"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
ms@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
mv@~2:
version "2.1.1"
resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2"
dependencies:
mkdirp "~0.5.1"
ncp "~2.0.0"
rimraf "~2.4.0"
nan@^2.10.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"
ncp@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3"
oauth-sign@~0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
dependencies:
wrappy "1"
one-time@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/one-time/-/one-time-0.0.4.tgz#f8cdf77884826fe4dff93e3a9cc37b1e4480742e"
os-homedir@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
process-nextick-args@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
qs@~6.5.1:
version "6.5.2"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
readable-stream@^2.3.6:
version "2.3.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~2.0.0"
safe-buffer "~5.1.1"
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
request@^2.53.0, request@^2.68.0:
version "2.87.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e"
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.6.0"
caseless "~0.12.0"
combined-stream "~1.0.5"
extend "~3.0.1"
forever-agent "~0.6.1"
form-data "~2.3.1"
har-validator "~5.0.3"
http-signature "~1.2.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
json-stringify-safe "~5.0.1"
mime-types "~2.1.17"
oauth-sign "~0.8.2"
performance-now "^2.1.0"
qs "~6.5.1"
safe-buffer "^5.1.1"
tough-cookie "~2.3.3"
tunnel-agent "^0.6.0"
uuid "^3.1.0"
rimraf@~2.4.0:
version "2.4.5"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da"
dependencies:
glob "^6.0.1"
safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
safe-json-stringify@~1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd"
safer-buffer@^2.0.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
semver@^5.1.0, semver@^5.5.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
sshpk@^1.7.0:
version "1.14.2"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.2.tgz#c6fc61648a3d9c4e764fd3fcdf4ea105e492ba98"
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
dashdash "^1.12.0"
getpass "^0.1.1"
safer-buffer "^2.0.2"
optionalDependencies:
bcrypt-pbkdf "^1.0.0"
ecc-jsbn "~0.1.1"
jsbn "~0.1.0"
tweetnacl "~0.14.0"
stack-trace@0.0.x:
version "0.0.10"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
standard-error@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/standard-error/-/standard-error-1.1.0.tgz#23e5168fa1c0820189e5812701a79058510d0d34"
string_decoder@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
dependencies:
safe-buffer "~5.1.0"
text-hex@0.0.x:
version "0.0.0"
resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-0.0.0.tgz#578fbc85a6a92636e42dd17b41d0218cce9eb2b3"
tough-cookie@~2.3.3:
version "2.3.4"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655"
dependencies:
punycode "^1.4.1"
triple-beam@^1.2.0, triple-beam@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
dependencies:
safe-buffer "^5.0.1"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
twit@^2.2.11:
version "2.2.11"
resolved "https://registry.yarnpkg.com/twit/-/twit-2.2.11.tgz#554343d1cf343ddf503280db821f61be5ab407c3"
dependencies:
bluebird "^3.1.5"
mime "^1.3.4"
request "^2.68.0"
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
uuid@^3.0.1, uuid@^3.1.0:
version "3.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
verror@1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
dependencies:
assert-plus "^1.0.0"
core-util-is "1.0.2"
extsprintf "^1.2.0"
winston-compat@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/winston-compat/-/winston-compat-0.1.4.tgz#599b4ce807ffe728713ecc25ede3f6b89425b739"
dependencies:
cycle "~1.0.3"
logform "^1.6.0"
triple-beam "^1.2.0"
winston-daily-rotate-file@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/winston-daily-rotate-file/-/winston-daily-rotate-file-3.2.3.tgz#9f80e7a421ab32b073c1217bae62e762001197d6"
dependencies:
file-stream-rotator "^0.2.1"
semver "^5.5.0"
triple-beam "^1.3.0"
winston-compat "^0.1.4"
winston-transport "^4.2.0"
winston-transport@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.2.0.tgz#a20be89edf2ea2ca39ba25f3e50344d73e6520e5"
dependencies:
readable-stream "^2.3.6"
triple-beam "^1.2.0"
winston@3:
version "3.0.0"
resolved "https://registry.yarnpkg.com/winston/-/winston-3.0.0.tgz#1f0b24a96586798bcf0cd149fb07ed47cb01a1b2"
dependencies:
async "^2.6.0"
diagnostics "^1.0.1"
is-stream "^1.1.0"
logform "^1.9.0"
one-time "0.0.4"
readable-stream "^2.3.6"
stack-trace "0.0.x"
triple-beam "^1.3.0"
winston-transport "^4.2.0"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"