Beispiel #1
0
 def __init__(self, caller, masternode_alias=None):
     self.caller = caller
     self.ui = TabMNConf_gui(masternode_alias)
     self.caller.tabMNConf = self.ui
     self.runInThread = ThreadFuns.runInThread
     self.spath_found = False
     self.spath = -1
     # Lookup Collateral dialog
     self.dlg = FindCollTx_dlg(self)
     # Connect GUI buttons
     self.ui.btn_genKey.clicked.connect(lambda: self.onGenerateMNkey())
     self.ui.btn_addressToSpath.clicked.connect(lambda: self.onFindSpathAndPrivKey())
     self.ui.btn_findTxid.clicked.connect(lambda: self.onLookupTx())
     self.ui.btn_editTxid.clicked.connect(lambda: self.onEditTx())
     self.ui.edt_txid.returnPressed.connect(lambda: self.onEditTx())
     self.ui.btn_cancelMNConf.clicked.connect(lambda: self.onCancelMNConfig())
     self.ui.btn_saveMNConf.clicked.connect(lambda: self.onSaveMNConf())
     self.ui.btn_spathToAddress.clicked.connect(lambda: self.spathToAddress())
     self.ui.testnetCheck.clicked.connect(lambda: self.onChangeTestnet())
Beispiel #2
0
    def onLookupTx(self):
        # address check
        currAddr = self.ui.edt_address.text().strip()
        # Check rpc connection
        printDbg("Checking RPC connection")
        if not self.caller.rpcConnected:
            self.caller.myPopUp2(QMessageBox.Critical,
                                 'SPMT - hw device check',
                                 "Connect to RPC server first")
            printDbg("Unable to connect: %s" % self.caller.rpcStatusMess)
            return None
        try:
            # Create Lookup dialog
            ui = FindCollTx_dlg(self.ui, self.caller.rpcClient, currAddr)
            if ui.exec_():
                txid, txidn = ui.getSelection()
                self.ui.edt_txid.setText(txid)
                self.ui.edt_txidn.setValue(txidn)

        except Exception as e:
            printDbg(e)
