• Stars
    star
    158
  • Rank 237,131 (Top 5 %)
  • Language
    TypeScript
  • License
    GNU General Publi...
  • Created over 11 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Stratum protocol server and client for Node.js

Build Status Coverage Status Dependency Status

NPM

Node.js Stratum Server / Client / RPC Daemon

Exposes a server to enable Stratum mining protocol (server and client) usage on Node.js and subscribe for events using EventEmitter, and accept stratum-notify from *coind daemons

This is not a ready-to-use miner pool, you may use this server to implement your favorite altcoins, all the pool logic is up to you (shares, passwords, sessions, etc).

Highlights

  • Simple but powerful API for managing both server and client
  • Build-in support for spawn coins daemons (bitcoind, litecoind, etc) process and accept RPC calls
  • Easy for you to add your own procedures do the RPC server (using expose)
  • No need to worry about .conf files for the daemons, everything is passed through command line the best way possible (but you may override arguments)
  • All classes based on EventEmitter by default (through the Base class)
  • The client part make it easy, along with an RPC server, to setup your own farming pool for coins
  • You can create a proxy from it using the Client interface, mix up Stratum with your own RPC definition and commands

Install

npm install stratum

Notice that you may install this globally using -g, stratum-notify will be available system wide

Stratum notify

if you want to call it manually for testing purposes
node node_modules/.bin/stratum-notify --host localhost --port 1337 --password willbebase64encoded --type block --data "jsondata"

This command is called automatically if you set the coind options, they are forked when the server is started.

Usage

var Server = require('stratum').Server;

// these settings can be changed using Server.defaults as well, for every new server up
var server = new Server({
  /**
   * RPC to listen interface for this server
   */
  rpc     : {
    /**
     * Bind to address
     *
     * @type {String}
     */
    host: 'localhost',
    /**
     * RPC port
     *
     * @type {Number}
     */
    port: 1337,
    /**
     * RPC password, this needs to be a SHA256 hash, defaults to 'password'
     * To create a hash out of your password, launch node.js and write
     *
     * require('crypto').createHash('sha256').update('password').digest('hex');
     *
     * @type {String}
     */
    password: '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8',
    /**
     * Mode to listen. By default listen only on TCP, but you may use 'http' or 'both' (deal
     * with HTTP and TCP at same time)
     */
    mode: 'tcp'
  },
  /**
   * The server settings itself
   */
  settings: {
    /**
     * Address to set the X-Stratum header if someone connects using HTTP
     * @type {String}
     */
    hostname: 'localhost',
    /**
     * Max server lag before considering the server "too busy" and drop new connections
     * @type {Number}
     */
    toobusy : 70,
    /**
     * Bind to address, use 0.0.0.0 for external access
     * @type {string}
     */
    host    : 'localhost',
    /**
     * Port for the stratum TCP server to listen on
     * @type {Number}
     */
    port    : 3333
  }
});

server.on('mining', function(req, deferred){
    switch (req.method){
        case 'subscribe':
            // req.params[0] -> if filled, it's the User Agent, like CGMiner/CPUMiner sends
            // Just resolve the deferred, the promise will be resolved and the data sent to the connected client
            deferred.resolve([subscription, extranonce1, extranonce2_size]);
            break;
    }
});

server.listen();

You can connect to Stratum servers as well:

var Client = require('stratum').Client;

client = new Client();

client.connect({
    host: 'localhost',
    port: 3333
}).then(function(){
    return ...;
}).then(function(value){
    if (value){
        //etc
    }
});

Examples

Check the examples folder, each part (client and server) is completely explained, and how to proceed on each possible case.

Documentation

The following documentation expects that:

var stratum = require('stratum');

Base

Available through stratum.Base

All the classes inherit from the base class, that inherits from EventEmitter3, and got an additional method:

debug(msg)

Show debug messages for the class only if DEBUG=stratum environment variable is set

stratum.Base.debug('oops');

Server

Available through stratum.Server

You can write your own defaults that applies to all new server instances through stratum.Server.defaults

stratum.Server.defaults.settings.toobusy = 50;

You can also include your own stratum method calls through stratum.Server.commands object, the server will lookup them automatically and provide it in the event emitted callback. The 'mining.' prefix is expected, so if you put 'hashes', it expects the command to be mining.hashes

