def __init__(self, name, config):
        """
        Initializes new electrum wallet instance

        @param name: Name of the wallet
        @param config: Configuration dictionary e.g {
            'server': 'localhost:7777:s',
            'rpc_user': '******',
            'rpc_pass_': 'pass',
            'electrum_path': '/opt/var/data/electrum',
            'seed': '....',
            'fee': 10000,
            'testnet': 1
        }
        """
        self._name = name
        self._config = config
        self._config['testnet'] = bool(self._config['testnet'])
        if self._config['testnet'] is True:
            constants.set_testnet()

        self._config['verbos'] = False
        self._electrum_config = SimpleConfig(self._config)
        self._wallet_path = os.path.join(self._electrum_config.path, 'wallets',
                                         self._name)
        self._storage = WalletStorage(path=self._wallet_path)
        if not self._storage.file_exists():
            self._electrum_config.set_key('default_wallet_path',
                                          self._wallet_path)
            k = keystore.from_seed(self._config['seed'],
                                   self._config['passphrase'], False)
            k.update_password(None, self._config['password'])
            self._storage.put('keystore', k.dump())
            self._storage.put('wallet_type', 'standard')
            self._storage.put('use_encryption', bool(self._config['password']))
            self._storage.write()
            self._wallet = Wallet(self._storage)
            # self._server = daemon.get_server(self._electrum_config)
            self._network = Network(self._electrum_config)
            self._network.start()
            self._wallet.start_threads(self._network)
            self._wallet.synchronize()
            self._wallet.wait_until_synchronized()
            self._wallet.stop_threads()
            self._wallet.storage.write()
        else:
            self._network = None
            self._wallet = self._wallet = Wallet(self._storage)

        self._commands = Commands(config=self._electrum_config,
                                  wallet=self._wallet,
                                  network=self._network)

        self._init_commands()
 def wrapper(self, *args, **kwargs):
     constants.set_testnet()
     try:
         return func(self, *args, **kwargs)
     finally:
         constants.set_mainnet()
示例#3
0
                           ) if config_options.get('gui') != 'kivy' else '')

    # check uri
    uri = config_options.get('url')
    if uri:
        if not uri.startswith('bitcoin:'):
            print_stderr('unknown command:', uri)
            sys.exit(1)
        config_options['url'] = uri

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

    if config.get('testnet'):
        constants.set_testnet()
    elif config.get('regtest'):
        constants.set_regtest()
    elif config.get('simnet'):
        constants.set_simnet()

    if cmdname == 'gui':
        fd, server = daemon.get_fd_or_server(config)
        if fd is not None:
            plugins = init_plugins(config, config.get('gui', 'qt'))
            d = daemon.Daemon(config, fd)
            d.init_gui(config, plugins)
            sys.exit(0)
        else:
            result = server.gui(config_options)
示例#4
0
 def setUpClass(cls):
     super().setUpClass()
     constants.set_testnet()
示例#5
0
import os

from electrum.simple_config import SimpleConfig
from electrum import constants
from electrum.daemon import Daemon
from electrum.storage import WalletStorage
from electrum.wallet import Wallet, create_new_wallet
from electrum.commands import Commands


config = SimpleConfig({"testnet": True})  # to use ~/.electrum/testnet as datadir
constants.set_testnet()  # to set testnet magic bytes
daemon = Daemon(config, listen_jsonrpc=False)
network = daemon.network
assert network.asyncio_loop.is_running()

# get wallet on disk
wallet_dir = os.path.dirname(config.get_wallet_path())
wallet_path = os.path.join(wallet_dir, "test_wallet")
if not os.path.exists(wallet_path):
    create_new_wallet(path=wallet_path, segwit=True)

# open wallet
storage = WalletStorage(wallet_path)
wallet = Wallet(storage)
wallet.start_network(network)

