Пример #1
0
 def __init__(self, lbryum_path):
     self.config = SimpleConfig()
     self.config.set_key('chain', 'lbrycrd_main')
     self.storage = WalletStorage(lbryum_path)
     self.wallet = Wallet(self.storage)
     self.cmd_runner = Commands(self.config, self.wallet, None)
     if not self.wallet.has_seed():
         seed = self.wallet.make_seed()
         self.wallet.add_seed(seed, "derp")
         self.wallet.create_master_keys("derp")
         self.wallet.create_main_account()
         self.wallet.update_password("derp", "")
     self.network = Network(self.config)
     self.blockchain = get_blockchain(self.config, self.network)
     print self.config.get('chain'), self.blockchain
     self.wallet.storage.write()
Пример #2
0
def run_non_RPC(config):
    cmdname = config.get('cmd')

    storage = WalletStorage(config.get_wallet_path())
    if storage.file_exists:
        sys.exit("Error: Remove the existing wallet first!")

    def password_dialog():
        return prompt_password(
            "Password (hit return if you do not wish to encrypt your wallet):")

    if cmdname == 'restore':
        text = config.get('text')
        password = password_dialog() if Wallet.is_seed(text) or Wallet.is_xprv(
            text) or Wallet.is_private_key(text) else None
        try:
            wallet = Wallet.from_text(text, password, storage)
        except BaseException as e:
            sys.exit(str(e))
        if not config.get('offline'):
            network = Network(config)
            network.start()
            wallet.start_threads(network)
            log.info("Recovering wallet...")
            wallet.synchronize()
            wallet.wait_until_synchronized()
            msg = "Recovery successful" if wallet.is_found(
            ) else "Found no history for this wallet"
        else:
            msg = "This wallet was restored offline. It may contain more addresses than displayed."
        log.info(msg)
    elif cmdname == 'create':
        password = password_dialog()
        wallet = Wallet(storage)
        seed = wallet.make_seed()
        wallet.add_seed(seed, password)
        wallet.create_master_keys(password)
        wallet.create_main_account()
        wallet.synchronize()
        print "Your wallet generation seed is:\n\"%s\"" % seed
        print "Please keep it in a safe place; if you lose it, you will not be able to restore " \
              "your wallet."
    elif cmdname == 'deseed':
        wallet = Wallet(storage)
        if not wallet.seed:
            log.info("Error: This wallet has no seed")
        else:
            ns = wallet.storage.path + '.seedless'
            print "Warning: you are going to create a seedless wallet'\n" \
                  "It will be saved in '%s'" % ns
            if raw_input("Are you sure you want to continue? (y/n) ") in [
                    'y', 'Y', 'yes'
            ]:
                wallet.storage.path = ns
                wallet.seed = ''
                wallet.storage.put('seed', '')
                wallet.use_encryption = False
                wallet.storage.put('use_encryption', wallet.use_encryption)
                for k in wallet.imported_keys.keys():
                    wallet.imported_keys[k] = ''
                wallet.storage.put('imported_keys', wallet.imported_keys)
                print "Done."
            else:
                print "Action canceled."
        wallet.storage.write()
    else:
        raise Exception("Unknown command %s" % cmdname)
    wallet.storage.write()
    log.info("Wallet saved in '%s'", wallet.storage.path)
Пример #3
0
def main():
    # make sure that certificates are here
    assert os.path.exists(requests.utils.DEFAULT_CA_BUNDLE_PATH)

    # on osx, delete Process Serial Number arg generated for apps launched in Finder
    sys.argv = filter(lambda x: not x.startswith('-psn'), sys.argv)

    # old 'help' syntax
    if len(sys.argv) > 1 and sys.argv[1] == 'help':
        sys.argv.remove('help')
        sys.argv.append('-h')

    # read arguments from stdin pipe and prompt
    for i, arg in enumerate(sys.argv):
        if arg == '-':
            if not sys.stdin.isatty():
                sys.argv[i] = sys.stdin.read()
                break
            else:
                raise BaseException('Cannot get argument from stdin')
        elif arg == '?':
            sys.argv[i] = raw_input("Enter argument:")
        elif arg == ':':
            sys.argv[i] = prompt_password('Enter argument (will not echo):',
                                          False)

    # parse command line
    parser = get_parser()
    args = parser.parse_args()

    if args.verbose:
        logging.getLogger("lbryum").setLevel(logging.INFO)
    else:
        logging.getLogger("lbryum").setLevel(logging.ERROR)

    # config is an object passed to the various constructors (wallet, interface, gui)
    config_options = args.__dict__
    for k, v in config_options.items():
        if v is None or (k in config_variables.get(args.cmd, {}).keys()):
            config_options.pop(k)
    if config_options.get('server'):
        config_options['auto_connect'] = False

    config = SimpleConfig(config_options)
    cmdname = config.get('cmd')

    # run non-RPC commands separately
    if cmdname in ['create', 'restore', 'deseed']:
        run_non_RPC(config)
        sys.exit(0)

    # check if a daemon is running
    server = get_daemon(config)

    if cmdname == 'daemon':
        if server is not None:
            result = server.daemon(config_options)
        else:
            subcommand = config.get('subcommand')
            if subcommand in ['status', 'stop']:
                print "Daemon not running"
                sys.exit(1)
            elif subcommand == 'start':
                if hasattr(os, "fork"):
                    p = os.fork()
                else:
                    log.warning(
                        "Cannot start lbryum daemon as a background process")
                    log.warning(
                        "To use lbryum commands, run them from a different window"
                    )
                    p = 0
                if p == 0:
                    network = Network(config)
                    network.start()
                    daemon = Daemon(config, network)
                    daemon.start()
                    daemon.join()
                    sys.exit(0)
                else:
                    print "starting daemon (PID %d)" % p
                    sys.exit(0)
            else:
                print "syntax: lbryum daemon <start|status|stop>"
                sys.exit(1)

    else:
        # command line
        init_cmdline(config_options)
        if server is not None:
            result = server.run_cmdline(config_options)
        else:
            cmd = known_commands[cmdname]
            if cmd.requires_network:
                print "Network daemon is not running. Try 'lbryum daemon start'"
                sys.exit(1)
            else:
                result = run_offline_command(config, config_options)

    print json.dumps(result, indent=2)
    sys.exit(0)
Пример #4
0
def main():
    # make sure that certificates are here
    assert os.path.exists(requests.utils.DEFAULT_CA_BUNDLE_PATH)

    # parse command line
    parser = get_parser()
    args = parser.parse_args()

    if args.verbose:
        logging.getLogger("lbryum").setLevel(logging.INFO)
    else:
        logging.getLogger("lbryum").setLevel(logging.ERROR)
    handler = logging.StreamHandler()
    handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)-8s "
                                           "%(name)s:%(lineno)d: %(message)s"))
    logging.getLogger("lbryum").addHandler(handler)

    # config is an object passed to the various constructors (wallet, interface)
    config_options = args.__dict__
    for k, v in config_options.items():
        if v is None or (k in config_variables.get(args.cmd, {}).keys()):
            config_options.pop(k)
    if config_options.get('server'):
        config_options['auto_connect'] = False
    config = SimpleConfig(config_options)
    cmdname = config.get('cmd')

    # run non-RPC commands separately
    if cmdname in ['create', 'restore', 'deseed']:
        run_non_RPC(config)
        sys.exit(0)

    # check if a daemon is running
    server = get_daemon(config)

    if cmdname == 'daemon':
        if server is not None:
            result = server.daemon(config_options)
        else:
            subcommand = config.get('subcommand')
            if subcommand in ['status', 'stop']:
                print "Daemon not running"
                sys.exit(1)
            elif subcommand == 'start':
                if hasattr(os, "fork"):
                    p = os.fork()
                else:
                    log.warning("Cannot start lbryum daemon as a background process")
                    log.warning("To use lbryum commands, run them from a different window")
                    p = 0
                if p == 0:
                    network = Network(config)
                    network.start()
                    daemon = Daemon(config, network)
                    daemon.start()
                    daemon.join()
                    sys.exit(0)
                else:
                    print "starting daemon (PID %d)" % p
                    sys.exit(0)
            else:
                print "syntax: lbryum daemon <start|status|stop>"
                sys.exit(1)
    else:
        # command line
        init_cmdline(config_options)
        if server is not None:
            result = server.run_cmdline(config_options)
        else:
            cmd = Commands.known_commands[cmdname]
            if cmd.requires_network:
                print "Network daemon is not running. Try 'lbryum daemon start'"
                sys.exit(1)
            else:
                result = run_offline_command(config, config_options)
    print json.dumps(result, indent=2)
    sys.exit(0)
