Skip to content

Commit

Permalink
v3.0.0 - Major updates inc. Hive Support
Browse files Browse the repository at this point in the history
Not everything is listed below, since there has been a lot of refactoring to make `steemfeed-js` more flexible,
and there has also been lots of small changes such as cleaning up syntax to make lines more readable.

Overall, this is a major update to `steemfeed-js`, making the system more flexible, potentially usable across forks of
Steem, and cleaner code making it easier to understand and develop `steemfeed-js`.

**New Exchange Adapter**

 - Added `IonomyAdapter.js`, allowing price feeds to include prices from ionomy.com

**Various Improvements**

 - Refactored handling of config defaults and parsing CLI options into `lib/settings.py`

 - `publish_feed` now uses `config.base_symbol` and `config.quote_symbol` instead of hardcoded
   `STEEM` / `SBD`

 - Refactored the hardcoded `steem` / `usd` default exchange pair lookup into config options
   `config.ex_symbol` and `config.ex_compare`

 - Tons of refactoring to `lib/exchange.js` to improve the adapter initialisation process.

**New Additions**

 - New config options

     - `ex_symbol` - The symbol we're obtaining the price of. Default: `steem`

     - `ex_compare` - The symbol we're pricing `ex_symbol` with (i.e. the other half of the exchange pair). Default: `usd`

     - `base_symbol` - The symbol used for the `"base": "0.512 SBD"` part of the feed. Default: `SBD`

     - `quote_symbol` - The symbol used for the `"quote": "1.000 STEEM"` part of the feed. Default: `STEEM`
     - `disable_exchanges` which allows the user to disable one or more exchanges if
       they're down, or returning bad data.

     - `exchanges_no_provide` - allowing the user to disable individual coin pairs from being used,
       per each exchange.

     - `exchanges_provide` - works similarly to `exchanges_no_provide`, except it allows
       new coin pairs to be added to existing exchanges, instead of removing them.

     - `network` - allows Steemfeed-JS to work with forks, such as [Hive](https://hive.io)

 - Created `lib/adapters/base.js`, which contains `BaseAdapter` - an example adapter with comment blocks
   explaining how you should layout a new exchange adapter.

 - Added `has_pair` method to all exchange adapters, and added `has_pair` check in all `get_pair` methods.

 - Added `code` attribute to all exchange adapters, a unique short string used as the "ID" for the adapter.

 - Added `available_adapters` list to `lib/exchange.js`, allowing adapters to be programatically enabled/disabled etc.

**Using Steemfeed-JS with Hive?**

Open up your `config.json` and remove any existing Steem `"node"` config line. (or change it to `https://anyx.io`)

Add the config line `"network": "hive"`

Stop, re-build, and start steemfeed-js, and you'll be broadcasting a Hive feed :)
  • Loading branch information
Someguy123 committed Mar 22, 2020
1 parent d72f415 commit e52e9c5
Show file tree
Hide file tree
Showing 16 changed files with 580 additions and 75 deletions.
3 changes: 3 additions & 0 deletions .jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"esversion": 9
}
103 changes: 95 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,105 @@ Configuration
===========
```
{
"node": "https://steemd.privex.io/",
"name": "your steem name",
"name": "your steem/hive name",
"wif": "your active private key",
"network": "steem",
"interval": 60,
"peg": false,
"peg_multi": 1
}
```

- **node** - The URL of the steem node to use.
- **name** - The name of the steem account that will publish the feed
- **wif** - The active private key for the steem account
- **interval** - The number of minutes between publishing the feed
- **peg** - Set to true only if you want to adjust your price feed bias
- **peg_multi** - If "peg" is set to true, then this will change the "quote" to 1 / peg_multi. If you set "peg_multi" to 2 it will show a 100% bias on your feed.
- **name** (REQUIRED) - The name of the steem account that will publish the feed

- **wif** (REQUIRED) - The active private key for the steem account