# you can use ~CLI commands by accessing command_runner
command_runner = Commands(config, wallet=None, network=network)
command_runner.wallet = wallet
print("balance", command_runner.getbalance())
示例#6
0
#!/usr/bin/env python3
# [rights]  Copyright 2020 brianddk at github https://github.com/brianddk
# [license] Apache 2.0 License https://www.apache.org/licenses/LICENSE-2.0
# [repo]    github.com/brianddk/reddit/blob/master/python/elec-get-addr.py
# [btc]     BTC-b32: bc1qwc2203uym96u0nmq04pcgqfs9ldqz9l3mz8fpj
# [tipjar]  github.com/brianddk/reddit/blob/master/tipjar/tipjar.txt
# [ref]     reddit.com/r/Electrum/comments/jn2m0q/-/gaz1dbm/
# [req]     python -m pip install electrum
# [note]    with open(r"..\reddit\python\script.py", 'r') as s: exec(s.read())

from electrum.constants import set_testnet
from electrum.bip32 import BIP32Node
from electrum.bitcoin import pubkey_to_address

# Set testnet
set_testnet()

# You get this from Wallet info dialog
xpub = 'vpub5SLqN2bLY4WeYkHyoQNaC4JuFVxDVWtx7YUjuxRwWTkLocCBy3ejp3X3Uxmefk1ae4ZCpTVYkJPUG2pAgv8K9mdxfgcGDwWRzq7YTWCCmAq'
path = 'm/0/0'
xpub = BIP32Node.from_xkey(xpub)

for i in range(0, 20):
    path = f"{path[:3]}/{i}"
    node = xpub.subkey_at_public_derivation(path)
    pubk = node.eckey.get_public_key_bytes()
    addr = pubkey_to_address('p2wpkh', pubk.hex())
    print(f"Address at path [{path}]: {addr}")
示例#7
0
def main():

    seed = globals().get('seed', None)
    if 'wallet' not in globals():
        # Not in electrum console, free to toggle network
        constants.set_testnet()
        if len(argv) > 1:
            seed = argv[1]

    if (constants.net.TESTNET):

        bip = {}
        (mnemo, tprv, gwif) = [None] * 3

        if seed:
            (tmp, seed) = (seed, None)
            if '0x' == tmp[:2].lower():
                tmp = tmp[2:]
            if set(tmp).issubset(hexdigits) and 64 == len(tmp):
                seed = bytes.fromhex(tmp)
                gwif = to_wif(seed, True, 'p2pkh').split(':')[
                    -1]  # to_wif(seed,True,'').split(':')[-1]
            elif 'tprv' == tmp[:4]:
                tprv = tmp
            elif 12 == len(tmp.split()):
                mnemo = tmp
            else:
                gwif = tmp
                _, seed, _ = from_wif(tmp)

        bip39 = BIP39("English")
        if not (seed or mnemo or gwif or tprv):
            mnemo = bip39.generate()
        if mnemo:
            seed = bip39.to_seed(mnemo)
        if tprv:
            bip32 = BIP32Node.from_xkey(tprv)
        if seed:
            bip32 = BIP32Node.from_rootseed(seed, xtype='standard')
            tprv = bip32.to_xprv()

        desc = {
            '44': ['pkh'],
            '49': ['wpkh', 'sh'],
            '84': ['wpkh'],
            '86': ['tr']
        }
        conf = {
            '44': 'legacy',
            '49': 'p2sh-segwit',
            '84': 'bech32',
            '86': 'bech32m'
        }
        for k in desc.keys():
            imp = {'timestamp': 'now', 'range': [0, 1000], 'next_index': 1}
            imp = [dict(imp), dict(imp)]
            acct = f"{k}'/1'/0'"
            if gwif:
                key = seed
                wif = gwif
            else:
                key = bip32.subkey_at_private_derivation(
                    f"m/{acct}/0/0").eckey.get_secret_bytes()
                wif = to_wif(key, True, 'p2pkh').split(':')[-1]
            bip[k] = {}
            bip[k]['key'] = key.hex()
            bip[k]['wif'] = wif
            change = 0
            for j in ['addr', 'change']:
                path = f"{acct}/{change}"
                desc_str = f"{tprv}/{path}/*"
                for i in desc[k]:
                    desc_str = f"{i}({desc_str})"
                desc_str = descsum_create(desc_str)
                imp[change]['desc'] = desc_str
                imp[change]['internal'] = bool(change)
                imp[change]['active'] = not bool(change)
                bip[k][j] = {}
                bip[k][j]['derivation'] = path
                bip[k][j]['desc'] = desc_str
                bip[k][j]['import'] = 'importdescriptors ' + dumps(
                    imp[change]).replace('"', r'\"')
                change += 1
            imp_txt = dumps(imp).replace('"', r'\"')
            if '86' == k:
                cmd = ''
            else:
                cmd = f'createwallet "bip{k}-berkley" false true\n'
                cmd += f'sethdseed true "{wif}"\n'
            cmd += f'createwallet "bip{k}-sqlite"  false true "" false true\n'
            cmd += f'importdescriptors "{imp_txt}"'
            bip[k]['import'] = imp_txt
            bip[k]['commands'] = cmd

        print(f'\n# Your BIP39 Mnemonic:    "{mnemo}"')
        print(f'# Your BIP32 Root Key:    "{tprv}"')
        print(
            f'\n# Your legacy hdseed      wif:"{bip["44"]["wif"]}", priv:"{bip["44"]["key"]}"'
        )
        print(
            f'# Your p2sh-segwit hdseed wif:"{bip["49"]["wif"]}", priv:"{bip["49"]["key"]}"'
        )
        print(
            f'# Your bech32 hdseed      wif:"{bip["84"]["wif"]}", priv:"{bip["84"]["key"]}"\n'
        )

        for k in desc.keys():
            print(f'##################################################')
            print(
                f'# Your BIP{k} config is:\ntest.addresstype={conf[k]}\ntest.changetype={conf[k]}\n'
            )
            print(f'# Your BIP{k} commands are:\n{bip[k]["commands"]}\n')

    else:
        print("You are not on Testnet, Exiting for safety")
