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

@holger80 · 2020-08-19 22:07 · hive-139531

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

#development #beem #python #hiveonboard
Payout: 0.000 HBD
Votes: 558
More interactions (upvote, reblog, reply) coming soon.