Beispiel #3
0
class TabMNConf():
    def __init__(self, caller, masternode_alias=None):
        self.caller = caller
        self.ui = TabMNConf_gui(masternode_alias)
        self.caller.tabMNConf = self.ui
        self.runInThread = ThreadFuns.runInThread
        self.spath_found = False
        self.spath = -1
        # Lookup Collateral dialog
        self.dlg = FindCollTx_dlg(self)
        # Connect GUI buttons
        self.ui.btn_genKey.clicked.connect(lambda: self.onGenerateMNkey())
        self.ui.btn_addressToSpath.clicked.connect(
            lambda: self.onFindSpathAndPrivKey())
        self.ui.btn_findTxid.clicked.connect(lambda: self.onLookupTx())
        self.ui.btn_editTxid.clicked.connect(lambda: self.onEditTx())
        self.ui.edt_txid.returnPressed.connect(lambda: self.onEditTx())
        self.ui.btn_cancelMNConf.clicked.connect(
            lambda: self.onCancelMNConfig())
        self.ui.btn_saveMNConf.clicked.connect(lambda: self.onSaveMNConf())
        self.ui.btn_spathToAddress.clicked.connect(
            lambda: self.spathToAddress())
        self.ui.testnetCheck.clicked.connect(lambda: self.onChangeTestnet())

    def addressToSpath(self):
        printOK("addressToSpath pressed")
        self.spath_found = False
        # Check dongle
        printDbg("Checking HW device")
        if self.caller.hwStatus != 2:
            self.caller.myPopUp2(QMessageBox.Critical, 'QMT - hw device check',
                                 "Connect to HW device first")
            printDbg(
                "Unable to connect to hardware device. The device status is: %d"
                % self.caller.hwStatus)
            return None
        self.runInThread(self.findSpath, (0, 10), self.findSpath_done)

    @pyqtSlot(object, int, int)
    def findSpath(self, ctrl, starting_spath, spath_count):
        currAddr = self.ui.edt_address.text().strip()
        currHwAcc = self.ui.edt_hwAccount.value()
        # first scan. Subsequent called by findSpath_done
        self.spath_found, self.spath = self.caller.hwdevice.scanForBip32(
            currHwAcc, currAddr, starting_spath, spath_count, self.isTestnet())
        printOK("Bip32 scan complete. result=%s   spath=%s" %
                (self.spath_found, self.spath))
        self.curr_starting_spath = starting_spath
        self.curr_spath_count = spath_count

    @pyqtSlot()
    def findSpath_done(self):
        currAddr = self.ui.edt_address.text().strip()
        currHwAcc = self.ui.edt_hwAccount.value()
        spath = self.spath
        starting_spath = self.curr_starting_spath
        spath_count = self.curr_spath_count

        if self.spath_found:
            printOK("spath is %d" % spath)
            mess = "Found address %s in HW account %s with spath_id %s" % (
                currAddr, currHwAcc, spath)
            self.caller.myPopUp2(QMessageBox.Information, 'QMT - spath search',
                                 mess)
            self.ui.edt_spath.setValue(spath)
            self.findPubKey()

        else:
            mess = "Scanned addresses <b>%d</b> to <b>%d</b> of HW account <b>%d</b>.<br>" % (
                starting_spath, starting_spath + spath_count - 1, currHwAcc)
            mess += "Unable to find the address <i>%s</i>.<br>Maybe it's on a different account.<br><br>" % currAddr
            mess += "Do you want to scan %d more addresses of account n.<b>%d</b> ?" % (
                spath_count, currHwAcc)
            ans = self.caller.myPopUp(QMessageBox.Critical,
                                      'QMT - spath search', mess)
            if ans == QMessageBox.Yes:
                starting_spath += spath_count
                self.runInThread(self.findSpath, (starting_spath, spath_count),
                                 self.findSpath_done)

    @pyqtSlot()
    def findPubKey(self):
        printDbg("Computing public key...")
        currSpath = self.ui.edt_spath.value()
        currHwAcc = self.ui.edt_hwAccount.value()
        # Check dongle
        printDbg("Checking HW device")
        if self.caller.hwStatus != 2:
            self.caller.myPopUp2(QMessageBox.Critical, 'QMT - hw device check',
                                 "Connect to HW device first")
            printDbg(
                "Unable to connect to hardware device. The device status is: %d"
                % self.caller.hwStatus)
            return None

        try:
            result = self.caller.hwdevice.scanForPubKey(currHwAcc, currSpath)

        except Exception as e:
            error_msg = "ERROR: %s" % e.args[0]
            printDbg(error_msg)
            result = None

        # Connection pop-up
        warningText = "Another application (such as Ledger Wallet app) has probably taken over "
        warningText += "the communication with the Ledger device.<br><br>To continue, close that application and "
        warningText += "click the <b>Retry</b> button.\nTo cancel, click the <b>Abort</b> button"
        mBox = QMessageBox(QMessageBox.Critical, "WARNING", warningText,
                           QMessageBox.Retry)
        mBox.setStandardButtons(QMessageBox.Retry | QMessageBox.Abort)

        while result is None:
            ans = mBox.exec_()
            if ans == QMessageBox.Abort:
                return
            # we need to reconnect the device
            self.caller.hwdevice.dongle.close()
            self.caller.hwdevice.initDevice()

            result = self.caller.hwdevice.scanForPubKey(currHwAcc, currSpath)

        mess = "Found public key:\n%s" % result
        self.caller.myPopUp2(QMessageBox.Information, "QMT - findPubKey", mess)
        printOK("Public Key: %s" % result)
        self.ui.edt_pubKey.setText(result)

    def findRow_mn_list(self, name):
        row = 0
        while self.caller.tabMain.myList.item(row)['name'] < name:
            row += 1
        return row

    def isTestnet(self):
        return self.ui.testnetCheck.isChecked()

    @pyqtSlot()
    def onCancelMNConfig(self):
        self.caller.tabs.setCurrentIndex(0)
        self.caller.tabs.removeTab(1)
        self.caller.mnode_to_change = None

    @pyqtSlot()
    def onChangeTestnet(self):
        if self.isTestnet():
            self.ui.edt_masternodePort.setValue(51474)
        else:
            self.ui.edt_masternodePort.setValue(51472)

    @pyqtSlot()
    def onEditTx(self):
        if not self.ui.edt_txid.isEnabled():
            self.ui.btn_editTxid.setText("OK")
            self.ui.edt_txid.setEnabled(True)
            self.ui.edt_txidn.setEnabled(True)
            self.ui.btn_findTxid.setEnabled(False)
            self.ui.btn_saveMNConf.setEnabled(False)

        else:
            self.ui.btn_editTxid.setText("edit")
            self.ui.edt_txid.setEnabled(False)
            self.ui.edt_txidn.setEnabled(False)
            self.ui.btn_findTxid.setEnabled(True)
            self.ui.btn_saveMNConf.setEnabled(True)

    @pyqtSlot()
    def onFindSpathAndPrivKey(self):
        self.ui.edt_spath.setValue(0)
        self.ui.edt_pubKey.setText('')
        self.addressToSpath()

    @pyqtSlot()
    def onLookupTx(self):
        # address check
        currAddr = self.ui.edt_address.text().strip()
        # Check rpc connection
        printDbg("Checking RPC connection")
        if not self.caller.rpcConnected:
            self.caller.myPopUp2(QMessageBox.Critical, 'QMT - hw device check',
                                 "Connect to RPC server first")
            printDbg("Unable to connect: %s" % self.caller.rpcStatusMess)
            return None
        try:
            # Update Lookup dialog
            self.dlg.load_data(currAddr)
            if self.dlg.exec_():
                txid, txidn = self.dlg.getSelection()
                self.ui.edt_txid.setText(txid)
                self.ui.edt_txidn.setValue(txidn)

        except Exception as e:
            printDbg(e)

    @pyqtSlot()
    def onGenerateMNkey(self):
        printDbg("Generate MNkey pressed")
        reply = QMessageBox.Yes

        if self.ui.edt_mnPrivKey.text() != "":
            reply = self.caller.myPopUp(
                QMessageBox.Warning, "GENERATE PRIV KEY",
                "Are you sure?\nThis will overwrite current private key",
                QMessageBox.No)

        if reply == QMessageBox.No:
            return

        newkey = generate_privkey(self.isTestnet())
        self.ui.edt_mnPrivKey.setText(newkey)

    @pyqtSlot()
    def onSaveMNConf(self):
        try:
            if self.ui.edt_pubKey.text() == "" or self.ui.edt_txid.text(
            ) == "" or self.ui.edt_mnPrivKey.text() == "":
                mess_text = 'Attention! Complete the form before saving.<br>'
                mess_text += "<b>pubKey = </b>%s<br>" % self.ui.edt_pubKey.text(
                )
                mess_text += "<b>txId = </b>%s<br>" % self.ui.edt_txid.text()
                mess_text += "<b>mnPrivKey = </b>%s<br>" % self.ui.edt_mnPrivKey.text(
                )
                self.caller.myPopUp2(QMessageBox.Critical, 'Complete Form',
                                     mess_text)
                return

            if not is_hex(self.ui.edt_txid.text()):
                mess_text = 'Attention! txid format is not valid.<br>'
                mess_text += "<b>txId = </b>%s<br>" % self.ui.edt_txid.text()
                mess_text += 'transaction id must be in hex format.<br>'
                self.caller.myPopUp2(QMessageBox.Critical, 'Complete Form',
                                     mess_text)
                return

            # check for duplicate name
            mn_alias = self.ui.edt_name.text().strip()
            # if we are changing a masternode don't check old alias
            old_alias = None
            if not self.caller.mnode_to_change is None:
                old_alias = self.caller.mnode_to_change['name']
            if self.caller.isMasternodeInList(
                    mn_alias) and old_alias != mn_alias:
                mess_text = 'Attention! The name <b>%s</b> is already in use for another masternode.<br>' % mn_alias
                mess_text += 'Choose a different name (alias) for the masternode'
                self.caller.myPopUp2(QMessageBox.Critical, 'Complete Form',
                                     mess_text)
                return

            # remove previous element
            if not self.caller.mnode_to_change is None:
                # remove from memory list
                self.caller.masternode_list.remove(self.caller.mnode_to_change)
                # remove from tabMain list
                row = self.caller.tabMain.myList.row
                name = self.caller.tabMain.current_mn[
                    self.caller.mnode_to_change['name']]
                self.caller.tabMain.myList.takeItem(row(name))
                self.caller.mnode_to_change = None

            # create new item
            new_masternode = {}
            new_masternode['name'] = mn_alias
            masternodeIp = self.ui.edt_masternodeIp.text().strip()
            if not masternodeIp.endswith('.onion'):
                masternodeIp = ip_address(masternodeIp).compressed
            new_masternode['ip'] = masternodeIp
            new_masternode['port'] = self.ui.edt_masternodePort.value()
            new_masternode['mnPrivKey'] = self.ui.edt_mnPrivKey.text().strip()
            new_masternode['isTestnet'] = 0 if not self.isTestnet() else 1
            new_masternode['isHardware'] = True
            new_masternode['hwAcc'] = self.ui.edt_hwAccount.value()

            coll = {}
            coll['address'] = self.ui.edt_address.text().strip()
            coll['spath'] = self.ui.edt_spath.value()
            coll['pubKey'] = self.ui.edt_pubKey.text().strip()
            coll['txid'] = self.ui.edt_txid.text().strip()
            coll['txidn'] = self.ui.edt_txidn.value()

            new_masternode['collateral'] = coll

            # add new item
            self.caller.masternode_list.append(new_masternode)
            # Write to file
            printDbg("saving MN configuration for %s" % new_masternode['name'])
            writeToFile(self.caller.masternode_list, masternodes_File)
            printDbg("saved")

            # Insert item in list of Main tab and connect buttons
            name = new_masternode['name']
            namelist = [x['name'] for x in self.caller.masternode_list]
            row = namelist.index(name)
            if row == -1:
                row = None
            self.caller.tabMain.insert_mn_list(name, new_masternode['ip'],
                                               new_masternode['port'], row)
            self.caller.tabMain.btn_remove[name].clicked.connect(
                lambda: self.caller.t_main.onRemoveMN())
            self.caller.tabMain.btn_edit[name].clicked.connect(
                lambda: self.caller.t_main.onEditMN())
            self.caller.tabMain.btn_start[name].clicked.connect(
                lambda: self.caller.t_main.onStartMN())
            self.caller.tabMain.btn_rewards[name].clicked.connect(
                lambda: self.caller.t_main.onRewardsMN())

            # Clear voting masternodes configuration and update cache
            self.caller.t_governance.clear()

            # go back
            self.onCancelMNConfig()

        except Exception as e:
            error_msg = "ERROR: %s" % e
            printDbg(error_msg)
            self.caller.myPopUp2(QMessageBox.Critical, 'ERROR', error_msg)

    @pyqtSlot()
    def spathToAddress(self):
        printOK("spathToAddress pressed")
        currHwAcc = self.ui.edt_hwAccount.value()
        currSpath = self.ui.edt_spath.value()
        # Check dongle
        printDbg("Checking HW device")
        if self.caller.hwStatus != 2:
            self.caller.myPopUp2(QMessageBox.Critical, 'QMT - hw device check',
                                 "Connect to HW device first")
            printDbg(
                "Unable to connect to hardware device. The device status is: %d"
                % self.caller.hwStatus)
            return None
        addr = self.caller.hwdevice.scanForAddress(currHwAcc, currSpath,
                                                   self.isTestnet())
        self.ui.edt_address.setText(addr)
        self.findPubKey()
