How To Create A Hive Engine Bot With Python

Welcome. In this tutorial, we are going to use Python to create a Hive Engine bot.

This bot is going to scan the TribalDex diesel pools.

Whenever a swap is made, our bot will send us a text message.

It will also check the order books on TribalDex, to see if there are any buy orders that we could arbitrage.

If there are, the bot will let us know.

Things You'll Need

You don't need to be an expert programmer to set this bot up. I've already written all of the code for you.

You do need a bit of common sense, and you need to be able to follow instructions.

If you think you can handle that, then let's move forward.

Here's what you'll need for this bot to work:

Let's go over each of these steps.

Installing Python

Before you go installing Python on your system, let's check if you already have it installed.

Open up the Terminal or Command Prompt application on your computer. Then type the following command:

python3 --version

If that doesn't work, try this one:

python --version

If you already have Python installed, you should get a message like this:

python3 is installed on my system

If you don't have it installed yet, you can install it by doing one of the following:

For Mac or Linux, install Homebrew and then type:

brew install python3

For Windows, you can just download Python directly from the Python website.

Once you're done, make sure to check your installation by entering python3 --version  in your Terminal.

Installing Beem

Beem is a Python library that will allow us to interact with the Hive blockchain.

Here's how you install it.

Enter the following command into Terminal:

python3 -m pip install beem

If that doesn't work, try this:

python -m pip install beem

Installing Twilio

Twilio is the Python library that we'll be using to send SMS messages. There are other options out there, so if you're already experienced with Python, then feel free to use whatever service you like.

Here's how you install Twilio.

Enter the following command into Terminal:

pip install twilio

If that doesn't work, try this:

pip3 install twilio

If neither of those work, here's a useful guide to installing Twilio.

Creating A Twilio Account

This part is pretty straighforward. Just create a free account on Twilio.com.

Then just generate a free Twilio phone number. You will need to verify your own phone number by having a text sent to your phone.

Make sure to use your real phone number, because this is the only number that your free account will be able to send text messages to.

Also, the free account comes with about $15 worth of credits. $1 of that will be used to create your free Twilio phone number, and then each text you send will cost slightly above $0.01.

This means that the free account will send about ~1300 free text messages to you. After you use up that balance, you'll need to start paying the 1 cent per SMS if you find the service valuable enough.

Your Twilio Credentials

There are 3 pieces of info that you'll need in order to connect the Hive Engine bot to your Twilio account.

your Twilio SID and Auth ID

Once you have that information, we can move on to the fun part- actually creating the bot.

Setting Up Your Bot

Open up your text editor and create a new file called bot.py

You can save this wherever you like, but I recommend saving it at the root of your drive for easy access.

Paste the following code into your new file:

from beem.blockchain import Blockchain
from beem import Hive
import json
from types import SimpleNamespace
import ftplib
import hiveengine.wallet
from hiveengine.market import Market
from collections import defaultdict
import os
from twilio.rest import Client

# You need to set the following variables...

twilioSID = 'YOUR_TWILIO_SID'
twilioAuthID = 'YOUR_TWILIO_AUTH_ID'
twilioPhoneNumber = 'YOUR_TWILIO_NUMBER' #your twilio phone number, including country code. for example '+12223334444'
textMessageRecipient = 'YOUR_PHONE_NUMBER' #the number you want to send the message to, must be your verified number that you connected to Twilio
pairToWatch = 'SWAP.HIVE:DEC' #the trading pair you want to monitor, for example 'SWAP.HIVE:DEC'
tokenToWatch = 'DEC' #the token you want to buy. if you wanted to buy DEC, you would be watching for DEC sell orders

# YOU ARE DONE SETTING VARIABLES, DON'T TOUCH ANYTHING ELSE

client = Client(twilioSID, twilioAuthID)

h = Hive()
blockchain = Blockchain(blockchain_instance=h)


# in this script we are looking for sells in the diesel pool, so we can buy from diesel pool and sell to buy book

stream = blockchain.stream()

