Example #1
0
    def data(self, index, role=Qt.DisplayRole):
        row, col = index.row(), index.column()
        txout = self.dustTxOutlist[row]
        addrStr = script_to_addrStr(txout.getScript())
        pyAddr = self.wlt.addrMap[addrStr_to_hash160(addrStr)[1]]
        chainIndex = pyAddr.chainIndex + 1
        if role == Qt.DisplayRole:
            if col == DUSTCOLS.chainIndex: return QVariant(chainIndex)
            if col == DUSTCOLS.AddrStr: return QVariant(addrStr)
            if col == DUSTCOLS.Btc:
                return QVariant(coin2str(txout.getValue(), maxZeros=8))
        elif role == Qt.TextAlignmentRole:
            if col == DUSTCOLS.chainIndex:
                return QVariant(int(Qt.AlignLeft | Qt.AlignVCenter))
            if col == DUSTCOLS.AddrStr:
                return QVariant(int(Qt.AlignLeft | Qt.AlignVCenter))
            if col == DUSTCOLS.Btc:
                return QVariant(int(Qt.AlignRight | Qt.AlignVCenter))
        elif role == Qt.ForegroundRole:
            return QVariant(Colors.Foreground)
        elif role == Qt.FontRole:
            if col == DUSTCOLS.Btc:
                return GETFONT('Fixed')

        return QVariant()
 def createLogDisplay(self):
     logTextDisplay = QTextEdit()
     logTextDisplay.setFont(GETFONT('Fixed', 8))
     w, h = relaxedSizeNChar(logTextDisplay, 68)[0], int(12 * 8.2)
     logTextDisplay.setMinimumWidth(w)
     logTextDisplay.setMinimumHeight(h)
     logTextDisplay.setReadOnly(True)
     return logTextDisplay
Example #3
0
    def updateWalletTable(self):
        numWallets = len(self.main.walletMap)
        self.wltTable.setRowCount(numWallets)
        self.wltTable.setColumnCount(4)

        row = 0
        for wltID, wltObj in self.main.walletMap.iteritems():
            wltValueBTC = '(...)'
            wltValueUSD = '(...)'
            if TheBDM.getState() == BDM_BLOCKCHAIN_READY:
                convertVal = float(self.lastSellStr.replace(',', ''))
                wltBal = wltObj.getBalance('Total')
                wltValueBTC = coin2str(wltBal, maxZeros=2)
                wltValueUSD = '$' + self.addCommasToPrice(
                    '%0.2f' % (wltBal * convertVal / 1e8))

            rowItems = []
            rowItems.append(QTableWidgetItem(wltID))
            rowItems.append(QTableWidgetItem(wltObj.labelName))
            rowItems.append(QTableWidgetItem(wltValueBTC))
            rowItems.append(QTableWidgetItem(wltValueUSD))

            rowItems[-2].setTextAlignment(Qt.AlignRight)
            rowItems[-1].setTextAlignment(Qt.AlignRight)
            rowItems[-2].setFont(GETFONT('Fixed', 10))
            rowItems[-1].setFont(GETFONT('Fixed', 10))

            for i, item in enumerate(rowItems):
                self.wltTable.setItem(row, i, item)
                item.setFlags(Qt.NoItemFlags)

            self.wltTable.setHorizontalHeaderItem(
                0, QTableWidgetItem(tr('Wallet ID')))
            self.wltTable.setHorizontalHeaderItem(
                1, QTableWidgetItem(tr('Wallet Name')))
            self.wltTable.setHorizontalHeaderItem(
                2, QTableWidgetItem(tr('BTC Balance')))
            self.wltTable.setHorizontalHeaderItem(
                3, QTableWidgetItem(tr('USD ($) Value')))
            self.wltTable.verticalHeader().hide()

            row += 1
Example #4
0
    def data(self, index, role=Qt.DisplayRole):
        col = index.column()
        node = self.getNodeItem(index)

        if role == Qt.DisplayRole:
            if col == COL_NAME:
                return QVariant(node.treeNode.getName())

            if col == COL_DESCR:
                try:
                    return QVariant(node.treeNode.getComment())
                except:
                    pass

            if col == COL_VALUE:
                try:
                    return QVariant(
                        coin2str(node.treeNode.getBalance(), maxZeros=2))
                except:
                    pass

            if col == COL_TXOUTCOUNT:
                try:
                    return QVariant(node.treeNode.getCount())
                except:
                    pass

        elif role == Qt.CheckStateRole:
            try:
                if col == COL_NAME:
                    st = node.treeNode.checked()
                    return st
                else:
                    return QVariant()
            except:
                pass

        elif role == Qt.BackgroundRole:
            try:
                if node.treeNode.checked() != Qt.Unchecked:
                    return QVariant(Colors.SlightBlue)
            except:
                pass

        elif role == Qt.FontRole:
            try:
                if node.treeNode.checked() != Qt.Unchecked:
                    return GETFONT('Fixed', bold=True)
            except:
                pass

        return QVariant()