Пример #5
0
def run_non_RPC(config):
    _ = get_blockchain(config, None)
    cmdname = config.get('cmd')

    storage = WalletStorage(config.get_wallet_path())
    if storage.file_exists:
        sys.exit("Error: Remove the existing wallet first!")

    def password_dialog():
        return prompt_password("Password (hit return if you do not wish to encrypt your wallet):")

    if cmdname == 'restore':
        text = config.get('text')
        no_password = config.get('no_password')
        password = None
        if not no_password and (Wallet.is_seed(text) or Wallet.is_xprv(text) or Wallet.is_private_key(text)):
            password = password_dialog()
        try:
            wallet = Wallet.from_text(text, password, storage)
            wallet.create_main_account()
        except BaseException as e:
            sys.exit(str(e))
        if not config.get('offline'):
            network = Network(config)
            network.start()
            wallet.start_threads(network)
            log.info("Recovering wallet...")
            wallet.synchronize()
            wallet.wait_until_synchronized()
            print "Recovery successful" if wallet.is_found() else "Found no history for this wallet"
        else:
            print "This wallet was restored offline. It may contain more addresses than displayed."
    elif cmdname == 'create':
        password = password_dialog()
        wallet = Wallet(storage)
        seed = wallet.make_seed()
        wallet.add_seed(seed, password)
        wallet.create_master_keys(password)
        wallet.create_main_account()
        wallet.synchronize()
        print "Your wallet generation seed is:\n\"%s\"" % seed
        print "Please keep it in a safe place; if you lose it, you will not be able to restore " \
              "your wallet."
    elif cmdname == 'deseed':
        wallet = Wallet(storage)
        if not wallet.seed:
            log.info("Error: This wallet has no seed")
        else:
            ns = wallet.storage.path + '.seedless'
            print "Warning: you are going to create a seedless wallet'\n" \
                  "It will be saved in '%s'" % ns
            if raw_input("Are you sure you want to continue? (y/n) ") in ['y', 'Y', 'yes']:
                wallet.storage.path = ns
                wallet.seed = ''
                wallet.storage.put('seed', '')
                wallet.use_encryption = False
                wallet.storage.put('use_encryption', wallet.use_encryption)
                for k in wallet.imported_keys.keys():
                    wallet.imported_keys[k] = ''
                wallet.storage.put('imported_keys', wallet.imported_keys)
                print "Done."
            else:
                print "Action canceled."
        wallet.storage.write()
    else:
        raise Exception("Unknown command %s" % cmdname)
    wallet.storage.write()
    log.info("Wallet saved in '%s'", wallet.storage.path)
