mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-20 10:22:18 +01:00
Merge branch 'release-candidate-0.9.0' of github.com:bisq-network/bisq into clean-up-payment-method-forms
# Conflicts: # desktop/src/main/java/bisq/desktop/util/FormBuilder.java
This commit is contained in:
commit
ea73cbab76
@ -120,6 +120,7 @@ public class Version {
|
||||
|
||||
//TODO move to consensus area
|
||||
public static final byte COMPENSATION_REQUEST = (byte) 0x01;
|
||||
public static final byte REIMBURSEMENT_REQUEST = (byte) 0x01;
|
||||
public static final byte PROPOSAL = (byte) 0x01;
|
||||
public static final byte BLIND_VOTE = (byte) 0x01;
|
||||
public static final byte VOTE_REVEAL = (byte) 0x01;
|
||||
|
@ -1360,10 +1360,11 @@ enum TxType {
|
||||
PAY_TRADE_FEE = 6;
|
||||
PROPOSAL = 7;
|
||||
COMPENSATION_REQUEST = 8;
|
||||
BLIND_VOTE = 9;
|
||||
VOTE_REVEAL = 10;
|
||||
LOCKUP = 11;
|
||||
UNLOCK = 12;
|
||||
REIMBURSEMENT_REQUEST = 9;
|
||||
BLIND_VOTE = 10;
|
||||
VOTE_REVEAL = 11;
|
||||
LOCKUP = 12;
|
||||
UNLOCK = 13;
|
||||
}
|
||||
|
||||
message TxInput {
|
||||
@ -1403,16 +1404,17 @@ enum TxOutputType {
|
||||
BTC_OUTPUT = 4;
|
||||
PROPOSAL_OP_RETURN_OUTPUT = 5;
|
||||
COMP_REQ_OP_RETURN_OUTPUT = 6;
|
||||
CONFISCATE_BOND_OP_RETURN_OUTPUT = 7;
|
||||
ISSUANCE_CANDIDATE_OUTPUT = 8;
|
||||
BLIND_VOTE_LOCK_STAKE_OUTPUT = 9;
|
||||
BLIND_VOTE_OP_RETURN_OUTPUT = 10;
|
||||
VOTE_REVEAL_UNLOCK_STAKE_OUTPUT = 11;
|
||||
VOTE_REVEAL_OP_RETURN_OUTPUT = 12;
|
||||
LOCKUP_OUTPUT = 13;
|
||||
LOCKUP_OP_RETURN_OUTPUT = 14;
|
||||
UNLOCK_OUTPUT = 15;
|
||||
INVALID_OUTPUT = 16;
|
||||
REIMBURSEMENT_OP_RETURN_OUTPUT = 7;
|
||||
CONFISCATE_BOND_OP_RETURN_OUTPUT = 8;
|
||||
ISSUANCE_CANDIDATE_OUTPUT = 9;
|
||||
BLIND_VOTE_LOCK_STAKE_OUTPUT = 10;
|
||||
BLIND_VOTE_OP_RETURN_OUTPUT = 11;
|
||||
VOTE_REVEAL_UNLOCK_STAKE_OUTPUT = 12;
|
||||
VOTE_REVEAL_OP_RETURN_OUTPUT = 13;
|
||||
LOCKUP_OUTPUT = 14;
|
||||
LOCKUP_OP_RETURN_OUTPUT = 15;
|
||||
UNLOCK_OUTPUT = 16;
|
||||
INVALID_OUTPUT = 17;
|
||||
}
|
||||
|
||||
message SpentInfo {
|
||||
@ -1474,6 +1476,7 @@ message Issuance {
|
||||
int32 chain_height = 2;
|
||||
int64 amount = 3;
|
||||
string pub_key = 4;
|
||||
string issuance_type = 5;
|
||||
}
|
||||
|
||||
message Proposal {
|
||||
@ -1484,11 +1487,12 @@ message Proposal {
|
||||
string tx_id = 5;
|
||||
oneof message {
|
||||
CompensationProposal compensation_proposal = 6;
|
||||
ChangeParamProposal change_param_proposal = 7;
|
||||
BondedRoleProposal bonded_role_proposal = 8;
|
||||
ConfiscateBondProposal confiscate_bond_proposal = 9;
|
||||
GenericProposal generic_proposal = 10;
|
||||
RemoveAssetProposal remove_asset_proposal = 11;
|
||||
ReimbursementProposal reimbursement_proposal = 7;
|
||||
ChangeParamProposal change_param_proposal = 8;
|
||||
BondedRoleProposal bonded_role_proposal = 9;
|
||||
ConfiscateBondProposal confiscate_bond_proposal = 10;
|
||||
GenericProposal generic_proposal = 11;
|
||||
RemoveAssetProposal remove_asset_proposal = 12;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1497,6 +1501,11 @@ message CompensationProposal {
|
||||
string bsq_address = 2;
|
||||
}
|
||||
|
||||
message ReimbursementProposal {
|
||||
int64 requested_bsq = 1;
|
||||
string bsq_address = 2;
|
||||
}
|
||||
|
||||
message ChangeParamProposal {
|
||||
string param = 1; // name of enum
|
||||
int64 param_value = 2;
|
||||
|
@ -146,11 +146,28 @@ public class BtcWalletService extends WalletService {
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CompensationRequest tx
|
||||
// Proposal txs
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Transaction completePreparedCompensationRequestTx(Coin issuanceAmount, Address issuanceAddress, Transaction feeTx, byte[] opReturnData) throws
|
||||
TransactionVerificationException, WalletException, InsufficientMoneyException {
|
||||
|
||||
public Transaction completePreparedProposalTx(Transaction preparedBurnFeeTx, byte[] opReturnData)
|
||||
throws WalletException, InsufficientMoneyException, TransactionVerificationException {
|
||||
return completePreparedProposalTx(preparedBurnFeeTx, opReturnData, null, null);
|
||||
}
|
||||
|
||||
public Transaction completePreparedReimbursementRequestTx(Coin issuanceAmount, Address issuanceAddress, Transaction feeTx, byte[] opReturnData)
|
||||
throws TransactionVerificationException, WalletException, InsufficientMoneyException {
|
||||
return completePreparedProposalTx(feeTx, opReturnData, issuanceAmount, issuanceAddress);
|
||||
}
|
||||
|
||||
public Transaction completePreparedCompensationRequestTx(Coin issuanceAmount, Address issuanceAddress, Transaction feeTx, byte[] opReturnData)
|
||||
throws TransactionVerificationException, WalletException, InsufficientMoneyException {
|
||||
return completePreparedProposalTx(feeTx, opReturnData, issuanceAmount, issuanceAddress);
|
||||
}
|
||||
|
||||
private Transaction completePreparedProposalTx(Transaction feeTx, byte[] opReturnData,
|
||||
@Nullable Coin issuanceAmount, @Nullable Address issuanceAddress)
|
||||
throws TransactionVerificationException, WalletException, InsufficientMoneyException {
|
||||
|
||||
// (BsqFee)tx has following structure:
|
||||
// inputs [1-n] BSQ inputs (fee)
|
||||
@ -160,7 +177,7 @@ public class BtcWalletService extends WalletService {
|
||||
// inputs [1-n] BSQ inputs for request fee
|
||||
// inputs [1-n] BTC inputs for BSQ issuance and miner fee
|
||||
// outputs [1] Mandatory BSQ request fee change output (>= 546 Satoshi)
|
||||
// outputs [1] Potentially BSQ issuance output (>= 546 Satoshi)
|
||||
// outputs [1] Potentially BSQ issuance output (>= 546 Satoshi) - in case of a issuance tx, otherwise that output does not exist
|
||||
// outputs [0-1] BTC change output from issuance and miner fee inputs (>= 546 Satoshi)
|
||||
// outputs [1] OP_RETURN with opReturnData and amount 0
|
||||
// mining fee: BTC mining fee + burned BSQ fee
|
||||
@ -174,9 +191,11 @@ public class BtcWalletService extends WalletService {
|
||||
// BSQ change outputs from BSQ fee inputs.
|
||||
feeTx.getOutputs().forEach(preparedTx::addOutput);
|
||||
|
||||
// BSQ issuance output
|
||||
preparedTx.addOutput(issuanceAmount, issuanceAddress);
|
||||
|
||||
// For generic proposals there is no issuance output, for compensation and reimburse requests there is
|
||||
if (issuanceAmount != null && issuanceAddress != null) {
|
||||
// BSQ issuance output
|
||||
preparedTx.addOutput(issuanceAmount, issuanceAddress);
|
||||
}
|
||||
|
||||
// safety check counter to avoid endless loops
|
||||
int counter = 0;
|
||||
@ -204,8 +223,8 @@ public class BtcWalletService extends WalletService {
|
||||
}
|
||||
|
||||
Transaction tx = new Transaction(params);
|
||||
preparedBsqTxInputs.stream().forEach(tx::addInput);
|
||||
preparedBsqTxOutputs.stream().forEach(tx::addOutput);
|
||||
preparedBsqTxInputs.forEach(tx::addInput);
|
||||
preparedBsqTxOutputs.forEach(tx::addOutput);
|
||||
|
||||
SendRequest sendRequest = SendRequest.forTx(tx);
|
||||
sendRequest.shuffleOutputs = false;
|
||||
@ -228,7 +247,7 @@ public class BtcWalletService extends WalletService {
|
||||
|
||||
numInputs = resultTx.getInputs().size();
|
||||
txSizeWithUnsignedInputs = resultTx.bitcoinSerialize().length;
|
||||
final long estimatedFeeAsLong = txFeePerByte.multiply(txSizeWithUnsignedInputs + sigSizePerInput * numInputs).value;
|
||||
long estimatedFeeAsLong = txFeePerByte.multiply(txSizeWithUnsignedInputs + sigSizePerInput * numInputs).value;
|
||||
// calculated fee must be inside of a tolerance range with tx fee
|
||||
isFeeOutsideTolerance = Math.abs(resultTx.getFee().value - estimatedFeeAsLong) > 1000;
|
||||
}
|
||||
@ -244,17 +263,6 @@ public class BtcWalletService extends WalletService {
|
||||
return resultTx;
|
||||
}
|
||||
|
||||
//TODO Similar like completePreparedCompensationRequestTx but without second output for BSQ issuance
|
||||
public Transaction completePreparedProposalTx(Transaction preparedBurnFeeTx, byte[] opReturnData) {
|
||||
try {
|
||||
//TODO dummy
|
||||
return completePreparedCompensationRequestTx(Coin.valueOf(10000), getFreshAddressEntry().getAddress(),
|
||||
preparedBurnFeeTx, opReturnData);
|
||||
} catch (TransactionVerificationException | InsufficientMoneyException | WalletException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new RuntimeException("completePreparedGenericProposalTx not implemented yet.");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Blind vote tx
|
||||
|
@ -42,6 +42,8 @@ import bisq.core.dao.governance.proposal.compensation.CompensationProposalServic
|
||||
import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposalService;
|
||||
import bisq.core.dao.governance.proposal.generic.GenericProposalService;
|
||||
import bisq.core.dao.governance.proposal.param.ChangeParamProposalService;
|
||||
import bisq.core.dao.governance.proposal.reimbursement.ReimbursementConsensus;
|
||||
import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposalService;
|
||||
import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposalService;
|
||||
import bisq.core.dao.governance.proposal.role.BondedRoleProposalService;
|
||||
import bisq.core.dao.governance.role.BondedRole;
|
||||
@ -54,7 +56,7 @@ import bisq.core.dao.state.blockchain.Tx;
|
||||
import bisq.core.dao.state.blockchain.TxOutput;
|
||||
import bisq.core.dao.state.blockchain.TxOutputKey;
|
||||
import bisq.core.dao.state.blockchain.TxType;
|
||||
import bisq.core.dao.state.governance.Issuance;
|
||||
import bisq.core.dao.state.governance.IssuanceType;
|
||||
import bisq.core.dao.state.governance.Param;
|
||||
import bisq.core.dao.state.period.DaoPhase;
|
||||
import bisq.core.dao.state.period.PeriodService;
|
||||
@ -104,6 +106,7 @@ public class DaoFacade implements DaoSetupService {
|
||||
private final MyBlindVoteListService myBlindVoteListService;
|
||||
private final MyVoteListService myVoteListService;
|
||||
private final CompensationProposalService compensationProposalService;
|
||||
private final ReimbursementProposalService reimbursementProposalService;
|
||||
private final ChangeParamProposalService changeParamProposalService;
|
||||
private final ConfiscateBondProposalService confiscateBondProposalService;
|
||||
private final BondedRoleProposalService bondedRoleProposalService;
|
||||
@ -126,6 +129,7 @@ public class DaoFacade implements DaoSetupService {
|
||||
MyBlindVoteListService myBlindVoteListService,
|
||||
MyVoteListService myVoteListService,
|
||||
CompensationProposalService compensationProposalService,
|
||||
ReimbursementProposalService reimbursementProposalService,
|
||||
ChangeParamProposalService changeParamProposalService,
|
||||
ConfiscateBondProposalService confiscateBondProposalService,
|
||||
BondedRoleProposalService bondedRoleProposalService,
|
||||
@ -144,6 +148,7 @@ public class DaoFacade implements DaoSetupService {
|
||||
this.myBlindVoteListService = myBlindVoteListService;
|
||||
this.myVoteListService = myVoteListService;
|
||||
this.compensationProposalService = compensationProposalService;
|
||||
this.reimbursementProposalService = reimbursementProposalService;
|
||||
this.changeParamProposalService = changeParamProposalService;
|
||||
this.confiscateBondProposalService = confiscateBondProposalService;
|
||||
this.bondedRoleProposalService = bondedRoleProposalService;
|
||||
@ -223,6 +228,15 @@ public class DaoFacade implements DaoSetupService {
|
||||
requestedBsq);
|
||||
}
|
||||
|
||||
public ProposalWithTransaction getReimbursementProposalWithTransaction(String name,
|
||||
String link,
|
||||
Coin requestedBsq)
|
||||
throws ValidationException, InsufficientMoneyException, TxException {
|
||||
return reimbursementProposalService.createProposalWithTransaction(name,
|
||||
link,
|
||||
requestedBsq);
|
||||
}
|
||||
|
||||
public ProposalWithTransaction getParamProposalWithTransaction(String name,
|
||||
String link,
|
||||
Param param,
|
||||
@ -517,8 +531,8 @@ public class DaoFacade implements DaoSetupService {
|
||||
return daoStateService.getGenesisTotalSupply();
|
||||
}
|
||||
|
||||
public Set<Issuance> getIssuanceSet() {
|
||||
return daoStateService.getIssuanceSet();
|
||||
public int getNumIssuanceTransactions(IssuanceType issuanceType) {
|
||||
return daoStateService.getIssuanceSet(issuanceType).size();
|
||||
}
|
||||
|
||||
public Set<Tx> getFeeTxs() {
|
||||
@ -541,8 +555,8 @@ public class DaoFacade implements DaoSetupService {
|
||||
return daoStateService.getTotalBurntFee();
|
||||
}
|
||||
|
||||
public long getTotalIssuedAmountFromCompRequests() {
|
||||
return daoStateService.getTotalIssuedAmount();
|
||||
public long getTotalIssuedAmount(IssuanceType issuanceType) {
|
||||
return daoStateService.getTotalIssuedAmount(issuanceType);
|
||||
}
|
||||
|
||||
public long getBlockTime(int issuanceBlockHeight) {
|
||||
@ -553,8 +567,8 @@ public class DaoFacade implements DaoSetupService {
|
||||
return daoStateService.getIssuanceBlockHeight(txId);
|
||||
}
|
||||
|
||||
public boolean isIssuanceTx(String txId) {
|
||||
return daoStateService.isIssuanceTx(txId);
|
||||
public boolean isIssuanceTx(String txId, IssuanceType issuanceType) {
|
||||
return daoStateService.isIssuanceTx(txId, issuanceType);
|
||||
}
|
||||
|
||||
public boolean hasTxBurntFee(String hashAsString) {
|
||||
@ -605,6 +619,14 @@ public class DaoFacade implements DaoSetupService {
|
||||
return CompensationConsensus.getMaxCompensationRequestAmount(daoStateService, periodService.getChainHeight());
|
||||
}
|
||||
|
||||
public Coin getMinReimbursementRequestAmount() {
|
||||
return ReimbursementConsensus.getMinReimbursementRequestAmount(daoStateService, periodService.getChainHeight());
|
||||
}
|
||||
|
||||
public Coin getMaxReimbursementRequestAmount() {
|
||||
return ReimbursementConsensus.getMaxReimbursementRequestAmount(daoStateService, periodService.getChainHeight());
|
||||
}
|
||||
|
||||
public long getPramValue(Param param) {
|
||||
return daoStateService.getParamValue(param, periodService.getChainHeight());
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ import bisq.core.dao.governance.proposal.generic.GenericProposalService;
|
||||
import bisq.core.dao.governance.proposal.generic.GenericProposalValidator;
|
||||
import bisq.core.dao.governance.proposal.param.ChangeParamProposalService;
|
||||
import bisq.core.dao.governance.proposal.param.ChangeParamValidator;
|
||||
import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposalService;
|
||||
import bisq.core.dao.governance.proposal.reimbursement.ReimbursementValidator;
|
||||
import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposalService;
|
||||
import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetValidator;
|
||||
import bisq.core.dao.governance.proposal.role.BondedRoleProposalService;
|
||||
@ -131,6 +133,9 @@ public class DaoModule extends AppModule {
|
||||
bind(CompensationValidator.class).in(Singleton.class);
|
||||
bind(CompensationProposalService.class).in(Singleton.class);
|
||||
|
||||
bind(ReimbursementValidator.class).in(Singleton.class);
|
||||
bind(ReimbursementProposalService.class).in(Singleton.class);
|
||||
|
||||
bind(ChangeParamValidator.class).in(Singleton.class);
|
||||
bind(ChangeParamProposalService.class).in(Singleton.class);
|
||||
|
||||
|
@ -41,6 +41,7 @@ import bisq.core.dao.governance.proposal.compensation.CompensationProposal;
|
||||
import bisq.core.dao.state.DaoStateListener;
|
||||
import bisq.core.dao.state.DaoStateService;
|
||||
import bisq.core.dao.state.blockchain.Block;
|
||||
import bisq.core.dao.state.governance.IssuanceType;
|
||||
import bisq.core.dao.state.period.DaoPhase;
|
||||
import bisq.core.dao.state.period.PeriodService;
|
||||
|
||||
@ -83,6 +84,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
/**
|
||||
* Publishes blind vote tx and blind vote payload to p2p network.
|
||||
* Maintains myBlindVoteList for own blind votes. Triggers republishing of my blind votes at startup during blind
|
||||
@ -278,8 +281,10 @@ public class MyBlindVoteListService implements PersistedDataHost, DaoStateListen
|
||||
.filter(txId -> periodService.isTxInPastCycle(txId, periodService.getChainHeight()))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return new MeritList(daoStateService.getIssuanceSet().stream()
|
||||
return new MeritList(daoStateService.getIssuanceSet(IssuanceType.COMPENSATION).stream()
|
||||
.map(issuance -> {
|
||||
checkArgument(issuance.getIssuanceType() == IssuanceType.COMPENSATION,
|
||||
"IssuanceType must be COMPENSATION for MeritList");
|
||||
// We check if it is our proposal
|
||||
if (!myCompensationProposalTxIs.contains(issuance.getTxId()))
|
||||
return null;
|
||||
|
@ -21,6 +21,7 @@ import bisq.core.dao.governance.voteresult.VoteResultException;
|
||||
import bisq.core.dao.state.DaoStateService;
|
||||
import bisq.core.dao.state.blockchain.Tx;
|
||||
import bisq.core.dao.state.governance.Issuance;
|
||||
import bisq.core.dao.state.governance.IssuanceType;
|
||||
|
||||
import bisq.common.crypto.Encryption;
|
||||
import bisq.common.util.Utilities;
|
||||
@ -68,8 +69,11 @@ public class MeritConsensus {
|
||||
.filter(merit -> isSignatureValid(merit.getSignature(), merit.getIssuance().getPubKey(), blindVoteTxId))
|
||||
.mapToLong(merit -> {
|
||||
try {
|
||||
return getWeightedMeritAmount(merit.getIssuance().getAmount(),
|
||||
merit.getIssuance().getChainHeight(),
|
||||
Issuance issuance = merit.getIssuance();
|
||||
checkArgument(issuance.getIssuanceType() == IssuanceType.COMPENSATION,
|
||||
"issuance must be of type COMPENSATION");
|
||||
return getWeightedMeritAmount(issuance.getAmount(),
|
||||
issuance.getChainHeight(),
|
||||
txChainHeight,
|
||||
BLOCKS_PER_YEAR);
|
||||
} catch (Throwable t) {
|
||||
@ -148,6 +152,7 @@ public class MeritConsensus {
|
||||
.mapToLong(merit -> {
|
||||
try {
|
||||
Issuance issuance = merit.getIssuance();
|
||||
checkArgument(issuance.getIssuanceType() == IssuanceType.COMPENSATION, "issuance must be of type COMPENSATION");
|
||||
int issuanceHeight = issuance.getChainHeight();
|
||||
checkArgument(issuanceHeight <= currentChainHeight,
|
||||
"issuanceHeight must not be larger as currentChainHeight");
|
||||
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.core.dao.governance.proposal;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
|
||||
/**
|
||||
* Marker interface for proposals which can lead to new BSQ issuance
|
||||
*/
|
||||
public interface IssuanceProposal {
|
||||
Coin getRequestedBsq();
|
||||
|
||||
String getBsqAddress();
|
||||
|
||||
String getTxId();
|
||||
}
|
@ -22,6 +22,7 @@ import bisq.core.dao.governance.proposal.compensation.CompensationProposal;
|
||||
import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposal;
|
||||
import bisq.core.dao.governance.proposal.generic.GenericProposal;
|
||||
import bisq.core.dao.governance.proposal.param.ChangeParamProposal;
|
||||
import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal;
|
||||
import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal;
|
||||
import bisq.core.dao.governance.proposal.role.BondedRoleProposal;
|
||||
import bisq.core.dao.state.blockchain.TxType;
|
||||
@ -93,6 +94,8 @@ public abstract class Proposal implements PersistablePayload, NetworkPayload, Co
|
||||
switch (proto.getMessageCase()) {
|
||||
case COMPENSATION_PROPOSAL:
|
||||
return CompensationProposal.fromProto(proto);
|
||||
case REIMBURSEMENT_PROPOSAL:
|
||||
return ReimbursementProposal.fromProto(proto);
|
||||
case CHANGE_PARAM_PROPOSAL:
|
||||
return ChangeParamProposal.fromProto(proto);
|
||||
case BONDED_ROLE_PROPOSAL:
|
||||
|
@ -21,6 +21,7 @@ import bisq.core.locale.Res;
|
||||
|
||||
public enum ProposalType {
|
||||
COMPENSATION_REQUEST,
|
||||
REIMBURSEMENT_REQUEST,
|
||||
CHANGE_PARAM,
|
||||
BONDED_ROLE,
|
||||
CONFISCATE_BOND,
|
||||
|
@ -19,6 +19,7 @@ package bisq.core.dao.governance.proposal;
|
||||
|
||||
import bisq.core.dao.exceptions.ValidationException;
|
||||
import bisq.core.dao.governance.proposal.compensation.CompensationProposal;
|
||||
import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal;
|
||||
import bisq.core.dao.state.DaoStateService;
|
||||
import bisq.core.dao.state.blockchain.Tx;
|
||||
import bisq.core.dao.state.blockchain.TxType;
|
||||
@ -112,7 +113,12 @@ public class ProposalValidator {
|
||||
}
|
||||
if (proposal instanceof CompensationProposal) {
|
||||
if (optionalTx.get().getTxType() != TxType.COMPENSATION_REQUEST) {
|
||||
log.error("TxType is not PROPOSAL. proposal.getTxId()={}", proposal.getTxId());
|
||||
log.error("TxType is not a COMPENSATION_REQUEST. proposal.getTxId()={}", proposal.getTxId());
|
||||
return false;
|
||||
}
|
||||
} else if (proposal instanceof ReimbursementProposal) {
|
||||
if (optionalTx.get().getTxType() != TxType.REIMBURSEMENT_REQUEST) {
|
||||
log.error("TxType is not a REIMBURSEMENT_REQUEST. proposal.getTxId()={}", proposal.getTxId());
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
@ -18,6 +18,7 @@
|
||||
package bisq.core.dao.governance.proposal.compensation;
|
||||
|
||||
import bisq.core.app.BisqEnvironment;
|
||||
import bisq.core.dao.governance.proposal.IssuanceProposal;
|
||||
import bisq.core.dao.governance.proposal.Proposal;
|
||||
import bisq.core.dao.governance.proposal.ProposalType;
|
||||
import bisq.core.dao.state.blockchain.TxType;
|
||||
@ -43,7 +44,7 @@ import javax.annotation.concurrent.Immutable;
|
||||
@Slf4j
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Value
|
||||
public final class CompensationProposal extends Proposal {
|
||||
public final class CompensationProposal extends Proposal implements IssuanceProposal {
|
||||
private final long requestedBsq;
|
||||
private final String bsqAddress;
|
||||
|
||||
|
@ -91,16 +91,20 @@ public class ChangeParamValidator extends ProposalValidator {
|
||||
break;
|
||||
|
||||
case COMPENSATION_REQUEST_MIN_AMOUNT:
|
||||
case REIMBURSEMENT_MIN_AMOUNT:
|
||||
if (paramValue < Restrictions.getMinNonDustOutput().value)
|
||||
throw new ChangeParamValidationException(Res.get("validation.amountBelowDust", Restrictions.getMinNonDustOutput().value));
|
||||
checkMinMax(param, paramValue, 100, -50);
|
||||
break;
|
||||
case COMPENSATION_REQUEST_MAX_AMOUNT:
|
||||
case REIMBURSEMENT_MAX_AMOUNT:
|
||||
checkMinMax(param, paramValue, 100, -50);
|
||||
break;
|
||||
|
||||
case QUORUM_COMP_REQUEST:
|
||||
break;
|
||||
case QUORUM_REIMBURSEMENT:
|
||||
break;
|
||||
case QUORUM_CHANGE_PARAM:
|
||||
break;
|
||||
case QUORUM_ROLE:
|
||||
@ -114,6 +118,8 @@ public class ChangeParamValidator extends ProposalValidator {
|
||||
|
||||
case THRESHOLD_COMP_REQUEST:
|
||||
break;
|
||||
case THRESHOLD_REIMBURSEMENT:
|
||||
break;
|
||||
case THRESHOLD_CHANGE_PARAM:
|
||||
break;
|
||||
case THRESHOLD_ROLE:
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.core.dao.governance.proposal.reimbursement;
|
||||
|
||||
import bisq.core.dao.state.DaoStateService;
|
||||
import bisq.core.dao.state.governance.Param;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class ReimbursementConsensus {
|
||||
public static Coin getMinReimbursementRequestAmount(DaoStateService daoStateService, int chainHeight) {
|
||||
return Coin.valueOf(daoStateService.getParamValue(Param.REIMBURSEMENT_MIN_AMOUNT, chainHeight));
|
||||
}
|
||||
|
||||
public static Coin getMaxReimbursementRequestAmount(DaoStateService daoStateService, int chainHeight) {
|
||||
return Coin.valueOf(daoStateService.getParamValue(Param.REIMBURSEMENT_MAX_AMOUNT, chainHeight));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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.core.dao.governance.proposal.reimbursement;
|
||||
|
||||
import bisq.core.app.BisqEnvironment;
|
||||
import bisq.core.dao.governance.proposal.IssuanceProposal;
|
||||
import bisq.core.dao.governance.proposal.Proposal;
|
||||
import bisq.core.dao.governance.proposal.ProposalType;
|
||||
import bisq.core.dao.state.blockchain.TxType;
|
||||
import bisq.core.dao.state.governance.Param;
|
||||
|
||||
import bisq.common.app.Version;
|
||||
|
||||
import io.bisq.generated.protobuffer.PB;
|
||||
|
||||
import org.bitcoinj.core.Address;
|
||||
import org.bitcoinj.core.AddressFormatException;
|
||||
import org.bitcoinj.core.Coin;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@Slf4j
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Value
|
||||
public final class ReimbursementProposal extends Proposal implements IssuanceProposal {
|
||||
private final long requestedBsq;
|
||||
private final String bsqAddress;
|
||||
|
||||
ReimbursementProposal(String name,
|
||||
String link,
|
||||
Coin requestedBsq,
|
||||
String bsqAddress) {
|
||||
this(name,
|
||||
link,
|
||||
bsqAddress,
|
||||
requestedBsq.value,
|
||||
Version.REIMBURSEMENT_REQUEST,
|
||||
new Date().getTime(),
|
||||
"");
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PROTO BUFFER
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private ReimbursementProposal(String name,
|
||||
String link,
|
||||
String bsqAddress,
|
||||
long requestedBsq,
|
||||
byte version,
|
||||
long creationDate,
|
||||
String txId) {
|
||||
super(name,
|
||||
link,
|
||||
version,
|
||||
creationDate,
|
||||
txId);
|
||||
|
||||
this.requestedBsq = requestedBsq;
|
||||
this.bsqAddress = bsqAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PB.Proposal.Builder getProposalBuilder() {
|
||||
final PB.ReimbursementProposal.Builder builder = PB.ReimbursementProposal.newBuilder()
|
||||
.setBsqAddress(bsqAddress)
|
||||
.setRequestedBsq(requestedBsq);
|
||||
return super.getProposalBuilder().setReimbursementProposal(builder);
|
||||
}
|
||||
|
||||
public static ReimbursementProposal fromProto(PB.Proposal proto) {
|
||||
final PB.ReimbursementProposal proposalProto = proto.getReimbursementProposal();
|
||||
return new ReimbursementProposal(proto.getName(),
|
||||
proto.getLink(),
|
||||
proposalProto.getBsqAddress(),
|
||||
proposalProto.getRequestedBsq(),
|
||||
(byte) proto.getVersion(),
|
||||
proto.getCreationDate(),
|
||||
proto.getTxId());
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Coin getRequestedBsq() {
|
||||
return Coin.valueOf(requestedBsq);
|
||||
}
|
||||
|
||||
public Address getAddress() throws AddressFormatException {
|
||||
// Remove leading 'B'
|
||||
String underlyingBtcAddress = bsqAddress.substring(1, bsqAddress.length());
|
||||
return Address.fromBase58(BisqEnvironment.getParameters(), underlyingBtcAddress);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ProposalType getType() {
|
||||
return ProposalType.REIMBURSEMENT_REQUEST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Param getQuorumParam() {
|
||||
return Param.QUORUM_REIMBURSEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Param getThresholdParam() {
|
||||
return Param.THRESHOLD_REIMBURSEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TxType getTxType() {
|
||||
return TxType.REIMBURSEMENT_REQUEST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Proposal cloneProposalAndAddTxId(String txId) {
|
||||
return new ReimbursementProposal(getName(),
|
||||
getLink(),
|
||||
getBsqAddress(),
|
||||
getRequestedBsq().value,
|
||||
getVersion(),
|
||||
getCreationDate().getTime(),
|
||||
txId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ReimbursementProposal{" +
|
||||
"\n requestedBsq=" + requestedBsq +
|
||||
",\n bsqAddress='" + bsqAddress + '\'' +
|
||||
"\n} " + super.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.core.dao.governance.proposal.reimbursement;
|
||||
|
||||
import bisq.core.btc.exceptions.TransactionVerificationException;
|
||||
import bisq.core.btc.exceptions.WalletException;
|
||||
import bisq.core.btc.wallet.BsqWalletService;
|
||||
import bisq.core.btc.wallet.BtcWalletService;
|
||||
import bisq.core.dao.exceptions.ValidationException;
|
||||
import bisq.core.dao.governance.proposal.BaseProposalService;
|
||||
import bisq.core.dao.governance.proposal.Proposal;
|
||||
import bisq.core.dao.governance.proposal.ProposalConsensus;
|
||||
import bisq.core.dao.governance.proposal.ProposalWithTransaction;
|
||||
import bisq.core.dao.governance.proposal.TxException;
|
||||
import bisq.core.dao.state.DaoStateService;
|
||||
import bisq.core.dao.state.blockchain.OpReturnType;
|
||||
|
||||
import bisq.common.app.Version;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.InsufficientMoneyException;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Creates the ReimbursementProposal and the transaction.
|
||||
*/
|
||||
@Slf4j
|
||||
public class ReimbursementProposalService extends BaseProposalService<ReimbursementProposal> {
|
||||
|
||||
private Coin requestedBsq;
|
||||
private String bsqAddress;
|
||||
|
||||
@Inject
|
||||
public ReimbursementProposalService(BsqWalletService bsqWalletService,
|
||||
BtcWalletService btcWalletService,
|
||||
DaoStateService daoStateService,
|
||||
ReimbursementValidator proposalValidator) {
|
||||
super(bsqWalletService,
|
||||
btcWalletService,
|
||||
daoStateService,
|
||||
proposalValidator);
|
||||
}
|
||||
|
||||
public ProposalWithTransaction createProposalWithTransaction(String name,
|
||||
String link,
|
||||
Coin requestedBsq)
|
||||
throws ValidationException, InsufficientMoneyException, TxException {
|
||||
this.requestedBsq = requestedBsq;
|
||||
this.bsqAddress = bsqWalletService.getUnusedBsqAddressAsString();
|
||||
|
||||
return super.createProposalWithTransaction(name, link);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReimbursementProposal createProposalWithoutTxId() {
|
||||
return new ReimbursementProposal(
|
||||
name,
|
||||
link,
|
||||
requestedBsq,
|
||||
bsqAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] getOpReturnData(byte[] hashOfPayload) {
|
||||
return ProposalConsensus.getOpReturnData(hashOfPayload,
|
||||
OpReturnType.REIMBURSEMENT_REQUEST.getType(),
|
||||
Version.REIMBURSEMENT_REQUEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Transaction completeTx(Transaction preparedBurnFeeTx, byte[] opReturnData, Proposal proposal)
|
||||
throws WalletException, InsufficientMoneyException, TransactionVerificationException {
|
||||
ReimbursementProposal reimbursementProposal = (ReimbursementProposal) proposal;
|
||||
return btcWalletService.completePreparedReimbursementRequestTx(
|
||||
reimbursementProposal.getRequestedBsq(),
|
||||
reimbursementProposal.getAddress(),
|
||||
preparedBurnFeeTx,
|
||||
opReturnData);
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.core.dao.governance.proposal.reimbursement;
|
||||
|
||||
import bisq.core.dao.exceptions.ValidationException;
|
||||
import bisq.core.dao.governance.proposal.Proposal;
|
||||
import bisq.core.dao.governance.proposal.ProposalValidator;
|
||||
import bisq.core.dao.state.DaoStateService;
|
||||
import bisq.core.dao.state.period.PeriodService;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static org.apache.commons.lang3.Validate.notEmpty;
|
||||
|
||||
@Slf4j
|
||||
public class ReimbursementValidator extends ProposalValidator {
|
||||
|
||||
@Inject
|
||||
public ReimbursementValidator(DaoStateService daoStateService, PeriodService periodService) {
|
||||
super(daoStateService, periodService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateDataFields(Proposal proposal) throws ValidationException {
|
||||
try {
|
||||
super.validateDataFields(proposal);
|
||||
|
||||
ReimbursementProposal reimbursementProposal = (ReimbursementProposal) proposal;
|
||||
String bsqAddress = reimbursementProposal.getBsqAddress();
|
||||
notEmpty(bsqAddress, "bsqAddress must not be empty");
|
||||
checkArgument(bsqAddress.substring(0, 1).equals("B"), "bsqAddress must start with B");
|
||||
reimbursementProposal.getAddress(); // throws AddressFormatException if wrong address
|
||||
|
||||
Coin requestedBsq = reimbursementProposal.getRequestedBsq();
|
||||
Coin maxReimbursementRequestAmount = ReimbursementConsensus.getMaxReimbursementRequestAmount(daoStateService, periodService.getChainHeight());
|
||||
checkArgument(requestedBsq.compareTo(maxReimbursementRequestAmount) <= 0,
|
||||
"Requested BSQ must not exceed " + (maxReimbursementRequestAmount.value / 100L) + " BSQ");
|
||||
Coin minReimbursementRequestAmount = ReimbursementConsensus.getMinReimbursementRequestAmount(daoStateService, periodService.getChainHeight());
|
||||
checkArgument(requestedBsq.compareTo(minReimbursementRequestAmount) >= 0,
|
||||
"Requested BSQ must not be less than " + (minReimbursementRequestAmount.value / 100L) + " BSQ");
|
||||
} catch (Throwable throwable) {
|
||||
throw new ValidationException(throwable);
|
||||
}
|
||||
}
|
||||
}
|
@ -30,9 +30,9 @@ import bisq.core.dao.governance.blindvote.VoteWithProposalTxId;
|
||||
import bisq.core.dao.governance.blindvote.VoteWithProposalTxIdList;
|
||||
import bisq.core.dao.governance.merit.MeritConsensus;
|
||||
import bisq.core.dao.governance.merit.MeritList;
|
||||
import bisq.core.dao.governance.proposal.IssuanceProposal;
|
||||
import bisq.core.dao.governance.proposal.Proposal;
|
||||
import bisq.core.dao.governance.proposal.ProposalListPresentation;
|
||||
import bisq.core.dao.governance.proposal.compensation.CompensationProposal;
|
||||
import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposal;
|
||||
import bisq.core.dao.governance.proposal.param.ChangeParamProposal;
|
||||
import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal;
|
||||
@ -564,8 +564,8 @@ public class VoteResultService implements DaoStateListener, DaoSetupService {
|
||||
private void applyIssuance(Set<EvaluatedProposal> acceptedEvaluatedProposals, int chainHeight) {
|
||||
acceptedEvaluatedProposals.stream()
|
||||
.map(EvaluatedProposal::getProposal)
|
||||
.filter(proposal -> proposal instanceof CompensationProposal)
|
||||
.forEach(proposal -> issuanceService.issueBsq((CompensationProposal) proposal, chainHeight));
|
||||
.filter(proposal -> proposal instanceof IssuanceProposal)
|
||||
.forEach(proposal -> issuanceService.issueBsq((IssuanceProposal) proposal, chainHeight));
|
||||
}
|
||||
|
||||
private void applyParamChange(Set<EvaluatedProposal> acceptedEvaluatedProposals, int chainHeight) {
|
||||
|
@ -17,12 +17,15 @@
|
||||
|
||||
package bisq.core.dao.governance.voteresult.issuance;
|
||||
|
||||
import bisq.core.dao.governance.proposal.IssuanceProposal;
|
||||
import bisq.core.dao.governance.proposal.compensation.CompensationProposal;
|
||||
import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal;
|
||||
import bisq.core.dao.state.DaoStateService;
|
||||
import bisq.core.dao.state.blockchain.Tx;
|
||||
import bisq.core.dao.state.blockchain.TxInput;
|
||||
import bisq.core.dao.state.blockchain.TxOutput;
|
||||
import bisq.core.dao.state.governance.Issuance;
|
||||
import bisq.core.dao.state.governance.IssuanceType;
|
||||
import bisq.core.dao.state.period.DaoPhase;
|
||||
import bisq.core.dao.state.period.PeriodService;
|
||||
|
||||
@ -32,6 +35,8 @@ import java.util.Optional;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
//TODO case that user misses reveal phase not impl. yet
|
||||
|
||||
@Slf4j
|
||||
@ -50,42 +55,51 @@ public class IssuanceService {
|
||||
this.periodService = periodService;
|
||||
}
|
||||
|
||||
public void issueBsq(CompensationProposal compensationProposal, int chainHeight) {
|
||||
public void issueBsq(IssuanceProposal issuanceProposal, int chainHeight) {
|
||||
daoStateService.getIssuanceCandidateTxOutputs().stream()
|
||||
.filter(txOutput -> isValid(txOutput, compensationProposal, periodService, chainHeight))
|
||||
.filter(txOutput -> isValid(txOutput, issuanceProposal, periodService, chainHeight))
|
||||
.forEach(txOutput -> {
|
||||
IssuanceType issuanceType = IssuanceType.UNDEFINED;
|
||||
if (issuanceProposal instanceof CompensationProposal) {
|
||||
issuanceType = IssuanceType.COMPENSATION;
|
||||
} else if (issuanceProposal instanceof ReimbursementProposal) {
|
||||
issuanceType = IssuanceType.REIMBURSEMENT;
|
||||
}
|
||||
checkArgument(issuanceType != IssuanceType.UNDEFINED, "issuanceType must not be undefined");
|
||||
|
||||
// We don't check atm if the output is unspent. We cannot use the bsqWallet as that would not
|
||||
// reflect our current block state (could have been spent at later block which is valid and
|
||||
// bsqWallet would show that spent state). We would need to support a spent status for the outputs
|
||||
// which are interpreted as BTC (as a not yet accepted comp. request).
|
||||
Optional<Tx> optionalTx = daoStateService.getTx(compensationProposal.getTxId());
|
||||
Optional<Tx> optionalTx = daoStateService.getTx(issuanceProposal.getTxId());
|
||||
if (optionalTx.isPresent()) {
|
||||
long amount = compensationProposal.getRequestedBsq().value;
|
||||
long amount = issuanceProposal.getRequestedBsq().value;
|
||||
Tx tx = optionalTx.get();
|
||||
// We use key from first input
|
||||
TxInput txInput = tx.getTxInputs().get(0);
|
||||
String pubKey = txInput.getPubKey();
|
||||
Issuance issuance = new Issuance(tx.getId(), chainHeight, amount, pubKey);
|
||||
Issuance issuance = new Issuance(tx.getId(), chainHeight, amount, pubKey, issuanceType);
|
||||
daoStateService.addIssuance(issuance);
|
||||
daoStateService.addUnspentTxOutput(txOutput);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("\n################################################################################\n");
|
||||
sb.append("We issued new BSQ to tx with ID ").append(txOutput.getTxId())
|
||||
.append("\nIssued BSQ: ").append(compensationProposal.getRequestedBsq())
|
||||
.append("\nIssued BSQ: ").append(issuanceProposal.getRequestedBsq())
|
||||
.append("\nIssuance type: ").append(issuanceType.name())
|
||||
.append("\n################################################################################\n");
|
||||
log.info(sb.toString());
|
||||
} else {
|
||||
//TODO throw exception
|
||||
log.error("Tx for compensation request not found. txId={}", compensationProposal.getTxId());
|
||||
log.error("Tx for compensation request not found. txId={}", issuanceProposal.getTxId());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isValid(TxOutput txOutput, CompensationProposal compensationProposal, PeriodService periodService, int chainHeight) {
|
||||
return txOutput.getTxId().equals(compensationProposal.getTxId())
|
||||
&& compensationProposal.getRequestedBsq().value == txOutput.getValue()
|
||||
&& compensationProposal.getBsqAddress().substring(1).equals(txOutput.getAddress())
|
||||
private boolean isValid(TxOutput txOutput, IssuanceProposal issuanceProposal, PeriodService periodService, int chainHeight) {
|
||||
return txOutput.getTxId().equals(issuanceProposal.getTxId())
|
||||
&& issuanceProposal.getRequestedBsq().value == txOutput.getValue()
|
||||
&& issuanceProposal.getBsqAddress().substring(1).equals(txOutput.getAddress())
|
||||
&& periodService.isTxInPhaseAndCycle(txOutput.getTxId(), DaoPhase.Phase.PROPOSAL, chainHeight);
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ enum JsonTxOutputType {
|
||||
BTC_OUTPUT("BTC"),
|
||||
PROPOSAL_OP_RETURN_OUTPUT("Proposal opReturn"),
|
||||
COMP_REQ_OP_RETURN_OUTPUT("Compensation request opReturn"),
|
||||
REIMBURSEMENT_OP_RETURN_OUTPUT("Reimbursement request opReturn"),
|
||||
CONFISCATE_BOND_OP_RETURN_OUTPUT("Confiscate bond opReturn"),
|
||||
ISSUANCE_CANDIDATE_OUTPUT("Issuance candidate"),
|
||||
BLIND_VOTE_LOCK_STAKE_OUTPUT("Blind vote lock stake"),
|
||||
|
@ -29,6 +29,7 @@ enum JsonTxType {
|
||||
PAY_TRADE_FEE("Pay trade fee"),
|
||||
PROPOSAL("Proposal"),
|
||||
COMPENSATION_REQUEST("Compensation request"),
|
||||
REIMBURSEMENT_REQUEST("Reimbursement request"),
|
||||
BLIND_VOTE("Blind vote"),
|
||||
VOTE_REVEAL("Vote reveal"),
|
||||
LOCKUP("Lockup"),
|
||||
|
@ -90,6 +90,11 @@ class OpReturnParser {
|
||||
return TxOutputType.COMP_REQ_OP_RETURN_OUTPUT;
|
||||
else
|
||||
break;
|
||||
case REIMBURSEMENT_REQUEST:
|
||||
if (ProposalConsensus.hasOpReturnDataValidLength(opReturnData))
|
||||
return TxOutputType.REIMBURSEMENT_OP_RETURN_OUTPUT;
|
||||
else
|
||||
break;
|
||||
case BLIND_VOTE:
|
||||
if (BlindVoteConsensus.hasOpReturnDataValidLength(opReturnData))
|
||||
return TxOutputType.BLIND_VOTE_OP_RETURN_OUTPUT;
|
||||
|
@ -83,6 +83,7 @@ public class TxInputParser {
|
||||
case BTC_OUTPUT:
|
||||
case PROPOSAL_OP_RETURN_OUTPUT:
|
||||
case COMP_REQ_OP_RETURN_OUTPUT:
|
||||
case REIMBURSEMENT_OP_RETURN_OUTPUT:
|
||||
case CONFISCATE_BOND_OP_RETURN_OUTPUT:
|
||||
case ISSUANCE_CANDIDATE_OUTPUT:
|
||||
break;
|
||||
|
@ -205,7 +205,8 @@ public class TxOutputParser {
|
||||
if (availableInputValue > 0 &&
|
||||
index == 1 &&
|
||||
optionalOpReturnType.isPresent() &&
|
||||
optionalOpReturnType.get() == OpReturnType.COMPENSATION_REQUEST) {
|
||||
(optionalOpReturnType.get() == OpReturnType.COMPENSATION_REQUEST ||
|
||||
optionalOpReturnType.get() == OpReturnType.REIMBURSEMENT_REQUEST)) {
|
||||
optionalIssuanceCandidate = Optional.of(txOutput);
|
||||
} else {
|
||||
txOutput.setTxOutputType(TxOutputType.BTC_OUTPUT);
|
||||
@ -225,6 +226,8 @@ public class TxOutputParser {
|
||||
return Optional.of(OpReturnType.PROPOSAL);
|
||||
case COMP_REQ_OP_RETURN_OUTPUT:
|
||||
return Optional.of(OpReturnType.COMPENSATION_REQUEST);
|
||||
case REIMBURSEMENT_OP_RETURN_OUTPUT:
|
||||
return Optional.of(OpReturnType.REIMBURSEMENT_REQUEST);
|
||||
case BLIND_VOTE_OP_RETURN_OUTPUT:
|
||||
return Optional.of(OpReturnType.BLIND_VOTE);
|
||||
case VOTE_REVEAL_OP_RETURN_OUTPUT:
|
||||
|
@ -195,7 +195,8 @@ public class TxParser {
|
||||
processProposal(blockHeight, tempTx, bsqFee);
|
||||
break;
|
||||
case COMPENSATION_REQUEST:
|
||||
processCompensationRequest(blockHeight, tempTx, bsqFee);
|
||||
case REIMBURSEMENT_REQUEST:
|
||||
processIssuance(blockHeight, tempTx, bsqFee);
|
||||
break;
|
||||
case BLIND_VOTE:
|
||||
processBlindVote(blockHeight, tempTx, bsqFee);
|
||||
@ -211,7 +212,7 @@ public class TxParser {
|
||||
|
||||
// We need to check if any tempTxOutput is available and if so and the OpReturn data is invalid we
|
||||
// set the output to a BTC output. We must not use `if else` cases here!
|
||||
if (opReturnType != OpReturnType.COMPENSATION_REQUEST) {
|
||||
if (opReturnType != OpReturnType.COMPENSATION_REQUEST && opReturnType != OpReturnType.REIMBURSEMENT_REQUEST) {
|
||||
txOutputParser.getOptionalIssuanceCandidate().ifPresent(tempTxOutput -> tempTxOutput.setTxOutputType(TxOutputType.BTC_OUTPUT));
|
||||
}
|
||||
|
||||
@ -235,7 +236,7 @@ public class TxParser {
|
||||
}
|
||||
}
|
||||
|
||||
private void processCompensationRequest(int blockHeight, TempTx tempTx, long bsqFee) {
|
||||
private void processIssuance(int blockHeight, TempTx tempTx, long bsqFee) {
|
||||
boolean isFeeAndPhaseValid = isFeeAndPhaseValid(blockHeight, bsqFee, DaoPhase.Phase.PROPOSAL, Param.PROPOSAL_FEE);
|
||||
Optional<TempTxOutput> optionalIssuanceCandidate = txOutputParser.getOptionalIssuanceCandidate();
|
||||
if (isFeeAndPhaseValid) {
|
||||
@ -400,21 +401,24 @@ public class TxParser {
|
||||
case PROPOSAL:
|
||||
return TxType.PROPOSAL;
|
||||
case COMPENSATION_REQUEST:
|
||||
case REIMBURSEMENT_REQUEST:
|
||||
boolean hasCorrectNumOutputs = tempTx.getTempTxOutputs().size() >= 3;
|
||||
if (!hasCorrectNumOutputs) {
|
||||
log.warn("Compensation request tx need to have at least 3 outputs");
|
||||
log.warn("Compensation/reimbursement request tx need to have at least 3 outputs");
|
||||
return TxType.INVALID;
|
||||
}
|
||||
|
||||
TempTxOutput issuanceTxOutput = tempTx.getTempTxOutputs().get(1);
|
||||
boolean hasIssuanceOutput = issuanceTxOutput.getTxOutputType() == TxOutputType.ISSUANCE_CANDIDATE_OUTPUT;
|
||||
if (!hasIssuanceOutput) {
|
||||
log.warn("Compensation request txOutput type of output at index 1 need to be ISSUANCE_CANDIDATE_OUTPUT. " +
|
||||
log.warn("Compensation/reimbursement request txOutput type of output at index 1 need to be ISSUANCE_CANDIDATE_OUTPUT. " +
|
||||
"TxOutputType={}", issuanceTxOutput.getTxOutputType());
|
||||
return TxType.INVALID;
|
||||
}
|
||||
|
||||
return TxType.COMPENSATION_REQUEST;
|
||||
return opReturnType == OpReturnType.COMPENSATION_REQUEST ?
|
||||
TxType.COMPENSATION_REQUEST :
|
||||
TxType.REIMBURSEMENT_REQUEST;
|
||||
case BLIND_VOTE:
|
||||
return TxType.BLIND_VOTE;
|
||||
case VOTE_REVEAL:
|
||||
|
@ -32,6 +32,7 @@ import bisq.core.dao.state.blockchain.TxOutputType;
|
||||
import bisq.core.dao.state.blockchain.TxType;
|
||||
import bisq.core.dao.state.governance.ConfiscateBond;
|
||||
import bisq.core.dao.state.governance.Issuance;
|
||||
import bisq.core.dao.state.governance.IssuanceType;
|
||||
import bisq.core.dao.state.governance.Param;
|
||||
import bisq.core.dao.state.governance.ParamChange;
|
||||
import bisq.core.dao.state.period.Cycle;
|
||||
@ -407,6 +408,7 @@ public class DaoStateService implements DaoSetupService {
|
||||
return false;
|
||||
case PROPOSAL_OP_RETURN_OUTPUT:
|
||||
case COMP_REQ_OP_RETURN_OUTPUT:
|
||||
case REIMBURSEMENT_OP_RETURN_OUTPUT:
|
||||
case ISSUANCE_CANDIDATE_OUTPUT:
|
||||
return true;
|
||||
case BLIND_VOTE_LOCK_STAKE_OUTPUT:
|
||||
@ -451,6 +453,7 @@ public class DaoStateService implements DaoSetupService {
|
||||
return false;
|
||||
case PROPOSAL_OP_RETURN_OUTPUT:
|
||||
case COMP_REQ_OP_RETURN_OUTPUT:
|
||||
case REIMBURSEMENT_OP_RETURN_OUTPUT:
|
||||
return true;
|
||||
case ISSUANCE_CANDIDATE_OUTPUT:
|
||||
return isIssuanceTx(txOutput.getTxId());
|
||||
@ -502,31 +505,42 @@ public class DaoStateService implements DaoSetupService {
|
||||
daoState.getIssuanceMap().put(issuance.getTxId(), issuance);
|
||||
}
|
||||
|
||||
public Set<Issuance> getIssuanceSet() {
|
||||
return new HashSet<>(daoState.getIssuanceMap().values());
|
||||
public Set<Issuance> getIssuanceSet(IssuanceType issuanceType) {
|
||||
return daoState.getIssuanceMap().values().stream()
|
||||
.filter(issuance -> issuance.getIssuanceType() == issuanceType)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public Optional<Issuance> getIssuance(String txId, IssuanceType issuanceType) {
|
||||
return daoState.getIssuanceMap().values().stream()
|
||||
.filter(issuance -> issuance.getTxId().equals(txId))
|
||||
.filter(issuance -> issuance.getIssuanceType() == issuanceType)
|
||||
.findAny();
|
||||
}
|
||||
|
||||
public Optional<Issuance> getIssuance(String txId) {
|
||||
if (daoState.getIssuanceMap().containsKey(txId))
|
||||
return Optional.of(daoState.getIssuanceMap().get(txId));
|
||||
else
|
||||
return Optional.empty();
|
||||
return daoState.getIssuanceMap().values().stream()
|
||||
.filter(issuance -> issuance.getTxId().equals(txId))
|
||||
.findAny();
|
||||
}
|
||||
|
||||
//TODO rename acceptedIssuanceTx
|
||||
public boolean isIssuanceTx(String txId) {
|
||||
return getIssuance(txId).isPresent();
|
||||
}
|
||||
|
||||
public boolean isIssuanceTx(String txId, IssuanceType issuanceType) {
|
||||
return getIssuance(txId, issuanceType).isPresent();
|
||||
}
|
||||
|
||||
public int getIssuanceBlockHeight(String txId) {
|
||||
return getIssuance(txId)
|
||||
.map(Issuance::getChainHeight)
|
||||
.orElse(0);
|
||||
}
|
||||
|
||||
public long getTotalIssuedAmount() {
|
||||
public long getTotalIssuedAmount(IssuanceType issuanceType) {
|
||||
return getIssuanceCandidateTxOutputs().stream()
|
||||
.filter(txOutput -> isIssuanceTx(txOutput.getTxId()))
|
||||
.filter(txOutput -> isIssuanceTx(txOutput.getTxId(), issuanceType))
|
||||
.mapToLong(TxOutput::getValue)
|
||||
.sum();
|
||||
}
|
||||
|
@ -30,9 +30,10 @@ public enum OpReturnType {
|
||||
//TODO add undefined ?
|
||||
PROPOSAL((byte) 0x10),
|
||||
COMPENSATION_REQUEST((byte) 0x11),
|
||||
BLIND_VOTE((byte) 0x12),
|
||||
VOTE_REVEAL((byte) 0x13),
|
||||
LOCKUP((byte) 0x14);
|
||||
REIMBURSEMENT_REQUEST((byte) 0x12),
|
||||
BLIND_VOTE((byte) 0x13),
|
||||
VOTE_REVEAL((byte) 0x14),
|
||||
LOCKUP((byte) 0x15);
|
||||
|
||||
@Getter
|
||||
private byte type;
|
||||
|
@ -28,6 +28,7 @@ public enum TxOutputType {
|
||||
BTC_OUTPUT,
|
||||
PROPOSAL_OP_RETURN_OUTPUT,
|
||||
COMP_REQ_OP_RETURN_OUTPUT,
|
||||
REIMBURSEMENT_OP_RETURN_OUTPUT,
|
||||
CONFISCATE_BOND_OP_RETURN_OUTPUT,
|
||||
ISSUANCE_CANDIDATE_OUTPUT,
|
||||
BLIND_VOTE_LOCK_STAKE_OUTPUT,
|
||||
|
@ -34,6 +34,7 @@ public enum TxType {
|
||||
PAY_TRADE_FEE(false, true),
|
||||
PROPOSAL(true, true),
|
||||
COMPENSATION_REQUEST(true, true),
|
||||
REIMBURSEMENT_REQUEST(true, true),
|
||||
BLIND_VOTE(true, true),
|
||||
VOTE_REVEAL(true, false),
|
||||
LOCKUP(true, false),
|
||||
|
@ -17,13 +17,12 @@
|
||||
|
||||
package bisq.core.dao.state.governance;
|
||||
|
||||
import bisq.common.proto.ProtoUtil;
|
||||
import bisq.common.proto.network.NetworkPayload;
|
||||
import bisq.common.proto.persistable.PersistablePayload;
|
||||
|
||||
import io.bisq.generated.protobuffer.PB;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import lombok.Value;
|
||||
@ -45,12 +44,14 @@ public class Issuance implements PersistablePayload, NetworkPayload {
|
||||
@Nullable
|
||||
private final String pubKey; // sig key as hex of first input in issuance tx
|
||||
|
||||
@Inject
|
||||
public Issuance(String txId, int chainHeight, long amount, @Nullable String pubKey) {
|
||||
private final IssuanceType issuanceType;
|
||||
|
||||
public Issuance(String txId, int chainHeight, long amount, @Nullable String pubKey, IssuanceType issuanceType) {
|
||||
this.txId = txId;
|
||||
this.chainHeight = chainHeight;
|
||||
this.amount = amount;
|
||||
this.pubKey = pubKey;
|
||||
this.issuanceType = issuanceType;
|
||||
}
|
||||
|
||||
|
||||
@ -62,7 +63,8 @@ public class Issuance implements PersistablePayload, NetworkPayload {
|
||||
final PB.Issuance.Builder builder = PB.Issuance.newBuilder()
|
||||
.setTxId(txId)
|
||||
.setChainHeight(chainHeight)
|
||||
.setAmount(amount);
|
||||
.setAmount(amount)
|
||||
.setIssuanceType(issuanceType.name());
|
||||
|
||||
Optional.ofNullable(pubKey).ifPresent(e -> builder.setPubKey(pubKey));
|
||||
|
||||
@ -73,7 +75,8 @@ public class Issuance implements PersistablePayload, NetworkPayload {
|
||||
return new Issuance(proto.getTxId(),
|
||||
proto.getChainHeight(),
|
||||
proto.getAmount(),
|
||||
proto.getPubKey().isEmpty() ? null : proto.getPubKey());
|
||||
proto.getPubKey().isEmpty() ? null : proto.getPubKey(),
|
||||
proto.getIssuanceType().isEmpty() ? IssuanceType.UNDEFINED : ProtoUtil.enumFromProto(IssuanceType.class, proto.getIssuanceType()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -83,6 +86,7 @@ public class Issuance implements PersistablePayload, NetworkPayload {
|
||||
",\n chainHeight=" + chainHeight +
|
||||
",\n amount=" + amount +
|
||||
",\n pubKey='" + pubKey + '\'' +
|
||||
",\n issuanceType='" + issuanceType + '\'' +
|
||||
"\n}";
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.core.dao.state.governance;
|
||||
|
||||
public enum IssuanceType {
|
||||
UNDEFINED,
|
||||
COMPENSATION,
|
||||
REIMBURSEMENT
|
||||
}
|
@ -67,12 +67,15 @@ public enum Param {
|
||||
// As BSQ based validation values can change over time if BSQ value rise we need to support that in the Params as well
|
||||
COMPENSATION_REQUEST_MIN_AMOUNT(1_000), // 10 BSQ
|
||||
COMPENSATION_REQUEST_MAX_AMOUNT(10_000_000), // 100 000 BSQ
|
||||
REIMBURSEMENT_MIN_AMOUNT(1_000), // 10 BSQ
|
||||
REIMBURSEMENT_MAX_AMOUNT(1_000_000), // 10 000 BSQ
|
||||
|
||||
// Quorum required for voting result to be valid.
|
||||
// Quorum is the min. amount of total BSQ (earned+stake) which was used for voting on a request.
|
||||
// E.g. If only 2000 BSQ was used on a vote but 10 000 is required the result is invalid even if the voters voted
|
||||
// 100% for acceptance. This should prevent that changes can be done with low stakeholder participation.
|
||||
QUORUM_COMP_REQUEST(2_000_000), // 20 000 BSQ
|
||||
QUORUM_REIMBURSEMENT(2_000_000), // 20 000 BSQ
|
||||
QUORUM_CHANGE_PARAM(10_000_000), // 100 000 BSQ
|
||||
QUORUM_ROLE(5_000_000), // 50 000 BSQ
|
||||
QUORUM_CONFISCATION(20_000_000), // 200 000 BSQ
|
||||
@ -85,6 +88,7 @@ public enum Param {
|
||||
// The result must be larger than the threshold. A 50% vote result for a threshold with 50% is not sufficient,
|
||||
// it requires min. 50.01%.
|
||||
THRESHOLD_COMP_REQUEST(5_000), // 50%
|
||||
THRESHOLD_REIMBURSEMENT(5_000), // 50%
|
||||
THRESHOLD_CHANGE_PARAM(7_500), // 75% That might change the THRESHOLD_CHANGE_PARAM and QUORUM_CHANGE_PARAM as well. So we have to be careful here!
|
||||
THRESHOLD_ROLE(5_000), // 50%
|
||||
THRESHOLD_CONFISCATION(8_500), // 85% Confiscation is considered an exceptional case and need very high consensus among the stakeholders.
|
||||
|
@ -134,9 +134,12 @@ public class BsqFormatter extends BSFormatter {
|
||||
case BLIND_VOTE_FEE:
|
||||
case COMPENSATION_REQUEST_MIN_AMOUNT:
|
||||
case COMPENSATION_REQUEST_MAX_AMOUNT:
|
||||
case REIMBURSEMENT_MIN_AMOUNT:
|
||||
case REIMBURSEMENT_MAX_AMOUNT:
|
||||
return formatCoinWithCode(Coin.valueOf(value));
|
||||
|
||||
case QUORUM_COMP_REQUEST:
|
||||
case QUORUM_REIMBURSEMENT:
|
||||
case QUORUM_CHANGE_PARAM:
|
||||
case QUORUM_ROLE:
|
||||
case QUORUM_CONFISCATION:
|
||||
@ -145,6 +148,7 @@ public class BsqFormatter extends BSFormatter {
|
||||
return formatCoinWithCode(Coin.valueOf(value));
|
||||
|
||||
case THRESHOLD_COMP_REQUEST:
|
||||
case THRESHOLD_REIMBURSEMENT:
|
||||
case THRESHOLD_CHANGE_PARAM:
|
||||
case THRESHOLD_ROLE:
|
||||
case THRESHOLD_CONFISCATION:
|
||||
@ -183,10 +187,13 @@ public class BsqFormatter extends BSFormatter {
|
||||
case BLIND_VOTE_FEE:
|
||||
case COMPENSATION_REQUEST_MIN_AMOUNT:
|
||||
case COMPENSATION_REQUEST_MAX_AMOUNT:
|
||||
case REIMBURSEMENT_MIN_AMOUNT:
|
||||
case REIMBURSEMENT_MAX_AMOUNT:
|
||||
return parseToCoin(inputValue).value;
|
||||
|
||||
|
||||
case QUORUM_COMP_REQUEST:
|
||||
case QUORUM_REIMBURSEMENT:
|
||||
case QUORUM_CHANGE_PARAM:
|
||||
case QUORUM_ROLE:
|
||||
case QUORUM_CONFISCATION:
|
||||
@ -196,6 +203,7 @@ public class BsqFormatter extends BSFormatter {
|
||||
|
||||
|
||||
case THRESHOLD_COMP_REQUEST:
|
||||
case THRESHOLD_REIMBURSEMENT:
|
||||
case THRESHOLD_CHANGE_PARAM:
|
||||
case THRESHOLD_ROLE:
|
||||
case THRESHOLD_CONFISCATION:
|
||||
|
@ -189,6 +189,8 @@ shared.tradingFeeInBsqInfo=equivalent to {0} used as mining fee
|
||||
shared.openURL=Open {0}
|
||||
shared.fiat=Fiat
|
||||
shared.crypto=Crypto
|
||||
shared.all=All
|
||||
shared.edit=Edit
|
||||
|
||||
|
||||
####################################################################
|
||||
@ -210,8 +212,8 @@ mainView.menu.account=Account
|
||||
mainView.menu.dao=DAO
|
||||
|
||||
mainView.marketPrice.provider=Price by
|
||||
mainView.marketPrice.label=Market Price
|
||||
mainView.marketPriceWithProvider.label=Market Price by {0}
|
||||
mainView.marketPrice.label=Market price
|
||||
mainView.marketPriceWithProvider.label=Market price by {0}
|
||||
mainView.marketPrice.tooltip.provider=The displayed price is provided by {0}
|
||||
mainView.marketPrice.bisqInternalPrice=Price of latest Bisq trade
|
||||
mainView.marketPrice.tooltip.bisqInternalPrice=There is no market price from external price feed providers available.\n\
|
||||
@ -751,7 +753,9 @@ 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.proposal=Proposal
|
||||
funds.tx.proposalTxFee=Miner fee for proposal
|
||||
funds.tx.reimbursementRequestTxFee=Reimbursement request
|
||||
funds.tx.compensationRequestTxFee=Compensation request
|
||||
|
||||
|
||||
####################################################################
|
||||
@ -840,14 +844,14 @@ setting.preferences.useCustomValue=Use custom value
|
||||
setting.preferences.txFeeMin=Transaction fee must be at least {0} satoshis/byte
|
||||
setting.preferences.txFeeTooLarge=Your input is above any reasonable value (>5000 satoshis/byte). Transaction fee is usually in the range of 50-400 satoshis/byte.
|
||||
setting.preferences.ignorePeers=Ignore peers with onion address (comma sep.)
|
||||
setting.preferences.refererId=Referral ID:
|
||||
setting.preferences.refererId=Referral ID
|
||||
setting.preferences.refererId.prompt=Optional referral ID
|
||||
setting.preferences.currenciesInList=Currencies in market price feed list
|
||||
setting.preferences.prefCurrency=Preferred currency:
|
||||
setting.preferences.prefCurrency=Preferred currency
|
||||
setting.preferences.displayFiat=Display national currencies
|
||||
setting.preferences.noFiat=There are no national currencies selected
|
||||
setting.preferences.cannotRemovePrefCurrency=You cannot remove your selected preferred display currency
|
||||
setting.preferences.displayAltcoins=Display altcoins:
|
||||
setting.preferences.displayAltcoins=Display altcoins
|
||||
setting.preferences.noAltcoins=There are no altcoins selected
|
||||
setting.preferences.addFiat=Add national currency
|
||||
setting.preferences.addAltcoin=Add altcoin
|
||||
@ -861,7 +865,7 @@ settings.preferences.languageChange=To apply the language change to all screens
|
||||
settings.preferences.arbitrationLanguageWarning=In case of a dispute, please note that arbitration is handled in {0}.
|
||||
settings.preferences.selectCurrencyNetwork=Select network
|
||||
setting.preferences.daoOptions=DAO options
|
||||
setting.preferences.dao.resync.label=Rebuild DAO state from genesis tx:
|
||||
setting.preferences.dao.resync.label=Rebuild DAO state from genesis tx
|
||||
setting.preferences.dao.resync.button=Resync
|
||||
setting.preferences.dao.resync.popup=After an application restart the BSQ consensus state will be rebuilt from the genesis transaction.
|
||||
setting.preferences.dao.isDaoFullNode=Run Bisq as DAO full node
|
||||
@ -961,7 +965,7 @@ account.menu.seedWords=Wallet seed
|
||||
account.menu.backup=Backup
|
||||
account.menu.notifications=Notifications
|
||||
|
||||
account.arbitratorRegistration.pubKey=Public key:
|
||||
account.arbitratorRegistration.pubKey=Public key
|
||||
|
||||
account.arbitratorRegistration.register=Register arbitrator
|
||||
account.arbitratorRegistration.revoke=Revoke registration
|
||||
@ -1173,12 +1177,12 @@ dao.proposal.menuItem.vote=Vote on proposals
|
||||
dao.proposal.menuItem.result=Vote results
|
||||
dao.cycle.headline=Voting cycle
|
||||
dao.cycle.overview.headline=Voting cycle overview
|
||||
dao.cycle.currentPhase=Current phase:
|
||||
dao.cycle.currentBlockHeight=Current block height:
|
||||
dao.cycle.proposal=Proposal phase:
|
||||
dao.cycle.blindVote=Blind vote phase:
|
||||
dao.cycle.voteReveal=Vote reveal phase:
|
||||
dao.cycle.voteResult=Vote result:
|
||||
dao.cycle.currentPhase=Current phase
|
||||
dao.cycle.currentBlockHeight=Current block height
|
||||
dao.cycle.proposal=Proposal phase
|
||||
dao.cycle.blindVote=Blind vote phase
|
||||
dao.cycle.voteReveal=Vote reveal phase
|
||||
dao.cycle.voteResult=Vote result
|
||||
dao.cycle.phaseDuration={0} blocks (≈{1}); Block {2} - {3} (≈{4} - ≈{5})
|
||||
|
||||
dao.cycle.info.headline=Information
|
||||
@ -1233,12 +1237,18 @@ dao.param.BLIND_VOTE_FEE=Voting fee in BSQ
|
||||
dao.param.COMPENSATION_REQUEST_MIN_AMOUNT=Compensation request min. BSQ amount
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.param.COMPENSATION_REQUEST_MAX_AMOUNT=Compensation request max. BSQ amount
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.param.REIMBURSEMENT_MIN_AMOUNT=Reimbursement request min. BSQ amount
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.param.REIMBURSEMENT_MAX_AMOUNT=Reimbursement request max. BSQ amount
|
||||
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.param.QUORUM_GENERIC=Required quorum in BSQ for generic proposal
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.param.QUORUM_COMP_REQUEST=Required quorum in BSQ for compensation request
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.param.QUORUM_REIMBURSEMENT=Required quorum in BSQ for reimbursement request
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.param.QUORUM_CHANGE_PARAM=Required quorum in BSQ for changing a parameter
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.param.QUORUM_REMOVE_ASSET=Required quorum in BSQ for removing an asset
|
||||
@ -1254,6 +1264,8 @@ dao.param.THRESHOLD_GENERIC=Required threshold in % for generic proposal
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.param.THRESHOLD_COMP_REQUEST=Required threshold in % for compensation request
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.param.THRESHOLD_REIMBURSEMENT=Required threshold in % for reimbursement request
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.param.THRESHOLD_CHANGE_PARAM=Required threshold in % for changing a parameter
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.param.THRESHOLD_REMOVE_ASSET=Required threshold in % for removing an asset
|
||||
@ -1300,10 +1312,10 @@ dao.bonding.menuItem.bondedRoles=Bonded roles
|
||||
dao.bonding.menuItem.lockupBSQ=Lockup BSQ
|
||||
dao.bonding.menuItem.unlockBSQ=Unlock BSQ
|
||||
dao.bonding.lock.lockBSQ=Lockup BSQ
|
||||
dao.bonding.lock.amount=Amount of BSQ to lockup:
|
||||
dao.bonding.lock.time=Unlock time in blocks:
|
||||
dao.bonding.lock.type=Type of bond:
|
||||
dao.bonding.lock.bondedRoles=Bonded roles:
|
||||
dao.bonding.lock.amount=Amount of BSQ to lockup
|
||||
dao.bonding.lock.time=Unlock time in blocks
|
||||
dao.bonding.lock.type=Type of bond
|
||||
dao.bonding.lock.bondedRoles=Bonded roles
|
||||
dao.bonding.lock.setAmount=Set BSQ amount to lockup (min. amount is {0})
|
||||
dao.bonding.lock.setTime=Number of blocks when locked funds become spendable after the unlock transaction ({0} - {1})
|
||||
dao.bonding.lock.lockupButton=Lockup
|
||||
@ -1314,8 +1326,8 @@ dao.bonding.unlock.unlock=Unlock
|
||||
dao.bonding.unlock.sendTx.headline=Confirm unlock transaction
|
||||
dao.bonding.unlock.sendTx.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed?
|
||||
dao.bonding.dashboard.bondsHeadline=Bonded BSQ
|
||||
dao.bonding.dashboard.lockupAmount=Lockup funds:
|
||||
dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over):
|
||||
dao.bonding.dashboard.lockupAmount=Lockup funds
|
||||
dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over)
|
||||
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.bond.lockupType.BONDED_ROLE=Bonded role
|
||||
@ -1382,6 +1394,8 @@ dao.phase.separatedPhaseBar.RESULT=Vote result
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.proposal.type.COMPENSATION_REQUEST=Compensation request
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.proposal.type.REIMBURSEMENT_REQUEST=Reimbursement request
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.proposal.type.BONDED_ROLE=Proposal for a bonded role
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.proposal.type.REMOVE_ASSET=Proposal for removing an asset
|
||||
@ -1395,6 +1409,8 @@ dao.proposal.type.CONFISCATE_BOND=Proposal for confiscating a bond
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.proposal.type.short.COMPENSATION_REQUEST=Compensation request
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.proposal.type.short.REIMBURSEMENT_REQUEST=Reimbursement request
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.proposal.type.short.BONDED_ROLE=Bonded role
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.proposal.type.short.REMOVE_ASSET=Removing an altcoin
|
||||
@ -1430,15 +1446,15 @@ dao.proposal.create.createNew=Make new proposal
|
||||
dao.proposal.create.create.button=Make proposal
|
||||
dao.proposal=proposal
|
||||
dao.proposal.display.type=Proposal type
|
||||
dao.proposal.display.name=Name/nickname:
|
||||
dao.proposal.display.link=Link to detail info:
|
||||
dao.proposal.display.name=Name/nickname
|
||||
dao.proposal.display.link=Link to detail info
|
||||
dao.proposal.display.link.prompt=Link to Github issue (https://github.com/bisq-network/compensation/issues)
|
||||
dao.proposal.display.requestedBsq=Requested amount in BSQ:
|
||||
dao.proposal.display.bsqAddress=BSQ address:
|
||||
dao.proposal.display.txId=Proposal transaction ID:
|
||||
dao.proposal.display.proposalFee=Proposal fee:
|
||||
dao.proposal.display.myVote=My vote:
|
||||
dao.proposal.display.voteResult=Vote result summary:
|
||||
dao.proposal.display.requestedBsq=Requested amount in BSQ
|
||||
dao.proposal.display.bsqAddress=BSQ address
|
||||
dao.proposal.display.txId=Proposal transaction ID
|
||||
dao.proposal.display.proposalFee=Proposal fee
|
||||
dao.proposal.display.myVote=My vote
|
||||
dao.proposal.display.voteResult=Vote result summary
|
||||
dao.proposal.display.bondedRoleComboBox.label=Bonded role type
|
||||
dao.proposal.display.requiredBondForRole.label=Required bond for role
|
||||
dao.proposal.display.tickerSymbol.label=Ticker Symbol
|
||||
@ -1458,7 +1474,7 @@ dao.proposal.voteResult.failed=Rejected
|
||||
dao.proposal.voteResult.summary=Result: {0}; Threshold: {1} (required > {2}); Quorum: {3} (required > {4})
|
||||
|
||||
dao.proposal.display.paramComboBox.label=Parameter
|
||||
dao.proposal.display.paramValue=Parameter value:
|
||||
dao.proposal.display.paramValue=Parameter value
|
||||
|
||||
dao.proposal.display.confiscateBondComboBox.label=Choose bond
|
||||
dao.proposal.display.assetComboBox.label=Asset to remove
|
||||
@ -1477,21 +1493,23 @@ dao.wallet.dashboard.distribution=Distribution of all BSQ
|
||||
dao.wallet.dashboard.locked=Global state of locked BSQ
|
||||
dao.wallet.dashboard.market=Market data
|
||||
dao.wallet.dashboard.txDetails=BSQ transactions details
|
||||
dao.wallet.dashboard.genesisBlockHeight=Genesis block height:
|
||||
dao.wallet.dashboard.genesisTxId=Genesis transaction ID:
|
||||
dao.wallet.dashboard.genesisIssueAmount=BSQ issued at genesis transaction:
|
||||
dao.wallet.dashboard.compRequestIssueAmount=BSQ issued for compensation requests:
|
||||
dao.wallet.dashboard.availableAmount=Total available BSQ:
|
||||
dao.wallet.dashboard.burntAmount=Burned BSQ (fees):
|
||||
dao.wallet.dashboard.totalLockedUpAmount=Locked up in bonds:
|
||||
dao.wallet.dashboard.totalUnlockingAmount=Unlocking BSQ from bonds:
|
||||
dao.wallet.dashboard.totalUnlockedAmount=Unlocked BSQ from bonds:
|
||||
dao.wallet.dashboard.allTx=No. of all BSQ transactions:
|
||||
dao.wallet.dashboard.utxo=No. of all unspent transaction outputs:
|
||||
dao.wallet.dashboard.issuanceTx=No. of all issuance transactions:
|
||||
dao.wallet.dashboard.burntTx=No. of all fee payments transactions:
|
||||
dao.wallet.dashboard.price=Latest BSQ/BTC trade price (in Bisq):
|
||||
dao.wallet.dashboard.marketCap=Market capitalisation (based on trade price):
|
||||
dao.wallet.dashboard.genesisBlockHeight=Genesis block height
|
||||
dao.wallet.dashboard.genesisTxId=Genesis transaction ID
|
||||
dao.wallet.dashboard.genesisIssueAmount=BSQ issued at genesis transaction
|
||||
dao.wallet.dashboard.compRequestIssueAmount=BSQ issued for compensation requests
|
||||
dao.wallet.dashboard.reimbursementAmount=BSQ issued for reimbursement requests
|
||||
dao.wallet.dashboard.availableAmount=Total available BSQ
|
||||
dao.wallet.dashboard.burntAmount=Burned BSQ (fees)
|
||||
dao.wallet.dashboard.totalLockedUpAmount=Locked up in bonds
|
||||
dao.wallet.dashboard.totalUnlockingAmount=Unlocking BSQ from bonds
|
||||
dao.wallet.dashboard.totalUnlockedAmount=Unlocked BSQ from bonds
|
||||
dao.wallet.dashboard.allTx=No. of all BSQ transactions
|
||||
dao.wallet.dashboard.utxo=No. of all unspent transaction outputs
|
||||
dao.wallet.dashboard.compensationIssuanceTx=No. of all compensation request issuance transactions
|
||||
dao.wallet.dashboard.reimbursementIssuanceTx=No. of all reimbursement request issuance transactions
|
||||
dao.wallet.dashboard.burntTx=No. of all fee payments transactions
|
||||
dao.wallet.dashboard.price=Latest BSQ/BTC trade price (in Bisq)
|
||||
dao.wallet.dashboard.marketCap=Market capitalisation (based on trade price)
|
||||
|
||||
dao.wallet.receive.fundBSQWallet=Fund Bisq BSQ wallet
|
||||
dao.wallet.receive.fundYourWallet=Fund your BSQ wallet
|
||||
@ -1499,12 +1517,12 @@ dao.wallet.receive.bsqAddress=BSQ address
|
||||
|
||||
dao.wallet.send.sendFunds=Send funds
|
||||
dao.wallet.send.sendBtcFunds=Send non-BSQ funds (BTC)
|
||||
dao.wallet.send.amount=Amount in BSQ:
|
||||
dao.wallet.send.btcAmount=Amount in BTC (non-BSQ funds):
|
||||
dao.wallet.send.amount=Amount in BSQ
|
||||
dao.wallet.send.btcAmount=Amount in BTC (non-BSQ funds)
|
||||
dao.wallet.send.setAmount=Set amount to withdraw (min. amount is {0})
|
||||
dao.wallet.send.setBtcAmount=Set amount in BTC to withdraw (min. amount is {0})
|
||||
dao.wallet.send.receiverAddress=Receiver's BSQ address:
|
||||
dao.wallet.send.receiverBtcAddress=Receiver's BTC address:
|
||||
dao.wallet.send.receiverAddress=Receiver's BSQ address
|
||||
dao.wallet.send.receiverBtcAddress=Receiver's BTC address
|
||||
dao.wallet.send.setDestinationAddress=Fill in your destination address
|
||||
dao.wallet.send.send=Send BSQ funds
|
||||
dao.wallet.send.sendBtc=Send BTC funds
|
||||
@ -1533,6 +1551,8 @@ dao.tx.type.enum.PAY_TRADE_FEE=Trading fee
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.COMPENSATION_REQUEST=Fee for compensation request
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.REIMBURSEMENT_REQUEST=Fee for reimbursement request
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.PROPOSAL=Fee for proposal
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.BLIND_VOTE=Fee for blind vote
|
||||
@ -1543,10 +1563,12 @@ dao.tx.type.enum.LOCKUP=Lock up bond
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.UNLOCK=Unlock bond
|
||||
|
||||
dao.tx.issuance=Compensation request/issuance
|
||||
dao.tx.issuance.tooltip=Compensation request which led to an issuance of new BSQ.\n\
|
||||
dao.tx.issuanceFromCompReq=Compensation request/issuance
|
||||
dao.tx.issuanceFromCompReq.tooltip=Compensation request which led to an issuance of new BSQ.\n\
|
||||
Issuance date: {0}
|
||||
dao.tx.issuanceFromReimbursement=Reimbursement request/issuance
|
||||
dao.tx.issuanceFromReimbursement.tooltip=Reimbursement request which led to an issuance of new BSQ.\n\
|
||||
Issuance date: {0}
|
||||
|
||||
dao.proposal.create.missingFunds=You don''t have sufficient funds for creating the proposal.\n\
|
||||
Missing: {0}
|
||||
dao.feeTx.confirm=Confirm {0} transaction
|
||||
|
@ -701,7 +701,7 @@ funds.tx.noTxAvailable=Keine Transaktionen verfügbar
|
||||
funds.tx.revert=Umkehren
|
||||
funds.tx.txSent=Transaktion erfolgreich zu einer neuen Adresse in der lokalen Bisq-Brieftasche gesendet.
|
||||
funds.tx.direction.self=An Sie selbst senden
|
||||
funds.tx.proposal=Vorschlag
|
||||
funds.tx.proposalTxFee=Vorschlag
|
||||
|
||||
|
||||
####################################################################
|
||||
@ -1356,8 +1356,8 @@ dao.tx.type.enum.LOCKUP=Sperre Kopplung
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.UNLOCK=Entsperre Kopplung
|
||||
|
||||
dao.tx.issuance=Entlohnungsanfrage/ausgabe
|
||||
dao.tx.issuance.tooltip=Entlohnungsanfrage, die zur Ausgabe neuere BSQ führte.\nAusgabedatum: {0}
|
||||
dao.tx.issuanceFromCompReq=Entlohnungsanfrage/ausgabe
|
||||
dao.tx.issuanceFromCompReq.tooltip=Entlohnungsanfrage, die zur Ausgabe neuere BSQ führte.\nAusgabedatum: {0}
|
||||
|
||||
dao.proposal.create.missingFunds=Sie haben nicht genügend Gelder um den Vorschlag zu erstellen.\nFehlend: {0}
|
||||
dao.feeTx.confirm=Bestätige {0} Transaktion
|
||||
|
@ -701,7 +701,7 @@ funds.tx.noTxAvailable=Δεν υπάρχουν διαθέσιμες συναλλ
|
||||
funds.tx.revert=Revert
|
||||
funds.tx.txSent=Η συναλλαγή απεστάλη επιτυχώς σε νέα διεύθυνση στο τοπικό πορτοφόλι Bisq.
|
||||
funds.tx.direction.self=Αποστολή στον εαυτό σου
|
||||
funds.tx.proposal=Πρόταση
|
||||
funds.tx.proposalTxFee=Πρόταση
|
||||
|
||||
|
||||
####################################################################
|
||||
@ -1356,8 +1356,8 @@ dao.tx.type.enum.LOCKUP=Lock up bond
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.UNLOCK=Unlock bond
|
||||
|
||||
dao.tx.issuance=Αίτημα/έκδοση αποζημίωσης
|
||||
dao.tx.issuance.tooltip=Αίτημα αποζημίωσης το οποίο οδήγησε σε έκδοση νέων BSQ.\nΗμερομηνία έκδοσης: {0}
|
||||
dao.tx.issuanceFromCompReq=Αίτημα/έκδοση αποζημίωσης
|
||||
dao.tx.issuanceFromCompReq.tooltip=Αίτημα αποζημίωσης το οποίο οδήγησε σε έκδοση νέων BSQ.\nΗμερομηνία έκδοσης: {0}
|
||||
|
||||
dao.proposal.create.missingFunds=Δεν έχεις επαρκή κεφάλαια για τη δημιουργία της πρότασης.\nΥπολείπονται: {0}
|
||||
dao.feeTx.confirm=Confirm {0} transaction
|
||||
|
@ -701,7 +701,7 @@ funds.tx.noTxAvailable=Sin transacciones disponibles
|
||||
funds.tx.revert=Revertir
|
||||
funds.tx.txSent=La transacción se ha enviado exitosamente a una nueva dirección en la billetera Bisq local.
|
||||
funds.tx.direction.self=Enviado a usted mismo
|
||||
funds.tx.proposal=Propuesta
|
||||
funds.tx.proposalTxFee=Propuesta
|
||||
|
||||
|
||||
####################################################################
|
||||
@ -1356,8 +1356,8 @@ dao.tx.type.enum.LOCKUP=Lock up bond
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.UNLOCK=Unlock bond
|
||||
|
||||
dao.tx.issuance=Solicitud/emisión de compensación
|
||||
dao.tx.issuance.tooltip=Solicitud de compensación que lleva a emitir nuevos BSQ.\nFecha de emisión: {0}
|
||||
dao.tx.issuanceFromCompReq=Solicitud/emisión de compensación
|
||||
dao.tx.issuanceFromCompReq.tooltip=Solicitud de compensación que lleva a emitir nuevos BSQ.\nFecha de emisión: {0}
|
||||
|
||||
dao.proposal.create.missingFunds=No tiene suficientes fondos para crear la propuesta.\nFaltan: {0}
|
||||
dao.feeTx.confirm=Confirm {0} transaction
|
||||
|
@ -701,7 +701,7 @@ funds.tx.noTxAvailable=هیچ تراکنشی موجود نیست
|
||||
funds.tx.revert=عودت
|
||||
funds.tx.txSent=تراکنش به طور موفقیت آمیز به یک آدرس جدید در کیف پول محلی Bisq ارسال شد.
|
||||
funds.tx.direction.self=ارسال شده به خودتان
|
||||
funds.tx.proposal=پیشنهاد
|
||||
funds.tx.proposalTxFee=پیشنهاد
|
||||
|
||||
|
||||
####################################################################
|
||||
@ -1356,8 +1356,8 @@ dao.tx.type.enum.LOCKUP=Lock up bond
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.UNLOCK=Unlock bond
|
||||
|
||||
dao.tx.issuance=درخواست/صدور خسارت
|
||||
dao.tx.issuance.tooltip=درخواست خسارت که منجر به یک صدور BSQ جدید می شود.\nتاریخ صدور: {0}
|
||||
dao.tx.issuanceFromCompReq=درخواست/صدور خسارت
|
||||
dao.tx.issuanceFromCompReq.tooltip=درخواست خسارت که منجر به یک صدور BSQ جدید می شود.\nتاریخ صدور: {0}
|
||||
|
||||
dao.proposal.create.missingFunds=شما وجوه کافی برای ایجاد پیشنهاد را ندارید.\nمقدار مورد نیاز: {0}
|
||||
dao.feeTx.confirm=Confirm {0} transaction
|
||||
|
@ -709,7 +709,7 @@ funds.tx.noTxAvailable=Aucune transaction disponible
|
||||
funds.tx.revert=Défaire
|
||||
funds.tx.txSent=Transaction envoyée avec succès à la nouvelle adresse dans le portefeuille local bisq.
|
||||
funds.tx.direction.self=Sent to yourself
|
||||
funds.tx.proposal=Proposition
|
||||
funds.tx.proposalTxFee=Proposition
|
||||
|
||||
|
||||
####################################################################
|
||||
@ -1076,8 +1076,8 @@ dao.tx.type.enum.BLIND_VOTE=Fee for blind vote
|
||||
dao.tx.type.enum.VOTE_REVEAL=Vote reveal
|
||||
dao.tx.type.enum.LOCK_UP=Lock bonds
|
||||
dao.tx.type.enum.UN_LOCK=Unlock bonds
|
||||
dao.tx.issuance=Compensation request/issuance
|
||||
dao.tx.issuance.tooltip=Compensation request which led to an issuance of new BSQ.\nIssuance date: {0}
|
||||
dao.tx.issuanceFromCompReq=Compensation request/issuance
|
||||
dao.tx.issuanceFromCompReq.tooltip=Compensation request which led to an issuance of new BSQ.\nIssuance date: {0}
|
||||
|
||||
dao.proposal.create.confirm.info=Proposal fee: {0}\nMining fee: {1} ({2} satoshis/byte)\nTransaction size: {3} Kb\n\nAre you sure you want to publish the proposal?
|
||||
dao.proposal.create.missingFunds=You don''t have sufficient funds for creating the proposal.\nMissing: {0}
|
||||
|
@ -701,7 +701,7 @@ funds.tx.noTxAvailable=Nincs hozzáférhető tranzakció
|
||||
funds.tx.revert=Visszaszállás
|
||||
funds.tx.txSent=Tranzakció sikeresen elküldve egy új címre a helyi Bisq pénztárcában.
|
||||
funds.tx.direction.self=Küld saját magadnak.
|
||||
funds.tx.proposal=Kártérítési kérelem
|
||||
funds.tx.proposalTxFee=Kártérítési kérelem
|
||||
|
||||
|
||||
####################################################################
|
||||
@ -1356,8 +1356,8 @@ dao.tx.type.enum.LOCKUP=Lock up bond
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.UNLOCK=Unlock bond
|
||||
|
||||
dao.tx.issuance=Compensation request/issuance
|
||||
dao.tx.issuance.tooltip=Compensation request which led to an issuance of new BSQ.\nIssuance date: {0}
|
||||
dao.tx.issuanceFromCompReq=Compensation request/issuance
|
||||
dao.tx.issuanceFromCompReq.tooltip=Compensation request which led to an issuance of new BSQ.\nIssuance date: {0}
|
||||
|
||||
dao.proposal.create.missingFunds=Nem rendelkezik elegendő összegekkel a kártérítési kérelem létrehozásához.\nHiányzó: {0}
|
||||
dao.feeTx.confirm=Confirm {0} transaction
|
||||
|
@ -701,7 +701,7 @@ funds.tx.noTxAvailable=Sem transações disponíveis
|
||||
funds.tx.revert=Reverter
|
||||
funds.tx.txSent=Transação enviada com sucesso para um novo endereço em sua carteira Bisq local.
|
||||
funds.tx.direction.self=Enviar para você mesmo
|
||||
funds.tx.proposal=Proposta
|
||||
funds.tx.proposalTxFee=Proposta
|
||||
|
||||
|
||||
####################################################################
|
||||
@ -1356,8 +1356,8 @@ dao.tx.type.enum.LOCKUP=Lock up bond
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.UNLOCK=Unlock bond
|
||||
|
||||
dao.tx.issuance=Compensation request/issuance
|
||||
dao.tx.issuance.tooltip=Compensation request which led to an issuance of new BSQ.\nIssuance date: {0}
|
||||
dao.tx.issuanceFromCompReq=Compensation request/issuance
|
||||
dao.tx.issuanceFromCompReq.tooltip=Compensation request which led to an issuance of new BSQ.\nIssuance date: {0}
|
||||
|
||||
dao.proposal.create.missingFunds=You don''t have sufficient funds for creating the proposal.\nMissing: {0}
|
||||
dao.feeTx.confirm=Confirm {0} transaction
|
||||
|
@ -701,7 +701,7 @@ funds.tx.noTxAvailable=Nicio tranzacție disponibilă
|
||||
funds.tx.revert=Revenire
|
||||
funds.tx.txSent=Tranzacția a fost virată cu succes la o nouă adresă în portofelul Bisq local.
|
||||
funds.tx.direction.self=Trimite-ți ție
|
||||
funds.tx.proposal=Solicitare de despăgubire
|
||||
funds.tx.proposalTxFee=Solicitare de despăgubire
|
||||
|
||||
|
||||
####################################################################
|
||||
@ -1356,8 +1356,8 @@ dao.tx.type.enum.LOCKUP=Lock up bond
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.UNLOCK=Unlock bond
|
||||
|
||||
dao.tx.issuance=Compensation request/issuance
|
||||
dao.tx.issuance.tooltip=Compensation request which led to an issuance of new BSQ.\nIssuance date: {0}
|
||||
dao.tx.issuanceFromCompReq=Compensation request/issuance
|
||||
dao.tx.issuanceFromCompReq.tooltip=Compensation request which led to an issuance of new BSQ.\nIssuance date: {0}
|
||||
|
||||
dao.proposal.create.missingFunds=Nu ai suficiente fonduri pentru crearea solicitării de despăgubire.\nLipsesc: {0}
|
||||
dao.feeTx.confirm=Confirm {0} transaction
|
||||
|
@ -701,7 +701,7 @@ funds.tx.noTxAvailable=Транзакции недоступны
|
||||
funds.tx.revert=Возврат
|
||||
funds.tx.txSent=Транзакция успешно отправлена на новый адрес локального кошелька Bisq.
|
||||
funds.tx.direction.self=Транзакция внутри кошелька
|
||||
funds.tx.proposal=Предложение
|
||||
funds.tx.proposalTxFee=Предложение
|
||||
|
||||
|
||||
####################################################################
|
||||
@ -1356,8 +1356,8 @@ dao.tx.type.enum.LOCKUP=Запереть гарантийный депозит
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.UNLOCK=Отпереть гарантийный депозит
|
||||
|
||||
dao.tx.issuance=Запрос/выдача компенсации
|
||||
dao.tx.issuance.tooltip=Запрос компенсации, который привел к выпуску новых BSQ.\nДата выпуска: {0}
|
||||
dao.tx.issuanceFromCompReq=Запрос/выдача компенсации
|
||||
dao.tx.issuanceFromCompReq.tooltip=Запрос компенсации, который привел к выпуску новых BSQ.\nДата выпуска: {0}
|
||||
|
||||
dao.proposal.create.missingFunds=У Вас недостаточно средств для создания предложения.\nНехватает: {0}
|
||||
dao.feeTx.confirm=Подтвердить транзакцию {0}
|
||||
|
@ -701,7 +701,7 @@ funds.tx.noTxAvailable=Nema dostupnih transakcija
|
||||
funds.tx.revert=Vrati
|
||||
funds.tx.txSent=Transakcija uspešno poslata na novu adresu u lokalnom Bisq novčaniku
|
||||
funds.tx.direction.self=Transakcija unutar novčanika
|
||||
funds.tx.proposal=Proposal
|
||||
funds.tx.proposalTxFee=Proposal
|
||||
|
||||
|
||||
####################################################################
|
||||
@ -1356,8 +1356,8 @@ dao.tx.type.enum.LOCKUP=Lock up bond
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.UNLOCK=Unlock bond
|
||||
|
||||
dao.tx.issuance=Compensation request/issuance
|
||||
dao.tx.issuance.tooltip=Compensation request which led to an issuance of new BSQ.\nIssuance date: {0}
|
||||
dao.tx.issuanceFromCompReq=Compensation request/issuance
|
||||
dao.tx.issuanceFromCompReq.tooltip=Compensation request which led to an issuance of new BSQ.\nIssuance date: {0}
|
||||
|
||||
dao.proposal.create.missingFunds=You don''t have sufficient funds for creating the proposal.\nMissing: {0}
|
||||
dao.feeTx.confirm=Confirm {0} transaction
|
||||
|
@ -701,7 +701,7 @@ funds.tx.noTxAvailable=ไม่มีธุรกรรมใด ๆ
|
||||
funds.tx.revert=กลับสู่สภาพเดิม
|
||||
funds.tx.txSent=ธุรกรรมถูกส่งสำเร็จไปยังที่อยู่ใหม่ใน Bisq wallet ท้องถิ่นแล้ว
|
||||
funds.tx.direction.self=ส่งถึงตัวคุณเอง
|
||||
funds.tx.proposal=คำขอ
|
||||
funds.tx.proposalTxFee=คำขอ
|
||||
|
||||
|
||||
####################################################################
|
||||
@ -1356,8 +1356,8 @@ dao.tx.type.enum.LOCKUP=Lock up bond
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.UNLOCK=Unlock bond
|
||||
|
||||
dao.tx.issuance=ค่าชดเชย คำขอ/การออก
|
||||
dao.tx.issuance.tooltip=คำขอค่าชดเชยซึ่งนำไปสู่การออก BSQ ใหม่\nวันที่ออก: {0}
|
||||
dao.tx.issuanceFromCompReq=ค่าชดเชย คำขอ/การออก
|
||||
dao.tx.issuanceFromCompReq.tooltip=คำขอค่าชดเชยซึ่งนำไปสู่การออก BSQ ใหม่\nวันที่ออก: {0}
|
||||
|
||||
dao.proposal.create.missingFunds=คุณไม่มีเงินเพียงพอสำหรับการสร้างข้อเสนอ\nขาดไป: {0}
|
||||
dao.feeTx.confirm=Confirm {0} transaction
|
||||
|
@ -701,7 +701,7 @@ funds.tx.noTxAvailable=Không có giao dịch nào
|
||||
funds.tx.revert=Khôi phục
|
||||
funds.tx.txSent=GIao dịch đã gửi thành công tới địa chỉ mới trong ví Bisq nội bộ.
|
||||
funds.tx.direction.self=Gửi cho chính bạn
|
||||
funds.tx.proposal=Đề xuất
|
||||
funds.tx.proposalTxFee=Đề xuất
|
||||
|
||||
|
||||
####################################################################
|
||||
@ -1356,8 +1356,8 @@ dao.tx.type.enum.LOCKUP=Lock up bond
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.UNLOCK=Unlock bond
|
||||
|
||||
dao.tx.issuance=Yêu cầu bồi thường/ban hành
|
||||
dao.tx.issuance.tooltip=Yêu cầu bồi thường dẫn đến ban hành BSQ mới.\nNgày ban hành: {0}
|
||||
dao.tx.issuanceFromCompReq=Yêu cầu bồi thường/ban hành
|
||||
dao.tx.issuanceFromCompReq.tooltip=Yêu cầu bồi thường dẫn đến ban hành BSQ mới.\nNgày ban hành: {0}
|
||||
|
||||
dao.proposal.create.missingFunds=Bạn không có đủ tiền để tạo đề xuất.\nThiếu: {0}
|
||||
dao.feeTx.confirm=Confirm {0} transaction
|
||||
|
@ -701,7 +701,7 @@ funds.tx.noTxAvailable=没有可用交易
|
||||
funds.tx.revert=还原
|
||||
funds.tx.txSent=交易成功发送到本地Bisq钱包中的新地址。
|
||||
funds.tx.direction.self=内部钱包交易
|
||||
funds.tx.proposal=Proposal
|
||||
funds.tx.proposalTxFee=Proposal
|
||||
|
||||
|
||||
####################################################################
|
||||
@ -1356,8 +1356,8 @@ dao.tx.type.enum.LOCKUP=Lock up bond
|
||||
# suppress inspection "UnusedProperty"
|
||||
dao.tx.type.enum.UNLOCK=Unlock bond
|
||||
|
||||
dao.tx.issuance=补偿请求/发行
|
||||
dao.tx.issuance.tooltip=导致新BSQ发行的补偿请求\n发行日期: {0}
|
||||
dao.tx.issuanceFromCompReq=补偿请求/发行
|
||||
dao.tx.issuanceFromCompReq.tooltip=导致新BSQ发行的补偿请求\n发行日期: {0}
|
||||
|
||||
dao.proposal.create.missingFunds=You don''t have sufficient funds for creating the proposal.\nMissing: {0}
|
||||
dao.feeTx.confirm=Confirm {0} transaction
|
||||
|
@ -98,7 +98,7 @@ bg color of non edit textFields: fafafa
|
||||
-bs-rd-white: #ffffff; /* 30 usages */
|
||||
-bs-rd-white-transparent: rgba(255, 255, 255, 0.31);
|
||||
-bs-rd-grey-light: #D8D8D8;
|
||||
-bs-rd-grey-medium-light:#E9E9E9;
|
||||
-bs-rd-grey-medium-light: #E9E9E9;
|
||||
-bs-rd-grey-very-light: #f8f8f8; /* 10 usages */
|
||||
-bs-rd-grey-background: #F2F2F2;
|
||||
-bs-rd-grey-background-bottom: #f6f6f6; /* 1 usages */
|
||||
@ -232,7 +232,7 @@ bg color of non edit textFields: fafafa
|
||||
}
|
||||
|
||||
.jfx-progress-bar > .bar,
|
||||
.jfx-progress-bar:indeterminate > .bar{
|
||||
.jfx-progress-bar:indeterminate > .bar {
|
||||
-fx-background-color: -bs-rd-green;
|
||||
}
|
||||
|
||||
@ -241,7 +241,7 @@ bg color of non edit textFields: fafafa
|
||||
}
|
||||
|
||||
.jfx-spinner:indeterminate .arc,
|
||||
.jfx-spinner:determinate .arc{
|
||||
.jfx-spinner:determinate .arc {
|
||||
-fx-stroke: -bs-rd-green;
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ bg color of non edit textFields: fafafa
|
||||
-fx-pref-height: 32;
|
||||
-fx-min-height: -fx-pref-height;
|
||||
-fx-padding: 0 40 0 40;
|
||||
-fx-effect: dropshadow( gaussian, -bs-rd-black-transparent, 2, 0, 0, 0, 1);
|
||||
-fx-effect: dropshadow(gaussian, -bs-rd-black-transparent, 2, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
.action-button {
|
||||
@ -280,7 +280,7 @@ bg color of non edit textFields: fafafa
|
||||
-fx-pref-height: 12;
|
||||
}
|
||||
|
||||
.jfx-check-box .mark ,
|
||||
.jfx-check-box .mark,
|
||||
.jfx-check-box .indeterminate-mark {
|
||||
-fx-border-radius: 0;
|
||||
-fx-border-width: 1;
|
||||
@ -289,7 +289,7 @@ bg color of non edit textFields: fafafa
|
||||
.jfx-combo-box {
|
||||
-jfx-focus-color: -bs-rd-green;
|
||||
-jfx-unfocus-color: -bs-rd-grey-line;
|
||||
-fx-background-color:-bs-rd-white;
|
||||
-fx-background-color: -bs-rd-white;
|
||||
}
|
||||
|
||||
.jfx-combo-box > .list-cell {
|
||||
@ -305,7 +305,7 @@ bg color of non edit textFields: fafafa
|
||||
|
||||
.jfx-text-field {
|
||||
-jfx-focus-color: -bs-rd-green;
|
||||
-fx-background-color:-bs-rd-white;
|
||||
-fx-background-color: -bs-rd-white;
|
||||
-fx-background-radius: 3 3 0 0;
|
||||
}
|
||||
|
||||
@ -394,7 +394,7 @@ bg color of non edit textFields: fafafa
|
||||
}
|
||||
|
||||
.input-with-border {
|
||||
-fx-background-color:-bs-rd-white;
|
||||
-fx-background-color: -bs-rd-white;
|
||||
-fx-border-width: 1;
|
||||
-fx-border-color: -bs-rd-grey-background-dark;
|
||||
-fx-border-radius: 3;
|
||||
@ -417,48 +417,55 @@ bg color of non edit textFields: fafafa
|
||||
}
|
||||
|
||||
.input-with-border .icon {
|
||||
-fx-padding:10;
|
||||
-fx-padding: 10;
|
||||
}
|
||||
|
||||
.scroll-bar{
|
||||
.scroll-bar {
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 0;
|
||||
}
|
||||
|
||||
.scroll-bar:horizontal .track,
|
||||
.scroll-bar:vertical .track {
|
||||
-fx-background-color: transparent;
|
||||
-fx-border-color:transparent;
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-radius: 0;
|
||||
}
|
||||
|
||||
.scroll-bar:vertical .track-background,
|
||||
.scroll-bar:horizontal .track-background {
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-insets: 0;
|
||||
-fx-background-radius: 0;
|
||||
}
|
||||
|
||||
.scroll-bar:horizontal .thumb {
|
||||
-fx-background-color: -bs-rd-grey-background-darker;
|
||||
-fx-background-insets: 2 0 2 0;
|
||||
-fx-background-radius: 3;
|
||||
}
|
||||
|
||||
.scroll-bar:vertical .thumb {
|
||||
-fx-background-color: -bs-rd-grey-background-darker;
|
||||
-fx-background-insets: 0 2 0 2;
|
||||
-fx-background-radius: 3;
|
||||
}
|
||||
|
||||
.scroll-bar:horizontal .thumb:hover,
|
||||
.scroll-bar:vertical .thumb:hover {
|
||||
-fx-background-color: -bs-rd-grey-background-darker-2;
|
||||
}
|
||||
|
||||
.scroll-bar:horizontal .thumb:pressed,
|
||||
.scroll-bar:vertical .thumb:pressed {
|
||||
-fx-background-color: -bs-rd-grey-background-darkest;
|
||||
}
|
||||
|
||||
.scroll-bar:vertical .increment-button,
|
||||
.scroll-bar:vertical .decrement-button,
|
||||
.scroll-bar:horizontal .increment-button,
|
||||
.scroll-bar:horizontal .decrement-button {
|
||||
-fx-background-color:transparent;
|
||||
-fx-background-color: transparent;
|
||||
-fx-padding: 1;
|
||||
}
|
||||
|
||||
@ -472,7 +479,7 @@ bg color of non edit textFields: fafafa
|
||||
|
||||
.scroll-bar:vertical:focused,
|
||||
.scroll-bar:horizontal:focused {
|
||||
-fx-background-color: transparent, -bs-rd-grey-background-darkest,-bs-rd-grey-background-darkest;
|
||||
-fx-background-color: transparent, -bs-rd-grey-background-darkest, -bs-rd-grey-background-darkest;
|
||||
}
|
||||
|
||||
/* Behavior */
|
||||
@ -758,11 +765,11 @@ textfield */
|
||||
}
|
||||
|
||||
.table-view .filler {
|
||||
-fx-background-color:-bs-rd-grey-very-light;
|
||||
-fx-background-color: -bs-rd-grey-very-light;
|
||||
}
|
||||
|
||||
.table-view {
|
||||
-fx-control-inner-background-alt: -fx-control-inner-background ;
|
||||
-fx-control-inner-background-alt: -fx-control-inner-background;
|
||||
}
|
||||
|
||||
.table-view .column-header .label {
|
||||
@ -1589,7 +1596,7 @@ textfield */
|
||||
}
|
||||
|
||||
#price-feed-combo {
|
||||
-fx-background-color:none;
|
||||
-fx-background-color: none;
|
||||
}
|
||||
|
||||
#price-feed-combo > .list-cell {
|
||||
|
@ -23,7 +23,6 @@ import org.bitcoinj.core.Coin;
|
||||
|
||||
import com.jfoenix.controls.JFXTextField;
|
||||
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.effect.BlurType;
|
||||
import javafx.scene.effect.DropShadow;
|
||||
import javafx.scene.effect.Effect;
|
||||
@ -86,7 +85,7 @@ public class BalanceTextField extends AnchorPane {
|
||||
if (formatter != null)
|
||||
textField.setText(formatter.formatCoinWithCode(balance));
|
||||
|
||||
//TODO: replace with new validation logic
|
||||
//TODO: replace with new validation logic
|
||||
// if (targetAmount != null) {
|
||||
// if (balance.compareTo(targetAmount) >= 0)
|
||||
// textField.setEffect(fundedEffect);
|
||||
|
@ -19,7 +19,7 @@ package bisq.desktop.components;
|
||||
|
||||
import com.jfoenix.controls.JFXPasswordField;
|
||||
|
||||
public class PasswordTextField extends JFXPasswordField{
|
||||
public class PasswordTextField extends JFXPasswordField {
|
||||
public PasswordTextField() {
|
||||
super();
|
||||
setLabelFloat(true);
|
||||
|
@ -69,7 +69,6 @@ public class SeparatedPhaseBars extends VBox {
|
||||
ProgressBar progressBar = new ProgressBar();
|
||||
progressBar.setMinHeight(9);
|
||||
progressBar.setMaxHeight(9);
|
||||
progressBar.setStyle("-fx-accent: -bs-green;");
|
||||
progressBar.progressProperty().bind(item.progressProperty);
|
||||
progressBar.setOpacity(item.isShowBlocks() ? 1 : 0.25);
|
||||
progressBars.getChildren().add(progressBar);
|
||||
|
@ -318,7 +318,6 @@ public class CashDepositForm extends GeneralBankForm {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void onCountrySelected(Country country) {
|
||||
selectedCountry = country;
|
||||
if (selectedCountry != null) {
|
||||
|
@ -106,9 +106,7 @@ public class AccountView extends ActivatableView<TabPane, Void> {
|
||||
};
|
||||
|
||||
tabChangeListener = (ov, oldValue, newValue) -> {
|
||||
if (arbitratorRegistrationTab != null) {
|
||||
navigation.navigateTo(MainView.class, AccountView.class, ArbitratorRegistrationView.class);
|
||||
} else if (newValue == fiatAccountsTab) {
|
||||
if (newValue == fiatAccountsTab) {
|
||||
navigation.navigateTo(MainView.class, AccountView.class, FiatAccountsView.class);
|
||||
} else if (newValue == altcoinAccountsTab) {
|
||||
navigation.navigateTo(MainView.class, AccountView.class, AltCoinAccountsView.class);
|
||||
@ -120,6 +118,8 @@ public class AccountView extends ActivatableView<TabPane, Void> {
|
||||
navigation.navigateTo(MainView.class, AccountView.class, SeedWordsView.class);
|
||||
} else if (newValue == backupTab) {
|
||||
navigation.navigateTo(MainView.class, AccountView.class, BackupView.class);
|
||||
} else if (newValue == arbitratorRegistrationTab) {
|
||||
navigation.navigateTo(MainView.class, AccountView.class, ArbitratorRegistrationView.class);
|
||||
} else {
|
||||
navigation.navigateTo(MainView.class, AccountView.class, FiatAccountsView.class);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import bisq.core.dao.governance.proposal.compensation.CompensationProposal;
|
||||
import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposal;
|
||||
import bisq.core.dao.governance.proposal.generic.GenericProposal;
|
||||
import bisq.core.dao.governance.proposal.param.ChangeParamProposal;
|
||||
import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal;
|
||||
import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal;
|
||||
import bisq.core.dao.governance.proposal.role.BondedRoleProposal;
|
||||
import bisq.core.dao.governance.role.BondedRole;
|
||||
@ -87,7 +88,6 @@ import javax.annotation.Nullable;
|
||||
|
||||
import static bisq.desktop.util.FormBuilder.addInputTextField;
|
||||
import static bisq.desktop.util.FormBuilder.addLabelHyperlinkWithIcon;
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
|
||||
import static bisq.desktop.util.FormBuilder.addTitledGroupBg;
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
@ -163,6 +163,7 @@ public class ProposalDisplay {
|
||||
|
||||
switch (proposalType) {
|
||||
case COMPENSATION_REQUEST:
|
||||
case REIMBURSEMENT_REQUEST:
|
||||
break;
|
||||
case CHANGE_PARAM:
|
||||
titledGroupBgRowSpan = 6;
|
||||
@ -202,14 +203,21 @@ public class ProposalDisplay {
|
||||
int comboBoxValueTextFieldIndex = -1;
|
||||
switch (proposalType) {
|
||||
case COMPENSATION_REQUEST:
|
||||
case REIMBURSEMENT_REQUEST:
|
||||
requestedBsqTextField = addInputTextField(gridPane, ++gridRow,
|
||||
Res.get("dao.proposal.display.requestedBsq"));
|
||||
BsqValidator bsqValidator = new BsqValidator(bsqFormatter);
|
||||
bsqValidator.setMinValue(daoFacade.getMinCompensationRequestAmount());
|
||||
bsqValidator.setMaxValue(daoFacade.getMaxCompensationRequestAmount());
|
||||
checkNotNull(requestedBsqTextField, "requestedBsqTextField must not be null");
|
||||
requestedBsqTextField.setValidator(bsqValidator);
|
||||
inputControls.add(requestedBsqTextField);
|
||||
|
||||
BsqValidator bsqValidator = new BsqValidator(bsqFormatter);
|
||||
if (proposalType == ProposalType.COMPENSATION_REQUEST) {
|
||||
bsqValidator.setMinValue(daoFacade.getMinCompensationRequestAmount());
|
||||
bsqValidator.setMaxValue(daoFacade.getMaxCompensationRequestAmount());
|
||||
} else if (proposalType == ProposalType.REIMBURSEMENT_REQUEST) {
|
||||
bsqValidator.setMinValue(daoFacade.getMinReimbursementRequestAmount());
|
||||
bsqValidator.setMaxValue(daoFacade.getMaxReimbursementRequestAmount());
|
||||
}
|
||||
requestedBsqTextField.setValidator(bsqValidator);
|
||||
break;
|
||||
case CHANGE_PARAM:
|
||||
checkNotNull(gridPane, "gridPane must not be null");
|
||||
@ -444,6 +452,10 @@ public class ProposalDisplay {
|
||||
CompensationProposal compensationProposal = (CompensationProposal) proposal;
|
||||
checkNotNull(requestedBsqTextField, "requestedBsqTextField must not be null");
|
||||
requestedBsqTextField.setText(bsqFormatter.formatCoinWithCode(compensationProposal.getRequestedBsq()));
|
||||
} else if (proposal instanceof ReimbursementProposal) {
|
||||
ReimbursementProposal reimbursementProposal = (ReimbursementProposal) proposal;
|
||||
checkNotNull(requestedBsqTextField, "requestedBsqTextField must not be null");
|
||||
requestedBsqTextField.setText(bsqFormatter.formatCoinWithCode(reimbursementProposal.getRequestedBsq()));
|
||||
} else if (proposal instanceof ChangeParamProposal) {
|
||||
ChangeParamProposal changeParamProposal = (ChangeParamProposal) proposal;
|
||||
checkNotNull(paramComboBox, "paramComboBox must not be null");
|
||||
|
@ -40,9 +40,9 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
|
||||
import static bisq.desktop.util.FormBuilder.addMultilineLabel;
|
||||
import static bisq.desktop.util.FormBuilder.addTitledGroupBg;
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
|
||||
|
||||
// We use here ChainHeightListener because we are interested in period changes not in the result of a completed
|
||||
// block. The event from the ChainHeightListener is sent before parsing starts.
|
||||
|
@ -46,6 +46,8 @@ import bisq.core.locale.Res;
|
||||
import bisq.core.util.BSFormatter;
|
||||
import bisq.core.util.BsqFormatter;
|
||||
|
||||
import bisq.asset.Asset;
|
||||
|
||||
import bisq.network.p2p.P2PService;
|
||||
|
||||
import bisq.common.app.DevEnv;
|
||||
@ -77,10 +79,6 @@ import static bisq.desktop.util.FormBuilder.addButtonAfterGroup;
|
||||
import static bisq.desktop.util.FormBuilder.addTitledGroupBg;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
||||
|
||||
import bisq.asset.Asset;
|
||||
|
||||
@FxmlView
|
||||
public class MakeProposalView extends ActivatableView<GridPane, Void> implements DaoStateListener {
|
||||
private final DaoFacade daoFacade;
|
||||
@ -263,6 +261,12 @@ public class MakeProposalView extends ActivatableView<GridPane, Void> implements
|
||||
return daoFacade.getCompensationProposalWithTransaction(proposalDisplay.nameTextField.getText(),
|
||||
proposalDisplay.linkInputTextField.getText(),
|
||||
bsqFormatter.parseToCoin(proposalDisplay.requestedBsqTextField.getText()));
|
||||
case REIMBURSEMENT_REQUEST:
|
||||
checkNotNull(proposalDisplay.requestedBsqTextField,
|
||||
"proposalDisplay.requestedBsqTextField must not be null");
|
||||
return daoFacade.getReimbursementProposalWithTransaction(proposalDisplay.nameTextField.getText(),
|
||||
proposalDisplay.linkInputTextField.getText(),
|
||||
bsqFormatter.parseToCoin(proposalDisplay.requestedBsqTextField.getText()));
|
||||
case CHANGE_PARAM:
|
||||
checkNotNull(proposalDisplay.paramComboBox,
|
||||
"proposalDisplay.paramComboBox must no tbe null");
|
||||
|
@ -30,7 +30,6 @@ import bisq.desktop.components.TxIdTextField;
|
||||
import bisq.desktop.main.dao.governance.PhasesView;
|
||||
import bisq.desktop.main.dao.governance.ProposalDisplay;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.util.FormBuilder;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
import bisq.desktop.util.Layout;
|
||||
import bisq.desktop.util.validation.BsqValidator;
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
package bisq.desktop.main.dao.governance.result;
|
||||
|
||||
import bisq.core.dao.governance.proposal.compensation.CompensationProposal;
|
||||
import bisq.core.dao.governance.proposal.IssuanceProposal;
|
||||
import bisq.core.dao.governance.voteresult.EvaluatedProposal;
|
||||
import bisq.core.dao.state.DaoStateService;
|
||||
import bisq.core.locale.Res;
|
||||
@ -75,8 +75,8 @@ public class CycleListItem {
|
||||
public String getIssuance() {
|
||||
long totalIssuance = resultsOfCycle.getEvaluatedProposals().stream()
|
||||
.filter(EvaluatedProposal::isAccepted)
|
||||
.filter(e -> e.getProposal() instanceof CompensationProposal)
|
||||
.map(e -> (CompensationProposal) e.getProposal())
|
||||
.filter(e -> e.getProposal() instanceof IssuanceProposal)
|
||||
.map(e -> (IssuanceProposal) e.getProposal())
|
||||
.mapToLong(e -> e.getRequestedBsq().value)
|
||||
.sum();
|
||||
return bsqFormatter.formatCoinWithCode(Coin.valueOf(totalIssuance));
|
||||
|
@ -25,6 +25,7 @@ import bisq.core.dao.governance.proposal.Proposal;
|
||||
import bisq.core.dao.governance.proposal.compensation.CompensationProposal;
|
||||
import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposal;
|
||||
import bisq.core.dao.governance.proposal.param.ChangeParamProposal;
|
||||
import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal;
|
||||
import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal;
|
||||
import bisq.core.dao.governance.proposal.role.BondedRoleProposal;
|
||||
import bisq.core.dao.governance.role.BondedRole;
|
||||
@ -110,6 +111,10 @@ public class ProposalListItem {
|
||||
CompensationProposal compensationProposal = (CompensationProposal) proposal;
|
||||
Coin requestedBsq = evaluatedProposal.isAccepted() ? compensationProposal.getRequestedBsq() : Coin.ZERO;
|
||||
return bsqFormatter.formatCoinWithCode(requestedBsq);
|
||||
case REIMBURSEMENT_REQUEST:
|
||||
ReimbursementProposal reimbursementProposal = (ReimbursementProposal) proposal;
|
||||
requestedBsq = evaluatedProposal.isAccepted() ? reimbursementProposal.getRequestedBsq() : Coin.ZERO;
|
||||
return bsqFormatter.formatCoinWithCode(requestedBsq);
|
||||
case CHANGE_PARAM:
|
||||
ChangeParamProposal changeParamProposal = (ChangeParamProposal) proposal;
|
||||
return changeParamProposal.getParam().getDisplayString();
|
||||
|
@ -26,7 +26,6 @@ import bisq.core.btc.wallet.BsqWalletService;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.util.BsqFormatter;
|
||||
|
||||
import bisq.common.util.Tuple2;
|
||||
import bisq.common.util.Tuple3;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
|
@ -27,6 +27,7 @@ import bisq.desktop.util.Layout;
|
||||
import bisq.core.dao.DaoFacade;
|
||||
import bisq.core.dao.state.DaoStateListener;
|
||||
import bisq.core.dao.state.blockchain.Block;
|
||||
import bisq.core.dao.state.governance.IssuanceType;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.monetary.Altcoin;
|
||||
import bisq.core.monetary.Price;
|
||||
@ -48,8 +49,8 @@ import javafx.scene.layout.GridPane;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
|
||||
import static bisq.desktop.util.FormBuilder.addLabelHyperlinkWithIcon;
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
|
||||
import static bisq.desktop.util.FormBuilder.addTitledGroupBg;
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
|
||||
|
||||
@FxmlView
|
||||
public class BsqDashboardView extends ActivatableView<GridPane, Void> implements DaoStateListener {
|
||||
@ -61,10 +62,10 @@ public class BsqDashboardView extends ActivatableView<GridPane, Void> implements
|
||||
private final BsqFormatter bsqFormatter;
|
||||
|
||||
private int gridRow = 0;
|
||||
private TextField genesisIssueAmountTextField, compRequestIssueAmountTextField, availableAmountTextField,
|
||||
private TextField genesisIssueAmountTextField, compRequestIssueAmountTextField, reimbursementAmountTextField, availableAmountTextField,
|
||||
burntAmountTextField, totalLockedUpAmountTextField, totalUnlockingAmountTextField,
|
||||
totalUnlockedAmountTextField, allTxTextField, burntTxTextField, utxoTextField, issuanceTxTextField,
|
||||
priceTextField, marketCapTextField;
|
||||
totalUnlockedAmountTextField, allTxTextField, burntTxTextField, utxoTextField, compensationIssuanceTxTextField,
|
||||
reimbursementIssuanceTxTextField, priceTextField, marketCapTextField;
|
||||
private ChangeListener<Number> priceChangeListener;
|
||||
private HyperlinkWithIcon hyperlinkWithIcon;
|
||||
|
||||
@ -90,10 +91,11 @@ public class BsqDashboardView extends ActivatableView<GridPane, Void> implements
|
||||
public void initialize() {
|
||||
gridRow = bsqBalanceUtil.addGroup(root, gridRow);
|
||||
|
||||
addTitledGroupBg(root, ++gridRow, 4, Res.get("dao.wallet.dashboard.distribution"), Layout.GROUP_DISTANCE);
|
||||
addTitledGroupBg(root, ++gridRow, 5, Res.get("dao.wallet.dashboard.distribution"), Layout.GROUP_DISTANCE);
|
||||
|
||||
genesisIssueAmountTextField = FormBuilder.addTopLabelTextField(root, gridRow, Res.get("dao.wallet.dashboard.genesisIssueAmount"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||
compRequestIssueAmountTextField = FormBuilder.addTopLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.compRequestIssueAmount")).second;
|
||||
reimbursementAmountTextField = FormBuilder.addTopLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.reimbursementAmount")).second;
|
||||
burntAmountTextField = FormBuilder.addTopLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.burntAmount")).second;
|
||||
availableAmountTextField = FormBuilder.addTopLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.availableAmount")).second;
|
||||
|
||||
@ -116,7 +118,8 @@ public class BsqDashboardView extends ActivatableView<GridPane, Void> implements
|
||||
hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", daoFacade.getGenesisTxId())));
|
||||
allTxTextField = FormBuilder.addTopLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.allTx")).second;
|
||||
utxoTextField = FormBuilder.addTopLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.utxo")).second;
|
||||
issuanceTxTextField = FormBuilder.addTopLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.issuanceTx")).second;
|
||||
compensationIssuanceTxTextField = FormBuilder.addTopLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.compensationIssuanceTx")).second;
|
||||
reimbursementIssuanceTxTextField = FormBuilder.addTopLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.reimbursementIssuanceTx")).second;
|
||||
burntTxTextField = FormBuilder.addTopLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.burntTx")).second;
|
||||
|
||||
priceChangeListener = (observable, oldValue, newValue) -> updatePrice();
|
||||
@ -167,8 +170,10 @@ public class BsqDashboardView extends ActivatableView<GridPane, Void> implements
|
||||
Coin issuedAmountFromGenesis = daoFacade.getGenesisTotalSupply();
|
||||
genesisIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromGenesis));
|
||||
|
||||
Coin issuedAmountFromCompRequests = Coin.valueOf(daoFacade.getTotalIssuedAmountFromCompRequests());
|
||||
Coin issuedAmountFromCompRequests = Coin.valueOf(daoFacade.getTotalIssuedAmount(IssuanceType.COMPENSATION));
|
||||
compRequestIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromCompRequests));
|
||||
Coin issuedAmountFromReimbursementRequests = Coin.valueOf(daoFacade.getTotalIssuedAmount(IssuanceType.REIMBURSEMENT));
|
||||
reimbursementAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromReimbursementRequests));
|
||||
|
||||
Coin burntFee = Coin.valueOf(daoFacade.getTotalBurntFee());
|
||||
Coin totalLockedUpAmount = Coin.valueOf(daoFacade.getTotalLockupAmount());
|
||||
@ -183,7 +188,8 @@ public class BsqDashboardView extends ActivatableView<GridPane, Void> implements
|
||||
totalUnlockedAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(totalUnlockedAmount));
|
||||
allTxTextField.setText(String.valueOf(daoFacade.getTxs().size()));
|
||||
utxoTextField.setText(String.valueOf(daoFacade.getUnspentTxOutputs().size()));
|
||||
issuanceTxTextField.setText(String.valueOf(daoFacade.getIssuanceSet().size()));
|
||||
compensationIssuanceTxTextField.setText(String.valueOf(daoFacade.getNumIssuanceTransactions(IssuanceType.COMPENSATION)));
|
||||
reimbursementIssuanceTxTextField.setText(String.valueOf(daoFacade.getNumIssuanceTransactions(IssuanceType.REIMBURSEMENT)));
|
||||
burntTxTextField.setText(String.valueOf(daoFacade.getFeeTxs().size()));
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,6 @@ import bisq.desktop.main.dao.wallet.BsqBalanceUtil;
|
||||
import bisq.desktop.main.funds.FundsView;
|
||||
import bisq.desktop.main.funds.deposit.DepositView;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.util.FormBuilder;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
import bisq.desktop.util.Layout;
|
||||
import bisq.desktop.util.validation.BsqAddressValidator;
|
||||
|
@ -35,6 +35,7 @@ import bisq.core.dao.DaoFacade;
|
||||
import bisq.core.dao.state.DaoStateListener;
|
||||
import bisq.core.dao.state.blockchain.Block;
|
||||
import bisq.core.dao.state.blockchain.TxType;
|
||||
import bisq.core.dao.state.governance.IssuanceType;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.user.Preferences;
|
||||
import bisq.core.util.BsqFormatter;
|
||||
@ -369,11 +370,19 @@ public class BsqTxView extends ActivatableView<GridPane, Void> implements BsqBal
|
||||
Label label;
|
||||
if (item.getConfirmations() > 0 && txType.ordinal() > TxType.INVALID.ordinal()) {
|
||||
if (txType == TxType.COMPENSATION_REQUEST &&
|
||||
daoFacade.isIssuanceTx(item.getTxId())) {
|
||||
daoFacade.isIssuanceTx(item.getTxId(), IssuanceType.COMPENSATION)) {
|
||||
if (field != null)
|
||||
field.setOnAction(null);
|
||||
|
||||
labelString = Res.get("dao.tx.issuance");
|
||||
labelString = Res.get("dao.tx.issuanceFromCompReq");
|
||||
label = new AutoTooltipLabel(labelString);
|
||||
setGraphic(label);
|
||||
} else if (txType == TxType.REIMBURSEMENT_REQUEST &&
|
||||
daoFacade.isIssuanceTx(item.getTxId(), IssuanceType.REIMBURSEMENT)) {
|
||||
if (field != null)
|
||||
field.setOnAction(null);
|
||||
|
||||
labelString = Res.get("dao.tx.issuanceFromReimbursement");
|
||||
label = new AutoTooltipLabel(labelString);
|
||||
setGraphic(label);
|
||||
} else if (item.isBurnedBsqTx() || item.getAmount().isZero()) {
|
||||
@ -535,13 +544,27 @@ public class BsqTxView extends ActivatableView<GridPane, Void> implements BsqBal
|
||||
case PROPOSAL:
|
||||
case COMPENSATION_REQUEST:
|
||||
String txId = item.getTxId();
|
||||
if (daoFacade.isIssuanceTx(txId)) {
|
||||
if (daoFacade.isIssuanceTx(txId, IssuanceType.COMPENSATION)) {
|
||||
awesomeIcon = AwesomeIcon.MONEY;
|
||||
style = "dao-tx-type-issuance-icon";
|
||||
int issuanceBlockHeight = daoFacade.getIssuanceBlockHeight(txId);
|
||||
long blockTime = daoFacade.getBlockTime(issuanceBlockHeight);
|
||||
String formattedDate = bsqFormatter.formatDateTime(new Date(blockTime));
|
||||
toolTipText = Res.get("dao.tx.issuance.tooltip", formattedDate);
|
||||
toolTipText = Res.get("dao.tx.issuanceFromCompReq.tooltip", formattedDate);
|
||||
} else {
|
||||
awesomeIcon = AwesomeIcon.FILE_TEXT;
|
||||
style = "dao-tx-type-proposal-fee-icon";
|
||||
}
|
||||
break;
|
||||
case REIMBURSEMENT_REQUEST:
|
||||
txId = item.getTxId();
|
||||
if (daoFacade.isIssuanceTx(txId, IssuanceType.REIMBURSEMENT)) {
|
||||
awesomeIcon = AwesomeIcon.MONEY;
|
||||
style = "dao-tx-type-issuance-icon";
|
||||
int issuanceBlockHeight = daoFacade.getIssuanceBlockHeight(txId);
|
||||
long blockTime = daoFacade.getBlockTime(issuanceBlockHeight);
|
||||
String formattedDate = bsqFormatter.formatDateTime(new Date(blockTime));
|
||||
toolTipText = Res.get("dao.tx.issuanceFromReimbursement.tooltip", formattedDate);
|
||||
} else {
|
||||
awesomeIcon = AwesomeIcon.FILE_TEXT;
|
||||
style = "dao-tx-type-proposal-fee-icon";
|
||||
|
@ -132,10 +132,15 @@ class TransactionsListItem {
|
||||
outgoing = false;
|
||||
txFeeForBsqPayment = true;
|
||||
|
||||
//
|
||||
final Optional<TxType> txTypeOptional = daoFacade.getOptionalTxType(txId);
|
||||
if (txTypeOptional.isPresent() && txTypeOptional.get().equals(TxType.COMPENSATION_REQUEST))
|
||||
details = Res.get("funds.tx.proposal");
|
||||
Optional<TxType> txTypeOptional = daoFacade.getOptionalTxType(txId);
|
||||
if (txTypeOptional.isPresent()) {
|
||||
if (txTypeOptional.get().equals(TxType.COMPENSATION_REQUEST))
|
||||
details = Res.get("funds.tx.compensationRequestTxFee");
|
||||
else if (txTypeOptional.get().equals(TxType.REIMBURSEMENT_REQUEST))
|
||||
details = Res.get("funds.tx.reimbursementRequestTxFee");
|
||||
else
|
||||
details = Res.get("funds.tx.proposalTxFee");
|
||||
}
|
||||
} else {
|
||||
outgoing = true;
|
||||
}
|
||||
|
@ -17,11 +17,11 @@
|
||||
~ along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import bisq.desktop.components.AutoTooltipButton?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import bisq.desktop.components.AutoTooltipButton?>
|
||||
<VBox fx:id="root" fx:controller="bisq.desktop.main.funds.transactions.TransactionsView"
|
||||
spacing="10" alignment="CENTER_RIGHT" xmlns:fx="http://javafx.com/fxml">
|
||||
<padding>
|
||||
|
@ -17,6 +17,7 @@
|
||||
~ along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import bisq.desktop.components.AutoTooltipButton?>
|
||||
<?import bisq.desktop.components.AutoTooltipLabel?>
|
||||
<?import bisq.desktop.components.AutoTooltipRadioButton?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
@ -27,7 +28,6 @@
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import bisq.desktop.components.AutoTooltipButton?>
|
||||
<VBox fx:id="root" fx:controller="bisq.desktop.main.funds.withdrawal.WithdrawalView"
|
||||
spacing="10" xmlns:fx="http://javafx.com/fxml">
|
||||
<padding>
|
||||
|
@ -30,8 +30,8 @@ import bisq.desktop.util.GUIUtil;
|
||||
import bisq.core.btc.exceptions.AddressEntryException;
|
||||
import bisq.core.btc.exceptions.InsufficientFundsException;
|
||||
import bisq.core.btc.listeners.BalanceListener;
|
||||
import bisq.core.btc.setup.WalletsSetup;
|
||||
import bisq.core.btc.model.AddressEntry;
|
||||
import bisq.core.btc.setup.WalletsSetup;
|
||||
import bisq.core.btc.wallet.BtcWalletService;
|
||||
import bisq.core.btc.wallet.Restrictions;
|
||||
import bisq.core.locale.Res;
|
||||
@ -65,7 +65,6 @@ import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.RadioButton;
|
||||
|
@ -103,7 +103,7 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
||||
final ObjectProperty<TradeCurrency> selectedTradeCurrencyProperty = new SimpleObjectProperty<>();
|
||||
final BooleanProperty showAllTradeCurrenciesProperty = new SimpleBooleanProperty(false);
|
||||
private final CurrencyList currencyListItems;
|
||||
private final CurrencyListItem showAllCurrencyListItem = new CurrencyListItem(new CryptoCurrency(GUIUtil.SHOW_ALL_FLAG, GUIUtil.SHOW_ALL_FLAG), -1);
|
||||
private final CurrencyListItem showAllCurrencyListItem = new CurrencyListItem(new CryptoCurrency(GUIUtil.SHOW_ALL_FLAG, ""), -1);
|
||||
final ObservableList<TradeStatistics2> tradeStatisticsByCurrency = FXCollections.observableArrayList();
|
||||
final ObservableList<XYChart.Data<Number, Number>> priceItems = FXCollections.observableArrayList();
|
||||
final ObservableList<XYChart.Data<Number, Number>> volumeItems = FXCollections.observableArrayList();
|
||||
|
@ -491,9 +491,9 @@ class OfferBookViewModel extends ActivatableViewModel {
|
||||
private void fillAllTradeCurrencies() {
|
||||
allTradeCurrencies.clear();
|
||||
// Used for ignoring filter (show all)
|
||||
allTradeCurrencies.add(new CryptoCurrency(GUIUtil.SHOW_ALL_FLAG, GUIUtil.SHOW_ALL_FLAG));
|
||||
allTradeCurrencies.add(new CryptoCurrency(GUIUtil.SHOW_ALL_FLAG, ""));
|
||||
allTradeCurrencies.addAll(preferences.getTradeCurrenciesAsObservable());
|
||||
allTradeCurrencies.add(new CryptoCurrency(GUIUtil.EDIT_FLAG, GUIUtil.EDIT_FLAG));
|
||||
allTradeCurrencies.add(new CryptoCurrency(GUIUtil.EDIT_FLAG, ""));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -61,8 +61,8 @@ import java.util.concurrent.TimeUnit;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
|
||||
import static bisq.desktop.util.FormBuilder.addMultilineLabel;
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
|
||||
|
||||
public class EmptyWalletWindow extends Overlay<EmptyWalletWindow> {
|
||||
private static final Logger log = LoggerFactory.getLogger(EmptyWalletWindow.class);
|
||||
|
@ -93,7 +93,8 @@ public class SelectDepositTxWindow extends Overlay<SelectDepositTxWindow> {
|
||||
Label label = addMultilineLabel(gridPane, ++rowIndex, Res.get("selectDepositTxWindow.msg"), 10);
|
||||
GridPane.setMargin(label, new Insets(0, 0, 10, 0));
|
||||
|
||||
transactionsComboBox = FormBuilder.addComboBox(gridPane, ++rowIndex, Res.get("selectDepositTxWindow.select"));;
|
||||
transactionsComboBox = FormBuilder.addComboBox(gridPane, ++rowIndex, Res.get("selectDepositTxWindow.select"));
|
||||
;
|
||||
transactionsComboBox.setConverter(new StringConverter<>() {
|
||||
@Override
|
||||
public String toString(Transaction transaction) {
|
||||
|
@ -54,7 +54,6 @@ import javafx.fxml.FXML;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
|
@ -26,7 +26,6 @@ import bisq.desktop.util.Layout;
|
||||
|
||||
import bisq.core.locale.Res;
|
||||
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
|
@ -60,8 +60,8 @@ import org.fxmisc.easybind.Subscription;
|
||||
import java.util.Optional;
|
||||
|
||||
import static bisq.desktop.util.FormBuilder.addButtonBusyAnimationLabelAfterGroup;
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelTextFieldWithCopyIcon;
|
||||
import static bisq.desktop.util.FormBuilder.addTitledGroupBg;
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelTextFieldWithCopyIcon;
|
||||
|
||||
public class SellerStep3View extends TradeStepView {
|
||||
|
||||
|
@ -38,8 +38,8 @@ import javafx.geometry.HPos;
|
||||
|
||||
import static bisq.desktop.util.FormBuilder.addHyperlinkWithIcon;
|
||||
import static bisq.desktop.util.FormBuilder.addLabel;
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
|
||||
import static bisq.desktop.util.FormBuilder.addTitledGroupBg;
|
||||
import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
|
||||
|
||||
@FxmlView
|
||||
public class AboutView extends ActivatableViewAndModel<GridPane, Activatable> {
|
||||
|
@ -50,7 +50,6 @@ import javax.inject.Inject;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.RadioButton;
|
||||
|
@ -128,8 +128,8 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
@Slf4j
|
||||
public class GUIUtil {
|
||||
public final static String SHOW_ALL_FLAG = "SHOW_ALL_FLAG";
|
||||
public final static String EDIT_FLAG = "EDIT_FLAG";
|
||||
public final static String SHOW_ALL_FLAG = "list.currency.showAll"; // Used for accessing the i18n resource
|
||||
public final static String EDIT_FLAG = "list.currency.editList"; // Used for accessing the i18n resource
|
||||
|
||||
public final static int FIAT_DECIMALS_WITH_ZEROS = 0;
|
||||
public final static int FIAT_PRICE_DECIMALS_WITH_ZEROS = 3;
|
||||
@ -295,10 +295,10 @@ public class GUIUtil {
|
||||
|
||||
switch (code) {
|
||||
case GUIUtil.SHOW_ALL_FLAG:
|
||||
currency.setText("▶ " + Res.get("list.currency.showAll"));
|
||||
currency.setText(Res.get("list.currency.showAll"));
|
||||
break;
|
||||
case GUIUtil.EDIT_FLAG:
|
||||
currency.setText(Res.get("▼ " + "list.currency.editList"));
|
||||
currency.setText(Res.get("list.currency.editList"));
|
||||
break;
|
||||
default:
|
||||
if (preferences.isSortMarketCurrenciesNumerically()) {
|
||||
@ -347,11 +347,11 @@ public class GUIUtil {
|
||||
|
||||
switch (code) {
|
||||
case GUIUtil.SHOW_ALL_FLAG:
|
||||
currencyType.setText("▶");
|
||||
currencyType.setText(Res.get("shared.all"));
|
||||
currency.setText(Res.get("list.currency.showAll"));
|
||||
break;
|
||||
case GUIUtil.EDIT_FLAG:
|
||||
currencyType.setText("▼");
|
||||
currencyType.setText(Res.get("shared.edit"));
|
||||
currency.setText(Res.get("list.currency.editList"));
|
||||
break;
|
||||
default:
|
||||
@ -392,10 +392,10 @@ public class GUIUtil {
|
||||
|
||||
switch (code) {
|
||||
case GUIUtil.SHOW_ALL_FLAG:
|
||||
currency.setText("▶ " + Res.get("list.currency.showAll"));
|
||||
currency.setText(Res.get("list.currency.showAll"));
|
||||
break;
|
||||
case GUIUtil.EDIT_FLAG:
|
||||
currency.setText(Res.get("▼ " + "list.currency.editList"));
|
||||
currency.setText(Res.get("list.currency.editList"));
|
||||
break;
|
||||
default:
|
||||
if (offerCountOptional.isPresent()) {
|
||||
@ -447,18 +447,16 @@ public class GUIUtil {
|
||||
|
||||
switch (code) {
|
||||
case GUIUtil.SHOW_ALL_FLAG:
|
||||
currencyType.setText("▶");
|
||||
currencyType.setText(Res.get("shared.all"));
|
||||
currency.setText(Res.get("list.currency.showAll"));
|
||||
break;
|
||||
case GUIUtil.EDIT_FLAG:
|
||||
currencyType.setText("▼");
|
||||
currencyType.setText(Res.get("shared.edit"));
|
||||
currency.setText(Res.get("list.currency.editList"));
|
||||
break;
|
||||
default:
|
||||
if (offerCountOptional.isPresent()) {
|
||||
offers.setText(offers.getText() + " (" + offerCountOptional.get() + " " +
|
||||
(offerCountOptional.get() == 1 ? postFixSingle : postFixMulti) + ")");
|
||||
}
|
||||
offerCountOptional.ifPresent(numOffer -> offers.setText(offers.getText() + " (" + numOffer + " " +
|
||||
(numOffer == 1 ? postFixSingle : postFixMulti) + ")"));
|
||||
}
|
||||
|
||||
setGraphic(box);
|
||||
@ -483,7 +481,7 @@ public class GUIUtil {
|
||||
this.getStyleClass().add("currency-label-selected");
|
||||
|
||||
if (id.equals(GUIUtil.SHOW_ALL_FLAG)) {
|
||||
setText("▶ " + Res.get("list.currency.showAll"));
|
||||
setText(Res.get("list.currency.showAll"));
|
||||
} else {
|
||||
setText(Res.get(id));
|
||||
}
|
||||
@ -516,7 +514,7 @@ public class GUIUtil {
|
||||
box.getChildren().addAll(paymentType, paymentMethod);
|
||||
|
||||
if (id.equals(GUIUtil.SHOW_ALL_FLAG)) {
|
||||
paymentType.setText("▶");
|
||||
paymentType.setText(Res.get("shared.all"));
|
||||
paymentMethod.setText(Res.get("list.currency.showAll"));
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,22 @@
|
||||
#!/bin/sh
|
||||
|
||||
# not tested script based on what @devinbileck posted in https://github.com/bisq-network/bisq/issues/1791
|
||||
JAVA_HOME=/usr/lib/jvm/openjdk-10.0.2
|
||||
|
||||
curl -L -O https://download.java.net/java/GA/jdk10/10.0.2/19aef61b38124481863b1413dce1855f/13/openjdk-10.0.2_linux-x64_bin.tar.gz
|
||||
sudo mkdir /usr/local/jvm/openjdk-10
|
||||
sudo tar -zxf openjdk-10.0.2_linux-x64_bin.tar.gz -C /usr/local/jvm/openjdk-10
|
||||
sudo update-alternatives --install "/usr/bin/java" "java" "/usr/local/jvm/openjdk-10/jdk-10.0.2/bin/java" 1500
|
||||
sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/local/jvm/openjdk-10/jdk-10.0.2/bin/javac" 1500
|
||||
git clone https://github.com/bisq-network/bisq
|
||||
if [ ! -d "$JAVA_HOME" ]; then
|
||||
apt-get -y install curl
|
||||
|
||||
curl -L -O https://download.java.net/java/GA/jdk10/10.0.2/19aef61b38124481863b1413dce1855f/13/openjdk-10.0.2_linux-x64_bin.tar.gz
|
||||
mkdir -p $JAVA_HOME
|
||||
tar -zxf openjdk-10.0.2_linux-x64_bin.tar.gz -C $JAVA_HOME --strip 1
|
||||
rm openjdk-10.0.2_linux-x64_bin.tar.gz
|
||||
|
||||
update-alternatives --install /usr/bin/java java $JAVA_HOME/bin/java 2000
|
||||
update-alternatives --install /usr/bin/javac javac $JAVA_HOME/bin/javac 2000
|
||||
fi
|
||||
|
||||
if [ ! -d "bisq" ]; then
|
||||
apt-get -y install git
|
||||
git clone https://github.com/bisq-network/bisq.git
|
||||
fi
|
||||
cd bisq
|
||||
./gradlew build
|
||||
java -jar desktop/build/libs/desktop-0.8.0-SNAPSHOT-all.jar
|
||||
|
Loading…
Reference in New Issue
Block a user