Example #5
0
 def __init__(self, parent, main):
     super(QWizard, self).__init__(parent)
     self.setWizardStyle(QWizard.ClassicStyle)
     self.parent = parent
     self.main = main
     self.setFont(GETFONT('var'))
     self.setWindowFlags(Qt.Window)
     # Need to adjust the wizard frame size whenever the page changes.
     self.connect(self, SIGNAL('currentIdChanged(int)'), self.fitContents)
     if USE_TESTNET:
         self.setWindowTitle('Armory - Bitcoin Wallet Management [TESTNET]')
         self.setWindowIcon(QIcon(':/armory_icon_green_32x32.png'))
     else:
         self.setWindowTitle('Armory - Bitcoin Wallet Management')
         self.setWindowIcon(QIcon(':/armory_icon_32x32.png'))
Example #6
0
    def data(self, index, role=Qt.DisplayRole):
        col = index.column()
        node = self.getNodeItem(index)

        if role == Qt.DisplayRole:
            if col == COL_OUTPUT:
                return QVariant(node.treeNode.getName())

            if col == COL_ADDR:
                try:
                    return QVariant(node.treeNode.getAddress())
                except:
                    pass

            if col == COL_VALUE:
                try:
                    return QVariant(node.treeNode.getValue())
                except:
                    pass

        elif role == Qt.CheckStateRole:
            try:
                if col == COL_OUTPUT:
                    if node.treeNode.isCheckable():
                        st = node.treeNode.checked()
                        return st
                else:
                    return QVariant()
            except:
                pass

        elif role == Qt.BackgroundRole:
            try:
                if node.treeNode.checked() != Qt.Unchecked:
                    return QVariant(Colors.SlightBlue)
            except:
                pass

        elif role == Qt.FontRole:
            try:
                if node.treeNode.checked() != Qt.Unchecked:
                    return GETFONT('Fixed', bold=True)
            except:
                pass

        return QVariant()
Example #7
0
def createPrintScene(wallet, amountString, expiresString):
   
   scene = SimplePrintableGraphicsScene(None, None)

   INCH = scene.INCH
   MARGIN = scene.MARGIN_PIXELS 
   scene.resetCursor()
   scene.drawPixmapFile(':/armory_logo_h36.png') 
   scene.newLine()
   scene.drawText('Paper Backup for Armory Wallet', GETFONT('Var', 11))
   scene.newLine()
   scene.drawText('http://www.bitcoinarmory.com')

   scene.newLine(extra_dy=20)
   scene.drawHLine()
   scene.newLine(extra_dy=20)


   ssType = ' (Unencrypted)'
   bType = tr('Single-Sheet ' + ssType)
   colRect, rowHgt = scene.drawColumn(['Wallet Version:', 'Wallet ID:', \
                                                'Wallet Name:', 'Backup Type:'])
   scene.moveCursor(15, 0)
   suf = 'c'
   colRect, rowHgt = scene.drawColumn(['1.35'+suf, wallet.uniqueIDB58, \
                                                wallet.labelName, bType])
   scene.moveCursor(15, colRect.y() + colRect.height(), absolute=True)

   # Display warning about unprotected key data
   wrap = 0.9*scene.pageRect().width()

   container = 'this wallet'
   warnMsg = tr(""" 
         <font color="#aa0000"><b>WARNING:</b></font> Anyone who has access to this 
         page has access to all the bitcoins in %s!  Please keep this 
         page in a safe place.""" % container)

   scene.newLine()
   scene.drawText(warnMsg, GETFONT('Var', 9), wrapWidth=wrap)

   scene.newLine(extra_dy=20)
   scene.drawHLine()
   scene.newLine(extra_dy=20)
   numLine = 'two'

   descrMsg = tr(""" 
      The following %s lines backup all addresses 
      <i>ever generated</i> by this wallet (previous and future).
      This can be used to recover your wallet if you forget your passphrase or 
      suffer hardware failure and lose your wallet files. """ % numLine)
   scene.drawText(descrMsg, GETFONT('var', 8), wrapWidth=wrap)
   scene.newLine(extra_dy=10)
  
   ###########################################################################
   # Finally, draw the backup information.
   bottomOfSceneHeader = scene.cursorPos.y()

   code12 = wallet.addrMap['ROOT'].binPrivKey32_Plain.toBinStr()
   Lines = []
   Prefix = [] 
   Prefix.append('Root Key:')
   Lines.append(makeSixteenBytesEasy(code12[:16]))
   Prefix.append('')
   Lines.append(makeSixteenBytesEasy(code12[16:]))
   # Draw the prefix
   origX,origY = scene.getCursorXY()
   scene.moveCursor(20,0) 
   colRect, rowHgt = scene.drawColumn(['<b>'+l+'</b>' for l in Prefix])
   
   nudgeDown = 2  # because the differing font size makes it look unaligned
   scene.moveCursor(20, nudgeDown)
   scene.drawColumn(Lines, 
                    
                           font=GETFONT('Fixed', 8, bold=True), \
                           rowHeight=rowHgt, 
                           useHtml=False)

   scene.moveCursor(MARGIN, colRect.y()-2, absolute=True)
   width = scene.pageRect().width() - 2*MARGIN
   scene.drawRect( width, colRect.height()+7, edgeColor=QColor(0,0,0), fillColor=None)

   scene.newLine(extra_dy=30)
   scene.drawText( tr("""
      The following QR code is for convenience only.  It contains the 
      exact same data as the %s lines above.  If you copy this backup 
      by hand, you can safely ignore this QR code. """ % numLine), wrapWidth=4*INCH)

   scene.moveCursor(20,0)
   x,y = scene.getCursorXY()
   edgeRgt = scene.pageRect().width() - MARGIN
   edgeBot = scene.pageRect().height() - MARGIN

   qrSize = max(1.5*INCH, min(edgeRgt - x, edgeBot - y, 2.0*INCH))
   scene.drawQR('\n'.join(Lines), qrSize)
   scene.newLine(extra_dy=25)
   scene.drawHLine(7*INCH, 5)
   scene.newLine(extra_dy=25)
   scene.drawText(tr(""" 
         <font color="#aa0000"><b>CONGRATULATIONS:</b></font> Thank you for participating
         in the MIT BitComp. You have received a Bitcoin Armory
         wallet containing %s You may collect this money by installing Bitcoin Armory
         from the website shown above. After you install the software move the funds to a new
         wallet or any address that you own. Do not deposit any bitcoins to this wallet. You
         don't know who else has access to this wallet! You have until %s to claim your bitcoins. After
         this date we will remove all remaining bitcoins from this wallet.""" %
         (amountString, expiresString)), GETFONT('Var', 11), wrapWidth=wrap)
      
   scene.newLine(extra_dy=25)
   return scene
