Esempio n. 1
0
    def runCommand(self):
        command = self.getCommand()
        self.addToHistory(command)

        command = self.getConstruct(command)

        if command:
            tmp_stdout = sys.stdout

            class stdoutProxy():
                def __init__(self, write_func):
                    self.write_func = write_func
                    self.skip = False

                def flush(self):
                    pass

                def write(self, text):
                    if not self.skip:
                        stripped_text = text.rstrip('\n')
                        self.write_func(stripped_text)
                        QtCore.QCoreApplication.processEvents()
                    self.skip = not self.skip

            if type(self.namespace.get(command)) == type(lambda: None):
                self.appendPlainText(
                    "'{}' is a function. Type '{}()' to use it in the Python console."
                    .format(command, command))
                self.newPrompt()
                return

            sys.stdout = stdoutProxy(self.appendPlainText)
            try:
                try:
                    # eval is generally considered bad practice. use it wisely!
                    # pylint: disable=eval-used
                    result = eval(command, self.namespace, self.namespace)
                    if result is not None:
                        if self.is_json:
                            print(util.json_encode(result))
                        else:
                            self.appendPlainText(repr(result))
                except SyntaxError:
                    # exec is generally considered bad practice. use it wisely!
                    # pylint: disable=exec-used
                    exec(command, self.namespace, self.namespace)
            except SystemExit:
                self.close()
            except (Exception, BaseException):
                # Catch errors in the network layer as well, as long as it uses BaseException.
                traceback_lines = traceback.format_exc().split('\n')
                # Remove traceback mentioning this file, and a linebreak
                for i in (3, 2, 1, -1):
                    traceback_lines.pop(i)
                self.appendPlainText('\n'.join(traceback_lines))
            sys.stdout = tmp_stdout
        self.newPrompt()
        self.set_json(False)
Esempio n. 2
0
def main():
    # The hook will only be used in the Qt GUI right now
    setup_thread_excepthook()
    # on osx, delete Process Serial Number arg generated for apps launched in Finder
    sys.argv = [x for x in sys.argv if not x.startswith('-psn')]

    # 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 Exception('Cannot get argument from stdin')
        elif arg == '?':
            sys.argv[i] = 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()

    # config is an object passed to the various constructors (wallet, interface, gui)
    config_options = args.__dict__
    config_options = {
        key: value
        for key, value in config_options.items()
        if value is not None and key not in config_variables.get(args.cmd, {})
    }

    logs.set_level(config_options['verbose'])

    if config_options.get('server'):
        config_options['auto_connect'] = False
    config_options['cwd'] = os.getcwd()

    # fixme: this can probably be achieved with a runtime hook (pyinstaller)
    try:
        if is_bundle and os.path.exists(
                os.path.join(sys._MEIPASS, 'is_portable')):
            config_options['portable'] = True
    except AttributeError:
        config_options['portable'] = False

    if config_options.get('portable'):
        config_options['electrum_sv_path'] = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), 'electrum_sv_data')

    if config_options.get('file_logging'):
        log_path = os.path.join(platform.user_dir(prefer_local=True), "logs")
        os.makedirs(log_path, exist_ok=True)
        log_path = os.path.join(log_path,
                                time.strftime("%Y%m%d-%H%M%S") + ".log")
        logs.add_file_output(log_path)

    if config_options.get('testnet'):
        Net.set_to(SVTestnet)

    # check uri
    uri = config_options.get('url')
    if uri:
        if not web.is_URI(uri):
            print('unknown command:', uri, file=sys.stderr)
            sys.exit(1)
        config_options['url'] = uri

    # todo: defer this to gui
    config = SimpleConfig(config_options)
    cmdname = config.get('cmd')

    # Set the app state proxy
    if cmdname == 'gui':
        try:
            from electrumsv.gui.qt.app_state import QtAppStateProxy
        except ImportError as e:
            platform.missing_import(e)
        QtAppStateProxy(config, 'qt')
    else:
        AppStateProxy(config, 'cmdline')

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

    if cmdname == 'gui':
        fd, server = daemon.get_fd_or_server(config)
        if fd is not None:
            d = daemon.Daemon(fd, True)
            d.start()
            app_state.app.run_gui()
            sys.exit(0)
        else:
            result = server.gui(config_options)

    elif cmdname == 'daemon':
        subcommand = config.get('subcommand')
        if subcommand in ['load_wallet']:
            init_daemon(config_options)

        if subcommand in [None, 'start']:
            fd, server = daemon.get_fd_or_server(config)
            if fd is not None:
                if subcommand == 'start':
                    pid = os.fork()
                    if pid:
                        print("starting daemon (PID %d)" % pid,
                              file=sys.stderr)
                        sys.exit(0)
                d = daemon.Daemon(fd, False)
                d.start()
                if config.get('websocket_server'):
                    try:
                        from electrumsv import websockets
                    except ImportError as e:
                        platform.missing_import(e)
                    websockets.WebSocketServer(config, d.network).start()
                if config.get('requests_dir'):
                    path = os.path.join(config.get('requests_dir'),
                                        'index.html')
                    if not os.path.exists(path):
                        print("Requests directory not configured.")
                        print("You can configure it using "
                              "https://github.com/spesmilo/electrum-merchant")
                        sys.exit(1)
                d.join()
                sys.exit(0)
            else:
                result = server.daemon(config_options)
        else:
            server = daemon.get_server(config)
            if server is not None:
                result = server.daemon(config_options)
            else:
                print("Daemon not running")
                sys.exit(1)
    else:
        # command line
        server = daemon.get_server(config)
        init_cmdline(config_options, server)
        if server is not None:
            result = server.run_cmdline(config_options)
        else:
            cmd = known_commands[cmdname]
            if cmd.requires_network:
                print("Daemon not running; try 'electrum-sv daemon start'")
                sys.exit(1)
            else:
                result = run_offline_command(config, config_options)
                # print result
    if isinstance(result, str):
        print(result)
    elif type(result) is dict and result.get('error'):
        print(result.get('error'), file=sys.stderr)
    elif result is not None:
        print(json_encode(result))
    sys.exit(0)