Beispiel #4
0
class TabMNConf():
    def __init__(self, caller, masternode_alias=None):
        self.caller = caller
        self.ui = TabMNConf_gui(masternode_alias)
        self.caller.tabMNConf = self.ui
        self.runInThread = ThreadFuns.runInThread
        self.spath_found = False
        self.spath = -1
        # Lookup Collateral dialog
        self.dlg = FindCollTx_dlg(self)
        # Connect GUI buttons
        self.ui.btn_genKey.clicked.connect(lambda: self.onGenerateMNkey())
        self.ui.btn_addressToSpath.clicked.connect(lambda: self.onFindSpathAndPrivKey())
        self.ui.btn_findTxid.clicked.connect(lambda: self.onLookupTx())
        self.ui.btn_editTxid.clicked.connect(lambda: self.onEditTx())
        self.ui.edt_txid.returnPressed.connect(lambda: self.onEditTx())
        self.ui.btn_cancelMNConf.clicked.connect(lambda: self.onCancelMNConfig())
        self.ui.btn_saveMNConf.clicked.connect(lambda: self.onSaveMNConf())
        self.ui.btn_spathToAddress.clicked.connect(lambda: self.spathToAddress())
        self.ui.testnetCheck.clicked.connect(lambda: self.onChangeTestnet())



    def addressToSpath(self):
        printOK("addressToSpath pressed")
        self.spath_found = False
        # Check HW device
        if self.caller.hwStatus != 2:
            myPopUp_sb(self.caller, "crit", 'SPMT - hw device check', "Connect to HW device first")
            printDbg("Unable to connect to hardware device. The device status is: %d" % self.caller.hwStatus)
            return None
        self.runInThread(self.findSpath, (0, 10), self.findSpath_done)



    def findSpath(self, ctrl, starting_spath, spath_count):
        currAddr = self.ui.edt_address.text().strip()
        currHwAcc = self.ui.edt_hwAccount.value()
        # first scan. Subsequent called by findSpath_done
        self.spath_found, self.spath = self.caller.hwdevice.scanForBip32(currHwAcc, currAddr, starting_spath, spath_count, self.isTestnet())
        printOK("Bip32 scan complete. result=%s   spath=%s" % (self.spath_found, self.spath))
        self.curr_starting_spath = starting_spath
        self.curr_spath_count = spath_count



    def findSpath_done(self):
        currAddr = self.ui.edt_address.text().strip()
        currHwAcc = self.ui.edt_hwAccount.value()
        spath = self.spath
        starting_spath = self.curr_starting_spath
        spath_count = self.curr_spath_count

        if self.spath_found:
            printOK("spath is %d" % spath)
            mess = "Found address %s in HW account %s with spath_id %s" % (currAddr, currHwAcc, spath)
            myPopUp_sb(self.caller, "info", 'SPMT - spath search', mess)
            self.ui.edt_spath.setValue(spath)
            self.findPubKey()

        else:
            mess = "Scanned addresses <b>%d</b> to <b>%d</b> of HW account <b>%d</b>.<br>" % (starting_spath, starting_spath+spath_count-1, currHwAcc)
            mess += "Unable to find the address <i>%s</i>.<br>Maybe it's on a different account.<br><br>" % currAddr
            mess += "Do you want to scan %d more addresses of account n.<b>%d</b> ?" % (spath_count, currHwAcc)
            ans = myPopUp(self.caller, "crit", 'SPMT - spath search', mess)
            if ans == QMessageBox.Yes:
                starting_spath += spath_count
                self.runInThread(self.findSpath, (starting_spath, spath_count), self.findSpath_done)



    def findPubKey(self):
        printDbg("Computing public key...")
        currSpath = self.ui.edt_spath.value()
        currHwAcc = self.ui.edt_hwAccount.value()
        # Check HW device
        if self.caller.hwStatus != 2:
            myPopUp_sb(self.caller, "crit", 'SPMT - hw device check', "Connect to HW device first")
            printDbg("Unable to connect to hardware device. The device status is: %d" % self.caller.hwStatus)
            return None

        result = self.caller.hwdevice.scanForPubKey(currHwAcc, currSpath, self.isTestnet())

        # Connection pop-up
        warningText = "Unable to find public key. The action was refused on the device or another application "
        warningText += "might have taken over the USB communication with the device.<br><br>"
        warningText += "To continue click the <b>Retry</b> button.\nTo cancel, click the <b>Abort</b> button."
        mBox = QMessageBox(QMessageBox.Critical, "WARNING", warningText, QMessageBox.Retry)
        mBox.setStandardButtons(QMessageBox.Retry | QMessageBox.Abort);

        while result is None:
            ans = mBox.exec_()
            if ans == QMessageBox.Abort:
                return
            # we need to reconnect the device
            self.caller.hwdevice.clearDevice()
            self.caller.hwdevice.initDevice(self.caller.header.hwDevices.currentIndex())

            result = self.caller.hwdevice.scanForPubKey(currHwAcc, currSpath, self.isTestnet())

        mess = "Found public key:\n%s" % result
        myPopUp_sb(self.caller, "info", "SPMT - findPubKey", mess)
        printOK("Public Key: %s" % result)
        self.ui.edt_pubKey.setText(result)



    def findRow_mn_list(self, name):
        row = 0
        while self.caller.tabMain.myList.item(row)['name'] < name:
            row += 1
        return row



    def isTestnet(self):
        return self.ui.testnetCheck.isChecked()



    def onCancelMNConfig(self):
        self.caller.tabs.setCurrentIndex(0)
        self.caller.tabs.removeTab(1)
        self.caller.mnode_to_change = None



    def onChangeTestnet(self):
        if self.isTestnet():
            self.ui.edt_masternodePort.setValue(51474)
        else:
            self.ui.edt_masternodePort.setValue(51472)



    def onEditTx(self):
        if not self.ui.edt_txid.isEnabled():
            self.ui.btn_editTxid.setText("OK")
            self.ui.edt_txid.setEnabled(True)
            self.ui.edt_txidn.setEnabled(True)
            self.ui.btn_findTxid.setEnabled(False)
            self.ui.btn_saveMNConf.setEnabled(False)

        else:
            self.ui.btn_editTxid.setText("edit")
            self.ui.edt_txid.setEnabled(False)
            self.ui.edt_txidn.setEnabled(False)
            self.ui.btn_findTxid.setEnabled(True)
            self.ui.btn_saveMNConf.setEnabled(True)



    def onFindSpathAndPrivKey(self):
        self.ui.edt_spath.setValue(0)
        self.ui.edt_pubKey.setText('')
        self.addressToSpath()



    def onLookupTx(self):
        # address check
        currAddr = self.ui.edt_address.text().strip()
        # Check rpc connection
        printDbg("Checking RPC connection")
        if not self.caller.rpcConnected:
            myPopUp_sb(self.caller, "crit", 'SPMT - hw device check', "Connect to RPC server first")
            printDbg("Unable to connect: %s" % self.caller.rpcStatusMess)
            return None
        try:
            # Update Lookup dialog
            self.dlg.load_data(currAddr)
            if self.dlg.exec_():
                txid, txidn = self.dlg.getSelection()
                self.ui.edt_txid.setText(txid)
                self.ui.edt_txidn.setValue(txidn)

        except Exception as e:
            printDbg(e)



    def onGenerateMNkey(self):
        printDbg("Generate MNkey pressed")
        reply = QMessageBox.Yes

        if self.ui.edt_mnPrivKey.text() != "":
            reply = myPopUp(self.caller, "warn", "GENERATE PRIV KEY",
                                 "Are you sure?\nThis will overwrite current private key", QMessageBox.No)

        if reply == QMessageBox.No:
            return

        newkey = generate_privkey(self.isTestnet())
        self.ui.edt_mnPrivKey.setText(newkey)



    def onSaveMNConf(self):
        try:
            if self.ui.edt_pubKey.text() == "" or self.ui.edt_txid.text() == "" or self.ui.edt_mnPrivKey.text() == "":
                mess_text = 'Attention! Complete the form before saving.<br>'
                mess_text += "<b>pubKey = </b>%s<br>" % self.ui.edt_pubKey.text()
                mess_text += "<b>txId = </b>%s<br>" % self.ui.edt_txid.text()
                mess_text += "<b>mnPrivKey = </b>%s<br>" % self.ui.edt_mnPrivKey.text()
                myPopUp_sb(self.caller, "crit", 'Complete Form', mess_text)
                return

            if not is_hex(self.ui.edt_txid.text()):
                mess_text = 'Attention! txid format is not valid.<br>'
                mess_text += "<b>txId = </b>%s<br>" % self.ui.edt_txid.text()
                mess_text += 'transaction id must be in hex format.<br>'
                myPopUp_sb(self.caller, "crit", 'Complete Form', mess_text)
                return

            # check for duplicate names
            mn_alias = self.ui.edt_name.text().strip()
            # if we are changing a masternode check for duplicate only if name is changed
            old_alias = None
            if not self.caller.mnode_to_change is None:
                old_alias = self.caller.mnode_to_change['name']
            if self.caller.isMasternodeInList(mn_alias) and old_alias != mn_alias:
                mess_text = 'Attention! The name <b>%s</b> is already in use for another masternode.<br>' % mn_alias
                mess_text += 'Choose a different name (alias) for the masternode'
                myPopUp_sb(self.caller, "crit", 'Complete Form', mess_text)
                return

            # create new item
            new_masternode = {}
            new_masternode['name'] = mn_alias
            masternodeIp = self.ui.edt_masternodeIp.text().strip()
            if not masternodeIp.endswith('.onion'):
                masternodeIp = ip_address(masternodeIp).compressed
            new_masternode['ip'] = masternodeIp
            new_masternode['port'] = self.ui.edt_masternodePort.value()
            new_masternode['mnPrivKey'] = self.ui.edt_mnPrivKey.text().strip()
            new_masternode['isTestnet'] = 0 if not self.isTestnet() else 1
            new_masternode['isHardware'] = True
            new_masternode['hwAcc'] = self.ui.edt_hwAccount.value()

            coll = {}
            coll['address'] = self.ui.edt_address.text().strip()
            coll['spath'] = self.ui.edt_spath.value()
            coll['pubKey'] = self.ui.edt_pubKey.text().strip()
            coll['txid'] = self.ui.edt_txid.text().strip()
            coll['txidn'] = self.ui.edt_txidn.value()

            new_masternode['collateral'] = coll

            # Add to cache, QListWidget and database (and remove/edit mnode_to_change)
            appendMasternode(self.caller, new_masternode)

            # go back
            self.onCancelMNConfig()

        except Exception as e:
            error_msg = "ERROR: %s" % e
            printDbg(error_msg)
            myPopUp_sb(self.caller, "crit", 'ERROR', error_msg)



    def spathToAddress(self):
        printOK("spathToAddress pressed")
        currHwAcc = self.ui.edt_hwAccount.value()
        currSpath = self.ui.edt_spath.value()
        # Check HW device
        if self.caller.hwStatus != 2:
            myPopUp_sb(self.caller, "crit", 'SPMT - hw device check', "Connect to HW device first")
            printDbg("Unable to connect to hardware device. The device status is: %d" % self.caller.hwStatus)
            return None
        addr = self.caller.hwdevice.scanForAddress(currHwAcc, currSpath, self.isTestnet())
        if addr:
            self.ui.edt_address.setText(addr)
            self.findPubKey()