Example #8
0
    def __init__(self, main):
        def updateDustLimit():
            try:
                self.dustTableModel.updateDustList(
                    self.getSelectedWlt(), str2coin(self.dustLimitText.text()))
                self.beGoneDustButton.setEnabled(
                    len(self.dustTableModel.dustTxOutlist) > 0)
                if self.dustTableModel.wlt:
                    self.lblHeader.setText(
                        tr("""<b>Dust Outputs for Wallet: %s</b>""" %
                           self.dustTableModel.wlt.labelName))
            except NegativeValueError:
                pass
            except TooMuchPrecisionError:
                pass
            except:
                LOGEXCEPT("Unexpected exception")
                pass

        def sendDust():
            try:
                utxiList = []
                for utxo in self.dustTableModel.dustTxOutlist:
                    # The PyCreateAndSignTx method require PyTx and PyBtcAddress objects
                    rawTx = TheBDM.getTxByHash(utxo.getTxHash()).serialize()
                    a160 = CheckHash160(utxo.getRecipientScrAddr())
                    for pyAddr in self.dustTableModel.wlt.addrMap.values():
                        if a160 == pyAddr.getAddr160():
                            pubKey = pyAddr.binPublicKey65.toBinStr()
                            txoIdx = utxo.getTxOutIndex()
                            utxiList.append(
                                UnsignedTxInput(rawTx, txoIdx, None, pubKey))
                            break
                # Make copies, destroy them in the finally clause
                privKeyMap = {}
                for addrObj in self.dustTableModel.wlt.addrMap.values():
                    scrAddr = SCRADDR_P2PKH_BYTE + addrObj.getAddr160()
                    if self.dustTableModel.wlt.useEncryption and self.dustTableModel.wlt.isLocked:
                        # Target wallet is encrypted...
                        unlockdlg = DlgUnlockWallet(self.dustTableModel.wlt,
                                                    self.main, self.main,
                                                    'Unlock Wallet to Import')
                        if not unlockdlg.exec_():
                            QMessageBox.critical(self, 'Wallet is Locked', \
                               'Cannot send dust without unlocking the wallet!', \
                               QMessageBox.Ok)
                            return
                    privKeyMap[scrAddr] = addrObj.binPrivKey32_Plain.copy()
                signedTx = PyCreateAndSignTx(
                    utxiList, [], privKeyMap,
                    SIGHASH_NONE | SIGHASH_ANYONECANPAY)

                print "-------------"
                print binary_to_hex(signedTx.serialize())

                # sock = socket.create_connection(('dust-b-gone.bitcoin.petertodd.org',80))
                # sock.send(signedTx.serialize())
                # sock.send(b'\n')
                # sock.close()

            except socket.error as err:
                QMessageBox.critical(
                    self.main, tr('Negative Value'),
                    tr("""
               Failed to connect to dust-b-gone server: %s""" % err.strerror),
                    QMessageBox.Ok)
            except NegativeValueError:
                QMessageBox.critical(
                    self.main, tr('Negative Value'),
                    tr("""
               You must enter a positive value of at least 0.0000 0001 
               and less than %s for the dust limit.""" % MAX_DUST_LIMIT_STR),
                    QMessageBox.Ok)
            except TooMuchPrecisionError:
                QMessageBox.critical(
                    self.main.main, tr('Too much precision'),
                    tr("""
               Bitcoins can only be specified down to 8 decimal places. 
               The smallest unit of a Bitcoin is 0.0000 0001 BTC. 
               Please enter a dust limit of at least 0.0000 0001 and less than %s."""
                       % MAX_DUST_LIMIT_STR), QMessageBox.Ok)
            finally:
                for scraddr in privKeyMap:
                    privKeyMap[scraddr].destroy()

        self.main = main

        self.lblHeader = QRichLabel(
            tr("""<b>Dust Outputs for Wallet: None Selected</b>"""),
            doWrap=False)
        self.beGoneDustButton = QPushButton("Remove Dust")
        self.beGoneDustButton.setEnabled(False)
        self.main.connect(self.beGoneDustButton, SIGNAL('clicked()'), sendDust)
        topRow = makeHorizFrame([self.lblHeader, 'stretch'])
        secondRow = makeHorizFrame([self.beGoneDustButton, 'stretch'])

        self.dustLimitLabel = QLabel("Max Dust Value (BTC): ")
        self.dustLimitText = QLineEdit()
        self.dustLimitText.setFont(GETFONT('Fixed'))
        self.dustLimitText.setMinimumWidth(
            tightSizeNChar(self.dustLimitText, 6)[0])
        self.dustLimitText.setMaximumWidth(
            tightSizeNChar(self.dustLimitText, 12)[0])
        self.dustLimitText.setAlignment(Qt.AlignRight)
        self.dustLimitText.setText(coin2str(DEFAULT_DUST_LIMIT))
        self.main.connect(self.dustLimitText, SIGNAL('textChanged(QString)'),
                          updateDustLimit)

        limitPanel = makeHorizFrame(
            [self.dustLimitLabel, self.dustLimitText, 'stretch'])

        self.dustTableModel = DustDisplayModel()
        self.dustTableView = QTableView()
        self.dustTableView.setModel(self.dustTableModel)
        self.dustTableView.setSelectionMode(QTableView.NoSelection)
        self.dustTableView.verticalHeader().setDefaultSectionSize(20)
        self.dustTableView.verticalHeader().hide()
        h = tightSizeNChar(self.dustTableView, 1)[1]
        self.dustTableView.setMinimumHeight(2 * (1.3 * h))
        self.dustTableView.setMaximumHeight(10 * (1.3 * h))
        initialColResize(self.dustTableView, [100, .7, .3])

        self.dustTableView.setContextMenuPolicy(Qt.CustomContextMenu)

        self.lblTxioInfo = QRichLabel('')
        self.lblTxioInfo.setMinimumWidth(
            tightSizeNChar(self.lblTxioInfo, 30)[0])

        self.main.connect(self.main.walletsView,
                          SIGNAL('clicked(QModelIndex)'), updateDustLimit)

        self.dustBGoneFrame = makeVertFrame(
            [topRow, secondRow, limitPanel, self.dustTableView, 'stretch'])

        # Now set the scrollarea widget to the layout
        self.tabToDisplay = QScrollArea()
        self.tabToDisplay.setWidgetResizable(True)
        self.tabToDisplay.setWidget(self.dustBGoneFrame)