- **node** (default: `https://api.steemit.com`) - The HTTP(S) URL of the steem node to use, e.g. `https://steemd.privex.io`

- **interval** (default: `60`) - The number of minutes between publishing the feed

- **network** (default: `steem`) - The network (chain) you're using this for. Options are: `steem` and `hive`

- **peg** (default: `false`) - Set to true only if you want to adjust your price feed bias

- **peg_multi** (default: `1`) - If "peg" is set to true, then this will change the "quote" to 1 / peg_multi. If you set "peg_multi" to 2 it will show a 100% bias on your feed.


Advanced Configuration Options
==============================

**NOTE:** The settings `ex_symbol`, `ex_compare`, `base_symbol` and `quote_symbol` normally do not need to be adjusted.

Just set the correct `network`, and those settings will be automatically updated to the correct values.


`ex_symbol` - The symbol we're obtaining the price of. Default: `steem`

`ex_compare` - The symbol we're pricing `ex_symbol` with (i.e. the other half of the exchange pair). Default: `usd`

`base_symbol` - The symbol used for the `"base": "0.512 SBD"` part of the feed. Default: `SBD`

`quote_symbol` - The symbol used for the `"quote": "1.000 STEEM"` part of the feed. Default: `STEEM`


`disable_exchanges` - A list of exchange `code` 's to disable. Exchanges listed here will not be used
directly (i.e. get price for A/B), nor indirectly (i.e. get price for A/D by converting A/C then C/D).

Example (disable all exchanges...):

```json
{
"disable_exchanges": ["bittrex", "poloniex", "kraken", "ionomy", "binance"]
}
```

`exchanges_no_provide` - Disable use of specific coin pairs per exchange, for example, you might want
to temporarily ban the usage of STEEM/BTC from Poloniex.

Example (block STEEM/BTC from poloniex, block BTC/USDT on Kraken):

```json
{
"exchanges_no_provide": {
"poloniex": [
["steem", "btc"]
],
"kraken": [
["btc", "usdt"]
]
},
}
```

`exchanges_provide` - Add new coin pairs to exchanges, allowing the user to inform steemfeed-js of
new pairs supported by a given exchange.

By default, most exchange adapters have the following pairs enabled (if the exchange supports them):

- BTC/USD
- BTC/USDT
- USDT/USD
- STEEM/BTC
- HIVE/BTC
- STEEM/USD (preferred over STEEM/BTC)
- HIVE/USD (preferred over HIVE/BTC)

Example (add BTC/DASH, EOS/USD, EOS/BTC to bittrex - add EOS/BTC to kraken):

```json
{
"exchanges_provide": {
"bittrex": [
["btc","dash"],
["eos","usd"],
["eos","btc"]
],
"kraken": [
["eos", "btc"]
]
}
}
```



72 changes: 31 additions & 41 deletions app.js
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/usr/bin/env node
/**
*
* Node.JS pricefeed script for steem
Expand All @@ -7,22 +8,20 @@
* Requires Node v8.11.4
*/

var config = require('./config.json');
var settings = require('./lib/settings');
var exchange = require('./lib/exchange');
var request = require('request');
var steem = require('steem');

if(!('node' in config)) { config['node'] = 'https://steemd.privex.io/'; }
// disable peg by default. 0% peg (bias)
if(!('peg' in config)) { config['peg'] = false; }
if(!('peg_multi' in config)) { config['peg_multi'] = 1; }
var config = settings.config,
retry_conf = settings.retry_conf;