Пример #6
0
def main(args=None):
    # make sure that certificates are here
    assert os.path.exists(requests.utils.DEFAULT_CA_BUNDLE_PATH)

    # parse command line
    parser = get_parser()
    args = parser.parse_args(args)

    if args.verbose:
        logging.getLogger("lbryum").setLevel(logging.INFO)
    else:
        logging.getLogger("lbryum").setLevel(logging.ERROR)
    handler = logging.StreamHandler()
    handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)-8s "
                                           "%(name)s:%(lineno)d: %(message)s"))
    logging.getLogger("lbryum").addHandler(handler)

    # config is an object passed to the various constructors (wallet, interface)
    config_options = args.__dict__
    for k, v in config_options.items():
        if v is None or (k in config_variables.get(args.cmd, {}).keys()):
            config_options.pop(k)
    if config_options.get('server'):
        config_options['auto_connect'] = False
    config = SimpleConfig(config_options)
    cmdname = config.get('cmd')

    # run non-RPC commands separately
    if cmdname in ['create', 'restore', 'deseed']:
        run_non_RPC(config)
        sys.exit(0)

    # check if a daemon is running
    server = get_daemon(config)

    if cmdname == 'daemon':
        if server is not None:
            result = server.daemon(config_options)
        else:
            subcommand = config.get('subcommand')
            if subcommand in ['status', 'stop']:
                print "Daemon not running"
                sys.exit(1)
            elif subcommand == 'start':
                if hasattr(os, "fork"):
                    p = os.fork()
                else:
                    log.warning("Cannot start lbryum daemon as a background process")
                    log.warning("To use lbryum commands, run them from a different window")
                    p = 0
                if p == 0:
                    network = Network(config)
                    network.start()
                    daemon = Daemon(config, network)
                    daemon.start()
                    daemon.join()
                    sys.exit(0)
                else:
                    print "starting daemon (PID %d)" % p
                    sys.exit(0)
            else:
                print "syntax: lbryum daemon <start|status|stop>"
                sys.exit(1)
    else:
        # command line
        init_cmdline(config_options)
        if server is not None:
            result = server.run_cmdline(config_options)
        else:
            cmd = Commands.known_commands[cmdname]
            if cmd.requires_network:
                print "Network daemon is not running. Try 'lbryum daemon start'"
                sys.exit(1)
            else:
                result = run_offline_command(config, config_options)
    print json.dumps(result, indent=2)
    sys.exit(0)
Пример #7
0
 def setup_network():
     self.network = Network(self.config)
     log.info("Loading the wallet")
     return defer.succeed(self.network.start())