Example #9
0
   def __init__(self, parent, main, cs_callback, get_csstate):
      super(FeeSelectionDialog, self).__init__(parent, main)
      
      #Button Label
      self.lblButtonFee = QLabelButton("")
      
      #get default values
      flatFee = self.main.getSettingOrSetDefault("Default_Fee", MIN_TX_FEE)
      flatFee = coin2str(flatFee, maxZeros=1).strip()
      fee_byte = str(self.main.getSettingOrSetDefault("Default_FeeByte", MIN_FEE_BYTE))
      blocksToConfirm = self.main.getSettingOrSetDefault(\
         "Default_FeeByte_BlocksToConfirm", NBLOCKS_TO_CONFIRM)
      
      self.coinSelectionCallback = cs_callback
      self.getCoinSelectionState = get_csstate
      self.validAutoFee = True
      try:
         autoFee_byte = str(estimateFee(blocksToConfirm) / 1000.0)
      except:
         autoFee_byte = "N/A"
         self.validAutoFee = False
         
      defaultCheckState = \
         self.main.getSettingOrSetDefault("FeeOption", DEFAULT_FEE_TYPE)
      
      #flat free
      def setFlatFee():
         def callbck():
            return self.selectType('FlatFee')
         return callbck
      
      def updateLbl():
         self.updateCoinSelection()
      
      self.radioFlatFee = QRadioButton(self.tr("Flat Fee (BTC)"))
      self.edtFeeAmt = QLineEdit(flatFee)
      self.edtFeeAmt.setFont(GETFONT('Fixed'))
      self.edtFeeAmt.setMinimumWidth(tightSizeNChar(self.edtFeeAmt, 6)[0])
      self.edtFeeAmt.setMaximumWidth(tightSizeNChar(self.edtFeeAmt, 12)[0])
      
      self.connect(self.radioFlatFee, SIGNAL('clicked()'), setFlatFee())
      self.connect(self.edtFeeAmt, SIGNAL('textChanged(QString)'), updateLbl)
      
      frmFlatFee = QFrame()
      frmFlatFee.setFrameStyle(STYLE_RAISED)
      layoutFlatFee = QGridLayout()
      layoutFlatFee.addWidget(self.radioFlatFee, 0, 0, 1, 1)
      layoutFlatFee.addWidget(self.edtFeeAmt, 0, 1, 1, 1)
      frmFlatFee.setLayout(layoutFlatFee)
      
      #fee/byte
      def setFeeByte():
         def callbck():
            return self.selectType('FeeByte')
         return callbck
      
      self.radioFeeByte = QRadioButton(self.tr("Fee/Byte (Satoshi/Byte)"))
      self.edtFeeByte = QLineEdit(fee_byte)
      self.edtFeeByte.setFont(GETFONT('Fixed'))
      self.edtFeeByte.setMinimumWidth(tightSizeNChar(self.edtFeeByte, 6)[0])
      self.edtFeeByte.setMaximumWidth(tightSizeNChar(self.edtFeeByte, 12)[0])
      
      self.connect(self.radioFeeByte, SIGNAL('clicked()'), setFeeByte())
      self.connect(self.edtFeeByte, SIGNAL('textChanged(QString)'), updateLbl)
            
      frmFeeByte = QFrame()
      frmFeeByte.setFrameStyle(STYLE_RAISED)
      layoutFeeByte = QGridLayout()
      layoutFeeByte.addWidget(self.radioFeeByte, 0, 0, 1, 1)
      layoutFeeByte.addWidget(self.edtFeeByte, 0, 1, 1, 1)
      frmFeeByte.setLayout(layoutFeeByte)
      
      #auto fee/byte
      def setAutoFeeByte():
         def callbck():
            return self.selectType('Auto')
         return callbck      
      
      radioButtonTxt = self.tr("Fee rate from node (sat/Byte): ")
      if not self.validAutoFee:      
         radioButtonTxt = self.tr("Failed to fetch fee/byte from node")
         
      self.radioAutoFeeByte = QRadioButton(radioButtonTxt)
      self.lblAutoFeeByte = QLabel(autoFee_byte)
      self.lblAutoFeeByte.setFont(GETFONT('Fixed'))
      self.lblAutoFeeByte.setMinimumWidth(tightSizeNChar(self.lblAutoFeeByte, 6)[0])
      self.lblAutoFeeByte.setMaximumWidth(tightSizeNChar(self.lblAutoFeeByte, 12)[0])
      
      self.sliderAutoFeeByte = QSlider(Qt.Horizontal, self)
      self.sliderAutoFeeByte.setMinimum(2)
      self.sliderAutoFeeByte.setMaximum(6)
      self.sliderAutoFeeByte.setValue(blocksToConfirm)
      self.lblSlider = QLabel()
      
      def getSliderLabelTxt():
         return self.tr("Blocks to confirm: %1").arg(\
               unicode(self.sliderAutoFeeByte.value()))
         
      def updateAutoFeeByte():
         blocksToConfirm = self.sliderAutoFeeByte.value()
         try:
            autoFee_byte = str(estimateFee(blocksToConfirm) / 1000.0)

         except:
            autoFee_byte = "N/A"
         
         self.lblSlider.setText(getSliderLabelTxt())         
         self.lblAutoFeeByte.setText(autoFee_byte)
         updateLbl()
         
      self.lblSlider.setText(getSliderLabelTxt())
      
      self.connect(self.radioAutoFeeByte, SIGNAL('clicked()'), setAutoFeeByte())
      self.sliderAutoFeeByte.valueChanged.connect(updateAutoFeeByte)
      self.sliderAutoFeeByte.setEnabled(False)
            
      frmAutoFeeByte = QFrame()
      frmAutoFeeByte.setFrameStyle(STYLE_RAISED)
      layoutAutoFeeByte = QGridLayout()
      layoutAutoFeeByte.addWidget(self.radioAutoFeeByte, 0, 0, 1, 1)
      layoutAutoFeeByte.addWidget(self.lblAutoFeeByte, 0, 1, 1, 1)  
      layoutAutoFeeByte.addWidget(self.lblSlider, 1, 0, 1, 2)
      layoutAutoFeeByte.addWidget(self.sliderAutoFeeByte, 2, 0, 1, 2)
      frmAutoFeeByte.setLayout(layoutAutoFeeByte)
      
      if not self.validAutoFee:
         frmAutoFeeByte.setEnabled(False)
      
      #adjust and close
      self.btnClose = QPushButton(self.tr('Close'))
      self.connect(self.btnClose, SIGNAL('clicked()'), self.accept)
      
      self.checkBoxAdjust = QCheckBox(self.tr('Adjust fee/byte for privacy'))
      self.checkBoxAdjust.setChecked(\
         self.main.getSettingOrSetDefault('AdjustFee', True))
            
      self.connect(self.checkBoxAdjust, SIGNAL('clicked()'), updateLbl)
      
      frmClose = makeHorizFrame(\
         [self.checkBoxAdjust, 'Stretch', self.btnClose], STYLE_NONE)
      
      #main layout
      layout = QGridLayout()
      layout.addWidget(frmAutoFeeByte, 0, 0, 1, 4)
      layout.addWidget(frmFeeByte, 2, 0, 1, 4)
      layout.addWidget(frmFlatFee, 4, 0, 1, 4)
      layout.addWidget(frmClose, 5, 0, 1, 4)
      
      self.setLayout(layout)      
      self.setWindowTitle(self.tr('Select Fee Type'))
      
      self.selectType(defaultCheckState)

      self.setFocus()  
Example #10
0
    def __init__(self, parent, main, cs_callback, get_csstate):
        super(FeeSelectionDialog, self).__init__(parent, main)

        #Button Label
        self.lblButtonFee = QLabelButton("")

        #get default values
        flatFee = self.main.getSettingOrSetDefault("Default_Fee", MIN_TX_FEE)
        flatFee = coin2str(flatFee, maxZeros=1).strip()
        fee_byte = str(
            self.main.getSettingOrSetDefault("Default_FeeByte", MIN_FEE_BYTE))
        blocksToConfirm = self.main.getSettingOrSetDefault(\
           "Default_FeeByte_BlocksToConfirm", NBLOCKS_TO_CONFIRM)
        feeStrategy = str(self.main.getSettingOrSetDefault(\
           "Default_FeeByte_Strategy", FEEBYTE_CONSERVATIVE))

        self.coinSelectionCallback = cs_callback
        self.getCoinSelectionState = get_csstate
        self.validAutoFee = True

        isSmartFee = True
        try:
            feeEstimate, isSmartFee, errorMsg = self.getFeeByteFromNode(
                blocksToConfirm, feeStrategy)
        except:
            feeEstimate = "N/A"
            self.validAutoFee = False

        defaultCheckState = \
           self.main.getSettingOrSetDefault("FeeOption", DEFAULT_FEE_TYPE)

        #flat free
        def setFlatFee():
            def callbck():
                return self.selectType('FlatFee')

            return callbck

        def updateLbl():
            self.updateCoinSelection()

        self.radioFlatFee = QRadioButton(self.tr("Flat Fee (BTC)"))
        self.edtFeeAmt = QLineEdit(flatFee)
        self.edtFeeAmt.setFont(GETFONT('Fixed'))
        self.edtFeeAmt.setMinimumWidth(tightSizeNChar(self.edtFeeAmt, 6)[0])
        self.edtFeeAmt.setMaximumWidth(tightSizeNChar(self.edtFeeAmt, 12)[0])

        self.connect(self.radioFlatFee, SIGNAL('clicked()'), setFlatFee())
        self.connect(self.edtFeeAmt, SIGNAL('textChanged(QString)'), updateLbl)

        frmFlatFee = QFrame()
        frmFlatFee.setFrameStyle(STYLE_RAISED)
        layoutFlatFee = QGridLayout()
        layoutFlatFee.addWidget(self.radioFlatFee, 0, 0, 1, 1)
        layoutFlatFee.addWidget(self.edtFeeAmt, 0, 1, 1, 1)
        frmFlatFee.setLayout(layoutFlatFee)

        #fee/byte
        def setFeeByte():
            def callbck():
                return self.selectType('FeeByte')

            return callbck

        self.radioFeeByte = QRadioButton(self.tr("Fee/Byte (Satoshi/Byte)"))
        self.edtFeeByte = QLineEdit(fee_byte)
        self.edtFeeByte.setFont(GETFONT('Fixed'))
        self.edtFeeByte.setMinimumWidth(tightSizeNChar(self.edtFeeByte, 6)[0])
        self.edtFeeByte.setMaximumWidth(tightSizeNChar(self.edtFeeByte, 12)[0])

        self.connect(self.radioFeeByte, SIGNAL('clicked()'), setFeeByte())
        self.connect(self.edtFeeByte, SIGNAL('textChanged(QString)'),
                     updateLbl)

        frmFeeByte = QFrame()
        frmFeeByte.setFrameStyle(STYLE_RAISED)
        layoutFeeByte = QGridLayout()
        layoutFeeByte.addWidget(self.radioFeeByte, 0, 0, 1, 1)
        layoutFeeByte.addWidget(self.edtFeeByte, 0, 1, 1, 1)
        frmFeeByte.setLayout(layoutFeeByte)

        #auto fee/byte
        if isSmartFee:
            frmAutoFeeByte = self.setupSmartAutoFeeByteUI(\
               feeEstimate, blocksToConfirm, feeStrategy)
        else:
            frmAutoFeeByte = self.setupLegacyAutoFeeByteUI(\
               feeEstimate, blocksToConfirm)

        #adjust and close
        self.btnClose = QPushButton(self.tr('Close'))
        self.connect(self.btnClose, SIGNAL('clicked()'), self.accept)

        self.checkBoxAdjust = QCheckBox(self.tr('Adjust fee/byte for privacy'))
        self.checkBoxAdjust.setChecked(\
           self.main.getSettingOrSetDefault('AdjustFee', True))

        self.connect(self.checkBoxAdjust, SIGNAL('clicked()'), updateLbl)

        frmClose = makeHorizFrame(\
           [self.checkBoxAdjust, 'Stretch', self.btnClose], STYLE_NONE)

        #main layout
        layout = QGridLayout()
        layout.addWidget(frmAutoFeeByte, 0, 0, 1, 4)
        layout.addWidget(frmFeeByte, 2, 0, 1, 4)
        layout.addWidget(frmFlatFee, 4, 0, 1, 4)
        layout.addWidget(frmClose, 5, 0, 1, 4)

        self.setLayout(layout)
        self.setWindowTitle(self.tr('Select Fee Type'))

        self.selectType(defaultCheckState)

        self.setFocus()
Example #11
0
    def setupSmartAutoFeeByteUI(self, feeEstimate, blocksToConfirm, strat):
        def setAutoFeeByte():
            def callbck():
                return self.selectType('Auto')

            return callbck

        stratList = [FEEBYTE_CONSERVATIVE, FEEBYTE_ECONOMICAL]

        def updateLbl():
            self.updateCoinSelection()

        def getStrategyString():
            try:
                cbIndex = self.comboStrat.currentIndex()
                return stratList[cbIndex]
            except:
                return FEEBYTE_CONSERVATIVE

        def feeByteToStr(feeByte):
            try:
                self.feeByte = feeByte
                return "<u>%.1f</u>" % feeByte
            except:
                self.feeByte = -1
                if isinstance(feeByte, str):
                    return feeByte
                else:
                    return "N/A"

        radioButtonTxt = self.tr("Fee rate from node (sat/Byte): ")
        if not self.validAutoFee:
            radioButtonTxt = self.tr("Failed to fetch fee/byte from node")

        self.radioAutoFeeByte = QRadioButton(radioButtonTxt)
        self.lblAutoFeeByte = QLabel(feeByteToStr(feeEstimate))
        self.lblAutoFeeByte.setFont(GETFONT('Fixed'))
        self.lblAutoFeeByte.setMinimumWidth(
            tightSizeNChar(self.lblAutoFeeByte, 6)[0])
        self.lblAutoFeeByte.setMaximumWidth(
            tightSizeNChar(self.lblAutoFeeByte, 12)[0])

        self.sliderAutoFeeByte = QSlider(Qt.Horizontal, self)
        self.sliderAutoFeeByte.setMinimum(2)
        self.sliderAutoFeeByte.setMaximum(100)
        self.sliderAutoFeeByte.setValue(blocksToConfirm)
        self.lblSlider = QLabel()

        self.lblStrat = QLabel(self.tr("Profile:"))
        self.ttStart = self.main.createToolTipWidget(
            self.tr('''
         <u>Fee Estimation Profiles:</u><br><br>
         <b>CONSERVATIVE:</b> Short term estimate. More reactive to current 
         changes in the mempool. Use this estimate if you want a high probability 
         of getting your transaction mined quickly. <br><br>
         <b>ECONOMICAL:</b> Long term estimate. Ignores short term changes to the 
         mempool. Use this profile if you want low fees and can tolerate swings 
         in the projected confirmation window. <br><br>

         The estimate profiles may not diverge until your node has gathered 
         enough data from the network to refine its predictions. Refer to the
         \"estimatesmartfee\" section in the Bitcoin Core 0.15 changelog for more
         informations.
         '''))
        self.comboStrat = QComboBox()
        currentIndex = 0
        for i in range(len(stratList)):
            self.comboStrat.addItem(stratList[i])
            if stratList[i] == strat:
                currentIndex = i
        self.comboStrat.setCurrentIndex(currentIndex)

        def getSliderLabelTxt():
            return self.tr("Blocks to confirm: %1").arg(\
                  unicode(self.sliderAutoFeeByte.value()))

        def updateAutoFeeByte():
            blocksToConfirm = self.sliderAutoFeeByte.value()
            strategy = getStrategyString()
            try:
                feeEstimate, version, err = \
                   self.getFeeByteFromNode(blocksToConfirm, strategy)
            except:
                feeEstimate = "N/A"

            self.lblSlider.setText(getSliderLabelTxt())
            self.lblAutoFeeByte.setText(feeByteToStr(feeEstimate))
            updateLbl()

        def stratComboChange():
            updateAutoFeeByte()

        self.lblSlider.setText(getSliderLabelTxt())

        self.connect(self.radioAutoFeeByte, SIGNAL('clicked()'),
                     setAutoFeeByte())
        self.sliderAutoFeeByte.valueChanged.connect(updateAutoFeeByte)
        self.sliderAutoFeeByte.setEnabled(False)

        self.connect(self.comboStrat, SIGNAL('currentIndexChanged(int)'),
                     stratComboChange)

        frmAutoFeeByte = QFrame()
        frmAutoFeeByte.setFrameStyle(STYLE_RAISED)
        layoutAutoFeeByte = QGridLayout()
        layoutAutoFeeByte.addWidget(self.radioAutoFeeByte, 0, 0, 1, 2)
        layoutAutoFeeByte.addWidget(self.lblAutoFeeByte, 0, 2, 1, 2)
        layoutAutoFeeByte.addWidget(self.lblSlider, 1, 0, 1, 1)
        layoutAutoFeeByte.addWidget(self.sliderAutoFeeByte, 2, 0, 1, 4)
        layoutAutoFeeByte.addWidget(self.lblStrat, 3, 0, 1, 1)
        layoutAutoFeeByte.addWidget(self.comboStrat, 3, 1, 1, 2)
        layoutAutoFeeByte.addWidget(self.ttStart, 3, 3, 1, 1)

        frmAutoFeeByte.setLayout(layoutAutoFeeByte)

        if not self.validAutoFee:
            frmAutoFeeByte.setEnabled(False)

        return frmAutoFeeByte
