mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-07-22 14:41:08 -04:00
Second trade process (WIP)
This commit is contained in:
parent
6e644ae2b7
commit
0700a53561
105 changed files with 4575 additions and 999 deletions
|
@ -310,22 +310,22 @@ public class TradeWalletService {
|
||||||
return new Result(preparedDepositTx, takerConnectedOutputsForAllInputs, takerOutputs);
|
return new Result(preparedDepositTx, takerConnectedOutputsForAllInputs, takerOutputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void offererSignsAndPublishDepositTx(Transaction takersPreparedDepositTx,
|
public void signAndPublishDepositTx(Transaction preparedDepositTx,
|
||||||
List<TransactionOutput> offererConnectedOutputsForAllInputs,
|
List<TransactionOutput> offererConnectedOutputsForAllInputs,
|
||||||
List<TransactionOutput> takerConnectedOutputsForAllInputs,
|
List<TransactionOutput> takerConnectedOutputsForAllInputs,
|
||||||
List<TransactionOutput> offererOutputs,
|
List<TransactionOutput> buyerOutputs,
|
||||||
Coin offererInputAmount,
|
Coin buyerInputAmount,
|
||||||
byte[] offererPubKey,
|
byte[] offererPubKey,
|
||||||
byte[] takerPubKey,
|
byte[] takerPubKey,
|
||||||
byte[] arbitratorPubKey,
|
byte[] arbitratorPubKey,
|
||||||
FutureCallback<Transaction> callback) throws SigningException, TransactionVerificationException,
|
FutureCallback<Transaction> callback) throws SigningException, TransactionVerificationException,
|
||||||
WalletException {
|
WalletException {
|
||||||
log.trace("offererSignsAndPublishTx called");
|
log.trace("offererSignsAndPublishTx called");
|
||||||
log.trace("takersPreparedDepositTx " + takersPreparedDepositTx.toString());
|
log.trace("preparedDepositTx " + preparedDepositTx.toString());
|
||||||
log.trace("offererConnectedOutputsForAllInputs " + offererConnectedOutputsForAllInputs.toString());
|
log.trace("offererConnectedOutputsForAllInputs " + offererConnectedOutputsForAllInputs.toString());
|
||||||
log.trace("takerConnectedOutputsForAllInputs " + takerConnectedOutputsForAllInputs.toString());
|
log.trace("takerConnectedOutputsForAllInputs " + takerConnectedOutputsForAllInputs.toString());
|
||||||
log.trace("offererOutputs " + offererOutputs.toString());
|
log.trace("buyerOutputs " + buyerOutputs.toString());
|
||||||
log.trace("offererInputAmount " + offererInputAmount.toFriendlyString());
|
log.trace("buyerInputAmount " + buyerInputAmount.toFriendlyString());
|
||||||
log.trace("offererPubKey " + ECKey.fromPublicOnly(offererPubKey).toString());
|
log.trace("offererPubKey " + ECKey.fromPublicOnly(offererPubKey).toString());
|
||||||
log.trace("takerPubKey " + ECKey.fromPublicOnly(takerPubKey).toString());
|
log.trace("takerPubKey " + ECKey.fromPublicOnly(takerPubKey).toString());
|
||||||
log.trace("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString());
|
log.trace("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString());
|
||||||
|
@ -335,10 +335,10 @@ public class TradeWalletService {
|
||||||
|
|
||||||
// Check if takers Multisig script is identical to mine
|
// Check if takers Multisig script is identical to mine
|
||||||
Script p2SHMultiSigOutputScript = getP2SHMultiSigOutputScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
Script p2SHMultiSigOutputScript = getP2SHMultiSigOutputScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
||||||
if (!takersPreparedDepositTx.getOutput(0).getScriptPubKey().equals(p2SHMultiSigOutputScript))
|
if (!preparedDepositTx.getOutput(0).getScriptPubKey().equals(p2SHMultiSigOutputScript))
|
||||||
throw new TransactionVerificationException("Takers p2SHMultiSigOutputScript does not match to my p2SHMultiSigOutputScript");
|
throw new TransactionVerificationException("Takers p2SHMultiSigOutputScript does not match to my p2SHMultiSigOutputScript");
|
||||||
|
|
||||||
// The outpoints are not available from the serialized takersPreparedDepositTx, so we cannot use that tx directly, but we use it to construct a new
|
// The outpoints are not available from the serialized preparedDepositTx, so we cannot use that tx directly, but we use it to construct a new
|
||||||
// depositTx
|
// depositTx
|
||||||
Transaction depositTx = new Transaction(params);
|
Transaction depositTx = new Transaction(params);
|
||||||
|
|
||||||
|
@ -358,8 +358,8 @@ public class TradeWalletService {
|
||||||
for (TransactionOutput connectedOutputForInput : takerConnectedOutputsForAllInputs) {
|
for (TransactionOutput connectedOutputForInput : takerConnectedOutputsForAllInputs) {
|
||||||
TransactionOutPoint outPoint = new TransactionOutPoint(params, connectedOutputForInput.getIndex(), connectedOutputForInput.getParentTransaction());
|
TransactionOutPoint outPoint = new TransactionOutPoint(params, connectedOutputForInput.getIndex(), connectedOutputForInput.getParentTransaction());
|
||||||
|
|
||||||
// We grab the signature from the takersPreparedDepositTx and apply it to the new tx input
|
// We grab the signature from the preparedDepositTx and apply it to the new tx input
|
||||||
TransactionInput takerInput = takersPreparedDepositTx.getInputs().get(offererConnectedOutputsForAllInputs.size());
|
TransactionInput takerInput = preparedDepositTx.getInputs().get(offererConnectedOutputsForAllInputs.size());
|
||||||
byte[] scriptProgram = takerInput.getScriptSig().getProgram();
|
byte[] scriptProgram = takerInput.getScriptSig().getProgram();
|
||||||
if (scriptProgram.length == 0)
|
if (scriptProgram.length == 0)
|
||||||
throw new TransactionVerificationException("Inputs from taker not singed.");
|
throw new TransactionVerificationException("Inputs from taker not singed.");
|
||||||
|
@ -368,8 +368,8 @@ public class TradeWalletService {
|
||||||
depositTx.addInput(transactionInput);
|
depositTx.addInput(transactionInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all outputs from takersPreparedDepositTx to depositTx
|
// Add all outputs from preparedDepositTx to depositTx
|
||||||
takersPreparedDepositTx.getOutputs().forEach(depositTx::addOutput);
|
preparedDepositTx.getOutputs().forEach(depositTx::addOutput);
|
||||||
|
|
||||||
// Sign inputs
|
// Sign inputs
|
||||||
for (int i = 0; i < offererConnectedOutputsForAllInputs.size(); i++) {
|
for (int i = 0; i < offererConnectedOutputsForAllInputs.size(); i++) {
|
||||||
|
@ -379,11 +379,11 @@ public class TradeWalletService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// subtract change amount
|
// subtract change amount
|
||||||
for (int i = 1; i < offererOutputs.size() + 1; i++) {
|
for (int i = 1; i < buyerOutputs.size() + 1; i++) {
|
||||||
offererSpendingAmount = offererSpendingAmount.subtract(depositTx.getOutput(i).getValue());
|
offererSpendingAmount = offererSpendingAmount.subtract(depositTx.getOutput(i).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offererInputAmount.compareTo(offererSpendingAmount) != 0)
|
if (buyerInputAmount.compareTo(offererSpendingAmount) != 0)
|
||||||
throw new TransactionVerificationException("Offerers input amount does not match required value.");
|
throw new TransactionVerificationException("Offerers input amount does not match required value.");
|
||||||
|
|
||||||
verifyTransaction(depositTx);
|
verifyTransaction(depositTx);
|
||||||
|
@ -416,11 +416,11 @@ public class TradeWalletService {
|
||||||
return wallet.getTransaction(tx.getHash());
|
return wallet.getTransaction(tx.getHash());
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] offererCreatesAndSignsPayoutTx(Transaction depositTx,
|
public byte[] createAndSignPayoutTx(Transaction depositTx,
|
||||||
Coin offererPayoutAmount,
|
Coin offererPayoutAmount,
|
||||||
Coin takerPayoutAmount,
|
Coin takerPayoutAmount,
|
||||||
AddressEntry offererAddressEntry,
|
AddressEntry buyerAddressEntry,
|
||||||
String takerPayoutAddressString,
|
String sellerPayoutAddressString,
|
||||||
byte[] offererPubKey,
|
byte[] offererPubKey,
|
||||||
byte[] takerPubKey,
|
byte[] takerPubKey,
|
||||||
byte[] arbitratorPubKey)
|
byte[] arbitratorPubKey)
|
||||||
|
@ -429,24 +429,24 @@ public class TradeWalletService {
|
||||||
log.trace("depositTx " + depositTx.toString());
|
log.trace("depositTx " + depositTx.toString());
|
||||||
log.trace("offererPayoutAmount " + offererPayoutAmount.toFriendlyString());
|
log.trace("offererPayoutAmount " + offererPayoutAmount.toFriendlyString());
|
||||||
log.trace("takerPayoutAmount " + takerPayoutAmount.toFriendlyString());
|
log.trace("takerPayoutAmount " + takerPayoutAmount.toFriendlyString());
|
||||||
log.trace("offererAddressEntry " + offererAddressEntry.toString());
|
log.trace("buyerAddressEntry " + buyerAddressEntry.toString());
|
||||||
log.trace("takerPayoutAddressString " + takerPayoutAddressString);
|
log.trace("sellerPayoutAddressString " + sellerPayoutAddressString);
|
||||||
log.trace("offererPubKey " + ECKey.fromPublicOnly(offererPubKey).toString());
|
log.trace("offererPubKey " + ECKey.fromPublicOnly(offererPubKey).toString());
|
||||||
log.trace("takerPubKey " + ECKey.fromPublicOnly(takerPubKey).toString());
|
log.trace("takerPubKey " + ECKey.fromPublicOnly(takerPubKey).toString());
|
||||||
log.trace("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString());
|
log.trace("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString());
|
||||||
|
|
||||||
if (!Utils.HEX.encode(offererAddressEntry.getPubKey()).equals(Utils.HEX.encode(offererPubKey)))
|
if (!Utils.HEX.encode(buyerAddressEntry.getPubKey()).equals(Utils.HEX.encode(offererPubKey)))
|
||||||
throw new SigningException("OffererPubKey not matching key pair from addressEntry");
|
throw new SigningException("OffererPubKey not matching key pair from addressEntry");
|
||||||
|
|
||||||
Transaction preparedPayoutTx = createPayoutTx(depositTx,
|
Transaction preparedPayoutTx = createPayoutTx(depositTx,
|
||||||
offererPayoutAmount,
|
offererPayoutAmount,
|
||||||
takerPayoutAmount,
|
takerPayoutAmount,
|
||||||
offererAddressEntry.getAddressString(),
|
buyerAddressEntry.getAddressString(),
|
||||||
takerPayoutAddressString);
|
sellerPayoutAddressString);
|
||||||
// MS redeemScript
|
// MS redeemScript
|
||||||
Script redeemScript = getMultiSigRedeemScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
Script redeemScript = getMultiSigRedeemScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
||||||
Sha256Hash sigHash = preparedPayoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false);
|
Sha256Hash sigHash = preparedPayoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false);
|
||||||
ECKey.ECDSASignature offererSignature = offererAddressEntry.getKeyPair().sign(sigHash).toCanonicalised();
|
ECKey.ECDSASignature offererSignature = buyerAddressEntry.getKeyPair().sign(sigHash).toCanonicalised();
|
||||||
|
|
||||||
verifyTransaction(preparedPayoutTx);
|
verifyTransaction(preparedPayoutTx);
|
||||||
|
|
||||||
|
@ -459,12 +459,12 @@ public class TradeWalletService {
|
||||||
return offererSignature.encodeToDER();
|
return offererSignature.encodeToDER();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void takerSignsAndPublishPayoutTx(Transaction depositTx,
|
public void signAndPublishPayoutTx(Transaction depositTx,
|
||||||
byte[] offererSignature,
|
byte[] buyerSignature,
|
||||||
Coin offererPayoutAmount,
|
Coin offererPayoutAmount,
|
||||||
Coin takerPayoutAmount,
|
Coin takerPayoutAmount,
|
||||||
String offererAddressString,
|
String buyerAddressString,
|
||||||
AddressEntry takerAddressEntry,
|
AddressEntry sellerAddressEntry,
|
||||||
byte[] offererPubKey,
|
byte[] offererPubKey,
|
||||||
byte[] takerPubKey,
|
byte[] takerPubKey,
|
||||||
byte[] arbitratorPubKey,
|
byte[] arbitratorPubKey,
|
||||||
|
@ -472,27 +472,27 @@ public class TradeWalletService {
|
||||||
throws AddressFormatException, TransactionVerificationException, WalletException, SigningException {
|
throws AddressFormatException, TransactionVerificationException, WalletException, SigningException {
|
||||||
log.trace("takerSignsAndPublishPayoutTx called");
|
log.trace("takerSignsAndPublishPayoutTx called");
|
||||||
log.trace("depositTx " + depositTx.toString());
|
log.trace("depositTx " + depositTx.toString());
|
||||||
log.trace("offererSignature r " + ECKey.ECDSASignature.decodeFromDER(offererSignature).r.toString());
|
log.trace("buyerSignature r " + ECKey.ECDSASignature.decodeFromDER(buyerSignature).r.toString());
|
||||||
log.trace("offererSignature s " + ECKey.ECDSASignature.decodeFromDER(offererSignature).s.toString());
|
log.trace("buyerSignature s " + ECKey.ECDSASignature.decodeFromDER(buyerSignature).s.toString());
|
||||||
log.trace("offererPayoutAmount " + offererPayoutAmount.toFriendlyString());
|
log.trace("offererPayoutAmount " + offererPayoutAmount.toFriendlyString());
|
||||||
log.trace("takerPayoutAmount " + takerPayoutAmount.toFriendlyString());
|
log.trace("takerPayoutAmount " + takerPayoutAmount.toFriendlyString());
|
||||||
log.trace("offererAddressString " + offererAddressString);
|
log.trace("buyerAddressString " + buyerAddressString);
|
||||||
log.trace("takerAddressEntry " + takerAddressEntry);
|
log.trace("sellerAddressEntry " + sellerAddressEntry);
|
||||||
log.trace("offererPubKey " + ECKey.fromPublicOnly(offererPubKey).toString());
|
log.trace("offererPubKey " + ECKey.fromPublicOnly(offererPubKey).toString());
|
||||||
log.trace("takerPubKey " + ECKey.fromPublicOnly(takerPubKey).toString());
|
log.trace("takerPubKey " + ECKey.fromPublicOnly(takerPubKey).toString());
|
||||||
log.trace("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString());
|
log.trace("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString());
|
||||||
|
|
||||||
if (!Utils.HEX.encode(takerAddressEntry.getPubKey()).equals(Utils.HEX.encode(takerPubKey)))
|
if (!Utils.HEX.encode(sellerAddressEntry.getPubKey()).equals(Utils.HEX.encode(takerPubKey)))
|
||||||
throw new SigningException("TakerPubKey not matching key pair from addressEntry");
|
throw new SigningException("TakerPubKey not matching key pair from addressEntry");
|
||||||
|
|
||||||
Transaction payoutTx = createPayoutTx(depositTx,
|
Transaction payoutTx = createPayoutTx(depositTx,
|
||||||
offererPayoutAmount,
|
offererPayoutAmount,
|
||||||
takerPayoutAmount,
|
takerPayoutAmount,
|
||||||
offererAddressString,
|
buyerAddressString,
|
||||||
takerAddressEntry.getAddressString());
|
sellerAddressEntry.getAddressString());
|
||||||
Script redeemScript = getMultiSigRedeemScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
Script redeemScript = getMultiSigRedeemScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
||||||
Sha256Hash sigHash = payoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false);
|
Sha256Hash sigHash = payoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false);
|
||||||
ECKey.ECDSASignature takerSignature = takerAddressEntry.getKeyPair().sign(sigHash).toCanonicalised();
|
ECKey.ECDSASignature takerSignature = sellerAddressEntry.getKeyPair().sign(sigHash).toCanonicalised();
|
||||||
|
|
||||||
log.trace("takerSignature r " + takerSignature.r.toString());
|
log.trace("takerSignature r " + takerSignature.r.toString());
|
||||||
log.trace("takerSignature s " + takerSignature.s.toString());
|
log.trace("takerSignature s " + takerSignature.s.toString());
|
||||||
|
@ -500,7 +500,7 @@ public class TradeWalletService {
|
||||||
Sha256Hash hashForSignature = payoutTx.hashForSignature(0, redeemScript.getProgram(), (byte) 1);
|
Sha256Hash hashForSignature = payoutTx.hashForSignature(0, redeemScript.getProgram(), (byte) 1);
|
||||||
log.trace("hashForSignature " + Utils.HEX.encode(hashForSignature.getBytes()));
|
log.trace("hashForSignature " + Utils.HEX.encode(hashForSignature.getBytes()));
|
||||||
|
|
||||||
TransactionSignature offererTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(offererSignature),
|
TransactionSignature offererTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(buyerSignature),
|
||||||
Transaction.SigHash.ALL, false);
|
Transaction.SigHash.ALL, false);
|
||||||
TransactionSignature takerTxSig = new TransactionSignature(takerSignature, Transaction.SigHash.ALL, false);
|
TransactionSignature takerTxSig = new TransactionSignature(takerSignature, Transaction.SigHash.ALL, false);
|
||||||
// Take care of order of signatures. See comment below at getMultiSigRedeemScript
|
// Take care of order of signatures. See comment below at getMultiSigRedeemScript
|
||||||
|
|
|
@ -61,7 +61,19 @@ public class TaskRunner<T extends Model> {
|
||||||
try {
|
try {
|
||||||
currentTask = tasks.poll();
|
currentTask = tasks.poll();
|
||||||
log.trace("Run task: " + currentTask.getSimpleName());
|
log.trace("Run task: " + currentTask.getSimpleName());
|
||||||
|
log.debug("sharedModel.getClass() " + sharedModel.getClass());
|
||||||
|
log.debug("sharedModel.getClass().getSuperclass() " + sharedModel.getClass().getSuperclass());
|
||||||
|
/* Object c = currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass());
|
||||||
|
log.debug("c " + c);
|
||||||
|
Object c2 = currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass().getSuperclass());
|
||||||
|
log.debug("c getSuperclass " + c2);
|
||||||
|
Object o = currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass()).newInstance(this, sharedModel);*/
|
||||||
|
//TODO solve in tasks problem with superclasses
|
||||||
|
try {
|
||||||
currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass()).newInstance(this, sharedModel).run();
|
currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass()).newInstance(this, sharedModel).run();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass().getSuperclass()).newInstance(this, sharedModel).run();
|
||||||
|
}
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
throwable.printStackTrace();
|
throwable.printStackTrace();
|
||||||
handleErrorMessage("Error at taskRunner: " + throwable.getMessage());
|
handleErrorMessage("Error at taskRunner: " + throwable.getMessage());
|
||||||
|
|
|
@ -22,6 +22,7 @@ lower gradient color on tab: dddddd
|
||||||
.root {
|
.root {
|
||||||
-bs-grey: #666666;
|
-bs-grey: #666666;
|
||||||
-bs-bg-grey: #dddddd;
|
-bs-bg-grey: #dddddd;
|
||||||
|
-bs-bg-green: #00aa33;
|
||||||
-bs-error-red: #dd0000;
|
-bs-error-red: #dd0000;
|
||||||
|
|
||||||
-fx-accent: #0f87c3;
|
-fx-accent: #0f87c3;
|
||||||
|
@ -466,6 +467,42 @@ textfield */
|
||||||
-fx-background-radius: 3px, 3px, 2px, 1px;
|
-fx-background-radius: 3px, 3px, 2px, 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Pending trades */
|
||||||
|
#trade-wizard-item-background-disabled {
|
||||||
|
-fx-body-color: linear-gradient(to bottom, #f4f4f4, #F0F0F0);
|
||||||
|
-fx-outer-border: linear-gradient(to bottom, #dddddd, #ccc);
|
||||||
|
-fx-background-color: -fx-shadow-highlight-color,
|
||||||
|
-fx-outer-border,
|
||||||
|
-fx-inner-border,
|
||||||
|
-fx-body-color;
|
||||||
|
-fx-background-insets: 0 0 -1 0, 0, 1, 2;
|
||||||
|
-fx-background-radius: 3px, 3px, 2px, 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#trade-wizard-item-background-active {
|
||||||
|
-fx-body-color: linear-gradient(to bottom, #f1f6f7, #e7f5f9);
|
||||||
|
-fx-outer-border: linear-gradient(to bottom, #b5e1ef, #6aa4b6);
|
||||||
|
-fx-background-color: -fx-shadow-highlight-color,
|
||||||
|
-fx-outer-border,
|
||||||
|
-fx-inner-border,
|
||||||
|
-fx-body-color;
|
||||||
|
-fx-background-insets: 0 0 -1 0, 0, 1, 2;
|
||||||
|
-fx-background-radius: 3px, 3px, 2px, 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#trade-wizard-item-background-completed{
|
||||||
|
-fx-body-color: linear-gradient(to bottom, #f4f4f4, #E1E9E1);
|
||||||
|
-fx-outer-border: linear-gradient(to bottom, #99ba9c, #619865);
|
||||||
|
-fx-background-color: -fx-shadow-highlight-color,
|
||||||
|
-fx-outer-border,
|
||||||
|
-fx-inner-border,
|
||||||
|
-fx-body-color;
|
||||||
|
-fx-background-insets: 0 0 -1 0, 0, 1, 2;
|
||||||
|
-fx-background-radius: 3px, 3px, 2px, 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* TitledGroupBg */
|
/* TitledGroupBg */
|
||||||
#titled-group-bg-label {
|
#titled-group-bg-label {
|
||||||
-fx-font-weight: bold;
|
-fx-font-weight: bold;
|
||||||
|
|
|
@ -91,9 +91,9 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
||||||
setDisable(true); // alpha
|
setDisable(true); // alpha
|
||||||
}};
|
}};
|
||||||
ToggleButton settingsButton = new NavButton(SettingsView.class, "Settings");
|
ToggleButton settingsButton = new NavButton(SettingsView.class, "Settings");
|
||||||
ToggleButton accountButton = new NavButton(AccountView.class, "Account") {{
|
ToggleButton accountButton = new NavButton(AccountView.class, "Account"); /*{{
|
||||||
setDisable(true); // alpha
|
setDisable(true); // alpha
|
||||||
}};
|
}};*/
|
||||||
Pane portfolioButtonHolder = new Pane(portfolioButton);
|
Pane portfolioButtonHolder = new Pane(portfolioButton);
|
||||||
Pane bankAccountComboBoxHolder = new Pane();
|
Pane bankAccountComboBoxHolder = new Pane();
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ public class AccountView extends ActivatableView<TabPane, AccountViewModel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// for IRC demo we deactivate the arbitratorSettingsTab
|
// for IRC demo we deactivate the arbitratorSettingsTab
|
||||||
arbitratorSettingsTab.setDisable(true);
|
// arbitratorSettingsTab.setDisable(true);
|
||||||
|
|
||||||
tab.setContent(view.getRoot());
|
tab.setContent(view.getRoot());
|
||||||
root.getSelectionModel().select(tab);
|
root.getSelectionModel().select(tab);
|
||||||
|
|
|
@ -28,6 +28,7 @@ import javax.inject.Inject;
|
||||||
|
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.*;
|
import javafx.scene.*;
|
||||||
|
import javafx.scene.layout.*;
|
||||||
import javafx.stage.Modality;
|
import javafx.stage.Modality;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
@ -69,6 +70,10 @@ public class ArbitratorSettingsView extends AbstractView {
|
||||||
stage.initOwner(primaryStage);
|
stage.initOwner(primaryStage);
|
||||||
Scene scene = new Scene((Parent) view.getRoot(), 800, 600);
|
Scene scene = new Scene((Parent) view.getRoot(), 800, 600);
|
||||||
stage.setScene(scene);
|
stage.setScene(scene);
|
||||||
|
stage.setOnCloseRequest(e -> {
|
||||||
|
// need to unset root to be re-uasabel to other popups screens
|
||||||
|
scene.setRoot(new Pane());
|
||||||
|
});
|
||||||
stage.show();
|
stage.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.main.account.content.irc;
|
package io.bitsquare.gui.main.account.content.altcoin;
|
||||||
|
|
||||||
import io.bitsquare.common.viewfx.model.Activatable;
|
import io.bitsquare.common.viewfx.model.Activatable;
|
||||||
import io.bitsquare.common.viewfx.model.DataModel;
|
import io.bitsquare.common.viewfx.model.DataModel;
|
||||||
|
@ -33,7 +33,7 @@ import javafx.beans.property.StringProperty;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
|
|
||||||
class IrcAccountDataModel implements Activatable, DataModel {
|
class AltCoinAccountDataModel implements Activatable, DataModel {
|
||||||
|
|
||||||
private final User user;
|
private final User user;
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ class IrcAccountDataModel implements Activatable, DataModel {
|
||||||
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public IrcAccountDataModel(User user) {
|
public AltCoinAccountDataModel(User user) {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.*?>
|
<?import javafx.scene.control.*?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.irc.IrcAccountView" hgap="5.0"
|
<GridPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.content.altcoin.AltCoinAccountView" hgap="5.0"
|
||||||
vgap="5.0"
|
vgap="5.0"
|
||||||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
|
||||||
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
|
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
|
|
@ -15,7 +15,7 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.main.account.content.irc;
|
package io.bitsquare.gui.main.account.content.altcoin;
|
||||||
|
|
||||||
import io.bitsquare.common.viewfx.view.ActivatableViewAndModel;
|
import io.bitsquare.common.viewfx.view.ActivatableViewAndModel;
|
||||||
import io.bitsquare.common.viewfx.view.FxmlView;
|
import io.bitsquare.common.viewfx.view.FxmlView;
|
||||||
|
@ -40,7 +40,7 @@ import javafx.util.Callback;
|
||||||
* Just temporary for giving the user a possibility to test the app via simulating the bank transfer in a IRC chat.
|
* Just temporary for giving the user a possibility to test the app via simulating the bank transfer in a IRC chat.
|
||||||
*/
|
*/
|
||||||
@FxmlView
|
@FxmlView
|
||||||
public class IrcAccountView extends ActivatableViewAndModel<GridPane, IrcAccountViewModel> implements Wizard.Step {
|
public class AltCoinAccountView extends ActivatableViewAndModel<GridPane, AltCoinAccountViewModel> implements Wizard.Step {
|
||||||
|
|
||||||
@FXML HBox buttonsHBox;
|
@FXML HBox buttonsHBox;
|
||||||
@FXML InputTextField ircNickNameTextField;
|
@FXML InputTextField ircNickNameTextField;
|
||||||
|
@ -51,7 +51,7 @@ public class IrcAccountView extends ActivatableViewAndModel<GridPane, IrcAccount
|
||||||
private Wizard wizard;
|
private Wizard wizard;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public IrcAccountView(IrcAccountViewModel model) {
|
public AltCoinAccountView(AltCoinAccountViewModel model) {
|
||||||
super(model);
|
super(model);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.bitsquare.gui.main.account.content.irc;
|
package io.bitsquare.gui.main.account.content.altcoin;
|
||||||
|
|
||||||
import io.bitsquare.common.viewfx.model.ActivatableWithDataModel;
|
import io.bitsquare.common.viewfx.model.ActivatableWithDataModel;
|
||||||
import io.bitsquare.common.viewfx.model.ViewModel;
|
import io.bitsquare.common.viewfx.model.ViewModel;
|
||||||
|
@ -36,7 +36,7 @@ import javafx.beans.property.StringProperty;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.util.StringConverter;
|
import javafx.util.StringConverter;
|
||||||
|
|
||||||
class IrcAccountViewModel extends ActivatableWithDataModel<IrcAccountDataModel> implements ViewModel {
|
class AltCoinAccountViewModel extends ActivatableWithDataModel<AltCoinAccountDataModel> implements ViewModel {
|
||||||
|
|
||||||
private final InputValidator nickNameValidator;
|
private final InputValidator nickNameValidator;
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ class IrcAccountViewModel extends ActivatableWithDataModel<IrcAccountDataModel>
|
||||||
final ObjectProperty<FiatAccount.Type> type = new SimpleObjectProperty<>();
|
final ObjectProperty<FiatAccount.Type> type = new SimpleObjectProperty<>();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public IrcAccountViewModel(IrcAccountDataModel dataModel, BankAccountNumberValidator nickNameValidator) {
|
public AltCoinAccountViewModel(AltCoinAccountDataModel dataModel, BankAccountNumberValidator nickNameValidator) {
|
||||||
super(dataModel);
|
super(dataModel);
|
||||||
this.nickNameValidator = nickNameValidator;
|
this.nickNameValidator = nickNameValidator;
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
package io.bitsquare.gui.main.account.settings;
|
package io.bitsquare.gui.main.account.settings;
|
||||||
|
|
||||||
import io.bitsquare.BitsquareException;
|
|
||||||
import io.bitsquare.common.viewfx.view.ActivatableViewAndModel;
|
import io.bitsquare.common.viewfx.view.ActivatableViewAndModel;
|
||||||
import io.bitsquare.common.viewfx.view.CachingViewLoader;
|
import io.bitsquare.common.viewfx.view.CachingViewLoader;
|
||||||
import io.bitsquare.common.viewfx.view.FxmlView;
|
import io.bitsquare.common.viewfx.view.FxmlView;
|
||||||
|
@ -29,7 +28,7 @@ import io.bitsquare.gui.Navigation;
|
||||||
import io.bitsquare.gui.main.MainView;
|
import io.bitsquare.gui.main.MainView;
|
||||||
import io.bitsquare.gui.main.account.AccountView;
|
import io.bitsquare.gui.main.account.AccountView;
|
||||||
import io.bitsquare.gui.main.account.content.changepassword.ChangePasswordView;
|
import io.bitsquare.gui.main.account.content.changepassword.ChangePasswordView;
|
||||||
import io.bitsquare.gui.main.account.content.irc.IrcAccountView;
|
import io.bitsquare.gui.main.account.content.fiat.FiatAccountView;
|
||||||
import io.bitsquare.gui.main.account.content.registration.RegistrationView;
|
import io.bitsquare.gui.main.account.content.registration.RegistrationView;
|
||||||
import io.bitsquare.gui.main.account.content.restrictions.RestrictionsView;
|
import io.bitsquare.gui.main.account.content.restrictions.RestrictionsView;
|
||||||
import io.bitsquare.gui.main.account.content.seedwords.SeedWordsView;
|
import io.bitsquare.gui.main.account.content.seedwords.SeedWordsView;
|
||||||
|
@ -52,7 +51,7 @@ public class AccountSettingsView extends ActivatableViewAndModel {
|
||||||
private final ViewLoader viewLoader;
|
private final ViewLoader viewLoader;
|
||||||
private final Navigation navigation;
|
private final Navigation navigation;
|
||||||
|
|
||||||
private MenuItem seedWords, password, restrictions, ircAccount, registration;
|
private MenuItem seedWords, password, restrictions, fiatAccount, registration;
|
||||||
private Navigation.Listener listener;
|
private Navigation.Listener listener;
|
||||||
|
|
||||||
@FXML private VBox leftVBox;
|
@FXML private VBox leftVBox;
|
||||||
|
@ -77,15 +76,10 @@ public class AccountSettingsView extends ActivatableViewAndModel {
|
||||||
seedWords = new MenuItem(navigation, toggleGroup, "Wallet seed", SeedWordsView.class);
|
seedWords = new MenuItem(navigation, toggleGroup, "Wallet seed", SeedWordsView.class);
|
||||||
password = new MenuItem(navigation, toggleGroup, "Wallet password", ChangePasswordView.class);
|
password = new MenuItem(navigation, toggleGroup, "Wallet password", ChangePasswordView.class);
|
||||||
restrictions = new MenuItem(navigation, toggleGroup, "Arbitrator selection", RestrictionsView.class);
|
restrictions = new MenuItem(navigation, toggleGroup, "Arbitrator selection", RestrictionsView.class);
|
||||||
ircAccount = new MenuItem(navigation, toggleGroup, "Payments account(s)", IrcAccountView.class);
|
fiatAccount = new MenuItem(navigation, toggleGroup, "Payments account(s)", FiatAccountView.class);
|
||||||
registration = new MenuItem(navigation, toggleGroup, "Renew your account", RegistrationView.class);
|
registration = new MenuItem(navigation, toggleGroup, "Renew your account", RegistrationView.class);
|
||||||
|
|
||||||
seedWords.setDisable(true);
|
leftVBox.getChildren().addAll(seedWords, password, restrictions, fiatAccount, registration);
|
||||||
password.setDisable(true);
|
|
||||||
restrictions.setDisable(true);
|
|
||||||
registration.setDisable(true);
|
|
||||||
|
|
||||||
leftVBox.getChildren().addAll(seedWords, password, restrictions, ircAccount, registration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -93,7 +87,7 @@ public class AccountSettingsView extends ActivatableViewAndModel {
|
||||||
navigation.addListener(listener);
|
navigation.addListener(listener);
|
||||||
ViewPath viewPath = navigation.getCurrentPath();
|
ViewPath viewPath = navigation.getCurrentPath();
|
||||||
if (viewPath.size() == 3 && viewPath.indexOf(AccountSettingsView.class) == 2) {
|
if (viewPath.size() == 3 && viewPath.indexOf(AccountSettingsView.class) == 2) {
|
||||||
navigation.navigateTo(MainView.class, AccountView.class, AccountSettingsView.class, IrcAccountView.class);
|
navigation.navigateTo(MainView.class, AccountView.class, AccountSettingsView.class, SeedWordsView.class);
|
||||||
}
|
}
|
||||||
else if (viewPath.size() == 4 && viewPath.indexOf(AccountSettingsView.class) == 2) {
|
else if (viewPath.size() == 4 && viewPath.indexOf(AccountSettingsView.class) == 2) {
|
||||||
loadView(viewPath.get(3));
|
loadView(viewPath.get(3));
|
||||||
|
@ -114,9 +108,8 @@ public class AccountSettingsView extends ActivatableViewAndModel {
|
||||||
if (view instanceof SeedWordsView) seedWords.setSelected(true);
|
if (view instanceof SeedWordsView) seedWords.setSelected(true);
|
||||||
else if (view instanceof ChangePasswordView) password.setSelected(true);
|
else if (view instanceof ChangePasswordView) password.setSelected(true);
|
||||||
else if (view instanceof RestrictionsView) restrictions.setSelected(true);
|
else if (view instanceof RestrictionsView) restrictions.setSelected(true);
|
||||||
else if (view instanceof IrcAccountView) ircAccount.setSelected(true);
|
else if (view instanceof FiatAccountView) fiatAccount.setSelected(true);
|
||||||
else if (view instanceof RegistrationView) registration.setSelected(true);
|
else if (view instanceof RegistrationView) registration.setSelected(true);
|
||||||
else throw new BitsquareException("Selecting main menu button for view " + view + " is not supported");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import io.bitsquare.common.viewfx.view.ViewLoader;
|
||||||
import io.bitsquare.common.viewfx.view.Wizard;
|
import io.bitsquare.common.viewfx.view.Wizard;
|
||||||
import io.bitsquare.gui.Navigation;
|
import io.bitsquare.gui.Navigation;
|
||||||
import io.bitsquare.gui.main.MainView;
|
import io.bitsquare.gui.main.MainView;
|
||||||
import io.bitsquare.gui.main.account.content.irc.IrcAccountView;
|
import io.bitsquare.gui.main.account.content.fiat.FiatAccountView;
|
||||||
import io.bitsquare.gui.main.account.content.password.PasswordView;
|
import io.bitsquare.gui.main.account.content.password.PasswordView;
|
||||||
import io.bitsquare.gui.main.account.content.registration.RegistrationView;
|
import io.bitsquare.gui.main.account.content.registration.RegistrationView;
|
||||||
import io.bitsquare.gui.main.account.content.restrictions.RestrictionsView;
|
import io.bitsquare.gui.main.account.content.restrictions.RestrictionsView;
|
||||||
|
@ -46,7 +46,7 @@ public class AccountSetupWizard extends ActivatableView implements Wizard {
|
||||||
@FXML VBox leftVBox;
|
@FXML VBox leftVBox;
|
||||||
@FXML AnchorPane content;
|
@FXML AnchorPane content;
|
||||||
|
|
||||||
private WizardItem seedWords, password, ircAccount, restrictions, registration;
|
private WizardItem seedWords, password, fiatAccount, restrictions, registration;
|
||||||
private Navigation.Listener listener;
|
private Navigation.Listener listener;
|
||||||
|
|
||||||
private final ViewLoader viewLoader;
|
private final ViewLoader viewLoader;
|
||||||
|
@ -78,17 +78,17 @@ public class AccountSetupWizard extends ActivatableView implements Wizard {
|
||||||
password.onCompleted();
|
password.onCompleted();
|
||||||
restrictions.show();
|
restrictions.show();
|
||||||
}
|
}
|
||||||
else if (viewClass == IrcAccountView.class) {
|
else if (viewClass == FiatAccountView.class) {
|
||||||
seedWords.onCompleted();
|
seedWords.onCompleted();
|
||||||
password.onCompleted();
|
password.onCompleted();
|
||||||
restrictions.onCompleted();
|
restrictions.onCompleted();
|
||||||
ircAccount.show();
|
fiatAccount.show();
|
||||||
}
|
}
|
||||||
else if (viewClass == RegistrationView.class) {
|
else if (viewClass == RegistrationView.class) {
|
||||||
seedWords.onCompleted();
|
seedWords.onCompleted();
|
||||||
password.onCompleted();
|
password.onCompleted();
|
||||||
restrictions.onCompleted();
|
restrictions.onCompleted();
|
||||||
ircAccount.onCompleted();
|
fiatAccount.onCompleted();
|
||||||
registration.show();
|
registration.show();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -99,23 +99,18 @@ public class AccountSetupWizard extends ActivatableView implements Wizard {
|
||||||
"Setup password", "Protect your wallet with a password");
|
"Setup password", "Protect your wallet with a password");
|
||||||
restrictions = new WizardItem(RestrictionsView.class,
|
restrictions = new WizardItem(RestrictionsView.class,
|
||||||
"Select arbitrators", "Select which arbitrators you want to use for trading");
|
"Select arbitrators", "Select which arbitrators you want to use for trading");
|
||||||
ircAccount = new WizardItem(IrcAccountView.class,
|
fiatAccount = new WizardItem(FiatAccountView.class,
|
||||||
" Setup Payments account(s)", "You need to setup at least one payment account");
|
" Setup Payments account(s)", "You need to setup at least one payment account");
|
||||||
registration = new WizardItem(RegistrationView.class,
|
registration = new WizardItem(RegistrationView.class,
|
||||||
"Register your account", "The registration in the Blockchain requires a payment of 0.0002 BTC");
|
"Register your account", "The registration in the Blockchain requires a payment of 0.0002 BTC");
|
||||||
|
|
||||||
leftVBox.getChildren().addAll(seedWords, password, restrictions, ircAccount, registration);
|
leftVBox.getChildren().addAll(seedWords, password, restrictions, fiatAccount, registration);
|
||||||
|
|
||||||
seedWords.setDisable(true);
|
|
||||||
password.setDisable(true);
|
|
||||||
restrictions.setDisable(true);
|
|
||||||
registration.setDisable(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void activate() {
|
public void activate() {
|
||||||
navigation.addListener(listener);
|
navigation.addListener(listener);
|
||||||
ircAccount.show();
|
seedWords.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -135,10 +130,10 @@ public class AccountSetupWizard extends ActivatableView implements Wizard {
|
||||||
}
|
}
|
||||||
else if (currentStep instanceof RestrictionsView) {
|
else if (currentStep instanceof RestrictionsView) {
|
||||||
restrictions.onCompleted();
|
restrictions.onCompleted();
|
||||||
ircAccount.show();
|
fiatAccount.show();
|
||||||
}
|
}
|
||||||
else if (currentStep instanceof IrcAccountView) {
|
else if (currentStep instanceof FiatAccountView) {
|
||||||
ircAccount.onCompleted();
|
fiatAccount.onCompleted();
|
||||||
registration.show();
|
registration.show();
|
||||||
}
|
}
|
||||||
else if (currentStep instanceof RegistrationView) {
|
else if (currentStep instanceof RegistrationView) {
|
||||||
|
|
|
@ -28,31 +28,31 @@ import io.bitsquare.trade.protocol.placeoffer.tasks.AddOfferToRemoteOfferBook;
|
||||||
import io.bitsquare.trade.protocol.placeoffer.tasks.BroadcastCreateOfferFeeTx;
|
import io.bitsquare.trade.protocol.placeoffer.tasks.BroadcastCreateOfferFeeTx;
|
||||||
import io.bitsquare.trade.protocol.placeoffer.tasks.CreateOfferFeeTx;
|
import io.bitsquare.trade.protocol.placeoffer.tasks.CreateOfferFeeTx;
|
||||||
import io.bitsquare.trade.protocol.placeoffer.tasks.ValidateOffer;
|
import io.bitsquare.trade.protocol.placeoffer.tasks.ValidateOffer;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.OffererProtocol;
|
import io.bitsquare.trade.protocol.trade.offerer.OffererAsBuyerProtocol;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.CreateAndSignPayoutTx;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererCreatesAndSignPayoutTx;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.CreateOffererDepositTxInputs;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererCreatesDepositTxInputs;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessPayoutTxPublishedMessage;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererProcessPayoutTxPublishedMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessRequestDepositTxInputsMessage;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererProcessRequestDepositTxInputsMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessRequestPublishDepositTxMessage;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererProcessRequestPublishDepositTxMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendRequestTakerDepositPaymentMessage;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSendsRequestSellerDepositPaymentMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendFiatTransferStartedMessage;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSendsFiatTransferStartedMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendDepositTxPublishedMessage;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSendsDepositTxPublishedMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SignAndPublishDepositTx;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSignsAndPublishDepositTx;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyAndSignContract;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererVerifiesAndSignsContract;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakeOfferFeePayment;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakeOfferFeePayment;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakerAccount;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakerAccount;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.TakerProtocol;
|
import io.bitsquare.trade.protocol.trade.taker.TakerAsSellerProtocol;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.CreateAndSignContract;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCreatesAndSignContract;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.CreateTakeOfferFeeTx;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.CreateTakeOfferFeeTx;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.ProcessDepositTxPublishedMessage;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerProcessDepositTxPublishedMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.ProcessFiatTransferStartedMessage;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerProcessFiatTransferStartedMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.ProcessRequestTakerDepositPaymentMessage;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerProcessRequestSellerDepositPaymentMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendPayoutTxPublishedMessage;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSendsPayoutTxPublishedMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendRequestDepositTxInputsMessage;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSendsRequestDepositTxInputsMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendRequestPublishDepositTxMessage;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSendsRequestPublishDepositTxMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SignAndPublishPayoutTx;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSignsAndPublishPayoutTx;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.CommitDepositTx;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCommitDepositTx;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.CreateAndSignDepositTx;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCreatesAndSignsDepositTx;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOfferFeePayment;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOfferFeePayment;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOffererAccount;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOffererAccount;
|
||||||
|
|
||||||
|
@ -100,44 +100,44 @@ public class DebugView extends InitializableView {
|
||||||
|
|
||||||
|
|
||||||
/*---- Protocol ----*/
|
/*---- Protocol ----*/
|
||||||
OffererProtocol.class,
|
OffererAsBuyerProtocol.class,
|
||||||
ProcessRequestDepositTxInputsMessage.class,
|
OffererProcessRequestDepositTxInputsMessage.class,
|
||||||
CreateOffererDepositTxInputs.class,
|
OffererCreatesDepositTxInputs.class,
|
||||||
SendRequestTakerDepositPaymentMessage.class,
|
OffererSendsRequestSellerDepositPaymentMessage.class,
|
||||||
|
|
||||||
ProcessRequestPublishDepositTxMessage.class,
|
OffererProcessRequestPublishDepositTxMessage.class,
|
||||||
VerifyTakerAccount.class,
|
VerifyTakerAccount.class,
|
||||||
VerifyAndSignContract.class,
|
OffererVerifiesAndSignsContract.class,
|
||||||
SignAndPublishDepositTx.class,
|
OffererSignsAndPublishDepositTx.class,
|
||||||
SendDepositTxPublishedMessage.class,
|
OffererSendsDepositTxPublishedMessage.class,
|
||||||
|
|
||||||
CreateAndSignPayoutTx.class,
|
OffererCreatesAndSignPayoutTx.class,
|
||||||
VerifyTakeOfferFeePayment.class,
|
VerifyTakeOfferFeePayment.class,
|
||||||
SendFiatTransferStartedMessage.class,
|
OffererSendsFiatTransferStartedMessage.class,
|
||||||
|
|
||||||
ProcessPayoutTxPublishedMessage.class,
|
OffererProcessPayoutTxPublishedMessage.class,
|
||||||
Boolean.class, /* used as seperator*/
|
Boolean.class, /* used as seperator*/
|
||||||
|
|
||||||
|
|
||||||
/*---- Protocol ----*/
|
/*---- Protocol ----*/
|
||||||
TakerProtocol.class,
|
TakerAsSellerProtocol.class,
|
||||||
CreateTakeOfferFeeTx.class,
|
CreateTakeOfferFeeTx.class,
|
||||||
SendRequestDepositTxInputsMessage.class,
|
TakerSendsRequestDepositTxInputsMessage.class,
|
||||||
|
|
||||||
ProcessRequestTakerDepositPaymentMessage.class,
|
TakerProcessRequestSellerDepositPaymentMessage.class,
|
||||||
VerifyOffererAccount.class,
|
VerifyOffererAccount.class,
|
||||||
CreateAndSignContract.class,
|
TakerCreatesAndSignContract.class,
|
||||||
CreateAndSignDepositTx.class,
|
TakerCreatesAndSignsDepositTx.class,
|
||||||
SendRequestPublishDepositTxMessage.class,
|
TakerSendsRequestPublishDepositTxMessage.class,
|
||||||
|
|
||||||
ProcessDepositTxPublishedMessage.class,
|
TakerProcessDepositTxPublishedMessage.class,
|
||||||
CommitDepositTx.class,
|
TakerCommitDepositTx.class,
|
||||||
|
|
||||||
ProcessFiatTransferStartedMessage.class,
|
TakerProcessFiatTransferStartedMessage.class,
|
||||||
|
|
||||||
SignAndPublishPayoutTx.class,
|
TakerSignsAndPublishPayoutTx.class,
|
||||||
VerifyOfferFeePayment.class,
|
VerifyOfferFeePayment.class,
|
||||||
SendPayoutTxPublishedMessage.class
|
TakerSendsPayoutTxPublishedMessage.class
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@ package io.bitsquare.gui.main.portfolio.closed;
|
||||||
import io.bitsquare.common.viewfx.model.ActivatableWithDataModel;
|
import io.bitsquare.common.viewfx.model.ActivatableWithDataModel;
|
||||||
import io.bitsquare.common.viewfx.model.ViewModel;
|
import io.bitsquare.common.viewfx.model.ViewModel;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
import io.bitsquare.trade.OffererTrade;
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
import io.bitsquare.trade.TakerTrade;
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
import io.bitsquare.trade.Trade;
|
import io.bitsquare.trade.Trade;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
@ -71,8 +71,8 @@ class ClosedTradesViewModel extends ActivatableWithDataModel<ClosedTradesDataMod
|
||||||
String getState(ClosedTradesListItem item) {
|
String getState(ClosedTradesListItem item) {
|
||||||
if (item != null && item.getTrade() != null) {
|
if (item != null && item.getTrade() != null) {
|
||||||
Trade.LifeCycleState lifeCycleState = item.getTrade().lifeCycleStateProperty().get();
|
Trade.LifeCycleState lifeCycleState = item.getTrade().lifeCycleStateProperty().get();
|
||||||
if (lifeCycleState instanceof TakerTrade.TakerLifeCycleState) {
|
if (lifeCycleState instanceof TakerAsBuyerTrade.LifeCycleState) {
|
||||||
switch ((TakerTrade.TakerLifeCycleState) lifeCycleState) {
|
switch ((TakerAsBuyerTrade.LifeCycleState) lifeCycleState) {
|
||||||
case COMPLETED:
|
case COMPLETED:
|
||||||
return "Completed";
|
return "Completed";
|
||||||
case FAILED:
|
case FAILED:
|
||||||
|
@ -81,8 +81,8 @@ class ClosedTradesViewModel extends ActivatableWithDataModel<ClosedTradesDataMod
|
||||||
throw new RuntimeException("That must not happen. We got a pending state but we are in the closed trades list.");
|
throw new RuntimeException("That must not happen. We got a pending state but we are in the closed trades list.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (lifeCycleState instanceof OffererTrade.OffererLifeCycleState) {
|
else if (lifeCycleState instanceof OffererAsSellerTrade.LifeCycleState) {
|
||||||
switch ((OffererTrade.OffererLifeCycleState) lifeCycleState) {
|
switch ((OffererAsSellerTrade.LifeCycleState) lifeCycleState) {
|
||||||
case OFFER_CANCELED:
|
case OFFER_CANCELED:
|
||||||
return "Canceled";
|
return "Canceled";
|
||||||
case COMPLETED:
|
case COMPLETED:
|
||||||
|
@ -94,11 +94,7 @@ class ClosedTradesViewModel extends ActivatableWithDataModel<ClosedTradesDataMod
|
||||||
throw new RuntimeException("That must not happen. We got a pending state but we are in the closed trades list.");
|
throw new RuntimeException("That must not happen. We got a pending state but we are in the closed trades list.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new RuntimeException("That must not happen. We got no defined state.");
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -23,7 +23,9 @@ import io.bitsquare.common.viewfx.model.Activatable;
|
||||||
import io.bitsquare.common.viewfx.model.DataModel;
|
import io.bitsquare.common.viewfx.model.DataModel;
|
||||||
import io.bitsquare.gui.components.Popups;
|
import io.bitsquare.gui.components.Popups;
|
||||||
import io.bitsquare.offer.Offer;
|
import io.bitsquare.offer.Offer;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
import io.bitsquare.trade.OffererTrade;
|
import io.bitsquare.trade.OffererTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
import io.bitsquare.trade.TakerTrade;
|
import io.bitsquare.trade.TakerTrade;
|
||||||
import io.bitsquare.trade.Trade;
|
import io.bitsquare.trade.Trade;
|
||||||
import io.bitsquare.trade.TradeManager;
|
import io.bitsquare.trade.TradeManager;
|
||||||
|
@ -35,6 +37,8 @@ import com.google.inject.Inject;
|
||||||
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import javafx.beans.property.IntegerProperty;
|
import javafx.beans.property.IntegerProperty;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
import javafx.beans.property.SimpleIntegerProperty;
|
import javafx.beans.property.SimpleIntegerProperty;
|
||||||
|
@ -65,8 +69,8 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
||||||
final StringProperty txId = new SimpleStringProperty();
|
final StringProperty txId = new SimpleStringProperty();
|
||||||
final IntegerProperty selectedIndex = new SimpleIntegerProperty(-1);
|
final IntegerProperty selectedIndex = new SimpleIntegerProperty(-1);
|
||||||
|
|
||||||
final ObjectProperty<TakerTrade.TakerProcessState> takerProcessState = new SimpleObjectProperty<>();
|
final ObjectProperty<Trade.ProcessState> takerProcessState = new SimpleObjectProperty<>();
|
||||||
final ObjectProperty<OffererTrade.OffererProcessState> offererProcessState = new SimpleObjectProperty<>();
|
final ObjectProperty<Trade.ProcessState> offererProcessState = new SimpleObjectProperty<>();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public PendingTradesDataModel(TradeManager tradeManager, WalletService walletService, User user) {
|
public PendingTradesDataModel(TradeManager tradeManager, WalletService walletService, User user) {
|
||||||
|
@ -115,10 +119,10 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
||||||
isOfferer = getTrade().getOffer().getP2PSigPubKey().equals(user.getP2PSigPubKey());
|
isOfferer = getTrade().getOffer().getP2PSigPubKey().equals(user.getP2PSigPubKey());
|
||||||
|
|
||||||
Trade trade = getTrade();
|
Trade trade = getTrade();
|
||||||
if (trade instanceof TakerTrade)
|
if (trade instanceof TakerAsSellerTrade)
|
||||||
takerProcessState.bind(((TakerTrade) trade).processStateProperty());
|
takerProcessState.bind(trade.processStateProperty());
|
||||||
else
|
else
|
||||||
offererProcessState.bind(((OffererTrade) trade).processStateProperty());
|
offererProcessState.bind(trade.processStateProperty());
|
||||||
|
|
||||||
log.trace("selectTrade trade.stateProperty().get() " + trade.processStateProperty().get());
|
log.trace("selectTrade trade.stateProperty().get() " + trade.processStateProperty().get());
|
||||||
|
|
||||||
|
@ -127,11 +131,11 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
void fiatPaymentStarted() {
|
void fiatPaymentStarted() {
|
||||||
((OffererTrade) getTrade()).onFiatPaymentStarted();
|
((OffererAsBuyerTrade) getTrade()).onFiatPaymentStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void fiatPaymentReceived() {
|
void fiatPaymentReceived() {
|
||||||
((TakerTrade) getTrade()).onFiatPaymentReceived();
|
((TakerAsSellerTrade) getTrade()).onFiatPaymentReceived();
|
||||||
}
|
}
|
||||||
|
|
||||||
void withdraw(String toAddress) {
|
void withdraw(String toAddress) {
|
||||||
|
@ -180,8 +184,9 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
||||||
return isOfferer;
|
return isOfferer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
Trade getTrade() {
|
Trade getTrade() {
|
||||||
return selectedItem.getTrade();
|
return selectedItem != null ? selectedItem.getTrade() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Coin getTotalFees() {
|
Coin getTotalFees() {
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
package io.bitsquare.gui.main.portfolio.pending;
|
package io.bitsquare.gui.main.portfolio.pending;
|
||||||
|
|
||||||
|
import io.bitsquare.trade.OffererTrade;
|
||||||
|
import io.bitsquare.trade.TakerTrade;
|
||||||
import io.bitsquare.trade.Trade;
|
import io.bitsquare.trade.Trade;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
@ -51,11 +53,17 @@ public class PendingTradesListItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
|
public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
|
||||||
return trade.tradeAmountProperty();
|
if (trade instanceof TakerTrade)
|
||||||
|
return ((TakerTrade) trade).tradeAmountProperty();
|
||||||
|
else
|
||||||
|
return ((OffererTrade) trade).tradeAmountProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() {
|
public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() {
|
||||||
return trade.tradeVolumeProperty();
|
if (trade instanceof TakerTrade)
|
||||||
|
return ((TakerTrade) trade).tradeVolumeProperty();
|
||||||
|
else
|
||||||
|
return ((OffererTrade) trade).tradeVolumeProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getDate() {
|
public Date getDate() {
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pending;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.main.portfolio.pending.steps.CompletedView;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pending.steps.StartFiatView;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pending.steps.WaitView;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class PendingTradesOffererAsBuyerView extends PendingTradesStepsView {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(PendingTradesOffererAsBuyerView.class);
|
||||||
|
|
||||||
|
private TradeWizardItem waitTxConfirm;
|
||||||
|
private TradeWizardItem startFiat;
|
||||||
|
private TradeWizardItem waitFiatReceived;
|
||||||
|
private TradeWizardItem completed;
|
||||||
|
|
||||||
|
|
||||||
|
public PendingTradesOffererAsBuyerView() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void activate() {
|
||||||
|
showWaitTxConfirm();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deactivate() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showWaitTxConfirm() {
|
||||||
|
showItem(waitTxConfirm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showStartFiat() {
|
||||||
|
showItem(startFiat);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showWaitFiatReceived() {
|
||||||
|
showItem(waitFiatReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showCompleted() {
|
||||||
|
showItem(completed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addWizards() {
|
||||||
|
waitTxConfirm = new TradeWizardItem(WaitView.class, "Wait for blockchain confirmation");
|
||||||
|
startFiat = new TradeWizardItem(StartFiatView.class, "Start payment");
|
||||||
|
waitFiatReceived = new TradeWizardItem(WaitView.class, "Wait until payment has arrived");
|
||||||
|
completed = new TradeWizardItem(CompletedView.class, "Completed");
|
||||||
|
leftVBox.getChildren().addAll(waitTxConfirm, startFiat, waitFiatReceived, completed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pending;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.util.Layout;
|
||||||
|
|
||||||
|
import javafx.scene.*;
|
||||||
|
import javafx.scene.layout.*;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public abstract class PendingTradesStepsView extends HBox {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(PendingTradesStepsView.class);
|
||||||
|
|
||||||
|
protected VBox leftVBox;
|
||||||
|
protected AnchorPane contentPane;
|
||||||
|
protected TradeWizardItem current;
|
||||||
|
|
||||||
|
public PendingTradesStepsView() {
|
||||||
|
setSpacing(Layout.PADDING_WINDOW);
|
||||||
|
buildViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void activate() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deactivate() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void buildViews() {
|
||||||
|
addLeftBox();
|
||||||
|
addContentPane();
|
||||||
|
addWizards();
|
||||||
|
activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected void addWizards();
|
||||||
|
|
||||||
|
protected void showItem(TradeWizardItem item) {
|
||||||
|
if (current != null)
|
||||||
|
current.onCompleted();
|
||||||
|
current = item;
|
||||||
|
current.show();
|
||||||
|
loadView(item.getViewClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void loadView(Class<? extends Node> viewClass) {
|
||||||
|
Node view = null;
|
||||||
|
try {
|
||||||
|
view = viewClass.getDeclaredConstructor().newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
contentPane.getChildren().setAll(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addLeftBox() {
|
||||||
|
leftVBox = new VBox();
|
||||||
|
leftVBox.setSpacing(Layout.SPACING_VBOX);
|
||||||
|
getChildren().add(leftVBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addContentPane() {
|
||||||
|
contentPane = new AnchorPane();
|
||||||
|
HBox.setHgrow(contentPane, Priority.SOMETIMES);
|
||||||
|
getChildren().add(contentPane);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,10 @@ import io.bitsquare.common.viewfx.model.ViewModel;
|
||||||
import io.bitsquare.gui.util.BSFormatter;
|
import io.bitsquare.gui.util.BSFormatter;
|
||||||
import io.bitsquare.gui.util.validation.BtcAddressValidator;
|
import io.bitsquare.gui.util.validation.BtcAddressValidator;
|
||||||
import io.bitsquare.locale.BSResources;
|
import io.bitsquare.locale.BSResources;
|
||||||
import io.bitsquare.trade.OffererTrade;
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
import io.bitsquare.trade.TakerTrade;
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
import org.bitcoinj.utils.Fiat;
|
import org.bitcoinj.utils.Fiat;
|
||||||
|
@ -240,7 +242,50 @@ class PendingTradesViewModel extends ActivatableWithDataModel<PendingTradesDataM
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTakerState() {
|
private void updateTakerState() {
|
||||||
TakerTrade.TakerProcessState processState = dataModel.takerProcessState.get();
|
if (dataModel.getTrade() instanceof TakerAsSellerTrade) {
|
||||||
|
TakerAsSellerTrade.ProcessState processState = (TakerAsSellerTrade.ProcessState) dataModel.takerProcessState.get();
|
||||||
|
log.debug("updateTakerState " + processState);
|
||||||
|
if (processState != null) {
|
||||||
|
switch (processState) {
|
||||||
|
case TAKE_OFFER_FEE_TX_CREATED:
|
||||||
|
break;
|
||||||
|
case TAKE_OFFER_FEE_PUBLISHED:
|
||||||
|
break;
|
||||||
|
case TAKE_OFFER_FEE_PUBLISH_FAILED:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEPOSIT_PUBLISHED:
|
||||||
|
viewState.set(ViewState.TAKER_SELLER_WAIT_TX_CONF);
|
||||||
|
break;
|
||||||
|
case DEPOSIT_CONFIRMED:
|
||||||
|
viewState.set(ViewState.TAKER_SELLER_WAIT_PAYMENT_STARTED);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIAT_PAYMENT_STARTED:
|
||||||
|
viewState.set(ViewState.TAKER_SELLER_CONFIRM_RECEIVE_PAYMENT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIAT_PAYMENT_RECEIVED:
|
||||||
|
viewState.set(ViewState.TAKER_SELLER_COMPLETED);
|
||||||
|
break;
|
||||||
|
case PAYOUT_PUBLISHED:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MESSAGE_SENDING_FAILED:
|
||||||
|
viewState.set(ViewState.MESSAGE_SENDING_FAILED);
|
||||||
|
break;
|
||||||
|
case EXCEPTION:
|
||||||
|
viewState.set(ViewState.EXCEPTION);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
log.warn("unhandled processState " + processState);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dataModel.getTrade() instanceof TakerAsBuyerTrade) {
|
||||||
|
TakerAsBuyerTrade.ProcessState processState = (TakerAsBuyerTrade.ProcessState) dataModel.takerProcessState.get();
|
||||||
log.debug("updateTakerState " + processState);
|
log.debug("updateTakerState " + processState);
|
||||||
if (processState != null) {
|
if (processState != null) {
|
||||||
switch (processState) {
|
switch (processState) {
|
||||||
|
@ -282,8 +327,11 @@ class PendingTradesViewModel extends ActivatableWithDataModel<PendingTradesDataM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void updateOffererState() {
|
private void updateOffererState() {
|
||||||
OffererTrade.OffererProcessState processState = dataModel.offererProcessState.get();
|
if (dataModel.getTrade() instanceof OffererAsBuyerTrade) {
|
||||||
|
OffererAsBuyerTrade.ProcessState processState = (OffererAsBuyerTrade.ProcessState) dataModel.offererProcessState.get();
|
||||||
log.debug("updateOffererState " + processState);
|
log.debug("updateOffererState " + processState);
|
||||||
if (processState != null) {
|
if (processState != null) {
|
||||||
switch (processState) {
|
switch (processState) {
|
||||||
|
@ -315,4 +363,39 @@ class PendingTradesViewModel extends ActivatableWithDataModel<PendingTradesDataM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (dataModel.getTrade() instanceof OffererAsSellerTrade) {
|
||||||
|
OffererAsSellerTrade.ProcessState processState = (OffererAsSellerTrade.ProcessState) dataModel.offererProcessState.get();
|
||||||
|
log.debug("updateOffererState " + processState);
|
||||||
|
if (processState != null) {
|
||||||
|
switch (processState) {
|
||||||
|
case DEPOSIT_PUBLISHED:
|
||||||
|
viewState.set(ViewState.OFFERER_BUYER_WAIT_TX_CONF);
|
||||||
|
break;
|
||||||
|
case DEPOSIT_CONFIRMED:
|
||||||
|
viewState.set(ViewState.OFFERER_BUYER_START_PAYMENT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIAT_PAYMENT_STARTED:
|
||||||
|
viewState.set(ViewState.OFFERER_BUYER_WAIT_CONFIRM_PAYMENT_RECEIVED);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PAYOUT_PUBLISHED:
|
||||||
|
viewState.set(ViewState.OFFERER_BUYER_COMPLETED);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MESSAGE_SENDING_FAILED:
|
||||||
|
viewState.set(ViewState.MESSAGE_SENDING_FAILED);
|
||||||
|
break;
|
||||||
|
case EXCEPTION:
|
||||||
|
viewState.set(ViewState.EXCEPTION);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
log.warn("unhandled viewState " + processState);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pending;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.util.Colors;
|
||||||
|
|
||||||
|
import javafx.geometry.Insets;
|
||||||
|
import javafx.geometry.Pos;
|
||||||
|
import javafx.scene.*;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
|
||||||
|
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||||
|
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||||
|
|
||||||
|
public class TradeWizardItem extends Button {
|
||||||
|
public Class<? extends Node> getViewClass() {
|
||||||
|
return viewClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Class<? extends Node> viewClass;
|
||||||
|
|
||||||
|
public TradeWizardItem(Class<? extends Node> viewClass, String title) {
|
||||||
|
this.viewClass = viewClass;
|
||||||
|
|
||||||
|
setText(title);
|
||||||
|
setId("trade-wizard-item-background-disabled");
|
||||||
|
setPrefHeight(40);
|
||||||
|
setPrefWidth(270);
|
||||||
|
setPadding(new Insets(0, 20, 0, 10));
|
||||||
|
setAlignment(Pos.CENTER_LEFT);
|
||||||
|
|
||||||
|
Label icon = new Label();
|
||||||
|
icon.setTextFill(Colors.MID_GREY);
|
||||||
|
AwesomeDude.setIcon(icon, AwesomeIcon.ANGLE_DOWN);
|
||||||
|
setGraphic(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
void show() {
|
||||||
|
setId("trade-wizard-item-background-active");
|
||||||
|
Label icon = new Label();
|
||||||
|
icon.setTextFill(Colors.BLUE);
|
||||||
|
AwesomeDude.setIcon(icon, AwesomeIcon.ARROW_RIGHT);
|
||||||
|
setGraphic(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onCompleted() {
|
||||||
|
setId("trade-wizard-item-background-completed");
|
||||||
|
Label icon = new Label();
|
||||||
|
icon.setTextFill(Colors.GREEN);
|
||||||
|
AwesomeDude.setIcon(icon, AwesomeIcon.OK);
|
||||||
|
setGraphic(icon);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pending.proto;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.main.portfolio.pending.PendingTradesOffererAsBuyerView;
|
||||||
|
import io.bitsquare.gui.util.Layout;
|
||||||
|
|
||||||
|
import javafx.application.Application;
|
||||||
|
import javafx.scene.*;
|
||||||
|
import javafx.scene.layout.*;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class PendingMain extends Application {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(PendingMain.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(Stage primaryStage) {
|
||||||
|
AnchorPane root = new AnchorPane();
|
||||||
|
PendingTradesOffererAsBuyerView pendingTradesOffererAsBuyerView = new PendingTradesOffererAsBuyerView();
|
||||||
|
AnchorPane.setLeftAnchor(pendingTradesOffererAsBuyerView, Layout.PADDING_WINDOW);
|
||||||
|
AnchorPane.setRightAnchor(pendingTradesOffererAsBuyerView, Layout.PADDING_WINDOW);
|
||||||
|
AnchorPane.setTopAnchor(pendingTradesOffererAsBuyerView, Layout.PADDING_WINDOW);
|
||||||
|
AnchorPane.setBottomAnchor(pendingTradesOffererAsBuyerView, Layout.PADDING_WINDOW);
|
||||||
|
|
||||||
|
root.getChildren().add(pendingTradesOffererAsBuyerView);
|
||||||
|
|
||||||
|
Scene scene = new Scene(root, 1000, 600);
|
||||||
|
scene.getStylesheets().setAll(
|
||||||
|
"/io/bitsquare/gui/bitsquare.css",
|
||||||
|
"/io/bitsquare/gui/images.css");
|
||||||
|
primaryStage.setScene(scene);
|
||||||
|
primaryStage.show();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pending.steps;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.components.InfoDisplay;
|
||||||
|
import io.bitsquare.gui.components.InputTextField;
|
||||||
|
import io.bitsquare.gui.util.Layout;
|
||||||
|
|
||||||
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.layout.*;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static io.bitsquare.gui.util.ComponentBuilder.*;
|
||||||
|
|
||||||
|
public class CompletedView extends AnchorPane{
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(WaitView.class);
|
||||||
|
|
||||||
|
private Label btcTradeAmountLabel;
|
||||||
|
private TextField btcTradeAmountTextField;
|
||||||
|
private Label fiatTradeAmountLabel;
|
||||||
|
private TextField fiatTradeAmountTextField;
|
||||||
|
private Label feesLabel;
|
||||||
|
private TextField feesTextField;
|
||||||
|
private Label securityDepositLabel;
|
||||||
|
private TextField securityDepositTextField;
|
||||||
|
private InfoDisplay infoDisplay;
|
||||||
|
|
||||||
|
private InputTextField withdrawAddressTextField;
|
||||||
|
private TextField withdrawAmountTextField;
|
||||||
|
|
||||||
|
public CompletedView() {
|
||||||
|
buildViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildViews() {
|
||||||
|
AnchorPane.setLeftAnchor(this, 0d);
|
||||||
|
AnchorPane.setRightAnchor(this, 0d);
|
||||||
|
AnchorPane.setTopAnchor(this, 0d);
|
||||||
|
AnchorPane.setBottomAnchor(this, 0d);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
GridPane gridPane = getAndAddGridPane(this);
|
||||||
|
|
||||||
|
getAndAddTitledGroupBg(gridPane, i, 5, "Summary");
|
||||||
|
LabelTextFieldPair btcTradeAmountPair = getAndAddLabelTextFieldPair(gridPane, i++, "You have bought:", Layout.FIRST_ROW_DISTANCE);
|
||||||
|
btcTradeAmountLabel = btcTradeAmountPair.label;
|
||||||
|
btcTradeAmountTextField = btcTradeAmountPair.textField;
|
||||||
|
|
||||||
|
LabelTextFieldPair fiatTradeAmountPair = getAndAddLabelTextFieldPair(gridPane, i++, "You have paid:");
|
||||||
|
fiatTradeAmountLabel = fiatTradeAmountPair.label;
|
||||||
|
fiatTradeAmountTextField = fiatTradeAmountPair.textField;
|
||||||
|
|
||||||
|
LabelTextFieldPair feesPair = getAndAddLabelTextFieldPair(gridPane, i++, "Total fees paid:");
|
||||||
|
feesLabel = feesPair.label;
|
||||||
|
feesTextField = feesPair.textField;
|
||||||
|
|
||||||
|
LabelTextFieldPair securityDepositPair = getAndAddLabelTextFieldPair(gridPane, i++, "Refunded security deposit:");
|
||||||
|
securityDepositLabel = securityDepositPair.label;
|
||||||
|
securityDepositTextField = securityDepositPair.textField;
|
||||||
|
|
||||||
|
infoDisplay = getAndAddInfoDisplay(gridPane, i++, "infoDisplay", this::onOpenHelp);
|
||||||
|
|
||||||
|
getAndAddTitledGroupBg(gridPane, i, 2, "Withdraw your bitcoins", Layout.GROUP_DISTANCE);
|
||||||
|
withdrawAmountTextField = getAndAddLabelTextFieldPair(gridPane, i++, "Amount to withdraw:", Layout.FIRST_ROW_AND_GROUP_DISTANCE).textField;
|
||||||
|
withdrawAddressTextField = getAndAddLabelInputTextFieldPair(gridPane, i++, "Withdraw to address:").inputTextField;
|
||||||
|
getAndAddButton(gridPane, i++, "Withdraw to external wallet", this::onWithdraw);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onWithdraw(ActionEvent actionEvent) {
|
||||||
|
log.debug("onWithdraw");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onOpenHelp(ActionEvent actionEvent) {
|
||||||
|
log.debug("onOpenHelp");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pending.steps;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.components.InfoDisplay;
|
||||||
|
import io.bitsquare.gui.components.TxIdTextField;
|
||||||
|
import io.bitsquare.gui.util.Layout;
|
||||||
|
|
||||||
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.layout.*;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static io.bitsquare.gui.util.ComponentBuilder.*;
|
||||||
|
|
||||||
|
public class ConfirmFiatView extends AnchorPane {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ConfirmFiatView.class);
|
||||||
|
|
||||||
|
private TextField statusTextField;
|
||||||
|
private TxIdTextField txIdTextField;
|
||||||
|
private InfoDisplay infoDisplay;
|
||||||
|
|
||||||
|
public ConfirmFiatView() {
|
||||||
|
buildViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildViews() {
|
||||||
|
AnchorPane.setLeftAnchor(this, 0d);
|
||||||
|
AnchorPane.setRightAnchor(this, 0d);
|
||||||
|
AnchorPane.setTopAnchor(this, 0d);
|
||||||
|
AnchorPane.setBottomAnchor(this, 0d);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
GridPane gridPane = getAndAddGridPane(this);
|
||||||
|
getAndAddTitledGroupBg(gridPane, i, 3, "Trade status");
|
||||||
|
statusTextField = getAndAddLabelTextFieldPair(gridPane, i++, "Status:", Layout.FIRST_ROW_DISTANCE).textField;
|
||||||
|
txIdTextField = getAndAddLabelTxIdTextFieldPair(gridPane, i++, "Deposit transaction ID:").txIdTextField;
|
||||||
|
infoDisplay = getAndAddInfoDisplay(gridPane, i++, "infoDisplay", this::onOpenHelp);
|
||||||
|
getAndAddButton(gridPane, i++, "Confirm payment receipt", this::onPaymentReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onPaymentReceived(ActionEvent actionEvent) {
|
||||||
|
log.debug("onPaymentReceived");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onOpenHelp(ActionEvent actionEvent) {
|
||||||
|
log.debug("onOpenHelp");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pending.steps;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.components.InfoDisplay;
|
||||||
|
import io.bitsquare.gui.components.TextFieldWithCopyIcon;
|
||||||
|
import io.bitsquare.gui.util.Layout;
|
||||||
|
|
||||||
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.layout.*;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static io.bitsquare.gui.util.ComponentBuilder.*;
|
||||||
|
|
||||||
|
public class StartFiatView extends AnchorPane {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(WaitView.class);
|
||||||
|
|
||||||
|
private TextFieldWithCopyIcon fiatAmountTextField;
|
||||||
|
private TextField paymentMethodTextField;
|
||||||
|
private TextFieldWithCopyIcon holderNameTextField;
|
||||||
|
private TextFieldWithCopyIcon primarTextField;
|
||||||
|
private TextFieldWithCopyIcon secondaryIdTextField;
|
||||||
|
private InfoDisplay infoDisplay;
|
||||||
|
|
||||||
|
public StartFiatView() {
|
||||||
|
buildViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildViews() {
|
||||||
|
AnchorPane.setLeftAnchor(this, 0d);
|
||||||
|
AnchorPane.setRightAnchor(this, 0d);
|
||||||
|
AnchorPane.setTopAnchor(this, 0d);
|
||||||
|
AnchorPane.setBottomAnchor(this, 0d);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
GridPane gridPane = getAndAddGridPane(this);
|
||||||
|
getAndAddTitledGroupBg(gridPane, i, 6, "Payments details");
|
||||||
|
fiatAmountTextField = getAndAddLabelTextFieldWithCopyIconPair(gridPane, i++, "Amount to transfer:", Layout.FIRST_ROW_DISTANCE).textFieldWithCopyIcon;
|
||||||
|
paymentMethodTextField = getAndAddLabelTextFieldPair(gridPane, i++, "Payment method:").textField;
|
||||||
|
holderNameTextField = getAndAddLabelTextFieldWithCopyIconPair(gridPane, i++, "Receiver:").textFieldWithCopyIcon;
|
||||||
|
primarTextField = getAndAddLabelTextFieldWithCopyIconPair(gridPane, i++, "IBAN:").textFieldWithCopyIcon;
|
||||||
|
secondaryIdTextField = getAndAddLabelTextFieldWithCopyIconPair(gridPane, i++, "BIC:").textFieldWithCopyIcon;
|
||||||
|
infoDisplay = getAndAddInfoDisplay(gridPane, i++, "infoDisplay", this::onOpenHelp);
|
||||||
|
getAndAddButton(gridPane, i++, "Payment started", this::onPaymentStarted);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onPaymentStarted(ActionEvent actionEvent) {
|
||||||
|
log.debug("onPaymentStarted");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onOpenHelp(ActionEvent actionEvent) {
|
||||||
|
log.debug("onOpenHelp");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.main.portfolio.pending.steps;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.components.InfoDisplay;
|
||||||
|
import io.bitsquare.gui.components.TxIdTextField;
|
||||||
|
import io.bitsquare.gui.util.Layout;
|
||||||
|
|
||||||
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.layout.*;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static io.bitsquare.gui.util.ComponentBuilder.*;
|
||||||
|
|
||||||
|
public class WaitView extends AnchorPane {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(WaitView.class);
|
||||||
|
|
||||||
|
|
||||||
|
private TextField statusTextField;
|
||||||
|
private TxIdTextField txIdTextField;
|
||||||
|
private InfoDisplay infoDisplay;
|
||||||
|
|
||||||
|
public WaitView() {
|
||||||
|
buildViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildViews() {
|
||||||
|
AnchorPane.setLeftAnchor(this, 0d);
|
||||||
|
AnchorPane.setRightAnchor(this, 0d);
|
||||||
|
AnchorPane.setTopAnchor(this, 0d);
|
||||||
|
AnchorPane.setBottomAnchor(this, 0d);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
GridPane gridPane = getAndAddGridPane(this);
|
||||||
|
getAndAddTitledGroupBg(gridPane, i, 3, "Trade status");
|
||||||
|
statusTextField = getAndAddLabelTextFieldPair(gridPane, i++, "Status:", Layout.FIRST_ROW_DISTANCE).textField;
|
||||||
|
txIdTextField = getAndAddLabelTxIdTextFieldPair(gridPane, i++, "Deposit transaction ID:").txIdTextField;
|
||||||
|
infoDisplay = getAndAddInfoDisplay(gridPane, i++, "infoDisplay", this::onOpenHelp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onOpenHelp(ActionEvent actionEvent) {
|
||||||
|
log.debug("onOpenHelp");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ import io.bitsquare.common.viewfx.view.View;
|
||||||
import io.bitsquare.common.viewfx.view.ViewLoader;
|
import io.bitsquare.common.viewfx.view.ViewLoader;
|
||||||
import io.bitsquare.gui.Navigation;
|
import io.bitsquare.gui.Navigation;
|
||||||
import io.bitsquare.gui.components.InputTextField;
|
import io.bitsquare.gui.components.InputTextField;
|
||||||
import io.bitsquare.gui.components.Popups;
|
|
||||||
import io.bitsquare.gui.main.MainView;
|
import io.bitsquare.gui.main.MainView;
|
||||||
import io.bitsquare.gui.main.trade.createoffer.CreateOfferView;
|
import io.bitsquare.gui.main.trade.createoffer.CreateOfferView;
|
||||||
import io.bitsquare.gui.main.trade.offerbook.OfferBookView;
|
import io.bitsquare.gui.main.trade.offerbook.OfferBookView;
|
||||||
|
@ -128,13 +127,6 @@ public abstract class TradeView extends ActivatableView<TabPane, Void> {
|
||||||
OfferActionHandler offerActionHandler = new OfferActionHandler() {
|
OfferActionHandler offerActionHandler = new OfferActionHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void createOffer(Coin amount, Fiat price) {
|
public void createOffer(Coin amount, Fiat price) {
|
||||||
if (TradeView.this instanceof SellView) {
|
|
||||||
Popups.openWarningPopup("Warning",
|
|
||||||
"Please note that a sell offer is not supported yet for trading",
|
|
||||||
"You can create the offer and it appears in the offerbook, " +
|
|
||||||
"but nobody can take the offer.\n" +
|
|
||||||
"That will be implemented in an upcoming development milestone.");
|
|
||||||
}
|
|
||||||
TradeView.this.amount = amount;
|
TradeView.this.amount = amount;
|
||||||
TradeView.this.price = price;
|
TradeView.this.price = price;
|
||||||
TradeView.this.navigation.navigateTo(MainView.class, TradeView.this.getClass(),
|
TradeView.this.navigation.navigateTo(MainView.class, TradeView.this.getClass(),
|
||||||
|
@ -175,7 +167,7 @@ public abstract class TradeView extends ActivatableView<TabPane, Void> {
|
||||||
// CreateOffer and TakeOffer must not be cached by ViewLoader as we cannot use a view multiple times
|
// CreateOffer and TakeOffer must not be cached by ViewLoader as we cannot use a view multiple times
|
||||||
// in different graphs
|
// in different graphs
|
||||||
takeOfferView = (TakeOfferView) view;
|
takeOfferView = (TakeOfferView) view;
|
||||||
takeOfferView.initWithData(direction, amount, offer);
|
takeOfferView.initWithData(amount, offer);
|
||||||
takeOfferPane = ((TakeOfferView) view).getRoot();
|
takeOfferPane = ((TakeOfferView) view).getRoot();
|
||||||
final Tab tab = new Tab("Take offer");
|
final Tab tab = new Tab("Take offer");
|
||||||
takeOfferView.setCloseHandler(() -> {
|
takeOfferView.setCloseHandler(() -> {
|
||||||
|
|
|
@ -75,7 +75,7 @@ class CreateOfferDataModel implements Activatable, DataModel {
|
||||||
|
|
||||||
private final String offerId;
|
private final String offerId;
|
||||||
|
|
||||||
@Nullable private Offer.Direction direction = null;
|
private Offer.Direction direction;
|
||||||
private AddressEntry addressEntry;
|
private AddressEntry addressEntry;
|
||||||
|
|
||||||
final StringProperty requestPlaceOfferErrorMessage = new SimpleStringProperty();
|
final StringProperty requestPlaceOfferErrorMessage = new SimpleStringProperty();
|
||||||
|
@ -211,8 +211,12 @@ class CreateOfferDataModel implements Activatable, DataModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculateTotalToPay() {
|
void calculateTotalToPay() {
|
||||||
if (securityDepositAsCoin.get() != null)
|
if (securityDepositAsCoin.get() != null) {
|
||||||
|
if (direction == Offer.Direction.BUY)
|
||||||
totalToPayAsCoin.set(offerFeeAsCoin.get().add(networkFeeAsCoin.get()).add(securityDepositAsCoin.get()));
|
totalToPayAsCoin.set(offerFeeAsCoin.get().add(networkFeeAsCoin.get()).add(securityDepositAsCoin.get()));
|
||||||
|
else
|
||||||
|
totalToPayAsCoin.set(offerFeeAsCoin.get().add(networkFeeAsCoin.get()).add(securityDepositAsCoin.get()).add(amountAsCoin.get()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -234,13 +238,6 @@ class CreateOfferDataModel implements Activatable, DataModel {
|
||||||
return direction;
|
return direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("NullableProblems")
|
|
||||||
void setDirection(Offer.Direction direction) {
|
|
||||||
// direction can not be changed once it is initially set
|
|
||||||
checkNotNull(direction);
|
|
||||||
this.direction = direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
WalletService getWalletService() {
|
WalletService getWalletService() {
|
||||||
return walletService;
|
return walletService;
|
||||||
}
|
}
|
||||||
|
@ -270,4 +267,9 @@ class CreateOfferDataModel implements Activatable, DataModel {
|
||||||
public Boolean getDisplaySecurityDepositInfo() {
|
public Boolean getDisplaySecurityDepositInfo() {
|
||||||
return preferences.getDisplaySecurityDepositInfo();
|
return preferences.getDisplaySecurityDepositInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void initWithData(Offer.Direction direction, Coin amount, Fiat price) {
|
||||||
|
checkNotNull(direction);
|
||||||
|
this.direction = direction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
<Insets bottom="10.0" left="10.0" right="10.0" top="20.0"/>
|
<Insets bottom="10.0" left="10.0" right="10.0" top="20.0"/>
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
<ImageView fx:id="imageView" pickOnBounds="true"/>
|
<ImageView fx:id="imageView" pickOnBounds="true"/>
|
||||||
<Label fx:id="buyLabel" id="direction-icon-label" text="%createOffer.amountPriceBox.subTitle"
|
<Label fx:id="buyLabel" id="direction-icon-label"
|
||||||
alignment="CENTER">
|
alignment="CENTER">
|
||||||
<padding>
|
<padding>
|
||||||
<Insets top="-5.0"/>
|
<Insets top="-5.0"/>
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
<Insets right="10.0" top="20.0"/>
|
<Insets right="10.0" top="20.0"/>
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
<VBox spacing="4">
|
<VBox spacing="4">
|
||||||
<Label id="input-description-label" text="%createOffer.amountPriceBox.amountDescription"
|
<Label fx:id="amountToTradeLabel" id="input-description-label" text="%createOffer.amountPriceBox.amountDescription"
|
||||||
prefWidth="170"/>
|
prefWidth="170"/>
|
||||||
<HBox>
|
<HBox>
|
||||||
<InputTextField fx:id="amountTextField" id="text-input-with-currency-text-field"
|
<InputTextField fx:id="amountTextField" id="text-input-with-currency-text-field"
|
||||||
|
@ -125,8 +125,7 @@
|
||||||
</HBox>
|
</HBox>
|
||||||
</VBox>
|
</VBox>
|
||||||
|
|
||||||
<InfoDisplay gridPane="$gridPane" onAction="#onOpenGeneralHelp" rowIndex="2"
|
<InfoDisplay fx:id="amountPriceBoxInfo" gridPane="$gridPane" onAction="#onOpenGeneralHelp" rowIndex="2"/>
|
||||||
text="%createOffer.amountPriceBox.info"/>
|
|
||||||
|
|
||||||
<Button fx:id="showPaymentInfoScreenButton" text="%createOffer.amountPriceBox.next" id="show-details-button"
|
<Button fx:id="showPaymentInfoScreenButton" text="%createOffer.amountPriceBox.next" id="show-details-button"
|
||||||
GridPane.columnIndex="1" GridPane.rowIndex="3" defaultButton="true"
|
GridPane.columnIndex="1" GridPane.rowIndex="3" defaultButton="true"
|
||||||
|
|
|
@ -35,6 +35,7 @@ import io.bitsquare.gui.main.help.Help;
|
||||||
import io.bitsquare.gui.main.help.HelpId;
|
import io.bitsquare.gui.main.help.HelpId;
|
||||||
import io.bitsquare.gui.main.portfolio.PortfolioView;
|
import io.bitsquare.gui.main.portfolio.PortfolioView;
|
||||||
import io.bitsquare.gui.main.portfolio.offer.OffersView;
|
import io.bitsquare.gui.main.portfolio.offer.OffersView;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pending.PendingTradesView;
|
||||||
import io.bitsquare.gui.main.trade.TradeView;
|
import io.bitsquare.gui.main.trade.TradeView;
|
||||||
import io.bitsquare.gui.util.ImageUtil;
|
import io.bitsquare.gui.util.ImageUtil;
|
||||||
import io.bitsquare.locale.BSResources;
|
import io.bitsquare.locale.BSResources;
|
||||||
|
@ -80,14 +81,14 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||||
@FXML AddressTextField addressTextField;
|
@FXML AddressTextField addressTextField;
|
||||||
@FXML BalanceTextField balanceTextField;
|
@FXML BalanceTextField balanceTextField;
|
||||||
@FXML ProgressIndicator placeOfferSpinner;
|
@FXML ProgressIndicator placeOfferSpinner;
|
||||||
@FXML InfoDisplay advancedInfoDisplay, fundsBoxInfoDisplay;
|
@FXML InfoDisplay amountPriceBoxInfo, advancedInfoDisplay, fundsBoxInfoDisplay;
|
||||||
@FXML TitledGroupBg priceAmountPane, payFundsPane, showDetailsPane;
|
@FXML TitledGroupBg priceAmountPane, payFundsPane, showDetailsPane;
|
||||||
@FXML Button showPaymentInfoScreenButton, showAdvancedSettingsButton, placeOfferButton;
|
@FXML Button showPaymentInfoScreenButton, showAdvancedSettingsButton, placeOfferButton;
|
||||||
@FXML InputTextField amountTextField, minAmountTextField, priceTextField, volumeTextField;
|
@FXML InputTextField amountTextField, minAmountTextField, priceTextField, volumeTextField;
|
||||||
@FXML TextField acceptedArbitratorsTextField, totalToPayTextField, bankAccountTypeTextField,
|
@FXML TextField acceptedArbitratorsTextField, totalToPayTextField, bankAccountTypeTextField,
|
||||||
bankAccountCurrencyTextField, bankAccountCountyTextField, acceptedCountriesTextField,
|
bankAccountCurrencyTextField, bankAccountCountyTextField, acceptedCountriesTextField,
|
||||||
acceptedLanguagesTextField;
|
acceptedLanguagesTextField;
|
||||||
@FXML Label buyLabel, addressLabel, balanceLabel, totalToPayLabel, totalToPayInfoIconLabel, bankAccountTypeLabel,
|
@FXML Label buyLabel, amountToTradeLabel, addressLabel, balanceLabel, totalToPayLabel, totalToPayInfoIconLabel, bankAccountTypeLabel,
|
||||||
bankAccountCurrencyLabel, bankAccountCountyLabel, acceptedCountriesLabel, acceptedCountriesLabelIcon,
|
bankAccountCurrencyLabel, bankAccountCountyLabel, acceptedCountriesLabel, acceptedCountriesLabelIcon,
|
||||||
acceptedLanguagesLabel, acceptedLanguagesLabelIcon, acceptedArbitratorsLabel,
|
acceptedLanguagesLabel, acceptedLanguagesLabelIcon, acceptedArbitratorsLabel,
|
||||||
acceptedArbitratorsLabelIcon, amountBtcLabel, priceFiatLabel, volumeFiatLabel, minAmountBtcLabel,
|
acceptedArbitratorsLabelIcon, amountBtcLabel, priceFiatLabel, volumeFiatLabel, minAmountBtcLabel,
|
||||||
|
@ -116,8 +117,8 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||||
protected void initialize() {
|
protected void initialize() {
|
||||||
setupListeners();
|
setupListeners();
|
||||||
setupBindings();
|
setupBindings();
|
||||||
balanceTextField.setup(model.getWalletService(), model.address.get(),
|
|
||||||
model.getFormatter());
|
balanceTextField.setup(model.getWalletService(), model.address.get(), model.getFormatter());
|
||||||
volumeTextField.setPromptText(BSResources.get("createOffer.volume.prompt", model.fiatCode.get()));
|
volumeTextField.setPromptText(BSResources.get("createOffer.volume.prompt", model.fiatCode.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,9 +293,9 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||||
|
|
||||||
model.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> {
|
model.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> {
|
||||||
// TODO temp just for testing
|
// TODO temp just for testing
|
||||||
// newValue = false;
|
newValue = false;
|
||||||
// close();
|
close();
|
||||||
//navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class, OffersView.class);
|
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class, OffersView.class);
|
||||||
|
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
overlayManager.blurContent();
|
overlayManager.blurContent();
|
||||||
|
@ -336,20 +337,17 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||||
minAmountBtcLabel.textProperty().bind(model.btcCode);
|
minAmountBtcLabel.textProperty().bind(model.btcCode);
|
||||||
|
|
||||||
priceDescriptionLabel.textProperty().bind(createStringBinding(() ->
|
priceDescriptionLabel.textProperty().bind(createStringBinding(() ->
|
||||||
BSResources.get("createOffer.amountPriceBox.priceDescription",
|
BSResources.get("createOffer.amountPriceBox.priceDescription", model.fiatCode.get()), model.fiatCode));
|
||||||
model.fiatCode.get()),
|
|
||||||
model.fiatCode));
|
volumeDescriptionLabel.textProperty().bind(createStringBinding(() -> model.volumeDescriptionLabel.get(), model.fiatCode, model.volumeDescriptionLabel));
|
||||||
volumeDescriptionLabel.textProperty().bind(createStringBinding(() ->
|
|
||||||
BSResources.get("createOffer.amountPriceBox.volumeDescription",
|
|
||||||
model.fiatCode.get()),
|
|
||||||
model.fiatCode));
|
|
||||||
|
|
||||||
buyLabel.textProperty().bind(model.directionLabel);
|
buyLabel.textProperty().bind(model.directionLabel);
|
||||||
|
amountToTradeLabel.textProperty().bind(model.amountToTradeLabel);
|
||||||
amountTextField.textProperty().bindBidirectional(model.amount);
|
amountTextField.textProperty().bindBidirectional(model.amount);
|
||||||
minAmountTextField.textProperty().bindBidirectional(model.minAmount);
|
minAmountTextField.textProperty().bindBidirectional(model.minAmount);
|
||||||
priceTextField.textProperty().bindBidirectional(model.price);
|
priceTextField.textProperty().bindBidirectional(model.price);
|
||||||
volumeTextField.textProperty().bindBidirectional(model.volume);
|
volumeTextField.textProperty().bindBidirectional(model.volume);
|
||||||
|
amountPriceBoxInfo.textProperty().bind(model.amountPriceBoxInfo);
|
||||||
|
|
||||||
totalToPayTextField.textProperty().bind(model.totalToPay);
|
totalToPayTextField.textProperty().bind(model.totalToPay);
|
||||||
|
|
||||||
|
@ -471,19 +469,25 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||||
infoGridPane.setVgap(5);
|
infoGridPane.setVgap(5);
|
||||||
infoGridPane.setPadding(new Insets(10, 10, 10, 10));
|
infoGridPane.setPadding(new Insets(10, 10, 10, 10));
|
||||||
|
|
||||||
addPayInfoEntry(infoGridPane, 0,
|
int i = 0;
|
||||||
|
if (model.isSeller()) {
|
||||||
|
addPayInfoEntry(infoGridPane, i++,
|
||||||
|
BSResources.get("createOffer.fundsBox.tradeAmount"),
|
||||||
|
model.tradeAmount.get());
|
||||||
|
}
|
||||||
|
addPayInfoEntry(infoGridPane, i++,
|
||||||
BSResources.get("createOffer.fundsBox.securityDeposit"),
|
BSResources.get("createOffer.fundsBox.securityDeposit"),
|
||||||
model.securityDeposit.get());
|
model.securityDeposit.get());
|
||||||
addPayInfoEntry(infoGridPane, 1, BSResources.get("createOffer.fundsBox.offerFee"),
|
addPayInfoEntry(infoGridPane, i++, BSResources.get("createOffer.fundsBox.offerFee"),
|
||||||
model.offerFee.get());
|
model.offerFee.get());
|
||||||
addPayInfoEntry(infoGridPane, 2, BSResources.get("createOffer.fundsBox.networkFee"),
|
addPayInfoEntry(infoGridPane, i++, BSResources.get("createOffer.fundsBox.networkFee"),
|
||||||
model.networkFee.get());
|
model.networkFee.get());
|
||||||
Separator separator = new Separator();
|
Separator separator = new Separator();
|
||||||
separator.setOrientation(Orientation.HORIZONTAL);
|
separator.setOrientation(Orientation.HORIZONTAL);
|
||||||
separator.setStyle("-fx-background: #666;");
|
separator.setStyle("-fx-background: #666;");
|
||||||
GridPane.setConstraints(separator, 1, 3);
|
GridPane.setConstraints(separator, 1, i++);
|
||||||
infoGridPane.getChildren().add(separator);
|
infoGridPane.getChildren().add(separator);
|
||||||
addPayInfoEntry(infoGridPane, 4, BSResources.get("createOffer.fundsBox.total"),
|
addPayInfoEntry(infoGridPane, i++, BSResources.get("createOffer.fundsBox.total"),
|
||||||
model.totalToPay.get());
|
model.totalToPay.get());
|
||||||
totalToPayInfoPopover = new PopOver(infoGridPane);
|
totalToPayInfoPopover = new PopOver(infoGridPane);
|
||||||
if (totalToPayInfoIconLabel.getScene() != null) {
|
if (totalToPayInfoIconLabel.getScene() != null) {
|
||||||
|
|
|
@ -50,13 +50,18 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||||
private final BSFormatter formatter;
|
private final BSFormatter formatter;
|
||||||
private final FiatValidator fiatValidator;
|
private final FiatValidator fiatValidator;
|
||||||
|
|
||||||
|
|
||||||
final StringProperty amount = new SimpleStringProperty();
|
final StringProperty amount = new SimpleStringProperty();
|
||||||
final StringProperty minAmount = new SimpleStringProperty();
|
final StringProperty minAmount = new SimpleStringProperty();
|
||||||
final StringProperty price = new SimpleStringProperty();
|
final StringProperty price = new SimpleStringProperty();
|
||||||
final StringProperty volume = new SimpleStringProperty();
|
final StringProperty volume = new SimpleStringProperty();
|
||||||
|
final StringProperty volumeDescriptionLabel = new SimpleStringProperty();
|
||||||
|
final StringProperty amountPriceBoxInfo = new SimpleStringProperty();
|
||||||
final StringProperty securityDeposit = new SimpleStringProperty();
|
final StringProperty securityDeposit = new SimpleStringProperty();
|
||||||
|
final StringProperty tradeAmount = new SimpleStringProperty();
|
||||||
final StringProperty totalToPay = new SimpleStringProperty();
|
final StringProperty totalToPay = new SimpleStringProperty();
|
||||||
final StringProperty directionLabel = new SimpleStringProperty();
|
final StringProperty directionLabel = new SimpleStringProperty();
|
||||||
|
final StringProperty amountToTradeLabel = new SimpleStringProperty();
|
||||||
final StringProperty offerFee = new SimpleStringProperty();
|
final StringProperty offerFee = new SimpleStringProperty();
|
||||||
final StringProperty networkFee = new SimpleStringProperty();
|
final StringProperty networkFee = new SimpleStringProperty();
|
||||||
final StringProperty bankAccountType = new SimpleStringProperty();
|
final StringProperty bankAccountType = new SimpleStringProperty();
|
||||||
|
@ -113,9 +118,21 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||||
|
|
||||||
// setOfferBookFilter is a one time call
|
// setOfferBookFilter is a one time call
|
||||||
void initWithData(Offer.Direction direction, Coin amount, Fiat price) {
|
void initWithData(Offer.Direction direction, Coin amount, Fiat price) {
|
||||||
dataModel.setDirection(direction);
|
dataModel.initWithData( direction, amount, price);
|
||||||
directionLabel.set(dataModel.getDirection() == Offer.Direction.BUY ? BSResources.get("shared.buy") : BSResources.get
|
|
||||||
("shared.sell"));
|
if (dataModel.getDirection() == Offer.Direction.BUY) {
|
||||||
|
directionLabel.set(BSResources.get("shared.buyBitcoin"));
|
||||||
|
amountToTradeLabel.set(BSResources.get("createOffer.amountPriceBox.amountDescription", BSResources.get("shared.buy")));
|
||||||
|
volumeDescriptionLabel.set(BSResources.get("createOffer.amountPriceBox.buy.volumeDescription", fiatCode.get()));
|
||||||
|
amountPriceBoxInfo.set(BSResources.get("createOffer.amountPriceBox.buy.info"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
directionLabel.set(BSResources.get("shared.sellBitcoin"));
|
||||||
|
amountToTradeLabel.set(BSResources.get("createOffer.amountPriceBox.amountDescription", BSResources.get("shared.sell")));
|
||||||
|
volumeDescriptionLabel.set(BSResources.get("createOffer.amountPriceBox.sell.volumeDescription", fiatCode.get()));
|
||||||
|
amountPriceBoxInfo.set(BSResources.get("createOffer.amountPriceBox.sell.info"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// apply only if valid
|
// apply only if valid
|
||||||
boolean amountValid = false;
|
boolean amountValid = false;
|
||||||
|
@ -327,6 +344,9 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||||
securityDeposit.bind(createStringBinding(() -> formatter.formatCoinWithCode(dataModel.securityDepositAsCoin.get()),
|
securityDeposit.bind(createStringBinding(() -> formatter.formatCoinWithCode(dataModel.securityDepositAsCoin.get()),
|
||||||
dataModel.securityDepositAsCoin));
|
dataModel.securityDepositAsCoin));
|
||||||
|
|
||||||
|
tradeAmount.bind(createStringBinding(() -> formatter.formatCoinWithCode(dataModel.amountAsCoin.get()),
|
||||||
|
dataModel.amountAsCoin));
|
||||||
|
|
||||||
totalToPayAsCoin.bind(dataModel.totalToPayAsCoin);
|
totalToPayAsCoin.bind(dataModel.totalToPayAsCoin);
|
||||||
|
|
||||||
offerFee.bind(createStringBinding(() -> formatter.formatCoinWithCode(dataModel.offerFeeAsCoin.get()),
|
offerFee.bind(createStringBinding(() -> formatter.formatCoinWithCode(dataModel.offerFeeAsCoin.get()),
|
||||||
|
@ -407,4 +427,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||||
return fiatValidator.validate(input);
|
return fiatValidator.validate(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isSeller() {
|
||||||
|
return dataModel.getDirection() == Offer.Direction.SELL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,9 +145,9 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
||||||
table.sort();
|
table.sort();
|
||||||
|
|
||||||
//TODO temp for testing
|
//TODO temp for testing
|
||||||
/* amountTextField.setText("1");
|
amountTextField.setText("1");
|
||||||
priceTextField.setText("300");
|
priceTextField.setText("300");
|
||||||
volumeTextField.setText("300");*/
|
volumeTextField.setText("300");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -227,8 +227,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
||||||
offerActionHandler.takeOffer(model.getAmountAsCoin(), model.getPriceAsCoin(), offer);
|
offerActionHandler.takeOffer(model.getAmountAsCoin(), model.getPriceAsCoin(), offer);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Popups.openInfoPopup("Not implemented yet",
|
offerActionHandler.takeOffer(model.getAmountAsCoin(), model.getPriceAsCoin(), offer);
|
||||||
"At the moment you can only take offers in the Sell BTC screen.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -98,6 +98,7 @@ class TakeOfferDataModel implements Activatable, DataModel {
|
||||||
|
|
||||||
void initWithData(Coin amount, Offer offer) {
|
void initWithData(Coin amount, Offer offer) {
|
||||||
this.offer = offer;
|
this.offer = offer;
|
||||||
|
securityDepositAsCoin.set(offer.getSecurityDeposit());
|
||||||
|
|
||||||
if (amount != null &&
|
if (amount != null &&
|
||||||
!amount.isGreaterThan(offer.getAmount()) &&
|
!amount.isGreaterThan(offer.getAmount()) &&
|
||||||
|
@ -108,7 +109,6 @@ class TakeOfferDataModel implements Activatable, DataModel {
|
||||||
amountAsCoin.set(offer.getAmount());
|
amountAsCoin.set(offer.getAmount());
|
||||||
}
|
}
|
||||||
|
|
||||||
securityDepositAsCoin.set(offer.getSecurityDeposit());
|
|
||||||
calculateVolume();
|
calculateVolume();
|
||||||
calculateTotalToPay();
|
calculateTotalToPay();
|
||||||
|
|
||||||
|
@ -143,17 +143,15 @@ class TakeOfferDataModel implements Activatable, DataModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculateTotalToPay() {
|
void calculateTotalToPay() {
|
||||||
try {
|
if (getDirection() == Offer.Direction.SELL)
|
||||||
if (securityDepositAsCoin.get() != null) {
|
totalToPayAsCoin.set(offerFeeAsCoin.get().add(networkFeeAsCoin.get()).add(securityDepositAsCoin.get()));
|
||||||
totalToPayAsCoin.set(offerFeeAsCoin.get().add(amountAsCoin.get()).add(networkFeeAsCoin.get()).add
|
else
|
||||||
(securityDepositAsCoin.get()));
|
totalToPayAsCoin.set(offerFeeAsCoin.get().add(networkFeeAsCoin.get()).add(securityDepositAsCoin.get()).add(amountAsCoin.get()));
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
|
||||||
// Should be never reached
|
|
||||||
log.error(t.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Offer.Direction getDirection() {
|
||||||
|
return offer.getDirection();
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||||
boolean isMinAmountLessOrEqualAmount() {
|
boolean isMinAmountLessOrEqualAmount() {
|
||||||
|
|
|
@ -67,8 +67,7 @@
|
||||||
<Insets right="10.0" top="20.0"/>
|
<Insets right="10.0" top="20.0"/>
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
<VBox spacing="4">
|
<VBox spacing="4">
|
||||||
<Label id="input-description-label" text="%takeOffer.amountPriceBox.amountDescription"
|
<Label fx:id="amountDescriptionLabel" id="input-description-label" prefWidth="170"/>
|
||||||
prefWidth="170"/>
|
|
||||||
<HBox>
|
<HBox>
|
||||||
<InputTextField fx:id="amountTextField" id="text-input-with-currency-text-field"
|
<InputTextField fx:id="amountTextField" id="text-input-with-currency-text-field"
|
||||||
promptText="%takeOffer.amount.prompt" prefWidth="170"
|
promptText="%takeOffer.amount.prompt" prefWidth="170"
|
||||||
|
@ -120,8 +119,7 @@
|
||||||
style=" -fx-alignment: center;"/>
|
style=" -fx-alignment: center;"/>
|
||||||
</VBox>
|
</VBox>
|
||||||
|
|
||||||
<InfoDisplay gridPane="$gridPane" onAction="#onOpenGeneralHelp" rowIndex="2"
|
<InfoDisplay fx:id="amountPriceBoxInfoDisplay" gridPane="$gridPane" onAction="#onOpenGeneralHelp" rowIndex="2"/>
|
||||||
text="%takeOffer.amountPriceBox.info"/>
|
|
||||||
|
|
||||||
<Label fx:id="isOfferAvailableLabel" text="%takeOffer.fundsBox.isOfferAvailable" GridPane.rowIndex="3">
|
<Label fx:id="isOfferAvailableLabel" text="%takeOffer.fundsBox.isOfferAvailable" GridPane.rowIndex="3">
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
|
@ -179,8 +177,7 @@
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
</BalanceTextField>
|
</BalanceTextField>
|
||||||
|
|
||||||
<InfoDisplay fx:id="fundsBoxInfoDisplay" gridPane="$gridPane" onAction="#onOpenFundingHelp" rowIndex="7"
|
<InfoDisplay fx:id="fundsBoxInfoDisplay" gridPane="$gridPane" onAction="#onOpenFundingHelp" rowIndex="7" visible="false"/>
|
||||||
text="%takeOffer.fundsBox.info" visible="false"/>
|
|
||||||
|
|
||||||
<HBox spacing="10" GridPane.columnIndex="1" GridPane.rowIndex="8">
|
<HBox spacing="10" GridPane.columnIndex="1" GridPane.rowIndex="8">
|
||||||
<Button fx:id="showAdvancedSettingsButton" text="%takeOffer.fundsBox.showAdvanced"
|
<Button fx:id="showAdvancedSettingsButton" text="%takeOffer.fundsBox.showAdvanced"
|
||||||
|
|
|
@ -67,6 +67,8 @@ import org.controlsfx.control.action.AbstractAction;
|
||||||
import org.controlsfx.control.action.Action;
|
import org.controlsfx.control.action.Action;
|
||||||
import org.controlsfx.dialog.Dialog;
|
import org.controlsfx.dialog.Dialog;
|
||||||
|
|
||||||
|
import static javafx.beans.binding.Bindings.createStringBinding;
|
||||||
|
|
||||||
@FxmlView
|
@FxmlView
|
||||||
public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOfferViewModel> {
|
public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOfferViewModel> {
|
||||||
|
|
||||||
|
@ -76,13 +78,13 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||||
@FXML AddressTextField addressTextField;
|
@FXML AddressTextField addressTextField;
|
||||||
@FXML BalanceTextField balanceTextField;
|
@FXML BalanceTextField balanceTextField;
|
||||||
@FXML ProgressIndicator takeOfferSpinner, isOfferAvailableProgressIndicator;
|
@FXML ProgressIndicator takeOfferSpinner, isOfferAvailableProgressIndicator;
|
||||||
@FXML InfoDisplay advancedInfoDisplay, fundsBoxInfoDisplay;
|
@FXML InfoDisplay amountPriceBoxInfoDisplay, advancedInfoDisplay, fundsBoxInfoDisplay;
|
||||||
@FXML TitledGroupBg priceAmountPane, payFundsPane, showDetailsPane;
|
@FXML TitledGroupBg priceAmountPane, payFundsPane, showDetailsPane;
|
||||||
@FXML Button showPaymentInfoScreenButton, showAdvancedSettingsButton, takeOfferButton;
|
@FXML Button showPaymentInfoScreenButton, showAdvancedSettingsButton, takeOfferButton;
|
||||||
@FXML TextField priceTextField, volumeTextField, acceptedArbitratorsTextField, totalToPayTextField,
|
@FXML TextField priceTextField, volumeTextField, acceptedArbitratorsTextField, totalToPayTextField,
|
||||||
bankAccountTypeTextField, bankAccountCurrencyTextField, bankAccountCountyTextField,
|
bankAccountTypeTextField, bankAccountCurrencyTextField, bankAccountCountyTextField,
|
||||||
acceptedCountriesTextField, acceptedLanguagesTextField;
|
acceptedCountriesTextField, acceptedLanguagesTextField;
|
||||||
@FXML Label isOfferAvailableLabel, buyLabel, addressLabel, amountRangeTextField, balanceLabel, totalToPayLabel,
|
@FXML Label isOfferAvailableLabel, buyLabel, addressLabel, amountDescriptionLabel, amountRangeTextField, balanceLabel, totalToPayLabel,
|
||||||
totalToPayInfoIconLabel,
|
totalToPayInfoIconLabel,
|
||||||
bankAccountTypeLabel, bankAccountCurrencyLabel, bankAccountCountyLabel, acceptedCountriesLabel,
|
bankAccountTypeLabel, bankAccountCurrencyLabel, bankAccountCountyLabel, acceptedCountriesLabel,
|
||||||
acceptedLanguagesLabel, acceptedArbitratorsLabel, amountBtcLabel, priceDescriptionLabel,
|
acceptedLanguagesLabel, acceptedArbitratorsLabel, amountBtcLabel, priceDescriptionLabel,
|
||||||
|
@ -118,16 +120,17 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||||
model.errorMessage.removeListener(errorMessageChangeListener);
|
model.errorMessage.removeListener(errorMessageChangeListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initWithData(Offer.Direction direction, Coin amount, Offer offer) {
|
public void initWithData(Coin amount, Offer offer) {
|
||||||
model.initWithData(direction, amount, offer);
|
model.initWithData(amount, offer);
|
||||||
|
|
||||||
if (direction == Offer.Direction.BUY)
|
if (offer.getDirection() == Offer.Direction.SELL)
|
||||||
imageView.setId("image-buy-large");
|
imageView.setId("image-buy-large");
|
||||||
else
|
else
|
||||||
imageView.setId("image-sell-large");
|
imageView.setId("image-sell-large");
|
||||||
|
|
||||||
priceDescriptionLabel.setText(BSResources.get("takeOffer.amountPriceBox.priceDescription", model.getFiatCode()));
|
priceDescriptionLabel.setText(BSResources.get("takeOffer.amountPriceBox.priceDescription", model.getFiatCode()));
|
||||||
volumeDescriptionLabel.setText(BSResources.get("takeOffer.amountPriceBox.volumeDescription", model.getFiatCode()));
|
volumeDescriptionLabel.setText(BSResources.get("takeOffer.amountPriceBox.volumeDescription", model.getFiatCode()));
|
||||||
|
volumeDescriptionLabel.textProperty().bind(createStringBinding(() -> model.volumeDescriptionLabel.get(), model.fiatCode, model.volumeDescriptionLabel));
|
||||||
|
|
||||||
balanceTextField.setup(model.getWalletService(), model.address.get(), model.getFormatter());
|
balanceTextField.setup(model.getWalletService(), model.address.get(), model.getFormatter());
|
||||||
|
|
||||||
|
@ -144,6 +147,8 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||||
acceptedLanguagesTextField.setText(model.getAcceptedLanguages());
|
acceptedLanguagesTextField.setText(model.getAcceptedLanguages());
|
||||||
acceptedArbitratorsTextField.setText(model.getAcceptedArbitratorIds());
|
acceptedArbitratorsTextField.setText(model.getAcceptedArbitratorIds());
|
||||||
|
|
||||||
|
amountPriceBoxInfoDisplay.textProperty().bind(model.amountPriceBoxInfo);
|
||||||
|
fundsBoxInfoDisplay.textProperty().bind(model.fundsBoxInfoDisplay);
|
||||||
showCheckAvailabilityScreen();
|
showCheckAvailabilityScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,9 +248,9 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||||
|
|
||||||
model.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> {
|
model.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> {
|
||||||
// TODO temp just for testing
|
// TODO temp just for testing
|
||||||
/* newValue = false;
|
newValue = false;
|
||||||
close();*/
|
close();
|
||||||
//navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
|
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
|
||||||
|
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
overlayManager.blurContent();
|
overlayManager.blurContent();
|
||||||
|
@ -287,6 +292,8 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||||
volumeTextField.textProperty().bindBidirectional(model.volume);
|
volumeTextField.textProperty().bindBidirectional(model.volume);
|
||||||
totalToPayTextField.textProperty().bind(model.totalToPay);
|
totalToPayTextField.textProperty().bind(model.totalToPay);
|
||||||
addressTextField.amountAsCoinProperty().bind(model.totalToPayAsCoin);
|
addressTextField.amountAsCoinProperty().bind(model.totalToPayAsCoin);
|
||||||
|
amountDescriptionLabel.textProperty().bind(model.amountDescription);
|
||||||
|
|
||||||
|
|
||||||
// Validation
|
// Validation
|
||||||
amountTextField.validationResultProperty().bind(model.amountValidationResult);
|
amountTextField.validationResultProperty().bind(model.amountValidationResult);
|
||||||
|
@ -429,22 +436,27 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||||
infoGridPane.setVgap(5);
|
infoGridPane.setVgap(5);
|
||||||
infoGridPane.setPadding(new Insets(10, 10, 10, 10));
|
infoGridPane.setPadding(new Insets(10, 10, 10, 10));
|
||||||
|
|
||||||
addPayInfoEntry(infoGridPane, 0,
|
int i = 0;
|
||||||
|
if (model.isSeller()) {
|
||||||
|
addPayInfoEntry(infoGridPane, i++,
|
||||||
BSResources.get("takeOffer.fundsBox.amount"),
|
BSResources.get("takeOffer.fundsBox.amount"),
|
||||||
model.getAmount());
|
model.getAmount());
|
||||||
addPayInfoEntry(infoGridPane, 1,
|
}
|
||||||
|
|
||||||
|
|
||||||
|
addPayInfoEntry(infoGridPane, i++,
|
||||||
BSResources.get("takeOffer.fundsBox.securityDeposit"),
|
BSResources.get("takeOffer.fundsBox.securityDeposit"),
|
||||||
model.securityDeposit.get());
|
model.securityDeposit.get());
|
||||||
addPayInfoEntry(infoGridPane, 2, BSResources.get("takeOffer.fundsBox.offerFee"),
|
addPayInfoEntry(infoGridPane, i++, BSResources.get("takeOffer.fundsBox.offerFee"),
|
||||||
model.getOfferFee());
|
model.getOfferFee());
|
||||||
addPayInfoEntry(infoGridPane, 3, BSResources.get("takeOffer.fundsBox.networkFee"),
|
addPayInfoEntry(infoGridPane, i++, BSResources.get("takeOffer.fundsBox.networkFee"),
|
||||||
model.getNetworkFee());
|
model.getNetworkFee());
|
||||||
Separator separator = new Separator();
|
Separator separator = new Separator();
|
||||||
separator.setOrientation(Orientation.HORIZONTAL);
|
separator.setOrientation(Orientation.HORIZONTAL);
|
||||||
separator.setStyle("-fx-background: #666;");
|
separator.setStyle("-fx-background: #666;");
|
||||||
GridPane.setConstraints(separator, 1, 4);
|
GridPane.setConstraints(separator, 1, i++);
|
||||||
infoGridPane.getChildren().add(separator);
|
infoGridPane.getChildren().add(separator);
|
||||||
addPayInfoEntry(infoGridPane, 5, BSResources.get("takeOffer.fundsBox.total"),
|
addPayInfoEntry(infoGridPane, i++, BSResources.get("takeOffer.fundsBox.total"),
|
||||||
model.totalToPay.get());
|
model.totalToPay.get());
|
||||||
totalToPayInfoPopover = new PopOver(infoGridPane);
|
totalToPayInfoPopover = new PopOver(infoGridPane);
|
||||||
if (totalToPayInfoIconLabel.getScene() != null) {
|
if (totalToPayInfoIconLabel.getScene() != null) {
|
||||||
|
|
|
@ -26,6 +26,8 @@ import io.bitsquare.gui.util.validation.InputValidator;
|
||||||
import io.bitsquare.locale.BSResources;
|
import io.bitsquare.locale.BSResources;
|
||||||
import io.bitsquare.locale.CurrencyUtil;
|
import io.bitsquare.locale.CurrencyUtil;
|
||||||
import io.bitsquare.offer.Offer;
|
import io.bitsquare.offer.Offer;
|
||||||
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
|
|
||||||
import org.bitcoinj.core.Address;
|
import org.bitcoinj.core.Address;
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
@ -54,7 +56,6 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||||
DETAILS_SCREEN
|
DETAILS_SCREEN
|
||||||
}
|
}
|
||||||
|
|
||||||
private String fiatCode;
|
|
||||||
private String amountRange;
|
private String amountRange;
|
||||||
private String price;
|
private String price;
|
||||||
private String directionLabel;
|
private String directionLabel;
|
||||||
|
@ -85,7 +86,11 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||||
final StringProperty transactionId = new SimpleStringProperty();
|
final StringProperty transactionId = new SimpleStringProperty();
|
||||||
final StringProperty errorMessage = new SimpleStringProperty();
|
final StringProperty errorMessage = new SimpleStringProperty();
|
||||||
final StringProperty btcCode = new SimpleStringProperty();
|
final StringProperty btcCode = new SimpleStringProperty();
|
||||||
|
final StringProperty amountDescription = new SimpleStringProperty();
|
||||||
|
final StringProperty volumeDescriptionLabel = new SimpleStringProperty();
|
||||||
|
final StringProperty fiatCode = new SimpleStringProperty();
|
||||||
|
final StringProperty amountPriceBoxInfo = new SimpleStringProperty();
|
||||||
|
final StringProperty fundsBoxInfoDisplay = new SimpleStringProperty();
|
||||||
|
|
||||||
final BooleanProperty takeOfferButtonDisabled = new SimpleBooleanProperty(false);
|
final BooleanProperty takeOfferButtonDisabled = new SimpleBooleanProperty(false);
|
||||||
final BooleanProperty isTakeOfferSpinnerVisible = new SimpleBooleanProperty(false);
|
final BooleanProperty isTakeOfferSpinnerVisible = new SimpleBooleanProperty(false);
|
||||||
|
@ -115,18 +120,31 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||||
}
|
}
|
||||||
|
|
||||||
// setOfferBookFilter is a one time call
|
// setOfferBookFilter is a one time call
|
||||||
void initWithData(Offer.Direction direction, Coin amount, Offer offer) {
|
void initWithData(Coin amount, Offer offer) {
|
||||||
dataModel.initWithData(amount, offer);
|
dataModel.initWithData(amount, offer);
|
||||||
|
|
||||||
directionLabel = direction == Offer.Direction.BUY ?
|
directionLabel = offer.getDirection() == Offer.Direction.SELL ?
|
||||||
BSResources.get("shared.buy") : BSResources.get("shared.sell");
|
BSResources.get("shared.buyBitcoin") : BSResources.get("shared.sellBitcoin");
|
||||||
|
|
||||||
fiatCode = offer.getCurrencyCode();
|
fiatCode.set(offer.getCurrencyCode());
|
||||||
if (!dataModel.isMinAmountLessOrEqualAmount()) {
|
if (!dataModel.isMinAmountLessOrEqualAmount()) {
|
||||||
amountValidationResult.set(new InputValidator.ValidationResult(false,
|
amountValidationResult.set(new InputValidator.ValidationResult(false,
|
||||||
BSResources.get("takeOffer.validation.amountSmallerThanMinAmount")));
|
BSResources.get("takeOffer.validation.amountSmallerThanMinAmount")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dataModel.getDirection() == Offer.Direction.BUY) {
|
||||||
|
amountDescription.set(BSResources.get("takeOffer.amountPriceBox.buy.amountDescription", offer.getId()));
|
||||||
|
volumeDescriptionLabel.set(BSResources.get("takeOffer.amountPriceBox.buy.volumeDescription", fiatCode.get()));
|
||||||
|
amountPriceBoxInfo.set(BSResources.get("takeOffer.amountPriceBox.buy.info"));
|
||||||
|
fundsBoxInfoDisplay.set(BSResources.get("takeOffer.fundsBox.buy.info"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
amountDescription.set(BSResources.get("takeOffer.amountPriceBox.sell.amountDescription", offer.getId()));
|
||||||
|
volumeDescriptionLabel.set(BSResources.get("takeOffer.amountPriceBox.sell.volumeDescription", fiatCode.get()));
|
||||||
|
amountPriceBoxInfo.set(BSResources.get("takeOffer.amountPriceBox.sell.info"));
|
||||||
|
fundsBoxInfoDisplay.set(BSResources.get("takeOffer.fundsBox.sell.info"));
|
||||||
|
}
|
||||||
|
|
||||||
//model.volumeAsFiat.set(offer.getVolumeByAmount(model.amountAsCoin.get()));
|
//model.volumeAsFiat.set(offer.getVolumeByAmount(model.amountAsCoin.get()));
|
||||||
|
|
||||||
amountRange = formatter.formatCoinWithCode(offer.getMinAmount()) + " - " +
|
amountRange = formatter.formatCoinWithCode(offer.getMinAmount()) + " - " +
|
||||||
|
@ -210,11 +228,13 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||||
dataModel.takeOffer((takerTrade) -> {
|
dataModel.takeOffer((takerTrade) -> {
|
||||||
takerTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
|
takerTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
|
||||||
log.debug("takerTrade state = " + newValue);
|
log.debug("takerTrade state = " + newValue);
|
||||||
|
|
||||||
String msg = "";
|
String msg = "";
|
||||||
if (takerTrade.getErrorMessage() != null)
|
if (takerTrade.getErrorMessage() != null)
|
||||||
msg = "\nError message: " + takerTrade.getErrorMessage();
|
msg = "\nError message: " + takerTrade.getErrorMessage();
|
||||||
|
|
||||||
switch (newValue) {
|
if (takerTrade instanceof TakerAsBuyerTrade) {
|
||||||
|
switch ((TakerAsBuyerTrade.ProcessState) newValue) {
|
||||||
case TAKE_OFFER_FEE_TX_CREATED:
|
case TAKE_OFFER_FEE_TX_CREATED:
|
||||||
break;
|
break;
|
||||||
case DEPOSIT_PUBLISHED:
|
case DEPOSIT_PUBLISHED:
|
||||||
|
@ -244,6 +264,39 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||||
log.warn("Unhandled takerTrade state: " + newValue);
|
log.warn("Unhandled takerTrade state: " + newValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade) {
|
||||||
|
switch ((TakerAsSellerTrade.ProcessState) newValue) {
|
||||||
|
case TAKE_OFFER_FEE_TX_CREATED:
|
||||||
|
break;
|
||||||
|
case DEPOSIT_PUBLISHED:
|
||||||
|
case DEPOSIT_CONFIRMED:
|
||||||
|
assert takerTrade.getDepositTx() != null;
|
||||||
|
transactionId.set(takerTrade.getDepositTx().getHashAsString());
|
||||||
|
applyTakeOfferRequestResult(true);
|
||||||
|
break;
|
||||||
|
case FIAT_PAYMENT_STARTED:
|
||||||
|
break;
|
||||||
|
case TAKE_OFFER_FEE_PUBLISH_FAILED:
|
||||||
|
errorMessage.set("An error occurred when paying the takerTrade fee." + msg);
|
||||||
|
takeOfferRequested = false;
|
||||||
|
break;
|
||||||
|
case MESSAGE_SENDING_FAILED:
|
||||||
|
errorMessage.set("An error occurred when sending a message to the offerer. Maybe there are connection problems. " +
|
||||||
|
"Please try later again." + msg);
|
||||||
|
takeOfferRequested = false;
|
||||||
|
break;
|
||||||
|
case PAYOUT_PUBLISHED:
|
||||||
|
break;
|
||||||
|
case EXCEPTION:
|
||||||
|
errorMessage.set(msg);
|
||||||
|
takeOfferRequested = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.warn("Unhandled takerTrade state: " + newValue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (errorMessage.get() != null) {
|
if (errorMessage.get() != null) {
|
||||||
isAmountAndPriceValidAndWalletFunded = false;
|
isAmountAndPriceValidAndWalletFunded = false;
|
||||||
|
@ -255,6 +308,10 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isSeller() {
|
||||||
|
return dataModel.getDirection() == Offer.Direction.BUY;
|
||||||
|
}
|
||||||
|
|
||||||
void securityDepositInfoDisplayed() {
|
void securityDepositInfoDisplayed() {
|
||||||
dataModel.securityDepositInfoDisplayed();
|
dataModel.securityDepositInfoDisplayed();
|
||||||
}
|
}
|
||||||
|
@ -307,7 +364,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||||
}
|
}
|
||||||
|
|
||||||
String getFiatCode() {
|
String getFiatCode() {
|
||||||
return fiatCode;
|
return fiatCode.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
String getAmount() {
|
String getAmount() {
|
||||||
|
|
|
@ -24,6 +24,6 @@ public class Colors {
|
||||||
public static final Paint LIGHT_GREY = Color.valueOf("#CCCCCC");
|
public static final Paint LIGHT_GREY = Color.valueOf("#CCCCCC");
|
||||||
public static final Paint MID_GREY = Color.valueOf("#666666");
|
public static final Paint MID_GREY = Color.valueOf("#666666");
|
||||||
public static final Paint DARK_GREY = Color.valueOf("#333333");
|
public static final Paint DARK_GREY = Color.valueOf("#333333");
|
||||||
public static final Paint GREEN = Color.valueOf("#00AA00");
|
public static final Paint GREEN = Color.valueOf("#00aa33");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
227
core/src/main/java/io/bitsquare/gui/util/ComponentBuilder.java
Normal file
227
core/src/main/java/io/bitsquare/gui/util/ComponentBuilder.java
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.util;
|
||||||
|
|
||||||
|
import io.bitsquare.gui.components.InfoDisplay;
|
||||||
|
import io.bitsquare.gui.components.InputTextField;
|
||||||
|
import io.bitsquare.gui.components.TextFieldWithCopyIcon;
|
||||||
|
import io.bitsquare.gui.components.TitledGroupBg;
|
||||||
|
import io.bitsquare.gui.components.TxIdTextField;
|
||||||
|
|
||||||
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.event.EventHandler;
|
||||||
|
import javafx.geometry.HPos;
|
||||||
|
import javafx.geometry.Insets;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.layout.*;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class ComponentBuilder {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ComponentBuilder.class);
|
||||||
|
|
||||||
|
public static GridPane getAndAddGridPane(Pane parent) {
|
||||||
|
GridPane gridPane = new GridPane();
|
||||||
|
AnchorPane.setLeftAnchor(gridPane, 10d);
|
||||||
|
AnchorPane.setRightAnchor(gridPane, 10d);
|
||||||
|
AnchorPane.setTopAnchor(gridPane, 10d);
|
||||||
|
AnchorPane.setBottomAnchor(gridPane, 10d);
|
||||||
|
gridPane.setHgap(Layout.GRID_GAP);
|
||||||
|
gridPane.setVgap(Layout.GRID_GAP);
|
||||||
|
ColumnConstraints columnConstraints1 = new ColumnConstraints();
|
||||||
|
columnConstraints1.setHalignment(HPos.RIGHT);
|
||||||
|
columnConstraints1.setHgrow(Priority.SOMETIMES);
|
||||||
|
|
||||||
|
ColumnConstraints columnConstraints2 = new ColumnConstraints();
|
||||||
|
columnConstraints2.setHgrow(Priority.ALWAYS);
|
||||||
|
|
||||||
|
gridPane.getColumnConstraints().addAll(columnConstraints1, columnConstraints2);
|
||||||
|
|
||||||
|
parent.getChildren().add(gridPane);
|
||||||
|
return gridPane;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TitledGroupBg getAndAddTitledGroupBg(GridPane gridPane, int rowIndex, int rowSpan, String title) {
|
||||||
|
return getAndAddTitledGroupBg(gridPane, rowIndex, rowSpan, title, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TitledGroupBg getAndAddTitledGroupBg(GridPane gridPane, int rowIndex, int rowSpan, String title, double top) {
|
||||||
|
TitledGroupBg titledGroupBg = new TitledGroupBg();
|
||||||
|
titledGroupBg.setText(title);
|
||||||
|
titledGroupBg.prefWidthProperty().bind(gridPane.widthProperty());
|
||||||
|
GridPane.setRowIndex(titledGroupBg, rowIndex);
|
||||||
|
GridPane.setRowSpan(titledGroupBg, rowSpan);
|
||||||
|
GridPane.setColumnSpan(titledGroupBg, 2);
|
||||||
|
GridPane.setMargin(titledGroupBg, new Insets(top, -10, -10, -10));
|
||||||
|
gridPane.getChildren().add(titledGroupBg);
|
||||||
|
return titledGroupBg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Label getAndAddLabel(GridPane gridPane, int rowIndex, String title, double top) {
|
||||||
|
Label label = new Label(title);
|
||||||
|
GridPane.setRowIndex(label, rowIndex);
|
||||||
|
GridPane.setMargin(label, new Insets(top, 0, 0, 0));
|
||||||
|
gridPane.getChildren().add(label);
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LabelTextFieldPair getAndAddLabelTextFieldPair(GridPane gridPane, int rowIndex, String title) {
|
||||||
|
return getAndAddLabelTextFieldPair(gridPane, rowIndex, title, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LabelTextFieldPair getAndAddLabelTextFieldPair(GridPane gridPane, int rowIndex, String title, double top) {
|
||||||
|
Label label = getAndAddLabel(gridPane, rowIndex, title, top);
|
||||||
|
|
||||||
|
TextField textField = new TextField();
|
||||||
|
textField.setEditable(false);
|
||||||
|
textField.setMouseTransparent(true);
|
||||||
|
textField.setFocusTraversable(false);
|
||||||
|
GridPane.setRowIndex(textField, rowIndex);
|
||||||
|
GridPane.setColumnIndex(textField, 1);
|
||||||
|
GridPane.setMargin(textField, new Insets(top, 0, 0, 0));
|
||||||
|
gridPane.getChildren().add(textField);
|
||||||
|
|
||||||
|
return new LabelTextFieldPair(label, textField);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LabelInputTextFieldPair getAndAddLabelInputTextFieldPair(GridPane gridPane, int rowIndex, String title) {
|
||||||
|
return getAndAddLabelInputTextFieldPair(gridPane, rowIndex, title, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LabelInputTextFieldPair getAndAddLabelInputTextFieldPair(GridPane gridPane, int rowIndex, String title, double top) {
|
||||||
|
Label label = getAndAddLabel(gridPane, rowIndex, title, top);
|
||||||
|
|
||||||
|
InputTextField inputTextField = new InputTextField();
|
||||||
|
GridPane.setRowIndex(inputTextField, rowIndex);
|
||||||
|
GridPane.setColumnIndex(inputTextField, 1);
|
||||||
|
GridPane.setMargin(inputTextField, new Insets(top, 0, 0, 0));
|
||||||
|
gridPane.getChildren().add(inputTextField);
|
||||||
|
|
||||||
|
return new LabelInputTextFieldPair(label, inputTextField);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LabelTxIdTextFieldPair getAndAddLabelTxIdTextFieldPair(GridPane gridPane, int rowIndex, String title) {
|
||||||
|
return getAndAddLabelTxIdTextFieldPair(gridPane, rowIndex, title, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LabelTxIdTextFieldPair getAndAddLabelTxIdTextFieldPair(GridPane gridPane, int rowIndex, String title, double top) {
|
||||||
|
Label label = getAndAddLabel(gridPane, rowIndex, title, top);
|
||||||
|
|
||||||
|
TxIdTextField txIdTextField = new TxIdTextField();
|
||||||
|
GridPane.setRowIndex(txIdTextField, rowIndex);
|
||||||
|
GridPane.setColumnIndex(txIdTextField, 1);
|
||||||
|
GridPane.setMargin(txIdTextField, new Insets(top, 0, 0, 0));
|
||||||
|
gridPane.getChildren().add(txIdTextField);
|
||||||
|
|
||||||
|
return new LabelTxIdTextFieldPair(label, txIdTextField);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LabelTextFieldWithCopyIconPair getAndAddLabelTextFieldWithCopyIconPair(GridPane gridPane, int rowIndex, String title) {
|
||||||
|
return getAndAddLabelTextFieldWithCopyIconPair(gridPane, rowIndex, title, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LabelTextFieldWithCopyIconPair getAndAddLabelTextFieldWithCopyIconPair(GridPane gridPane, int rowIndex, String title, double top) {
|
||||||
|
Label label = getAndAddLabel(gridPane, rowIndex, title, top);
|
||||||
|
|
||||||
|
TextFieldWithCopyIcon textFieldWithCopyIcon = new TextFieldWithCopyIcon();
|
||||||
|
GridPane.setRowIndex(textFieldWithCopyIcon, rowIndex);
|
||||||
|
GridPane.setColumnIndex(textFieldWithCopyIcon, 1);
|
||||||
|
GridPane.setMargin(textFieldWithCopyIcon, new Insets(top, 0, 0, 0));
|
||||||
|
gridPane.getChildren().add(textFieldWithCopyIcon);
|
||||||
|
|
||||||
|
return new LabelTextFieldWithCopyIconPair(label, textFieldWithCopyIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InfoDisplay getAndAddInfoDisplay(GridPane gridPane,
|
||||||
|
int rowIndex,
|
||||||
|
String text,
|
||||||
|
EventHandler<ActionEvent> onActionHandler) {
|
||||||
|
return getAndAddInfoDisplay(gridPane, rowIndex, text, onActionHandler, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InfoDisplay getAndAddInfoDisplay(GridPane gridPane,
|
||||||
|
int rowIndex,
|
||||||
|
String text,
|
||||||
|
EventHandler<ActionEvent> onActionHandler,
|
||||||
|
double top) {
|
||||||
|
InfoDisplay infoDisplay = new InfoDisplay();
|
||||||
|
infoDisplay.setText(text);
|
||||||
|
infoDisplay.setOnAction(onActionHandler);
|
||||||
|
GridPane.setRowIndex(infoDisplay, rowIndex);
|
||||||
|
GridPane.setMargin(infoDisplay, new Insets(top, 0, 0, 0));
|
||||||
|
gridPane.getChildren().add(infoDisplay);
|
||||||
|
|
||||||
|
return infoDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Button getAndAddButton(GridPane gridPane,
|
||||||
|
int rowIndex,
|
||||||
|
String title,
|
||||||
|
EventHandler<ActionEvent> onActionHandler) {
|
||||||
|
Button button = new Button(title);
|
||||||
|
button.setDefaultButton(true);
|
||||||
|
button.setOnAction(onActionHandler);
|
||||||
|
GridPane.setRowIndex(button, rowIndex);
|
||||||
|
GridPane.setColumnIndex(button, 1);
|
||||||
|
GridPane.setMargin(button, new Insets(15, 0, 40, 0));
|
||||||
|
gridPane.getChildren().add(button);
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LabelTextFieldPair {
|
||||||
|
public Label label;
|
||||||
|
public TextField textField;
|
||||||
|
|
||||||
|
public LabelTextFieldPair(Label label, TextField textField) {
|
||||||
|
this.label = label;
|
||||||
|
this.textField = textField;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LabelInputTextFieldPair {
|
||||||
|
public Label label;
|
||||||
|
public InputTextField inputTextField;
|
||||||
|
|
||||||
|
public LabelInputTextFieldPair(Label label, InputTextField inputTextField) {
|
||||||
|
this.label = label;
|
||||||
|
this.inputTextField = inputTextField;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LabelTxIdTextFieldPair {
|
||||||
|
public Label label;
|
||||||
|
public TxIdTextField txIdTextField;
|
||||||
|
|
||||||
|
public LabelTxIdTextFieldPair(Label label, TxIdTextField txIdTextField) {
|
||||||
|
this.label = label;
|
||||||
|
this.txIdTextField = txIdTextField;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LabelTextFieldWithCopyIconPair {
|
||||||
|
public Label label;
|
||||||
|
public TextFieldWithCopyIcon textFieldWithCopyIcon;
|
||||||
|
|
||||||
|
public LabelTextFieldWithCopyIconPair(Label label, TextFieldWithCopyIcon textFieldWithCopyIcon) {
|
||||||
|
this.label = label;
|
||||||
|
this.textFieldWithCopyIcon = textFieldWithCopyIcon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
30
core/src/main/java/io/bitsquare/gui/util/Layout.java
Normal file
30
core/src/main/java/io/bitsquare/gui/util/Layout.java
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.gui.util;
|
||||||
|
|
||||||
|
public class Layout {
|
||||||
|
public static final double FIRST_ROW_DISTANCE = 20d;
|
||||||
|
public static final double GROUP_DISTANCE = 40d;
|
||||||
|
public static final double FIRST_ROW_AND_GROUP_DISTANCE = GROUP_DISTANCE+FIRST_ROW_DISTANCE;
|
||||||
|
public static double PADDING_WINDOW = 20d;
|
||||||
|
public static double PADDING = 10d;
|
||||||
|
public static double SPACING_HBOX = 10d;
|
||||||
|
public static double SPACING_VBOX = 5d;
|
||||||
|
public static double GRID_GAP = 5d;
|
||||||
|
|
||||||
|
}
|
151
core/src/main/java/io/bitsquare/trade/OffererAsBuyerTrade.java
Normal file
151
core/src/main/java/io/bitsquare/trade/OffererAsBuyerTrade.java
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade;
|
||||||
|
|
||||||
|
import io.bitsquare.offer.Offer;
|
||||||
|
import io.bitsquare.storage.Storage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.offerer.OffererAsBuyerProtocol;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class OffererAsBuyerTrade extends OffererTrade implements Serializable {
|
||||||
|
// That object is saved to disc. We need to take care of changes to not break deserialization.
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
transient private static final Logger log = LoggerFactory.getLogger(OffererAsBuyerTrade.class);
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Enum
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public enum LifeCycleState implements OffererTrade.LifeCycleState {
|
||||||
|
OFFER_OPEN,
|
||||||
|
OFFER_RESERVED,
|
||||||
|
OFFER_CANCELED,
|
||||||
|
PENDING,
|
||||||
|
COMPLETED,
|
||||||
|
FAILED
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ProcessState implements OffererTrade.ProcessState {
|
||||||
|
UNDEFINED,
|
||||||
|
DEPOSIT_PUBLISHED,
|
||||||
|
DEPOSIT_CONFIRMED,
|
||||||
|
|
||||||
|
FIAT_PAYMENT_STARTED,
|
||||||
|
|
||||||
|
PAYOUT_PUBLISHED,
|
||||||
|
|
||||||
|
MESSAGE_SENDING_FAILED,
|
||||||
|
EXCEPTION
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor, initialization
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public OffererAsBuyerTrade(Offer offer, Storage<? extends TradeList> storage) {
|
||||||
|
super(offer, storage);
|
||||||
|
log.trace("Created by constructor");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||||
|
in.defaultReadObject();
|
||||||
|
log.trace("Created from serialized form.");
|
||||||
|
|
||||||
|
initStateProperties();
|
||||||
|
initAmountProperty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createProtocol() {
|
||||||
|
protocol = new OffererAsBuyerProtocol(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initStates() {
|
||||||
|
processState = ProcessState.UNDEFINED;
|
||||||
|
lifeCycleState = LifeCycleState.OFFER_OPEN;
|
||||||
|
initStateProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Fiat
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public void onFiatPaymentStarted() {
|
||||||
|
assert protocol instanceof OffererAsBuyerProtocol;
|
||||||
|
((OffererAsBuyerProtocol) protocol).onFiatPaymentStarted();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Setter for Mutable objects
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProcessState(Trade.ProcessState processState) {
|
||||||
|
super.setProcessState(processState);
|
||||||
|
|
||||||
|
switch ((ProcessState) processState) {
|
||||||
|
case EXCEPTION:
|
||||||
|
disposeProtocol();
|
||||||
|
setLifeCycleState(LifeCycleState.FAILED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLifeCycleState(Trade.LifeCycleState lifeCycleState) {
|
||||||
|
super.setLifeCycleState(lifeCycleState);
|
||||||
|
|
||||||
|
switch ((LifeCycleState) lifeCycleState) {
|
||||||
|
case FAILED:
|
||||||
|
disposeProtocol();
|
||||||
|
break;
|
||||||
|
case COMPLETED:
|
||||||
|
disposeProtocol();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setThrowable(Throwable throwable) {
|
||||||
|
super.setThrowable(throwable);
|
||||||
|
setProcessState(ProcessState.EXCEPTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Protected
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleConfidenceResult() {
|
||||||
|
if (((ProcessState) processState).ordinal() < ProcessState.DEPOSIT_CONFIRMED.ordinal())
|
||||||
|
setProcessState(ProcessState.DEPOSIT_CONFIRMED);
|
||||||
|
}
|
||||||
|
}
|
153
core/src/main/java/io/bitsquare/trade/OffererAsSellerTrade.java
Normal file
153
core/src/main/java/io/bitsquare/trade/OffererAsSellerTrade.java
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade;
|
||||||
|
|
||||||
|
import io.bitsquare.offer.Offer;
|
||||||
|
import io.bitsquare.storage.Storage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.offerer.OffererAsSellerProtocol;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class OffererAsSellerTrade extends OffererTrade implements Serializable {
|
||||||
|
// That object is saved to disc. We need to take care of changes to not break deserialization.
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
transient private static final Logger log = LoggerFactory.getLogger(OffererAsSellerTrade.class);
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Enum
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public enum LifeCycleState implements OffererTrade.LifeCycleState {
|
||||||
|
OFFER_OPEN,
|
||||||
|
OFFER_RESERVED,
|
||||||
|
OFFER_CANCELED,
|
||||||
|
PENDING,
|
||||||
|
COMPLETED,
|
||||||
|
FAILED
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ProcessState implements OffererTrade.ProcessState {
|
||||||
|
UNDEFINED,
|
||||||
|
DEPOSIT_PUBLISHED,
|
||||||
|
DEPOSIT_CONFIRMED,
|
||||||
|
|
||||||
|
FIAT_PAYMENT_STARTED,
|
||||||
|
|
||||||
|
FIAT_PAYMENT_RECEIVED,
|
||||||
|
|
||||||
|
PAYOUT_PUBLISHED,
|
||||||
|
|
||||||
|
MESSAGE_SENDING_FAILED,
|
||||||
|
EXCEPTION
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor, initialization
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public OffererAsSellerTrade(Offer offer, Storage<? extends TradeList> storage) {
|
||||||
|
super(offer, storage);
|
||||||
|
log.trace("Created by constructor");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||||
|
in.defaultReadObject();
|
||||||
|
log.trace("Created from serialized form.");
|
||||||
|
|
||||||
|
initStateProperties();
|
||||||
|
initAmountProperty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createProtocol() {
|
||||||
|
protocol = new OffererAsSellerProtocol(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initStates() {
|
||||||
|
processState = ProcessState.UNDEFINED;
|
||||||
|
lifeCycleState = LifeCycleState.OFFER_OPEN;
|
||||||
|
initStateProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Fiat
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public void onFiatPaymentReceived() {
|
||||||
|
assert protocol instanceof OffererAsSellerProtocol;
|
||||||
|
((OffererAsSellerProtocol) protocol).onFiatPaymentReceived();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Setter for Mutable objects
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProcessState(Trade.ProcessState processState) {
|
||||||
|
super.setProcessState(processState);
|
||||||
|
|
||||||
|
switch ((ProcessState) processState) {
|
||||||
|
case EXCEPTION:
|
||||||
|
disposeProtocol();
|
||||||
|
setLifeCycleState(LifeCycleState.FAILED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLifeCycleState(Trade.LifeCycleState lifeCycleState) {
|
||||||
|
super.setLifeCycleState(lifeCycleState);
|
||||||
|
|
||||||
|
switch ((LifeCycleState) lifeCycleState) {
|
||||||
|
case FAILED:
|
||||||
|
disposeProtocol();
|
||||||
|
break;
|
||||||
|
case COMPLETED:
|
||||||
|
disposeProtocol();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setThrowable(Throwable throwable) {
|
||||||
|
super.setThrowable(throwable);
|
||||||
|
setProcessState(ProcessState.EXCEPTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Protected
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleConfidenceResult() {
|
||||||
|
if (((ProcessState) processState).ordinal() < ProcessState.DEPOSIT_CONFIRMED.ordinal())
|
||||||
|
setProcessState(ProcessState.DEPOSIT_CONFIRMED);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -21,18 +21,11 @@ import io.bitsquare.offer.Offer;
|
||||||
import io.bitsquare.p2p.Peer;
|
import io.bitsquare.p2p.Peer;
|
||||||
import io.bitsquare.storage.Storage;
|
import io.bitsquare.storage.Storage;
|
||||||
import io.bitsquare.trade.protocol.trade.ProcessModel;
|
import io.bitsquare.trade.protocol.trade.ProcessModel;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.OffererProtocol;
|
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.models.OffererProcessModel;
|
import io.bitsquare.trade.protocol.trade.offerer.models.OffererProcessModel;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
import org.bitcoinj.core.TransactionConfidence;
|
|
||||||
import org.bitcoinj.utils.Fiat;
|
import org.bitcoinj.utils.Fiat;
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
|
||||||
import com.google.common.util.concurrent.Futures;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
@ -43,12 +36,10 @@ import javafx.beans.property.ObjectProperty;
|
||||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class OffererTrade extends Trade implements Serializable {
|
public abstract class OffererTrade extends Trade implements Serializable {
|
||||||
// That object is saved to disc. We need to take care of changes to not break deserialization.
|
// That object is saved to disc. We need to take care of changes to not break deserialization.
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@ -59,26 +50,10 @@ public class OffererTrade extends Trade implements Serializable {
|
||||||
// Enum
|
// Enum
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public enum OffererLifeCycleState implements LifeCycleState {
|
public interface LifeCycleState extends Trade.LifeCycleState {
|
||||||
OFFER_OPEN,
|
|
||||||
OFFER_RESERVED,
|
|
||||||
OFFER_CANCELED,
|
|
||||||
PENDING,
|
|
||||||
COMPLETED,
|
|
||||||
FAILED
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum OffererProcessState implements ProcessState {
|
public interface ProcessState extends Trade.ProcessState {
|
||||||
UNDEFINED,
|
|
||||||
DEPOSIT_PUBLISHED,
|
|
||||||
DEPOSIT_CONFIRMED,
|
|
||||||
|
|
||||||
FIAT_PAYMENT_STARTED,
|
|
||||||
|
|
||||||
PAYOUT_PUBLISHED,
|
|
||||||
|
|
||||||
MESSAGE_SENDING_FAILED,
|
|
||||||
EXCEPTION
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,31 +61,23 @@ public class OffererTrade extends Trade implements Serializable {
|
||||||
// Fields
|
// Fields
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Transient/Immutable
|
|
||||||
transient private ObjectProperty<OffererProcessState> processStateProperty;
|
|
||||||
transient private ObjectProperty<OffererLifeCycleState> lifeCycleStateProperty;
|
|
||||||
|
|
||||||
// Mutable
|
// Mutable
|
||||||
private Coin tradeAmount;
|
protected Coin tradeAmount;
|
||||||
private Peer tradingPeer;
|
protected Peer tradingPeer;
|
||||||
private OffererProcessState processState;
|
transient protected ObjectProperty<Coin> tradeAmountProperty;
|
||||||
private OffererLifeCycleState lifeCycleState;
|
transient protected ObjectProperty<Fiat> tradeVolumeProperty;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor, initialization
|
// Constructor, initialization
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public OffererTrade(Offer offer, Storage<? extends TradeList> storage) {
|
protected OffererTrade(Offer offer, Storage<? extends TradeList> storage) {
|
||||||
super(offer, storage);
|
super(offer, storage);
|
||||||
log.trace("Created by constructor");
|
log.trace("Created by constructor");
|
||||||
|
|
||||||
processState = OffererProcessState.UNDEFINED;
|
initStates();
|
||||||
lifeCycleState = OffererLifeCycleState.OFFER_OPEN;
|
initStateProperties();
|
||||||
|
|
||||||
processStateProperty = new SimpleObjectProperty<>(processState);
|
|
||||||
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
|
|
||||||
|
|
||||||
tradeAmountProperty = new SimpleObjectProperty<>();
|
tradeAmountProperty = new SimpleObjectProperty<>();
|
||||||
tradeVolumeProperty = new SimpleObjectProperty<>();
|
tradeVolumeProperty = new SimpleObjectProperty<>();
|
||||||
}
|
}
|
||||||
|
@ -119,87 +86,24 @@ public class OffererTrade extends Trade implements Serializable {
|
||||||
in.defaultReadObject();
|
in.defaultReadObject();
|
||||||
log.trace("Created from serialized form.");
|
log.trace("Created from serialized form.");
|
||||||
|
|
||||||
processStateProperty = new SimpleObjectProperty<>(processState);
|
initStateProperties();
|
||||||
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
|
initAmountProperty();
|
||||||
|
|
||||||
tradeAmountProperty = new SimpleObjectProperty<>();
|
|
||||||
tradeVolumeProperty = new SimpleObjectProperty<>();
|
|
||||||
|
|
||||||
if (tradeAmount != null) {
|
|
||||||
tradeAmountProperty.set(tradeAmount);
|
|
||||||
tradeVolumeProperty.set(getTradeVolume());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ProcessModel createProcessModel() {
|
public ProcessModel createProcessModel() {
|
||||||
return new OffererProcessModel();
|
return new OffererProcessModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void createProtocol() {
|
|
||||||
protocol = new OffererProtocol(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onFiatPaymentStarted() {
|
|
||||||
assert protocol != null;
|
|
||||||
((OffererProtocol) protocol).onFiatPaymentStarted();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Getter only
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReadOnlyObjectProperty<OffererProcessState> processStateProperty() {
|
|
||||||
return processStateProperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReadOnlyObjectProperty<OffererLifeCycleState> lifeCycleStateProperty() {
|
|
||||||
return lifeCycleStateProperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OffererProcessModel getProcessModel() {
|
|
||||||
return (OffererProcessModel) processModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Setter for Mutable objects
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public void setProcessState(OffererProcessState processState) {
|
|
||||||
this.processState = processState;
|
|
||||||
processStateProperty.set(processState);
|
|
||||||
|
|
||||||
switch (processState) {
|
|
||||||
case EXCEPTION:
|
|
||||||
disposeProtocol();
|
|
||||||
setLifeCycleState(OffererLifeCycleState.FAILED);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLifeCycleState(OffererLifeCycleState lifeCycleState) {
|
|
||||||
switch (lifeCycleState) {
|
|
||||||
case FAILED:
|
|
||||||
disposeProtocol();
|
|
||||||
break;
|
|
||||||
case COMPLETED:
|
|
||||||
disposeProtocol();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
this.lifeCycleState = lifeCycleState;
|
|
||||||
lifeCycleStateProperty.set(lifeCycleState);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Getter/Setter for Mutable objects
|
// Getter/Setter for Mutable objects
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public OffererProcessModel getProcessModel() {
|
||||||
|
return (OffererProcessModel) processModel;
|
||||||
|
}
|
||||||
|
|
||||||
public void setTradingPeer(Peer tradingPeer) {
|
public void setTradingPeer(Peer tradingPeer) {
|
||||||
this.tradingPeer = tradingPeer;
|
this.tradingPeer = tradingPeer;
|
||||||
}
|
}
|
||||||
|
@ -230,30 +134,27 @@ public class OffererTrade extends Trade implements Serializable {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
|
||||||
|
return tradeAmountProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() {
|
||||||
|
return tradeVolumeProperty;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Protected
|
// Protected
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setupConfidenceListener() {
|
protected void initAmountProperty() {
|
||||||
assert depositTx != null;
|
tradeAmountProperty = new SimpleObjectProperty<>();
|
||||||
TransactionConfidence transactionConfidence = depositTx.getConfidence();
|
tradeVolumeProperty = new SimpleObjectProperty<>();
|
||||||
ListenableFuture<TransactionConfidence> future = transactionConfidence.getDepthFuture(1);
|
|
||||||
Futures.addCallback(future, new FutureCallback<TransactionConfidence>() {
|
|
||||||
@Override
|
|
||||||
public void onSuccess(TransactionConfidence result) {
|
|
||||||
if (processState.ordinal() < OffererProcessState.DEPOSIT_CONFIRMED.ordinal())
|
|
||||||
setProcessState(OffererProcessState.DEPOSIT_CONFIRMED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
if (tradeAmount != null) {
|
||||||
public void onFailure(@NotNull Throwable t) {
|
tradeAmountProperty.set(tradeAmount);
|
||||||
t.printStackTrace();
|
tradeVolumeProperty.set(getTradeVolume());
|
||||||
log.error(t.getMessage());
|
|
||||||
Throwables.propagate(t);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -261,8 +162,6 @@ public class OffererTrade extends Trade implements Serializable {
|
||||||
return "OffererTrade{" +
|
return "OffererTrade{" +
|
||||||
"tradeAmount=" + tradeAmount +
|
"tradeAmount=" + tradeAmount +
|
||||||
", tradingPeer=" + tradingPeer +
|
", tradingPeer=" + tradingPeer +
|
||||||
", processState=" + processState +
|
super.toString();
|
||||||
", lifeCycleState=" + lifeCycleState +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
161
core/src/main/java/io/bitsquare/trade/TakerAsBuyerTrade.java
Normal file
161
core/src/main/java/io/bitsquare/trade/TakerAsBuyerTrade.java
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade;
|
||||||
|
|
||||||
|
import io.bitsquare.offer.Offer;
|
||||||
|
import io.bitsquare.p2p.Peer;
|
||||||
|
import io.bitsquare.storage.Storage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.TakerAsBuyerProtocol;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Coin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class TakerAsBuyerTrade extends TakerTrade implements Serializable {
|
||||||
|
// That object is saved to disc. We need to take care of changes to not break deserialization.
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
transient private static final Logger log = LoggerFactory.getLogger(TakerAsBuyerTrade.class);
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Enum
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public enum LifeCycleState implements TakerTrade.LifeCycleState {
|
||||||
|
PENDING,
|
||||||
|
COMPLETED,
|
||||||
|
FAILED
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ProcessState implements TakerTrade.ProcessState {
|
||||||
|
UNDEFINED,
|
||||||
|
TAKE_OFFER_FEE_TX_CREATED,
|
||||||
|
TAKE_OFFER_FEE_PUBLISHED,
|
||||||
|
TAKE_OFFER_FEE_PUBLISH_FAILED,
|
||||||
|
|
||||||
|
DEPOSIT_PUBLISHED,
|
||||||
|
DEPOSIT_CONFIRMED,
|
||||||
|
|
||||||
|
FIAT_PAYMENT_STARTED,
|
||||||
|
|
||||||
|
FIAT_PAYMENT_RECEIVED,
|
||||||
|
PAYOUT_PUBLISHED,
|
||||||
|
|
||||||
|
MESSAGE_SENDING_FAILED,
|
||||||
|
EXCEPTION
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor, initialization
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public TakerAsBuyerTrade(Offer offer, Coin tradeAmount, Peer tradingPeer,
|
||||||
|
Storage<? extends TradeList> storage) {
|
||||||
|
super(offer, tradeAmount, tradingPeer, storage);
|
||||||
|
log.trace("Created by constructor");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||||
|
in.defaultReadObject();
|
||||||
|
log.trace("Created from serialized form.");
|
||||||
|
|
||||||
|
initStateProperties();
|
||||||
|
initAmountProperty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initStates() {
|
||||||
|
processState = ProcessState.UNDEFINED;
|
||||||
|
lifeCycleState = TakerAsBuyerTrade.LifeCycleState.PENDING;
|
||||||
|
initStateProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createProtocol() {
|
||||||
|
protocol = new TakerAsBuyerProtocol(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// API
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public void takeAvailableOffer() {
|
||||||
|
assert protocol instanceof TakerAsBuyerProtocol;
|
||||||
|
((TakerAsBuyerProtocol) protocol).takeAvailableOffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onFiatPaymentStarted() {
|
||||||
|
assert protocol instanceof TakerAsBuyerProtocol;
|
||||||
|
((TakerAsBuyerProtocol) protocol).onFiatPaymentStarted();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Setter for Mutable objects
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProcessState(Trade.ProcessState processState) {
|
||||||
|
super.setProcessState(processState);
|
||||||
|
|
||||||
|
switch ((ProcessState) processState) {
|
||||||
|
case EXCEPTION:
|
||||||
|
disposeProtocol();
|
||||||
|
setLifeCycleState(TakerAsBuyerTrade.LifeCycleState.FAILED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLifeCycleState(Trade.LifeCycleState lifeCycleState) {
|
||||||
|
super.setLifeCycleState(lifeCycleState);
|
||||||
|
|
||||||
|
switch ((LifeCycleState) lifeCycleState) {
|
||||||
|
case FAILED:
|
||||||
|
disposeProtocol();
|
||||||
|
break;
|
||||||
|
case COMPLETED:
|
||||||
|
disposeProtocol();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setThrowable(Throwable throwable) {
|
||||||
|
super.setThrowable(throwable);
|
||||||
|
setProcessState(ProcessState.EXCEPTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Protected
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleConfidenceResult() {
|
||||||
|
if (((ProcessState) processState).ordinal() < ProcessState.DEPOSIT_CONFIRMED.ordinal())
|
||||||
|
setProcessState(ProcessState.DEPOSIT_CONFIRMED);
|
||||||
|
}
|
||||||
|
}
|
164
core/src/main/java/io/bitsquare/trade/TakerAsSellerTrade.java
Normal file
164
core/src/main/java/io/bitsquare/trade/TakerAsSellerTrade.java
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade;
|
||||||
|
|
||||||
|
import io.bitsquare.offer.Offer;
|
||||||
|
import io.bitsquare.p2p.Peer;
|
||||||
|
import io.bitsquare.storage.Storage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.TakerAsSellerProtocol;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Coin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class TakerAsSellerTrade extends TakerTrade implements Serializable {
|
||||||
|
// That object is saved to disc. We need to take care of changes to not break deserialization.
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
transient private static final Logger log = LoggerFactory.getLogger(TakerAsSellerTrade.class);
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Enum
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public enum LifeCycleState implements TakerTrade.LifeCycleState {
|
||||||
|
PENDING,
|
||||||
|
COMPLETED,
|
||||||
|
FAILED
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ProcessState implements TakerTrade.ProcessState {
|
||||||
|
UNDEFINED,
|
||||||
|
TAKE_OFFER_FEE_TX_CREATED,
|
||||||
|
TAKE_OFFER_FEE_PUBLISHED,
|
||||||
|
TAKE_OFFER_FEE_PUBLISH_FAILED,
|
||||||
|
|
||||||
|
DEPOSIT_PUBLISHED,
|
||||||
|
DEPOSIT_CONFIRMED,
|
||||||
|
|
||||||
|
FIAT_PAYMENT_STARTED,
|
||||||
|
|
||||||
|
FIAT_PAYMENT_RECEIVED,
|
||||||
|
PAYOUT_PUBLISHED,
|
||||||
|
|
||||||
|
MESSAGE_SENDING_FAILED,
|
||||||
|
EXCEPTION
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor, initialization
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public TakerAsSellerTrade(Offer offer, Coin tradeAmount, Peer tradingPeer,
|
||||||
|
Storage<? extends TradeList> storage) {
|
||||||
|
super(offer, tradeAmount, tradingPeer, storage);
|
||||||
|
log.trace("Created by constructor");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||||
|
in.defaultReadObject();
|
||||||
|
log.trace("Created from serialized form.");
|
||||||
|
|
||||||
|
initStateProperties();
|
||||||
|
initAmountProperty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initStates() {
|
||||||
|
processState = ProcessState.UNDEFINED;
|
||||||
|
lifeCycleState = TakerAsSellerTrade.LifeCycleState.PENDING;
|
||||||
|
initStateProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createProtocol() {
|
||||||
|
protocol = new TakerAsSellerProtocol(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// API
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public void takeAvailableOffer() {
|
||||||
|
assert protocol instanceof TakerAsSellerProtocol;
|
||||||
|
((TakerAsSellerProtocol) protocol).takeAvailableOffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onFiatPaymentReceived() {
|
||||||
|
assert protocol instanceof TakerAsSellerProtocol;
|
||||||
|
((TakerAsSellerProtocol) protocol).onFiatPaymentReceived();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Setter for Mutable objects
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProcessState(Trade.ProcessState processState) {
|
||||||
|
ProcessState state = (ProcessState) processState;
|
||||||
|
this.processState = processState;
|
||||||
|
processStateProperty.set(processState);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case EXCEPTION:
|
||||||
|
disposeProtocol();
|
||||||
|
setLifeCycleState(TakerAsSellerTrade.LifeCycleState.FAILED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLifeCycleState(Trade.LifeCycleState lifeCycleState) {
|
||||||
|
LifeCycleState state = (LifeCycleState) lifeCycleState;
|
||||||
|
switch (state) {
|
||||||
|
case FAILED:
|
||||||
|
disposeProtocol();
|
||||||
|
break;
|
||||||
|
case COMPLETED:
|
||||||
|
disposeProtocol();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.lifeCycleState = lifeCycleState;
|
||||||
|
lifeCycleStateProperty.set(lifeCycleState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setThrowable(Throwable throwable) {
|
||||||
|
super.setThrowable(throwable);
|
||||||
|
setProcessState(ProcessState.EXCEPTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Protected
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleConfidenceResult() {
|
||||||
|
if (((ProcessState) processState).ordinal() < ProcessState.DEPOSIT_CONFIRMED.ordinal())
|
||||||
|
setProcessState(ProcessState.DEPOSIT_CONFIRMED);
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,18 +21,11 @@ import io.bitsquare.offer.Offer;
|
||||||
import io.bitsquare.p2p.Peer;
|
import io.bitsquare.p2p.Peer;
|
||||||
import io.bitsquare.storage.Storage;
|
import io.bitsquare.storage.Storage;
|
||||||
import io.bitsquare.trade.protocol.trade.ProcessModel;
|
import io.bitsquare.trade.protocol.trade.ProcessModel;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.TakerProtocol;
|
|
||||||
import io.bitsquare.trade.protocol.trade.taker.models.TakerProcessModel;
|
import io.bitsquare.trade.protocol.trade.taker.models.TakerProcessModel;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
import org.bitcoinj.core.TransactionConfidence;
|
|
||||||
import org.bitcoinj.utils.Fiat;
|
import org.bitcoinj.utils.Fiat;
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
|
||||||
import com.google.common.util.concurrent.Futures;
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@ -40,12 +33,10 @@ import javafx.beans.property.ObjectProperty;
|
||||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class TakerTrade extends Trade implements Serializable {
|
public abstract class TakerTrade extends Trade implements Serializable {
|
||||||
// That object is saved to disc. We need to take care of changes to not break deserialization.
|
// That object is saved to disc. We need to take care of changes to not break deserialization.
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@ -56,28 +47,10 @@ public class TakerTrade extends Trade implements Serializable {
|
||||||
// Enum
|
// Enum
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public enum TakerLifeCycleState implements LifeCycleState {
|
public interface LifeCycleState extends Trade.LifeCycleState {
|
||||||
PENDING,
|
|
||||||
COMPLETED,
|
|
||||||
FAILED
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum TakerProcessState implements ProcessState {
|
public interface ProcessState extends Trade.ProcessState {
|
||||||
UNDEFINED,
|
|
||||||
TAKE_OFFER_FEE_TX_CREATED,
|
|
||||||
TAKE_OFFER_FEE_PUBLISHED,
|
|
||||||
TAKE_OFFER_FEE_PUBLISH_FAILED,
|
|
||||||
|
|
||||||
DEPOSIT_PUBLISHED,
|
|
||||||
DEPOSIT_CONFIRMED,
|
|
||||||
|
|
||||||
FIAT_PAYMENT_STARTED,
|
|
||||||
|
|
||||||
FIAT_PAYMENT_RECEIVED,
|
|
||||||
PAYOUT_PUBLISHED,
|
|
||||||
|
|
||||||
MESSAGE_SENDING_FAILED,
|
|
||||||
EXCEPTION
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,24 +58,18 @@ public class TakerTrade extends Trade implements Serializable {
|
||||||
// Fields
|
// Fields
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Transient/Immutable
|
|
||||||
transient private ObjectProperty<TakerProcessState> processStateProperty;
|
|
||||||
transient private ObjectProperty<TakerLifeCycleState> lifeCycleStateProperty;
|
|
||||||
|
|
||||||
// Immutable
|
// Immutable
|
||||||
private final Coin tradeAmount;
|
protected final Coin tradeAmount;
|
||||||
private final Peer tradingPeer;
|
protected final Peer tradingPeer;
|
||||||
|
transient protected ObjectProperty<Coin> tradeAmountProperty;
|
||||||
// Mutable
|
transient protected ObjectProperty<Fiat> tradeVolumeProperty;
|
||||||
private TakerProcessState processState;
|
|
||||||
private TakerLifeCycleState lifeCycleState;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor, initialization
|
// Constructor, initialization
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public TakerTrade(Offer offer, Coin tradeAmount, Peer tradingPeer,
|
protected TakerTrade(Offer offer, Coin tradeAmount, Peer tradingPeer,
|
||||||
Storage<? extends TradeList> storage) {
|
Storage<? extends TradeList> storage) {
|
||||||
super(offer, storage);
|
super(offer, storage);
|
||||||
log.trace("Created by constructor");
|
log.trace("Created by constructor");
|
||||||
|
@ -110,53 +77,24 @@ public class TakerTrade extends Trade implements Serializable {
|
||||||
this.tradeAmount = tradeAmount;
|
this.tradeAmount = tradeAmount;
|
||||||
this.tradingPeer = tradingPeer;
|
this.tradingPeer = tradingPeer;
|
||||||
|
|
||||||
processState = TakerProcessState.UNDEFINED;
|
initStates();
|
||||||
lifeCycleState = TakerLifeCycleState.PENDING;
|
initStateProperties();
|
||||||
|
initAmountProperty();
|
||||||
processStateProperty = new SimpleObjectProperty<>(processState);
|
|
||||||
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
|
|
||||||
|
|
||||||
tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount);
|
|
||||||
tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
|
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||||
in.defaultReadObject();
|
in.defaultReadObject();
|
||||||
log.trace("Created from serialized form.");
|
log.trace("Created from serialized form.");
|
||||||
|
|
||||||
processStateProperty = new SimpleObjectProperty<>(processState);
|
initStateProperties();
|
||||||
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
|
initAmountProperty();
|
||||||
|
|
||||||
tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount);
|
|
||||||
tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ProcessModel createProcessModel() {
|
public ProcessModel createProcessModel() {
|
||||||
return new TakerProcessModel();
|
return new TakerProcessModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void createProtocol() {
|
|
||||||
protocol = new TakerProtocol(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// API
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public void takeAvailableOffer() {
|
|
||||||
assert processModel != null;
|
|
||||||
((TakerProtocol) protocol).takeAvailableOffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onFiatPaymentReceived() {
|
|
||||||
assert protocol != null;
|
|
||||||
((TakerProtocol) protocol).onFiatPaymentReceived();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Getter only
|
// Getter only
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -175,70 +113,26 @@ public class TakerTrade extends Trade implements Serializable {
|
||||||
return tradingPeer;
|
return tradingPeer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReadOnlyObjectProperty<TakerProcessState> processStateProperty() {
|
|
||||||
return processStateProperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReadOnlyObjectProperty<TakerLifeCycleState> lifeCycleStateProperty() {
|
|
||||||
return lifeCycleStateProperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TakerProcessModel getProcessModel() {
|
public TakerProcessModel getProcessModel() {
|
||||||
return (TakerProcessModel) processModel;
|
return (TakerProcessModel) processModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
return tradeAmountProperty;
|
||||||
// Setter for Mutable objects
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public void setLifeCycleState(TakerLifeCycleState lifeCycleState) {
|
|
||||||
this.lifeCycleState = lifeCycleState;
|
|
||||||
lifeCycleStateProperty.set(lifeCycleState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProcessState(TakerProcessState processState) {
|
public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() {
|
||||||
this.processState = processState;
|
return tradeVolumeProperty;
|
||||||
processStateProperty.set(processState);
|
|
||||||
|
|
||||||
if (processState == TakerProcessState.EXCEPTION) {
|
|
||||||
setLifeCycleState(TakerLifeCycleState.FAILED);
|
|
||||||
disposeProtocol();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setThrowable(Throwable throwable) {
|
|
||||||
super.setThrowable(throwable);
|
|
||||||
setProcessState(TakerTrade.TakerProcessState.EXCEPTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Protected
|
// Protected
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setupConfidenceListener() {
|
protected void initAmountProperty() {
|
||||||
assert depositTx != null;
|
tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount);
|
||||||
TransactionConfidence transactionConfidence = depositTx.getConfidence();
|
tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume());
|
||||||
ListenableFuture<TransactionConfidence> future = transactionConfidence.getDepthFuture(1);
|
|
||||||
Futures.addCallback(future, new FutureCallback<TransactionConfidence>() {
|
|
||||||
@Override
|
|
||||||
public void onSuccess(TransactionConfidence result) {
|
|
||||||
if (processState.ordinal() < TakerProcessState.DEPOSIT_CONFIRMED.ordinal())
|
|
||||||
setProcessState(TakerProcessState.DEPOSIT_CONFIRMED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(@NotNull Throwable t) {
|
|
||||||
t.printStackTrace();
|
|
||||||
log.error(t.getMessage());
|
|
||||||
Throwables.propagate(t);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -246,8 +140,6 @@ public class TakerTrade extends Trade implements Serializable {
|
||||||
return "TakerTrade{" +
|
return "TakerTrade{" +
|
||||||
"tradeAmount=" + tradeAmount +
|
"tradeAmount=" + tradeAmount +
|
||||||
", tradingPeer=" + tradingPeer +
|
", tradingPeer=" + tradingPeer +
|
||||||
", processState=" + processState +
|
super.toString();
|
||||||
", lifeCycleState=" + lifeCycleState +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,8 +33,14 @@ import io.bitsquare.user.User;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
import org.bitcoinj.core.Transaction;
|
import org.bitcoinj.core.Transaction;
|
||||||
|
import org.bitcoinj.core.TransactionConfidence;
|
||||||
import org.bitcoinj.utils.Fiat;
|
import org.bitcoinj.utils.Fiat;
|
||||||
|
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
|
import com.google.common.util.concurrent.Futures;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
@ -45,6 +51,9 @@ import javax.annotation.Nullable;
|
||||||
|
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||||
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -64,10 +73,10 @@ abstract public class Trade extends Model implements Serializable {
|
||||||
// Interfaces
|
// Interfaces
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
interface ProcessState {
|
public interface LifeCycleState {
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface LifeCycleState {
|
public interface ProcessState {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,6 +85,9 @@ abstract public class Trade extends Model implements Serializable {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Transient/Immutable
|
// Transient/Immutable
|
||||||
|
transient protected ObjectProperty<ProcessState> processStateProperty;
|
||||||
|
transient protected ObjectProperty<LifeCycleState> lifeCycleStateProperty;
|
||||||
|
|
||||||
transient private Storage<? extends TradeList> storage;
|
transient private Storage<? extends TradeList> storage;
|
||||||
transient protected Protocol protocol;
|
transient protected Protocol protocol;
|
||||||
|
|
||||||
|
@ -85,6 +97,8 @@ abstract public class Trade extends Model implements Serializable {
|
||||||
protected final ProcessModel processModel;
|
protected final ProcessModel processModel;
|
||||||
|
|
||||||
// Mutable
|
// Mutable
|
||||||
|
protected ProcessState processState;
|
||||||
|
protected LifeCycleState lifeCycleState;
|
||||||
private MailboxMessage mailboxMessage;
|
private MailboxMessage mailboxMessage;
|
||||||
protected Transaction depositTx;
|
protected Transaction depositTx;
|
||||||
private Contract contract;
|
private Contract contract;
|
||||||
|
@ -96,15 +110,13 @@ abstract public class Trade extends Model implements Serializable {
|
||||||
// Transient/Mutable
|
// Transient/Mutable
|
||||||
transient private String errorMessage;
|
transient private String errorMessage;
|
||||||
transient private Throwable throwable;
|
transient private Throwable throwable;
|
||||||
transient protected ObjectProperty<Coin> tradeAmountProperty;
|
|
||||||
transient protected ObjectProperty<Fiat> tradeVolumeProperty;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor, initialization
|
// Constructor, initialization
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Trade(Offer offer, Storage<? extends TradeList> storage) {
|
protected Trade(Offer offer, Storage<? extends TradeList> storage) {
|
||||||
log.trace("Created by constructor");
|
log.trace("Created by constructor");
|
||||||
this.offer = offer;
|
this.offer = offer;
|
||||||
this.storage = storage;
|
this.storage = storage;
|
||||||
|
@ -141,18 +153,6 @@ abstract public class Trade extends Model implements Serializable {
|
||||||
protocol.setMailboxMessage(mailboxMessage);
|
protocol.setMailboxMessage(mailboxMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStorage(Storage<? extends TradeList> storage) {
|
|
||||||
this.storage = storage;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected ProcessModel createProcessModel();
|
|
||||||
|
|
||||||
abstract protected void createProtocol();
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// API
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// The deserialized tx has not actual confidence data, so we need to get the fresh one from the wallet.
|
// The deserialized tx has not actual confidence data, so we need to get the fresh one from the wallet.
|
||||||
public void updateDepositTxFromWallet(TradeWalletService tradeWalletService) {
|
public void updateDepositTxFromWallet(TradeWalletService tradeWalletService) {
|
||||||
|
@ -163,6 +163,7 @@ abstract public class Trade extends Model implements Serializable {
|
||||||
public void setDepositTx(Transaction tx) {
|
public void setDepositTx(Transaction tx) {
|
||||||
this.depositTx = tx;
|
this.depositTx = tx;
|
||||||
setupConfidenceListener();
|
setupConfidenceListener();
|
||||||
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disposeProtocol() {
|
public void disposeProtocol() {
|
||||||
|
@ -180,7 +181,57 @@ abstract public class Trade extends Model implements Serializable {
|
||||||
storage.queueUpForSave();
|
storage.queueUpForSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void setupConfidenceListener();
|
public void setStorage(Storage<? extends TradeList> storage) {
|
||||||
|
this.storage = storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProcessState(Trade.ProcessState processState) {
|
||||||
|
this.processState = processState;
|
||||||
|
processStateProperty.set(processState);
|
||||||
|
storage.queueUpForSave();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLifeCycleState(Trade.LifeCycleState lifeCycleState) {
|
||||||
|
this.lifeCycleState = lifeCycleState;
|
||||||
|
lifeCycleStateProperty.set(lifeCycleState);
|
||||||
|
storage.queueUpForSave();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setupConfidenceListener() {
|
||||||
|
if (depositTx != null) {
|
||||||
|
TransactionConfidence transactionConfidence = depositTx.getConfidence();
|
||||||
|
ListenableFuture<TransactionConfidence> future = transactionConfidence.getDepthFuture(1);
|
||||||
|
Futures.addCallback(future, new FutureCallback<TransactionConfidence>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(TransactionConfidence result) {
|
||||||
|
handleConfidenceResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NotNull Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
log.error(t.getMessage());
|
||||||
|
Throwables.propagate(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
abstract protected void createProtocol();
|
||||||
|
|
||||||
|
abstract protected void initAmountProperty();
|
||||||
|
|
||||||
|
abstract protected void handleConfidenceResult();
|
||||||
|
|
||||||
|
abstract protected void initStates();
|
||||||
|
|
||||||
|
abstract protected ProcessModel createProcessModel();
|
||||||
|
|
||||||
|
protected void initStateProperties() {
|
||||||
|
processStateProperty = new SimpleObjectProperty<>(processState);
|
||||||
|
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -224,24 +275,19 @@ abstract public class Trade extends Model implements Serializable {
|
||||||
return offer.getSecurityDeposit();
|
return offer.getSecurityDeposit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
|
|
||||||
return tradeAmountProperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() {
|
|
||||||
return tradeVolumeProperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
abstract public Coin getTradeAmount();
|
abstract public Coin getTradeAmount();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
abstract public Fiat getTradeVolume();
|
abstract public Fiat getTradeVolume();
|
||||||
|
|
||||||
abstract public ReadOnlyObjectProperty<? extends ProcessState> processStateProperty();
|
public ReadOnlyObjectProperty<? extends ProcessState> processStateProperty() {
|
||||||
|
return processStateProperty;
|
||||||
|
}
|
||||||
|
|
||||||
abstract public ReadOnlyObjectProperty<? extends LifeCycleState> lifeCycleStateProperty();
|
public ReadOnlyObjectProperty<? extends LifeCycleState> lifeCycleStateProperty() {
|
||||||
|
return lifeCycleStateProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -314,18 +360,21 @@ abstract public class Trade extends Model implements Serializable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Trade{" +
|
return ", protocol=" + protocol +
|
||||||
"throwable=" + throwable +
|
|
||||||
", offer=" + offer +
|
", offer=" + offer +
|
||||||
", date=" + date +
|
", date=" + date +
|
||||||
|
", processModel=" + processModel +
|
||||||
|
", processState=" + processState +
|
||||||
|
", lifeCycleState=" + lifeCycleState +
|
||||||
", mailboxMessage=" + mailboxMessage +
|
", mailboxMessage=" + mailboxMessage +
|
||||||
", depositTx=" + depositTx +
|
", depositTx=" + depositTx +
|
||||||
", contract=" + contract +
|
", contract=" + contract +
|
||||||
", contractAsJson='" + contractAsJson + '\'' +
|
", contractAsJson='" + contractAsJson + '\'' +
|
||||||
", takerContractSignature='" + takerContractSignature + '\'' +
|
", takerContractSignature='" + takerContractSignature + '\'' +
|
||||||
", offererContractSignature='" + offererContractSignature + '\'' +
|
", offererContractSignature='" + offererContractSignature + '\'' +
|
||||||
|
", payoutTx=" + payoutTx +
|
||||||
", errorMessage='" + errorMessage + '\'' +
|
", errorMessage='" + errorMessage + '\'' +
|
||||||
", processModel=" + processModel +
|
", throwable=" + throwable +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -56,6 +56,7 @@ import com.google.common.util.concurrent.FutureCallback;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -90,7 +91,7 @@ public class TradeManager {
|
||||||
private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>();
|
private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>();
|
||||||
private final Storage<TradeList> pendingTradesStorage;
|
private final Storage<TradeList> pendingTradesStorage;
|
||||||
private final Storage<TradeList> openOfferTradesStorage;
|
private final Storage<TradeList> openOfferTradesStorage;
|
||||||
private final TradeList<OffererTrade> openOfferTrades;
|
private final TradeList<OffererAsBuyerTrade> openOfferTrades;
|
||||||
private final TradeList<Trade> pendingTrades;
|
private final TradeList<Trade> pendingTrades;
|
||||||
private final TradeList<Trade> closedTrades;
|
private final TradeList<Trade> closedTrades;
|
||||||
|
|
||||||
|
@ -149,25 +150,43 @@ public class TradeManager {
|
||||||
// When all services are initialized we create the protocols for our open offers and persisted pendingTrades
|
// When all services are initialized we create the protocols for our open offers and persisted pendingTrades
|
||||||
// OffererAsBuyerProtocol listens for take offer requests, so we need to instantiate it early.
|
// OffererAsBuyerProtocol listens for take offer requests, so we need to instantiate it early.
|
||||||
public void onAllServicesInitialized() {
|
public void onAllServicesInitialized() {
|
||||||
for (OffererTrade offererTrade : openOfferTrades) {
|
for (OffererAsBuyerTrade OffererAsBuyerTrade : openOfferTrades) {
|
||||||
Offer offer = offererTrade.getOffer();
|
Offer offer = OffererAsBuyerTrade.getOffer();
|
||||||
// We add own offers to offerbook when we go online again
|
// We add own offers to offerbook when we go online again
|
||||||
offerBookService.addOffer(offer,
|
offerBookService.addOffer(offer,
|
||||||
() -> log.debug("Successful removed open offer from DHT"),
|
() -> log.debug("Successful removed open offer from DHT"),
|
||||||
(message, throwable) -> log.error("Remove open offer from DHT failed. " + message));
|
(message, throwable) -> log.error("Remove open offer from DHT failed. " + message));
|
||||||
setupDepositPublishedListener(offererTrade);
|
setupDepositPublishedListener(OffererAsBuyerTrade);
|
||||||
offererTrade.setStorage(openOfferTradesStorage);
|
OffererAsBuyerTrade.setStorage(openOfferTradesStorage);
|
||||||
initTrade(offererTrade);
|
initTrade(OffererAsBuyerTrade);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
List<Trade> failedTrades = new ArrayList<>();
|
||||||
for (Trade trade : pendingTrades) {
|
for (Trade trade : pendingTrades) {
|
||||||
// We continue an interrupted trade.
|
// We continue an interrupted trade.
|
||||||
// TODO if the peer has changed its IP address, we need to make another findPeer request. At the moment we use the peer stored in trade to
|
// TODO if the peer has changed its IP address, we need to make another findPeer request. At the moment we use the peer stored in trade to
|
||||||
// continue the trade, but that might fail.
|
// continue the trade, but that might fail.
|
||||||
|
|
||||||
|
boolean failed = false;
|
||||||
|
if (trade instanceof TakerAsSellerTrade) {
|
||||||
|
failed = trade.lifeCycleState == TakerAsSellerTrade.LifeCycleState.FAILED;
|
||||||
|
}
|
||||||
|
else if (trade instanceof TakerAsBuyerTrade) {
|
||||||
|
failed = trade.lifeCycleState == TakerAsBuyerTrade.LifeCycleState.FAILED;
|
||||||
|
}
|
||||||
|
if (failed) {
|
||||||
|
failedTrades.add(trade);
|
||||||
|
}
|
||||||
|
else {
|
||||||
trade.setStorage(pendingTradesStorage);
|
trade.setStorage(pendingTradesStorage);
|
||||||
trade.updateDepositTxFromWallet(tradeWalletService);
|
trade.updateDepositTxFromWallet(tradeWalletService);
|
||||||
initTrade(trade);
|
initTrade(trade);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
for (Trade trade : failedTrades) {
|
||||||
|
pendingTrades.remove(trade);
|
||||||
|
closedTrades.add(trade);
|
||||||
|
}
|
||||||
|
|
||||||
// if there are messages in our mailbox we apply it and remove them from the DHT
|
// if there are messages in our mailbox we apply it and remove them from the DHT
|
||||||
mailboxService.getAllMessages(user.getP2PSigPubKey(),
|
mailboxService.getAllMessages(user.getP2PSigPubKey(),
|
||||||
|
@ -210,8 +229,8 @@ public class TradeManager {
|
||||||
log.debug("shutDown");
|
log.debug("shutDown");
|
||||||
shutDownRequested = true;
|
shutDownRequested = true;
|
||||||
// we remove own offers form offerbook when we go offline
|
// we remove own offers form offerbook when we go offline
|
||||||
for (OffererTrade offererTrade : openOfferTrades) {
|
for (OffererAsBuyerTrade OffererAsBuyerTrade : openOfferTrades) {
|
||||||
Offer offer = offererTrade.getOffer();
|
Offer offer = OffererAsBuyerTrade.getOffer();
|
||||||
offerBookService.removeOfferAtShutDown(offer);
|
offerBookService.removeOfferAtShutDown(offer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,23 +277,23 @@ public class TradeManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePlaceOfferResult(Transaction transaction, Offer offer, TransactionResultHandler resultHandler) {
|
private void handlePlaceOfferResult(Transaction transaction, Offer offer, TransactionResultHandler resultHandler) {
|
||||||
OffererTrade offererTrade = new OffererTrade(offer, openOfferTradesStorage);
|
OffererAsBuyerTrade offererAsBuyerTrade = new OffererAsBuyerTrade(offer, openOfferTradesStorage);
|
||||||
openOfferTrades.add(offererTrade);
|
openOfferTrades.add(offererAsBuyerTrade);
|
||||||
initTrade(offererTrade);
|
initTrade(offererAsBuyerTrade);
|
||||||
setupDepositPublishedListener(offererTrade);
|
setupDepositPublishedListener(offererAsBuyerTrade);
|
||||||
resultHandler.handleResult(transaction);
|
resultHandler.handleResult(transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupDepositPublishedListener(OffererTrade offererTrade) {
|
private void setupDepositPublishedListener(OffererAsBuyerTrade offererAsBuyerTrade) {
|
||||||
offererTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
|
offererAsBuyerTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
|
||||||
log.debug("offererTrade state = " + newValue);
|
log.debug("OffererAsBuyerTrade state = " + newValue);
|
||||||
if (newValue == OffererTrade.OffererProcessState.DEPOSIT_PUBLISHED) {
|
if (newValue == OffererAsBuyerTrade.ProcessState.DEPOSIT_PUBLISHED) {
|
||||||
removeOpenOffer(offererTrade.getOffer(),
|
removeOpenOffer(offererAsBuyerTrade.getOffer(),
|
||||||
() -> log.debug("remove offer was successful"),
|
() -> log.debug("remove offer was successful"),
|
||||||
log::error,
|
log::error,
|
||||||
false);
|
false);
|
||||||
pendingTrades.add(offererTrade);
|
pendingTrades.add(offererAsBuyerTrade);
|
||||||
offererTrade.setStorage(pendingTradesStorage);
|
offererAsBuyerTrade.setStorage(pendingTradesStorage);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -290,15 +309,15 @@ public class TradeManager {
|
||||||
offerBookService.removeOffer(offer,
|
offerBookService.removeOffer(offer,
|
||||||
() -> {
|
() -> {
|
||||||
offer.setState(Offer.State.REMOVED);
|
offer.setState(Offer.State.REMOVED);
|
||||||
Optional<OffererTrade> offererTradeOptional = openOfferTrades.stream().filter(e -> e.getId().equals(offer.getId())).findAny();
|
Optional<OffererAsBuyerTrade> OffererAsBuyerTradeOptional = openOfferTrades.stream().filter(e -> e.getId().equals(offer.getId())).findAny();
|
||||||
if (offererTradeOptional.isPresent()) {
|
if (OffererAsBuyerTradeOptional.isPresent()) {
|
||||||
OffererTrade offererTrade = offererTradeOptional.get();
|
OffererAsBuyerTrade offererAsBuyerTrade = OffererAsBuyerTradeOptional.get();
|
||||||
openOfferTrades.remove(offererTrade);
|
openOfferTrades.remove(offererAsBuyerTrade);
|
||||||
|
|
||||||
if (isCancelRequest) {
|
if (isCancelRequest) {
|
||||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_CANCELED);
|
offererAsBuyerTrade.setLifeCycleState(OffererAsBuyerTrade.LifeCycleState.OFFER_CANCELED);
|
||||||
closedTrades.add(offererTrade);
|
closedTrades.add(offererAsBuyerTrade);
|
||||||
offererTrade.disposeProtocol();
|
offererAsBuyerTrade.disposeProtocol();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +370,7 @@ public class TradeManager {
|
||||||
takeOfferResultHandler) {
|
takeOfferResultHandler) {
|
||||||
disposeCheckOfferAvailabilityRequest(offer);
|
disposeCheckOfferAvailabilityRequest(offer);
|
||||||
if (offer.getState() == Offer.State.AVAILABLE) {
|
if (offer.getState() == Offer.State.AVAILABLE) {
|
||||||
TakerTrade takerTrade = new TakerTrade(offer, amount, model.getPeer(), pendingTradesStorage);
|
TakerAsSellerTrade takerTrade = new TakerAsSellerTrade(offer, amount, model.getPeer(), pendingTradesStorage);
|
||||||
initTrade(takerTrade);
|
initTrade(takerTrade);
|
||||||
pendingTrades.add(takerTrade);
|
pendingTrades.add(takerTrade);
|
||||||
takerTrade.takeAvailableOffer();
|
takerTrade.takeAvailableOffer();
|
||||||
|
@ -371,7 +390,7 @@ public class TradeManager {
|
||||||
// TODO handle overpaid securityDeposit
|
// TODO handle overpaid securityDeposit
|
||||||
Coin amountToWithdraw = trade.getSecurityDeposit();
|
Coin amountToWithdraw = trade.getSecurityDeposit();
|
||||||
assert trade.getTradeAmount() != null;
|
assert trade.getTradeAmount() != null;
|
||||||
if (trade instanceof OffererTrade)
|
if (trade instanceof OffererAsBuyerTrade)
|
||||||
amountToWithdraw = amountToWithdraw.add(trade.getTradeAmount());
|
amountToWithdraw = amountToWithdraw.add(trade.getTradeAmount());
|
||||||
|
|
||||||
FutureCallback<Transaction> callback = new FutureCallback<Transaction>() {
|
FutureCallback<Transaction> callback = new FutureCallback<Transaction>() {
|
||||||
|
@ -379,10 +398,10 @@ public class TradeManager {
|
||||||
public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
|
public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
|
||||||
if (transaction != null) {
|
if (transaction != null) {
|
||||||
log.info("onWithdraw onSuccess tx ID:" + transaction.getHashAsString());
|
log.info("onWithdraw onSuccess tx ID:" + transaction.getHashAsString());
|
||||||
if (trade instanceof OffererTrade)
|
if (trade instanceof OffererAsBuyerTrade)
|
||||||
((OffererTrade) trade).setLifeCycleState(OffererTrade.OffererLifeCycleState.COMPLETED);
|
((OffererAsBuyerTrade) trade).setLifeCycleState(OffererAsBuyerTrade.LifeCycleState.COMPLETED);
|
||||||
else
|
else
|
||||||
((TakerTrade) trade).setLifeCycleState(TakerTrade.TakerLifeCycleState.COMPLETED);
|
((TakerAsSellerTrade) trade).setLifeCycleState(TakerAsSellerTrade.LifeCycleState.COMPLETED);
|
||||||
|
|
||||||
pendingTrades.remove(trade);
|
pendingTrades.remove(trade);
|
||||||
closedTrades.add(trade);
|
closedTrades.add(trade);
|
||||||
|
@ -421,7 +440,7 @@ public class TradeManager {
|
||||||
// Getters
|
// Getters
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public ObservableList<OffererTrade> getOpenOfferTrades() {
|
public ObservableList<OffererAsBuyerTrade> getOpenOfferTrades() {
|
||||||
return openOfferTrades.getObservableList();
|
return openOfferTrades.getObservableList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.messages;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class ConfirmReserveOfferMessage extends TradeMessage implements Serializable {
|
||||||
|
// That object is sent over the wire, so we need to take care of version compatibility.
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ConfirmReserveOfferMessage.class);
|
||||||
|
|
||||||
|
public ConfirmReserveOfferMessage(String tradeId) {
|
||||||
|
super(tradeId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,20 +30,20 @@ public class FiatTransferStartedMessage extends TradeMessage implements MailboxM
|
||||||
// That object is sent over the wire, so we need to take care of version compatibility.
|
// That object is sent over the wire, so we need to take care of version compatibility.
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public final byte[] offererSignature;
|
public final byte[] buyerSignature;
|
||||||
public final Coin offererPayoutAmount;
|
public final Coin offererPayoutAmount;
|
||||||
public final Coin takerPayoutAmount;
|
public final Coin takerPayoutAmount;
|
||||||
public final String offererPayoutAddress;
|
public final String buyerPayoutAddress;
|
||||||
|
|
||||||
public FiatTransferStartedMessage(String tradeId,
|
public FiatTransferStartedMessage(String tradeId,
|
||||||
byte[] offererSignature,
|
byte[] buyerSignature,
|
||||||
Coin offererPayoutAmount,
|
Coin offererPayoutAmount,
|
||||||
Coin takerPayoutAmount,
|
Coin takerPayoutAmount,
|
||||||
String offererPayoutAddress) {
|
String buyerPayoutAddress) {
|
||||||
super(tradeId);
|
super(tradeId);
|
||||||
this.offererSignature = offererSignature;
|
this.buyerSignature = buyerSignature;
|
||||||
this.offererPayoutAmount = offererPayoutAmount;
|
this.offererPayoutAmount = offererPayoutAmount;
|
||||||
this.takerPayoutAmount = takerPayoutAmount;
|
this.takerPayoutAmount = takerPayoutAmount;
|
||||||
this.offererPayoutAddress = offererPayoutAddress;
|
this.buyerPayoutAddress = buyerPayoutAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.messages;
|
||||||
|
|
||||||
|
import io.bitsquare.fiat.FiatAccount;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.TransactionOutput;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import java.security.PublicKey;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
public class RequestPayDepositMessage extends TradeMessage implements Serializable {
|
||||||
|
// That object is sent over the wire, so we need to take care of version compatibility.
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public final List<TransactionOutput> buyerConnectedOutputsForAllInputs;
|
||||||
|
public final List<TransactionOutput> buyerOutputs;
|
||||||
|
public final byte[] buyerTradeWalletPubKey;
|
||||||
|
public final PublicKey buyerP2PSigPublicKey;
|
||||||
|
public final PublicKey buyerP2PEncryptPublicKey;
|
||||||
|
public final FiatAccount buyerFiatAccount;
|
||||||
|
public final String buyerAccountId;
|
||||||
|
|
||||||
|
public RequestPayDepositMessage(String tradeId,
|
||||||
|
List<TransactionOutput> buyerConnectedOutputsForAllInputs,
|
||||||
|
List<TransactionOutput> buyerOutputs,
|
||||||
|
byte[] buyerTradeWalletPubKey,
|
||||||
|
PublicKey buyerP2PSigPublicKey,
|
||||||
|
PublicKey buyerP2PEncryptPublicKey,
|
||||||
|
FiatAccount buyerFiatAccount,
|
||||||
|
String buyerAccountId) {
|
||||||
|
super(tradeId);
|
||||||
|
this.buyerP2PSigPublicKey = buyerP2PSigPublicKey;
|
||||||
|
this.buyerP2PEncryptPublicKey = buyerP2PEncryptPublicKey;
|
||||||
|
this.buyerConnectedOutputsForAllInputs = buyerConnectedOutputsForAllInputs;
|
||||||
|
this.buyerOutputs = buyerOutputs;
|
||||||
|
this.buyerTradeWalletPubKey = buyerTradeWalletPubKey;
|
||||||
|
this.buyerFiatAccount = buyerFiatAccount;
|
||||||
|
this.buyerAccountId = buyerAccountId;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Bitsquare.
|
|
||||||
*
|
|
||||||
* Bitsquare 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.
|
|
||||||
*
|
|
||||||
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.bitsquare.trade.protocol.trade.messages;
|
|
||||||
|
|
||||||
import io.bitsquare.fiat.FiatAccount;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.TransactionOutput;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import java.security.PublicKey;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
public class RequestTakerDepositPaymentMessage extends TradeMessage implements Serializable {
|
|
||||||
// That object is sent over the wire, so we need to take care of version compatibility.
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public final List<TransactionOutput> offererConnectedOutputsForAllInputs;
|
|
||||||
public final List<TransactionOutput> offererOutputs;
|
|
||||||
public final byte[] offererTradeWalletPubKey;
|
|
||||||
public final PublicKey offererP2PSigPublicKey;
|
|
||||||
public final PublicKey offererP2PEncryptPublicKey;
|
|
||||||
public final FiatAccount offererFiatAccount;
|
|
||||||
public final String offererAccountId;
|
|
||||||
|
|
||||||
public RequestTakerDepositPaymentMessage(String tradeId,
|
|
||||||
List<TransactionOutput> offererConnectedOutputsForAllInputs,
|
|
||||||
List<TransactionOutput> offererOutputs,
|
|
||||||
byte[] offererTradeWalletPubKey,
|
|
||||||
PublicKey offererP2PSigPublicKey,
|
|
||||||
PublicKey offererP2PEncryptPublicKey,
|
|
||||||
FiatAccount offererFiatAccount,
|
|
||||||
String offererAccountId) {
|
|
||||||
super(tradeId);
|
|
||||||
this.offererP2PSigPublicKey = offererP2PSigPublicKey;
|
|
||||||
this.offererP2PEncryptPublicKey = offererP2PEncryptPublicKey;
|
|
||||||
this.offererConnectedOutputsForAllInputs = offererConnectedOutputsForAllInputs;
|
|
||||||
this.offererOutputs = offererOutputs;
|
|
||||||
this.offererTradeWalletPubKey = offererTradeWalletPubKey;
|
|
||||||
this.offererFiatAccount = offererFiatAccount;
|
|
||||||
this.offererAccountId = offererAccountId;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -23,7 +23,7 @@ import io.bitsquare.p2p.Message;
|
||||||
import io.bitsquare.p2p.MessageHandler;
|
import io.bitsquare.p2p.MessageHandler;
|
||||||
import io.bitsquare.p2p.Peer;
|
import io.bitsquare.p2p.Peer;
|
||||||
import io.bitsquare.p2p.listener.SendMessageListener;
|
import io.bitsquare.p2p.listener.SendMessageListener;
|
||||||
import io.bitsquare.trade.OffererTrade;
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
import io.bitsquare.trade.protocol.Protocol;
|
import io.bitsquare.trade.protocol.Protocol;
|
||||||
import io.bitsquare.trade.protocol.availability.messages.ReportOfferAvailabilityMessage;
|
import io.bitsquare.trade.protocol.availability.messages.ReportOfferAvailabilityMessage;
|
||||||
import io.bitsquare.trade.protocol.availability.messages.RequestIsOfferAvailableMessage;
|
import io.bitsquare.trade.protocol.availability.messages.RequestIsOfferAvailableMessage;
|
||||||
|
@ -32,17 +32,17 @@ import io.bitsquare.trade.protocol.trade.messages.RequestDepositTxInputsMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.RequestPublishDepositTxMessage;
|
import io.bitsquare.trade.protocol.trade.messages.RequestPublishDepositTxMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
|
import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.models.OffererProcessModel;
|
import io.bitsquare.trade.protocol.trade.offerer.models.OffererProcessModel;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.CommitPayoutTx;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererCommitsPayoutTx;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.CreateAndSignPayoutTx;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererCreatesAndSignPayoutTx;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.CreateOffererDepositTxInputs;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererCreatesDepositTxInputs;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessPayoutTxPublishedMessage;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererProcessPayoutTxPublishedMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessRequestDepositTxInputsMessage;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererProcessRequestDepositTxInputsMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessRequestPublishDepositTxMessage;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererProcessRequestPublishDepositTxMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendRequestTakerDepositPaymentMessage;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSendsDepositTxPublishedMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendFiatTransferStartedMessage;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSendsFiatTransferStartedMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendDepositTxPublishedMessage;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSendsRequestSellerDepositPaymentMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SignAndPublishDepositTx;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSignsAndPublishDepositTx;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyAndSignContract;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererVerifiesAndSignsContract;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakeOfferFeePayment;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakeOfferFeePayment;
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakerAccount;
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakerAccount;
|
||||||
|
|
||||||
|
@ -51,21 +51,21 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import static io.bitsquare.util.Validator.*;
|
import static io.bitsquare.util.Validator.*;
|
||||||
|
|
||||||
public class OffererProtocol implements Protocol {
|
public class OffererAsBuyerProtocol implements Protocol {
|
||||||
private static final Logger log = LoggerFactory.getLogger(OffererProtocol.class);
|
private static final Logger log = LoggerFactory.getLogger(OffererAsBuyerProtocol.class);
|
||||||
|
|
||||||
private final MessageHandler messageHandler;
|
private MessageHandler messageHandler;
|
||||||
private final OffererTrade offererTrade;
|
private final OffererAsBuyerTrade offererAsBuyerTrade;
|
||||||
private final OffererProcessModel offererTradeProcessModel;
|
private final OffererProcessModel offererTradeProcessModel;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public OffererProtocol(OffererTrade model) {
|
public OffererAsBuyerProtocol(OffererAsBuyerTrade model) {
|
||||||
log.debug("New OffererProtocol " + this);
|
log.debug("New OffererProtocol " + this);
|
||||||
this.offererTrade = model;
|
this.offererAsBuyerTrade = model;
|
||||||
offererTradeProcessModel = offererTrade.getProcessModel();
|
offererTradeProcessModel = offererAsBuyerTrade.getProcessModel();
|
||||||
messageHandler = this::handleMessage;
|
messageHandler = this::handleMessage;
|
||||||
|
|
||||||
offererTradeProcessModel.getMessageService().addMessageHandler(messageHandler);
|
offererTradeProcessModel.getMessageService().addMessageHandler(messageHandler);
|
||||||
|
@ -90,7 +90,10 @@ public class OffererProtocol implements Protocol {
|
||||||
public void cleanup() {
|
public void cleanup() {
|
||||||
log.debug("cleanup " + this);
|
log.debug("cleanup " + this);
|
||||||
|
|
||||||
|
if (messageHandler != null) {
|
||||||
offererTradeProcessModel.getMessageService().removeMessageHandler(messageHandler);
|
offererTradeProcessModel.getMessageService().removeMessageHandler(messageHandler);
|
||||||
|
messageHandler = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -106,7 +109,7 @@ public class OffererProtocol implements Protocol {
|
||||||
// to take the
|
// to take the
|
||||||
// offer
|
// offer
|
||||||
// at the same time
|
// at the same time
|
||||||
boolean isOfferOpen = offererTrade.lifeCycleStateProperty().get() == OffererTrade.OffererLifeCycleState.OFFER_OPEN;
|
boolean isOfferOpen = offererAsBuyerTrade.lifeCycleStateProperty().get() == OffererAsBuyerTrade.LifeCycleState.OFFER_OPEN;
|
||||||
ReportOfferAvailabilityMessage reportOfferAvailabilityMessage = new ReportOfferAvailabilityMessage(offererTradeProcessModel.getId(), isOfferOpen);
|
ReportOfferAvailabilityMessage reportOfferAvailabilityMessage = new ReportOfferAvailabilityMessage(offererTradeProcessModel.getId(), isOfferOpen);
|
||||||
offererTradeProcessModel.getMessageService().sendMessage(sender, reportOfferAvailabilityMessage, new SendMessageListener() {
|
offererTradeProcessModel.getMessageService().sendMessage(sender, reportOfferAvailabilityMessage, new SendMessageListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -131,16 +134,17 @@ public class OffererProtocol implements Protocol {
|
||||||
private void handleRequestDepositTxInputsMessage(RequestDepositTxInputsMessage tradeMessage, Peer taker) {
|
private void handleRequestDepositTxInputsMessage(RequestDepositTxInputsMessage tradeMessage, Peer taker) {
|
||||||
checkTradeId(offererTradeProcessModel.getId(), tradeMessage);
|
checkTradeId(offererTradeProcessModel.getId(), tradeMessage);
|
||||||
offererTradeProcessModel.setTradeMessage(tradeMessage);
|
offererTradeProcessModel.setTradeMessage(tradeMessage);
|
||||||
offererTrade.setTradingPeer(taker);
|
offererAsBuyerTrade.setTradingPeer(taker);
|
||||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_RESERVED);
|
|
||||||
|
|
||||||
TaskRunner<OffererTrade> taskRunner = new TaskRunner<>(offererTrade,
|
offererAsBuyerTrade.setLifeCycleState(OffererAsBuyerTrade.LifeCycleState.OFFER_RESERVED);
|
||||||
|
|
||||||
|
TaskRunner<OffererAsBuyerTrade> taskRunner = new TaskRunner<>(offererAsBuyerTrade,
|
||||||
() -> log.debug("taskRunner at handleRequestDepositTxInputsMessage completed"),
|
() -> log.debug("taskRunner at handleRequestDepositTxInputsMessage completed"),
|
||||||
this::handleTaskRunnerFault);
|
this::handleTaskRunnerFault);
|
||||||
taskRunner.addTasks(
|
taskRunner.addTasks(
|
||||||
ProcessRequestDepositTxInputsMessage.class,
|
OffererProcessRequestDepositTxInputsMessage.class,
|
||||||
CreateOffererDepositTxInputs.class,
|
OffererCreatesDepositTxInputs.class,
|
||||||
SendRequestTakerDepositPaymentMessage.class
|
OffererSendsRequestSellerDepositPaymentMessage.class
|
||||||
);
|
);
|
||||||
taskRunner.run();
|
taskRunner.run();
|
||||||
}
|
}
|
||||||
|
@ -148,15 +152,15 @@ public class OffererProtocol implements Protocol {
|
||||||
private void handleRequestPublishDepositTxMessage(RequestPublishDepositTxMessage tradeMessage) {
|
private void handleRequestPublishDepositTxMessage(RequestPublishDepositTxMessage tradeMessage) {
|
||||||
offererTradeProcessModel.setTradeMessage(tradeMessage);
|
offererTradeProcessModel.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
TaskRunner<OffererTrade> taskRunner = new TaskRunner<>(offererTrade,
|
TaskRunner<OffererAsBuyerTrade> taskRunner = new TaskRunner<>(offererAsBuyerTrade,
|
||||||
() -> log.debug("taskRunner at handleRequestPublishDepositTxMessage completed"),
|
() -> log.debug("taskRunner at handleRequestPublishDepositTxMessage completed"),
|
||||||
this::handleTaskRunnerFault);
|
this::handleTaskRunnerFault);
|
||||||
taskRunner.addTasks(
|
taskRunner.addTasks(
|
||||||
ProcessRequestPublishDepositTxMessage.class,
|
OffererProcessRequestPublishDepositTxMessage.class,
|
||||||
VerifyTakerAccount.class,
|
VerifyTakerAccount.class,
|
||||||
VerifyAndSignContract.class,
|
OffererVerifiesAndSignsContract.class,
|
||||||
SignAndPublishDepositTx.class,
|
OffererSignsAndPublishDepositTx.class,
|
||||||
SendDepositTxPublishedMessage.class
|
OffererSendsDepositTxPublishedMessage.class
|
||||||
);
|
);
|
||||||
taskRunner.run();
|
taskRunner.run();
|
||||||
}
|
}
|
||||||
|
@ -168,13 +172,13 @@ public class OffererProtocol implements Protocol {
|
||||||
|
|
||||||
// User clicked the "bank transfer started" button
|
// User clicked the "bank transfer started" button
|
||||||
public void onFiatPaymentStarted() {
|
public void onFiatPaymentStarted() {
|
||||||
TaskRunner<OffererTrade> taskRunner = new TaskRunner<>(offererTrade,
|
TaskRunner<OffererAsBuyerTrade> taskRunner = new TaskRunner<>(offererAsBuyerTrade,
|
||||||
() -> log.debug("taskRunner at handleBankTransferStartedUIEvent completed"),
|
() -> log.debug("taskRunner at handleBankTransferStartedUIEvent completed"),
|
||||||
this::handleTaskRunnerFault);
|
this::handleTaskRunnerFault);
|
||||||
taskRunner.addTasks(
|
taskRunner.addTasks(
|
||||||
CreateAndSignPayoutTx.class,
|
|
||||||
VerifyTakeOfferFeePayment.class,
|
VerifyTakeOfferFeePayment.class,
|
||||||
SendFiatTransferStartedMessage.class
|
OffererCreatesAndSignPayoutTx.class,
|
||||||
|
OffererSendsFiatTransferStartedMessage.class
|
||||||
);
|
);
|
||||||
taskRunner.run();
|
taskRunner.run();
|
||||||
}
|
}
|
||||||
|
@ -187,7 +191,7 @@ public class OffererProtocol implements Protocol {
|
||||||
private void handlePayoutTxPublishedMessage(PayoutTxPublishedMessage tradeMessage) {
|
private void handlePayoutTxPublishedMessage(PayoutTxPublishedMessage tradeMessage) {
|
||||||
offererTradeProcessModel.setTradeMessage(tradeMessage);
|
offererTradeProcessModel.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
TaskRunner<OffererTrade> taskRunner = new TaskRunner<>(offererTrade,
|
TaskRunner<OffererAsBuyerTrade> taskRunner = new TaskRunner<>(offererAsBuyerTrade,
|
||||||
() -> {
|
() -> {
|
||||||
log.debug("taskRunner at handlePayoutTxPublishedMessage completed");
|
log.debug("taskRunner at handlePayoutTxPublishedMessage completed");
|
||||||
// we are done!
|
// we are done!
|
||||||
|
@ -195,8 +199,8 @@ public class OffererProtocol implements Protocol {
|
||||||
},
|
},
|
||||||
this::handleTaskRunnerFault);
|
this::handleTaskRunnerFault);
|
||||||
|
|
||||||
taskRunner.addTasks(ProcessPayoutTxPublishedMessage.class);
|
taskRunner.addTasks(OffererProcessPayoutTxPublishedMessage.class);
|
||||||
taskRunner.addTasks(CommitPayoutTx.class);
|
taskRunner.addTasks(OffererCommitsPayoutTx.class);
|
||||||
taskRunner.run();
|
taskRunner.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +215,7 @@ public class OffererProtocol implements Protocol {
|
||||||
TradeMessage tradeMessage = (TradeMessage) message;
|
TradeMessage tradeMessage = (TradeMessage) message;
|
||||||
nonEmptyStringOf(tradeMessage.tradeId);
|
nonEmptyStringOf(tradeMessage.tradeId);
|
||||||
|
|
||||||
if (tradeMessage.tradeId.equals(offererTrade.getId())) {
|
if (tradeMessage.tradeId.equals(offererAsBuyerTrade.getId())) {
|
||||||
if (tradeMessage instanceof RequestIsOfferAvailableMessage) {
|
if (tradeMessage instanceof RequestIsOfferAvailableMessage) {
|
||||||
handleRequestIsOfferAvailableMessage((RequestIsOfferAvailableMessage) tradeMessage, sender);
|
handleRequestIsOfferAvailableMessage((RequestIsOfferAvailableMessage) tradeMessage, sender);
|
||||||
}
|
}
|
|
@ -0,0 +1,239 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.offerer;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.p2p.MailboxMessage;
|
||||||
|
import io.bitsquare.p2p.Message;
|
||||||
|
import io.bitsquare.p2p.MessageHandler;
|
||||||
|
import io.bitsquare.p2p.Peer;
|
||||||
|
import io.bitsquare.p2p.listener.SendMessageListener;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
|
import io.bitsquare.trade.protocol.Protocol;
|
||||||
|
import io.bitsquare.trade.protocol.availability.messages.ReportOfferAvailabilityMessage;
|
||||||
|
import io.bitsquare.trade.protocol.availability.messages.RequestIsOfferAvailableMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.RequestPayDepositMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.offerer.models.OffererProcessModel;
|
||||||
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererCommitDepositTx;
|
||||||
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererCreatesAndSignsContract;
|
||||||
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererCreatesAndSignsDepositTx;
|
||||||
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererProcessDepositTxPublishedMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererProcessFiatTransferStartedMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererProcessRequestPayDepositMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSendsPayoutTxPublishedMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSendsRequestPublishDepositTxMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSignsAndPublishPayoutTx;
|
||||||
|
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakerAccount;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOfferFeePayment;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static io.bitsquare.util.Validator.*;
|
||||||
|
|
||||||
|
public class OffererAsSellerProtocol implements Protocol {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(OffererAsSellerProtocol.class);
|
||||||
|
|
||||||
|
private final MessageHandler messageHandler;
|
||||||
|
private final OffererAsSellerTrade offererAsSellerTrade;
|
||||||
|
private final OffererProcessModel offererTradeProcessModel;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public OffererAsSellerProtocol(OffererAsSellerTrade model) {
|
||||||
|
log.debug("New OffererProtocol " + this);
|
||||||
|
this.offererAsSellerTrade = model;
|
||||||
|
offererTradeProcessModel = offererAsSellerTrade.getProcessModel();
|
||||||
|
messageHandler = this::handleMessage;
|
||||||
|
|
||||||
|
offererTradeProcessModel.getMessageService().addMessageHandler(messageHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Public methods
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public void setMailboxMessage(MailboxMessage mailboxMessage) {
|
||||||
|
log.debug("setMailboxMessage " + mailboxMessage);
|
||||||
|
// Might be called twice, so check that its only processed once
|
||||||
|
/* if (offererTradeProcessModel.getMailboxMessage() == null) {
|
||||||
|
offererTradeProcessModel.setMailboxMessage(mailboxMessage);
|
||||||
|
if (mailboxMessage instanceof PayoutTxPublishedMessage) {
|
||||||
|
handlePayoutTxPublishedMessage((PayoutTxPublishedMessage) mailboxMessage);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanup() {
|
||||||
|
log.debug("cleanup " + this);
|
||||||
|
|
||||||
|
offererTradeProcessModel.getMessageService().removeMessageHandler(messageHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Incoming message handling
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// IsOfferAvailable
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void handle(RequestIsOfferAvailableMessage tradeMessage, Peer sender) {
|
||||||
|
try {
|
||||||
|
checkTradeId(offererTradeProcessModel.getId(), tradeMessage);
|
||||||
|
|
||||||
|
// We don't store anything in the offererTradeProcessModel as we might be in a trade process and receive that request from another peer who wants
|
||||||
|
// to take the
|
||||||
|
// offer
|
||||||
|
// at the same time
|
||||||
|
boolean isOfferOpen = offererAsSellerTrade.lifeCycleStateProperty().get() == OffererAsSellerTrade.LifeCycleState.OFFER_OPEN;
|
||||||
|
|
||||||
|
ReportOfferAvailabilityMessage reportOfferAvailabilityMessage = new ReportOfferAvailabilityMessage(offererTradeProcessModel.getId(), isOfferOpen);
|
||||||
|
offererTradeProcessModel.getMessageService().sendMessage(sender, reportOfferAvailabilityMessage, new SendMessageListener() {
|
||||||
|
@Override
|
||||||
|
public void handleResult() {
|
||||||
|
// Offerer does not do anything at that moment. Peer might only watch the offer and does not start a trade.
|
||||||
|
log.trace("ReportOfferAvailabilityMessage successfully arrived at peer");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleFault() {
|
||||||
|
log.warn("Sending ReportOfferAvailabilityMessage failed.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable t) {
|
||||||
|
// We don't handle the error as we might be in a trade process with another trader
|
||||||
|
t.printStackTrace();
|
||||||
|
log.warn("Exception at handleRequestIsOfferAvailableMessage " + t.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Trade
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void handle(RequestPayDepositMessage tradeMessage) {
|
||||||
|
offererTradeProcessModel.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
|
TaskRunner<OffererAsSellerTrade> taskRunner = new TaskRunner<>(offererAsSellerTrade,
|
||||||
|
() -> log.debug("taskRunner at handleTakerDepositPaymentRequestMessage completed"),
|
||||||
|
this::handleTaskRunnerFault);
|
||||||
|
|
||||||
|
taskRunner.addTasks(
|
||||||
|
OffererProcessRequestPayDepositMessage.class,
|
||||||
|
VerifyTakerAccount.class,
|
||||||
|
OffererCreatesAndSignsContract.class,
|
||||||
|
OffererCreatesAndSignsDepositTx.class,
|
||||||
|
OffererSendsRequestPublishDepositTxMessage.class
|
||||||
|
);
|
||||||
|
taskRunner.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handle(DepositTxPublishedMessage tradeMessage) {
|
||||||
|
offererTradeProcessModel.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
|
TaskRunner<OffererAsSellerTrade> taskRunner = new TaskRunner<>(offererAsSellerTrade,
|
||||||
|
() -> log.debug("taskRunner at handleDepositTxPublishedMessage completed"),
|
||||||
|
this::handleTaskRunnerFault);
|
||||||
|
|
||||||
|
taskRunner.addTasks(
|
||||||
|
OffererProcessDepositTxPublishedMessage.class,
|
||||||
|
OffererCommitDepositTx.class
|
||||||
|
);
|
||||||
|
taskRunner.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handle(FiatTransferStartedMessage tradeMessage) {
|
||||||
|
offererTradeProcessModel.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
|
TaskRunner<OffererAsSellerTrade> taskRunner = new TaskRunner<>(offererAsSellerTrade,
|
||||||
|
() -> log.debug("taskRunner at handleFiatTransferStartedMessage completed"),
|
||||||
|
this::handleTaskRunnerFault);
|
||||||
|
|
||||||
|
taskRunner.addTasks(OffererProcessFiatTransferStartedMessage.class);
|
||||||
|
taskRunner.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Called from UI
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// User clicked the "bank transfer received" button, so we release the funds for pay out
|
||||||
|
public void onFiatPaymentReceived() {
|
||||||
|
offererAsSellerTrade.setProcessState(OffererAsSellerTrade.ProcessState.FIAT_PAYMENT_RECEIVED);
|
||||||
|
|
||||||
|
TaskRunner<OffererAsSellerTrade> taskRunner = new TaskRunner<>(offererAsSellerTrade,
|
||||||
|
() -> {
|
||||||
|
log.debug("taskRunner at handleFiatReceivedUIEvent completed");
|
||||||
|
|
||||||
|
// we are done!
|
||||||
|
offererTradeProcessModel.onComplete();
|
||||||
|
},
|
||||||
|
this::handleTaskRunnerFault);
|
||||||
|
|
||||||
|
taskRunner.addTasks(
|
||||||
|
VerifyOfferFeePayment.class,
|
||||||
|
OffererSignsAndPublishPayoutTx.class,
|
||||||
|
OffererSendsPayoutTxPublishedMessage.class
|
||||||
|
);
|
||||||
|
taskRunner.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Massage dispatcher
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void handleMessage(Message message, Peer sender) {
|
||||||
|
log.trace("handleNewMessage: message = " + message.getClass().getSimpleName() + " from " + sender);
|
||||||
|
if (message instanceof TradeMessage) {
|
||||||
|
TradeMessage tradeMessage = (TradeMessage) message;
|
||||||
|
nonEmptyStringOf(tradeMessage.tradeId);
|
||||||
|
if (tradeMessage.tradeId.equals(offererAsSellerTrade.getId())) {
|
||||||
|
if (tradeMessage instanceof RequestIsOfferAvailableMessage) {
|
||||||
|
handle((RequestIsOfferAvailableMessage) tradeMessage, sender);
|
||||||
|
}
|
||||||
|
else if (tradeMessage instanceof RequestPayDepositMessage) {
|
||||||
|
handle((RequestPayDepositMessage) tradeMessage);
|
||||||
|
}
|
||||||
|
else if (tradeMessage instanceof DepositTxPublishedMessage) {
|
||||||
|
handle((DepositTxPublishedMessage) tradeMessage);
|
||||||
|
}
|
||||||
|
else if (tradeMessage instanceof FiatTransferStartedMessage) {
|
||||||
|
handle((FiatTransferStartedMessage) tradeMessage);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.error("Incoming tradeMessage not supported. " + tradeMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleTaskRunnerFault(String errorMessage) {
|
||||||
|
log.error(errorMessage);
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ import io.bitsquare.offer.Offer;
|
||||||
import io.bitsquare.user.User;
|
import io.bitsquare.user.User;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
import org.bitcoinj.core.Transaction;
|
||||||
import org.bitcoinj.core.TransactionOutput;
|
import org.bitcoinj.core.TransactionOutput;
|
||||||
import org.bitcoinj.crypto.DeterministicKey;
|
import org.bitcoinj.crypto.DeterministicKey;
|
||||||
|
|
||||||
|
@ -36,8 +37,6 @@ import java.security.PublicKey;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -57,7 +56,8 @@ public class Offerer implements Serializable {
|
||||||
private Coin payoutAmount;
|
private Coin payoutAmount;
|
||||||
private List<TransactionOutput> connectedOutputsForAllInputs;
|
private List<TransactionOutput> connectedOutputsForAllInputs;
|
||||||
private List<TransactionOutput> outputs; // used to verify amounts with change outputs
|
private List<TransactionOutput> outputs; // used to verify amounts with change outputs
|
||||||
|
private Transaction preparedDepositTx;
|
||||||
|
private PublicKey p2pSigPublicKey;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor, initialization
|
// Constructor, initialization
|
||||||
|
@ -99,6 +99,10 @@ public class Offerer implements Serializable {
|
||||||
return user.getP2PSigPubKey();
|
return user.getP2PSigPubKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PublicKey getP2pEncryptPublicKey() {
|
||||||
|
return user.getP2PEncryptPubKey();
|
||||||
|
}
|
||||||
|
|
||||||
public PublicKey getP2pEncryptPubKey() {
|
public PublicKey getP2pEncryptPubKey() {
|
||||||
return user.getP2PEncryptPubKey();
|
return user.getP2PEncryptPubKey();
|
||||||
}
|
}
|
||||||
|
@ -124,7 +128,7 @@ public class Offerer implements Serializable {
|
||||||
// Getter/Setter for Mutable objects
|
// Getter/Setter for Mutable objects
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public List<TransactionOutput> getOutputs() {
|
public List<TransactionOutput> getOutputs() {
|
||||||
return outputs;
|
return outputs;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +137,6 @@ public class Offerer implements Serializable {
|
||||||
this.outputs = outputs;
|
this.outputs = outputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public byte[] getPayoutTxSignature() {
|
public byte[] getPayoutTxSignature() {
|
||||||
return payoutTxSignature;
|
return payoutTxSignature;
|
||||||
}
|
}
|
||||||
|
@ -142,7 +145,6 @@ public class Offerer implements Serializable {
|
||||||
this.payoutTxSignature = payoutTxSignature;
|
this.payoutTxSignature = payoutTxSignature;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Coin getPayoutAmount() {
|
public Coin getPayoutAmount() {
|
||||||
return payoutAmount;
|
return payoutAmount;
|
||||||
}
|
}
|
||||||
|
@ -151,7 +153,6 @@ public class Offerer implements Serializable {
|
||||||
this.payoutAmount = payoutAmount;
|
this.payoutAmount = payoutAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public List<TransactionOutput> getConnectedOutputsForAllInputs() {
|
public List<TransactionOutput> getConnectedOutputsForAllInputs() {
|
||||||
return connectedOutputsForAllInputs;
|
return connectedOutputsForAllInputs;
|
||||||
}
|
}
|
||||||
|
@ -160,6 +161,22 @@ public class Offerer implements Serializable {
|
||||||
this.connectedOutputsForAllInputs = connectedOutputsForAllInputs;
|
this.connectedOutputsForAllInputs = connectedOutputsForAllInputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Transaction getPreparedDepositTx() {
|
||||||
|
return preparedDepositTx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreparedDepositTx(Transaction preparedDepositTx) {
|
||||||
|
this.preparedDepositTx = preparedDepositTx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PublicKey getP2pSigPublicKey() {
|
||||||
|
return p2pSigPublicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setP2pSigPublicKey(PublicKey p2pSigPublicKey) {
|
||||||
|
this.p2pSigPublicKey = p2pSigPublicKey;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Offerer{" +
|
return "Offerer{" +
|
||||||
|
@ -172,4 +189,6 @@ public class Offerer implements Serializable {
|
||||||
", outputs=" + outputs +
|
", outputs=" + outputs +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@ import io.bitsquare.p2p.MessageService;
|
||||||
import io.bitsquare.trade.protocol.trade.ProcessModel;
|
import io.bitsquare.trade.protocol.trade.ProcessModel;
|
||||||
import io.bitsquare.user.User;
|
import io.bitsquare.user.User;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Transaction;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@ -47,6 +49,7 @@ public class OffererProcessModel extends ProcessModel implements Serializable {
|
||||||
|
|
||||||
// Mutable
|
// Mutable
|
||||||
private String takeOfferFeeTxId;
|
private String takeOfferFeeTxId;
|
||||||
|
private Transaction payoutTx;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -99,6 +102,13 @@ public class OffererProcessModel extends ProcessModel implements Serializable {
|
||||||
this.takeOfferFeeTxId = takeOfferFeeTxId;
|
this.takeOfferFeeTxId = takeOfferFeeTxId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Transaction getPayoutTx() {
|
||||||
|
return payoutTx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPayoutTx(Transaction payoutTx) {
|
||||||
|
this.payoutTx = payoutTx;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -108,4 +118,6 @@ public class OffererProcessModel extends ProcessModel implements Serializable {
|
||||||
", takeOfferFeeTxId='" + takeOfferFeeTxId + '\'' +
|
", takeOfferFeeTxId='" + takeOfferFeeTxId + '\'' +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class Taker implements Serializable {
|
||||||
// Mutable
|
// Mutable
|
||||||
private String accountId;
|
private String accountId;
|
||||||
private FiatAccount fiatAccount;
|
private FiatAccount fiatAccount;
|
||||||
private PublicKey p2pSigPublicKey;
|
private PublicKey p2pSigPubKey;
|
||||||
private PublicKey p2pEncryptPubKey;
|
private PublicKey p2pEncryptPubKey;
|
||||||
private String contractAsJson;
|
private String contractAsJson;
|
||||||
private String contractSignature;
|
private String contractSignature;
|
||||||
|
@ -53,7 +53,8 @@ public class Taker implements Serializable {
|
||||||
private List<TransactionOutput> connectedOutputsForAllInputs;
|
private List<TransactionOutput> connectedOutputsForAllInputs;
|
||||||
private String payoutAddressString;
|
private String payoutAddressString;
|
||||||
private byte[] tradeWalletPubKey;
|
private byte[] tradeWalletPubKey;
|
||||||
|
private List<TransactionOutput> outputs;
|
||||||
|
private byte[] signature;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor, initialization
|
// Constructor, initialization
|
||||||
|
@ -89,12 +90,12 @@ public class Taker implements Serializable {
|
||||||
this.fiatAccount = fiatAccount;
|
this.fiatAccount = fiatAccount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PublicKey getP2pSigPublicKey() {
|
public PublicKey getP2pSigPubKey() {
|
||||||
return p2pSigPublicKey;
|
return p2pSigPubKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setP2pSigPublicKey(PublicKey p2pSigPublicKey) {
|
public void setP2pSigPubKey(PublicKey p2pSigPubKey) {
|
||||||
this.p2pSigPublicKey = p2pSigPublicKey;
|
this.p2pSigPubKey = p2pSigPubKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PublicKey getP2pEncryptPubKey() {
|
public PublicKey getP2pEncryptPubKey() {
|
||||||
|
@ -161,13 +162,28 @@ public class Taker implements Serializable {
|
||||||
this.tradeWalletPubKey = tradeWalletPubKey;
|
this.tradeWalletPubKey = tradeWalletPubKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<TransactionOutput> getOutputs() {
|
||||||
|
return outputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOutputs(List<TransactionOutput> outputs) {
|
||||||
|
this.outputs = outputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getSignature() {
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSignature(byte[] signature) {
|
||||||
|
this.signature = signature;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Taker{" +
|
return "Taker{" +
|
||||||
"accountId='" + accountId + '\'' +
|
"accountId='" + accountId + '\'' +
|
||||||
", fiatAccount=" + fiatAccount +
|
", fiatAccount=" + fiatAccount +
|
||||||
", p2pSigPublicKey=" + p2pSigPublicKey +
|
", p2pSigPublicKey=" + p2pSigPubKey +
|
||||||
", p2pEncryptPubKey=" + p2pEncryptPubKey +
|
", p2pEncryptPubKey=" + p2pEncryptPubKey +
|
||||||
", contractAsJson='" + contractAsJson + '\'' +
|
", contractAsJson='" + contractAsJson + '\'' +
|
||||||
", contractSignature='" + contractSignature + '\'' +
|
", contractSignature='" + contractSignature + '\'' +
|
||||||
|
@ -178,4 +194,6 @@ public class Taker implements Serializable {
|
||||||
", tradeWalletPubKey=" + Arrays.toString(tradeWalletPubKey) +
|
", tradeWalletPubKey=" + Arrays.toString(tradeWalletPubKey) +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.OffererTrade;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Transaction;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class OffererCommitDepositTx extends OffererTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(OffererCommitDepositTx.class);
|
||||||
|
|
||||||
|
public OffererCommitDepositTx(TaskRunner taskHandler, OffererTrade model) {
|
||||||
|
super(taskHandler, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
// To access tx confidence we need to add that tx into our wallet.
|
||||||
|
Transaction depositTx = offererTradeProcessModel.getTradeWalletService().commitTx(offererTrade.getDepositTx());
|
||||||
|
|
||||||
|
offererTrade.setDepositTx(depositTx);
|
||||||
|
|
||||||
|
complete();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
offererTrade.setThrowable(t);
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,10 +25,10 @@ import org.bitcoinj.core.Transaction;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class CommitPayoutTx extends OffererTradeTask {
|
public class OffererCommitsPayoutTx extends OffererTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(CommitPayoutTx.class);
|
private static final Logger log = LoggerFactory.getLogger(OffererCommitsPayoutTx.class);
|
||||||
|
|
||||||
public CommitPayoutTx(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
public OffererCommitsPayoutTx(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||||
super(taskHandler, offererTradeProcessModel);
|
super(taskHandler, offererTradeProcessModel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.offer.Offer;
|
||||||
import io.bitsquare.trade.OffererTrade;
|
import io.bitsquare.trade.OffererTrade;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
@ -25,10 +26,10 @@ import org.bitcoinj.core.Coin;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class CreateAndSignPayoutTx extends OffererTradeTask {
|
public class OffererCreatesAndSignPayoutTx extends OffererTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(CreateAndSignPayoutTx.class);
|
private static final Logger log = LoggerFactory.getLogger(OffererCreatesAndSignPayoutTx.class);
|
||||||
|
|
||||||
public CreateAndSignPayoutTx(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
public OffererCreatesAndSignPayoutTx(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||||
super(taskHandler, offererTradeProcessModel);
|
super(taskHandler, offererTradeProcessModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,10 +38,16 @@ public class CreateAndSignPayoutTx extends OffererTradeTask {
|
||||||
try {
|
try {
|
||||||
assert offererTrade.getTradeAmount() != null;
|
assert offererTrade.getTradeAmount() != null;
|
||||||
Coin securityDeposit = offererTrade.getSecurityDeposit();
|
Coin securityDeposit = offererTrade.getSecurityDeposit();
|
||||||
Coin offererPayoutAmount = offererTrade.getTradeAmount().add(securityDeposit);
|
|
||||||
@SuppressWarnings("UnnecessaryLocalVariable") Coin takerPayoutAmount = securityDeposit;
|
|
||||||
|
|
||||||
byte[] offererPayoutTxSignature = offererTradeProcessModel.getTradeWalletService().offererCreatesAndSignsPayoutTx(
|
Coin offererPayoutAmount = securityDeposit;
|
||||||
|
if (offererTrade.getOffer().getDirection() == Offer.Direction.BUY)
|
||||||
|
offererPayoutAmount = offererPayoutAmount.add(offererTrade.getTradeAmount());
|
||||||
|
|
||||||
|
Coin takerPayoutAmount = securityDeposit;
|
||||||
|
if (offererTrade.getOffer().getDirection() == Offer.Direction.SELL)
|
||||||
|
takerPayoutAmount = takerPayoutAmount.add(offererTrade.getTradeAmount());
|
||||||
|
|
||||||
|
byte[] offererPayoutTxSignature = offererTradeProcessModel.getTradeWalletService().createAndSignPayoutTx(
|
||||||
offererTrade.getDepositTx(),
|
offererTrade.getDepositTx(),
|
||||||
offererPayoutAmount,
|
offererPayoutAmount,
|
||||||
takerPayoutAmount,
|
takerPayoutAmount,
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.Contract;
|
||||||
|
import io.bitsquare.trade.OffererTrade;
|
||||||
|
import io.bitsquare.util.Utilities;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class OffererCreatesAndSignsContract extends OffererTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(OffererCreatesAndSignsContract.class);
|
||||||
|
|
||||||
|
public OffererCreatesAndSignsContract(TaskRunner taskHandler, OffererTrade model) {
|
||||||
|
super(taskHandler, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
assert offererTradeProcessModel.getTakeOfferFeeTxId() != null;
|
||||||
|
Contract contract = new Contract(
|
||||||
|
offererTradeProcessModel.getOffer(),
|
||||||
|
model.getTradeAmount(),
|
||||||
|
offererTradeProcessModel.getTakeOfferFeeTxId(),
|
||||||
|
offererTradeProcessModel.offerer.getAccountId(),
|
||||||
|
offererTradeProcessModel.offerer.getAccountId(),
|
||||||
|
offererTradeProcessModel.offerer.getFiatAccount(),
|
||||||
|
offererTradeProcessModel.offerer.getFiatAccount(),
|
||||||
|
offererTradeProcessModel.getOffer().getP2PSigPubKey(),
|
||||||
|
offererTradeProcessModel.offerer.getP2pSigPubKey());
|
||||||
|
String contractAsJson = Utilities.objectToJson(contract);
|
||||||
|
String signature = offererTradeProcessModel.getSignatureService().signMessage(offererTradeProcessModel.offerer.getRegistrationKeyPair(),
|
||||||
|
contractAsJson);
|
||||||
|
|
||||||
|
model.setContract(contract);
|
||||||
|
model.setContractAsJson(contractAsJson);
|
||||||
|
model.setOffererContractSignature(signature);
|
||||||
|
|
||||||
|
complete();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
offererTrade.setThrowable(t);
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.btc.FeePolicy;
|
||||||
|
import io.bitsquare.btc.TradeWalletService;
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.OffererTrade;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Coin;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class OffererCreatesAndSignsDepositTx extends OffererTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(OffererCreatesAndSignsDepositTx.class);
|
||||||
|
|
||||||
|
public OffererCreatesAndSignsDepositTx(TaskRunner taskHandler, OffererTrade model) {
|
||||||
|
super(taskHandler, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
assert offererTrade.getTradeAmount() != null;
|
||||||
|
Coin offererInputAmount = offererTrade.getSecurityDeposit().add(FeePolicy.TX_FEE).add(offererTrade.getTradeAmount());
|
||||||
|
Coin msOutputAmount = offererInputAmount.add(offererTrade.getSecurityDeposit());
|
||||||
|
|
||||||
|
TradeWalletService.Result result = offererTradeProcessModel.getTradeWalletService().takerCreatesAndSignsDepositTx(
|
||||||
|
offererInputAmount,
|
||||||
|
msOutputAmount,
|
||||||
|
offererTradeProcessModel.taker.getConnectedOutputsForAllInputs(),
|
||||||
|
offererTradeProcessModel.taker.getOutputs(),
|
||||||
|
offererTradeProcessModel.offerer.getAddressEntry(),
|
||||||
|
offererTradeProcessModel.taker.getTradeWalletPubKey(),
|
||||||
|
offererTradeProcessModel.offerer.getTradeWalletPubKey(),
|
||||||
|
offererTradeProcessModel.getArbitratorPubKey());
|
||||||
|
|
||||||
|
|
||||||
|
offererTradeProcessModel.offerer.setConnectedOutputsForAllInputs(result.getConnectedOutputsForAllInputs());
|
||||||
|
offererTradeProcessModel.offerer.setPreparedDepositTx(result.getDepositTx());
|
||||||
|
|
||||||
|
complete();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
offererTrade.setThrowable(t);
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,8 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
import io.bitsquare.btc.FeePolicy;
|
import io.bitsquare.btc.FeePolicy;
|
||||||
import io.bitsquare.btc.TradeWalletService;
|
import io.bitsquare.btc.TradeWalletService;
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
import io.bitsquare.trade.OffererTrade;
|
import io.bitsquare.trade.OffererTrade;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
@ -27,10 +29,10 @@ import org.bitcoinj.core.Coin;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class CreateOffererDepositTxInputs extends OffererTradeTask {
|
public class OffererCreatesDepositTxInputs extends OffererTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(CreateOffererDepositTxInputs.class);
|
private static final Logger log = LoggerFactory.getLogger(OffererCreatesDepositTxInputs.class);
|
||||||
|
|
||||||
public CreateOffererDepositTxInputs(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
public OffererCreatesDepositTxInputs(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||||
super(taskHandler, offererTradeProcessModel);
|
super(taskHandler, offererTradeProcessModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,8 +40,8 @@ public class CreateOffererDepositTxInputs extends OffererTradeTask {
|
||||||
protected void doRun() {
|
protected void doRun() {
|
||||||
try {
|
try {
|
||||||
log.debug("offererTrade.id" + offererTrade.getId());
|
log.debug("offererTrade.id" + offererTrade.getId());
|
||||||
Coin offererInputAmount = offererTrade.getSecurityDeposit().add(FeePolicy.TX_FEE);
|
Coin inputAmount = offererTrade.getSecurityDeposit().add(FeePolicy.TX_FEE);
|
||||||
TradeWalletService.Result result = offererTradeProcessModel.getTradeWalletService().createOffererDepositTxInputs(offererInputAmount,
|
TradeWalletService.Result result = offererTradeProcessModel.getTradeWalletService().createOffererDepositTxInputs(inputAmount,
|
||||||
offererTradeProcessModel.offerer.getAddressEntry());
|
offererTradeProcessModel.offerer.getAddressEntry());
|
||||||
|
|
||||||
offererTradeProcessModel.offerer.setConnectedOutputsForAllInputs(result.getConnectedOutputsForAllInputs());
|
offererTradeProcessModel.offerer.setConnectedOutputsForAllInputs(result.getConnectedOutputsForAllInputs());
|
||||||
|
@ -49,7 +51,14 @@ public class CreateOffererDepositTxInputs extends OffererTradeTask {
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
offererTrade.setThrowable(t);
|
offererTrade.setThrowable(t);
|
||||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade) {
|
||||||
|
offererTrade.setLifeCycleState(OffererAsSellerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
}
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade) {
|
||||||
|
offererTrade.setLifeCycleState(OffererAsSellerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
}
|
||||||
|
|
||||||
failed(t);
|
failed(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
|
import io.bitsquare.trade.OffererTrade;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static io.bitsquare.util.Validator.checkTradeId;
|
||||||
|
|
||||||
|
public class OffererProcessDepositTxPublishedMessage extends OffererTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(OffererProcessDepositTxPublishedMessage.class);
|
||||||
|
|
||||||
|
public OffererProcessDepositTxPublishedMessage(TaskRunner taskHandler, OffererTrade model) {
|
||||||
|
super(taskHandler, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
DepositTxPublishedMessage message = (DepositTxPublishedMessage) offererTradeProcessModel.getTradeMessage();
|
||||||
|
checkTradeId(offererTradeProcessModel.getId(), message);
|
||||||
|
checkNotNull(message);
|
||||||
|
|
||||||
|
offererTrade.setDepositTx(checkNotNull(message.depositTx));
|
||||||
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade)
|
||||||
|
offererTrade.setProcessState(OffererAsBuyerTrade.ProcessState.DEPOSIT_PUBLISHED);
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade)
|
||||||
|
offererTrade.setProcessState(OffererAsSellerTrade.ProcessState.DEPOSIT_PUBLISHED);
|
||||||
|
|
||||||
|
complete();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
offererTrade.setThrowable(t);
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
|
import io.bitsquare.trade.OffererTrade;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static io.bitsquare.util.Validator.*;
|
||||||
|
|
||||||
|
public class OffererProcessFiatTransferStartedMessage extends OffererTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(OffererProcessFiatTransferStartedMessage.class);
|
||||||
|
|
||||||
|
public OffererProcessFiatTransferStartedMessage(TaskRunner taskHandler, OffererTrade model) {
|
||||||
|
super(taskHandler, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
FiatTransferStartedMessage message = (FiatTransferStartedMessage) offererTradeProcessModel.getTradeMessage();
|
||||||
|
checkTradeId(offererTradeProcessModel.getId(), message);
|
||||||
|
checkNotNull(message);
|
||||||
|
|
||||||
|
offererTradeProcessModel.taker.setSignature(checkNotNull(message.buyerSignature));
|
||||||
|
offererTradeProcessModel.offerer.setPayoutAmount(positiveCoinOf(nonZeroCoinOf(message.offererPayoutAmount)));
|
||||||
|
offererTradeProcessModel.taker.setPayoutAmount(positiveCoinOf(nonZeroCoinOf(message.offererPayoutAmount)));
|
||||||
|
offererTradeProcessModel.taker.setPayoutAddressString(nonEmptyStringOf(message.buyerPayoutAddress));
|
||||||
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade)
|
||||||
|
offererTrade.setProcessState(OffererAsBuyerTrade.ProcessState.FIAT_PAYMENT_STARTED);
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade)
|
||||||
|
offererTrade.setProcessState(OffererAsSellerTrade.ProcessState.FIAT_PAYMENT_STARTED);
|
||||||
|
|
||||||
|
complete();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
offererTrade.setThrowable(t);
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,8 @@
|
||||||
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
import io.bitsquare.trade.OffererTrade;
|
import io.bitsquare.trade.OffererTrade;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
|
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
|
||||||
|
|
||||||
|
@ -27,10 +29,10 @@ import org.slf4j.LoggerFactory;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static io.bitsquare.util.Validator.checkTradeId;
|
import static io.bitsquare.util.Validator.checkTradeId;
|
||||||
|
|
||||||
public class ProcessPayoutTxPublishedMessage extends OffererTradeTask {
|
public class OffererProcessPayoutTxPublishedMessage extends OffererTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(ProcessPayoutTxPublishedMessage.class);
|
private static final Logger log = LoggerFactory.getLogger(OffererProcessPayoutTxPublishedMessage.class);
|
||||||
|
|
||||||
public ProcessPayoutTxPublishedMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
public OffererProcessPayoutTxPublishedMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||||
super(taskHandler, offererTradeProcessModel);
|
super(taskHandler, offererTradeProcessModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +45,10 @@ public class ProcessPayoutTxPublishedMessage extends OffererTradeTask {
|
||||||
|
|
||||||
offererTrade.setPayoutTx(checkNotNull(message.payoutTx));
|
offererTrade.setPayoutTx(checkNotNull(message.payoutTx));
|
||||||
|
|
||||||
offererTrade.setProcessState(OffererTrade.OffererProcessState.PAYOUT_PUBLISHED);
|
if (offererTrade instanceof OffererAsBuyerTrade)
|
||||||
|
offererTrade.setProcessState(OffererAsBuyerTrade.ProcessState.PAYOUT_PUBLISHED);
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade)
|
||||||
|
offererTrade.setProcessState(OffererAsSellerTrade.ProcessState.PAYOUT_PUBLISHED);
|
||||||
|
|
||||||
complete();
|
complete();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
|
@ -18,6 +18,8 @@
|
||||||
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
import io.bitsquare.trade.OffererTrade;
|
import io.bitsquare.trade.OffererTrade;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.RequestDepositTxInputsMessage;
|
import io.bitsquare.trade.protocol.trade.messages.RequestDepositTxInputsMessage;
|
||||||
|
|
||||||
|
@ -27,10 +29,10 @@ import org.slf4j.LoggerFactory;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static io.bitsquare.util.Validator.*;
|
import static io.bitsquare.util.Validator.*;
|
||||||
|
|
||||||
public class ProcessRequestDepositTxInputsMessage extends OffererTradeTask {
|
public class OffererProcessRequestDepositTxInputsMessage extends OffererTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(ProcessRequestDepositTxInputsMessage.class);
|
private static final Logger log = LoggerFactory.getLogger(OffererProcessRequestDepositTxInputsMessage.class);
|
||||||
|
|
||||||
public ProcessRequestDepositTxInputsMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
public OffererProcessRequestDepositTxInputsMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||||
super(taskHandler, offererTradeProcessModel);
|
super(taskHandler, offererTradeProcessModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +51,12 @@ public class ProcessRequestDepositTxInputsMessage extends OffererTradeTask {
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
offererTrade.setThrowable(t);
|
offererTrade.setThrowable(t);
|
||||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade)
|
||||||
|
offererTrade.setLifeCycleState(OffererAsBuyerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade)
|
||||||
|
offererTrade.setLifeCycleState(OffererAsSellerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
|
||||||
failed(t);
|
failed(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.OffererTrade;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.RequestPayDepositMessage;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.*;
|
||||||
|
import static io.bitsquare.util.Validator.*;
|
||||||
|
|
||||||
|
public class OffererProcessRequestPayDepositMessage extends OffererTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(OffererProcessRequestPayDepositMessage.class);
|
||||||
|
|
||||||
|
public OffererProcessRequestPayDepositMessage(TaskRunner taskHandler, OffererTrade model) {
|
||||||
|
super(taskHandler, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
RequestPayDepositMessage message = (RequestPayDepositMessage) offererTradeProcessModel.getTradeMessage();
|
||||||
|
checkTradeId(offererTradeProcessModel.getId(), message);
|
||||||
|
checkNotNull(message);
|
||||||
|
|
||||||
|
offererTradeProcessModel.taker.setConnectedOutputsForAllInputs(checkNotNull(message.buyerConnectedOutputsForAllInputs));
|
||||||
|
checkArgument(message.buyerConnectedOutputsForAllInputs.size() > 0);
|
||||||
|
offererTradeProcessModel.taker.setOutputs(checkNotNull(message.buyerOutputs));
|
||||||
|
offererTradeProcessModel.taker.setTradeWalletPubKey(checkNotNull(message.buyerTradeWalletPubKey));
|
||||||
|
offererTradeProcessModel.taker.setP2pSigPubKey(checkNotNull(message.buyerP2PSigPublicKey));
|
||||||
|
offererTradeProcessModel.taker.setP2pEncryptPubKey(checkNotNull(message.buyerP2PEncryptPublicKey));
|
||||||
|
offererTradeProcessModel.taker.setFiatAccount(checkNotNull(message.buyerFiatAccount));
|
||||||
|
offererTradeProcessModel.taker.setAccountId(nonEmptyStringOf(message.buyerAccountId));
|
||||||
|
|
||||||
|
complete();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
offererTrade.setThrowable(t);
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,8 @@
|
||||||
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
import io.bitsquare.trade.OffererTrade;
|
import io.bitsquare.trade.OffererTrade;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.RequestPublishDepositTxMessage;
|
import io.bitsquare.trade.protocol.trade.messages.RequestPublishDepositTxMessage;
|
||||||
|
|
||||||
|
@ -27,10 +29,10 @@ import org.slf4j.LoggerFactory;
|
||||||
import static com.google.common.base.Preconditions.*;
|
import static com.google.common.base.Preconditions.*;
|
||||||
import static io.bitsquare.util.Validator.*;
|
import static io.bitsquare.util.Validator.*;
|
||||||
|
|
||||||
public class ProcessRequestPublishDepositTxMessage extends OffererTradeTask {
|
public class OffererProcessRequestPublishDepositTxMessage extends OffererTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(ProcessRequestPublishDepositTxMessage.class);
|
private static final Logger log = LoggerFactory.getLogger(OffererProcessRequestPublishDepositTxMessage.class);
|
||||||
|
|
||||||
public ProcessRequestPublishDepositTxMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
public OffererProcessRequestPublishDepositTxMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||||
super(taskHandler, offererTradeProcessModel);
|
super(taskHandler, offererTradeProcessModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +45,7 @@ public class ProcessRequestPublishDepositTxMessage extends OffererTradeTask {
|
||||||
|
|
||||||
offererTradeProcessModel.taker.setFiatAccount(checkNotNull(message.takerFiatAccount));
|
offererTradeProcessModel.taker.setFiatAccount(checkNotNull(message.takerFiatAccount));
|
||||||
offererTradeProcessModel.taker.setAccountId(nonEmptyStringOf(message.takerAccountId));
|
offererTradeProcessModel.taker.setAccountId(nonEmptyStringOf(message.takerAccountId));
|
||||||
offererTradeProcessModel.taker.setP2pSigPublicKey(checkNotNull(message.takerP2PSigPublicKey));
|
offererTradeProcessModel.taker.setP2pSigPubKey(checkNotNull(message.takerP2PSigPublicKey));
|
||||||
offererTradeProcessModel.taker.setP2pEncryptPubKey(checkNotNull(message.takerP2PEncryptPublicKey));
|
offererTradeProcessModel.taker.setP2pEncryptPubKey(checkNotNull(message.takerP2PEncryptPublicKey));
|
||||||
offererTradeProcessModel.taker.setContractAsJson(nonEmptyStringOf(message.takerContractAsJson));
|
offererTradeProcessModel.taker.setContractAsJson(nonEmptyStringOf(message.takerContractAsJson));
|
||||||
offererTradeProcessModel.taker.setContractSignature(nonEmptyStringOf(message.takerContractSignature));
|
offererTradeProcessModel.taker.setContractSignature(nonEmptyStringOf(message.takerContractSignature));
|
||||||
|
@ -56,7 +58,12 @@ public class ProcessRequestPublishDepositTxMessage extends OffererTradeTask {
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
offererTrade.setThrowable(t);
|
offererTrade.setThrowable(t);
|
||||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade)
|
||||||
|
offererTrade.setLifeCycleState(OffererAsBuyerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade)
|
||||||
|
offererTrade.setLifeCycleState(OffererAsSellerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
|
||||||
failed(t);
|
failed(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,16 +19,18 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
import io.bitsquare.p2p.listener.SendMessageListener;
|
import io.bitsquare.p2p.listener.SendMessageListener;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
import io.bitsquare.trade.OffererTrade;
|
import io.bitsquare.trade.OffererTrade;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
|
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class SendDepositTxPublishedMessage extends OffererTradeTask {
|
public class OffererSendsDepositTxPublishedMessage extends OffererTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(SendDepositTxPublishedMessage.class);
|
private static final Logger log = LoggerFactory.getLogger(OffererSendsDepositTxPublishedMessage.class);
|
||||||
|
|
||||||
public SendDepositTxPublishedMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
public OffererSendsDepositTxPublishedMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||||
super(taskHandler, offererTradeProcessModel);
|
super(taskHandler, offererTradeProcessModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +50,12 @@ public class SendDepositTxPublishedMessage extends OffererTradeTask {
|
||||||
public void handleFault() {
|
public void handleFault() {
|
||||||
appendToErrorMessage("Sending DepositTxPublishedMessage failed");
|
appendToErrorMessage("Sending DepositTxPublishedMessage failed");
|
||||||
offererTrade.setErrorMessage(errorMessage);
|
offererTrade.setErrorMessage(errorMessage);
|
||||||
offererTrade.setProcessState(OffererTrade.OffererProcessState.MESSAGE_SENDING_FAILED);
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade)
|
||||||
|
offererTrade.setProcessState(OffererAsBuyerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade)
|
||||||
|
offererTrade.setProcessState(OffererAsSellerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
|
||||||
failed();
|
failed();
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -19,16 +19,18 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
import io.bitsquare.p2p.listener.SendMessageListener;
|
import io.bitsquare.p2p.listener.SendMessageListener;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
import io.bitsquare.trade.OffererTrade;
|
import io.bitsquare.trade.OffererTrade;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage;
|
import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class SendFiatTransferStartedMessage extends OffererTradeTask {
|
public class OffererSendsFiatTransferStartedMessage extends OffererTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(SendFiatTransferStartedMessage.class);
|
private static final Logger log = LoggerFactory.getLogger(OffererSendsFiatTransferStartedMessage.class);
|
||||||
|
|
||||||
public SendFiatTransferStartedMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
public OffererSendsFiatTransferStartedMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||||
super(taskHandler, offererTradeProcessModel);
|
super(taskHandler, offererTradeProcessModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,13 +44,20 @@ public class SendFiatTransferStartedMessage extends OffererTradeTask {
|
||||||
offererTradeProcessModel.offerer.getAddressEntry().getAddressString());
|
offererTradeProcessModel.offerer.getAddressEntry().getAddressString());
|
||||||
|
|
||||||
offererTradeProcessModel.getMessageService().sendMessage(offererTrade.getTradingPeer(), tradeMessage,
|
offererTradeProcessModel.getMessageService().sendMessage(offererTrade.getTradingPeer(), tradeMessage,
|
||||||
offererTradeProcessModel.taker.getP2pSigPublicKey(),
|
offererTradeProcessModel.taker.getP2pSigPubKey(),
|
||||||
offererTradeProcessModel.taker.getP2pEncryptPubKey(),
|
offererTradeProcessModel.taker.getP2pEncryptPubKey(),
|
||||||
new SendMessageListener() {
|
new SendMessageListener() {
|
||||||
@Override
|
@Override
|
||||||
public void handleResult() {
|
public void handleResult() {
|
||||||
log.trace("Sending FiatTransferStartedMessage succeeded.");
|
log.trace("Sending FiatTransferStartedMessage succeeded.");
|
||||||
offererTrade.setProcessState(OffererTrade.OffererProcessState.FIAT_PAYMENT_STARTED);
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade) {
|
||||||
|
((OffererAsBuyerTrade) offererTrade).setProcessState(OffererAsBuyerTrade.ProcessState.FIAT_PAYMENT_STARTED);
|
||||||
|
}
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade) {
|
||||||
|
((OffererAsSellerTrade) offererTrade).setProcessState(OffererAsSellerTrade.ProcessState.FIAT_PAYMENT_STARTED);
|
||||||
|
}
|
||||||
|
|
||||||
complete();
|
complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +65,14 @@ public class SendFiatTransferStartedMessage extends OffererTradeTask {
|
||||||
public void handleFault() {
|
public void handleFault() {
|
||||||
appendToErrorMessage("Sending FiatTransferStartedMessage failed");
|
appendToErrorMessage("Sending FiatTransferStartedMessage failed");
|
||||||
offererTrade.setErrorMessage(errorMessage);
|
offererTrade.setErrorMessage(errorMessage);
|
||||||
offererTrade.setProcessState(OffererTrade.OffererProcessState.MESSAGE_SENDING_FAILED);
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade) {
|
||||||
|
((OffererAsBuyerTrade) offererTrade).setProcessState(OffererAsBuyerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
}
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade) {
|
||||||
|
((OffererAsSellerTrade) offererTrade).setProcessState(OffererAsSellerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
failed();
|
failed();
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.p2p.listener.SendMessageListener;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
|
import io.bitsquare.trade.OffererTrade;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class OffererSendsPayoutTxPublishedMessage extends OffererTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(OffererSendsPayoutTxPublishedMessage.class);
|
||||||
|
|
||||||
|
public OffererSendsPayoutTxPublishedMessage(TaskRunner taskHandler, OffererTrade model) {
|
||||||
|
super(taskHandler, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
PayoutTxPublishedMessage tradeMessage = new PayoutTxPublishedMessage(offererTradeProcessModel.getId(), offererTradeProcessModel.getPayoutTx());
|
||||||
|
offererTradeProcessModel.getMessageService().sendMessage(offererTrade.getTradingPeer(),
|
||||||
|
tradeMessage,
|
||||||
|
offererTradeProcessModel.offerer.getP2pSigPublicKey(),
|
||||||
|
offererTradeProcessModel.offerer.getP2pEncryptPubKey(),
|
||||||
|
new SendMessageListener() {
|
||||||
|
@Override
|
||||||
|
public void handleResult() {
|
||||||
|
log.trace("PayoutTxPublishedMessage successfully arrived at peer");
|
||||||
|
complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleFault() {
|
||||||
|
appendToErrorMessage("Sending PayoutTxPublishedMessage failed");
|
||||||
|
offererTrade.setErrorMessage(errorMessage);
|
||||||
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade)
|
||||||
|
offererTrade.setProcessState(OffererAsBuyerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade)
|
||||||
|
offererTrade.setProcessState(OffererAsSellerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
|
||||||
|
failed();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
offererTrade.setThrowable(t);
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,52 +19,59 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
import io.bitsquare.p2p.listener.SendMessageListener;
|
import io.bitsquare.p2p.listener.SendMessageListener;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
import io.bitsquare.trade.OffererTrade;
|
import io.bitsquare.trade.OffererTrade;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.RequestTakerDepositPaymentMessage;
|
import io.bitsquare.trade.protocol.trade.messages.RequestPublishDepositTxMessage;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class SendRequestTakerDepositPaymentMessage extends OffererTradeTask {
|
public class OffererSendsRequestPublishDepositTxMessage extends OffererTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(SendRequestTakerDepositPaymentMessage.class);
|
private static final Logger log = LoggerFactory.getLogger(OffererSendsRequestPublishDepositTxMessage.class);
|
||||||
|
|
||||||
public SendRequestTakerDepositPaymentMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
public OffererSendsRequestPublishDepositTxMessage(TaskRunner taskHandler, OffererTrade model) {
|
||||||
super(taskHandler, offererTradeProcessModel);
|
super(taskHandler, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doRun() {
|
protected void doRun() {
|
||||||
try {
|
try {
|
||||||
RequestTakerDepositPaymentMessage tradeMessage = new RequestTakerDepositPaymentMessage(
|
RequestPublishDepositTxMessage tradeMessage = new RequestPublishDepositTxMessage(
|
||||||
offererTradeProcessModel.getId(),
|
offererTradeProcessModel.getId(),
|
||||||
offererTradeProcessModel.offerer.getConnectedOutputsForAllInputs(),
|
|
||||||
offererTradeProcessModel.offerer.getOutputs(),
|
|
||||||
offererTradeProcessModel.offerer.getTradeWalletPubKey(),
|
|
||||||
offererTradeProcessModel.offerer.getP2pSigPubKey(),
|
|
||||||
offererTradeProcessModel.offerer.getP2pEncryptPubKey(),
|
|
||||||
offererTradeProcessModel.offerer.getFiatAccount(),
|
offererTradeProcessModel.offerer.getFiatAccount(),
|
||||||
offererTradeProcessModel.offerer.getAccountId());
|
offererTradeProcessModel.offerer.getAccountId(),
|
||||||
|
offererTradeProcessModel.offerer.getP2pSigPubKey(),
|
||||||
|
offererTradeProcessModel.offerer.getP2pEncryptPublicKey(),
|
||||||
|
offererTrade.getContractAsJson(),
|
||||||
|
offererTrade.getOffererContractSignature(),
|
||||||
|
offererTradeProcessModel.offerer.getAddressEntry().getAddressString(),
|
||||||
|
offererTradeProcessModel.offerer.getPreparedDepositTx(),
|
||||||
|
offererTradeProcessModel.offerer.getConnectedOutputsForAllInputs()
|
||||||
|
);
|
||||||
|
|
||||||
offererTradeProcessModel.getMessageService().sendMessage(offererTrade.getTradingPeer(), tradeMessage, new SendMessageListener() {
|
offererTradeProcessModel.getMessageService().sendMessage(offererTrade.getTradingPeer(), tradeMessage, new SendMessageListener() {
|
||||||
@Override
|
@Override
|
||||||
public void handleResult() {
|
public void handleResult() {
|
||||||
log.trace("RequestTakerDepositPaymentMessage successfully arrived at peer");
|
|
||||||
complete();
|
complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleFault() {
|
public void handleFault() {
|
||||||
appendToErrorMessage("Sending RequestTakerDepositPaymentMessage failed");
|
appendToErrorMessage("Sending RequestOffererPublishDepositTxMessage failed");
|
||||||
offererTrade.setErrorMessage(errorMessage);
|
offererTrade.setErrorMessage(errorMessage);
|
||||||
offererTrade.setProcessState(OffererTrade.OffererProcessState.MESSAGE_SENDING_FAILED);
|
|
||||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
|
if (offererTrade instanceof OffererAsBuyerTrade)
|
||||||
|
offererTrade.setProcessState(OffererAsBuyerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade)
|
||||||
|
offererTrade.setProcessState(OffererAsSellerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
|
||||||
failed();
|
failed();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
offererTrade.setThrowable(t);
|
offererTrade.setThrowable(t);
|
||||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
|
|
||||||
failed(t);
|
failed(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.p2p.listener.SendMessageListener;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
|
import io.bitsquare.trade.OffererTrade;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.RequestPayDepositMessage;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class OffererSendsRequestSellerDepositPaymentMessage extends OffererTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(OffererSendsRequestSellerDepositPaymentMessage.class);
|
||||||
|
|
||||||
|
public OffererSendsRequestSellerDepositPaymentMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||||
|
super(taskHandler, offererTradeProcessModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
RequestPayDepositMessage tradeMessage = new RequestPayDepositMessage(
|
||||||
|
offererTradeProcessModel.getId(),
|
||||||
|
offererTradeProcessModel.offerer.getConnectedOutputsForAllInputs(),
|
||||||
|
offererTradeProcessModel.offerer.getOutputs(),
|
||||||
|
offererTradeProcessModel.offerer.getTradeWalletPubKey(),
|
||||||
|
offererTradeProcessModel.offerer.getP2pSigPubKey(),
|
||||||
|
offererTradeProcessModel.offerer.getP2pEncryptPubKey(),
|
||||||
|
offererTradeProcessModel.offerer.getFiatAccount(),
|
||||||
|
offererTradeProcessModel.offerer.getAccountId());
|
||||||
|
|
||||||
|
offererTradeProcessModel.getMessageService().sendMessage(offererTrade.getTradingPeer(), tradeMessage, new SendMessageListener() {
|
||||||
|
@Override
|
||||||
|
public void handleResult() {
|
||||||
|
log.trace("RequestTakerDepositPaymentMessage successfully arrived at peer");
|
||||||
|
complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleFault() {
|
||||||
|
appendToErrorMessage("Sending RequestTakerDepositPaymentMessage failed");
|
||||||
|
offererTrade.setErrorMessage(errorMessage);
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade) {
|
||||||
|
((OffererAsBuyerTrade) offererTrade).setProcessState(OffererAsBuyerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
((OffererAsBuyerTrade) offererTrade).setLifeCycleState(OffererAsBuyerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
}
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade) {
|
||||||
|
((OffererAsSellerTrade) offererTrade).setProcessState(OffererAsSellerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
((OffererAsSellerTrade) offererTrade).setLifeCycleState(OffererAsSellerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
failed();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
offererTrade.setThrowable(t);
|
||||||
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade) {
|
||||||
|
((OffererAsBuyerTrade) offererTrade).setProcessState(OffererAsBuyerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
((OffererAsSellerTrade) offererTrade).setLifeCycleState(OffererAsSellerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
}
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade) {
|
||||||
|
((OffererAsSellerTrade) offererTrade).setProcessState(OffererAsSellerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
((OffererAsSellerTrade) offererTrade).setLifeCycleState(OffererAsSellerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.btc.FeePolicy;
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
|
import io.bitsquare.trade.OffererTrade;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Coin;
|
||||||
|
import org.bitcoinj.core.Transaction;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class OffererSignsAndPublishDepositTx extends OffererTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(OffererSignsAndPublishDepositTx.class);
|
||||||
|
|
||||||
|
public OffererSignsAndPublishDepositTx(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||||
|
super(taskHandler, offererTradeProcessModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
Coin inputAmount = offererTrade.getSecurityDeposit().add(FeePolicy.TX_FEE);
|
||||||
|
|
||||||
|
offererTradeProcessModel.getTradeWalletService().signAndPublishDepositTx(
|
||||||
|
offererTradeProcessModel.taker.getPreparedDepositTx(),
|
||||||
|
offererTradeProcessModel.offerer.getConnectedOutputsForAllInputs(),
|
||||||
|
offererTradeProcessModel.taker.getConnectedOutputsForAllInputs(),
|
||||||
|
offererTradeProcessModel.offerer.getOutputs(),
|
||||||
|
inputAmount,
|
||||||
|
offererTradeProcessModel.offerer.getTradeWalletPubKey(),
|
||||||
|
offererTradeProcessModel.taker.getTradeWalletPubKey(),
|
||||||
|
offererTradeProcessModel.getArbitratorPubKey(),
|
||||||
|
new FutureCallback<Transaction>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(Transaction transaction) {
|
||||||
|
log.trace("offererSignAndPublishTx succeeded " + transaction);
|
||||||
|
|
||||||
|
offererTrade.setDepositTx(transaction);
|
||||||
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade) {
|
||||||
|
offererTrade.setProcessState(OffererAsBuyerTrade.ProcessState.DEPOSIT_PUBLISHED);
|
||||||
|
offererTrade.setLifeCycleState(OffererAsBuyerTrade.LifeCycleState.PENDING);
|
||||||
|
}
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade) {
|
||||||
|
offererTrade.setProcessState(OffererAsSellerTrade.ProcessState.DEPOSIT_PUBLISHED);
|
||||||
|
offererTrade.setLifeCycleState(OffererAsSellerTrade.LifeCycleState.PENDING);
|
||||||
|
}
|
||||||
|
|
||||||
|
complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NotNull Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
offererTrade.setThrowable(t);
|
||||||
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade)
|
||||||
|
offererTrade.setLifeCycleState(OffererAsBuyerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade)
|
||||||
|
offererTrade.setLifeCycleState(OffererAsSellerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
offererTrade.setThrowable(t);
|
||||||
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade)
|
||||||
|
offererTrade.setLifeCycleState(OffererAsBuyerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade)
|
||||||
|
offererTrade.setLifeCycleState(OffererAsSellerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,11 +17,11 @@
|
||||||
|
|
||||||
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
import io.bitsquare.btc.FeePolicy;
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
import io.bitsquare.trade.OffererTrade;
|
import io.bitsquare.trade.OffererTrade;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
|
||||||
import org.bitcoinj.core.Transaction;
|
import org.bitcoinj.core.Transaction;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
|
@ -31,34 +31,35 @@ import org.jetbrains.annotations.NotNull;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class SignAndPublishDepositTx extends OffererTradeTask {
|
public class OffererSignsAndPublishPayoutTx extends OffererTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(SignAndPublishDepositTx.class);
|
private static final Logger log = LoggerFactory.getLogger(OffererSignsAndPublishPayoutTx.class);
|
||||||
|
|
||||||
public SignAndPublishDepositTx(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
public OffererSignsAndPublishPayoutTx(TaskRunner taskHandler, OffererTrade model) {
|
||||||
super(taskHandler, offererTradeProcessModel);
|
super(taskHandler, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doRun() {
|
protected void doRun() {
|
||||||
try {
|
try {
|
||||||
Coin offererInputAmount = offererTrade.getSecurityDeposit().add(FeePolicy.TX_FEE);
|
offererTradeProcessModel.getTradeWalletService().signAndPublishPayoutTx(
|
||||||
offererTradeProcessModel.getTradeWalletService().offererSignsAndPublishDepositTx(
|
offererTrade.getDepositTx(),
|
||||||
offererTradeProcessModel.taker.getPreparedDepositTx(),
|
offererTradeProcessModel.taker.getSignature(),
|
||||||
offererTradeProcessModel.offerer.getConnectedOutputsForAllInputs(),
|
offererTradeProcessModel.offerer.getPayoutAmount(),
|
||||||
offererTradeProcessModel.taker.getConnectedOutputsForAllInputs(),
|
offererTradeProcessModel.taker.getPayoutAmount(),
|
||||||
offererTradeProcessModel.offerer.getOutputs(),
|
offererTradeProcessModel.taker.getPayoutAddressString(),
|
||||||
offererInputAmount,
|
offererTradeProcessModel.offerer.getAddressEntry(),
|
||||||
offererTradeProcessModel.offerer.getTradeWalletPubKey(),
|
offererTradeProcessModel.offerer.getTradeWalletPubKey(),
|
||||||
offererTradeProcessModel.taker.getTradeWalletPubKey(),
|
offererTradeProcessModel.taker.getTradeWalletPubKey(),
|
||||||
offererTradeProcessModel.getArbitratorPubKey(),
|
offererTradeProcessModel.getArbitratorPubKey(),
|
||||||
new FutureCallback<Transaction>() {
|
new FutureCallback<Transaction>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Transaction transaction) {
|
public void onSuccess(Transaction transaction) {
|
||||||
log.trace("offererSignAndPublishTx succeeded " + transaction);
|
offererTradeProcessModel.setPayoutTx(transaction);
|
||||||
|
|
||||||
offererTrade.setDepositTx(transaction);
|
if (offererTrade instanceof OffererAsBuyerTrade)
|
||||||
offererTrade.setProcessState(OffererTrade.OffererProcessState.DEPOSIT_PUBLISHED);
|
offererTrade.setProcessState(OffererAsBuyerTrade.ProcessState.PAYOUT_PUBLISHED);
|
||||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.PENDING);
|
else if (offererTrade instanceof OffererAsSellerTrade)
|
||||||
|
offererTrade.setProcessState(OffererAsSellerTrade.ProcessState.PAYOUT_PUBLISHED);
|
||||||
|
|
||||||
complete();
|
complete();
|
||||||
}
|
}
|
||||||
|
@ -67,14 +68,12 @@ public class SignAndPublishDepositTx extends OffererTradeTask {
|
||||||
public void onFailure(@NotNull Throwable t) {
|
public void onFailure(@NotNull Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
offererTrade.setThrowable(t);
|
offererTrade.setThrowable(t);
|
||||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
|
|
||||||
failed(t);
|
failed(t);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
offererTrade.setThrowable(t);
|
offererTrade.setThrowable(t);
|
||||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
|
|
||||||
failed(t);
|
failed(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,16 +19,18 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
import io.bitsquare.trade.Contract;
|
import io.bitsquare.trade.Contract;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
import io.bitsquare.trade.OffererTrade;
|
import io.bitsquare.trade.OffererTrade;
|
||||||
import io.bitsquare.util.Utilities;
|
import io.bitsquare.util.Utilities;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class VerifyAndSignContract extends OffererTradeTask {
|
public class OffererVerifiesAndSignsContract extends OffererTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(VerifyAndSignContract.class);
|
private static final Logger log = LoggerFactory.getLogger(OffererVerifiesAndSignsContract.class);
|
||||||
|
|
||||||
public VerifyAndSignContract(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
public OffererVerifiesAndSignsContract(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||||
super(taskHandler, offererTradeProcessModel);
|
super(taskHandler, offererTradeProcessModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +46,7 @@ public class VerifyAndSignContract extends OffererTradeTask {
|
||||||
offererTradeProcessModel.offerer.getFiatAccount(),
|
offererTradeProcessModel.offerer.getFiatAccount(),
|
||||||
offererTradeProcessModel.taker.getFiatAccount(),
|
offererTradeProcessModel.taker.getFiatAccount(),
|
||||||
offererTradeProcessModel.offerer.getP2pSigPubKey(),
|
offererTradeProcessModel.offerer.getP2pSigPubKey(),
|
||||||
offererTradeProcessModel.taker.getP2pSigPublicKey());
|
offererTradeProcessModel.taker.getP2pSigPubKey());
|
||||||
String contractAsJson = Utilities.objectToJson(contract);
|
String contractAsJson = Utilities.objectToJson(contract);
|
||||||
String signature = offererTradeProcessModel.getSignatureService().signMessage(offererTradeProcessModel.offerer.getRegistrationKeyPair(),
|
String signature = offererTradeProcessModel.getSignatureService().signMessage(offererTradeProcessModel.offerer.getRegistrationKeyPair(),
|
||||||
contractAsJson);
|
contractAsJson);
|
||||||
|
@ -58,7 +60,12 @@ public class VerifyAndSignContract extends OffererTradeTask {
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
offererTrade.setThrowable(t);
|
offererTrade.setThrowable(t);
|
||||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade)
|
||||||
|
offererTrade.setLifeCycleState(OffererAsBuyerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade)
|
||||||
|
offererTrade.setLifeCycleState(OffererAsSellerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
|
||||||
failed(t);
|
failed(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,6 +18,8 @@
|
||||||
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||||
import io.bitsquare.trade.OffererTrade;
|
import io.bitsquare.trade.OffererTrade;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -47,12 +49,21 @@ public class VerifyTakerAccount extends OffererTradeTask {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
failed("Account registration validation for peer failed.");
|
failed("Account registration validation for peer failed.");
|
||||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade)
|
||||||
|
offererTrade.setLifeCycleState(OffererAsBuyerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade)
|
||||||
|
offererTrade.setLifeCycleState(OffererAsSellerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
offererTrade.setThrowable(t);
|
offererTrade.setThrowable(t);
|
||||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
|
|
||||||
|
if (offererTrade instanceof OffererAsBuyerTrade)
|
||||||
|
offererTrade.setLifeCycleState(OffererAsBuyerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
else if (offererTrade instanceof OffererAsSellerTrade)
|
||||||
|
offererTrade.setLifeCycleState(OffererAsSellerTrade.LifeCycleState.OFFER_OPEN);
|
||||||
|
|
||||||
failed(t);
|
failed(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.taker;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.p2p.MailboxMessage;
|
||||||
|
import io.bitsquare.p2p.Message;
|
||||||
|
import io.bitsquare.p2p.MessageHandler;
|
||||||
|
import io.bitsquare.p2p.Peer;
|
||||||
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.protocol.Protocol;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.RequestPublishDepositTxMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.models.TakerProcessModel;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.BroadcastTakeOfferFeeTx;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.CreateTakeOfferFeeTx;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCommitsPayoutTx;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCreatesAndSignsPayoutTx;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCreatesDepositTxInputs;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerProcessPayoutTxPublishedMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerProcessRequestPublishDepositTxMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSendsDepositTxPublishedMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSendsFiatTransferStartedMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSendsRequestPayDepositMessage;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSignsAndPublishDepositTx;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerVerifiesAndSignsContract;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOfferFeePayment;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOffererAccount;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static io.bitsquare.util.Validator.nonEmptyStringOf;
|
||||||
|
|
||||||
|
public class TakerAsBuyerProtocol implements Protocol {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(TakerAsBuyerProtocol.class);
|
||||||
|
|
||||||
|
private final TakerAsBuyerTrade takerAsBuyerTrade;
|
||||||
|
private final TakerProcessModel takerTradeProcessModel;
|
||||||
|
private final MessageHandler messageHandler;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructor
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public TakerAsBuyerProtocol(TakerAsBuyerTrade takerTrade) {
|
||||||
|
log.debug("New SellerAsTakerProtocol " + this);
|
||||||
|
this.takerAsBuyerTrade = takerTrade;
|
||||||
|
takerTradeProcessModel = takerTrade.getProcessModel();
|
||||||
|
|
||||||
|
messageHandler = this::handleMessage;
|
||||||
|
takerTradeProcessModel.getMessageService().addMessageHandler(messageHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Public methods
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
public void cleanup() {
|
||||||
|
log.debug("cleanup " + this);
|
||||||
|
takerTradeProcessModel.getMessageService().removeMessageHandler(messageHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMailboxMessage(MailboxMessage mailboxMessage) {
|
||||||
|
log.debug("setMailboxMessage " + mailboxMessage);
|
||||||
|
// Might be called twice, so check that its only processed once
|
||||||
|
/* if (takerTradeProcessModel.getMailboxMessage() == null) {
|
||||||
|
takerTradeProcessModel.setMailboxMessage(mailboxMessage);
|
||||||
|
if (mailboxMessage instanceof FiatTransferStartedMessage) {
|
||||||
|
handleFiatTransferStartedMessage((FiatTransferStartedMessage) mailboxMessage);
|
||||||
|
}
|
||||||
|
else if (mailboxMessage instanceof DepositTxPublishedMessage) {
|
||||||
|
handleDepositTxPublishedMessage((DepositTxPublishedMessage) mailboxMessage);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public void takeAvailableOffer() {
|
||||||
|
TaskRunner<TakerAsBuyerTrade> taskRunner = new TaskRunner<>(takerAsBuyerTrade,
|
||||||
|
() -> log.debug("taskRunner at takeAvailableOffer completed"),
|
||||||
|
this::handleTaskRunnerFault);
|
||||||
|
|
||||||
|
taskRunner.addTasks(
|
||||||
|
CreateTakeOfferFeeTx.class,
|
||||||
|
BroadcastTakeOfferFeeTx.class,
|
||||||
|
TakerCreatesDepositTxInputs.class,
|
||||||
|
TakerSendsRequestPayDepositMessage.class
|
||||||
|
);
|
||||||
|
taskRunner.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Incoming message handling
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void handle(RequestPublishDepositTxMessage tradeMessage) {
|
||||||
|
takerTradeProcessModel.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
|
TaskRunner<TakerAsBuyerTrade> taskRunner = new TaskRunner<>(takerAsBuyerTrade,
|
||||||
|
() -> log.debug("taskRunner at handleRequestPublishDepositTxMessage completed"),
|
||||||
|
this::handleTaskRunnerFault);
|
||||||
|
taskRunner.addTasks(
|
||||||
|
TakerProcessRequestPublishDepositTxMessage.class,
|
||||||
|
VerifyOffererAccount.class,
|
||||||
|
TakerVerifiesAndSignsContract.class,
|
||||||
|
TakerSignsAndPublishDepositTx.class,
|
||||||
|
TakerSendsDepositTxPublishedMessage.class
|
||||||
|
);
|
||||||
|
taskRunner.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Called from UI
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// User clicked the "bank transfer started" button
|
||||||
|
public void onFiatPaymentStarted() {
|
||||||
|
TaskRunner<TakerAsBuyerTrade> taskRunner = new TaskRunner<>(takerAsBuyerTrade,
|
||||||
|
() -> log.debug("taskRunner at onFiatPaymentStarted completed"),
|
||||||
|
this::handleTaskRunnerFault);
|
||||||
|
taskRunner.addTasks(
|
||||||
|
VerifyOfferFeePayment.class,
|
||||||
|
TakerCreatesAndSignsPayoutTx.class,
|
||||||
|
TakerSendsFiatTransferStartedMessage.class
|
||||||
|
);
|
||||||
|
taskRunner.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Incoming message handling
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void handle(PayoutTxPublishedMessage tradeMessage) {
|
||||||
|
takerTradeProcessModel.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
|
TaskRunner<TakerAsBuyerTrade> taskRunner = new TaskRunner<>(takerAsBuyerTrade,
|
||||||
|
() -> {
|
||||||
|
log.debug("taskRunner at handlePayoutTxPublishedMessage completed");
|
||||||
|
// we are done!
|
||||||
|
takerTradeProcessModel.onComplete();
|
||||||
|
},
|
||||||
|
this::handleTaskRunnerFault);
|
||||||
|
|
||||||
|
taskRunner.addTasks(
|
||||||
|
TakerProcessPayoutTxPublishedMessage.class,
|
||||||
|
TakerCommitsPayoutTx.class);
|
||||||
|
taskRunner.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Massage dispatcher
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private void handleMessage(Message message, Peer sender) {
|
||||||
|
log.trace("handleNewMessage: message = " + message.getClass().getSimpleName() + " from " + sender);
|
||||||
|
if (message instanceof TradeMessage) {
|
||||||
|
TradeMessage tradeMessage = (TradeMessage) message;
|
||||||
|
nonEmptyStringOf(tradeMessage.tradeId);
|
||||||
|
|
||||||
|
if (tradeMessage.tradeId.equals(takerTradeProcessModel.getId())) {
|
||||||
|
if (tradeMessage instanceof RequestPublishDepositTxMessage) {
|
||||||
|
handle((RequestPublishDepositTxMessage) tradeMessage);
|
||||||
|
}
|
||||||
|
else if (tradeMessage instanceof PayoutTxPublishedMessage) {
|
||||||
|
handle((PayoutTxPublishedMessage) tradeMessage);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.error("Incoming message not supported. " + tradeMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleTaskRunnerFault(String errorMessage) {
|
||||||
|
log.error(errorMessage);
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,25 +22,26 @@ import io.bitsquare.p2p.MailboxMessage;
|
||||||
import io.bitsquare.p2p.Message;
|
import io.bitsquare.p2p.Message;
|
||||||
import io.bitsquare.p2p.MessageHandler;
|
import io.bitsquare.p2p.MessageHandler;
|
||||||
import io.bitsquare.p2p.Peer;
|
import io.bitsquare.p2p.Peer;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
import io.bitsquare.trade.TakerTrade;
|
import io.bitsquare.trade.TakerTrade;
|
||||||
import io.bitsquare.trade.protocol.Protocol;
|
import io.bitsquare.trade.protocol.Protocol;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
|
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage;
|
import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.RequestTakerDepositPaymentMessage;
|
import io.bitsquare.trade.protocol.trade.messages.RequestPayDepositMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
|
import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.models.TakerProcessModel;
|
import io.bitsquare.trade.protocol.trade.taker.models.TakerProcessModel;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.BroadcastTakeOfferFeeTx;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.BroadcastTakeOfferFeeTx;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.CreateAndSignContract;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCommitDepositTx;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCreatesAndSignContract;
|
||||||
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCreatesAndSignsDepositTx;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.CreateTakeOfferFeeTx;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.CreateTakeOfferFeeTx;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.ProcessDepositTxPublishedMessage;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerProcessDepositTxPublishedMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.ProcessFiatTransferStartedMessage;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerProcessFiatTransferStartedMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.ProcessRequestTakerDepositPaymentMessage;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerProcessRequestSellerDepositPaymentMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendPayoutTxPublishedMessage;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSendsPayoutTxPublishedMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendRequestDepositTxInputsMessage;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSendsRequestDepositTxInputsMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendRequestPublishDepositTxMessage;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSendsRequestPublishDepositTxMessage;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SignAndPublishPayoutTx;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSignsAndPublishPayoutTx;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.CommitDepositTx;
|
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.CreateAndSignDepositTx;
|
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOfferFeePayment;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOfferFeePayment;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOffererAccount;
|
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOffererAccount;
|
||||||
|
|
||||||
|
@ -49,10 +50,10 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import static io.bitsquare.util.Validator.nonEmptyStringOf;
|
import static io.bitsquare.util.Validator.nonEmptyStringOf;
|
||||||
|
|
||||||
public class TakerProtocol implements Protocol {
|
public class TakerAsSellerProtocol implements Protocol {
|
||||||
private static final Logger log = LoggerFactory.getLogger(TakerProtocol.class);
|
private static final Logger log = LoggerFactory.getLogger(TakerAsSellerProtocol.class);
|
||||||
|
|
||||||
private final TakerTrade takerTrade;
|
private final TakerAsSellerTrade takerAsSellerTrade;
|
||||||
private final TakerProcessModel takerTradeProcessModel;
|
private final TakerProcessModel takerTradeProcessModel;
|
||||||
private final MessageHandler messageHandler;
|
private final MessageHandler messageHandler;
|
||||||
|
|
||||||
|
@ -61,9 +62,9 @@ public class TakerProtocol implements Protocol {
|
||||||
// Constructor
|
// Constructor
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public TakerProtocol(TakerTrade takerTrade) {
|
public TakerAsSellerProtocol(TakerAsSellerTrade takerTrade) {
|
||||||
log.debug("New SellerAsTakerProtocol " + this);
|
log.debug("New SellerAsTakerProtocol " + this);
|
||||||
this.takerTrade = takerTrade;
|
this.takerAsSellerTrade = takerTrade;
|
||||||
takerTradeProcessModel = takerTrade.getProcessModel();
|
takerTradeProcessModel = takerTrade.getProcessModel();
|
||||||
|
|
||||||
messageHandler = this::handleMessage;
|
messageHandler = this::handleMessage;
|
||||||
|
@ -95,14 +96,14 @@ public class TakerProtocol implements Protocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void takeAvailableOffer() {
|
public void takeAvailableOffer() {
|
||||||
TaskRunner<TakerTrade> taskRunner = new TaskRunner<>(takerTrade,
|
TaskRunner<TakerTrade> taskRunner = new TaskRunner<>(takerAsSellerTrade,
|
||||||
() -> log.debug("taskRunner at takeAvailableOffer completed"),
|
() -> log.debug("taskRunner at takeAvailableOffer completed"),
|
||||||
this::handleTaskRunnerFault);
|
this::handleTaskRunnerFault);
|
||||||
|
|
||||||
taskRunner.addTasks(
|
taskRunner.addTasks(
|
||||||
CreateTakeOfferFeeTx.class,
|
CreateTakeOfferFeeTx.class,
|
||||||
BroadcastTakeOfferFeeTx.class,
|
BroadcastTakeOfferFeeTx.class,
|
||||||
SendRequestDepositTxInputsMessage.class
|
TakerSendsRequestDepositTxInputsMessage.class
|
||||||
);
|
);
|
||||||
taskRunner.run();
|
taskRunner.run();
|
||||||
}
|
}
|
||||||
|
@ -112,19 +113,19 @@ public class TakerProtocol implements Protocol {
|
||||||
// Incoming message handling
|
// Incoming message handling
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void handleRequestTakerDepositPaymentMessage(RequestTakerDepositPaymentMessage tradeMessage) {
|
private void handleRequestTakerDepositPaymentMessage(RequestPayDepositMessage tradeMessage) {
|
||||||
takerTradeProcessModel.setTradeMessage(tradeMessage);
|
takerTradeProcessModel.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
TaskRunner<TakerTrade> taskRunner = new TaskRunner<>(takerTrade,
|
TaskRunner<TakerTrade> taskRunner = new TaskRunner<>(takerAsSellerTrade,
|
||||||
() -> log.debug("taskRunner at handleTakerDepositPaymentRequestMessage completed"),
|
() -> log.debug("taskRunner at handleTakerDepositPaymentRequestMessage completed"),
|
||||||
this::handleTaskRunnerFault);
|
this::handleTaskRunnerFault);
|
||||||
|
|
||||||
taskRunner.addTasks(
|
taskRunner.addTasks(
|
||||||
ProcessRequestTakerDepositPaymentMessage.class,
|
TakerProcessRequestSellerDepositPaymentMessage.class,
|
||||||
VerifyOffererAccount.class,
|
VerifyOffererAccount.class,
|
||||||
CreateAndSignContract.class,
|
TakerCreatesAndSignContract.class,
|
||||||
CreateAndSignDepositTx.class,
|
TakerCreatesAndSignsDepositTx.class,
|
||||||
SendRequestPublishDepositTxMessage.class
|
TakerSendsRequestPublishDepositTxMessage.class
|
||||||
);
|
);
|
||||||
taskRunner.run();
|
taskRunner.run();
|
||||||
}
|
}
|
||||||
|
@ -132,13 +133,13 @@ public class TakerProtocol implements Protocol {
|
||||||
private void handleDepositTxPublishedMessage(DepositTxPublishedMessage tradeMessage) {
|
private void handleDepositTxPublishedMessage(DepositTxPublishedMessage tradeMessage) {
|
||||||
takerTradeProcessModel.setTradeMessage(tradeMessage);
|
takerTradeProcessModel.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
TaskRunner<TakerTrade> taskRunner = new TaskRunner<>(takerTrade,
|
TaskRunner<TakerAsSellerTrade> taskRunner = new TaskRunner<>(takerAsSellerTrade,
|
||||||
() -> log.debug("taskRunner at handleDepositTxPublishedMessage completed"),
|
() -> log.debug("taskRunner at handleDepositTxPublishedMessage completed"),
|
||||||
this::handleTaskRunnerFault);
|
this::handleTaskRunnerFault);
|
||||||
|
|
||||||
taskRunner.addTasks(
|
taskRunner.addTasks(
|
||||||
ProcessDepositTxPublishedMessage.class,
|
TakerProcessDepositTxPublishedMessage.class,
|
||||||
CommitDepositTx.class
|
TakerCommitDepositTx.class
|
||||||
);
|
);
|
||||||
taskRunner.run();
|
taskRunner.run();
|
||||||
}
|
}
|
||||||
|
@ -146,11 +147,11 @@ public class TakerProtocol implements Protocol {
|
||||||
private void handleFiatTransferStartedMessage(FiatTransferStartedMessage tradeMessage) {
|
private void handleFiatTransferStartedMessage(FiatTransferStartedMessage tradeMessage) {
|
||||||
takerTradeProcessModel.setTradeMessage(tradeMessage);
|
takerTradeProcessModel.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
TaskRunner<TakerTrade> taskRunner = new TaskRunner<>(takerTrade,
|
TaskRunner<TakerAsSellerTrade> taskRunner = new TaskRunner<>(takerAsSellerTrade,
|
||||||
() -> log.debug("taskRunner at handleFiatTransferStartedMessage completed"),
|
() -> log.debug("taskRunner at handleFiatTransferStartedMessage completed"),
|
||||||
this::handleTaskRunnerFault);
|
this::handleTaskRunnerFault);
|
||||||
|
|
||||||
taskRunner.addTasks(ProcessFiatTransferStartedMessage.class);
|
taskRunner.addTasks(TakerProcessFiatTransferStartedMessage.class);
|
||||||
taskRunner.run();
|
taskRunner.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,9 +162,9 @@ public class TakerProtocol implements Protocol {
|
||||||
|
|
||||||
// User clicked the "bank transfer received" button, so we release the funds for pay out
|
// User clicked the "bank transfer received" button, so we release the funds for pay out
|
||||||
public void onFiatPaymentReceived() {
|
public void onFiatPaymentReceived() {
|
||||||
takerTrade.setProcessState(TakerTrade.TakerProcessState.FIAT_PAYMENT_RECEIVED);
|
takerAsSellerTrade.setProcessState(TakerAsSellerTrade.ProcessState.FIAT_PAYMENT_RECEIVED);
|
||||||
|
|
||||||
TaskRunner<TakerTrade> taskRunner = new TaskRunner<>(takerTrade,
|
TaskRunner<TakerAsSellerTrade> taskRunner = new TaskRunner<>(takerAsSellerTrade,
|
||||||
() -> {
|
() -> {
|
||||||
log.debug("taskRunner at handleFiatReceivedUIEvent completed");
|
log.debug("taskRunner at handleFiatReceivedUIEvent completed");
|
||||||
|
|
||||||
|
@ -173,9 +174,9 @@ public class TakerProtocol implements Protocol {
|
||||||
this::handleTaskRunnerFault);
|
this::handleTaskRunnerFault);
|
||||||
|
|
||||||
taskRunner.addTasks(
|
taskRunner.addTasks(
|
||||||
SignAndPublishPayoutTx.class,
|
|
||||||
VerifyOfferFeePayment.class,
|
VerifyOfferFeePayment.class,
|
||||||
SendPayoutTxPublishedMessage.class
|
TakerSignsAndPublishPayoutTx.class,
|
||||||
|
TakerSendsPayoutTxPublishedMessage.class
|
||||||
);
|
);
|
||||||
taskRunner.run();
|
taskRunner.run();
|
||||||
}
|
}
|
||||||
|
@ -191,8 +192,8 @@ public class TakerProtocol implements Protocol {
|
||||||
nonEmptyStringOf(tradeMessage.tradeId);
|
nonEmptyStringOf(tradeMessage.tradeId);
|
||||||
|
|
||||||
if (tradeMessage.tradeId.equals(takerTradeProcessModel.getId())) {
|
if (tradeMessage.tradeId.equals(takerTradeProcessModel.getId())) {
|
||||||
if (tradeMessage instanceof RequestTakerDepositPaymentMessage) {
|
if (tradeMessage instanceof RequestPayDepositMessage) {
|
||||||
handleRequestTakerDepositPaymentMessage((RequestTakerDepositPaymentMessage) tradeMessage);
|
handleRequestTakerDepositPaymentMessage((RequestPayDepositMessage) tradeMessage);
|
||||||
}
|
}
|
||||||
else if (tradeMessage instanceof DepositTxPublishedMessage) {
|
else if (tradeMessage instanceof DepositTxPublishedMessage) {
|
||||||
handleDepositTxPublishedMessage((DepositTxPublishedMessage) tradeMessage);
|
handleDepositTxPublishedMessage((DepositTxPublishedMessage) tradeMessage);
|
|
@ -20,6 +20,7 @@ package io.bitsquare.trade.protocol.trade.taker.models;
|
||||||
import io.bitsquare.fiat.FiatAccount;
|
import io.bitsquare.fiat.FiatAccount;
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
|
import org.bitcoinj.core.Transaction;
|
||||||
import org.bitcoinj.core.TransactionOutput;
|
import org.bitcoinj.core.TransactionOutput;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -56,6 +57,10 @@ public class Offerer implements Serializable {
|
||||||
private String accountId;
|
private String accountId;
|
||||||
private PublicKey p2pSigPublicKey;
|
private PublicKey p2pSigPublicKey;
|
||||||
private PublicKey p2pEncryptPubKey;
|
private PublicKey p2pEncryptPubKey;
|
||||||
|
private String contractAsJson;
|
||||||
|
private String contractSignature;
|
||||||
|
private Transaction preparedDepositTx;
|
||||||
|
private PublicKey p2pSigPubKey;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -166,6 +171,41 @@ public class Offerer implements Serializable {
|
||||||
this.p2pEncryptPubKey = p2pEncryptPubKey;
|
this.p2pEncryptPubKey = p2pEncryptPubKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getContractAsJson() {
|
||||||
|
return contractAsJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContractAsJson(String contractAsJson) {
|
||||||
|
this.contractAsJson = contractAsJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getContractSignature() {
|
||||||
|
return contractSignature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContractSignature(String contractSignature) {
|
||||||
|
this.contractSignature = contractSignature;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Transaction getPreparedDepositTx() {
|
||||||
|
return preparedDepositTx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreparedDepositTx(Transaction preparedDepositTx) {
|
||||||
|
this.preparedDepositTx = preparedDepositTx;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public PublicKey getP2pSigPubKey() {
|
||||||
|
return p2pSigPubKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setP2pSigPubKey(PublicKey p2pSigPubKey) {
|
||||||
|
this.p2pSigPubKey = p2pSigPubKey;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
|
@ -56,7 +56,8 @@ public class Taker implements Serializable {
|
||||||
private List<TransactionOutput> connectedOutputsForAllInputs;
|
private List<TransactionOutput> connectedOutputsForAllInputs;
|
||||||
private Coin payoutAmount;
|
private Coin payoutAmount;
|
||||||
private Transaction preparedDepositTx;
|
private Transaction preparedDepositTx;
|
||||||
|
private List<TransactionOutput> outputs; // used to verify amounts with change outputs
|
||||||
|
private byte[] payoutTxSignature;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor, initialization
|
// Constructor, initialization
|
||||||
|
@ -118,6 +119,10 @@ public class Taker implements Serializable {
|
||||||
return getAddressEntry().getPubKey();
|
return getAddressEntry().getPubKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PublicKey getP2pEncryptPubKey() {
|
||||||
|
return user.getP2PEncryptPubKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Getter/Setter for Mutable objects
|
// Getter/Setter for Mutable objects
|
||||||
|
@ -150,6 +155,24 @@ public class Taker implements Serializable {
|
||||||
this.preparedDepositTx = preparedDepositTx;
|
this.preparedDepositTx = preparedDepositTx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public List<TransactionOutput> getOutputs() {
|
||||||
|
return outputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOutputs(List<TransactionOutput> outputs) {
|
||||||
|
this.outputs = outputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public byte[] getPayoutTxSignature() {
|
||||||
|
return payoutTxSignature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPayoutTxSignature(byte[] payoutTxSignature) {
|
||||||
|
this.payoutTxSignature = payoutTxSignature;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Taker{" +
|
return "Taker{" +
|
||||||
|
@ -161,4 +184,6 @@ public class Taker implements Serializable {
|
||||||
", preparedDepositTx=" + preparedDepositTx +
|
", preparedDepositTx=" + preparedDepositTx +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
import io.bitsquare.trade.TakerTrade;
|
import io.bitsquare.trade.TakerTrade;
|
||||||
|
|
||||||
import org.bitcoinj.core.Transaction;
|
import org.bitcoinj.core.Transaction;
|
||||||
|
@ -45,8 +47,10 @@ public class BroadcastTakeOfferFeeTx extends TakerTradeTask {
|
||||||
public void onSuccess(Transaction transaction) {
|
public void onSuccess(Transaction transaction) {
|
||||||
log.debug("Take offer fee published successfully. Transaction ID = " + transaction.getHashAsString());
|
log.debug("Take offer fee published successfully. Transaction ID = " + transaction.getHashAsString());
|
||||||
|
|
||||||
takerTrade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_PUBLISHED);
|
if (takerTrade instanceof TakerAsBuyerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsBuyerTrade.ProcessState.TAKE_OFFER_FEE_PUBLISHED);
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.TAKE_OFFER_FEE_PUBLISHED);
|
||||||
complete();
|
complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +59,11 @@ public class BroadcastTakeOfferFeeTx extends TakerTradeTask {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
appendToErrorMessage("Take offer fee payment failed. Maybe your network connection was lost. Please try again.");
|
appendToErrorMessage("Take offer fee payment failed. Maybe your network connection was lost. Please try again.");
|
||||||
takerTrade.setErrorMessage(errorMessage);
|
takerTrade.setErrorMessage(errorMessage);
|
||||||
takerTrade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_PUBLISH_FAILED);
|
|
||||||
|
if (takerTrade instanceof TakerAsBuyerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsBuyerTrade.ProcessState.TAKE_OFFER_FEE_PUBLISH_FAILED);
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.TAKE_OFFER_FEE_PUBLISH_FAILED);
|
||||||
|
|
||||||
failed(t);
|
failed(t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
import io.bitsquare.trade.TakerTrade;
|
import io.bitsquare.trade.TakerTrade;
|
||||||
|
|
||||||
import org.bitcoinj.core.Transaction;
|
import org.bitcoinj.core.Transaction;
|
||||||
|
@ -39,7 +41,11 @@ public class CreateTakeOfferFeeTx extends TakerTradeTask {
|
||||||
.getAddressEntry());
|
.getAddressEntry());
|
||||||
|
|
||||||
takerTradeProcessModel.setTakeOfferFeeTx(createTakeOfferFeeTx);
|
takerTradeProcessModel.setTakeOfferFeeTx(createTakeOfferFeeTx);
|
||||||
takerTrade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_TX_CREATED);
|
|
||||||
|
if (takerTrade instanceof TakerAsBuyerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsBuyerTrade.ProcessState.TAKE_OFFER_FEE_TX_CREATED);
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.TAKE_OFFER_FEE_TX_CREATED);
|
||||||
|
|
||||||
complete();
|
complete();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
|
|
@ -25,10 +25,10 @@ import org.bitcoinj.core.Transaction;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class CommitDepositTx extends TakerTradeTask {
|
public class TakerCommitDepositTx extends TakerTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(CommitDepositTx.class);
|
private static final Logger log = LoggerFactory.getLogger(TakerCommitDepositTx.class);
|
||||||
|
|
||||||
public CommitDepositTx(TaskRunner taskHandler, TakerTrade model) {
|
public TakerCommitDepositTx(TaskRunner taskHandler, TakerTrade model) {
|
||||||
super(taskHandler, model);
|
super(taskHandler, model);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.TakerTrade;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Transaction;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class TakerCommitsPayoutTx extends TakerTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(TakerCommitsPayoutTx.class);
|
||||||
|
|
||||||
|
public TakerCommitsPayoutTx(TaskRunner taskHandler, TakerTrade takerTradeProcessModel) {
|
||||||
|
super(taskHandler, takerTradeProcessModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
Transaction transaction = takerTradeProcessModel.getTradeWalletService().commitTx(takerTrade.getPayoutTx());
|
||||||
|
|
||||||
|
takerTrade.setPayoutTx(transaction);
|
||||||
|
|
||||||
|
complete();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
takerTrade.setThrowable(t);
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,10 +25,10 @@ import io.bitsquare.util.Utilities;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class CreateAndSignContract extends TakerTradeTask {
|
public class TakerCreatesAndSignContract extends TakerTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(CreateAndSignContract.class);
|
private static final Logger log = LoggerFactory.getLogger(TakerCreatesAndSignContract.class);
|
||||||
|
|
||||||
public CreateAndSignContract(TaskRunner taskHandler, TakerTrade model) {
|
public TakerCreatesAndSignContract(TaskRunner taskHandler, TakerTrade model) {
|
||||||
super(taskHandler, model);
|
super(taskHandler, model);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,10 @@ import org.bitcoinj.core.Coin;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class CreateAndSignDepositTx extends TakerTradeTask {
|
public class TakerCreatesAndSignsDepositTx extends TakerTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(CreateAndSignDepositTx.class);
|
private static final Logger log = LoggerFactory.getLogger(TakerCreatesAndSignsDepositTx.class);
|
||||||
|
|
||||||
public CreateAndSignDepositTx(TaskRunner taskHandler, TakerTrade model) {
|
public TakerCreatesAndSignsDepositTx(TaskRunner taskHandler, TakerTrade model) {
|
||||||
super(taskHandler, model);
|
super(taskHandler, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ public class CreateAndSignDepositTx extends TakerTradeTask {
|
||||||
protected void doRun() {
|
protected void doRun() {
|
||||||
try {
|
try {
|
||||||
assert takerTrade.getTradeAmount() != null;
|
assert takerTrade.getTradeAmount() != null;
|
||||||
Coin takerInputAmount = takerTrade.getTradeAmount().add(takerTrade.getSecurityDeposit()).add(FeePolicy.TX_FEE);
|
Coin takerInputAmount = takerTrade.getSecurityDeposit().add(FeePolicy.TX_FEE);
|
||||||
Coin msOutputAmount = takerInputAmount.add(takerTrade.getSecurityDeposit());
|
Coin msOutputAmount = takerInputAmount.add(takerTrade.getSecurityDeposit());
|
||||||
|
|
||||||
TradeWalletService.Result result = takerTradeProcessModel.getTradeWalletService().takerCreatesAndSignsDepositTx(
|
TradeWalletService.Result result = takerTradeProcessModel.getTradeWalletService().takerCreatesAndSignsDepositTx(
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.TakerTrade;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Coin;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class TakerCreatesAndSignsPayoutTx extends TakerTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(TakerCreatesAndSignsPayoutTx.class);
|
||||||
|
|
||||||
|
public TakerCreatesAndSignsPayoutTx(TaskRunner taskHandler, TakerTrade takerTradeProcessModel) {
|
||||||
|
super(taskHandler, takerTradeProcessModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
assert takerTrade.getTradeAmount() != null;
|
||||||
|
Coin securityDeposit = takerTrade.getSecurityDeposit();
|
||||||
|
|
||||||
|
Coin offererPayoutAmount = securityDeposit;
|
||||||
|
Coin takerPayoutAmount = securityDeposit.add(takerTrade.getTradeAmount());
|
||||||
|
|
||||||
|
byte[] takerPayoutTxSignature = takerTradeProcessModel.getTradeWalletService().createAndSignPayoutTx(
|
||||||
|
takerTrade.getDepositTx(),
|
||||||
|
offererPayoutAmount,
|
||||||
|
takerPayoutAmount,
|
||||||
|
takerTradeProcessModel.taker.getAddressEntry(),
|
||||||
|
takerTradeProcessModel.offerer.getPayoutAddressString(),
|
||||||
|
takerTradeProcessModel.offerer.getTradeWalletPubKey(),
|
||||||
|
takerTradeProcessModel.taker.getTradeWalletPubKey(),
|
||||||
|
takerTradeProcessModel.getArbitratorPubKey());
|
||||||
|
|
||||||
|
takerTradeProcessModel.taker.setPayoutTxSignature(takerPayoutTxSignature);
|
||||||
|
takerTradeProcessModel.taker.setPayoutAmount(takerPayoutAmount);
|
||||||
|
takerTradeProcessModel.offerer.setPayoutAmount(offererPayoutAmount);
|
||||||
|
|
||||||
|
complete();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
takerTrade.setThrowable(t);
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.btc.FeePolicy;
|
||||||
|
import io.bitsquare.btc.TradeWalletService;
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.TakerTrade;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Coin;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class TakerCreatesDepositTxInputs extends TakerTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(TakerCreatesDepositTxInputs.class);
|
||||||
|
|
||||||
|
public TakerCreatesDepositTxInputs(TaskRunner taskHandler, TakerTrade takerTradeProcessModel) {
|
||||||
|
super(taskHandler, takerTradeProcessModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
log.debug("takerTrade.id" + takerTrade.getId());
|
||||||
|
Coin inputAmount = takerTrade.getSecurityDeposit().add(FeePolicy.TX_FEE);
|
||||||
|
TradeWalletService.Result result = takerTradeProcessModel.getTradeWalletService().createOffererDepositTxInputs(inputAmount,
|
||||||
|
takerTradeProcessModel.taker.getAddressEntry());
|
||||||
|
|
||||||
|
takerTradeProcessModel.taker.setConnectedOutputsForAllInputs(result.getConnectedOutputsForAllInputs());
|
||||||
|
takerTradeProcessModel.taker.setOutputs(result.getOutputs());
|
||||||
|
|
||||||
|
complete();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
takerTrade.setThrowable(t);
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,8 @@
|
||||||
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
import io.bitsquare.trade.TakerTrade;
|
import io.bitsquare.trade.TakerTrade;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
|
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
|
||||||
|
|
||||||
|
@ -27,10 +29,10 @@ import org.slf4j.LoggerFactory;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static io.bitsquare.util.Validator.checkTradeId;
|
import static io.bitsquare.util.Validator.checkTradeId;
|
||||||
|
|
||||||
public class ProcessDepositTxPublishedMessage extends TakerTradeTask {
|
public class TakerProcessDepositTxPublishedMessage extends TakerTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(ProcessDepositTxPublishedMessage.class);
|
private static final Logger log = LoggerFactory.getLogger(TakerProcessDepositTxPublishedMessage.class);
|
||||||
|
|
||||||
public ProcessDepositTxPublishedMessage(TaskRunner taskHandler, TakerTrade model) {
|
public TakerProcessDepositTxPublishedMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||||
super(taskHandler, model);
|
super(taskHandler, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +44,11 @@ public class ProcessDepositTxPublishedMessage extends TakerTradeTask {
|
||||||
checkNotNull(message);
|
checkNotNull(message);
|
||||||
|
|
||||||
takerTrade.setDepositTx(checkNotNull(message.depositTx));
|
takerTrade.setDepositTx(checkNotNull(message.depositTx));
|
||||||
takerTrade.setProcessState(TakerTrade.TakerProcessState.DEPOSIT_PUBLISHED);
|
|
||||||
|
if (takerTrade instanceof TakerAsBuyerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsBuyerTrade.ProcessState.DEPOSIT_PUBLISHED);
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.DEPOSIT_PUBLISHED);
|
||||||
|
|
||||||
complete();
|
complete();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
|
@ -18,6 +18,8 @@
|
||||||
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
import io.bitsquare.trade.TakerTrade;
|
import io.bitsquare.trade.TakerTrade;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage;
|
import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage;
|
||||||
|
|
||||||
|
@ -27,10 +29,10 @@ import org.slf4j.LoggerFactory;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static io.bitsquare.util.Validator.*;
|
import static io.bitsquare.util.Validator.*;
|
||||||
|
|
||||||
public class ProcessFiatTransferStartedMessage extends TakerTradeTask {
|
public class TakerProcessFiatTransferStartedMessage extends TakerTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(ProcessFiatTransferStartedMessage.class);
|
private static final Logger log = LoggerFactory.getLogger(TakerProcessFiatTransferStartedMessage.class);
|
||||||
|
|
||||||
public ProcessFiatTransferStartedMessage(TaskRunner taskHandler, TakerTrade model) {
|
public TakerProcessFiatTransferStartedMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||||
super(taskHandler, model);
|
super(taskHandler, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,11 +43,15 @@ public class ProcessFiatTransferStartedMessage extends TakerTradeTask {
|
||||||
checkTradeId(takerTradeProcessModel.getId(), message);
|
checkTradeId(takerTradeProcessModel.getId(), message);
|
||||||
checkNotNull(message);
|
checkNotNull(message);
|
||||||
|
|
||||||
takerTradeProcessModel.offerer.setSignature(checkNotNull(message.offererSignature));
|
takerTradeProcessModel.offerer.setSignature(checkNotNull(message.buyerSignature));
|
||||||
takerTradeProcessModel.offerer.setPayoutAmount(positiveCoinOf(nonZeroCoinOf(message.offererPayoutAmount)));
|
takerTradeProcessModel.offerer.setPayoutAmount(positiveCoinOf(nonZeroCoinOf(message.offererPayoutAmount)));
|
||||||
takerTradeProcessModel.taker.setPayoutAmount(positiveCoinOf(nonZeroCoinOf(message.takerPayoutAmount)));
|
takerTradeProcessModel.taker.setPayoutAmount(positiveCoinOf(nonZeroCoinOf(message.takerPayoutAmount)));
|
||||||
takerTradeProcessModel.offerer.setPayoutAddressString(nonEmptyStringOf(message.offererPayoutAddress));
|
takerTradeProcessModel.offerer.setPayoutAddressString(nonEmptyStringOf(message.buyerPayoutAddress));
|
||||||
takerTrade.setProcessState(TakerTrade.TakerProcessState.FIAT_PAYMENT_STARTED);
|
|
||||||
|
if (takerTrade instanceof TakerAsBuyerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsBuyerTrade.ProcessState.FIAT_PAYMENT_STARTED);
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.FIAT_PAYMENT_STARTED);
|
||||||
|
|
||||||
complete();
|
complete();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
|
import io.bitsquare.trade.TakerTrade;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static io.bitsquare.util.Validator.checkTradeId;
|
||||||
|
|
||||||
|
public class TakerProcessPayoutTxPublishedMessage extends TakerTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(TakerProcessPayoutTxPublishedMessage.class);
|
||||||
|
|
||||||
|
public TakerProcessPayoutTxPublishedMessage(TaskRunner taskHandler, TakerTrade takerTradeProcessModel) {
|
||||||
|
super(taskHandler, takerTradeProcessModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
PayoutTxPublishedMessage message = (PayoutTxPublishedMessage) takerTradeProcessModel.getTradeMessage();
|
||||||
|
checkTradeId(takerTradeProcessModel.getId(), message);
|
||||||
|
checkNotNull(message);
|
||||||
|
|
||||||
|
takerTrade.setPayoutTx(checkNotNull(message.payoutTx));
|
||||||
|
|
||||||
|
if (takerTrade instanceof TakerAsBuyerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsBuyerTrade.ProcessState.PAYOUT_PUBLISHED);
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.PAYOUT_PUBLISHED);
|
||||||
|
|
||||||
|
complete();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
takerTrade.setThrowable(t);
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.TakerTrade;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.RequestPublishDepositTxMessage;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.*;
|
||||||
|
import static io.bitsquare.util.Validator.*;
|
||||||
|
|
||||||
|
public class TakerProcessRequestPublishDepositTxMessage extends TakerTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(TakerProcessRequestPublishDepositTxMessage.class);
|
||||||
|
|
||||||
|
public TakerProcessRequestPublishDepositTxMessage(TaskRunner taskHandler, TakerTrade takerTradeProcessModel) {
|
||||||
|
super(taskHandler, takerTradeProcessModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
RequestPublishDepositTxMessage message = (RequestPublishDepositTxMessage) takerTradeProcessModel.getTradeMessage();
|
||||||
|
checkTradeId(takerTradeProcessModel.getId(), message);
|
||||||
|
checkNotNull(message);
|
||||||
|
|
||||||
|
takerTradeProcessModel.offerer.setFiatAccount(checkNotNull(message.takerFiatAccount));
|
||||||
|
takerTradeProcessModel.offerer.setAccountId(nonEmptyStringOf(message.takerAccountId));
|
||||||
|
takerTradeProcessModel.offerer.setP2pSigPublicKey(checkNotNull(message.takerP2PSigPublicKey));
|
||||||
|
takerTradeProcessModel.offerer.setP2pEncryptPubKey(checkNotNull(message.takerP2PEncryptPublicKey));
|
||||||
|
takerTradeProcessModel.offerer.setContractAsJson(nonEmptyStringOf(message.takerContractAsJson));
|
||||||
|
takerTradeProcessModel.offerer.setContractSignature(nonEmptyStringOf(message.takerContractSignature));
|
||||||
|
takerTradeProcessModel.offerer.setPayoutAddressString(nonEmptyStringOf(message.takerPayoutAddressString));
|
||||||
|
takerTradeProcessModel.offerer.setPreparedDepositTx(checkNotNull(message.takersPreparedDepositTx));
|
||||||
|
takerTradeProcessModel.offerer.setConnectedOutputsForAllInputs(checkNotNull(message.takerConnectedOutputsForAllInputs));
|
||||||
|
checkArgument(message.takerConnectedOutputsForAllInputs.size() > 0);
|
||||||
|
|
||||||
|
complete();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
takerTrade.setThrowable(t);
|
||||||
|
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
import io.bitsquare.trade.TakerTrade;
|
import io.bitsquare.trade.TakerTrade;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.RequestTakerDepositPaymentMessage;
|
import io.bitsquare.trade.protocol.trade.messages.RequestPayDepositMessage;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -27,28 +27,28 @@ import org.slf4j.LoggerFactory;
|
||||||
import static com.google.common.base.Preconditions.*;
|
import static com.google.common.base.Preconditions.*;
|
||||||
import static io.bitsquare.util.Validator.*;
|
import static io.bitsquare.util.Validator.*;
|
||||||
|
|
||||||
public class ProcessRequestTakerDepositPaymentMessage extends TakerTradeTask {
|
public class TakerProcessRequestSellerDepositPaymentMessage extends TakerTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(ProcessRequestTakerDepositPaymentMessage.class);
|
private static final Logger log = LoggerFactory.getLogger(TakerProcessRequestSellerDepositPaymentMessage.class);
|
||||||
|
|
||||||
public ProcessRequestTakerDepositPaymentMessage(TaskRunner taskHandler, TakerTrade model) {
|
public TakerProcessRequestSellerDepositPaymentMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||||
super(taskHandler, model);
|
super(taskHandler, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doRun() {
|
protected void doRun() {
|
||||||
try {
|
try {
|
||||||
RequestTakerDepositPaymentMessage message = (RequestTakerDepositPaymentMessage) takerTradeProcessModel.getTradeMessage();
|
RequestPayDepositMessage message = (RequestPayDepositMessage) takerTradeProcessModel.getTradeMessage();
|
||||||
checkTradeId(takerTradeProcessModel.getId(), message);
|
checkTradeId(takerTradeProcessModel.getId(), message);
|
||||||
checkNotNull(message);
|
checkNotNull(message);
|
||||||
|
|
||||||
takerTradeProcessModel.offerer.setConnectedOutputsForAllInputs(checkNotNull(message.offererConnectedOutputsForAllInputs));
|
takerTradeProcessModel.offerer.setConnectedOutputsForAllInputs(checkNotNull(message.buyerConnectedOutputsForAllInputs));
|
||||||
checkArgument(message.offererConnectedOutputsForAllInputs.size() > 0);
|
checkArgument(message.buyerConnectedOutputsForAllInputs.size() > 0);
|
||||||
takerTradeProcessModel.offerer.setOutputs(checkNotNull(message.offererOutputs));
|
takerTradeProcessModel.offerer.setOutputs(checkNotNull(message.buyerOutputs));
|
||||||
takerTradeProcessModel.offerer.setTradeWalletPubKey(checkNotNull(message.offererTradeWalletPubKey));
|
takerTradeProcessModel.offerer.setTradeWalletPubKey(checkNotNull(message.buyerTradeWalletPubKey));
|
||||||
takerTradeProcessModel.offerer.setP2pSigPublicKey(checkNotNull(message.offererP2PSigPublicKey));
|
takerTradeProcessModel.offerer.setP2pSigPublicKey(checkNotNull(message.buyerP2PSigPublicKey));
|
||||||
takerTradeProcessModel.offerer.setP2pEncryptPubKey(checkNotNull(message.offererP2PEncryptPublicKey));
|
takerTradeProcessModel.offerer.setP2pEncryptPubKey(checkNotNull(message.buyerP2PEncryptPublicKey));
|
||||||
takerTradeProcessModel.offerer.setFiatAccount(checkNotNull(message.offererFiatAccount));
|
takerTradeProcessModel.offerer.setFiatAccount(checkNotNull(message.buyerFiatAccount));
|
||||||
takerTradeProcessModel.offerer.setAccountId(nonEmptyStringOf(message.offererAccountId));
|
takerTradeProcessModel.offerer.setAccountId(nonEmptyStringOf(message.buyerAccountId));
|
||||||
|
|
||||||
complete();
|
complete();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.p2p.listener.SendMessageListener;
|
||||||
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
|
import io.bitsquare.trade.TakerTrade;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class TakerSendsDepositTxPublishedMessage extends TakerTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(TakerSendsDepositTxPublishedMessage.class);
|
||||||
|
|
||||||
|
public TakerSendsDepositTxPublishedMessage(TaskRunner taskHandler, TakerTrade takerTradeProcessModel) {
|
||||||
|
super(taskHandler, takerTradeProcessModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
DepositTxPublishedMessage tradeMessage = new DepositTxPublishedMessage(takerTradeProcessModel.getId(), takerTrade.getDepositTx());
|
||||||
|
|
||||||
|
takerTradeProcessModel.getMessageService().sendMessage(takerTrade.getTradingPeer(), tradeMessage, new SendMessageListener() {
|
||||||
|
@Override
|
||||||
|
public void handleResult() {
|
||||||
|
log.trace("DepositTxPublishedMessage successfully arrived at peer");
|
||||||
|
complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleFault() {
|
||||||
|
appendToErrorMessage("Sending DepositTxPublishedMessage failed");
|
||||||
|
takerTrade.setErrorMessage(errorMessage);
|
||||||
|
|
||||||
|
if (takerTrade instanceof TakerAsBuyerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsBuyerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
|
||||||
|
failed();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
takerTrade.setThrowable(t);
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.p2p.listener.SendMessageListener;
|
||||||
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
|
import io.bitsquare.trade.TakerTrade;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class TakerSendsFiatTransferStartedMessage extends TakerTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(TakerSendsFiatTransferStartedMessage.class);
|
||||||
|
|
||||||
|
public TakerSendsFiatTransferStartedMessage(TaskRunner taskHandler, TakerTrade takerTradeProcessModel) {
|
||||||
|
super(taskHandler, takerTradeProcessModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
FiatTransferStartedMessage tradeMessage = new FiatTransferStartedMessage(takerTradeProcessModel.getId(),
|
||||||
|
takerTradeProcessModel.taker.getPayoutTxSignature(),
|
||||||
|
takerTradeProcessModel.offerer.getPayoutAmount(),
|
||||||
|
takerTradeProcessModel.taker.getPayoutAmount(),
|
||||||
|
takerTradeProcessModel.taker.getAddressEntry().getAddressString());
|
||||||
|
|
||||||
|
takerTradeProcessModel.getMessageService().sendMessage(takerTrade.getTradingPeer(), tradeMessage,
|
||||||
|
takerTradeProcessModel.taker.getP2pSigPubKey(),
|
||||||
|
takerTradeProcessModel.taker.getP2pEncryptPubKey(),
|
||||||
|
new SendMessageListener() {
|
||||||
|
@Override
|
||||||
|
public void handleResult() {
|
||||||
|
log.trace("Sending FiatTransferStartedMessage succeeded.");
|
||||||
|
|
||||||
|
if (takerTrade instanceof TakerAsBuyerTrade) {
|
||||||
|
takerTrade.setProcessState(TakerAsBuyerTrade.ProcessState.FIAT_PAYMENT_STARTED);
|
||||||
|
}
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade) {
|
||||||
|
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.FIAT_PAYMENT_STARTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleFault() {
|
||||||
|
appendToErrorMessage("Sending FiatTransferStartedMessage failed");
|
||||||
|
takerTrade.setErrorMessage(errorMessage);
|
||||||
|
|
||||||
|
if (takerTrade instanceof TakerAsBuyerTrade) {
|
||||||
|
((TakerAsBuyerTrade) takerTrade).setProcessState(TakerAsBuyerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
}
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade) {
|
||||||
|
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
failed();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
takerTrade.setThrowable(t);
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,16 +19,18 @@ package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
import io.bitsquare.p2p.listener.SendMessageListener;
|
import io.bitsquare.p2p.listener.SendMessageListener;
|
||||||
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
import io.bitsquare.trade.TakerTrade;
|
import io.bitsquare.trade.TakerTrade;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
|
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class SendPayoutTxPublishedMessage extends TakerTradeTask {
|
public class TakerSendsPayoutTxPublishedMessage extends TakerTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(SendPayoutTxPublishedMessage.class);
|
private static final Logger log = LoggerFactory.getLogger(TakerSendsPayoutTxPublishedMessage.class);
|
||||||
|
|
||||||
public SendPayoutTxPublishedMessage(TaskRunner taskHandler, TakerTrade model) {
|
public TakerSendsPayoutTxPublishedMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||||
super(taskHandler, model);
|
super(taskHandler, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +53,12 @@ public class SendPayoutTxPublishedMessage extends TakerTradeTask {
|
||||||
public void handleFault() {
|
public void handleFault() {
|
||||||
appendToErrorMessage("Sending PayoutTxPublishedMessage failed");
|
appendToErrorMessage("Sending PayoutTxPublishedMessage failed");
|
||||||
takerTrade.setErrorMessage(errorMessage);
|
takerTrade.setErrorMessage(errorMessage);
|
||||||
takerTrade.setProcessState(TakerTrade.TakerProcessState.MESSAGE_SENDING_FAILED);
|
|
||||||
|
if (takerTrade instanceof TakerAsBuyerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsBuyerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
|
||||||
failed();
|
failed();
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -19,6 +19,8 @@ package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
import io.bitsquare.p2p.listener.SendMessageListener;
|
import io.bitsquare.p2p.listener.SendMessageListener;
|
||||||
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
import io.bitsquare.trade.TakerTrade;
|
import io.bitsquare.trade.TakerTrade;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.RequestDepositTxInputsMessage;
|
import io.bitsquare.trade.protocol.trade.messages.RequestDepositTxInputsMessage;
|
||||||
|
|
||||||
|
@ -27,10 +29,10 @@ import javafx.application.Platform;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class SendRequestDepositTxInputsMessage extends TakerTradeTask {
|
public class TakerSendsRequestDepositTxInputsMessage extends TakerTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(SendRequestDepositTxInputsMessage.class);
|
private static final Logger log = LoggerFactory.getLogger(TakerSendsRequestDepositTxInputsMessage.class);
|
||||||
|
|
||||||
public SendRequestDepositTxInputsMessage(TaskRunner taskHandler, TakerTrade model) {
|
public TakerSendsRequestDepositTxInputsMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||||
super(taskHandler, model);
|
super(taskHandler, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +62,7 @@ public class SendRequestDepositTxInputsMessage extends TakerTradeTask {
|
||||||
// We try to repeat once and if that fails as well we persist the state for a later retry.
|
// We try to repeat once and if that fails as well we persist the state for a later retry.
|
||||||
if (retryCounter == 0) {
|
if (retryCounter == 0) {
|
||||||
retryCounter++;
|
retryCounter++;
|
||||||
Platform.runLater(SendRequestDepositTxInputsMessage.this::doRun);
|
Platform.runLater(TakerSendsRequestDepositTxInputsMessage.this::doRun);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
appendToErrorMessage("Sending TakeOfferFeePayedMessage to offerer failed. Maybe the network connection was " +
|
appendToErrorMessage("Sending TakeOfferFeePayedMessage to offerer failed. Maybe the network connection was " +
|
||||||
|
@ -68,7 +70,12 @@ public class SendRequestDepositTxInputsMessage extends TakerTradeTask {
|
||||||
"or cancel that trade.");
|
"or cancel that trade.");
|
||||||
|
|
||||||
takerTrade.setErrorMessage(errorMessage);
|
takerTrade.setErrorMessage(errorMessage);
|
||||||
takerTrade.setProcessState(TakerTrade.TakerProcessState.MESSAGE_SENDING_FAILED);
|
|
||||||
|
if (takerTrade instanceof TakerAsBuyerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsBuyerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
|
||||||
|
|
||||||
failed();
|
failed();
|
||||||
}
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.p2p.listener.SendMessageListener;
|
||||||
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
|
import io.bitsquare.trade.TakerTrade;
|
||||||
|
import io.bitsquare.trade.protocol.trade.messages.RequestPayDepositMessage;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class TakerSendsRequestPayDepositMessage extends TakerTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(TakerSendsRequestPayDepositMessage.class);
|
||||||
|
|
||||||
|
public TakerSendsRequestPayDepositMessage(TaskRunner taskHandler, TakerTrade takerTradeProcessModel) {
|
||||||
|
super(taskHandler, takerTradeProcessModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
RequestPayDepositMessage tradeMessage = new RequestPayDepositMessage(
|
||||||
|
takerTradeProcessModel.getId(),
|
||||||
|
takerTradeProcessModel.taker.getConnectedOutputsForAllInputs(),
|
||||||
|
takerTradeProcessModel.taker.getOutputs(),
|
||||||
|
takerTradeProcessModel.taker.getTradeWalletPubKey(),
|
||||||
|
takerTradeProcessModel.taker.getP2pSigPubKey(),
|
||||||
|
takerTradeProcessModel.taker.getP2pEncryptPubKey(),
|
||||||
|
takerTradeProcessModel.taker.getFiatAccount(),
|
||||||
|
takerTradeProcessModel.taker.getAccountId());
|
||||||
|
|
||||||
|
takerTradeProcessModel.getMessageService().sendMessage(takerTrade.getTradingPeer(), tradeMessage, new SendMessageListener() {
|
||||||
|
@Override
|
||||||
|
public void handleResult() {
|
||||||
|
log.trace("RequestTakerDepositPaymentMessage successfully arrived at peer");
|
||||||
|
complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleFault() {
|
||||||
|
appendToErrorMessage("Sending RequestTakerDepositPaymentMessage failed");
|
||||||
|
takerTrade.setErrorMessage(errorMessage);
|
||||||
|
if (takerTrade instanceof TakerAsBuyerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsBuyerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
|
||||||
|
failed();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
takerTrade.setThrowable(t);
|
||||||
|
|
||||||
|
if (takerTrade instanceof TakerAsBuyerTrade) {
|
||||||
|
takerTrade.setProcessState(TakerAsBuyerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
}
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade) {
|
||||||
|
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,16 +19,18 @@ package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
import io.bitsquare.p2p.listener.SendMessageListener;
|
import io.bitsquare.p2p.listener.SendMessageListener;
|
||||||
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
import io.bitsquare.trade.TakerTrade;
|
import io.bitsquare.trade.TakerTrade;
|
||||||
import io.bitsquare.trade.protocol.trade.messages.RequestPublishDepositTxMessage;
|
import io.bitsquare.trade.protocol.trade.messages.RequestPublishDepositTxMessage;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class SendRequestPublishDepositTxMessage extends TakerTradeTask {
|
public class TakerSendsRequestPublishDepositTxMessage extends TakerTradeTask {
|
||||||
private static final Logger log = LoggerFactory.getLogger(SendRequestPublishDepositTxMessage.class);
|
private static final Logger log = LoggerFactory.getLogger(TakerSendsRequestPublishDepositTxMessage.class);
|
||||||
|
|
||||||
public SendRequestPublishDepositTxMessage(TaskRunner taskHandler, TakerTrade model) {
|
public TakerSendsRequestPublishDepositTxMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||||
super(taskHandler, model);
|
super(taskHandler, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +60,11 @@ public class SendRequestPublishDepositTxMessage extends TakerTradeTask {
|
||||||
public void handleFault() {
|
public void handleFault() {
|
||||||
appendToErrorMessage("Sending RequestOffererPublishDepositTxMessage failed");
|
appendToErrorMessage("Sending RequestOffererPublishDepositTxMessage failed");
|
||||||
takerTrade.setErrorMessage(errorMessage);
|
takerTrade.setErrorMessage(errorMessage);
|
||||||
takerTrade.setProcessState(TakerTrade.TakerProcessState.MESSAGE_SENDING_FAILED);
|
|
||||||
|
if (takerTrade instanceof TakerAsBuyerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsBuyerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade)
|
||||||
|
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.MESSAGE_SENDING_FAILED);
|
||||||
|
|
||||||
failed();
|
failed();
|
||||||
}
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Bitsquare.
|
||||||
|
*
|
||||||
|
* Bitsquare 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.
|
||||||
|
*
|
||||||
|
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||||
|
|
||||||
|
import io.bitsquare.btc.FeePolicy;
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
|
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||||
|
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||||
|
import io.bitsquare.trade.TakerTrade;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Coin;
|
||||||
|
import org.bitcoinj.core.Transaction;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class TakerSignsAndPublishDepositTx extends TakerTradeTask {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(TakerSignsAndPublishDepositTx.class);
|
||||||
|
|
||||||
|
public TakerSignsAndPublishDepositTx(TaskRunner taskHandler, TakerTrade takerTradeProcessModel) {
|
||||||
|
super(taskHandler, takerTradeProcessModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
try {
|
||||||
|
Coin inputAmount = takerTrade.getSecurityDeposit().add(FeePolicy.TX_FEE);
|
||||||
|
|
||||||
|
takerTradeProcessModel.getTradeWalletService().signAndPublishDepositTx(
|
||||||
|
takerTradeProcessModel.offerer.getPreparedDepositTx(),
|
||||||
|
takerTradeProcessModel.offerer.getConnectedOutputsForAllInputs(),
|
||||||
|
takerTradeProcessModel.taker.getConnectedOutputsForAllInputs(),
|
||||||
|
takerTradeProcessModel.taker.getOutputs(),
|
||||||
|
inputAmount,
|
||||||
|
takerTradeProcessModel.offerer.getTradeWalletPubKey(),
|
||||||
|
takerTradeProcessModel.taker.getTradeWalletPubKey(),
|
||||||
|
takerTradeProcessModel.getArbitratorPubKey(),
|
||||||
|
new FutureCallback<Transaction>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(Transaction transaction) {
|
||||||
|
log.trace("takerSignAndPublishTx succeeded " + transaction);
|
||||||
|
|
||||||
|
takerTrade.setDepositTx(transaction);
|
||||||
|
|
||||||
|
if (takerTrade instanceof TakerAsBuyerTrade) {
|
||||||
|
takerTrade.setProcessState(TakerAsBuyerTrade.ProcessState.DEPOSIT_PUBLISHED);
|
||||||
|
takerTrade.setLifeCycleState(TakerAsBuyerTrade.LifeCycleState.PENDING);
|
||||||
|
}
|
||||||
|
else if (takerTrade instanceof TakerAsSellerTrade) {
|
||||||
|
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.DEPOSIT_PUBLISHED);
|
||||||
|
takerTrade.setLifeCycleState(TakerAsSellerTrade.LifeCycleState.PENDING);
|
||||||
|
}
|
||||||
|
|
||||||
|
complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NotNull Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
takerTrade.setThrowable(t);
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
takerTrade.setThrowable(t);
|
||||||
|
failed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue