delegationOnboardBot - a new bot for managing delegation to referred accounts created with hiveonboarding

in HiveDevs4 years ago

The post Bounty to Develop Delegation Manager for Hiveonboard has inspired me to develop a python based delegation manager bot for hiveonboard. The source code can be found in https://github.com/holgern/delegationOnboardBot

Running bot

How does the bot work?

The bot receives a list of all referred accounts by using the API from hiveonboard. Then the current RC level of these accounts is monitored, whenever it drops below a threshold a delegation is given.

The given delegation is removed by the bot when one of the following conditions hold:

  • The account has gained sufficient Hive Power
  • The delegation period exceeds a specific time duration (can be disabled)
  • The account posts without setting beneficiaries to the referrer (can be disabled)
  • Bad behavior was detected (managed by a mute from muteAccount)

The parameter that control the bot are set in the config.json.
A description of the parameter in the config.json can be found in the readme.

Installing and running the bot

Detailed instruction can be found in the readme.

Receiving all created accounts from the hiveonboard api

The following code part fetches all created account that have a referrer equal to peakd

import requests
limit = 20
offset = 0
referrerAccount = "peakd"
onboard_api = "https://hiveonboard.com/api/referrer/" + referrerAccount
last_result = []
cnt = 0
result = []
while last_result is not None and len(last_result) == limit or cnt == 0:
    cnt += 1        
    r = requests.get(onboard_api + '?offset=%d' % (offset))
    if r.ok:
        last_result = r.json()["items"]
        if last_result is not None and len(last_result) > 0:
            result += last_result
            offset += limit

Streaming blocks

Checking for new created accounts

The bot streams now all hive blocks and whenever a new account was created, it checks if this account was created through hiveonboard. When this is the case and the referrer account is the correct one, it is added to the account list.

elif op["type"] == "create_claimed_account":
    if op["json_metadata"] == "":
        continue
    meta_data = json.loads(op["json_metadata"])
    if "beneficiaries" not in meta_data:
        continue
    for entry in meta_data["beneficiaries"]:
        if entry["label"] == "referrer" and entry["name"] == self.config["referrerAccount"]:
            self.accounts[op["new_account_name"]] = {"timestamp": None, "weight": None, "muted": False, "rc": 0, "hp": 0,
                                                     "delegated_hp": 0, "delegation_timestamp": None, "rc_comments": 0,
                                                     "delegation_revoked": False}
            self.accounts[op["new_account_name"]]["weight"] = entry["weight"]
            self.accounts[op["new_account_name"]]["timestamp"] = op["timestamp"].replace(tzinfo=None)
            store_data(self.data_file, "accounts", self.accounts)

Checking Comment, Vote, Transfer and Custom_json

Whenever a referred account is broadcasting either a comment, a vote, a transfer or a custom_json operation, it is checked if the account has sufficient RC. When the account is not able to broadcast at least minPostRC posts, he will receive a small delegation, when the following conditions apply:

  • no delegation yet
  • no revoked delegation
  • less owned HP than maxUserHP
def check_account_on_activity(self, account, timestamp):
    if account not in self.accounts:
        return
    acc = Account(account, blockchain_instance=self.hive)
    self.accounts[account]["rc"] = acc.get_rc_manabar()["current_mana"]
    self.accounts[account]["hp"] = acc.get_token_power(only_own_vests=True)
    self.accounts[account]["rc_comments"] = self.accounts[account]["rc"] / self.comment_rc_costs
    store_data(self.data_file, "accounts", self.accounts)
    if self.accounts[account]["delegated_hp"] > 0:
        return
    if self.accounts[account]["delegation_revoked"]:
        return
    if self.accounts[account]["hp"] > self.config["maxUserHP"]:
        return
    if self.accounts[account]["rc_comments"] < self.config["minPostRC"]:
        ok = self.add_delegation(account, timestamp)
        if ok:
            self.notify_account(account, self.config["delegationMsg"])

where comment_rc_costs is defined as follows:

rc = RC(blockchain_instance=self.hive)
self.comment_rc_costs = rc.comment(tx_size=4000, permlink_length=40, parent_permlink_length=0)

Checking if beneficiaries are correctly set

Whenever a referred account is broadcasting a new post, it is checked if the beneficiaries are correctly set. When they are not set and the account had received an delegation, the delegation is revoked.

def check_beneficiaries(self, author, permlink):
    if author not in self.accounts:
        return
    if self.accounts[author]["delegated_hp"] == 0:
        return
    if self.accounts[author]["delegation_revoked"]:
        return
    if not self.config["beneficiaryRemoval"]:
        return
    comment = None
    cnt = 0
    while comment is None and cnt < 10:
        cnt += 1
        try:
            comment = Comment(construct_authorperm(author, permlink), blockchain_instance=self.hive)
        except:
            comment = None
            time.sleep(3)
    referrer_ok = False
    for bene in comment["beneficiaries"]:
        if bene["account"] == self.config["referrerAccount"] and bene["weight"] == self.accounts[author]["weight"]:
            referrer_ok = True
    if not referrer_ok:
        self.remove_delegation(author)
        self.notify_account(author, self.config["delegationBeneficiaryMsg"])

Checking if an account is muted by "muteAccount"

Whenever an account is muted by muteAccount and had receveid an delegation, the delegation is revoked.

More checks

It is also checked if an account reaches maxUserHP HP, when this is the case, the delegation is removed.

It is also possible to limit the delegation to a certain duration by setting delegationLength. When this is set, delegations are monitored and when the delegation age is higher than the specified threshold, the delegation is removed.

The remaining Hive Power of the delegationAccount is also monitored and when it drops below a threshold a transfer memo is broadcasted.

Storing and loading the current state

The bot writes all important state variables on every change into a data container and loads them on startup.

This makes the bot in combination with systemd very robust. Whenever something goes wrong, the bot is restarted by systemd and the state variables are restored.

Summary

The bot helps services which are using hiveonboard for refering new users and which are managing HP delegation manually by now.

The bot is managing delegation/undelegation of HP to new created accounts through hiveonboard.

Every service who is using hiveonboard for referring new user, can use this bot for automatic delegation management.


If you like what I do, consider casting a vote for me as witness on Hivesigner or on PeakD

Sort:  

Incredible work @holger80! Most impressing how fast you managed to create this.

Just a sidenote:
This app isn't limited to referred accounts created by hiveonboard, since every dApp could use the Open Standard Referral System right now. One example would be https://quello.io which adapted this system from early on and are creating accounts following this system as well.

Just now looking into if Hive onboarding through linkedin would be viable, have to look up with the open standard referral system is...

Upvoted to thank you @holger80 for supporting the CO2Fund by, e.g., supporting posts, banner presentation, SP/HP delegation, dustsweeper gifts, helpful tools, etc.

This is pretty awesome!!

Great one!
I was hoping someone will do something like this.

Great work @holger80 !!
Thank you very much for your work!
Hive on ;)

Good work!

Upvoted by GITPLAIT!

We have a curation trial on Hive.vote. you can earn a passive income by delegating to @gitplait
We share 80 % of the curation rewards with the delegators.


To delegate, use the links or adjust 10HIVE, 20HIVE, 50HIVE, 100HIVE, 200HIVE, 500HIVE, 1,000HIVE, 10,000HIVE, 100,000HIVE


Join the Community and chat with us on Discord let’s solve problems & build together.

cool thx for your hard work

I have picked your post for my daily hive voting initiative, Keep it up and Hive On!!

it looks interesting ... it will only take me a while to study it for the sake of my English and language but a little ochu ps. interesting