示例#1
0
    def setUpClass(cls):
        nodelist = NodeList()
        stm = Steem(node=nodelist.get_nodes())
        stm.config.refreshBackup()
        stm.set_default_nodes(["xyz"])
        del stm

        cls.urls = nodelist.get_nodes()
        cls.bts = Steem(node=cls.urls, nobroadcast=True, num_retries=10)
        set_shared_steem_instance(cls.bts)
示例#2
0
def set_node_list(chain_type=None):
    nodelist = NodeList()
    nodelist.update_nodes()
    chain = None

    if chain_type == 'steemit':
        steem_nodes = nodelist.get_steem_nodes()
        chain = Steem(node=steem_nodes)
        chain.set_default_nodes(steem_nodes)
    elif chain_type == 'hive':
        nodelist = NodeList()
        nodelist.update_nodes()
        hive_nodes = nodelist.get_hive_nodes()
        chain = Hive(node=hive_nodes)
        chain.set_default_nodes(hive_nodes)

    set_shared_blockchain_instance(chain)
    return chain
示例#3
0
    def setUpClass(cls):
        cls.nodelist = NodeList()
        cls.nodelist.update_nodes(steem_instance=Steem(
            node=cls.nodelist.get_nodes(normal=True, appbase=True),
            num_retries=10))
        stm = Steem(node=cls.nodelist.get_nodes())
        stm.config.refreshBackup()
        stm.set_default_nodes(["xyz"])
        del stm

        cls.urls = cls.nodelist.get_nodes()
        cls.bts = Steem(node=cls.urls, nobroadcast=True, num_retries=10)
        set_shared_steem_instance(cls.bts)
        acc = Account("holger80", steem_instance=cls.bts)
        comment = acc.get_blog(limit=20)[-1]
        cls.authorperm = comment.authorperm
        votes = acc.get_account_votes()
        last_vote = votes[-1]
        cls.authorpermvoter = '@' + last_vote['authorperm'] + '|' + acc["name"]
示例#4
0
    def setUpClass(cls):
        cls.nodelist = NodeList()
        cls.nodelist.update_nodes(steem_instance=Steem(
            node=cls.nodelist.get_nodes(hive=True), num_retries=10))
        stm = Steem(node=cls.nodelist.get_nodes(hive=True))
        stm.config.refreshBackup()
        stm.set_default_nodes(["xyz"])
        del stm

        cls.urls = cls.nodelist.get_nodes(hive=True)
        cls.bts = Steem(node=cls.urls, nobroadcast=True, num_retries=10)
        set_shared_steem_instance(cls.bts)
        acc = Account("fullnodeupdate", steem_instance=cls.bts)
        comment = Comment(acc.get_blog_entries(limit=20)[-1],
                          steem_instance=cls.bts)
        cls.authorperm = comment.authorperm
        votes = comment.get_votes()
        last_vote = votes[-1]
        cls.authorpermvoter = comment['authorperm'] + '|' + last_vote["voter"]
