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

Wallets connections

parent 72f0c003
Branches
Tags
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