diff --git a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java index 007c59e8a1..789cbc33c8 100644 --- a/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java +++ b/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java @@ -36,9 +36,11 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.dao.DaoFacade; import bisq.core.dao.bonding.BondingConsensus; +import bisq.core.dao.bonding.lockup.LockupType; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; import bisq.core.util.validation.IntegerValidator; +import bisq.core.util.validation.StringValidator; import bisq.network.p2p.P2PService; @@ -48,11 +50,19 @@ import org.bitcoinj.core.InsufficientMoneyException; import javax.inject.Inject; import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; import javafx.scene.layout.GridPane; import javafx.beans.value.ChangeListener; +import javafx.collections.FXCollections; + +import javafx.util.StringConverter; + +import java.util.Arrays; + import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; +import static bisq.desktop.util.FormBuilder.addLabelComboBox; import static bisq.desktop.util.FormBuilder.addLabelInputTextField; import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @@ -67,10 +77,13 @@ public class LockupView extends ActivatableView implements BsqBa private final BsqValidator bsqValidator; private final DaoFacade daoFacade; private final IntegerValidator timeInputTextFieldValidator; + private final StringValidator bondIdValidator; private int gridRow = 0; private InputTextField amountInputTextField; private InputTextField timeInputTextField; + private ComboBox lockupTypeComboBox; + private InputTextField bondIdInputTextField; private Button lockupButton; private ChangeListener focusOutListener; private ChangeListener inputTextFieldListener; @@ -101,6 +114,9 @@ public class LockupView extends ActivatableView implements BsqBa timeInputTextFieldValidator = new IntegerValidator(); timeInputTextFieldValidator.setMinValue(BondingConsensus.getMinLockTime()); timeInputTextFieldValidator.setMaxValue(BondingConsensus.getMaxLockTime()); + + bondIdValidator = new StringValidator(); + bondIdValidator.setLength(20); } @Override @@ -119,11 +135,39 @@ public class LockupView extends ActivatableView implements BsqBa String.valueOf(BondingConsensus.getMinLockTime()), String.valueOf(BondingConsensus.getMaxLockTime()))); timeInputTextField.setValidator(timeInputTextFieldValidator); + lockupTypeComboBox = addLabelComboBox(root, ++gridRow, + Res.getWithCol("dao.bonding.lock.type"), Layout.GRID_GAP).second; + lockupTypeComboBox.setConverter(new StringConverter() { + @Override + public String toString(LockupType lockupType) { + return lockupType.toString(); + } + + @Override + public LockupType fromString(String string) { + return null; + } + }); + lockupTypeComboBox.setItems(FXCollections.observableArrayList(Arrays.asList(LockupType.values()))); + lockupTypeComboBox.getSelectionModel().selectFirst(); + + bondIdInputTextField = addLabelInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.bondId"), Layout.GRID_GAP).second; + bondIdInputTextField.setPromptText(Res.get("dao.bonding.lock.setBondId")); + bondIdInputTextField.setValidator(bondIdValidator); + lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bonding.lock.lockupButton")); lockupButton.setOnAction((event) -> { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText()); int lockupTime = Integer.parseInt(timeInputTextField.getText()); + LockupType type = lockupTypeComboBox.getValue(); + // TODO get hash of something +// byte[] bytes = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + byte[] bytes = bondIdInputTextField.getText().getBytes(); + if (type != LockupType.BONDED_ROLE) + bytes = null; + final byte[] hash = bytes; + new Popup<>().headLine(Res.get("dao.bonding.lock.sendFunds.headline")) .confirmation(Res.get("dao.bonding.lock.sendFunds.details", bsqFormatter.formatCoinWithCode(lockupAmount), @@ -133,6 +177,8 @@ public class LockupView extends ActivatableView implements BsqBa .onAction(() -> { daoFacade.publishLockupTx(lockupAmount, lockupTime, + type, + hash, () -> { new Popup<>().feedback(Res.get("dao.tx.published.success")).show(); }, diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java index fbd909d4a9..e322ac3a54 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalDisplay.java @@ -35,10 +35,13 @@ import bisq.core.dao.voting.proposal.ProposalConsensus; import bisq.core.dao.voting.proposal.ProposalType; import bisq.core.dao.voting.proposal.compensation.CompensationConsensus; import bisq.core.dao.voting.proposal.compensation.CompensationProposal; +import bisq.core.dao.voting.proposal.confiscatebond.ConfiscateBondProposal; import bisq.core.dao.voting.proposal.param.ChangeParamProposal; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; +import bisq.common.util.Utilities; + import javafx.scene.control.ComboBox; import javafx.scene.control.ScrollPane; import javafx.scene.control.TextArea; @@ -53,6 +56,7 @@ import javafx.geometry.HPos; import javafx.beans.value.ChangeListener; import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import javafx.util.StringConverter; @@ -82,6 +86,7 @@ public class ProposalDisplay { public InputTextField requestedBsqTextField, bsqAddressTextField, paramValueTextField; @Nullable public ComboBox paramComboBox; + public ComboBox confiscateBondComboBox; @Getter private int gridRow; public TextArea descriptionTextArea; @@ -121,7 +126,7 @@ public class ProposalDisplay { int rowSpan; boolean hasAddedFields = proposalType == ProposalType.COMPENSATION_REQUEST || - proposalType == ProposalType.CHANGE_PARAM; + proposalType == ProposalType.CHANGE_PARAM || proposalType == ProposalType.CONFISCATE_BOND; if (isMakeProposalScreen) { rowSpan = hasAddedFields ? 8 : 6; } else if (showDetails) { @@ -132,6 +137,8 @@ public class ProposalDisplay { rowSpan = 6; else if (proposalType == ProposalType.CHANGE_PARAM) rowSpan = 7; + else if (proposalType == ProposalType.CONFISCATE_BOND) + rowSpan = 6; else rowSpan = 5; } @@ -200,6 +207,26 @@ public class ProposalDisplay { paramValueTextField = addLabelInputTextField(gridPane, ++gridRow, Res.get("dao.proposal.display.paramValue")).second; break; case REMOVE_ALTCOIN: + break; + case CONFISCATE_BOND: + confiscateBondComboBox = addLabelComboBox(gridPane, ++gridRow, + Res.get("dao.proposal.display.confiscateBondComboBox.label")).second; + ObservableList confiscatableBonds = + FXCollections.observableArrayList(daoFacade.getLockupAndUnlockingBondIds()); +// confiscatableBonds.addAll("bond1", "bond2", "bond3"); + confiscateBondComboBox.setItems(confiscatableBonds); + confiscateBondComboBox.setConverter(new StringConverter() { + @Override + public String toString(byte[] id) { + return Utilities.bytesAsHexString(id); + } + + @Override + public byte[] fromString(String string) { + return null; + } + }); + break; } @@ -232,10 +259,14 @@ public class ProposalDisplay { bsqAddressTextField.setText(compensationProposal.getBsqAddress()); } else if (proposal instanceof ChangeParamProposal) { ChangeParamProposal changeParamProposal = (ChangeParamProposal) proposal; - checkNotNull(paramComboBox, "paramComboBox must no tbe null"); + checkNotNull(paramComboBox, "paramComboBox must not be null"); paramComboBox.getSelectionModel().select(changeParamProposal.getParam()); checkNotNull(paramValueTextField, "paramValueTextField must no tbe null"); paramValueTextField.setText(String.valueOf(changeParamProposal.getParamValue())); + } else if (proposal instanceof ConfiscateBondProposal) { + ConfiscateBondProposal confiscateBondProposal = (ConfiscateBondProposal) proposal; + checkNotNull(confiscateBondComboBox, "confiscateBondComboBox must not be null"); + confiscateBondComboBox.getSelectionModel().select(confiscateBondProposal.getBondId()); } int chainHeight; if (txIdTextField != null) { @@ -258,6 +289,7 @@ public class ProposalDisplay { if (bsqAddressTextField != null) bsqAddressTextField.clear(); if (paramComboBox != null) paramComboBox.getSelectionModel().clearSelection(); if (paramValueTextField != null) paramValueTextField.clear(); + if (confiscateBondComboBox != null) confiscateBondComboBox.getSelectionModel().clearSelection(); if (txIdTextField != null) txIdTextField.cleanup(); if (descriptionTextArea != null) descriptionTextArea.textProperty().removeListener(descriptionTextAreaListener); } @@ -294,6 +326,9 @@ public class ProposalDisplay { if (paramValueTextField != null) paramValueTextField.setEditable(isEditable); + if (confiscateBondComboBox != null) + confiscateBondComboBox.setDisable(!isEditable); + linkInputTextField.setVisible(true); linkInputTextField.setManaged(true); linkHyperlinkWithIcon.setVisible(false); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 68009e6169..7a19c6c6c2 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -282,6 +282,16 @@ public class MakeProposalView extends ActivatableView implements case REMOVE_ALTCOIN: //TODO throw new RuntimeException("Not implemented yet"); + case CONFISCATE_BOND: + byte[] bondId = proposalDisplay.confiscateBondComboBox.getSelectionModel().getSelectedItem(); + if (bondId == null || bondId.length == 0) + throw new ValidationException("Invalid bond id, null or zero length"); + + return daoFacade.getConfiscateBondProposalWithTransaction(proposalDisplay.nameTextField.getText(), + proposalDisplay.titleTextField.getText(), + proposalDisplay.descriptionTextArea.getText(), + proposalDisplay.linkInputTextField.getText(), + bondId); default: final String msg = "Undefined ProposalType " + selectedProposalType; log.error(msg);