示例#5
0
class Beem:
    def __init__(self, bot, settings):
        self.bot = bot
        self.settings = settings
        self.stm = Steem()

    def _is_admin(self, member, channel, guild):
        # Check for admin/bot-admin
        isAdmin = member.permissions_in(channel).administrator
        if not isAdmin:
            checkAdmin = self.settings.getServerStat(guild, "AdminArray")
            for role in member.roles:
                for aRole in checkAdmin:
                    # Get the role that corresponds to the id
                    if str(aRole['ID']) == str(role.id):
                        isAdmin = True
        return isAdmin

    @commands.command(pass_context=True)
    async def account(self, ctx, *, account: str = None):
        """Retuns information about an account"""
        if account is None:
            regAccount = self.settings.getUserStat(ctx.message.author,
                                                   ctx.message.guild,
                                                   "SteemAccount")
            if regAccount is not None and regAccount != "":
                account = regAccount
            else:
                account = ctx.message.author
                account = str(account).split('#')[0]
        a = Account(account, steem_instance=self.stm)
        response = a.print_info(return_str=True)
        await ctx.channel.send("```" + response + "```")

    @commands.command(pass_context=True)
    async def register(self, ctx, *, account: str = None):
        """Register your steemit name"""
        if account is None:
            await ctx.channel.send("I do nothing!")
            return
        try:
            Account(account, steem_instance=self.stm)
        except:
            await ctx.channel.send("Could not register %s!" % account)
            return
        self.settings.setUserStat(ctx.message.author, ctx.message.guild,
                                  "SteemAccount", account)
        await ctx.channel.send("Registered!")

    @commands.command(pass_context=True)
    async def updatenodes(self, ctx):
        """Retuns information about the current node"""
        t = PrettyTable(["node", "Version", "score"])
        t.align = "l"
        nodelist = NodeList()
        nodelist.update_nodes(steem_instance=self.stm)
        nodes = nodelist.get_nodes()
        sorted_nodes = sorted(nodelist,
                              key=lambda node: node["score"],
                              reverse=True)
        for node in sorted_nodes:
            if node["url"] in nodes:
                score = float("{0:.1f}".format(node["score"]))
                t.add_row([node["url"], node["version"], score])
        response = t.get_string()
        self.stm.set_default_nodes(nodes)

        await ctx.channel.send("```" + response + "```")

    @commands.command(pass_context=True)
    async def pricehistory(self, ctx, width: int = 75):
        """Retuns information about the current steem price"""

        feed_history = self.stm.get_feed_history()
        current_base = Amount(feed_history['current_median_history']["base"],
                              steem_instance=self.stm)
        current_quote = Amount(feed_history['current_median_history']["quote"],
                               steem_instance=self.stm)
        price_history = feed_history["price_history"]
        price = []
        for h in price_history:
            base = Amount(h["base"], steem_instance=self.stm)
            quote = Amount(h["quote"], steem_instance=self.stm)
            price.append(base.amount / quote.amount)
        # charset = u'ascii'
        charset = u'utf8'
        chart = AsciiChart(height=10,
                           width=width,
                           offset=4,
                           placeholder='{:6.2f} $',
                           charset=charset)
        response = "Price history for STEEM (median price %4.2f $)\n" % (
            float(current_base) / float(current_quote))

        chart.adapt_on_series(price)
        chart.new_chart()
        chart.add_axis()
        chart._draw_h_line(chart._map_y(
            float(current_base) / float(current_quote)),
                           1,
                           int(chart.n / chart.skip),
                           line=chart.char_set["curve_hl_dot"])
        chart.add_curve(price)
        response += str(chart)
        await ctx.channel.send("```" + response + "```")

    @commands.command(pass_context=True)
    async def curation(self, ctx, *, authorperm: str):

        show_all_voter = False

        all_posts = False
        t = PrettyTable([
            "Voter", "Voting time", "Vote", "Early vote loss", "Curation",
            "Performance"
        ])
        t.align = "l"
        index = 0

        index += 1
        comment = Comment(authorperm, steem_instance=self.stm)
        payout = None
        curation_rewards_SBD = comment.get_curation_rewards(
            pending_payout_SBD=True, pending_payout_value=payout)
        curation_rewards_SP = comment.get_curation_rewards(
            pending_payout_SBD=False, pending_payout_value=payout)
        rows = []
        sum_curation = [0, 0, 0, 0]
        max_curation = [0, 0, 0, 0, 0, 0]
        highest_vote = [0, 0, 0, 0, 0, 0]
        for vote in comment["active_votes"]:
            vote_SBD = self.stm.rshares_to_sbd(int(vote["rshares"]))
            curation_SBD = curation_rewards_SBD["active_votes"][vote["voter"]]
            curation_SP = curation_rewards_SP["active_votes"][vote["voter"]]
            if vote_SBD > 0:
                penalty = (
                    (comment.get_curation_penalty(vote_time=vote["time"])) *
                    vote_SBD)
                performance = (float(curation_SBD) / vote_SBD * 100)
            else:
                performance = 0
                penalty = 0
            vote_befor_min = ((
                (vote["time"]) - comment["created"]).total_seconds() / 60)
            sum_curation[0] += vote_SBD
            sum_curation[1] += penalty
            sum_curation[2] += float(curation_SP)
            sum_curation[3] += float(curation_SBD)
            row = [
                vote["voter"], vote_befor_min, vote_SBD, penalty,
                float(curation_SP), performance
            ]
            if row[-1] > max_curation[-1]:
                max_curation = row
            if row[2] > highest_vote[2]:
                highest_vote = row
            rows.append(row)
        sortedList = sorted(rows, key=lambda row: (row[1]), reverse=False)
        new_row = []
        new_row2 = []
        voter = []
        voter2 = []

        voter = [""]
        voter2 = [""]
        for row in sortedList:
            if show_all_voter:
                if not all_posts:
                    voter = [row[0]]
                if all_posts:
                    new_row[0] = "%d. %s" % (index, comment.author)
                t.add_row(new_row + voter + [
                    "%.1f min" % row[1],
                    "%.3f SBD" % float(row[2]),
                    "%.3f SBD" % float(row[3]),
                    "%.3f SP" % (row[4]),
                    "%.1f %%" % (row[5])
                ])

                new_row = new_row2
        t.add_row(new_row2 + voter2 + ["", "", "", "", ""])
        if sum_curation[0] > 0:
            curation_sum_percentage = sum_curation[3] / sum_curation[0] * 100
        else:
            curation_sum_percentage = 0
        sum_line = new_row2 + voter2
        sum_line[-1] = "High. vote"

        t.add_row(sum_line + [
            "%.1f min" % highest_vote[1],
            "%.3f SBD" % float(highest_vote[2]),
            "%.3f SBD" % float(highest_vote[3]),
            "%.3f SP" % (highest_vote[4]),
            "%.1f %%" % (highest_vote[5])
        ])
        sum_line[-1] = "High. Cur."
        t.add_row(sum_line + [
            "%.1f min" % max_curation[1],
            "%.3f SBD" % float(max_curation[2]),
            "%.3f SBD" % float(max_curation[3]),
            "%.3f SP" % (max_curation[4]),
            "%.1f %%" % (max_curation[5])
        ])
        sum_line[-1] = "Sum"
        t.add_row(sum_line + [
            "-",
            "%.3f SBD" % (sum_curation[0]),
            "%.3f SBD" % (sum_curation[1]),
            "%.3f SP" % (sum_curation[2]),
            "%.2f %%" % curation_sum_percentage
        ])
        response = "curation for %s\n" % (authorperm)
        response += t.get_string()
        await ctx.channel.send("```" + response + "```")
