qml: show 2FA status and billing info in WalletDetails, expose billing schedule setting in config
This commit is contained in:
@@ -163,13 +163,86 @@ Pane {
|
||||
}
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
visible: Daemon.currentWallet && Daemon.currentWallet.walletType == '2fa'
|
||||
Layout.preferredWidth: parent.width
|
||||
|
||||
columns: 2
|
||||
|
||||
Label {
|
||||
text: qsTr('2FA')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: Daemon.currentWallet.canSignWithoutServer
|
||||
? qsTr('disabled (can sign without server')
|
||||
: qsTr('enabled')
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: !Daemon.currentWallet.canSignWithoutServer
|
||||
text: qsTr('Remaining TX')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
visible: !Daemon.currentWallet.canSignWithoutServer
|
||||
text: 'tx_remaining' in Daemon.currentWallet.billingInfo
|
||||
? Daemon.currentWallet.billingInfo['tx_remaining']
|
||||
: qsTr('unknown')
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.columnSpan: 2
|
||||
visible: !Daemon.currentWallet.canSignWithoutServer
|
||||
text: qsTr('Billing')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.columnSpan: 2
|
||||
Layout.leftMargin: constants.paddingMedium
|
||||
spacing: 0
|
||||
|
||||
ButtonGroup {
|
||||
id: billinggroup
|
||||
onCheckedButtonChanged: {
|
||||
Config.trustedcoinPrepay = checkedButton.value
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: AppController.plugin('trustedcoin').billingModel
|
||||
delegate: RowLayout {
|
||||
RadioButton {
|
||||
ButtonGroup.group: billinggroup
|
||||
property string value: modelData.value
|
||||
text: modelData.text
|
||||
checked: modelData.value == Config.trustedcoinPrepay
|
||||
}
|
||||
Label {
|
||||
text: Config.formatSats(modelData.sats_per_tx)
|
||||
font.family: FixedFont
|
||||
}
|
||||
Label {
|
||||
text: Config.baseUnit + '/tx'
|
||||
color: Material.accentColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
id: detailsLayout
|
||||
visible: Daemon.currentWallet
|
||||
Layout.preferredWidth: parent.width
|
||||
|
||||
columns: 2
|
||||
|
||||
Label {
|
||||
text: qsTr('Derivation prefix')
|
||||
visible: Daemon.currentWallet.isDeterministic
|
||||
|
||||
@@ -166,6 +166,17 @@ class QEConfig(AuthMixin, QObject):
|
||||
self.config.set_key('use_recoverable_channels', useRecoverableChannels)
|
||||
self.useRecoverableChannelsChanged.emit()
|
||||
|
||||
trustedcoinPrepayChanged = pyqtSignal()
|
||||
@pyqtProperty(int, notify=trustedcoinPrepayChanged)
|
||||
def trustedcoinPrepay(self):
|
||||
return self.config.get('trustedcoin_prepay', 20)
|
||||
|
||||
@trustedcoinPrepay.setter
|
||||
def trustedcoinPrepay(self, num_prepay):
|
||||
if num_prepay != self.config.get('trustedcoin_prepay', 20):
|
||||
self.config.set_key('trustedcoin_prepay', num_prepay)
|
||||
self.trustedcoinPrepayChanged.emit()
|
||||
|
||||
@pyqtSlot('qint64', result=str)
|
||||
@pyqtSlot('qint64', bool, result=str)
|
||||
@pyqtSlot(QEAmount, result=str)
|
||||
|
||||
@@ -301,6 +301,11 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
||||
def isLightning(self):
|
||||
return bool(self.wallet.lnworker)
|
||||
|
||||
billingInfoChanged = pyqtSignal()
|
||||
@pyqtProperty('QVariantMap', notify=billingInfoChanged)
|
||||
def billingInfo(self):
|
||||
return {} if self.wallet.wallet_type != '2fa' else self.wallet.billing_info
|
||||
|
||||
@pyqtProperty(bool, notify=dataChanged)
|
||||
def canHaveLightning(self):
|
||||
return self.wallet.can_have_lightning()
|
||||
@@ -349,6 +354,10 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
||||
def masterPubkey(self):
|
||||
return self.wallet.get_master_public_key()
|
||||
|
||||
@pyqtProperty(bool, notify=dataChanged)
|
||||
def canSignWithoutServer(self):
|
||||
return self.wallet.can_sign_without_server() if self.wallet.wallet_type == '2fa' else True
|
||||
|
||||
balanceChanged = pyqtSignal()
|
||||
|
||||
@pyqtProperty(QEAmount, notify=balanceChanged)
|
||||
|
||||
@@ -39,6 +39,8 @@ class Plugin(TrustedCoinPlugin):
|
||||
_otpSecret = ''
|
||||
shortIdChanged = pyqtSignal()
|
||||
_shortId = ''
|
||||
billingModelChanged = pyqtSignal()
|
||||
_billingModel = []
|
||||
|
||||
_remoteKeyState = ''
|
||||
remoteKeyStateChanged = pyqtSignal()
|
||||
@@ -91,6 +93,27 @@ class Plugin(TrustedCoinPlugin):
|
||||
self._remoteKeyState = new_state
|
||||
self.remoteKeyStateChanged.emit()
|
||||
|
||||
@pyqtProperty('QVariantList', notify=billingModelChanged)
|
||||
def billingModel(self):
|
||||
return self._billingModel
|
||||
|
||||
def updateBillingInfo(self, wallet):
|
||||
billingModel = []
|
||||
|
||||
price_per_tx = wallet.price_per_tx
|
||||
for k, v in sorted(price_per_tx.items()):
|
||||
if k == 1:
|
||||
continue
|
||||
item = {
|
||||
'text': 'Pay every %d transactions' % k,
|
||||
'value': k,
|
||||
'sats_per_tx': v/k
|
||||
}
|
||||
billingModel.append(item)
|
||||
|
||||
self._billingModel = billingModel
|
||||
self.billingModelChanged.emit()
|
||||
|
||||
@pyqtSlot()
|
||||
def fetchTermsAndConditions(self):
|
||||
def fetch_task():
|
||||
@@ -274,6 +297,8 @@ class Plugin(TrustedCoinPlugin):
|
||||
# extend wizard
|
||||
self.extend_wizard()
|
||||
|
||||
# wizard support functions
|
||||
|
||||
def extend_wizard(self):
|
||||
wizard = self._app.daemon.newWalletWizard
|
||||
self.logger.debug(repr(wizard))
|
||||
@@ -367,7 +392,7 @@ class Plugin(TrustedCoinPlugin):
|
||||
wizard_data['x3/'] = k3.dump()
|
||||
|
||||
|
||||
# regular wallet prompt functions
|
||||
# running wallet functions
|
||||
|
||||
def prompt_user_for_otp(self, wallet, tx, on_success, on_failure):
|
||||
self.logger.debug('prompt_user_for_otp')
|
||||
@@ -379,7 +404,12 @@ class Plugin(TrustedCoinPlugin):
|
||||
qewallet.request_otp(self.on_otp)
|
||||
|
||||
def on_otp(self, otp):
|
||||
if not otp:
|
||||
self.on_failure(_('No auth code'))
|
||||
return
|
||||
|
||||
self.logger.debug(f'on_otp {otp} for tx {repr(self.tx)}')
|
||||
|
||||
try:
|
||||
self.wallet.on_otp(self.tx, otp)
|
||||
except UserFacingException as e:
|
||||
@@ -388,8 +418,15 @@ class Plugin(TrustedCoinPlugin):
|
||||
if e.status_code == 400: # invalid OTP
|
||||
self.on_failure(_('Invalid one-time password.'))
|
||||
else:
|
||||
self.on_failure(_('Error') + ':\n' + str(e))
|
||||
self.on_failure(_('Service Error') + ':\n' + str(e))
|
||||
except Exception as e:
|
||||
self.on_failure(_('Error') + ':\n' + str(e))
|
||||
else:
|
||||
self.on_success(self.tx)
|
||||
|
||||
def billing_info_retrieved(self, wallet):
|
||||
self.logger.info('billing_info_retrieved')
|
||||
qewallet = QEWallet.getInstanceFor(wallet)
|
||||
qewallet.billingInfoChanged.emit()
|
||||
self.so.updateBillingInfo(wallet)
|
||||
|
||||
|
||||
@@ -519,8 +519,13 @@ class TrustedCoinPlugin(BasePlugin):
|
||||
wallet.billing_info = billing_info
|
||||
wallet.price_per_tx = dict(billing_info['price_per_tx'])
|
||||
wallet.price_per_tx.pop(1, None)
|
||||
self.billing_info_retrieved(wallet)
|
||||
return True
|
||||
|
||||
def billing_info_retrieved(self, wallet):
|
||||
# override to handle billing info when it becomes available
|
||||
pass
|
||||
|
||||
def start_request_thread(self, wallet):
|
||||
from threading import Thread
|
||||
if self.requesting is False:
|
||||
|
||||
Reference in New Issue
Block a user