Esempio n. 3
0
#!/usr/bin/env python3

import sys

from electrumsv.network import Network
from electrumsv.util import json_encode
from electrumsv.bitcoin import address_from_string

try:
    addr = sys.argv[1]
except Exception:
    print("usage: get_history <bitcoin_address>")
    sys.exit(1)

n = Network()
n.start()
sh = address_from_string(addr).to_scripthash_hex()
h = n.synchronous_get(('blockchain.scripthash.get_history', [sh]))
print(json_encode(h))
Esempio n. 4
0
def main():
    enforce_requirements()
    setup_windows_console()

    # The hook will only be used in the Qt GUI right now
    setup_thread_excepthook()

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

    # 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 Exception('Cannot get argument from stdin')
        elif arg == '?':
            sys.argv[i] = 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()

    # config is an object passed to various constructors
    config_options = args.__dict__
    config_options = {
        key: value
        for key, value in config_options.items()
        if value is not None and key not in config_variables.get(args.cmd, {})
    }

    logs.set_level(config_options['verbose'])

    if config_options.get('server'):
        config_options['auto_connect'] = False
    config_options['cwd'] = os.getcwd()

    # fixme: this can probably be achieved with a runtime hook (pyinstaller)
    portable_base_path = None
    try:
        if startup.is_bundle and os.path.exists(
                os.path.join(sys._MEIPASS, 'is_portable')):
            config_options['portable'] = True
            # Ensure the wallet data is stored in the same directory as the executable.
            portable_base_path = os.path.dirname(sys.executable)
    except AttributeError:
        config_options['portable'] = False

    if config_options.get('portable'):
        if portable_base_path is None:
            # Default to the same directory the 'electrum-sv' script is in.
            portable_base_path = os.path.dirname(os.path.realpath(sys.argv[0]))
        config_options['electrum_sv_path'] = os.path.join(
            portable_base_path, 'electrum_sv_data')

    if config_options.get('file_logging'):
        if config_options.get('portable'):
            log_path = os.path.join(config_options['electrum_sv_path'], "logs")
        else:
            log_path = os.path.join(platform.user_dir(prefer_local=True),
                                    "logs")
        os.makedirs(log_path, exist_ok=True)
        log_path = os.path.join(log_path,
                                time.strftime("%Y%m%d-%H%M%S") + ".log")
        logs.add_file_output(log_path)

    if config_options.get('testnet'):
        Net.set_to(SVTestnet)
    elif config_options.get('scalingtestnet'):
        Net.set_to(SVScalingTestnet)

    # check uri
    uri = config_options.get('url')
    if uri:
        if not web.is_URI(uri):
            print('unknown command:', uri, file=sys.stderr)
            sys.exit(1)
        config_options['url'] = uri

    # todo: defer this to gui
    config = SimpleConfig(config_options)
    cmdname = config.get('cmd')

    # Set the app state proxy
    if cmdname == 'gui':
        try:
            from electrumsv.gui.qt.app_state import QtAppStateProxy
        except ImportError as e:
            platform.missing_import(e)
        QtAppStateProxy(config, 'qt')
    elif cmdname == 'daemon' and 'daemon_app_module' in config_options:
        load_app_module(config_options['daemon_app_module'], config)
    else:
        AppStateProxy(config, 'cmdline')
        app_state.set_app(DefaultApp())

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

    if cmdname == 'gui':
        fd, server = daemon.get_fd_or_server(config)
        if fd is not None:
            run_app_with_daemon(fd, True, config_options)
        else:
            result = server.gui(config_options)

    elif cmdname == 'daemon':
        subcommand = config.get('subcommand')
        if subcommand in ['load_wallet']:
            init_daemon(config_options)

        if subcommand in [None, 'start']:
            fd, server = daemon.get_fd_or_server(config)
            if fd is not None:
                if not app_state.has_app():
                    print("No application present to run.")
                    sys.exit(0)

                if subcommand == 'start':
                    if not hasattr(os, "fork"):
                        print(
                            f"Starting the daemon is not supported on {sys.platform}."
                        )
                        sys.exit(0)
                    pid = os.fork()
                    if pid:
                        print("Starting daemon (PID %d)" % pid,
                              file=sys.stderr)
                        sys.exit(0)

                run_app_with_daemon(fd, False, config_options)
            else:
                result = server.daemon(config_options)
        else:
            server = daemon.get_server(config)
            if server is not None:
                result = server.daemon(config_options)
            else:
                print("Daemon not running")
                sys.exit(1)
    else:
        # command line
        server = daemon.get_server(config)
        init_cmdline(config_options, server)
        if server is not None:
            result = server.run_cmdline(config_options)
        else:
            cmd = known_commands[cmdname]
            if cmd.requires_network:
                print("Daemon not running; try 'electrum-sv daemon start'")
                sys.exit(1)
            else:
                result = run_offline_command(config, config_options)
                # print result
    if isinstance(result, str):
        print(result)
    elif type(result) is dict and result.get('error'):
        print(result.get('error'), file=sys.stderr)
    elif result is not None:
        print(json_encode(result))
    sys.exit(0)
Esempio n. 5
0
# A simple script that connects to a server and displays block headers

import sys
import time

from electrumsv.simple_config import SimpleConfig
from electrumsv.network import Network
from electrumsv.util import json_encode

# start network
c = SimpleConfig()
network = Network(c)
network.start()

# wait until connected
while network.is_connecting():
    time.sleep(0.1)

if not network.is_connected():
    print("daemon is not connected")
    sys.exit(1)

# 2. send the subscription
callback = lambda response: print(json_encode(response.get('result')))
network.send([('server.version', ["block_headers script", "1.2"])], callback)
network.send([('blockchain.headers.subscribe', [])], callback)

# 3. wait for results
while network.is_connected():
    time.sleep(1)