Merge pull request #9 from lbryio/next-tipbot
Latest version of tipbot, rewritten and solving most of the issues.
This commit is contained in:
commit
05dc97bda8
12 changed files with 1135 additions and 1744 deletions
93
.gitignore
vendored
93
.gitignore
vendored
|
@ -1,21 +1,78 @@
|
||||||
# Created by http://www.gitignore.io
|
# Logs
|
||||||
|
|
||||||
### Node ###
|
|
||||||
lib-cov
|
|
||||||
lcov.info
|
|
||||||
*.seed
|
|
||||||
*.log
|
|
||||||
*.csv
|
|
||||||
*.dat
|
|
||||||
*.out
|
|
||||||
*.pid
|
|
||||||
*.gz
|
|
||||||
|
|
||||||
pids
|
|
||||||
logs
|
logs
|
||||||
results
|
*.log
|
||||||
build
|
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
|
.grunt
|
||||||
|
|
||||||
node_modules
|
# Bower dependency directory (https://bower.io/)
|
||||||
config/config.yml
|
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
|
||||||
|
|
||||||
|
.idea/*
|
|
@ -1 +0,0 @@
|
||||||
/lib/
|
|
27
LICENSE
27
LICENSE
|
@ -1,20 +1,15 @@
|
||||||
Copyright (c) 2014 unek <unekpl@gmail.com>
|
The MIT License (MIT)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Copyright (c) 2018 LBRY Inc
|
||||||
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
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the
|
||||||
included in all copies or substantial portions of the Software.
|
"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 SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
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,
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
102
README.md
102
README.md
|
@ -1,74 +1,46 @@
|
||||||
This is a fork of node-tip-bot-twitter, an open-source node.js twitter bot for tipping with altcoins.
|
# Twitter tipbot - A twitter tipbot for LBRY
|
||||||
In particular, this fork is for [LBC](https://lbry.io/). LBRY.io, the network behind it, describes
|
|
||||||
itself as:
|
|
||||||
|
|
||||||
|
This repo contains the twitter tipbot used by LBRY. This bot allows users to tip each other LBC on twitter.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
### Prerequisites
|
||||||
|
* Lbrycrd-daemon
|
||||||
|
* Node.js v8+
|
||||||
|
* Yarn
|
||||||
|
* A twitter application on the tipbot account
|
||||||
|
|
||||||
|
>To get started you should clone the git:
|
||||||
```
|
```
|
||||||
...a free, open, and community-run digital marketplace.
|
git clone https://github.com/lbryio/twitter-tipbot
|
||||||
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.
|
|
||||||
```
|
```
|
||||||
|
>Install all modules with yarn:
|
||||||
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.
|
yarn install
|
||||||
|
|
||||||
# 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`.
|
>Rename default.example.json to default.json and enter the twitter tokens and daemon settings.
|
||||||
|
|
||||||
## Commands
|
>Run the bot with:
|
||||||
Commands are executed by placing gameunits <command> <arguments> in a tweet.
|
```
|
||||||
|
node index.js
|
||||||
|
```
|
||||||
|
>If you want to move over accounts from the old tipbot format which used usernames as identifier, run move_helper.js:
|
||||||
|
```
|
||||||
|
node move_helper.js
|
||||||
|
```
|
||||||
|
>It will automatically move over the old accounts to the new id based system.
|
||||||
|
|
||||||
| **Command** | **Arguments** | **Description**
|
## Contributing
|
||||||
|-------------|-------------------|--------------------------------------------------------------------
|
|
||||||
| `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
|
|
||||||
|
|
||||||
|
Contributions to this project are welcome, encouraged, and compensated. For more details, see [lbry.io/faq/contributing](https://lbry.io/faq/contributing)
|
||||||
|
|
||||||
|
## License
|
||||||
|
This project is MIT Licensed © [LBRYio](https://github.com/lbryio)
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
We take security seriously. Please contact security@lbry.io regarding any security issues.
|
||||||
|
Our PGP key is [here](https://keybase.io/lbry/key.asc) if you need it.
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
|
||||||
|
The primary contact for this project is [@filipnyquist](https://github.com/filipnyquist) (filip@lbry.io)
|
||||||
|
|
325
bin/tipbot.js
325
bin/tipbot.js
|
@ -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;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -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.'
|
|
17
config/default.example.json
Normal file
17
config/default.example.json
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"bot":{
|
||||||
|
"handle": "@devlbctipbot",
|
||||||
|
"requiredConfirms": 2
|
||||||
|
},
|
||||||
|
"twitter": {
|
||||||
|
"consumer_key": "****",
|
||||||
|
"consumer_secret": "****",
|
||||||
|
"access_token": "****",
|
||||||
|
"access_token_secret": "****"
|
||||||
|
},
|
||||||
|
"lbrycrd": {
|
||||||
|
"username": "lbry",
|
||||||
|
"password": "lbry",
|
||||||
|
"port": 9245
|
||||||
|
}
|
||||||
|
}
|
235
index.js
Normal file
235
index.js
Normal file
|
@ -0,0 +1,235 @@
|
||||||
|
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({
|
||||||
|
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.
|
||||||
|
});
|
||||||
|
|
||||||
|
const stream = T.stream("statuses/filter", { track: config.get("bot.handle") });
|
||||||
|
logger.info("Started LBRY twitter tipbot.");
|
||||||
|
|
||||||
|
stream.on("tweet", function(tweet) {
|
||||||
|
if(tweet.user.screen_name === config.get("bot.handle").substring(1)) return;
|
||||||
|
let msg = checkTrunc(tweet);
|
||||||
|
msg = msg.slice(msg.indexOf(config.get("bot.handle"))).split(" ");
|
||||||
|
if (msg.length >= 2) 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;
|
||||||
|
case "terms":
|
||||||
|
doTerms(tweet, msg);
|
||||||
|
break;
|
||||||
|
case "lbryian":
|
||||||
|
logger.info("Got a command with the old format, handling it...");
|
||||||
|
checkTweet(tweet, msg.splice(1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function doHelp(tweet, msg) {
|
||||||
|
try {
|
||||||
|
let post = await T.post("statuses/update", {
|
||||||
|
status:
|
||||||
|
`@${tweet.user.screen_name} `+
|
||||||
|
`All commands should be called with ${config.get("bot.handle")} + subcommand \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.\n"+
|
||||||
|
"terms - Sends you the TOS.",
|
||||||
|
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 doTerms(tweet, msg){
|
||||||
|
// ADD terms
|
||||||
|
await T.post("statuses/update", {
|
||||||
|
status:
|
||||||
|
`@${tweet.user.screen_name} `+
|
||||||
|
"There are no fees to use this bot except the automatic daemon fee. \n"+
|
||||||
|
"Under no circumstances shall LBRY Inc. be held responsible for lost, stolen or misdirected funds.",
|
||||||
|
in_reply_to_status_id: tweet.id_str
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function doBalance(tweet, msg) {
|
||||||
|
try {
|
||||||
|
const balance = await lbry.getBalance(id(tweet.user.id_str), config.get("bot.requiredConfirms")); // Amount of confirms before we can use it.
|
||||||
|
const post = await T.post("statuses/update", {
|
||||||
|
in_reply_to_status_id: tweet.id_str,
|
||||||
|
status: `@${tweet.user.screen_name} You have ${balance} LBC.`
|
||||||
|
});
|
||||||
|
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: `@${tweet.user.screen_name} Your deposit address is ${await getAddress(id(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) {
|
||||||
|
try {
|
||||||
|
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: `@${tweet.user.screen_name} I don´t know how to withdraw that many credits...`,
|
||||||
|
in_reply_to_status_id: tweet.id_str
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let txId = await lbry.sendFrom(id(tweet.user.id_str), address, amount);
|
||||||
|
await T.post("statuses/update", {
|
||||||
|
status: `@${tweet.user.screen_name} 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}`
|
||||||
|
);
|
||||||
|
} 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: `@${tweet.user.screen_name} I don´t know how to tip that many credits...`,
|
||||||
|
in_reply_to_status_id: tweet.id_str
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const userToTip = tweet.entities.user_mentions.find(u => `@${u.screen_name}` === msg[2]).id_str;
|
||||||
|
let tipToAddress = await getAddress(id(userToTip)) // Call this to ensure user has an account.
|
||||||
|
if (userToTip === null) {
|
||||||
|
return await T.post("statuses/update", {
|
||||||
|
status: `@${tweet.user.screen_name} I could not find that user...`,
|
||||||
|
in_reply_to_status_id: tweet.id_str
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const balanceFromUser = await lbry.getBalance(id(tweet.user.id_str), config.get("bot.requiredConfirms"));
|
||||||
|
if (balanceFromUser < amount) {
|
||||||
|
return await T.post("statuses/update", {
|
||||||
|
status: `@${tweet.user.screen_name} You tried tipping more than you have! You are ${amount-balanceFromUser} LBC short.`,
|
||||||
|
in_reply_to_status_id: tweet.id_str
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const txId = await lbry.sendFrom(id(tweet.user.id_str), tipToAddress, Number(amount), 1);
|
||||||
|
await T.post("statuses/update", {
|
||||||
|
status: `@${tweet.user.screen_name} Tipped ${
|
||||||
|
msg[2]
|
||||||
|
} ${amount} LBC! \nTransaction: ${txLink(txId)} \nSee https://lbry.io/faq/tipbot-twitter for more information.`,
|
||||||
|
in_reply_to_status_id: tweet.id_str
|
||||||
|
});
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
function id(usrId){
|
||||||
|
return `t-${usrId}`;
|
||||||
|
}
|
96
move_helper.js
Normal file
96
move_helper.js
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
// This file helps with moving over accounts from the old username system to the id system.
|
||||||
|
// It uses the same configuration files as index.js
|
||||||
|
// Checks for the old format, gets their id from twitter, creates new acc, moves balance.
|
||||||
|
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: "move-helper-%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"
|
||||||
|
})
|
||||||
|
]
|
||||||
|
});
|
||||||
|
let notSynced = [];
|
||||||
|
|
||||||
|
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.
|
||||||
|
});
|
||||||
|
|
||||||
|
async function main(){
|
||||||
|
let accs = await getAccounts();
|
||||||
|
logger.info(`Trying to move ${accs.length} accounts...`)
|
||||||
|
for (let i in accs){
|
||||||
|
try {
|
||||||
|
//Get user details from twitter.
|
||||||
|
let data = await T.get('users/show', { screen_name: accs[i] });
|
||||||
|
//Create a account for the user by id.
|
||||||
|
let usr = data.data.id_str;
|
||||||
|
await getAddress(id(usr));
|
||||||
|
//Move over from old account to the new account
|
||||||
|
const balanceFromOld = await lbry.getBalance(`twttr-${accs[i]}`);
|
||||||
|
if (balanceFromOld !== 0) {
|
||||||
|
let res = await lbry.move(
|
||||||
|
`twttr-${accs[i]}`,
|
||||||
|
id(usr),
|
||||||
|
Number(balanceFromOld)
|
||||||
|
);
|
||||||
|
// If move is successful, log it!
|
||||||
|
if (res) logger.info(`Transferred ${balanceFromOld} LBC from twttr-${accs[i]} to ${id(usr)}!`);
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
logger.info(`Could not sync ${accs[i]}, error occured:`, e.allErrors);
|
||||||
|
notSynced.push({ user: accs[i], error: e.allErrors});
|
||||||
|
logger.info("Could not sync these:"+JSON.stringify(notSynced));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get a list of all twitter accounts on lbrycrd.
|
||||||
|
async function getAccounts(){
|
||||||
|
let accs = await lbry.listAccounts();
|
||||||
|
accs = Object.entries(accs);
|
||||||
|
let accsArr = [];
|
||||||
|
for (let i in accs){
|
||||||
|
if(accs[i][0].startsWith('twttr-')) accsArr.push(accs[i][0].substring(6));
|
||||||
|
}
|
||||||
|
return accsArr;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getAddress(userId) {
|
||||||
|
try {
|
||||||
|
let uAddresses = await lbry.getAddressesByAccount(userId);
|
||||||
|
if (uAddresses.length > 0) return;
|
||||||
|
await lbry.getNewAddress(userId);
|
||||||
|
} catch (e) {
|
||||||
|
throw("Something went wrong while creating an account for the user: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function id(usrId){
|
||||||
|
return `t-${usrId}`;
|
||||||
|
}
|
||||||
|
main();
|
1198
package-lock.json
generated
1198
package-lock.json
generated
File diff suppressed because it is too large
Load diff
52
package.json
52
package.json
|
@ -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": {
|
"dependencies": {
|
||||||
"express": "^3.21.2",
|
"bitcoin-core": "^2.0.0",
|
||||||
"js-yaml": "^3.11.0",
|
"config": "^1.30.0",
|
||||||
"node-gameunits": "^0.3.5",
|
"twit": "^2.2.11",
|
||||||
"twitter": "^1.7.1",
|
"winston": "3",
|
||||||
"winston": "^2.4.2"
|
"winston-daily-rotate-file": "^3.2.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"name": "lbry-twitter-tipbot",
|
||||||
"prettier": "^1.12.0"
|
"version": "1.0.0",
|
||||||
},
|
"description": "A twitter tipbot for LBRY",
|
||||||
"scripts": {
|
"main": "index.js",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"repository": "https://github.com/lbryio/twitter-tipbot/",
|
||||||
"start": "node bin/tipbot",
|
"author": "filipnyquist <filip@lbry.io>",
|
||||||
"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",
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"private": false
|
||||||
"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"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
651
yarn.lock
Normal file
651
yarn.lock
Normal 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"
|
Loading…
Reference in a new issue