示例#8
0
 def setUpClass(cls):
     super().setUpClass()
     constants.set_testnet()
示例#9
0
def launch():
    # The hook will only be used in the Qt GUI right now
    util.setup_thread_excepthook()
    # on osx, delete Process Serial Number arg generated for apps launched in Finder
    sys.argv = list(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] = 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)
    if is_android:
        config_options = {
            'verbose': True,
            'cmd': 'gui',
            'gui': 'kivy',
        }
    else:
        config_options = args.__dict__
        f = lambda key: config_options[key] is not None and key not in config_variables.get(args.cmd, {}).keys()
        config_options = {key: config_options[key] for key in filter(f, config_options.keys())}
        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)
    if is_bundle and os.path.exists(os.path.join(sys._MEIPASS, 'is_portable')):
        config_options['portable'] = True

#if config_options.get('portable'):
    config_options['electrum_path'] = os.path.join(managers.shared().documentsDirectory(), 'electrum_data')

    # kivy sometimes freezes when we write to sys.stderr
    set_verbosity(config_options.get('verbose') and config_options.get('gui')!='kivy')

    # check uri
    '''
    uri = config_options.get('url')
    if uri:
        if not uri.startswith('bitcoin:'):
            print_stderr('unknown command:', uri)
            sys.exit(1)
        config_options['url'] = uri
    '''
    
    # todo: defer this to gui
    config = SimpleConfig(config_options)
    cmdname = config.get('cmd')

    if config.get('testnet'):
        constants.set_testnet()

    # 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:
            plugins = init_plugins(config, config.get('gui', 'qt'))
            d = daemon.Daemon(config, fd, True)
            d.start()
            d.init_gui(config, plugins)
            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_stderr("starting daemon (PID %d)" % pid)
                        sys.exit(0)
                init_plugins(config, 'cmdline')
                d = daemon.Daemon(config, fd, False)
                d.start()
                if config.get('websocket_server'):
                    from electrum import websockets
                    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_msg("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_msg("Daemon not running; try 'electrum daemon start'")
                sys.exit(1)
            else:
                plugins = init_plugins(config, 'cmdline')
                result = run_offline_command(config, config_options, plugins)
                # print result
    if isinstance(result, str):
        print_msg(result)
    elif type(result) is dict and result.get('error'):
        print_stderr(result.get('error'))
    elif result is not None:
        print_msg(json_encode(result))
    sys.exit(0)