Example #12
0
    def setupLegacyAutoFeeByteUI(self, feeEstimate, blocksToConfirm):
        def setAutoFeeByte():
            def callbck():
                return self.selectType('Auto')

            return callbck

        def updateLbl():
            self.updateCoinSelection()

        def feeByteToStr(feeByte):
            try:
                self.feeByte = feeByte
                return "<u>%.1f</u>" % feeByte
            except:
                self.feeByte = -1
                if isinstance(feeByte, str):
                    return feeByte
                else:
                    return "N/A"

        radioButtonTxt = self.tr("Fee rate from node (sat/Byte): ")
        if not self.validAutoFee:
            radioButtonTxt = self.tr("Failed to fetch fee/byte from node")

        self.radioAutoFeeByte = QRadioButton(radioButtonTxt)
        self.lblAutoFeeByte = QLabel(feeByteToStr(feeEstimate))
        self.lblAutoFeeByte.setFont(GETFONT('Fixed'))
        self.lblAutoFeeByte.setMinimumWidth(
            tightSizeNChar(self.lblAutoFeeByte, 6)[0])
        self.lblAutoFeeByte.setMaximumWidth(
            tightSizeNChar(self.lblAutoFeeByte, 12)[0])

        self.sliderAutoFeeByte = QSlider(Qt.Horizontal, self)
        self.sliderAutoFeeByte.setMinimum(2)
        self.sliderAutoFeeByte.setMaximum(6)
        self.sliderAutoFeeByte.setValue(blocksToConfirm)
        self.lblSlider = QLabel()

        def getSliderLabelTxt():
            return self.tr("Blocks to confirm: %1").arg(\
               unicode(self.sliderAutoFeeByte.value()))

        def updateAutoFeeByte():
            blocksToConfirm = self.sliderAutoFeeByte.value()
            try:
                feeEstimate, version, err = \
                   self.getFeeByteFromNode(blocksToConfirm, FEEBYTE_CONSERVATIVE)
            except:
                feeEstimate = "N/A"

            self.lblSlider.setText(getSliderLabelTxt())
            self.lblAutoFeeByte.setText(feeByteToStr(feeEstimate))
            updateLbl()

        self.lblSlider.setText(getSliderLabelTxt())

        self.connect(self.radioAutoFeeByte, SIGNAL('clicked()'),
                     setAutoFeeByte())
        self.sliderAutoFeeByte.valueChanged.connect(updateAutoFeeByte)
        self.sliderAutoFeeByte.setEnabled(False)

        frmAutoFeeByte = QFrame()
        frmAutoFeeByte.setFrameStyle(STYLE_RAISED)
        layoutAutoFeeByte = QGridLayout()
        layoutAutoFeeByte.addWidget(self.radioAutoFeeByte, 0, 0, 1, 1)
        layoutAutoFeeByte.addWidget(self.lblAutoFeeByte, 0, 1, 1, 1)
        layoutAutoFeeByte.addWidget(self.lblSlider, 1, 0, 1, 2)
        layoutAutoFeeByte.addWidget(self.sliderAutoFeeByte, 2, 0, 1, 2)
        frmAutoFeeByte.setLayout(layoutAutoFeeByte)

        if not self.validAutoFee:
            frmAutoFeeByte.setEnabled(False)

        return frmAutoFeeByte