Skip to content
Snippets Groups Projects
Commit 9840b66d authored by inso's avatar inso
Browse files

Wallets connections

parent 72f0c003
No related branches found
No related tags found
No related merge requests found
...@@ -36,20 +36,20 @@ class DividendsProcessor: ...@@ -36,20 +36,20 @@ class DividendsProcessor:
self._logger.debug("Dividend already in db") self._logger.debug("Dividend already in db")
return False return False
async def initialize_dividends(self, identity, transactions, log_stream): async def initialize_dividends(self, connection, transactions, log_stream):
""" """
Request transactions from the network to initialize data for a given pubkey Request transactions from the network to initialize data for a given pubkey
:param sakia.data.entities.Identity identity: :param sakia.data.entities.Connection connection:
:param List[sakia.data.entities.Transaction] transactions: the list of transactions found by tx processor :param List[sakia.data.entities.Transaction] transactions: the list of transactions found by tx processor
:param function log_stream: :param function log_stream:
""" """
history_data = await self._bma_connector.get(identity.currency, bma.ud.history, history_data = await self._bma_connector.get(connection.currency, bma.ud.history,
req_args={'pubkey': identity.pubkey}, verify=False) req_args={'pubkey': connection.pubkey}, verify=False)
log_stream("Found {0} available dividends".format(len(history_data["history"]["history"]))) log_stream("Found {0} available dividends".format(len(history_data["history"]["history"])))
block_numbers = [] block_numbers = []
for ud_data in history_data["history"]["history"]: for ud_data in history_data["history"]["history"]:
dividend = Dividend(currency=identity.currency, dividend = Dividend(currency=connection.currency,
pubkey=identity.pubkey, pubkey=connection.pubkey,
block_number=ud_data["block_number"], block_number=ud_data["block_number"],
timestamp=ud_data["time"], timestamp=ud_data["time"],
amount=ud_data["amount"], amount=ud_data["amount"],
......
...@@ -124,7 +124,9 @@ class TransactionsProcessor: ...@@ -124,7 +124,9 @@ class TransactionsProcessor:
responses = await self._bma_connector.broadcast(currency, bma.tx.process, req_args={'transaction': txdoc.signed_raw()}) responses = await self._bma_connector.broadcast(currency, bma.tx.process, req_args={'transaction': txdoc.signed_raw()})
result = (False, "") result = (False, "")
for r in responses: for r in responses:
if r.status == 200: if isinstance(r, BaseException):
result = (False, str(r))
elif r.status == 200:
result = (True, (await r.json())) result = (True, (await r.json()))
elif not result[0]: elif not result[0]:
result = (False, (await r.text())) result = (False, (await r.text()))
...@@ -133,14 +135,14 @@ class TransactionsProcessor: ...@@ -133,14 +135,14 @@ class TransactionsProcessor:
self.run_state_transitions(tx, [r.status for r in responses]) self.run_state_transitions(tx, [r.status for r in responses])
return result, tx return result, tx
async def initialize_transactions(self, identity, log_stream): async def initialize_transactions(self, connection, log_stream):
""" """
Request transactions from the network to initialize data for a given pubkey Request transactions from the network to initialize data for a given pubkey
:param sakia.data.entities.Identity pubkey: :param sakia.data.entities.Connection connection:
:param function log_stream: :param function log_stream:
""" """
history_data = await self._bma_connector.get(identity.currency, bma.tx.history, history_data = await self._bma_connector.get(connection.currency, bma.tx.history,
req_args={'pubkey': identity.pubkey}, verify=False) req_args={'pubkey': connection.pubkey}, verify=False)
txid = 0 txid = 0
nb_tx = len(history_data["history"]["sent"]) + len(history_data["history"]["received"]) nb_tx = len(history_data["history"]["sent"]) + len(history_data["history"]["received"])
log_stream("Found {0} transactions".format(nb_tx)) log_stream("Found {0} transactions".format(nb_tx))
...@@ -149,7 +151,7 @@ class TransactionsProcessor: ...@@ -149,7 +151,7 @@ class TransactionsProcessor:
sent = TransactionDoc.from_bma_history(history_data["currency"], sent_data) sent = TransactionDoc.from_bma_history(history_data["currency"], sent_data)
log_stream("{0}/{1} transactions".format(txid, nb_tx)) log_stream("{0}/{1} transactions".format(txid, nb_tx))
try: try:
tx = parse_transaction_doc(sent, identity.pubkey, sent_data["block_number"], tx = parse_transaction_doc(sent, connection.pubkey, sent_data["block_number"],
sent_data["time"], txid) sent_data["time"], txid)
self._repo.insert(tx) self._repo.insert(tx)
transactions.append(tx) transactions.append(tx)
......
...@@ -105,17 +105,17 @@ ...@@ -105,17 +105,17 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="button_guest"> <widget class="QPushButton" name="button_wallet">
<property name="text"> <property name="text">
<string>Connect as a guest</string> <string>Connect a wallet</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../../../../../res/icons/icons.qrc"> <iconset resource="../../../../../res/icons/icons.qrc">
<normaloff>:/icons/guest_icon</normaloff>:/icons/guest_icon</iconset> <normaloff>:/icons/wallet_icon</normaloff>:/icons/wallet_icon</iconset>
</property> </property>
<property name="iconSize"> <property name="iconSize">
<size> <size>
<width>32</width> <width>50</width>
<height>32</height> <height>32</height>
</size> </size>
</property> </property>
......
...@@ -21,7 +21,7 @@ class ConnectionConfigController(QObject): ...@@ -21,7 +21,7 @@ class ConnectionConfigController(QObject):
CONNECT = 0 CONNECT = 0
REGISTER = 1 REGISTER = 1
GUEST = 2 WALLET = 2
def __init__(self, parent, view, model): def __init__(self, parent, view, model):
""" """
...@@ -40,8 +40,8 @@ class ConnectionConfigController(QObject): ...@@ -40,8 +40,8 @@ class ConnectionConfigController(QObject):
lambda: self.step_node.set_result(ConnectionConfigController.CONNECT)) lambda: self.step_node.set_result(ConnectionConfigController.CONNECT))
self.view.button_register.clicked.connect( self.view.button_register.clicked.connect(
lambda: self.step_node.set_result(ConnectionConfigController.REGISTER)) lambda: self.step_node.set_result(ConnectionConfigController.REGISTER))
self.view.button_guest.clicked.connect( self.view.button_wallet.clicked.connect(
lambda: self.step_node.set_result(ConnectionConfigController.GUEST)) lambda: self.step_node.set_result(ConnectionConfigController.WALLET))
self.password_asker = None self.password_asker = None
self.view.values_changed.connect(lambda: self.view.button_next.setEnabled(self.check_key())) self.view.values_changed.connect(lambda: self.view.button_next.setEnabled(self.check_key()))
self.view.values_changed.connect(lambda: self.view.button_generate.setEnabled(self.check_key())) self.view.values_changed.connect(lambda: self.view.button_generate.setEnabled(self.check_key()))
...@@ -148,6 +148,12 @@ class ConnectionConfigController(QObject): ...@@ -148,6 +148,12 @@ class ConnectionConfigController(QObject):
self.view.button_next.clicked.connect(self.check_connect) self.view.button_next.clicked.connect(self.check_connect)
self.view.stacked_pages.setCurrentWidget(self.view.page_connection) self.view.stacked_pages.setCurrentWidget(self.view.page_connection)
connection_identity = await self.step_key connection_identity = await self.step_key
elif mode == ConnectionConfigController.WALLET:
self._logger.debug("Wallet mode")
self.view.button_next.clicked.connect(self.check_wallet)
self.view.edit_uid.hide()
self.view.stacked_pages.setCurrentWidget(self.view.page_connection)
connection_identity = await self.step_key
self.model.insert_or_update_connection() self.model.insert_or_update_connection()
self.view.stacked_pages.setCurrentWidget(self.view.page_services) self.view.stacked_pages.setCurrentWidget(self.view.page_services)
...@@ -177,10 +183,14 @@ class ConnectionConfigController(QObject): ...@@ -177,10 +183,14 @@ class ConnectionConfigController(QObject):
await self.model.initialize_identity(connection_identity, log_stream=self.view.stream_log) await self.model.initialize_identity(connection_identity, log_stream=self.view.stream_log)
self.view.stream_log("Initializing certifications informations...") self.view.stream_log("Initializing certifications informations...")
await self.model.initialize_certifications(connection_identity, log_stream=self.view.stream_log) await self.model.initialize_certifications(connection_identity, log_stream=self.view.stream_log)
if mode in (ConnectionConfigController.REGISTER,
ConnectionConfigController.CONNECT,
ConnectionConfigController.WALLET):
self.view.stream_log("Initializing transactions history...") self.view.stream_log("Initializing transactions history...")
transactions = await self.model.initialize_transactions(connection_identity, log_stream=self.view.stream_log) transactions = await self.model.initialize_transactions(self.model.connection, log_stream=self.view.stream_log)
self.view.stream_log("Initializing transactions history...") self.view.stream_log("Initializing dividends history...")
await self.model.initialize_dividends(connection_identity, transactions, log_stream=self.view.stream_log) await self.model.initialize_dividends(self.model.connection, transactions, log_stream=self.view.stream_log)
self.view.progress_bar.setValue(3) self.view.progress_bar.setValue(3)
await self.model.initialize_sources(self.view.stream_log) await self.model.initialize_sources(self.view.stream_log)
...@@ -197,6 +207,7 @@ class ConnectionConfigController(QObject): ...@@ -197,6 +207,7 @@ class ConnectionConfigController(QObject):
self.step_node.set_result(mode) self.step_node.set_result(mode)
self.step_key = asyncio.Future() self.step_key = asyncio.Future()
self.view.button_next.disconnect() self.view.button_next.disconnect()
self.view.edit_uid.show()
asyncio.ensure_future(self.process()) asyncio.ensure_future(self.process())
return return
self.accept() self.accept()
...@@ -235,6 +246,30 @@ class ConnectionConfigController(QObject): ...@@ -235,6 +246,30 @@ class ConnectionConfigController(QObject):
self.view.label_info.setText("") self.view.label_info.setText("")
return True return True
@asyncify
async def check_wallet(self, checked=False):
self._logger.debug("Is valid ? ")
self.view.display_info(self.tr("connecting..."))
try:
salt = self.view.edit_salt.text()
password = self.view.edit_password.text()
self.model.set_scrypt_infos(salt, password, self.view.scrypt_params)
self.model.set_uid("")
if not self.model.key_exists():
registered, found_identity = await self.model.check_registered()
self.view.button_connect.setEnabled(True)
self.view.button_register.setEnabled(True)
if registered[0] is False and registered[2] is None:
self.step_key.set_result(None)
elif registered[2]:
self.view.display_info(self.tr("""Your pubkey is associated to a pubkey.
Yours : {0}, the network : {1}""".format(registered[1], registered[2])))
else:
self.view.display_info(self.tr("A connection already exists using this key."))
except NoPeerAvailable:
self.config_dialog.label_error.setText(self.tr("Could not connect. Check node peering entry"))
@asyncify @asyncify
async def check_connect(self, checked=False): async def check_connect(self, checked=False):
self._logger.debug("Is valid ? ") self._logger.debug("Is valid ? ")
......
...@@ -107,6 +107,7 @@ class NavigationController(QObject): ...@@ -107,6 +107,7 @@ class NavigationController(QObject):
raw_data = self.view.tree_view.model().data(index, GenericTreeModel.ROLE_RAW_DATA) raw_data = self.view.tree_view.model().data(index, GenericTreeModel.ROLE_RAW_DATA)
if raw_data and raw_data["component"] == "Informations": if raw_data and raw_data["component"] == "Informations":
menu = QMenu(self.view) menu = QMenu(self.view)
if raw_data['misc']['connection'].uid:
action_gen_revokation = QAction(self.tr("Save revokation document"), menu) action_gen_revokation = QAction(self.tr("Save revokation document"), menu)
menu.addAction(action_gen_revokation) menu.addAction(action_gen_revokation)
action_gen_revokation.triggered.connect(lambda c: action_gen_revokation.triggered.connect(lambda c:
...@@ -123,6 +124,12 @@ class NavigationController(QObject): ...@@ -123,6 +124,12 @@ class NavigationController(QObject):
action_leave.triggered.connect(lambda c: self.send_leave(raw_data['misc']['connection'])) action_leave.triggered.connect(lambda c: self.send_leave(raw_data['misc']['connection']))
action_leave.setEnabled(self.model.identity_is_member(raw_data['misc']['connection'])) action_leave.setEnabled(self.model.identity_is_member(raw_data['misc']['connection']))
copy_pubkey = QAction(menu.tr("Copy pubkey to clipboard"), menu.parent())
copy_pubkey.triggered.connect(lambda checked,
c=raw_data['misc']['connection']: \
NavigationModel.copy_pubkey_to_clipboard(c))
menu.addAction(copy_pubkey)
action_remove = QAction(self.tr("Remove the connection"), menu) action_remove = QAction(self.tr("Remove the connection"), menu)
menu.addAction(action_remove) menu.addAction(action_remove)
action_remove.triggered.connect(lambda c: self.remove_connection(raw_data['misc']['connection'])) action_remove.triggered.connect(lambda c: self.remove_connection(raw_data['misc']['connection']))
......
...@@ -119,7 +119,9 @@ class InformationsModel(QObject): ...@@ -119,7 +119,9 @@ class InformationsModel(QObject):
mstime_remaining_text = self.tr("Expired or never published") mstime_remaining_text = self.tr("Expired or never published")
outdistanced_text = self.tr("Outdistanced") outdistanced_text = self.tr("Outdistanced")
is_member = False is_member = False
nb_certs = 0
if self.connection.uid:
try: try:
identity = self.identities_service.get_identity(self.connection.pubkey, self.connection.uid) identity = self.identities_service.get_identity(self.connection.pubkey, self.connection.uid)
mstime_remaining = self.identities_service.ms_time_remaining(identity) mstime_remaining = self.identities_service.ms_time_remaining(identity)
...@@ -140,10 +142,9 @@ class InformationsModel(QObject): ...@@ -140,10 +142,9 @@ class InformationsModel(QObject):
min=minutes) min=minutes)
except errors.DuniterError as e: except errors.DuniterError as e:
if e.ucode == errors.NO_MEMBER_MATCHING_PUB_OR_UID: if e.ucode == errors.NO_MEMBER_MATCHING_PUB_OR_UID:
nb_certs = 0 pass
else: else:
self._logger.error(str(e)) self._logger.error(str(e))
nb_certs = 0
return { return {
'amount': localized_amount, 'amount': localized_amount,
......
from PyQt5.QtCore import QObject from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtWidgets import QApplication
from sakia.models.generic_tree import GenericTreeModel from sakia.models.generic_tree import GenericTreeModel
from PyQt5.QtCore import pyqtSignal
from sakia.data.processors import ConnectionsProcessor from sakia.data.processors import ConnectionsProcessor
...@@ -22,9 +22,25 @@ class NavigationModel(QObject): ...@@ -22,9 +22,25 @@ class NavigationModel(QObject):
self._current_data = None self._current_data = None
def init_navigation_data(self): def init_navigation_data(self):
currencies = ConnectionsProcessor.instanciate(self.app).currencies()
if currencies:
self.navigation = [ self.navigation = [
{ {
'title': self.app.parameters.profile_name, 'title': self.tr('Network'),
'icon': ':/icons/network_icon',
'component': "Network",
'dependencies': {
'network_service': self.app.network_services[currencies[0]],
},
'misc': {
},
'children': []
}
]
else:
self.navigation = [
{
'title': self.tr("No connection configured"),
'component': "HomeScreen", 'component': "HomeScreen",
'parameters': self.app.parameters, 'parameters': self.app.parameters,
'dependencies': {}, 'dependencies': {},
...@@ -32,13 +48,14 @@ class NavigationModel(QObject): ...@@ -32,13 +48,14 @@ class NavigationModel(QObject):
'children': [] 'children': []
} }
] ]
self._current_data = self.navigation[0] self._current_data = self.navigation[0]
for connection in self.app.db.connections_repo.get_all(): for connection in self.app.db.connections_repo.get_all():
self.navigation[0]['children'].append(self.create_node(connection)) self.navigation[0]['children'].append(self.create_node(connection))
return self.navigation return self.navigation
def create_node(self, connection): def create_node(self, connection):
return { node = {
'title': connection.title(), 'title': connection.title(),
'component': "Informations", 'component': "Informations",
'dependencies': { 'dependencies': {
...@@ -65,19 +82,11 @@ class NavigationModel(QObject): ...@@ -65,19 +82,11 @@ class NavigationModel(QObject):
'misc': { 'misc': {
'connection': connection 'connection': connection
} }
},
{
'title': self.tr('Network'),
'icon': ':/icons/network_icon',
'component': "Network",
'dependencies': {
'network_service': self.app.network_services[connection.currency],
},
'misc': {
'connection': connection
} }
}, ]
{ }
if connection.uid:
node["children"] += [{
'title': self.tr('Identities'), 'title': self.tr('Identities'),
'icon': ':/icons/members_icon', 'icon': ':/icons/members_icon',
'component': "Identities", 'component': "Identities",
...@@ -102,9 +111,8 @@ class NavigationModel(QObject): ...@@ -102,9 +111,8 @@ class NavigationModel(QObject):
'misc': { 'misc': {
'connection': connection 'connection': connection
} }
} }]
] return node
}
def generic_tree(self): def generic_tree(self):
return GenericTreeModel.create("Navigation", self.navigation) return GenericTreeModel.create("Navigation", self.navigation)
...@@ -140,6 +148,10 @@ class NavigationModel(QObject): ...@@ -140,6 +148,10 @@ class NavigationModel(QObject):
async def remove_connection(self, connection): async def remove_connection(self, connection):
await self.app.remove_connection(connection) await self.app.remove_connection(connection)
async def send_leave(self, connection, password): async def send_leave(self, connection, password):
return await self.app.documents_service.send_membership(connection, password, "OUT") return await self.app.documents_service.send_membership(connection, password, "OUT")
@staticmethod
def copy_pubkey_to_clipboard(connection):
clipboard = QApplication.clipboard()
clipboard.setText(connection.pubkey)
\ No newline at end of file
...@@ -33,7 +33,6 @@ class NetworkController(QObject): ...@@ -33,7 +33,6 @@ class NetworkController(QObject):
:param PyQt5.QObject parent: :param PyQt5.QObject parent:
:param sakia.app.Application app: :param sakia.app.Application app:
:param sakia.services.NetworkService network_service: :param sakia.services.NetworkService network_service:
:param sakia.data.entities.Connection connection:
:return: :return:
""" """
view = NetworkView(parent.view,) view = NetworkView(parent.view,)
......
...@@ -42,7 +42,7 @@ class NavigationView(QFrame, Ui_Navigation): ...@@ -42,7 +42,7 @@ class NavigationView(QFrame, Ui_Navigation):
raw_data = self.tree_view.model().data(index, GenericTreeModel.ROLE_RAW_DATA) raw_data = self.tree_view.model().data(index, GenericTreeModel.ROLE_RAW_DATA)
if 'widget' in raw_data: if 'widget' in raw_data:
widget = raw_data['widget'] widget = raw_data['widget']
if self.stacked_widget.indexOf(widget): if self.stacked_widget.indexOf(widget) != -1:
self.stacked_widget.setCurrentWidget(widget) self.stacked_widget.setCurrentWidget(widget)
self.current_view_changed.emit(raw_data) self.current_view_changed.emit(raw_data)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment