The post [Bounty to Develop Delegation Manager for Hiveonboard](https://peakd.com/hive-101690/@sportstalksocial/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](https://images.hive.blog/DQmVXtw5zhwnfq9wrCLie1wSi1EoxyV6KMrzcpXQaKWXWJs/Running%20bot) ## 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](https://github.com/holgern/delegationOnboardBot/blob/master/README.md). ### Installing and running the bot Detailed instruction can be found in the [readme](https://github.com/holgern/delegationOnboardBot/blob/master/README.md). ### 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](https://hiveonboard.com/). 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](https://hivesigner.com/sign/account-witness-vote?witness=holger80&approve=1) or on [PeakD](https://peakd.com/witnesses)*

See: delegationOnboardBot - a new bot for managing delegation to referred accounts created with hiveonboarding by @holger80