示例#6
0
import discord
from discord.ext import commands
from beem import Steem
from beem.account import Account
from beem.rc import RC
import asyncio
import os
from datetime import datetime, timedelta

EF = os.environ.get('EF')
SR_P = os.environ.get('SR_P')
SR = os.environ.get('SR')
SV = os.environ.get('SV')

steem = Steem(offline=True)
steem.set_default_nodes("https://api.steemit.com")

client = commands.Bot(command_prefix=';;')


@client.event
async def on_ready():
    print("bot is ready")
    await testt()


async def testt():
    while (True):
        await claim()
        account = Account('sourovafrin')
        mana = account.get_manabar()
示例#7
0
class RedFisher:
    def __init__(self):
        """Initialisation."""

        self.load_settings()
        self.nodes = [
            'https://api.steemit.com', 'https://rpc.buildteam.io',
            'https://api.steem.house', 'https://steemd.steemitdev.com',
            'https://steemd.steemitstage.com', 'https://steemd.steemgigs.org'
        ]
        self.s = Steem(keys=self.posting_key)
        self.s.set_default_nodes(self.nodes)
        self.b = Blockchain(self.s)
        set_shared_steem_instance(self.s)
        self.p = Pool(4)

    def timer_start(self):
        """Set a timer to restart the program at 7pm the next day."""

        # Calculate how many seconds until 7pm tomorrow
        now = datetime.today()
        print(now.day)
        a_time = now.replace(day=now.day + 1, hour=19, minute=0, microsecond=0)
        d_time = a_time - now
        secs = d_time.seconds + 1

        # Reload settings from external file
        self.load_settings()

        # Start the timer
        t = threading.Timer(secs, self.redfisher)
        t.start()
        print('Timer set for ' + str(secs / 3600) + ' hours.')

    def load_settings(self):
        """Load the account requrements from an external file."""

        # Load the external .json
        settings = json.loads(open('settings.json', 'r').read())
        # Import the settings to variables
        self.days = settings['days']
        self.posts_per_week = settings['posts_per_week']
        self.min_sp = settings['min_sp']
        self.max_sv = settings['max_sv']
        self.posting_account = settings['posting_account']
        self.posting_key = settings['posting_key']

        print('settings loaded\ndays: %d\nposts per week: %d\nminimum steem '
              'power: %d' % (self.days, self.posts_per_week, self.min_sp))

    def redfisher(self):
        """
        Streams through all posts within given timeframe and sends accounts to
        be validated.
        """

        t1 = time.process_time()

        # Calculate the start block based on how many days were specified
        # in the settings
        now = datetime.now()
        start_date = now - timedelta(days=self.days)
        start_block = self.b.get_estimated_block_num(start_date)
        # Get the end block
        end_block = self.b.get_current_block_num()

        # Create/reset approved user dictionary
        self.user_list = dict()

        # stream comments from start block to current block
        print('streaming comments now')

        # Create checked accounts list
        checked_accounts = list()

        # Infinite while allows for many node swaps
        while True:
            try:
                # Start/continue the stream from start/lastchecked block
                for post in self.b.stream(opNames=['comment'],
                                          start=start_block,
                                          stop=end_block):
                    # Set start block to the one currently being checked
                    start_block = post['block_num']

                    # Assure that the post is not a comment
                    if post['parent_author'] == '':
                        author = post['author']

                        # Don't check accounts that have already been checked
                        if author not in checked_accounts:
                            # Add account to checked accounts
                            checked_accounts.append(author)
                            # Add account to pool to be checked
                            self.p.enqueue(func=self.check, user=author)
                            self.p.run()

                # All checks completed, break loop
                break

            except Exception as e:
                # Switch nodes
                print(e)
                self.failover()

        time.sleep(1)
        t2 = time.process_time()
        print(t2 - t1)

        # Wait for task pool to empty
        while self.p.done() == False:
            time.sleep(2)

        # Attempt to post every 20 seconds until complete
        while True:
            try:
                self.post()
                break
            except:
                time.sleep(20)

    def get_account_age(self, acc):
        """Calculate how old an account is.
        
        Keyword arguments:
        acc -- the account to be checked -- type: Account
        """

        # Declare account creation types
        types = [
            'create_claimed_account', 'account_create_with_delegation',
            'account_create'
        ]

        # Look through history until account creation is found
        for i in acc.history(only_ops=types):
            # Get account creation timestamp
            creation_date_raw = i['timestamp']
            break
        print(creation_date_raw)

        # Convert timestamp into datetime obj
        creation_date = datetime.strptime(creation_date_raw,
                                          '%Y-%m-%dT%H:%M:%S')

        # Calculate age in days
        now = datetime.now()
        acc_age = (now - creation_date).days

        return acc_age

    def post(self):
        """Make the post containing all the collected info for the round."""

        # Get date in string format
        date = datetime.today().strftime('%Y-%m-%d')
        print(date)

        # Read the post body from external file
        post_body = open('post_body.txt', 'r').read()

        # Order the approved accounts by age
        sorted_ul = sorted(self.user_list.keys(),
                           key=lambda y: (self.user_list[y]['age']))

        # For each approved user, add them to the bottom of the post table
        for username in sorted_ul:
            data = self.user_list[username]
            sp = str(round(data['sp'], 3))
            age = data['age']
            svp = data['svp']
            post_body += '\n@%s | %s | %s | %s' % (username, sp, age, svp)

        print(post_body)

        # Broadcast post transaction
        self.s.post(title='Small Accounts To Support - ' + date,
                    body=post_body,
                    author=self.posting_account,
                    tags=[
                        'onboarding', 'retention', 'steem', 'help',
                        'delegation', 'community', 'giveaway'
                    ])
        print('posted')

        # Reset the cycle
        self.refresh()

    def check(self, user):
        """
        Check that the users meet the requirements.
        
        user -- the account to be checked -- type: Account/str
        """

        # If an account wasn't passed, make str into account
        if type(user) != Account:
            acc = Account(user)

        # Check account steempower
        sp = self.sp_check(acc)
        print(user + " sp == " + str(sp))
        if sp <= float(self.min_sp):
            print('min sp met')

            # Check account posts per week
            ppw_check = self.post_check(acc)
            print(user + " posts per week check == " + str(ppw_check))
            if ppw_check:
                print('posts per week met')

                # Check self vote percent
                self_vote_pct = self.vote_check(acc)
                print(user + ' self votes == %' + str(self_vote_pct))
                if self_vote_pct < self.max_sv:
                    print('self vote check met')

                    # Check for powerups and powerdowns
                    powered_up, powered_down = self.vest_check(acc)
                    print(user + " powered up == " + str(powered_up))
                    print(user + " powered down == " + str(powered_down))
                    if powered_up and not powered_down:
                        print('vest check met')

                        # All checks completed

                        # Get account age
                        age = self.get_account_age(acc)

                        # Add account to list so their data is stored for the
                        # daily post.
                        self.user_list[user] = {
                            'sp': round(sp, 3),
                            'age': age,
                            'svp': round(self_vote_pct, 2)
                        }
                        print(self.user_list)

    def sp_check(self, acc):
        """
        Return the users steem power (ignoring outgoing delegations).
        
        acc -- the account to be checked -- type: Account
        """

        # Get absolute steempower
        sp = float(acc.get_steem_power())

        # Get all outgoing delegations and add them to account sp
        for delegation in acc.get_vesting_delegations():
            vests = float(delegation['vesting_shares']['amount'])
            precision = delegation['vesting_shares']['precision']

            dele_sp_raw = self.s.vests_to_sp(vests)
            dele_sp = dele_sp_raw / 10**precision

            sp += dele_sp

        return sp

    def vest_check(self, acc):
        """Check for opwer ups/downs and return 
        powered_up (bool), powered_down (bool).
        
        acc -- the account to be checked -- type: Account
        """

        # get all time powerup and powerdown history
        powered_up = False
        powered_down = False

        vest_history = acc.history_reverse(
            only_ops=['withdraw_vesting', 'transfer_to_vesting'])
        # check for powerups and powerdowns
        for change in vest_history:
            if change['type'] == 'withdraw_vesting':
                powered_down = True
            if change['type'] == 'transfer_to_vesting':
                powered_up = True

            if powered_up and powered_down:
                break

        return powered_up, powered_down

    def vote_check(self, acc):
        """Return the self vote percentage based on weight.
        
        acc -- the account to be checked -- type: Account
        """

        # Declare variables
        total = 0
        self_vote = 0

        # Date datetime for a week ago
        wa = self._get_date_past()
        # Go through all votes in the past week
        for i in acc.history_reverse(only_ops=['vote'], stop=wa):
            # Update total
            total += int(i['weight'])
            # Update self vote total if self vote
            if i['author'] == i['voter']:
                self_vote += int(i['weight'])

        # No votes made results in /0 error, return 0% self vote
        if total == 0:
            return 0

        self_vote_pct = (self_vote / total) * 100

        return self_vote_pct

    def post_check(self, acc):
        """Return true if posts per week requirement is met, false if not.
        
        acc -- the account to be checked -- type: Account
        """

        # Get datetime for a week ago
        wa = self._get_date_past()
        # Get comment history for the last week
        blog_history = acc.history_reverse(only_ops=['comment'], stop=wa)

        # Count how many posts were made in the last week
        count = 0
        for post in blog_history:
            # Check to make sure it isn't a reply
            if post['parent_author'] == '':
                count += 1

        if self.posts_per_week >= count:
            return True
        return True

    def _get_date_past(self, days_ago=7):
        """Returns the datetime for the current time, x days ago.
        
        days_ago -- how many days ago you want the datetime for -- type: int
        """

        now = datetime.now()
        return now - timedelta(days=days_ago)

    def refresh(self):
        """Called when the main module has finished executing and the post has 
        been made. It resets all the settings and resets the cycle.
        """

        self.user_list = dict()
        self.load_settings()
        self.timer_start()

    def failover(self):
        """Switch/cycle through nodes."""

        self.nodes = self.nodes[1:] + [self.nodes[0]]
        print('Switching nodes to ' + self.nodes[0])
