def __init__(self, config=None, loop=False): self.server = random.choice(filter_protocol(DEFAULT_SERVERS, 's')) self.proxy = None if config is None: from simple_config import SimpleConfig config = SimpleConfig() threading.Thread.__init__(self) self.daemon = True self.loop = loop self.config = config self.connect_event = threading.Event() self.subscriptions = {} self.responses = {} self.responses['default'] = Queue.Queue() self.callbacks = {} self.lock = threading.Lock() self.servers = {} # actual list from IRC self.rtime = 0 self.bytes_received = 0 self.is_connected = False
def __init__(self, config=None): if config is None: config = {} # Do not use mutables as default values! util.DaemonThread.__init__(self) self.config = SimpleConfig(config) if type(config) == type({}) else config self.num_server = 8 if not self.config.get('oneserver') else 0 self.blockchain = Blockchain(self.config, self) # A deque of interface header requests, processed left-to-right self.bc_requests = deque() # Server for addresses and transactions self.default_server = self.config.get('server') # Sanitize default server try: deserialize_server(self.default_server) except: self.default_server = None if not self.default_server: self.default_server = pick_random_server() self.lock = Lock() self.pending_sends = [] self.message_id = 0 self.debug = False self.irc_servers = {} # returned by interface (list from irc) self.recent_servers = self.read_recent_servers() self.banner = '' self.donation_address = '' self.fee = None self.relay_fee = None self.heights = {} self.merkle_roots = {} self.utxo_roots = {} # callbacks passed with subscriptions self.subscriptions = defaultdict(list) self.sub_cache = {} # callbacks set by the GUI self.callbacks = defaultdict(list) dir_path = os.path.join( self.config.path, 'certs') if not os.path.exists(dir_path): os.mkdir(dir_path) # subscriptions and requests self.subscribed_addresses = set() # Requests from client we've not seen a response to self.unanswered_requests = {} # retry times self.server_retry_time = time.time() self.nodes_retry_time = time.time() # kick off the network. interface is the main server we are currently # communicating with. interfaces is the set of servers we are connecting # to or have an ongoing connection with self.interface = None self.interfaces = {} self.auto_connect = self.config.get('auto_connect', False) self.connecting = set() self.socket_queue = Queue.Queue() self.start_network(deserialize_server(self.default_server)[2], deserialize_proxy(self.config.get('proxy')))
def __init__(self, socket, config=None): if config is None: config = {} # Do not use mutables as default arguments! threading.Thread.__init__(self) self.config = SimpleConfig(config) if type(config) == type({}) else config self.message_id = 0 self.unanswered_requests = {} self.subscriptions = {} self.debug = False self.lock = threading.Lock() self.pending_transactions_for_notifications = [] self.callbacks = {} self.running = True self.daemon = True if socket: self.pipe = util.SocketPipe(socket) self.network = None else: self.network = Network(config) self.pipe = util.QueuePipe(send_queue=self.network.requests_queue) self.network.start(self.pipe.get_queue) for key in ['status', 'banner', 'updated', 'servers', 'interfaces']: value = self.network.get_status_value(key) self.pipe.get_queue.put({'method': 'network.status', 'params': [key, value]}) # status variables self.status = 'connecting' self.servers = {} self.banner = '' self.blockchain_height = 0 self.server_height = 0 self.interfaces = []
def __init__(self, server, config=None): threading.Thread.__init__(self) self.daemon = True self.config = config if config is not None else SimpleConfig() self.lock = threading.Lock() self.is_connected = False self.debug = False # dump network messages. can be changed at runtime using the console self.message_id = 0 self.unanswered_requests = {} # are we waiting for a pong? self.is_ping = False # parse server self.server = server self.host, self.port, self.protocol = self.server.split(':') self.port = int(self.port) self.use_ssl = (self.protocol == 's') self.proxy = self.parse_proxy_options(self.config.get('proxy')) if self.proxy: self.proxy_mode = proxy_modes.index(self.proxy["mode"]) + 1 socks.setdefaultproxy(self.proxy_mode, self.proxy["host"], int(self.proxy["port"])) socket.socket = socks.socksocket # prevent dns leaks, see http://stackoverflow.com/questions/13184205/dns-over-proxy def getaddrinfo(*args): return [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (args[0], args[1]))] socket.getaddrinfo = getaddrinfo
def run_cmdline(self, config_options): password = config_options.get('password') new_password = config_options.get('new_password') config = SimpleConfig(config_options) config.fee_estimates = self.network.config.fee_estimates.copy() cmdname = config.get('cmd') cmd = known_commands[cmdname] if cmd.requires_wallet: path = config.get_wallet_path() wallet = self.wallets.get(path) if wallet is None: return { 'error': 'Wallet not open. Use "electrum-vtc daemon load_wallet"' } else: wallet = None # arguments passed to function args = map(lambda x: config.get(x), cmd.params) # decode json arguments args = map(json_decode, args) # options args += map( lambda x: (config_options.get(x) if x in ['password', 'new_password'] else config.get(x)), cmd.options) cmd_runner = Commands(config, wallet, self.network) func = getattr(cmd_runner, cmd.name) result = func(*args) return result
def __init__(self, socket, config=None): if config is None: config = {} # Do not use mutables as default arguments! util.DaemonThread.__init__(self) self.config = SimpleConfig(config) if type(config) == type({}) else config self.message_id = 0 self.unanswered_requests = {} self.subscriptions = {} self.debug = False self.lock = threading.Lock() self.callbacks = {} if socket: self.pipe = util.SocketPipe(socket) self.network = None else: self.pipe = util.QueuePipe() self.network = Network(self.pipe, config) self.network.start() for key in ['fee','status','banner','updated','servers','interfaces']: value = self.network.get_status_value(key) self.pipe.get_queue.put({'method':'network.status', 'params':[key, value]}) # status variables self.status = 'unknown' self.servers = {} self.banner = '' self.blockchain_height = 0 self.server_height = 0 self.interfaces = [] # value returned by estimatefee self.fee = None
def check_certificates(): config = SimpleConfig() mydir = os.path.join(config.path, "certs") certs = os.listdir(mydir) for c in certs: print c p = os.path.join(mydir, c) with open(p) as f: cert = f.read() check_cert(c, cert)
def __init__(self, pipe, config=None): if config is None: config = {} # Do not use mutables as default values! util.DaemonThread.__init__(self) self.config = SimpleConfig(config) if type(config) == type( {}) else config self.num_server = 8 if not self.config.get('oneserver') else 0 self.blockchain = Blockchain(self.config, self) self.queue = Queue.Queue() self.requests_queue = pipe.send_queue self.response_queue = pipe.get_queue # A deque of interface header requests, processed left-to-right self.bc_requests = deque() # Server for addresses and transactions self.default_server = self.config.get('server') # Sanitize default server try: deserialize_server(self.default_server) except: self.default_server = None if not self.default_server: self.default_server = pick_random_server() self.irc_servers = {} # returned by interface (list from irc) self.recent_servers = self.read_recent_servers() self.banner = '' self.fee = None self.heights = {} self.merkle_roots = {} self.utxo_roots = {} dir_path = os.path.join(self.config.path, 'certs') if not os.path.exists(dir_path): os.mkdir(dir_path) # subscriptions and requests self.subscribed_addresses = set() # cached address status self.addr_responses = {} # unanswered requests self.unanswered_requests = {} # retry times self.server_retry_time = time.time() self.nodes_retry_time = time.time() # kick off the network. interface is the main server we are currently # communicating with. interfaces is the set of servers we are connecting # to or have an ongoing connection with self.interface = None self.interfaces = {} self.auto_connect = self.config.get('auto_connect', True) self.start_network( deserialize_server(self.default_server)[2], deserialize_proxy(self.config.get('proxy')))
def __init__(self, config=None): if config is None: config = {} # Do not use mutables as default values! threading.Thread.__init__(self) self.daemon = True self.config = SimpleConfig(config) if type(config) == type( {}) else config self.lock = threading.Lock() self.num_server = 8 if not self.config.get('oneserver') else 0 self.blockchain = Blockchain(self.config, self) self.interfaces = {} self.queue = Queue.Queue() self.protocol = self.config.get('protocol', 's') # sanitize protocol if self.protocol not in 'sght': self.protocol = 's' self.running = False # Server for addresses and transactions self.default_server = self.config.get('server') # Sanitize default server try: host, port, protocol = self.default_server.split(':') assert protocol == self.protocol int(port) except: self.default_server = None if not self.default_server: self.default_server = pick_random_server(self.protocol) self.irc_servers = {} # returned by interface (list from irc) self.disconnected_servers = set([]) self.disconnected_time = time.time() self.recent_servers = self.config.get('recent_servers', []) # successful connections self.pending_servers = set() self.banner = '' self.interface = None self.proxy = self.config.get('proxy') self.heights = {} self.merkle_roots = {} self.utxo_roots = {} dir_path = os.path.join(self.config.path, 'certs') if not os.path.exists(dir_path): os.mkdir(dir_path) # address subscriptions and cached results self.addresses = {} self.connection_status = 'connecting' self.requests_queue = Queue.Queue()
def __init__(self, config = {}): threading.Thread.__init__(self) self.daemon = True self.config = SimpleConfig(config) if type(config) == type({}) else config self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.daemon_port = config.get('daemon_port', 8000) self.message_id = 0 self.unanswered_requests = {} self.subscriptions = {} self.debug = False self.lock = threading.Lock()
def run_gui(self, config_options): config = SimpleConfig(config_options) if self.gui: if hasattr(self.gui, 'new_window'): path = config.get_wallet_path() self.gui.new_window(path, config.get('url')) response = "ok" else: response = "error: current GUI does not support multiple windows" else: response = "Error: Electrum is running in daemon mode. Please stop the daemon first." return response
def __init__(self, config=None): if config is None: config = {} # Do not use mutables as default values! util.DaemonThread.__init__(self) self.config = SimpleConfig(config) if type(config) == type( {}) else config self.lock = threading.Lock() self.num_server = 8 if not self.config.get('oneserver') else 0 self.blockchain = Blockchain(self.config, self) self.interfaces = {} self.queue = Queue.Queue() # Server for addresses and transactions self.default_server = self.config.get('server') # Sanitize default server try: deserialize_server(self.default_server) except: self.default_server = None if not self.default_server: self.default_server = pick_random_server('s') self.protocol = deserialize_server(self.default_server)[2] self.irc_servers = {} # returned by interface (list from irc) self.disconnected_servers = set([]) self.recent_servers = self.read_recent_servers() self.pending_servers = set() self.banner = '' self.interface = None self.heights = {} self.merkle_roots = {} self.utxo_roots = {} dir_path = os.path.join(self.config.path, 'certs') if not os.path.exists(dir_path): os.mkdir(dir_path) # address subscriptions self.addresses = set() # cached results self.addr_responses = {} self.connection_status = 'connecting' self.requests_queue = Queue.Queue() self.set_proxy(deserialize_proxy(self.config.get('proxy'))) # retry times self.server_retry_time = time.time() self.nodes_retry_time = time.time()
def __init__(self, server, config = None): threading.Thread.__init__(self) self.daemon = True self.config = config if config is not None else SimpleConfig() self.lock = threading.Lock() self.is_connected = False self.debug = False # dump network messages. can be changed at runtime using the console self.message_id = 0 self.unanswered_requests = {} # are we waiting for a pong? self.is_ping = False # parse server self.server = server self.host, self.port, self.protocol = self.server.split(':') self.port = int(self.port) self.use_ssl = (self.protocol == 's')
def __init__(self, config=None): if config is None: config = {} # Do not use mutables as default arguments! threading.Thread.__init__(self) self.daemon = True self.config = SimpleConfig(config) if type(config) == type( {}) else config self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.daemon_port = config.get('daemon_port', DAEMON_PORT) self.message_id = 0 self.unanswered_requests = {} self.subscriptions = {} self.debug = False self.lock = threading.Lock() self.pending_transactions_for_notifications = []
def run_cmdline(self, config_options): password = config_options.get('password') config = SimpleConfig(config_options) cmdname = config.get('cmd') cmd = known_commands[cmdname] wallet = self.load_wallet(config) if cmd.requires_wallet else None # arguments passed to function args = map(lambda x: config.get(x), cmd.params) # decode json arguments args = map(json_decode, args) # options args += map(lambda x: config.get(x), cmd.options) cmd_runner = Commands(config, wallet, self.network) cmd_runner.password = password func = getattr(cmd_runner, cmd.name) result = func(*args) return result
def __init__(self, config=None): if config is None: config = {} # Do not use mutables as default values! threading.Thread.__init__(self) self.daemon = True self.config = SimpleConfig(config) if type(config) == type( {}) else config self.lock = threading.Lock() self.num_server = 8 if not self.config.get('oneserver') else 0 self.blockchain = Blockchain(self.config, self) self.interfaces = {} self.queue = Queue.Queue() self.callbacks = {} self.protocol = self.config.get('protocol', 's') self.running = False # Server for addresses and transactions self.default_server = self.config.get('server') if not self.default_server: self.default_server = pick_random_server(self.protocol) self.irc_servers = [] # returned by interface (list from irc) self.pending_servers = set([]) self.disconnected_servers = set([]) self.recent_servers = self.config.get('recent_servers', []) # successful connections self.banner = '' self.interface = None self.proxy = self.config.get('proxy') self.heights = {} self.merkle_roots = {} self.utxo_roots = {} self.server_lag = 0 dir_path = os.path.join(self.config.path, 'certs') if not os.path.exists(dir_path): os.mkdir(dir_path) # default subscriptions self.subscriptions = {} self.subscriptions[self.on_banner] = [('server.banner', [])] self.subscriptions[self.on_peers] = [('server.peers.subscribe', [])] self.pending_transactions_for_notifications = []
def run_daemon(self, config_options): config = SimpleConfig(config_options) sub = config.get('subcommand') assert sub in [ None, 'start', 'stop', 'status', 'load_wallet', 'close_wallet' ] if sub in [None, 'start']: response = "Daemon already running" elif sub == 'load_wallet': path = config.get_wallet_path() wallet = self.load_wallet(path, config.get('password')) self.cmd_runner.wallet = wallet response = True elif sub == 'close_wallet': path = config.get_wallet_path() if path in self.wallets: self.stop_wallet(path) response = True else: response = False elif sub == 'status': if self.network: p = self.network.get_parameters() response = { 'path': self.network.config.path, 'server': p[0], 'blockchain_height': self.network.get_local_height(), 'server_height': self.network.get_server_height(), 'spv_nodes': len(self.network.get_interfaces()), 'connected': self.network.is_connected(), 'auto_connect': p[4], 'version': ELECTRUM_VERSION, 'wallets': {k: w.is_up_to_date() for k, w in self.wallets.items()}, 'fee_per_kb': self.config.fee_per_kb(), } else: response = "Daemon offline" elif sub == 'stop': self.stop() response = "Daemon stopped" return response
def __init__(self, server, config=None): threading.Thread.__init__(self) self.daemon = True self.config = config if config is not None else SimpleConfig() self.connect_event = threading.Event() self.subscriptions = {} self.lock = threading.Lock() self.rtime = 0 self.bytes_received = 0 self.is_connected = False self.poll_interval = 1 self.debug = False # dump network messages. can be changed at runtime using the console #json self.message_id = 0 self.unanswered_requests = {} self.pending_transactions_for_notifications = [] # parse server self.server = server try: host, port, protocol = self.server.split(':') port = int(port) except Exception: self.server = None return if protocol not in 'ghst': raise Exception('Unknown protocol: %s' % protocol) self.host = host self.port = port self.protocol = protocol self.use_ssl = (protocol in 'sg') self.proxy = self.parse_proxy_options(self.config.get('proxy')) if self.proxy: self.proxy_mode = proxy_modes.index(self.proxy["mode"]) + 1
def server_selected(self, server_name): match = [ transports for (host, transports) in self.servers_list if host == server_name ] assert len(match) == 1 match = match[0] # Default to TCP if available else use anything # TODO: protocol should be selectable. tcp_port = [port for (protocol, port) in match if protocol == "t"] if len(tcp_port) == 0: protocol = match[0][0] port = match[0][1] else: protocol = "t" port = tcp_port[0] server_line = "%s:%s:%s" % (server_name, port, protocol) # Should this have exception handling? self.cfg = SimpleConfig() self.wallet.set_server(server_line, self.cfg.config["proxy"])
def __init__(self, server, response_queue, config=None): threading.Thread.__init__(self) self.daemon = True self.config = config if config is not None else SimpleConfig() # Set by stop(); no more data is exchanged and the thread exits after gracefully # closing the socket self.disconnect = False self._status = CS_OPENING self.debug = False # dump network messages. can be changed at runtime using the console self.message_id = 0 self.response_queue = response_queue self.request_queue = Queue.Queue() self.unanswered_requests = {} # request timeouts self.request_time = time.time() self.ping_time = 0 # parse server self.server = server self.host, self.port, self.protocol = self.server.split(':') self.port = int(self.port) self.use_ssl = (self.protocol == 's')
def test_parse_empyt_string(): sc = SimpleConfig() assert sc.params == {}
def __init__(self, config=None): if config is None: config = {} # Do not use mutables as default values! util.DaemonThread.__init__(self) self.config = SimpleConfig(config) if type(config) == type({}) else config self.num_server = 10 if not self.config.get('oneserver') else 0 self.blockchains = blockchain.read_blockchains(self.config) self.print_error("blockchains", self.blockchains.keys()) self.blockchain_index = config.get('blockchain_index', 0) if self.blockchain_index not in self.blockchains.keys(): self.blockchain_index = 0 # Server for addresses and transactions self.default_server = self.config.get('server') # Sanitize default server try: deserialize_server(self.default_server) except: self.default_server = None if not self.default_server: self.default_server = pick_random_server() self.lock = threading.Lock() self.pending_sends = [] self.message_id = 0 self.debug = False self.irc_servers = {} # returned by interface (list from irc) self.recent_servers = self.read_recent_servers() self.banner = '' self.donation_address = '' self.relay_fee = None # List of all proposals on the network. self.all_proposals = [] # callbacks passed with subscriptions self.subscriptions = defaultdict(list) self.sub_cache = {} # callbacks set by the GUI self.callbacks = defaultdict(list) dir_path = os.path.join( self.config.path, 'certs') if not os.path.exists(dir_path): os.mkdir(dir_path) # Servers that have invalid versions. self.invalid_version_servers = set() # subscriptions and requests self.subscribed_addresses = set() # Requests from client we've not seen a response to self.unanswered_requests = {} # retry times self.server_retry_time = time.time() self.nodes_retry_time = time.time() # kick off the network. interface is the main server we are currently # communicating with. interfaces is the set of servers we are connecting # to or have an ongoing connection with self.interface = None self.interfaces = {} self.auto_connect = self.config.get('auto_connect', True) self.connecting = set() self.socket_queue = Queue.Queue() self.start_network(deserialize_server(self.default_server)[2], deserialize_proxy(self.config.get('proxy')))
def __init__(self, actuator, expand_callback): super(MiniWindow, self).__init__() self.actuator = actuator self.btc_balance = None self.quote_currencies = ["EUR", "USD", "GBP"] self.actuator.set_configured_currency(self.set_quote_currency) self.exchanger = exchange_rate.Exchanger(self) # Needed because price discovery is done in a different thread # which needs to be sent back to this main one to update the GUI self.connect(self, SIGNAL("refresh_balance()"), self.refresh_balance) self.balance_label = BalanceLabel(self.change_quote_currency) self.balance_label.setObjectName("balance_label") self.receive_button = QPushButton(_("&Receive")) self.receive_button.setObjectName("receive_button") self.receive_button.setDefault(True) self.receive_button.clicked.connect(self.copy_address) # Bitcoin address code self.address_input = QLineEdit() self.address_input.setPlaceholderText(_("Enter a Bitcoin address...")) self.address_input.setObjectName("address_input") self.address_input.textEdited.connect(self.address_field_changed) resize_line_edit_width(self.address_input, "1BtaFUr3qVvAmwrsuDuu5zk6e4s2rxd2Gy") self.address_completions = QStringListModel() address_completer = QCompleter(self.address_input) address_completer.setCaseSensitivity(False) address_completer.setModel(self.address_completions) self.address_input.setCompleter(address_completer) address_layout = QHBoxLayout() address_layout.addWidget(self.address_input) self.amount_input = QLineEdit() self.amount_input.setPlaceholderText(_("... and amount")) self.amount_input.setObjectName("amount_input") # This is changed according to the user's displayed balance self.amount_validator = QDoubleValidator(self.amount_input) self.amount_validator.setNotation(QDoubleValidator.StandardNotation) self.amount_validator.setDecimals(8) self.amount_input.setValidator(self.amount_validator) # This removes the very ugly OSX highlighting, please leave this in :D self.address_input.setAttribute(Qt.WA_MacShowFocusRect, 0) self.amount_input.setAttribute(Qt.WA_MacShowFocusRect, 0) self.amount_input.textChanged.connect(self.amount_input_changed) self.send_button = QPushButton(_("&Send")) self.send_button.setObjectName("send_button") self.send_button.setDisabled(True) self.send_button.clicked.connect(self.send) main_layout = QGridLayout(self) main_layout.addWidget(self.balance_label, 0, 0) main_layout.addWidget(self.receive_button, 0, 1) main_layout.addWidget(self.address_input, 1, 0, 1, -1) main_layout.addWidget(self.amount_input, 2, 0) main_layout.addWidget(self.send_button, 2, 1) self.history_list = history_widget.HistoryWidget() self.history_list.setObjectName("history") self.history_list.hide() self.history_list.setAlternatingRowColors(True) main_layout.addWidget(self.history_list, 3, 0, 1, -1) menubar = QMenuBar() electrum_menu = menubar.addMenu(_("&Bitcoin")) servers_menu = electrum_menu.addMenu(_("&Servers")) servers_group = QActionGroup(self) self.actuator.set_servers_gui_stuff(servers_menu, servers_group) self.actuator.populate_servers_menu() electrum_menu.addSeparator() brain_seed = electrum_menu.addAction(_("&BrainWallet Info")) brain_seed.triggered.connect(self.actuator.show_seed_dialog) quit_option = electrum_menu.addAction(_("&Quit")) quit_option.triggered.connect(self.close) view_menu = menubar.addMenu(_("&View")) expert_gui = view_menu.addAction(_("&Pro Mode")) expert_gui.triggered.connect(expand_callback) themes_menu = view_menu.addMenu(_("&Themes")) selected_theme = self.actuator.selected_theme() theme_group = QActionGroup(self) for theme_name in self.actuator.theme_names(): theme_action = themes_menu.addAction(theme_name) theme_action.setCheckable(True) if selected_theme == theme_name: theme_action.setChecked(True) class SelectThemeFunctor: def __init__(self, theme_name, toggle_theme): self.theme_name = theme_name self.toggle_theme = toggle_theme def __call__(self, checked): if checked: self.toggle_theme(self.theme_name) delegate = SelectThemeFunctor(theme_name, self.toggle_theme) theme_action.toggled.connect(delegate) theme_group.addAction(theme_action) view_menu.addSeparator() show_history = view_menu.addAction(_("Show History")) show_history.setCheckable(True) show_history.toggled.connect(self.show_history) help_menu = menubar.addMenu(_("&Help")) the_website = help_menu.addAction(_("&Website")) the_website.triggered.connect(self.the_website) help_menu.addSeparator() report_bug = help_menu.addAction(_("&Report Bug")) report_bug.triggered.connect(self.show_report_bug) show_about = help_menu.addAction(_("&About")) show_about.triggered.connect(self.show_about) main_layout.setMenuBar(menubar) quit_shortcut = QShortcut(QKeySequence("Ctrl+Q"), self) quit_shortcut.activated.connect(self.close) close_shortcut = QShortcut(QKeySequence("Ctrl+W"), self) close_shortcut.activated.connect(self.close) self.cfg = SimpleConfig() g = self.cfg.config["winpos-lite"] self.setGeometry(g[0], g[1], g[2], g[3]) show_history.setChecked(self.cfg.config["history"]) self.show_history(self.cfg.config["history"]) self.setWindowIcon(QIcon(":electrum.png")) self.setWindowTitle("Electrum") self.setWindowFlags(Qt.Window | Qt.MSWindowsFixedSizeDialogHint) self.layout().setSizeConstraint(QLayout.SetFixedSize) self.setObjectName("main_window") self.show()
print "PaymentACK message received: %s" % paymntack.memo return True, paymntack.memo if __name__ == "__main__": try: uri = sys.argv[1] except: print "usage: %s url" % sys.argv[0] print "example url: \"novacoin:4LJgtjeXMjLA6nVzYMJh1LEkwxMFsRtnP4?amount=0.0018&r=https%3A%2F%2Fsite.com%2F\"" sys.exit(1) address, amount, label, message, request_url = util.parse_URI(uri) from simple_config import SimpleConfig config = SimpleConfig() pr = PaymentRequest(config) pr.read(request_url) if not pr.verify(): print 'verify failed' print pr.error sys.exit(1) print 'Payment Request Verified Domain: ', pr.domain print 'outputs', pr.outputs print 'Payment Memo: ', pr.details.memo tx = "blah" pr.send_ack(tx, refund_addr="1vXAXUnGitimzinpXrqDWVU4tyAAQ34RA")