stratum.Server.commands.hashes = function(id, any, params, you, want, to, pass, to, the, client){
    // this function is actually the "resolved" function, that sends data back to the client
    // it's reached by using deferred.resolve([...params...]); in the emitted callback

    // "this" is the current socket
    // "id" is the current RPC call id and is non-optional, must be always the first parameter

    // you should always return something like this:
    return this.stratumSend({
        error: null,
        result: [any, params, you, want], // your result
        id: id
    });
};

// the event `mining.hashes` will be fired on the callback

server.on('mining', function(req, deferred) {
    if (req.method === 'hashes'){
        deferred.resolve([any, params, you, want, to, pass, to, the, client]);
        // or reject
        deferred.reject([any, params, you, want, to, pass, to, the, client]);
    }
});

// mining.error event is emitted when something is wrong, mining related

server.on('mining.error', function(){

});

// the stratum.Server also holds defaults for coins daemons
console.log(stratum.Server.daemons); // a list of pre-configured daemons in stratum.Server.daemons

// You can inject them into the server later on, using stratum.Daemon

//instantiates a bitcoin stratum.Daemon and places inside the server
server.addDaemon(stratum.Server.daemons.bitcoin);

// you can instantiate using your own instance as well
server.addDaemon(stratum.Daemon.create({
    'name': 'MyExampleCoin',
    /*...*/
}));

RPCServer

Available through stratum.RPCServer.

Enables you to communicate from outside the Stratum module through an JSON RPC 2.0 interface. It's optional, and you don't need to enable it, you may communicate from inside out only.

It's mainly useful to receive notifications (wallet, block and alert), like the stratum-notify bin to receive json data from the outside, but you may extend the interface to accept any other commands that you deem necessary for your app.

It's advised to bind the RPCServer instance to either localhost or an internal IP range, and/or access through trusted proxies.

const rpc = new stratum.RPCServer({
    'mode': 'tcp', // can be 'tcp', 'http', 'both' (can handle TCP and HTTP/Websockets on one port)
    'port': 9999,
    'host': 'localhost', // bind to localhost
    'password': 'a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3' // SHA256 hash of the password, no plain text!
});

rpc.listen(); // listens on port 9999, binding to localhost

rpc.expose('mymethod', function(args, connection, callback){
    // if you want to pass an error, use the first callback parameter
    callback(error);
    // otherwise, pass the result through the second parameter
    callback(null, result);
});

// RPC calls like {"method":"mymethod","params":[1,"2"],"id":1}, the args parameter will receive only the [1,"2"]

Client

Available through stratum.Client

The client can connect to a stratum server and send and receive commands like if it was a miner.

The main reason for this part of the module is that you can setup a stratum proxy using it, to forward raw data (or even a command line call) to a stratum server.

You may also test your pool sending arbitrary test data to see if it's responding properly.

If your URL starts with 'stratum+tcp://', remove it!

var client = new stratum.Client();

client.on('mining.error', function(message){
});

client.on('mining', function(req, deferred){
    // this
});

client.connect(8080, 'localhost').then(function(socket){
    socket.stratumSubscribe('NodeMiner');
    socket.stratumAuthorize('user','pass');
    socket.stratumSubmit('worker', 'job_id', 'extranonce2', 'ntime', 'nonce');
    socket.stratumSend(data, true); //send a stratum command other than the previous ones
    socket.send(data); // send raw data through the socket
});

Daemon

Available through stratum.Daemon

Include or change the global configuration for daemons using the stratum.Server.daemons member. It's not set per instance, but rather globally.

The options path, args, notifyPath, notify are optional

stratum.Server.daemons['sillycoin'] = {
    'path': '/usr/bin/sillycoind', // optional
    'args': ['debug'], // optional
    'rpcserver': { // this whole block is optional, this is the stratum server RPC (not the daemon one))
        'port': 8888,
        'host': 'localhost',
        'password': 'rpcpassword',
        'notifyPath': './node_modules/.bin/stratum-notify', // optional
        'notify': ['block', 'wallet', 'alert'], // optional, will build walletnotify, blocknotify and alertnotify parameters
    }
    'name': 'SillyCoin',
    'user': 'rpcuser',
    'password': 'rpcpassword',
    'port': 0xDEAD,
    'host': 'localhost'
};