示例#8
0
class SteemExplorer():
    def __init__(self,
                 con: Configuration,
                 log: Logger,
                 nobroadcast=True,
                 active=''):
        self.conf = con
        self.stm = Steem(node="https://appbasetest.timcliff.com",
                         nobroadcast=nobroadcast,
                         unsigned=nobroadcast)
        self.stm.set_default_nodes(NODE_LIST)
        self.log = log
        set_shared_steem_instance(self.stm)

    def change_broadcast(self, nobroadcast):
        self.stm = Steem(nobroadcast=nobroadcast, unsigned=nobroadcast)
        set_shared_steem_instance(self.stm)

    def add_hard_key(self, nobroadcast, key):
        self.stm = Steem(nobroadcast=nobroadcast,
                         unsigned=nobroadcast,
                         keys={"active": key})
        set_shared_steem_instance(self.stm)

    def compute_cost(self, type=1, tx_size=1000, perm_len=10, pperm_len=0):
        rc = RC()
        if type == 1:
            cost = rc.comment(tx_size=tx_size,
                              permlink_length=perm_len,
                              parent_permlink_length=pperm_len)
        elif type == 2:
            cost = rc.vote(tx_size=tx_size)
        elif type == 3:
            cost = rc.transfer(tx_size=tx_size, market_op_count=perm_len)
        elif type == 4:
            cost = rc.custom_json(tx_size=tx_size)
        else:
            return False
        return cost

    def is_wallet(self):
        return self.stm.wallet.created()

    def unlocked(self):
        return self.stm.wallet.unlocked()

    def locked(self):
        return not self.unlocked()

    def unlock_wallet(self, p=''):
        if not p:
            p = getpass.getpass("Enter your BIP38 passphrase: ")
        try:
            self.stm.unlock(p)
        except WrongMasterPasswordException:
            return False
        return True

    def lock_wallet(self):
        self.stm.wallet.lock()

    def unlock(self, p=''):
        return self.unlock_wallet(p)

    def lock(self):
        self.stm.wallet.lock()

    def create_wallet(self, p=''):
        if not p:
            p = getpass.getpass("Enter your new BIP38 passphrase: ")
        if p:
            self.stm.wallet.create(p)
            return True
        else:  # pragma: no cover
            return False

    def change_passphrase(self, p=''):
        if not self.__wallet_hook():
            return False
        if not p:
            p = getpass.getpass("Enter your new BIP38 passphrase: ")
        self.stm.wallet.changePassphrase(p)
        return True

    def add_key(self, key):
        if key:
            if not self.__wallet_hook():
                return False
            self.stm.wallet.addPrivateKey(key)
            return True
        else:
            return False

    def delete_wallet(self):
        self.stm.wallet.wipe(True)

    def get_rc(self, account_name):
        acc = Account(account_name)
        mana = acc.get_rc_manabar()
        return mana

    def witness_json(self, name):
        try:
            w = Witness(name)
        except WitnessDoesNotExistsException:
            self.log.log("Witness does not exist.", 2)
            return False
        return w.json()

    def check_key(self, name, key):
        try:
            w = Witness(name)
        except WitnessDoesNotExistsException:
            self.log.log("Witness does not exist.", 2)
            return False
        if key == w['signing_key']:
            return True
        return False

    def disable_witness(self):
        return self.witness_set_properties(DISABLE_KEY)

    def witlist(self):
        w = Witnesses()
        w.printAsTable()

    def update(self, enable=True, key=''):
        if not self.__wallet_hook():
            return False
        w = Witness(self.conf.d['owner'])
        if enable:
            if key:
                if w.update(key,
                            self.conf.d['url'],
                            self.conf.d['props'],
                            account=self.conf.d['owner']):  # pragma: no cover
                    self.log.log("Witness updated with new parameters.", 2)
                    return True
            else:
                if w.update(self.conf.d['pub_key'],
                            self.conf.d['url'],
                            self.conf.d['props'],
                            account=self.conf.d['owner']):  # pragma: no cover
                    self.log.log("Witness updated with new parameters.", 2)
                    return True
        else:
            if w.update(DISABLE_KEY,
                        self.conf.d['url'],
                        self.conf.d['props'],
                        account=self.conf.d['owner']):  # pragma: no cover
                self.log.log("Witness disabled.", 1)
                return True

    def change_key(self, pub_key):
        if not self.__wallet_hook():
            return False
        w = Witness(self.conf.d['owner'])
        if pub_key:
            if w.update(pub_key,
                        self.conf.d['url'],
                        self.conf.d['props'],
                        account=self.conf.d['owner']):
                logstr = "Witness public key updated to {}.".format(pub_key)
                self.log.log(logstr, 1)
                return True
        else:
            return False

    def pubfeed(self, price):
        if not self.__wallet_hook():
            return False
        w = Witness(self.conf.d['owner'])
        if w.feed_publish(base=price, quote="1.000 STEEM"):
            logstr = "Feed published: {:.3f} SBD/STEEM".format(price)
            self.log.log(logstr, 1)
            return True

    def get_price_feed(self, name=''):
        try:
            if name:
                wjson = Witness(name).json()
                p = (float(wjson['sbd_exchange_rate']['base']['amount']) /
                     10**wjson['sbd_exchange_rate']['base']['precision'])
            else:
                wjson = Witness(self.conf.d['owner']).json()
                p = (float(wjson['sbd_exchange_rate']['base']['amount']) /
                     10**wjson['sbd_exchange_rate']['base']['precision'])
        except WitnessDoesNotExistsException:
            return False
        return p

    def get_missed(self, name=''):
        try:
            if name:
                w = Witness(name)
                m = w.json()['total_missed']
            else:
                w = Witness(self.conf.d['owner'])
                m = w.json()['total_missed']
        except WitnessDoesNotExistsException:
            return False
        return m

    def keygen(self, brain='', seq=0):
        bk = BrainKey(brainkey=brain, sequence=seq)
        b = dict()
        b['brainkey'] = bk.get_brainkey()
        b['privkey'] = bk.get_private()
        b['pubkey'] = bk.get_public_key()
        return b

    def suggest_brain(self):
        bk = BrainKey()
        b = dict()
        b['brainkey'] = bk.get_brainkey()
        b['privkey'] = bk.get_private()
        b['pubkey'] = bk.get_public_key()
        return b

    def witness_set_properties(self, pubkey=''):
        if pubkey:
            if self.stm.witness_update(pubkey,
                                       self.conf.d['url'],
                                       self.conf.d['props'],
                                       account=self.conf.d['owner']):
                return True
        else:
            if self.stm.witness_update(self.conf.d['pub_key'],
                                       self.conf.d['url'],
                                       self.conf.d['props'],
                                       account=self.conf.d['owner']):
                return True

    def __wallet_hook(self):
        if not self.is_wallet():
            return False

        if self.locked():
            if not self.unlock_wallet():
                return False
        return True