def test_get_set_stored_gas_price(self): """ Checks default stored gas price and set method. """ # checks default assert Settings.get_stored_gas_price() == 4 # checks set Settings.set_stored_gas_price(42) assert Settings.get_stored_gas_price() == 42
def test_get_set_is_persistent_keystore(self): """ Checks default persist value and set method. """ # checks default assert Settings.is_persistent_keystore() is False # checks set Settings.set_is_persistent_keystore(True) assert Settings.is_persistent_keystore() is True
def test_get_set_stored_network(self): """ Checks default stored network and set method. """ # checks default assert Settings.get_stored_network() == ChainID.MAINNET # checks set Settings.set_stored_network(ChainID.ROPSTEN) assert Settings.get_stored_network() == ChainID.ROPSTEN
def sync_keystore_to_non_persistent(cls): """ Copies keystore from persistent to non persistent storage. """ # TODO: handle dir doesn't exist source_dir = os.path.join(Settings.get_persistent_keystore_path(), KEYSTORE_DIR_SUFFIX) destination_dir = os.path.join( Settings.get_non_persistent_keystore_path(), KEYSTORE_DIR_SUFFIX) cls.sync_to_directory(source_dir, destination_dir)
def load_settings(self): """ Load json store settings to UI properties. """ self.is_stored_mainnet = Settings.is_stored_mainnet() self.is_stored_testnet = Settings.is_stored_testnet() self.stored_gas_price = Settings.get_stored_gas_price() is_persistent_keystore = (Settings.is_persistent_keystore() and check_write_permission()) self.set_persist_keystore_switch_state(is_persistent_keystore)
def store_is_persistent_keystore(self): """ Saves the persistency option to the store. Note that to save `True` we also check if we have write permissions. """ persist_keystore = self.is_ui_persistent_keystore() persist_keystore = persist_keystore and check_write_permission() persistency_toggled = (Settings.is_persistent_keystore() != persist_keystore) if persistency_toggled: self.sync_keystore(persist_keystore) Settings.set_is_persistent_keystore(persist_keystore)
def on_permissions_callback(permissions, grant_results): """ On write permission callback, toggles loading account from persistent keystore if granted. Also loads the current account to the app. This is called from the Java thread, hence the `@mainthread`. Find out more on the p4a permissions callback in: https://github.com/kivy/python-for-android/pull/1818 """ if all(grant_results): Settings.set_is_persistent_keystore(True) self.try_load_current_account()
def test_get_android_keystore_prefix(self): """ The keystore prefix should be the same as user_data_dir by default. But it can also be persisted to the sdcard. """ assert Settings.is_persistent_keystore() is False prefix = Settings._get_android_keystore_prefix() assert prefix == self.app.user_data_dir with mock.patch.object(Settings, 'is_persistent_keystore', return_value=True): prefix = Settings._get_android_keystore_prefix() assert prefix == '/sdcard/pywallet'
def pywalib(self): """ Gets or creates the PyWalib object. Also recreates the object if the keystore_path changed. """ keystore_path = Settings.get_keystore_path() chain_id = Settings.get_stored_network() if self._pywalib is None or \ self._pywalib.keystore_dir != keystore_path or \ self._pywalib.chain_id != chain_id: self._pywalib = PyWalib( keystore_dir=keystore_path, chain_id=chain_id) return self._pywalib
def fetch_balance(self): """ Fetches the new balance & sets accounts_balance property. """ if self.current_account is None: return address = '0x' + self.current_account.address.hex() chain_id = Settings.get_stored_network() try: balance = PyWalib.get_balance(address, chain_id) except ConnectionError: Dialog.on_balance_connection_error() Logger.warning('ConnectionError', exc_info=True) return except ValueError: # most likely the JSON object could not be decoded, refs #91 # currently logged as an error, because we want more insight # in order to eventually handle it more specifically Dialog.on_balance_value_error() Logger.error('ValueError', exc_info=True) return except UnknownEtherscanException: # also handles uknown errors, refs #112 Dialog.on_balance_unknown_error() Logger.error('UnknownEtherscanException', exc_info=True) return # triggers accounts_balance observers update self.accounts_balance[address] = balance
def setup(self): self.controller = App.get_running_app().controller self.keystore_path = Settings.get_keystore_path() accounts = self.controller.pywalib.get_account_list() if len(accounts) == 0: title = "No keystore found." body = "Import or create one." dialog = Dialog.create_dialog(title, body) dialog.open()
def fetch_history(self): if self.current_account is None: return chain_id = Settings.get_stored_network() address = '0x' + self.current_account.address.hex() try: transactions = PyWalib.get_transaction_history(address, chain_id) except ConnectionError: Dialog.on_history_connection_error() Logger.warning('ConnectionError', exc_info=True) return except NoTransactionFoundException: transactions = [] except ValueError: # most likely the JSON object could not be decoded, refs #91 Dialog.on_history_value_error() # currently logged as an error, because we want more insight # in order to eventually handle it more specifically Logger.error('ValueError', exc_info=True) return # triggers accounts_history observers update self.controller.accounts_history[address] = transactions
def unlock_send_transaction(self): """ Unlocks the account with password in order to sign and publish the transaction. """ controller = App.get_running_app().controller pywalib = controller.pywalib address = to_checksum_address(self.send_to_address) amount_eth = float(self.ids.send_amount_id.text) amount_wei = int(amount_eth * pow(10, 18)) gas_price_gwei = Settings.get_stored_gas_price() gas_price_wei = int(gas_price_gwei * (10**9)) account = controller.current_account Dialog.snackbar_message("Unlocking account...") try: account.unlock(self.password) except ValueError: Dialog.snackbar_message("Could not unlock account") return Dialog.snackbar_message("Unlocked! Sending transaction...") sender = account.address try: pywalib.transact(address, value=amount_wei, data='', sender=sender, gasprice=gas_price_wei) except InsufficientFundsException: Dialog.snackbar_message("Insufficient funds") return except UnknownEtherscanException: Dialog.snackbar_message("Unknown error") Logger.error('UnknownEtherscanException', exc_info=True) return # TODO: handle ConnectionError Dialog.snackbar_message("Sent!")
def test_is_stored_testnet(self): Settings.set_stored_network(ChainID.MAINNET) assert Settings.is_stored_testnet() is False Settings.set_stored_network(ChainID.ROPSTEN) assert Settings.is_stored_testnet() is True
def store_gas_price(self): """ Saves gas price value to the store. """ gas_price = self.get_ui_gas_price() Settings.set_stored_gas_price(gas_price)
def store_network(self): """ Saves selected network to the store. """ network = self.get_ui_network() Settings.set_stored_network(network)