You can start issuing commands to the daemon BEFORE calling start(), usually when you already have it running. start() will attempt to spawn the process.

var daemon = new stratum.Daemon({
    'path': '/usr/bin/sillycoind',
    'name': 'SillyCoin',
    'user': 'rpcuser',
    'password': 'rpcpassword',
    'port': 0xDEAD,
    'host': 'localhost',
    'args': ['debug']
});

async function start() {
    daemon.start();

    try {
        const result = await daemon.call('getinfo', []);
        // daemon returned a result
        console.log(result.balance);
    } catch (result) {
        // daemon returned an error
        console.log(result); // usually "Command timed out" or "Unauthorized access"
    }
}

start();

Debugging

Export/set the environment variable DEBUG=stratum on your command line before executing your code, that you'll be able to see everything behind the hood inside this module on the command line.

You can additionally set DEBUG=stratum,jsonrpc to also see the RPC part in-depth (for stratum.Daemon and stratum.RPCServer)

Development

  • BTC: 16QDbqa6UMFtMCdDcJJ5N2bqryH4Q56BVU
  • BCH: 1E6gKfkyxsjr2rSbcHbnfsQumKxkGKwRYc
  • ETH: 0xfF9087E7112d3b7D7B5bDD6C9ffb0970ACC162E7
  • MIOTA: NNIH9VGEQFZAJIITBO9FEDSYUDYXHMAINGSKWIU9ADUHYYNTIYGJADZITOCVMWEFTKJGCNCJN9ZRFUZKCPSUOMDAKD
  • NXT: NXT-7TJT-8NS2-8QBS-5Y89X
  • BTG: GY2RWXUKYDmYDaroMmucgUdF7dLqaHDKWu
  • XEM: NBC772-Q3SL4X-AGVNMP-JAWGJE-U6BCSB-Q7WNAX-YU5V
  • DASH: XaqxcT3BDmSLGB4M6ozrET1qJPBA4RJpng
  • XRB: xrb_3fi16pk4gyz331r4531m7jywrfsgp3h31yoyfusac77esuamh65r5kwjz7dm

More Repositories

1

actor-facebook-scraper

Scrape public Facebook pages, posts, reviews and comments
TypeScript
61
star
2

react-native-sim-data

React Native plugin to get the device's SIM data (carrier name, mcc mnc, country code, phone number, etc)
Java
61
star
3

minify-kohana

Minify module for Kohana 3.x
PHP
52
star
4

react-use-comlink

Three ways to use Comlink web workers through React Hooks (and in a typesafe manner).
TypeScript
46
star
5

js-diacritic-regex

Creates the inverse of transliterated string to a regex. What? Basically, diacritic insensitiveness
TypeScript
27
star
6

react-native-stager

A performant wizard-like multi stages component for React Native without a router
TypeScript
16
star
7

actor-shopify-scraper

Automate monitoring prices on the most popular solution for building online stores and selling products online. Crawl arbitrary Shopify-powered online stores and extract a list of all products in a structured form, including product title, price, description, etc
JavaScript
13
star
8

angular-equalizer

Equalize the height of a set of random elements, without necessarily having a common parent, container, etc.
TypeScript
11
star
9

googleapi-kohana

Google API client wrapper, focused on the OAuth of Google+ for Kohana 3.3
PHP
10
star
10

apify-login-session

Grab a session for any website for usage on your own actor
TypeScript
10
star
11

angular-errorlookup

Because AngularJS general error messages still suck. ngMessages can kiss my ass.
TypeScript
10
star
12

phery-kohana

Kohana 3.3 module with tight integration for Phery.js library https://github.com/pocesar/phery
PHP
10
star
13

js-bettercurry

Forget Function.bind and func.apply(context, arguments), performance matters! For a better curry!
JavaScript
8
star
14

twitter-kohana

Kohana 3.3 module for Twitter OAuth library
PHP
8
star
15

react-use-qrcode

React hook that allows you to decode QR Code data in a webworker (through comlink) using @zxing/library with some adaptations for web workers. Performance-first, non-ui blocking code. Uses OffscreenCanvas if available
TypeScript
8
star
16

node-detect-cryptocoin

