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()
) 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)
def setUpClass(cls): super().setUpClass() constants.set_testnet()
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())
#!/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}")
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")
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)