delegationOnboardBot - a new bot for managing delegation to referred accounts created with hiveonboarding
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