Detects which cryptcoin is the given cryptocoin address (starts with some coins listed in CoinWarz.com that have working block explorers)
JavaScript
7
star
17

angular-event-delegate

Use a common parent to delegate events to underlaying DOM elements using jQuery
JavaScript
7
star
18

angular-async-validator

Directives and service for reusable async validators, write once, use everywhere.
JavaScript
7
star
19

js-chain-commander

Chain commander is a library based on bluebird promises library, to encapsulate business rules logic in form of javascript objects or JSON.
JavaScript
7
star
20

angular-cleanmask

Angular helper directive to use the $viewValue of a ui-mask
6
star
21

node-nxt-api

API request for NXT crypto
JavaScript
6
star
22

angular-name-validation

Angular directive for validating UTF-8 full names on text inputs
6
star
23

node-packet-frame

Easy streaming packet framing and serialization
JavaScript
6
star
24

react-i18n-context

Making i18n in React 16.3+ the easiest way possible with the new Context API
TypeScript
5
star
25

node-moip2

Typescript para Moip API 2.0
TypeScript
5
star
26

angular-ecommerce-analytics

Google Analytics Ecommerce helper with tracking events
TypeScript
4
star
27

angular-onfinish

Directives that execute a function or an expression when ng-repeat is done with looping. No need for events.
JavaScript
4
star
28

apify-covid19-brazil

Get Coronavirus epidemilogy data for Brazil in CSV
JavaScript
4
star
29

node-aws-mjml-csv

CLI and programatic API to send emails using MJML (that is then parsed by Handlebars.js), populating your email passing the CSV columns to your template
TypeScript
4
star
30

node-importprivkey-pywallet

Simple script that calls curl in sequence to import pywallet dumpwallet json to Bitcoin (and forks) clients
JavaScript
3
star
31

actor-testing

Test your actors and tasks with multiple inputs, and expected outputs, integrating with results checker
JavaScript
3
star
32

actor-spawn-workers

Split work through multiple actors
JavaScript
3
star
33

actor-google-trending-searches

JavaScript
3
star
34

js-async-atomic-store

An agnostic little store abstraction for reading, writing and appending on the same data from multiple sources in a locking manner, that allows concurrent/parallel (like from many async sources) write, append and read.
TypeScript
3
star
35

jade-kohana

Jade templating engine on Kohana
PHP
2
star
36

hashids-kohana

Kohana 3.3 module for the Hashids library
PHP
2
star
37

apify-query-dataset

Use MongoDB query language style to search and generate a new subset of your datasets
JavaScript
2
star
38

node-nem-wallet

NEM Wallet
TypeScript
2
star
39

docker-node-alpine-gyp

Node alpine container for rebuilding stuff (when on windows host)
Shell
2
star
40

angular-track-height

Watch an element for the min or/and max height then save it for use somewhere else
HTML
2
star
41

ts-misbehaving-fuzzy-server

1
star
42

actor-request-list-bridge

Adds requestList requestsFromUrl to actors that don't support it
JavaScript
1
star
43

js-typescript-react-jspm

Boilerplate for personal use, someone might find it useful with Typescript + React + JSPM
JavaScript
1
star
44

actor-sitemap-to-request-queue

JavaScript
1
star
45

angular-unamed-scroll

Scroll to elements on page without relying on IDs. Adds named elements to the service, then scroll to them anywhere in your code
TypeScript
1
star
46

actor-crypto-watcher

TypeScript
1
star
47

docker-nginx-kohana

Shell
1
star
48

fgx

1
star
49

js-joi-match-error

A simple (and convenient) wrapper for passing to Joi.error()
TypeScript
1
star
50

apify-remote-control-ui

1
star
51

angular-save-content

Save the content of a part of your server rendered HTML, so it won't issue an AJAX call to fetch the templateUrl
JavaScript
1
star
52

actor-diff-datasets

JavaScript
1
star
53

hybridauth-kohana

Module, helpers and controllers for HybridAuth module https://github.com/hybridauth/hybridauth
PHP
1
star
54

actor-aggregate-fields

Aggregate all possible variations for the selected fields
JavaScript
1
star
55

actor-extract-social-info

1
star
56

angularjs-pheryjs

Pretty simple phery.js AJAX service for AngularJS that mimics $resource
JavaScript
1
star