for op in stream:
  if op["type"] == 'custom_json':
    if op["id"] == 'ssc-mainnet-hive':
      jsonData = json.loads(op["json"])

      if isinstance(jsonData, dict):
        if 'contractName' in jsonData:
          if jsonData["contractName"] == 'marketpools' and jsonData["contractAction"] == 'swapTokens':
            if jsonData['contractPayload']['tokenPair'] == pairToWatch and jsonData['contractPayload']['tokenSymbol'] == tokenToWatch:
              if 'minAmountOut' in jsonData['contractPayload']:
                price = float(jsonData['contractPayload']['minAmountOut']) / float(jsonData['contractPayload']['tokenAmount'])
                print('Price:')
                print(price)
                market = Market(blockchain_instance=h)
                buys = market.get_buy_book(tokenToWatch, account=None, limit=100, offset=0)
                profitableOrders = 0
                profitableVolume = 0
                for buyOrder in buys:
                  if float(buyOrder['price']) > price:
                    profitableOrders += 1
                    profitableVolume += float(buyOrder['quantity'])
                    print(tokenToWatch + ' Highest Buy Order: ' + buyOrder['price']);
                    print(tokenToWatch + ' Buybook Volume: ' + buyOrder['quantity']);
                message = client.messages \
                  .create(
                       body='[Dict], the price of ' + jsonData['contractPayload']['tokenSymbol'] + ' just dropped to ' + str(price) + ', and you can sell ' + str(profitableVolume) + ' above that price right now.',
                       from_= twilioPhoneNumber, #your twilio phone number, including country code and area code
                       to= textMessageRecipient 
                   )

      if isinstance(jsonData, list):
        for transaction in jsonData:
          if 'contractName' in transaction:
            if transaction["contractName"] == 'marketpools' and transaction["contractAction"] == 'swapTokens':
              if transaction['contractPayload']['tokenPair'] == pairToWatch and transaction['contractPayload']['tokenSymbol'] == tokenToWatch:
                if 'minAmountOut' in transaction['contractPayload']:
                  #print('Pair: ' + jsonData['contractPayload']['tokenPair'] + '\nInput: ' + jsonData['contractPayload']['tokenAmount'] + '\nMinimum Output: ' + jsonData['contractPayload']['minAmountOut'])
                  price = float(transaction['contractPayload']['minAmountOut']) / float(transaction['contractPayload']['tokenAmount'])
                  print('Price:')
                  print(price)
                  market = Market(blockchain_instance=h)
                  buys = market.get_buy_book(tokenToWatch, account=None, limit=100, offset=0)
                  profitableOrders = 0
                  profitableVolume = 0
                  for buyOrder in buys:
                    if float(buyOrder['price']) > price:
                      profitableOrders += 1
                      profitableVolume += float(buyOrder['quantity'])
                      print(tokenToWatch + ' Highest Buy Order: ' + buyOrder['price']);
                      print(tokenToWatch + ' Buybook Volume: ' + buyOrder['quantity']);
                  message = client.messages \
                    .create(
                         body='[List], the price of ' + transaction['contractPayload']['tokenSymbol'] + ' just dropped to ' + str(price) + ', and you can sell ' + str(profitableVolume) + ' above that price right now.',
                         from_= twilioPhoneNumber, #your twilio phone number, including country code and area code
                         to= textMessageRecipient #the number you want to send the message to, must be your verified number that you connected to Twilio
                     )

Save the file. In order to run this file, enter the following command into terminal:

python3 bot.py

Bot.py is whatever you named your file, and you also need to specify the path to that file.

This is why I recommended storing it at the root of your drive. If you stored this file in a folder at users/jimbob/python-stuff/scripts/bot/bot.py, then you would need to enter this command into Terminal:

python3 users/jimbob/python-stuff/scripts/bot/bot.py

If everything goes well, you should get a text message whenever someone sells your tokenToWatch in the Diesel Pool. You may need to give this some time, depending on how much volume that token has.

On the SWAP.HIVE:DEC pair, I get a message every 5 or 10 minutes. If your pair only gets traded once per day, you might not get a message for a while.

Try running the script with a more popular token pair first, just to verify that it's working properly.

Also, the order of your token pair matters. i.e 'SWAP.HIVE:DEC' works, but 'DEC:SWAP.HIVE' does not. Make sure your token pair is correct.

I recommend checking out my Hive Engine Explorer and searching for a diesel pool transaction for the pair you want to trade.

Hive Engine Diesel Pool Explorer

Then, click the TXID and take a look at the custom_json data for that transaction. That data will contain the token pair.

Custom Json data for hive transactions

I hope you enjoyed this tutorial. In the next part of this series, I will show you how to make your bot execute transactions, instead of just sending you a text.

Make sure to subscribe if you want to see more content like this.

If you have any questions, suggestions, feedback etc... join my Telegram and share your thoughts.

Thank you for stopping by. See you next time, peace out.

Update: I was requested to create a version that only sends you a text if the price drops below a certain threshold.

In order to do that, I've added a couple lines to the script.

Specifically, you'll notice a variable called "desiredPrice" in the script below. Edit this variable and set the price that you want to pay (the price in tokens, in our example you would be setting the SWAP.HIVE price)

Use the script below if you want to only be notified when the price drops to a specific level:

from beem.blockchain import Blockchain
from beem import Hive
import json
from types import SimpleNamespace
import ftplib
import hiveengine.wallet
from hiveengine.market import Market
from collections import defaultdict
import os
from twilio.rest import Client

# You need to set the following variables...

twilioSID = 'YOUR_TWILIO_SID'
twilioAuthID = 'YOUR_TWILIO_AUTH_ID'
twilioPhoneNumber = 'YOUR_TWILIO_NUMBER' #your twilio phone number, including country code. for example '+12223334444'
textMessageRecipient = 'YOUR_PHONE_NUMBER' #the number you want to send the message to, must be your verified number that you connected to Twilio
pairToWatch = 'SWAP.HIVE:DEC' #the trading pair you want to monitor, for example 'SWAP.HIVE:DEC'
tokenToWatch = 'DEC' #the token you want to buy. if you wanted to buy DEC, you would be watching for DEC sell orders
desiredPrice = 0.0001 #the price (in HIVE) that you want to pay for your token

# YOU ARE DONE SETTING VARIABLES, DON'T TOUCH ANYTHING ELSE

client = Client(twilioSID, twilioAuthID)

h = Hive()
blockchain = Blockchain(blockchain_instance=h)


# in this script we are looking for sells in the diesel pool, so we can buy from diesel pool and sell to buy book

stream = blockchain.stream()

for op in stream:
  if op["type"] == 'custom_json':
    if op["id"] == 'ssc-mainnet-hive':
      jsonData = json.loads(op["json"])

      if isinstance(jsonData, dict):
        if 'contractName' in jsonData:
          if jsonData["contractName"] == 'marketpools' and jsonData["contractAction"] == 'swapTokens':
            if jsonData['contractPayload']['tokenPair'] == pairToWatch and jsonData['contractPayload']['tokenSymbol'] == tokenToWatch:
              if 'minAmountOut' in jsonData['contractPayload']:
                price = float(jsonData['contractPayload']['minAmountOut']) / float(jsonData['contractPayload']['tokenAmount'])
                print('Price:')
                print(price)
                market = Market(blockchain_instance=h)
                buys = market.get_buy_book(tokenToWatch, account=None, limit=100, offset=0)
                profitableOrders = 0
                profitableVolume = 0
                for buyOrder in buys:
                  if float(buyOrder['price']) > price:
                    profitableOrders += 1
                    profitableVolume += float(buyOrder['quantity'])
                    print(tokenToWatch + ' Highest Buy Order: ' + buyOrder['price']);
                    print(tokenToWatch + ' Buybook Volume: ' + buyOrder['quantity']);
                if price <= desiredPrice:
                  message = client.messages \
                    .create(
                         body='The price of ' + jsonData['contractPayload']['tokenSymbol'] + ' just dropped to ' + str(price),
                         from_= twilioPhoneNumber, #your twilio phone number, including country code and area code
                         to= textMessageRecipient 
                     )

      if isinstance(jsonData, list):
        for transaction in jsonData:
          if 'contractName' in transaction:
            if transaction["contractName"] == 'marketpools' and transaction["contractAction"] == 'swapTokens':
              if transaction['contractPayload']['tokenPair'] == pairToWatch and transaction['contractPayload']['tokenSymbol'] == tokenToWatch:
                if 'minAmountOut' in transaction['contractPayload']:
                  #print('Pair: ' + jsonData['contractPayload']['tokenPair'] + '\nInput: ' + jsonData['contractPayload']['tokenAmount'] + '\nMinimum Output: ' + jsonData['contractPayload']['minAmountOut'])
                  price = float(transaction['contractPayload']['minAmountOut']) / float(transaction['contractPayload']['tokenAmount'])
                  print('Price:')
                  print(price)
                  market = Market(blockchain_instance=h)
                  buys = market.get_buy_book(tokenToWatch, account=None, limit=100, offset=0)
                  profitableOrders = 0
                  profitableVolume = 0
                  for buyOrder in buys:
                    if float(buyOrder['price']) > price:
                      profitableOrders += 1
                      profitableVolume += float(buyOrder['quantity'])
                      print(tokenToWatch + ' Highest Buy Order: ' + buyOrder['price']);
                      print(tokenToWatch + ' Buybook Volume: ' + buyOrder['quantity']);
                  if price <= desiredPrice:
                    message = client.messages \
                      .create(
                           body='The price of ' + transaction['contractPayload']['tokenSymbol'] + ' just dropped to ' + str(price),
                           from_= twilioPhoneNumber, #your twilio phone number, including country code and area code
                           to= textMessageRecipient #the number you want to send the message to, must be your verified number that you connected to Twilio
                       )