mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-24 23:18:17 +01:00
Add wallet info view with balance, xpub keys,
hd paths and button to open wallet details
This commit is contained in:
parent
810c0da0f9
commit
149b52859a
6 changed files with 245 additions and 9 deletions
|
@ -1042,7 +1042,7 @@ funds.tx.noTxAvailable=No transactions available
|
|||
funds.tx.revert=Revert
|
||||
funds.tx.txSent=Transaction successfully sent to a new address in the local Bisq wallet.
|
||||
funds.tx.direction.self=Sent to yourself
|
||||
funds.tx.daoTxFee=Miner fee for DAO tx
|
||||
funds.tx.daoTxFee=Miner fee for BSQ tx
|
||||
funds.tx.reimbursementRequestTxFee=Reimbursement request
|
||||
funds.tx.compensationRequestTxFee=Compensation request
|
||||
funds.tx.dustAttackTx=Received dust
|
||||
|
@ -1390,9 +1390,26 @@ account.menu.paymentAccount=National currency accounts
|
|||
account.menu.altCoinsAccountView=Altcoin accounts
|
||||
account.menu.password=Wallet password
|
||||
account.menu.seedWords=Wallet seed
|
||||
account.menu.walletInfo=Wallet info
|
||||
account.menu.backup=Backup
|
||||
account.menu.notifications=Notifications
|
||||
|
||||
account.menu.walletInfo.balance.headLine=Wallet balances
|
||||
account.menu.walletInfo.balance.info=This shows the internal wallet balance including unconfirmed transactions.\n\
|
||||
For Bitcoin the sum of the 'available balance' and the 'reserved for offers balance' must match the internal wallet balance \
|
||||
displayed here.
|
||||
account.menu.walletInfo.xpub.headLine=Watch keys (xpub keys)
|
||||
account.menu.walletInfo.walletSelector={0} {1} wallet
|
||||
account.menu.walletInfo.path.headLine=HD keychain paths
|
||||
account.menu.walletInfo.path.info=If you import the seed words in another wallet (like Electrum) you need to define the \
|
||||
path. Use that only in emergency cases when you lost access to the Bisq wallet and the data directory.\n\
|
||||
Spending funds from another wallet can easily screw up the Bisq internal data structures associated with the wallet \
|
||||
data and can lead to failed trades.\n\
|
||||
Do NEVER send BSQ from another wallet as that lead very likely to an invalid BSQ transaction and your \
|
||||
BSQ get burned.
|
||||
|
||||
account.menu.walletInfo.openDetails=Show raw wallet details and private keys
|
||||
|
||||
## TODO should we rename the following to a gereric name?
|
||||
account.arbitratorRegistration.pubKey=Public key
|
||||
|
||||
|
|
|
@ -44,7 +44,12 @@
|
|||
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"/>
|
||||
</Tab>
|
||||
<Tab fx:id="passwordTab" closable="false"/>
|
||||
<Tab fx:id="seedwordsTab" closable="false">
|
||||
<Tab fx:id="seedWordsTab" closable="false">
|
||||
<ScrollPane fitToWidth="true" hbarPolicy="NEVER"
|
||||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
||||
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"/>
|
||||
</Tab>
|
||||
<Tab fx:id="walletInfoTab" closable="false">
|
||||
<ScrollPane fitToWidth="true" hbarPolicy="NEVER"
|
||||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
||||
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"/>
|
||||
|
|
|
@ -30,6 +30,7 @@ import bisq.desktop.main.account.content.fiataccounts.FiatAccountsView;
|
|||
import bisq.desktop.main.account.content.notifications.MobileNotificationsView;
|
||||
import bisq.desktop.main.account.content.password.PasswordView;
|
||||
import bisq.desktop.main.account.content.seedwords.SeedWordsView;
|
||||
import bisq.desktop.main.account.content.walletinfo.WalletInfoView;
|
||||
import bisq.desktop.main.account.register.arbitrator.ArbitratorRegistrationView;
|
||||
import bisq.desktop.main.account.register.mediator.MediatorRegistrationView;
|
||||
import bisq.desktop.main.account.register.refundagent.RefundAgentRegistrationView;
|
||||
|
@ -67,7 +68,7 @@ public class AccountView extends ActivatableView<TabPane, Void> {
|
|||
|
||||
@FXML
|
||||
Tab fiatAccountsTab, altcoinAccountsTab, notificationTab,
|
||||
passwordTab, seedwordsTab, backupTab;
|
||||
passwordTab, seedWordsTab, walletInfoTab, backupTab;
|
||||
|
||||
private Navigation.Listener navigationListener;
|
||||
private ChangeListener<Tab> tabChangeListener;
|
||||
|
@ -101,7 +102,8 @@ public class AccountView extends ActivatableView<TabPane, Void> {
|
|||
altcoinAccountsTab.setText(Res.get("account.menu.altCoinsAccountView").toUpperCase());
|
||||
notificationTab.setText(Res.get("account.menu.notifications").toUpperCase());
|
||||
passwordTab.setText(Res.get("account.menu.password").toUpperCase());
|
||||
seedwordsTab.setText(Res.get("account.menu.seedWords").toUpperCase());
|
||||
seedWordsTab.setText(Res.get("account.menu.seedWords").toUpperCase());
|
||||
walletInfoTab.setText(Res.get("account.menu.walletInfo").toUpperCase());
|
||||
backupTab.setText(Res.get("account.menu.backup").toUpperCase());
|
||||
|
||||
navigationListener = viewPath -> {
|
||||
|
@ -161,8 +163,10 @@ public class AccountView extends ActivatableView<TabPane, Void> {
|
|||
navigation.navigateTo(MainView.class, AccountView.class, MobileNotificationsView.class);
|
||||
} else if (newValue == passwordTab && selectedTab != passwordTab) {
|
||||
navigation.navigateTo(MainView.class, AccountView.class, PasswordView.class);
|
||||
} else if (newValue == seedwordsTab && selectedTab != seedwordsTab) {
|
||||
} else if (newValue == seedWordsTab && selectedTab != seedWordsTab) {
|
||||
navigation.navigateTo(MainView.class, AccountView.class, SeedWordsView.class);
|
||||
} else if (newValue == walletInfoTab && selectedTab != walletInfoTab) {
|
||||
navigation.navigateTo(MainView.class, AccountView.class, WalletInfoView.class);
|
||||
} else if (newValue == backupTab && selectedTab != backupTab) {
|
||||
navigation.navigateTo(MainView.class, AccountView.class, BackupView.class);
|
||||
}
|
||||
|
@ -251,8 +255,10 @@ public class AccountView extends ActivatableView<TabPane, Void> {
|
|||
navigation.navigateTo(MainView.class, AccountView.class, MobileNotificationsView.class);
|
||||
else if (root.getSelectionModel().getSelectedItem() == passwordTab)
|
||||
navigation.navigateTo(MainView.class, AccountView.class, PasswordView.class);
|
||||
else if (root.getSelectionModel().getSelectedItem() == seedwordsTab)
|
||||
else if (root.getSelectionModel().getSelectedItem() == seedWordsTab)
|
||||
navigation.navigateTo(MainView.class, AccountView.class, SeedWordsView.class);
|
||||
else if (root.getSelectionModel().getSelectedItem() == walletInfoTab)
|
||||
navigation.navigateTo(MainView.class, AccountView.class, WalletInfoView.class);
|
||||
else if (root.getSelectionModel().getSelectedItem() == backupTab)
|
||||
navigation.navigateTo(MainView.class, AccountView.class, BackupView.class);
|
||||
else
|
||||
|
@ -314,7 +320,9 @@ public class AccountView extends ActivatableView<TabPane, Void> {
|
|||
} else if (view instanceof PasswordView) {
|
||||
selectedTab = passwordTab;
|
||||
} else if (view instanceof SeedWordsView) {
|
||||
selectedTab = seedwordsTab;
|
||||
selectedTab = seedWordsTab;
|
||||
} else if (view instanceof WalletInfoView) {
|
||||
selectedTab = walletInfoTab;
|
||||
} else if (view instanceof BackupView) {
|
||||
selectedTab = backupTab;
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
~ This file is part of Bisq.
|
||||
~
|
||||
~ Bisq is free software: you can redistribute it and/or modify it
|
||||
~ under the terms of the GNU Affero General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or (at
|
||||
~ your option) any later version.
|
||||
~
|
||||
~ Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
~ License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Affero General Public License
|
||||
~ along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<GridPane fx:id="root" fx:controller="bisq.desktop.main.account.content.walletinfo.WalletInfoView"
|
||||
hgap="5.0" vgap="5.0"
|
||||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
||||
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
<padding>
|
||||
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0"/>
|
||||
</padding>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="ALWAYS"/>
|
||||
</columnConstraints>
|
||||
|
||||
</GridPane>
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.main.account.content.walletinfo;
|
||||
|
||||
import bisq.desktop.common.view.ActivatableView;
|
||||
import bisq.desktop.common.view.FxmlView;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.main.overlays.windows.ShowWalletDataWindow;
|
||||
import bisq.desktop.util.Layout;
|
||||
|
||||
import bisq.core.btc.listeners.BalanceListener;
|
||||
import bisq.core.btc.wallet.BsqWalletService;
|
||||
import bisq.core.btc.wallet.BtcWalletService;
|
||||
import bisq.core.btc.wallet.WalletService;
|
||||
import bisq.core.btc.wallet.WalletsManager;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.util.FormattingUtils;
|
||||
import bisq.core.util.coin.BsqFormatter;
|
||||
import bisq.core.util.coin.CoinFormatter;
|
||||
|
||||
import bisq.common.config.Config;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.bitcoinj.wallet.DeterministicKeyChain;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.GridPane;
|
||||
|
||||
import static bisq.desktop.util.FormBuilder.addButtonAfterGroup;
|
||||
import static bisq.desktop.util.FormBuilder.addMultilineLabel;
|
||||
import static bisq.desktop.util.FormBuilder.addTitledGroupBg;
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
|
||||
import static org.bitcoinj.wallet.Wallet.BalanceType.ESTIMATED_SPENDABLE;
|
||||
|
||||
@FxmlView
|
||||
public class WalletInfoView extends ActivatableView<GridPane, Void> {
|
||||
|
||||
private final WalletsManager walletsManager;
|
||||
private final BtcWalletService btcWalletService;
|
||||
private final BsqWalletService bsqWalletService;
|
||||
private final CoinFormatter btcFormatter;
|
||||
private final BsqFormatter bsqFormatter;
|
||||
private int gridRow = 0;
|
||||
private Button openDetailsButton;
|
||||
private TextField btcTextField, bsqTextField;
|
||||
private BalanceListener btcWalletBalanceListener;
|
||||
private BalanceListener bsqWalletBalanceListener;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
private WalletInfoView(WalletsManager walletsManager,
|
||||
BtcWalletService btcWalletService,
|
||||
BsqWalletService bsqWalletService,
|
||||
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter btcFormatter,
|
||||
BsqFormatter bsqFormatter) {
|
||||
this.walletsManager = walletsManager;
|
||||
this.btcWalletService = btcWalletService;
|
||||
this.bsqWalletService = bsqWalletService;
|
||||
this.btcFormatter = btcFormatter;
|
||||
this.bsqFormatter = bsqFormatter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
addTitledGroupBg(root, gridRow, 3, Res.get("account.menu.walletInfo.balance.headLine"));
|
||||
addMultilineLabel(root, gridRow, Res.get("account.menu.walletInfo.balance.info"), Layout.FIRST_ROW_DISTANCE, Double.MAX_VALUE);
|
||||
btcTextField = addTopLabelTextField(root, ++gridRow, "BTC", -Layout.FLOATING_LABEL_DISTANCE).second;
|
||||
bsqTextField = addTopLabelTextField(root, ++gridRow, "BSQ", -Layout.FLOATING_LABEL_DISTANCE).second;
|
||||
|
||||
addTitledGroupBg(root, ++gridRow, 3, Res.get("account.menu.walletInfo.xpub.headLine"), Layout.GROUP_DISTANCE);
|
||||
addXpubKeys(btcWalletService, "BTC", gridRow, Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
++gridRow; // update gridRow
|
||||
addXpubKeys(bsqWalletService, "BSQ", ++gridRow, -Layout.FLOATING_LABEL_DISTANCE);
|
||||
|
||||
addTitledGroupBg(root, ++gridRow, 4, Res.get("account.menu.walletInfo.path.headLine"), Layout.GROUP_DISTANCE);
|
||||
addMultilineLabel(root, gridRow, Res.get("account.menu.walletInfo.path.info"), Layout.FIRST_ROW_AND_GROUP_DISTANCE, Double.MAX_VALUE);
|
||||
addTopLabelTextField(root, ++gridRow, Res.get("account.menu.walletInfo.walletSelector", "BTC", "legacy"), "44'/0'/0'", -Layout.FLOATING_LABEL_DISTANCE);
|
||||
addTopLabelTextField(root, ++gridRow, Res.get("account.menu.walletInfo.walletSelector", "BTC", "segwit"), "44'/0'/1'", -Layout.FLOATING_LABEL_DISTANCE);
|
||||
addTopLabelTextField(root, ++gridRow, Res.get("account.menu.walletInfo.walletSelector", "BSQ", ""), "44'/142'/0'", -Layout.FLOATING_LABEL_DISTANCE);
|
||||
|
||||
openDetailsButton = addButtonAfterGroup(root, ++gridRow, Res.get("account.menu.walletInfo.openDetails"));
|
||||
|
||||
btcWalletBalanceListener = new BalanceListener() {
|
||||
@Override
|
||||
public void onBalanceChanged(Coin balanceAsCoin, Transaction tx) {
|
||||
updateBalances(btcWalletService);
|
||||
}
|
||||
};
|
||||
bsqWalletBalanceListener = new BalanceListener() {
|
||||
@Override
|
||||
public void onBalanceChanged(Coin balanceAsCoin, Transaction tx) {
|
||||
updateBalances(bsqWalletService);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void activate() {
|
||||
btcWalletService.addBalanceListener(btcWalletBalanceListener);
|
||||
bsqWalletService.addBalanceListener(bsqWalletBalanceListener);
|
||||
updateBalances(btcWalletService);
|
||||
updateBalances(bsqWalletService);
|
||||
|
||||
openDetailsButton.setOnAction(e -> {
|
||||
if (walletsManager.areWalletsAvailable()) {
|
||||
new ShowWalletDataWindow(walletsManager).width(root.getWidth()).show();
|
||||
} else {
|
||||
new Popup().warning(Res.get("popup.warning.walletNotInitialized")).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deactivate() {
|
||||
btcWalletService.removeBalanceListener(btcWalletBalanceListener);
|
||||
bsqWalletService.removeBalanceListener(bsqWalletBalanceListener);
|
||||
openDetailsButton.setOnAction(null);
|
||||
}
|
||||
|
||||
private void addXpubKeys(WalletService walletService, String currency, int gridRow, double top) {
|
||||
int row = gridRow;
|
||||
double topDist = top;
|
||||
for (DeterministicKeyChain chain : walletService.getWallet().getActiveKeyChains()) {
|
||||
Script.ScriptType outputScriptType = chain.getOutputScriptType();
|
||||
String type = outputScriptType == Script.ScriptType.P2WPKH ? "segwit" : "legacy";
|
||||
String key = chain.getWatchingKey().serializePubB58(Config.baseCurrencyNetworkParameters(), outputScriptType);
|
||||
addTopLabelTextField(root, row,
|
||||
Res.get("account.menu.walletInfo.walletSelector", currency, type),
|
||||
key, topDist);
|
||||
row++;
|
||||
topDist = -Layout.FLOATING_LABEL_DISTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBalances(WalletService walletService) {
|
||||
if (walletService instanceof BtcWalletService) {
|
||||
btcTextField.setText(btcFormatter.formatCoinWithCode(walletService.getBalance(ESTIMATED_SPENDABLE)));
|
||||
} else {
|
||||
bsqTextField.setText(bsqFormatter.formatCoinWithCode(walletService.getBalance(ESTIMATED_SPENDABLE)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -54,7 +54,7 @@ public class ShowWalletDataWindow extends Overlay<ShowWalletDataWindow> {
|
|||
if (headLine == null)
|
||||
headLine = Res.get("showWalletDataWindow.walletData");
|
||||
|
||||
width = 660;
|
||||
width = 1000;
|
||||
createGridPane();
|
||||
addHeadLine();
|
||||
addContent();
|
||||
|
|
Loading…
Add table
Reference in a new issue