Hive API

edited February 14 in Account
wv2xh070anfp.png

Hive API. Let's call Ey Pi Ay)

Go to your Account
https://hiveos.farm/a/account/#pane-user
At the bottom you will be able to generate API keys. Save them.



Authentication
Every API call has a SHA-256 HMAC signature generated with your secret key. Our server generates it's own HMAC signature and compares it with the API caller's. If they don't match the API call is discarded. The HMAC signature is sent as a HTTP header called 'HMAC'.

The HMAC signature is created from the full raw POST data of your request.
Field "public_key" with your public key should be included in the request.
Example of your POST raw data:
method=getRigs&public_key=<your public key>

and the HMAC sha256 would be something like "db8c07bc43c7ca12b3df1cd5d46ad3ec76b772158f279a1c7a1eb3b45722be69" which you create with your secret key.

Then you add this hmac hash to HTTP header "HMAC: db8..." and make a HTTP POST with all this stuff.

POST URL is:
https://api.hiveos.farm/worker/eypiay.php




API Response

Responses fool the JSON RPC API http://www.jsonrpc.org/specification
So you will have "error" in json if something fails
{"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": null}

Or a valid response with "result" field in it:
{"jsonrpc": "2.0", "result": {"your precious data": "lalala"}, "id": null}



API methods

getWallets - get all your wallets data

getOC - get all your Overclocking profiles

getRigs - get the list of your rigs

getCurrentStats - get current monitor data

multiRocket - apply settings to multiple rigs. This method has extra parameters (POST fields). At least one is required.
  • rig_ids_str - coma separated string with rig ids "1,2,3,4"
  • miner - Miner to set. Leave it null if you do not want to change. "claymore", "claymore-z", "ewbf", ...
  • miner2 - Second miner to set. Leave it null if you do not want to change. "0" - if you want to unset it.
  • id_wal - ID of wallet. Leave it null if you do not want to change.
  • id_oc - ID of OC profile. Leave it null if you do not want to change.
So the request will look like
method=multiRocket&rig_ids_str=1,2,3&miner=claymore&public_key=<your public key>



Code examples are attached.
- PHP
- Python
- Java

If you can do other languages please send them here or with email.
«1