Пример #8
0
class LBRYumWallet(Wallet):
    def __init__(self, storage, config=None):
        Wallet.__init__(self, storage)
        self._config = config
        self.config = make_config(self._config)
        self.network = None
        self.wallet = None
        self._cmd_runner = None
        self.wallet_unlocked_d = defer.Deferred()
        self.is_first_run = False
        self.printed_retrieving_headers = False
        self._start_check = None
        self._catch_up_check = None
        self._caught_up_counter = 0
        self._lag_counter = 0
        self.blocks_behind = 0
        self.catchup_progress = 0

        # fired when the wallet actually unlocks (wallet_unlocked_d can be called multiple times)
        self.wallet_unlock_success = defer.Deferred()

    def _is_first_run(self):
        return (not self.printed_retrieving_headers and
                self.network.blockchain.retrieving_headers)

    def get_cmd_runner(self):
        if self._cmd_runner is None:
            self._cmd_runner = Commands(self.config, self.wallet, self.network)

        return self._cmd_runner

    def check_locked(self):
        if not self.wallet.use_encryption:
            log.info("Wallet is not encrypted")
            self.wallet_unlock_success.callback(True)
        elif not self._cmd_runner:
            raise Exception("Command runner hasn't been initialized yet")
        elif self._cmd_runner.locked:
            log.info("Waiting for wallet password")
            self.wallet_unlocked_d.addCallback(self.unlock)
        return self.wallet_unlock_success

    def unlock(self, password):
        if self._cmd_runner and self._cmd_runner.locked:
            try:
                self._cmd_runner.unlock_wallet(password)
                self.wallet_unlock_success.callback(True)
                log.info("Unlocked the wallet!")
            except InvalidPassword:
                log.warning("Incorrect password, try again")
                self.wallet_unlocked_d = defer.Deferred()
                self.wallet_unlocked_d.addCallback(self.unlock)
                return defer.succeed(False)
        return defer.succeed(True)

    def _start(self):
        network_start_d = defer.Deferred()

        def setup_network():
            self.network = Network(self.config)
            log.info("Loading the wallet")
            return defer.succeed(self.network.start())

        def check_started():
            if self.network.is_connecting():
                if self._is_first_run():
                    log.info("Running the wallet for the first time. This may take a moment.")
                    self.printed_retrieving_headers = True
                return False
            self._start_check.stop()
            self._start_check = None
            if self.network.is_connected():
                network_start_d.callback(True)
            else:
                network_start_d.errback(ValueError("Failed to connect to network."))

        self._start_check = task.LoopingCall(check_started)

        d = setup_network()
        d.addCallback(lambda _: self._load_wallet())
        d.addCallback(lambda _: self._start_check.start(.1))
        d.addCallback(lambda _: network_start_d)
        d.addCallback(lambda _: self._load_blockchain())
        d.addCallback(lambda _: log.info("Subscribing to addresses"))
        d.addCallback(lambda _: self.wallet.wait_until_synchronized(lambda _: None))
        d.addCallback(lambda _: log.info("Synchronized wallet"))
        d.addCallback(lambda _: self.get_cmd_runner())
        d.addCallbacks(lambda _: log.info("Set up lbryum command runner"))
        return d

    def _stop(self):
        if self._start_check is not None:
            self._start_check.stop()
            self._start_check = None

        if self._catch_up_check is not None:
            if self._catch_up_check.running:
                self._catch_up_check.stop()
            self._catch_up_check = None

        d = defer.Deferred()

        def check_stopped():
            if self.network:
                if self.network.is_connected():
                    return False
            stop_check.stop()
            self.network = None
            d.callback(True)

        if self.wallet:
            self.wallet.stop_threads()
            log.info("Stopped wallet")
        if self.network:
            self.network.stop()
            log.info("Stopped connection to lbryum server")

        stop_check = task.LoopingCall(check_stopped)
        stop_check.start(.1)
        return d

    def _load_wallet(self):
        path = self.config.get_wallet_path()
        storage = lbryum_wallet.WalletStorage(path)
        wallet = lbryum_wallet.Wallet(storage)
        if not storage.file_exists:
            self.is_first_run = True
            seed = wallet.make_seed()
            wallet.add_seed(seed, None)
            wallet.create_master_keys(None)
            wallet.create_main_account()
            wallet.synchronize()
        self.wallet = wallet
        self._check_large_wallet()
        return defer.succeed(True)

    def _check_large_wallet(self):
        addr_count = len(self.wallet.addresses(include_change=False))
        if addr_count > 1000:
            log.warning("Your wallet is excessively large (%i addresses), "
                        "please follow instructions here: "
                        "https://github.com/lbryio/lbry/issues/437 to reduce your wallet size",
                        addr_count)
        else:
            log.info("Wallet has %i addresses", addr_count)

    def _load_blockchain(self):
        blockchain_caught_d = defer.Deferred()

        def on_update_callback(event, *args):
            # This callback is called by lbryum when something chain
            # related has happened
            local_height = self.network.get_local_height()
            remote_height = self.network.get_server_height()
            updated_blocks_behind = self.network.get_blocks_behind()
            log.info(
                'Local Height: %s, remote height: %s, behind: %s',
                local_height, remote_height, updated_blocks_behind)

            self.blocks_behind = updated_blocks_behind
            if local_height != remote_height:
                return

            assert self.blocks_behind == 0
            self.network.unregister_callback(on_update_callback)
            log.info("Wallet Loaded")
            reactor.callFromThread(blockchain_caught_d.callback, True)

        self.network.register_callback(on_update_callback, ['updated'])

        d = defer.succeed(self.wallet.start_threads(self.network))
        d.addCallback(lambda _: blockchain_caught_d)
        return d

    # run commands as a defer.succeed,
    # lbryum commands should be run this way , unless if the command
    # only makes a lbrum server query, use _run_cmd_as_defer_to_thread()
    def _run_cmd_as_defer_succeed(self, command_name, *args, **kwargs):
        cmd_runner = self.get_cmd_runner()
        cmd = Commands.known_commands[command_name]
        func = getattr(cmd_runner, cmd.name)
        return defer.succeed(func(*args, **kwargs))

    # run commands as a deferToThread,  lbryum commands that only make
    # queries to lbryum server should be run this way
    # TODO: keep track of running threads and cancel them on `stop`
    #       otherwise the application will hang, waiting for threads to complete
    def _run_cmd_as_defer_to_thread(self, command_name, *args, **kwargs):
        cmd_runner = self.get_cmd_runner()
        cmd = Commands.known_commands[command_name]
        func = getattr(cmd_runner, cmd.name)
        return threads.deferToThread(func, *args, **kwargs)

    def _update_balance(self):
        accounts = None
        exclude_claimtrietx = True
        d = self._run_cmd_as_defer_succeed('getbalance', accounts, exclude_claimtrietx)
        d.addCallback(
            lambda result: Decimal(result['confirmed']) + Decimal(result.get('unconfirmed', 0.0)))
        return d

    # Always create and return a brand new address
    def get_new_address(self, for_change=False, account=None):
        return defer.succeed(self.wallet.create_new_address(account=account,
                                                            for_change=for_change))

    # Get the balance of a given address.
    def get_address_balance(self, address, include_balance=False):
        c, u, x = self.wallet.get_addr_balance(address)
        if include_balance is False:
            return Decimal(float(c) / COIN)
        else:
            return Decimal((float(c) + float(u) + float(x)) / COIN)

    @defer.inlineCallbacks
    def create_addresses_with_balance(self, num_addresses, amount, broadcast=True):
        addresses = self.wallet.get_unused_addresses(account=None)
        if len(addresses) > num_addresses:
            addresses = addresses[:num_addresses]
        elif len(addresses) < num_addresses:
            for i in range(len(addresses), num_addresses):
                address = self.wallet.create_new_address(account=None)
                addresses.append(address)

        outputs = [[address, amount] for address in addresses]
        tx = yield self._run_cmd_as_defer_succeed('payto', outputs, broadcast=broadcast)
        defer.returnValue(tx)

    # Return an address with no balance in it, if
    # there is none, create a brand new address
    @defer.inlineCallbacks
    def get_unused_address(self):
        addr = self.wallet.get_unused_address(account=None)
        if addr is None:
            addr = yield self.get_new_address()
        defer.returnValue(addr)

    def get_least_used_address(self, account=None, for_change=False, max_count=100):
        return defer.succeed(self.wallet.get_least_used_address(account, for_change, max_count))

    def get_block(self, blockhash):
        return self._run_cmd_as_defer_to_thread('getblock', blockhash)

    def get_most_recent_blocktime(self):
        height = self.network.get_local_height()
        if height < 0:
            return defer.succeed(None)
        header = self.network.get_header(self.network.get_local_height())
        return defer.succeed(header['timestamp'])

    def get_best_blockhash(self):
        height = self.network.get_local_height()
        if height < 0:
            return defer.succeed(None)
        header = self.network.blockchain.read_header(height)
        return defer.succeed(self.network.blockchain.hash_header(header))

    def _get_blockhash(self, height):
        header = self.network.blockchain.read_header(height)
        return defer.succeed(self.network.blockchain.hash_header(header))

    def _get_transaction(self, txid):
        return self._run_cmd_as_defer_to_thread("gettransaction", txid)

    def get_name_claims(self):
        return self._run_cmd_as_defer_succeed('getnameclaims')

    def _get_claims_for_name(self, name):
        return self._run_cmd_as_defer_to_thread('getclaimsforname', name)

    @defer.inlineCallbacks
    def _send_name_claim(self, name, value, amount,
                            certificate_id=None, claim_address=None, change_address=None):
        log.info("Send claim: %s for %s: %s ", name, amount, value)
        claim_out = yield self._run_cmd_as_defer_succeed('claim', name, value, amount,
                                                         certificate_id=certificate_id,
                                                         claim_addr=claim_address,
                                                         change_addr=change_address)
        defer.returnValue(claim_out)

    @defer.inlineCallbacks
    def _abandon_claim(self, claim_id, txid, nout):
        log.debug("Abandon %s" % claim_id)
        tx_out = yield self._run_cmd_as_defer_succeed('abandon', claim_id, txid, nout)
        defer.returnValue(tx_out)

    @defer.inlineCallbacks
    def _support_claim(self, name, claim_id, amount):
        log.debug("Support %s %s %f" % (name, claim_id, amount))
        claim_out = yield self._run_cmd_as_defer_succeed('support', name, claim_id, amount)
        defer.returnValue(claim_out)

    @defer.inlineCallbacks
    def _tip_claim(self, claim_id, amount):
        log.debug("Tip %s %f", claim_id, amount)
        claim_out = yield self._run_cmd_as_defer_succeed('sendwithsupport', claim_id, amount)
        defer.returnValue(claim_out)

    def _do_send_many(self, payments_to_send):
        def handle_payto_out(payto_out):
            if not payto_out['success']:
                raise Exception("Failed payto, reason:{}".format(payto_out['reason']))
            return payto_out['txid']

        log.debug("Doing send many. payments to send: %s", str(payments_to_send))
        d = self._run_cmd_as_defer_succeed('payto', payments_to_send.iteritems())
        d.addCallback(lambda out: handle_payto_out(out))
        return d

    def _get_value_for_name(self, name):
        if not name:
            raise Exception("No name given")
        return self._run_cmd_as_defer_to_thread('getvalueforname', name)

    def _get_value_for_uri(self, uri):
        if not uri:
            raise Exception("No uri given")
        return self._run_cmd_as_defer_to_thread('getvalueforuri', uri)

    def _get_values_for_uris(self, page, page_size, *uris):
        return self._run_cmd_as_defer_to_thread('getvaluesforuris', False, page, page_size,
                                                *uris)

    def _claim_certificate(self, name, amount):
        return self._run_cmd_as_defer_succeed('claimcertificate', name, amount)

    def _get_certificate_claims(self):
        return self._run_cmd_as_defer_succeed('getcertificateclaims')

    def get_claims_from_tx(self, txid):
        return self._run_cmd_as_defer_to_thread('getclaimsfromtx', txid)

    def _get_claim_by_outpoint(self, txid, nout):
        return self._run_cmd_as_defer_to_thread('getclaimbyoutpoint', txid, nout)

    def _get_claim_by_claimid(self, claim_id):
        return self._run_cmd_as_defer_to_thread('getclaimbyid', claim_id)

    def _get_claims_by_claimids(self, *claim_ids):
        return self._run_cmd_as_defer_to_thread('getclaimsbyids', claim_ids)

    def _get_balance_for_address(self, address):
        return defer.succeed(Decimal(self.wallet.get_addr_received(address)) / COIN)

    def get_nametrie(self):
        return self._run_cmd_as_defer_to_thread('getclaimtrie')

    def _get_history(self):
        return self._run_cmd_as_defer_succeed('claimhistory')

    def _address_is_mine(self, address):
        return self._run_cmd_as_defer_succeed('ismine', address)

    # returns a list of public keys associated with address
    # (could be multiple public keys if a multisig address)
    def get_pub_keys(self, address):
        return self._run_cmd_as_defer_succeed('getpubkeys', address)

    def list_addresses(self):
        return self._run_cmd_as_defer_succeed('listaddresses')

    def list_unspent(self):
        return self._run_cmd_as_defer_succeed('listunspent')

    def send_claim_to_address(self, claim_id, destination, amount):
        return self._run_cmd_as_defer_succeed('sendclaimtoaddress', claim_id, destination, amount)

    def import_certificate_info(self, serialized_certificate_info):
        return self._run_cmd_as_defer_succeed('importcertificateinfo', serialized_certificate_info)

    def export_certificate_info(self, certificate_claim_id):
        return self._run_cmd_as_defer_succeed('exportcertificateinfo', certificate_claim_id)

    def get_certificates_for_signing(self):
        return self._run_cmd_as_defer_succeed('getcertificatesforsigning')

    def claim_renew_all_before_expiration(self, height):
        return self._run_cmd_as_defer_succeed('renewclaimsbeforeexpiration', height)

    def claim_renew(self, txid, nout):
        return self._run_cmd_as_defer_succeed('renewclaim', txid, nout)

    def decrypt_wallet(self):
        if not self.wallet.use_encryption:
            return False
        if not self._cmd_runner:
            return False
        if self._cmd_runner.locked:
            return False
        self._cmd_runner.decrypt_wallet()
        return not self.wallet.use_encryption

    def encrypt_wallet(self, new_password, update_keyring=False):
        if not self._cmd_runner:
            return False
        if self._cmd_runner.locked:
            return False
        self._cmd_runner.update_password(new_password, update_keyring)
        return not self.wallet.use_encryption