console.log('-------------')
console.log('-------------');
log(`Loaded configuration:
Username: ${config.name}
Bias: ${config.peg ? config.peg_multi : 'Disabled'}
RPC Node: ${config.node}`)
console.log('-------------')
RPC Node: ${config.node}`);
console.log('-------------');

global.verbose = false;
for(var t_arg of process.argv) {
Expand All @@ -31,22 +30,11 @@ for(var t_arg of process.argv) {
}
}

steem.api.setOptions({ url: config['node'] });
steem.api.setOptions({ url: config.node });

// used for re-trying failed promises
function delay(t) {
return new Promise((r_resolve) => {
setTimeout(r_resolve, t);
});
}

// Attempts = how many times to allow an RPC problem before giving up
// Delay = how long before a retry
var retry_conf = {
feed_attempts: 10,
feed_delay: 60,
login_attempts: 6,
login_delay: 10
return new Promise((r_resolve) => setTimeout(r_resolve, t) );
}

class SteemAcc {
Expand Down Expand Up @@ -90,9 +78,9 @@ class SteemAcc {
console.error('Most likely the RPC node is down.');
var msg = ('message' in err) ? err.message : err;
console.error('The error returned was:', msg);
if(tries < retry_conf['login_attempts']) {
console.error(`Will retry in ${retry_conf['login_delay']} seconds`);
return delay(retry_conf['login_delay'] * 1000)
if(tries < retry_conf.login_attempts) {
console.error(`Will retry in ${retry_conf.login_delay} seconds`);
return delay(retry_conf.login_delay * 1000)
.then(() => resolve(this.loadAccount(reload, tries+1)))
.catch((e) => reject(e));
}
Expand All @@ -116,7 +104,7 @@ class SteemAcc {
};
this.user_data = ud;
return resolve(ud);
})
});
});
}

Expand All @@ -143,35 +131,35 @@ class SteemAcc {
publish_feed(rate, tries=0) {
try {
// var tr = new TransactionBuilder();
var ex_data = rate.toFixed(3) + " SBD";
var ex_data = rate.toFixed(3) + ` ${config.base_symbol}`;
var quote = 1;
if(config.peg) {
var pcnt = ((1 - config['peg_multi']) * 100).toFixed(2)
var pcnt = ((1 - config.peg_multi) * 100).toFixed(2);
log('Pegging is enabled. Reducing price by '+pcnt+'% (set config.peg to false to disable)');
log('Original price (pre-peg):', ex_data);
quote = 1 / config['peg_multi'];
quote = 1 / config.peg_multi;
}

var exchangeRate = {base: ex_data, quote: quote.toFixed(3) + " STEEM"}
var exchangeRate = {base: ex_data, quote: quote.toFixed(3) + ` ${config.quote_symbol}`};
var {username, active_wif} = this.user_data;
steem.broadcast.feedPublish(active_wif, username, exchangeRate,
(err, r) => {
if(err) {
console.error('Failed to publish feed...');
var msg = ('message' in err) ? err.message : err;
console.error('reason:', msg);
if(tries < retry_conf['feed_attempts']) {
console.error(`Will retry in ${retry_conf['feed_delay']} seconds`);
return delay(retry_conf['feed_delay'] * 1000)
if(tries < retry_conf.feed_attempts) {
console.error(`Will retry in ${retry_conf.feed_delay} seconds`);
return delay(retry_conf.feed_delay * 1000)
.then(() => this.publish_feed(rate, tries+1))
.catch(console.error);
}
console.error(`Giving up. Tried ${tries} times`)
console.error(`Giving up. Tried ${tries} times`);
return reject(err);
}
log('Data published at: ', ""+new Date())
log('Data published at: ', ""+new Date());
log('Successfully published feed.');
log(`TXID: ${r.id} TXNUM: ${r.trx_num}`)
log(`TXID: ${r.id} TXNUM: ${r.trx_num}`);
});
} catch(e) {
console.error(e);
Expand All @@ -190,8 +178,11 @@ try {
var shouldPublish = process.argv.length > 2 && process.argv[2] == "publishnow";
var dryRun = process.argv.length > 2 && process.argv[2] == "dry";

var cap_sym = config.ex_symbol.toUpperCase(),
cap_comp = config.ex_compare.toUpperCase();

function get_price(callback) {
exchange.get_pair('steem','usd',
exchange.get_pair( config.ex_symbol, config.ex_compare,
(err, price) => callback(err, parseFloat(price))
);
}
Expand All @@ -201,13 +192,12 @@ function main() {
if(err) {
return console.error('error loading prices, will retry later');
}
log('STEEM/USD is ', price.toFixed(3));
log('Attempting to publish feed...')
log(`${cap_sym}/${cap_comp} is: ${price.toFixed(3)} ${cap_comp} per ${cap_sym}`);
log('Attempting to publish feed...');
if(!dryRun) {
accountmgr.publish_feed(price);
} else {
console.log('Dry Run. Not actually publishing.')

console.log('Dry Run. Not actually publishing.');
}
});
}
Expand All @@ -229,7 +219,7 @@ accountmgr.login().then((user_data) => {
var interval = parseInt(config.interval) * 1000 * 60;
setInterval(() => main(), interval);
}).catch((e) => {
console.error(`An error occurred attempting to log into ${config.name}... Exiting`)
console.error(`An error occurred attempting to log into ${config.name}... Exiting`);
console.error('Reason:', e);
process.exit(1);
});
Expand Down
42 changes: 42 additions & 0 deletions config.advanced.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "your steem name",
"wif": "your active private key",
"interval": 60,
"peg": false,
"peg_multi": 1.0,
"node": "https://steemd.privex.io",
"ex_symbol": "steem",
"ex_compare": "usd",
"base_symbol": "SBD",
"quote_symbol": "STEEM",
"read_this_disable": [
"If an exchange is down, or has issues resulting in inaccurate prices,",
"then you can add exchanges to the disable_exchanges list, resulting in those ",
"exchanges never being used for any price data."
],
"disable_exchanges": [
"poloniex", "ionomy"
],
"exchanges_no_provide": {
"read_this": [
"The below example, disables the use of the BTC:STEEM pair for Poloniex.",
"This feature allows you to disable specific pairs per exchange, if they're",
"unstable, broken, or reporting bad data."
],
"poloniex": [
["btc", "steem"]
]
},
"exchanges_provide": {
"read_this": [
"This feature allows you to enable additional pairs for existing exchanges, which",
"aren't enabled by default",
"The below example, would add the pairs BTC/DASH and USD/EOS to the 'pairs provided' list",
"of the Bittrex adapter."
],
"bittrex": [
["btc","dash"],
["usd","eos"]
]
}
}
9 changes: 8 additions & 1 deletion config.example.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
{
"name": "your steem name",
"wif": "your active private key",
"network": "steem",

"interval": 60,

"peg": false,
"peg_multi": 1.0
"peg_multi": 1.0,

"disable_exchanges": [],
"exchanges_no_provide": {},
"exchanges_provide": {}
}
11 changes: 10 additions & 1 deletion lib/adapters/BTCEAdapter.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
var request = require('request');
var request = require('request'),
BaseAdapter = require('./base');

var BTCEAdapter = {
name: 'BTC-e',
code: 'btce',
provides: [
['btc','usd'],
['btc','eur'],
['btc','ltc']
],

has_pair: (from, to) => BaseAdapter.has_pair_ext(from, to, BTCEAdapter.provides),

get_pair: function(from,to,callback) {
if(['usd', 'eur', 'gbp', 'rub'].indexOf(to) == -1) {
// btc-e is backwards for altcoins, so flip the pair!
Expand All @@ -15,6 +20,10 @@ var BTCEAdapter = {
from = tmp;
}

if (!BTCEAdapter.has_pair(from, to)) {
return callback(`Pair ${from}/${to} is not supported by this adapter.`, null);
}

var pair = [from,to].join('_'),
ticker_url = 'https://btc-e.com/api/2/'+pair+'/ticker';

Expand Down
Loading

0 comments on commit e52e9c5

Please sign in to comment.