Comments

  • edited February 8
    --- reserved ---
  • Ура УРА УРА !!!! вперед делать приложухи :)
  • edited February 9
    DimaFern wrote: »

    Any chance of adding the rig local ip to the status response?

    Actually I've just found it in GetRigs so no worries.

  • edited February 12
    I'm trying the API using the Requests python package without success. API always returning "method no given".
    {
      "error": {
        "code": -32601, 
        "message": "method not given"
      }, 
      "id": null, 
      "jsonrpc": "2.0"
    }
    

    It would be nice to add some Python code example, as I'm not able to use the api with python.

    Here come's the snippet i'm using with python. I'm sure that i'm doing something wrong, but dunno whats wrong...

    The HMAC generating OK, i'm passing OK the params trought the request.post function, but API still saying no method issued. So weird.
    def minerStatsHiveOS():
    	api_key = 'api_key'
    	secret_key = 'secret_key'
    
    	import requests, json, datetime, hmac, hashlib, urllib, pycurl
    
    	url = 'https://api.hiveos.farm/worker/eypiay.php'
    	method = 'getRigs'
    	payload = {'public_key': api_key, 'method': method}
    	hmac_value = hmac.new(key=secret_key, msg=urllib.urlencode(payload), digestmod=hashlib.sha256).hexdigest()
    	
    	print hmac_value
    
    	headers = {'HMAC': hmac_value}
    
    	resp = requests.post(url=url, params=payload, headers=headers)
    	data = json.loads(resp.text)
    	
    	return make_response(jsonify(data), 200)
    


  • Ok. Now I see there are new python examples (they weren't first day the post came up). So it's working okay with CURL but no with Requests... Weird...
  • @dawy you are sending a POST request, you probably need to send a GET. Change `requests.post` to `requests.get` and see if it works :)
  • Hi! Great work.
    Need to return Red Temp value, I suggest it must be in getCurrentStats method.
    I need it to check temp and fans (I make a telegram bot)
  • В python скрипте на 193 строке нужно заменить return ocs на return stats
  • Keiskar wrote: »
    В python скрипте на 193 строке нужно заменить return ocs на return stats

    fixed. thanks.

    red temp is added into new field user.red_temp
  • edited February 14
    I'm sending a POST request to https://api.hiveos.farm/worker/eypiay.php?method=getCurrentStats&public_key=<public_key>; with Postman.app

    And I keep getting:
    {
      "error": {
      "code": -32601, 
      "message": "method not given"
      }, 
      "id": null, 
      "jsonrpc": "2.0"
    }
    

    HMAC generation is OK.
  • edited February 15
    I get it now, I need a pre-request script to generate the HMAC sha256 signature. Anyone have an example in JS?
  • very nice! thanks for this enhancement!
  • Отлично! спасибо, пробуем...
  • function for calculate hmac value on android
    static String HmacValue(String key, String data) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException, DecoderException {
    
            String returnString = "";
            try {
                SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(UTF_8), "HmacSHA256");
                Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
                sha256_HMAC.init(secret_key);
                returnString = new String(Hex.encodeHex(sha256_HMAC.doFinal(data.getBytes("UTF-8"))));
                Log.w(LOG_TAG,"retSrng "+returnString);
    
            }catch (Exception e){
                Log.e(LOG_TAG,"err in hmac encoding");
                e.printStackTrace();
            }
            return returnString;
        }
    
  • @DimaFern, may be possible to implement create QR-Code with secret and public key in personal account?
  • Хотел бы сделать клиентское приложение на nativeScript, но для этого нужно вам настроить сервер на Cross-Origin Resource Sharing (CORS), иначе из localhost'a отправляется сначала запрос OPTIONS, сервер отвечает отказом (не настроен получать такой метод) и собственно POST не отправляется.
    И сколько я не мучался отправлять разные запросы с разными параметрами и даже танцевал голый с бубном, ошибка одна и та же -32601
    Поделитесь запросом на JS (axios)
  • DimaFern wrote: »
    Keiskar wrote: »
    В python скрипте на 193 строке нужно заменить return ocs на return stats

    fixed. thanks.

    red temp is added into new field user.red_temp

    Спасибо, свойство red_temp вижу,
    но оно всегда приходит как "{" fngwi11ufxdr.png

    Также хочу попросить возвращать значение баланса лицевого счета, в виде свойства balance в секции user
  • I make my own code for nodejs / express , not complete but its work
    var express = require('express');
    var router = express.Router();
    var request = require('request');
    var CryptoJS = require("crypto-js");
    
    /* GET home page. */
    router.get('/api/:public_key/:secret_key/:method', function (req, res, next) {
      var key = req.params.secret_key;
      var data = 'public_key='+req.params.public_key+'&method='+req.params.method;
    
      var hash = CryptoJS.HmacSHA256(data, key);  
      const myhmackey = hash.toString();
    
      var options = {
        url: 'https://api.hiveos.farm/worker/eypiay.php',
        headers: {
          'HMAC': myhmackey,
          'content-type': 'application/jso'
        },
        form: {
          public_key: req.params.public_key,
          method: req.params.method
        }
      };
    
      function callback(error, response, body) {
        //process.stdout.write(getHash(data))
    
        console.log(body)
        if (!error && response.statusCode == 200) {
          var info = JSON.parse(body);
          var re = info;  
          res.json({
            success: true,
            data: re.result,
        })    
         
        }
      }
      
    
    
      request.post(options, callback);
     
    });
    
    module.exports = router;
    
  • вопрос такой. Как отключить 2-ую аутентификацию если потерял телефон и номер
  • how do i turn on the api access so that i can add my rig running hiveOS to awesome miner ?
  • hello i installed hiveos app in my samsung phone and it ask me public key (it s ok) and secret apikey , where can i find it or create it?
    tks
  • О уже и приложуху сварганили !
  • работает )))
  • Any plans to include commands such as reboot the server or upgrade or any other commands you can do from the control panel? or a watchdog output to a URL/JSON besides Telegram notifications that could trigger an external rebooter?
  • I noticed that my HiveOS API script has started to be rate limited (and returning more informative failures). First, sorry if I caused any issue; I assumed refreshing every 10 seconds like the web app does would be ok.

    Can someone offer guidance on how often each API call can be made? Are there APIs that can be called more often (e.g. stats)?

    I noticed this on the HiveOS todo list: "Dude, where is my GPU" script for detecting card physically with fans and leds.

    I have a script that does this for nvidia cards (blink LEDs) and another script that correlates HiveOS GPU number to the PCI manufacturer data for each GPU - useful for id'ing cards in a mixed card rig. As far as script for turning fans on/off - won't touch that ;) Easy to do and my LED blinky script can easily be modified to do so. Let me know if you are interested and I can pass them along.

  • edited March 10
    Answer: There is a limit of 50 request in 5 minutes to API or monitor url. Counters reset every 5 min after the first request in 5 minutes period. Same rate from the whole api.
  • edited March 12
    For python 3:
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    '''
    
    Hive OS API usage example
    
    Install curl:
    easy_install pycurl
    pip install pycurl
    '''
    
    
    import pycurl
    import sys
    import datetime
    import urllib.parse
    import hmac
    import hashlib
    import io
    import json
    
    
    argv = sys.argv
    argc = len(sys.argv)
    null = 0
    
    
    class HiveAPIExample:
    
        def __init__(self):
            pass
    
        __SECRET_KEY = b'YOURKEYHERE'
        """
            Your secret API key, you sign the message with it
            @var string 64 hex chars
            """
    
        __PUBLIC_KEY = b'YOURKEYHERE'
        """
            This is a public key
            @var string 64 hex chars
            """
    
        __URL = "https://api.hiveos.farm/worker/eypiay.php";
        """
            Api connection URL
            Please use HTTPS, not HTTP for calls for better security.
            @var string
            """
    
    
        def run(self):
            self.__log("=== Hive API example ===")
    
            method = argv[1]
    
            if method != "multiRocket":
                # run this class methods by name
                m = getattr(self, method)
                result = m()
            else:
                if argc >= 4:
                    # at least rig ids and miner required
                    # take the arguments from commandline
                    result = self.multiRocket(argv[2], argv[3], argv[4], argv[5], argv[6])
                else:
                    # To use rocket you have to know what you are doing. Then delete these lines and edit the following.
                    self.log("Please edit the source to use multiRocket method")
                    exit()
    
                    # this is just an example, use some of your real ids which you get with other methods
    
                    # set everything to rigs ids 1, 2 and 3
                    result = self.multiRocket("1,2,3", "claymore", "xmrig", 107800, 800)
    
                    # set bminer to rigs ids 4 and 5, unset second miner
                    # ??? result = self.multiRocket("4,5", "bminer", "0", null, null)
    
            if result is not None:
                # print_r($result);
                print ( json.dumps(result, indent=4) )
                print
    
        def request(self, params):
            """
                Make API request with given params. Signs the request with secret key.
                @param: array params
                @return array
                """
            params["public_key"] = self.__PUBLIC_KEY
            post_data = urllib.parse.urlencode(params)
            hmac_ = hmac.new(self.__SECRET_KEY, post_data.encode("utf-8"), hashlib.sha256).hexdigest()
    
            curl = pycurl.Curl()
            curl.setopt(pycurl.URL, self.__URL)
            curl.setopt(pycurl.HTTPHEADER, ['HMAC: ' + str(hmac_)])
            curl.setopt(pycurl.POST, True)
            curl.setopt(pycurl.POSTFIELDS, post_data)
            curl.setopt(pycurl.CONNECTTIMEOUT, 10)
            curl.setopt(pycurl.TIMEOUT, 5)
    
            buf = io.BytesIO()
            curl.setopt(pycurl.WRITEFUNCTION, buf.write)
            curl.perform()
    
            response = buf.getvalue()
    
            # Uncomment to debug raw JSON response
            # self.__log("< " + response)
    
            http_code = curl.getinfo(pycurl.HTTP_CODE)
    
            curl.close()
    
            result = json.loads(response.decode('utf-8'))
    
            if http_code != 200:
                if result["error"]:
                    # 404 with some valid JSON
                    self.__log("ERROR: HTTP " + str(http_code) + ": " + json.dumps(result["error"]))
                else:
                    self.__log("ERROR: HTTP " + str(http_code) + ": " + response)
            else:
                if result is None:
                    self.__log("ERROR: Unparsable JSON " + response)
                else:
                    if 'error' in result:  # || !$result["result"]
                        self.__log("ERROR: " + json_encode(result["error"]))
                    else:
                        result = result["result"]
    
            return result
    
        @staticmethod
        def __log(msg):
            str_ = '[' + str(datetime.datetime.today()) + '] ' + msg
            print ( str_ )
            # with open(loggerFilename) as log_file:
            #     log_file.write(str_)
    
        def getRigs(self):
            """
            Rigs list
            """
            params = {
                'method': 'getRigs'
            }
            rigs = self.request(params)
            if 'error ' in rigs:
                return False
    
            return rigs
    
        def getWallets(self):
            """
            Wallets list
            """
            params = {
                'method': 'getWallets'
            }
            wallets = self.request(params)
            if 'error' in wallets:
                return False
    
            return wallets
    
        def getOC(self):
            """
            Overclocking profiles
            """
            params = {
                'method': 'getOC'
            }
            ocs = self.request(params)
            if 'error' in ocs:
                return False
    
            return ocs
    
        def getCurrentStats(self):
            """
            Monitor stats for all the rigs
            """
            params = {
                'method': 'getCurrentStats'
            }
            stats = self.request(params)
            if 'error' in stats:
                return False
    
            return stats
    
        def multiRocket(self, rig_ids_str, miner, miner2, id_wal, id_oc):
            """
            Sets parameters for rigs
    
            @param rig_ids_str coma separated string with rig ids "1,2,3,4"
            @param miner Miner to set. Leave it null if you do not want to change. "claymore", "claymore-z", "ewbf", ...
            @param miner2 Second miner to set. Leave it null if you do not want to change. "0" - if you want to unset it.
            @param id_wal ID of wallet. Leave it null if you do not want to change.
            @param id_oc ID of OC profile. Leave it null if you do not want to change.
            @return bool|mixed
            """
            if rig_ids_str is not None:
                self.log("Rigs ids required")
                exit()
    
            params = {
                'method': 'multiRocket',
                'rig_ids_str': rig_ids_str,
                'miner': miner,
                'miner2': miner2,
                'id_wal': id_wal,
                'id_oc': id_oc
            }
    
            result = self.request(params)
            if 'error' in result:
                return False
    
            return result
    
    
    if argc <= 1:
        script = sys.argv[0]
        print ( "Usage: " + script + " methodName aguments" )
        print ( "Examples:" )
        print ( "\t" + script + " getRig" )
        print ( "\t" + script + " getWallets" )
        print ( "\t" + script + " getCurrentStats" )
        print ( "\t" + script + " multiRocket \"rig1,rig2\" [miner] [miner2] [id_wal] [id_oc]" )
    else:
        api = HiveAPIExample()
        api.run()
    
  • Nah, python 3 gives me:
    AttributeError: 'HiveAPIExample' object has no attribute 'log'
    
    I'm not able to fix this...
  • Can somebody pass line how to auth this using bash/curl? I'd like to get wallets list
  • Is there an Answer to the "Method not given" failure?
    Do i need payed Account for API use?
    Anyone successfully got ApI answer in Postman?
Sign In or Register to comment.