mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 09:52:23 +01:00
Add export feature for account age
This commit is contained in:
parent
2628eea9db
commit
2b6dd187c6
@ -287,7 +287,7 @@ public class AccountAgeWitnessService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Optional<AccountAgeWitness> findWitness(PaymentAccountPayload paymentAccountPayload,
|
public Optional<AccountAgeWitness> findWitness(PaymentAccountPayload paymentAccountPayload,
|
||||||
PubKeyRing pubKeyRing) {
|
PubKeyRing pubKeyRing) {
|
||||||
if (paymentAccountPayload == null) {
|
if (paymentAccountPayload == null) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
@ -19,17 +19,25 @@ package bisq.core.account.witness;
|
|||||||
|
|
||||||
import bisq.core.account.sign.SignedWitness;
|
import bisq.core.account.sign.SignedWitness;
|
||||||
import bisq.core.account.sign.SignedWitnessService;
|
import bisq.core.account.sign.SignedWitnessService;
|
||||||
|
import bisq.core.payment.PaymentAccount;
|
||||||
import bisq.core.payment.payload.PaymentAccountPayload;
|
import bisq.core.payment.payload.PaymentAccountPayload;
|
||||||
import bisq.core.trade.model.bisq_v1.Trade;
|
import bisq.core.trade.model.bisq_v1.Trade;
|
||||||
|
import bisq.core.util.JsonUtil;
|
||||||
|
|
||||||
import bisq.network.p2p.storage.P2PDataStorage;
|
import bisq.network.p2p.storage.P2PDataStorage;
|
||||||
|
|
||||||
|
import bisq.common.crypto.CryptoException;
|
||||||
import bisq.common.crypto.Hash;
|
import bisq.common.crypto.Hash;
|
||||||
import bisq.common.crypto.KeyRing;
|
import bisq.common.crypto.KeyRing;
|
||||||
import bisq.common.crypto.PubKeyRing;
|
import bisq.common.crypto.PubKeyRing;
|
||||||
|
import bisq.common.crypto.Sig;
|
||||||
|
import bisq.common.util.Hex;
|
||||||
import bisq.common.util.Utilities;
|
import bisq.common.util.Utilities;
|
||||||
|
|
||||||
|
import java.security.KeyPair;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Base64;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
@ -168,4 +176,48 @@ public class AccountAgeWitnessUtils {
|
|||||||
accountAgeWitnessService.tradeAmountIsSufficient(trade.getAmount()),
|
accountAgeWitnessService.tradeAmountIsSufficient(trade.getAmount()),
|
||||||
isSignWitnessTrade);
|
isSignWitnessTrade);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class AccountAgeWitnessDto {
|
||||||
|
private final String profileId;
|
||||||
|
private final String hashAsHex;
|
||||||
|
private final long date;
|
||||||
|
private final String pubKeyBase64;
|
||||||
|
private final String signatureBase64;
|
||||||
|
|
||||||
|
public AccountAgeWitnessDto(String profileId,
|
||||||
|
String hashAsHex,
|
||||||
|
long date,
|
||||||
|
String pubKeyBase64,
|
||||||
|
String signatureBase64) {
|
||||||
|
this.profileId = profileId;
|
||||||
|
this.hashAsHex = hashAsHex;
|
||||||
|
this.date = date;
|
||||||
|
this.pubKeyBase64 = pubKeyBase64;
|
||||||
|
this.signatureBase64 = signatureBase64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<String> exportAccount(AccountAgeWitnessService accountAgeWitnessService,
|
||||||
|
PaymentAccount account,
|
||||||
|
KeyRing keyRing,
|
||||||
|
String profileId) {
|
||||||
|
return accountAgeWitnessService.findWitness(account.getPaymentAccountPayload(), keyRing.getPubKeyRing())
|
||||||
|
.map(accountAgeWitness -> {
|
||||||
|
try {
|
||||||
|
String hashAsHex = Hex.encode(accountAgeWitness.getHash());
|
||||||
|
String message = profileId + hashAsHex + accountAgeWitness.getDate();
|
||||||
|
KeyPair signatureKeyPair = keyRing.getSignatureKeyPair();
|
||||||
|
String signatureBase64 = Sig.sign(signatureKeyPair.getPrivate(), message);
|
||||||
|
String pubKeyBase64 = Base64.getEncoder().encodeToString(Sig.getPublicKeyBytes(signatureKeyPair.getPublic()));
|
||||||
|
AccountAgeWitnessDto dto = new AccountAgeWitnessDto(profileId,
|
||||||
|
hashAsHex,
|
||||||
|
accountAgeWitness.getDate(),
|
||||||
|
pubKeyBase64,
|
||||||
|
signatureBase64);
|
||||||
|
return JsonUtil.objectToJson(dto);
|
||||||
|
} catch (CryptoException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1818,7 +1818,10 @@ providing cryptographic proof to the mediator or refund agent.\n\n\
|
|||||||
If you do not understand these requirements, do not trade L-BTC on Bisq.
|
If you do not understand these requirements, do not trade L-BTC on Bisq.
|
||||||
|
|
||||||
account.fiat.yourFiatAccounts=Your national currency accounts
|
account.fiat.yourFiatAccounts=Your national currency accounts
|
||||||
|
account.fiat.exportAccountAge=Export account age for Bisq 2
|
||||||
|
account.fiat.exportAccountAge.popup=Your account age and Bisq 2 profile ID got signed and the data is copied \
|
||||||
|
to the clipboard.\n\
|
||||||
|
Go back to Bisq 2 and follow the instructions there.
|
||||||
account.backup.title=Backup wallet
|
account.backup.title=Backup wallet
|
||||||
account.backup.location=Backup location
|
account.backup.location=Backup location
|
||||||
account.backup.selectLocation=Select backup location
|
account.backup.selectLocation=Select backup location
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
package bisq.desktop.main.account.content.fiataccounts;
|
package bisq.desktop.main.account.content.fiataccounts;
|
||||||
|
|
||||||
import bisq.desktop.common.view.FxmlView;
|
import bisq.desktop.common.view.FxmlView;
|
||||||
|
import bisq.desktop.components.AutoTooltipButton;
|
||||||
import bisq.desktop.components.TitledGroupBg;
|
import bisq.desktop.components.TitledGroupBg;
|
||||||
import bisq.desktop.components.paymentmethods.AchTransferForm;
|
import bisq.desktop.components.paymentmethods.AchTransferForm;
|
||||||
import bisq.desktop.components.paymentmethods.AdvancedCashForm;
|
import bisq.desktop.components.paymentmethods.AdvancedCashForm;
|
||||||
@ -100,6 +101,7 @@ import bisq.desktop.util.validation.UpholdValidator;
|
|||||||
import bisq.desktop.util.validation.WeChatPayValidator;
|
import bisq.desktop.util.validation.WeChatPayValidator;
|
||||||
|
|
||||||
import bisq.core.account.witness.AccountAgeWitnessService;
|
import bisq.core.account.witness.AccountAgeWitnessService;
|
||||||
|
import bisq.core.account.witness.AccountAgeWitnessUtils;
|
||||||
import bisq.core.locale.Res;
|
import bisq.core.locale.Res;
|
||||||
import bisq.core.offer.OfferRestrictions;
|
import bisq.core.offer.OfferRestrictions;
|
||||||
import bisq.core.payment.AmazonGiftCardAccount;
|
import bisq.core.payment.AmazonGiftCardAccount;
|
||||||
@ -120,6 +122,8 @@ import bisq.core.util.FormattingUtils;
|
|||||||
import bisq.core.util.coin.CoinFormatter;
|
import bisq.core.util.coin.CoinFormatter;
|
||||||
|
|
||||||
import bisq.common.config.Config;
|
import bisq.common.config.Config;
|
||||||
|
import bisq.common.crypto.KeyRing;
|
||||||
|
import bisq.common.util.Hex;
|
||||||
import bisq.common.util.Tuple2;
|
import bisq.common.util.Tuple2;
|
||||||
import bisq.common.util.Tuple3;
|
import bisq.common.util.Tuple3;
|
||||||
import bisq.common.util.Utilities;
|
import bisq.common.util.Utilities;
|
||||||
@ -135,7 +139,10 @@ import javafx.scene.control.Button;
|
|||||||
import javafx.scene.control.ComboBox;
|
import javafx.scene.control.ComboBox;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.ListView;
|
import javafx.scene.control.ListView;
|
||||||
|
import javafx.scene.input.Clipboard;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.layout.Priority;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
@ -157,6 +164,7 @@ public class FiatAccountsView extends PaymentAccountsView<GridPane, FiatAccounts
|
|||||||
private final BICValidator bicValidator;
|
private final BICValidator bicValidator;
|
||||||
private final CapitualValidator capitualValidator;
|
private final CapitualValidator capitualValidator;
|
||||||
private final LengthValidator inputValidator;
|
private final LengthValidator inputValidator;
|
||||||
|
private final KeyRing keyRing;
|
||||||
private final UpholdValidator upholdValidator;
|
private final UpholdValidator upholdValidator;
|
||||||
private final MoneyBeamValidator moneyBeamValidator;
|
private final MoneyBeamValidator moneyBeamValidator;
|
||||||
private final PopmoneyValidator popmoneyValidator;
|
private final PopmoneyValidator popmoneyValidator;
|
||||||
@ -208,12 +216,14 @@ public class FiatAccountsView extends PaymentAccountsView<GridPane, FiatAccounts
|
|||||||
AdvancedCashValidator advancedCashValidator,
|
AdvancedCashValidator advancedCashValidator,
|
||||||
TransferwiseValidator transferwiseValidator,
|
TransferwiseValidator transferwiseValidator,
|
||||||
AccountAgeWitnessService accountAgeWitnessService,
|
AccountAgeWitnessService accountAgeWitnessService,
|
||||||
|
KeyRing keyRing,
|
||||||
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter) {
|
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter) {
|
||||||
super(model, accountAgeWitnessService);
|
super(model, accountAgeWitnessService);
|
||||||
|
|
||||||
this.bicValidator = bicValidator;
|
this.bicValidator = bicValidator;
|
||||||
this.capitualValidator = capitualValidator;
|
this.capitualValidator = capitualValidator;
|
||||||
this.inputValidator = inputValidator;
|
this.inputValidator = inputValidator;
|
||||||
|
this.keyRing = keyRing;
|
||||||
this.inputValidator.setMaxLength(100); // restrict general field entry length
|
this.inputValidator.setMaxLength(100); // restrict general field entry length
|
||||||
this.inputValidator.setMinLength(2);
|
this.inputValidator.setMinLength(2);
|
||||||
this.upholdValidator = upholdValidator;
|
this.upholdValidator = upholdValidator;
|
||||||
@ -296,9 +306,9 @@ public class FiatAccountsView extends PaymentAccountsView<GridPane, FiatAccounts
|
|||||||
}
|
}
|
||||||
|
|
||||||
new Popup().information(Res.get(limitsInfoKey,
|
new Popup().information(Res.get(limitsInfoKey,
|
||||||
initialLimit,
|
initialLimit,
|
||||||
formatter.formatCoinWithCode(maxTradeLimitSecondMonth),
|
formatter.formatCoinWithCode(maxTradeLimitSecondMonth),
|
||||||
formatter.formatCoinWithCode(maxTradeLimitAsCoin)))
|
formatter.formatCoinWithCode(maxTradeLimitAsCoin)))
|
||||||
.width(700)
|
.width(700)
|
||||||
.closeButtonText(Res.get("shared.cancel"))
|
.closeButtonText(Res.get("shared.cancel"))
|
||||||
.actionButtonText(Res.get("shared.iUnderstand"))
|
.actionButtonText(Res.get("shared.iUnderstand"))
|
||||||
@ -490,6 +500,7 @@ public class FiatAccountsView extends PaymentAccountsView<GridPane, FiatAccounts
|
|||||||
Res.get("shared.deleteAccount"),
|
Res.get("shared.deleteAccount"),
|
||||||
Res.get("shared.cancel")
|
Res.get("shared.cancel")
|
||||||
);
|
);
|
||||||
|
|
||||||
Button updateButton = tuple.first;
|
Button updateButton = tuple.first;
|
||||||
updateButton.setOnAction(event -> onUpdateAccount(paymentMethodForm.getPaymentAccount()));
|
updateButton.setOnAction(event -> onUpdateAccount(paymentMethodForm.getPaymentAccount()));
|
||||||
Button deleteAccountButton = tuple.second;
|
Button deleteAccountButton = tuple.second;
|
||||||
@ -497,10 +508,39 @@ public class FiatAccountsView extends PaymentAccountsView<GridPane, FiatAccounts
|
|||||||
Button cancelButton = tuple.third;
|
Button cancelButton = tuple.third;
|
||||||
cancelButton.setOnAction(event -> onCancelSelectedAccount(paymentMethodForm.getPaymentAccount()));
|
cancelButton.setOnAction(event -> onCancelSelectedAccount(paymentMethodForm.getPaymentAccount()));
|
||||||
GridPane.setRowSpan(accountTitledGroupBg, paymentMethodForm.getRowSpan());
|
GridPane.setRowSpan(accountTitledGroupBg, paymentMethodForm.getRowSpan());
|
||||||
|
|
||||||
|
Button exportAccountAgeButton = new AutoTooltipButton(Res.get("account.fiat.exportAccountAge"));
|
||||||
|
exportAccountAgeButton.setOnAction(event -> onExportAccountAge(paymentMethodForm.getPaymentAccount()));
|
||||||
|
exportAccountAgeButton.setMaxWidth(Double.MAX_VALUE);
|
||||||
|
HBox.setHgrow(exportAccountAgeButton, Priority.ALWAYS);
|
||||||
|
HBox hBox = (HBox) cancelButton.getParent();
|
||||||
|
hBox.getChildren().add(exportAccountAgeButton);
|
||||||
|
|
||||||
model.onSelectAccount(current);
|
model.onSelectAccount(current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onExportAccountAge(PaymentAccount paymentAccount) {
|
||||||
|
String clipboardText = Clipboard.getSystemClipboard().getString();
|
||||||
|
String prefix = "BISQ2_ACCOUNT_AGE_REQUEST:";
|
||||||
|
if (clipboardText != null && clipboardText.startsWith(prefix)) {
|
||||||
|
String profileId = clipboardText.replace(prefix, "");
|
||||||
|
if (profileId.length() == 40) {
|
||||||
|
try {
|
||||||
|
Hex.decode(profileId);
|
||||||
|
AccountAgeWitnessUtils.exportAccount(accountAgeWitnessService, paymentAccount, keyRing, profileId)
|
||||||
|
.ifPresent(json -> {
|
||||||
|
Utilities.copyToClipboard(json);
|
||||||
|
new Popup().information(Res.get("account.fiat.exportAccountAge.popup")).show();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
} catch (Throwable ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.warn("Clipboard text not in expected format.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Utils
|
// Utils
|
||||||
|
@ -843,7 +843,9 @@ public class GUIUtil {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean canCreateOrTakeOfferOrShowPopup(User user, Navigation navigation, @Nullable TradeCurrency currency) {
|
public static boolean canCreateOrTakeOfferOrShowPopup(User user,
|
||||||
|
Navigation navigation,
|
||||||
|
@Nullable TradeCurrency currency) {
|
||||||
if (currency != null && currency.getCode().equals("BSQ")) {
|
if (currency != null && currency.getCode().equals("BSQ")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user