mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 09:52:23 +01:00
Second trade process (WIP)
This commit is contained in:
parent
6e644ae2b7
commit
0700a53561
@ -310,22 +310,22 @@ public class TradeWalletService {
|
||||
return new Result(preparedDepositTx, takerConnectedOutputsForAllInputs, takerOutputs);
|
||||
}
|
||||
|
||||
public void offererSignsAndPublishDepositTx(Transaction takersPreparedDepositTx,
|
||||
List<TransactionOutput> offererConnectedOutputsForAllInputs,
|
||||
List<TransactionOutput> takerConnectedOutputsForAllInputs,
|
||||
List<TransactionOutput> offererOutputs,
|
||||
Coin offererInputAmount,
|
||||
byte[] offererPubKey,
|
||||
byte[] takerPubKey,
|
||||
byte[] arbitratorPubKey,
|
||||
FutureCallback<Transaction> callback) throws SigningException, TransactionVerificationException,
|
||||
public void signAndPublishDepositTx(Transaction preparedDepositTx,
|
||||
List<TransactionOutput> offererConnectedOutputsForAllInputs,
|
||||
List<TransactionOutput> takerConnectedOutputsForAllInputs,
|
||||
List<TransactionOutput> buyerOutputs,
|
||||
Coin buyerInputAmount,
|
||||
byte[] offererPubKey,
|
||||
byte[] takerPubKey,
|
||||
byte[] arbitratorPubKey,
|
||||
FutureCallback<Transaction> callback) throws SigningException, TransactionVerificationException,
|
||||
WalletException {
|
||||
log.trace("offererSignsAndPublishTx called");
|
||||
log.trace("takersPreparedDepositTx " + takersPreparedDepositTx.toString());
|
||||
log.trace("preparedDepositTx " + preparedDepositTx.toString());
|
||||
log.trace("offererConnectedOutputsForAllInputs " + offererConnectedOutputsForAllInputs.toString());
|
||||
log.trace("takerConnectedOutputsForAllInputs " + takerConnectedOutputsForAllInputs.toString());
|
||||
log.trace("offererOutputs " + offererOutputs.toString());
|
||||
log.trace("offererInputAmount " + offererInputAmount.toFriendlyString());
|
||||
log.trace("buyerOutputs " + buyerOutputs.toString());
|
||||
log.trace("buyerInputAmount " + buyerInputAmount.toFriendlyString());
|
||||
log.trace("offererPubKey " + ECKey.fromPublicOnly(offererPubKey).toString());
|
||||
log.trace("takerPubKey " + ECKey.fromPublicOnly(takerPubKey).toString());
|
||||
log.trace("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString());
|
||||
@ -335,10 +335,10 @@ public class TradeWalletService {
|
||||
|
||||
// Check if takers Multisig script is identical to mine
|
||||
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");
|
||||
|
||||
// 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
|
||||
Transaction depositTx = new Transaction(params);
|
||||
|
||||
@ -358,8 +358,8 @@ public class TradeWalletService {
|
||||
for (TransactionOutput connectedOutputForInput : takerConnectedOutputsForAllInputs) {
|
||||
TransactionOutPoint outPoint = new TransactionOutPoint(params, connectedOutputForInput.getIndex(), connectedOutputForInput.getParentTransaction());
|
||||
|
||||
// We grab the signature from the takersPreparedDepositTx and apply it to the new tx input
|
||||
TransactionInput takerInput = takersPreparedDepositTx.getInputs().get(offererConnectedOutputsForAllInputs.size());
|
||||
// We grab the signature from the preparedDepositTx and apply it to the new tx input
|
||||
TransactionInput takerInput = preparedDepositTx.getInputs().get(offererConnectedOutputsForAllInputs.size());
|
||||
byte[] scriptProgram = takerInput.getScriptSig().getProgram();
|
||||
if (scriptProgram.length == 0)
|
||||
throw new TransactionVerificationException("Inputs from taker not singed.");
|
||||
@ -368,8 +368,8 @@ public class TradeWalletService {
|
||||
depositTx.addInput(transactionInput);
|
||||
}
|
||||
|
||||
// Add all outputs from takersPreparedDepositTx to depositTx
|
||||
takersPreparedDepositTx.getOutputs().forEach(depositTx::addOutput);
|
||||
// Add all outputs from preparedDepositTx to depositTx
|
||||
preparedDepositTx.getOutputs().forEach(depositTx::addOutput);
|
||||
|
||||
// Sign inputs
|
||||
for (int i = 0; i < offererConnectedOutputsForAllInputs.size(); i++) {
|
||||
@ -379,11 +379,11 @@ public class TradeWalletService {
|
||||
}
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
if (offererInputAmount.compareTo(offererSpendingAmount) != 0)
|
||||
if (buyerInputAmount.compareTo(offererSpendingAmount) != 0)
|
||||
throw new TransactionVerificationException("Offerers input amount does not match required value.");
|
||||
|
||||
verifyTransaction(depositTx);
|
||||
@ -416,37 +416,37 @@ public class TradeWalletService {
|
||||
return wallet.getTransaction(tx.getHash());
|
||||
}
|
||||
|
||||
public byte[] offererCreatesAndSignsPayoutTx(Transaction depositTx,
|
||||
Coin offererPayoutAmount,
|
||||
Coin takerPayoutAmount,
|
||||
AddressEntry offererAddressEntry,
|
||||
String takerPayoutAddressString,
|
||||
byte[] offererPubKey,
|
||||
byte[] takerPubKey,
|
||||
byte[] arbitratorPubKey)
|
||||
public byte[] createAndSignPayoutTx(Transaction depositTx,
|
||||
Coin offererPayoutAmount,
|
||||
Coin takerPayoutAmount,
|
||||
AddressEntry buyerAddressEntry,
|
||||
String sellerPayoutAddressString,
|
||||
byte[] offererPubKey,
|
||||
byte[] takerPubKey,
|
||||
byte[] arbitratorPubKey)
|
||||
throws AddressFormatException, TransactionVerificationException, SigningException {
|
||||
log.trace("offererCreatesAndSignsPayoutTx called");
|
||||
log.trace("depositTx " + depositTx.toString());
|
||||
log.trace("offererPayoutAmount " + offererPayoutAmount.toFriendlyString());
|
||||
log.trace("takerPayoutAmount " + takerPayoutAmount.toFriendlyString());
|
||||
log.trace("offererAddressEntry " + offererAddressEntry.toString());
|
||||
log.trace("takerPayoutAddressString " + takerPayoutAddressString);
|
||||
log.trace("buyerAddressEntry " + buyerAddressEntry.toString());
|
||||
log.trace("sellerPayoutAddressString " + sellerPayoutAddressString);
|
||||
log.trace("offererPubKey " + ECKey.fromPublicOnly(offererPubKey).toString());
|
||||
log.trace("takerPubKey " + ECKey.fromPublicOnly(takerPubKey).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");
|
||||
|
||||
Transaction preparedPayoutTx = createPayoutTx(depositTx,
|
||||
offererPayoutAmount,
|
||||
takerPayoutAmount,
|
||||
offererAddressEntry.getAddressString(),
|
||||
takerPayoutAddressString);
|
||||
buyerAddressEntry.getAddressString(),
|
||||
sellerPayoutAddressString);
|
||||
// MS redeemScript
|
||||
Script redeemScript = getMultiSigRedeemScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
||||
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);
|
||||
|
||||
@ -459,40 +459,40 @@ public class TradeWalletService {
|
||||
return offererSignature.encodeToDER();
|
||||
}
|
||||
|
||||
public void takerSignsAndPublishPayoutTx(Transaction depositTx,
|
||||
byte[] offererSignature,
|
||||
Coin offererPayoutAmount,
|
||||
Coin takerPayoutAmount,
|
||||
String offererAddressString,
|
||||
AddressEntry takerAddressEntry,
|
||||
byte[] offererPubKey,
|
||||
byte[] takerPubKey,
|
||||
byte[] arbitratorPubKey,
|
||||
FutureCallback<Transaction> callback)
|
||||
public void signAndPublishPayoutTx(Transaction depositTx,
|
||||
byte[] buyerSignature,
|
||||
Coin offererPayoutAmount,
|
||||
Coin takerPayoutAmount,
|
||||
String buyerAddressString,
|
||||
AddressEntry sellerAddressEntry,
|
||||
byte[] offererPubKey,
|
||||
byte[] takerPubKey,
|
||||
byte[] arbitratorPubKey,
|
||||
FutureCallback<Transaction> callback)
|
||||
throws AddressFormatException, TransactionVerificationException, WalletException, SigningException {
|
||||
log.trace("takerSignsAndPublishPayoutTx called");
|
||||
log.trace("depositTx " + depositTx.toString());
|
||||
log.trace("offererSignature r " + ECKey.ECDSASignature.decodeFromDER(offererSignature).r.toString());
|
||||
log.trace("offererSignature s " + ECKey.ECDSASignature.decodeFromDER(offererSignature).s.toString());
|
||||
log.trace("buyerSignature r " + ECKey.ECDSASignature.decodeFromDER(buyerSignature).r.toString());
|
||||
log.trace("buyerSignature s " + ECKey.ECDSASignature.decodeFromDER(buyerSignature).s.toString());
|
||||
log.trace("offererPayoutAmount " + offererPayoutAmount.toFriendlyString());
|
||||
log.trace("takerPayoutAmount " + takerPayoutAmount.toFriendlyString());
|
||||
log.trace("offererAddressString " + offererAddressString);
|
||||
log.trace("takerAddressEntry " + takerAddressEntry);
|
||||
log.trace("buyerAddressString " + buyerAddressString);
|
||||
log.trace("sellerAddressEntry " + sellerAddressEntry);
|
||||
log.trace("offererPubKey " + ECKey.fromPublicOnly(offererPubKey).toString());
|
||||
log.trace("takerPubKey " + ECKey.fromPublicOnly(takerPubKey).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");
|
||||
|
||||
Transaction payoutTx = createPayoutTx(depositTx,
|
||||
offererPayoutAmount,
|
||||
takerPayoutAmount,
|
||||
offererAddressString,
|
||||
takerAddressEntry.getAddressString());
|
||||
buyerAddressString,
|
||||
sellerAddressEntry.getAddressString());
|
||||
Script redeemScript = getMultiSigRedeemScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
||||
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 s " + takerSignature.s.toString());
|
||||
@ -500,7 +500,7 @@ public class TradeWalletService {
|
||||
Sha256Hash hashForSignature = payoutTx.hashForSignature(0, redeemScript.getProgram(), (byte) 1);
|
||||
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);
|
||||
TransactionSignature takerTxSig = new TransactionSignature(takerSignature, Transaction.SigHash.ALL, false);
|
||||
// Take care of order of signatures. See comment below at getMultiSigRedeemScript
|
||||
|
@ -45,7 +45,7 @@ public class TaskRunner<T extends Model> {
|
||||
this.resultHandler = resultHandler;
|
||||
this.errorMessageHandler = errorMessageHandler;
|
||||
}
|
||||
|
||||
|
||||
public final void addTasks(Class<? extends Task<? extends Model>>... items) {
|
||||
List<Class<? extends Task<? extends Model>>> list = Arrays.asList(items);
|
||||
tasks.addAll(list);
|
||||
@ -61,7 +61,19 @@ public class TaskRunner<T extends Model> {
|
||||
try {
|
||||
currentTask = tasks.poll();
|
||||
log.trace("Run task: " + currentTask.getSimpleName());
|
||||
currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass()).newInstance(this, sharedModel).run();
|
||||
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();
|
||||
} catch (Throwable throwable) {
|
||||
currentTask.getDeclaredConstructor(TaskRunner.class, sharedModel.getClass().getSuperclass()).newInstance(this, sharedModel).run();
|
||||
}
|
||||
} catch (Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
handleErrorMessage("Error at taskRunner: " + throwable.getMessage());
|
||||
|
@ -22,6 +22,7 @@ lower gradient color on tab: dddddd
|
||||
.root {
|
||||
-bs-grey: #666666;
|
||||
-bs-bg-grey: #dddddd;
|
||||
-bs-bg-green: #00aa33;
|
||||
-bs-error-red: #dd0000;
|
||||
|
||||
-fx-accent: #0f87c3;
|
||||
@ -466,6 +467,42 @@ textfield */
|
||||
-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 */
|
||||
#titled-group-bg-label {
|
||||
-fx-font-weight: bold;
|
||||
|
@ -91,9 +91,9 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
|
||||
setDisable(true); // alpha
|
||||
}};
|
||||
ToggleButton settingsButton = new NavButton(SettingsView.class, "Settings");
|
||||
ToggleButton accountButton = new NavButton(AccountView.class, "Account") {{
|
||||
ToggleButton accountButton = new NavButton(AccountView.class, "Account"); /*{{
|
||||
setDisable(true); // alpha
|
||||
}};
|
||||
}};*/
|
||||
Pane portfolioButtonHolder = new Pane(portfolioButton);
|
||||
Pane bankAccountComboBoxHolder = new Pane();
|
||||
|
||||
|
@ -118,7 +118,7 @@ public class AccountView extends ActivatableView<TabPane, AccountViewModel> {
|
||||
}
|
||||
|
||||
// for IRC demo we deactivate the arbitratorSettingsTab
|
||||
arbitratorSettingsTab.setDisable(true);
|
||||
// arbitratorSettingsTab.setDisable(true);
|
||||
|
||||
tab.setContent(view.getRoot());
|
||||
root.getSelectionModel().select(tab);
|
||||
|
@ -28,6 +28,7 @@ import javax.inject.Inject;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.*;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
@ -69,6 +70,10 @@ public class ArbitratorSettingsView extends AbstractView {
|
||||
stage.initOwner(primaryStage);
|
||||
Scene scene = new Scene((Parent) view.getRoot(), 800, 600);
|
||||
stage.setScene(scene);
|
||||
stage.setOnCloseRequest(e -> {
|
||||
// need to unset root to be re-uasabel to other popups screens
|
||||
scene.setRoot(new Pane());
|
||||
});
|
||||
stage.show();
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
* 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.DataModel;
|
||||
@ -33,7 +33,7 @@ import javafx.beans.property.StringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
class IrcAccountDataModel implements Activatable, DataModel {
|
||||
class AltCoinAccountDataModel implements Activatable, DataModel {
|
||||
|
||||
private final User user;
|
||||
|
||||
@ -48,7 +48,7 @@ class IrcAccountDataModel implements Activatable, DataModel {
|
||||
|
||||
|
||||
@Inject
|
||||
public IrcAccountDataModel(User user) {
|
||||
public AltCoinAccountDataModel(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?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"
|
||||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="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/>.
|
||||
*/
|
||||
|
||||
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.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.
|
||||
*/
|
||||
@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 InputTextField ircNickNameTextField;
|
||||
@ -51,7 +51,7 @@ public class IrcAccountView extends ActivatableViewAndModel<GridPane, IrcAccount
|
||||
private Wizard wizard;
|
||||
|
||||
@Inject
|
||||
public IrcAccountView(IrcAccountViewModel model) {
|
||||
public AltCoinAccountView(AltCoinAccountViewModel model) {
|
||||
super(model);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
* 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.ViewModel;
|
||||
@ -36,7 +36,7 @@ import javafx.beans.property.StringProperty;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
class IrcAccountViewModel extends ActivatableWithDataModel<IrcAccountDataModel> implements ViewModel {
|
||||
class AltCoinAccountViewModel extends ActivatableWithDataModel<AltCoinAccountDataModel> implements ViewModel {
|
||||
|
||||
private final InputValidator nickNameValidator;
|
||||
|
||||
@ -46,7 +46,7 @@ class IrcAccountViewModel extends ActivatableWithDataModel<IrcAccountDataModel>
|
||||
final ObjectProperty<FiatAccount.Type> type = new SimpleObjectProperty<>();
|
||||
|
||||
@Inject
|
||||
public IrcAccountViewModel(IrcAccountDataModel dataModel, BankAccountNumberValidator nickNameValidator) {
|
||||
public AltCoinAccountViewModel(AltCoinAccountDataModel dataModel, BankAccountNumberValidator nickNameValidator) {
|
||||
super(dataModel);
|
||||
this.nickNameValidator = nickNameValidator;
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
package io.bitsquare.gui.main.account.settings;
|
||||
|
||||
import io.bitsquare.BitsquareException;
|
||||
import io.bitsquare.common.viewfx.view.ActivatableViewAndModel;
|
||||
import io.bitsquare.common.viewfx.view.CachingViewLoader;
|
||||
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.account.AccountView;
|
||||
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.restrictions.RestrictionsView;
|
||||
import io.bitsquare.gui.main.account.content.seedwords.SeedWordsView;
|
||||
@ -52,7 +51,7 @@ public class AccountSettingsView extends ActivatableViewAndModel {
|
||||
private final ViewLoader viewLoader;
|
||||
private final Navigation navigation;
|
||||
|
||||
private MenuItem seedWords, password, restrictions, ircAccount, registration;
|
||||
private MenuItem seedWords, password, restrictions, fiatAccount, registration;
|
||||
private Navigation.Listener listener;
|
||||
|
||||
@FXML private VBox leftVBox;
|
||||
@ -77,15 +76,10 @@ public class AccountSettingsView extends ActivatableViewAndModel {
|
||||
seedWords = new MenuItem(navigation, toggleGroup, "Wallet seed", SeedWordsView.class);
|
||||
password = new MenuItem(navigation, toggleGroup, "Wallet password", ChangePasswordView.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);
|
||||
|
||||
seedWords.setDisable(true);
|
||||
password.setDisable(true);
|
||||
restrictions.setDisable(true);
|
||||
registration.setDisable(true);
|
||||
|
||||
leftVBox.getChildren().addAll(seedWords, password, restrictions, ircAccount, registration);
|
||||
leftVBox.getChildren().addAll(seedWords, password, restrictions, fiatAccount, registration);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -93,7 +87,7 @@ public class AccountSettingsView extends ActivatableViewAndModel {
|
||||
navigation.addListener(listener);
|
||||
ViewPath viewPath = navigation.getCurrentPath();
|
||||
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) {
|
||||
loadView(viewPath.get(3));
|
||||
@ -114,9 +108,8 @@ public class AccountSettingsView extends ActivatableViewAndModel {
|
||||
if (view instanceof SeedWordsView) seedWords.setSelected(true);
|
||||
else if (view instanceof ChangePasswordView) password.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 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.gui.Navigation;
|
||||
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.registration.RegistrationView;
|
||||
import io.bitsquare.gui.main.account.content.restrictions.RestrictionsView;
|
||||
@ -46,7 +46,7 @@ public class AccountSetupWizard extends ActivatableView implements Wizard {
|
||||
@FXML VBox leftVBox;
|
||||
@FXML AnchorPane content;
|
||||
|
||||
private WizardItem seedWords, password, ircAccount, restrictions, registration;
|
||||
private WizardItem seedWords, password, fiatAccount, restrictions, registration;
|
||||
private Navigation.Listener listener;
|
||||
|
||||
private final ViewLoader viewLoader;
|
||||
@ -78,17 +78,17 @@ public class AccountSetupWizard extends ActivatableView implements Wizard {
|
||||
password.onCompleted();
|
||||
restrictions.show();
|
||||
}
|
||||
else if (viewClass == IrcAccountView.class) {
|
||||
else if (viewClass == FiatAccountView.class) {
|
||||
seedWords.onCompleted();
|
||||
password.onCompleted();
|
||||
restrictions.onCompleted();
|
||||
ircAccount.show();
|
||||
fiatAccount.show();
|
||||
}
|
||||
else if (viewClass == RegistrationView.class) {
|
||||
seedWords.onCompleted();
|
||||
password.onCompleted();
|
||||
restrictions.onCompleted();
|
||||
ircAccount.onCompleted();
|
||||
fiatAccount.onCompleted();
|
||||
registration.show();
|
||||
}
|
||||
};
|
||||
@ -99,23 +99,18 @@ public class AccountSetupWizard extends ActivatableView implements Wizard {
|
||||
"Setup password", "Protect your wallet with a password");
|
||||
restrictions = new WizardItem(RestrictionsView.class,
|
||||
"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");
|
||||
registration = new WizardItem(RegistrationView.class,
|
||||
"Register your account", "The registration in the Blockchain requires a payment of 0.0002 BTC");
|
||||
|
||||
leftVBox.getChildren().addAll(seedWords, password, restrictions, ircAccount, registration);
|
||||
|
||||
seedWords.setDisable(true);
|
||||
password.setDisable(true);
|
||||
restrictions.setDisable(true);
|
||||
registration.setDisable(true);
|
||||
leftVBox.getChildren().addAll(seedWords, password, restrictions, fiatAccount, registration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
navigation.addListener(listener);
|
||||
ircAccount.show();
|
||||
seedWords.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -135,10 +130,10 @@ public class AccountSetupWizard extends ActivatableView implements Wizard {
|
||||
}
|
||||
else if (currentStep instanceof RestrictionsView) {
|
||||
restrictions.onCompleted();
|
||||
ircAccount.show();
|
||||
fiatAccount.show();
|
||||
}
|
||||
else if (currentStep instanceof IrcAccountView) {
|
||||
ircAccount.onCompleted();
|
||||
else if (currentStep instanceof FiatAccountView) {
|
||||
fiatAccount.onCompleted();
|
||||
registration.show();
|
||||
}
|
||||
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.CreateOfferFeeTx;
|
||||
import io.bitsquare.trade.protocol.placeoffer.tasks.ValidateOffer;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.OffererProtocol;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.CreateAndSignPayoutTx;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.CreateOffererDepositTxInputs;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessPayoutTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessRequestDepositTxInputsMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessRequestPublishDepositTxMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendRequestTakerDepositPaymentMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendFiatTransferStartedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendDepositTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SignAndPublishDepositTx;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyAndSignContract;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.OffererAsBuyerProtocol;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererCreatesAndSignPayoutTx;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererCreatesDepositTxInputs;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererProcessPayoutTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererProcessRequestDepositTxInputsMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererProcessRequestPublishDepositTxMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSendsRequestSellerDepositPaymentMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSendsFiatTransferStartedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSendsDepositTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSignsAndPublishDepositTx;
|
||||
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.VerifyTakerAccount;
|
||||
import io.bitsquare.trade.protocol.trade.taker.TakerProtocol;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.CreateAndSignContract;
|
||||
import io.bitsquare.trade.protocol.trade.taker.TakerAsSellerProtocol;
|
||||
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.ProcessDepositTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.ProcessFiatTransferStartedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.ProcessRequestTakerDepositPaymentMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendPayoutTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendRequestDepositTxInputsMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendRequestPublishDepositTxMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SignAndPublishPayoutTx;
|
||||
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.TakerProcessDepositTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerProcessFiatTransferStartedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerProcessRequestSellerDepositPaymentMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSendsPayoutTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSendsRequestDepositTxInputsMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSendsRequestPublishDepositTxMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSignsAndPublishPayoutTx;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCommitDepositTx;
|
||||
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.VerifyOffererAccount;
|
||||
|
||||
@ -100,44 +100,44 @@ public class DebugView extends InitializableView {
|
||||
|
||||
|
||||
/*---- Protocol ----*/
|
||||
OffererProtocol.class,
|
||||
ProcessRequestDepositTxInputsMessage.class,
|
||||
CreateOffererDepositTxInputs.class,
|
||||
SendRequestTakerDepositPaymentMessage.class,
|
||||
OffererAsBuyerProtocol.class,
|
||||
OffererProcessRequestDepositTxInputsMessage.class,
|
||||
OffererCreatesDepositTxInputs.class,
|
||||
OffererSendsRequestSellerDepositPaymentMessage.class,
|
||||
|
||||
ProcessRequestPublishDepositTxMessage.class,
|
||||
OffererProcessRequestPublishDepositTxMessage.class,
|
||||
VerifyTakerAccount.class,
|
||||
VerifyAndSignContract.class,
|
||||
SignAndPublishDepositTx.class,
|
||||
SendDepositTxPublishedMessage.class,
|
||||
OffererVerifiesAndSignsContract.class,
|
||||
OffererSignsAndPublishDepositTx.class,
|
||||
OffererSendsDepositTxPublishedMessage.class,
|
||||
|
||||
CreateAndSignPayoutTx.class,
|
||||
OffererCreatesAndSignPayoutTx.class,
|
||||
VerifyTakeOfferFeePayment.class,
|
||||
SendFiatTransferStartedMessage.class,
|
||||
OffererSendsFiatTransferStartedMessage.class,
|
||||
|
||||
ProcessPayoutTxPublishedMessage.class,
|
||||
OffererProcessPayoutTxPublishedMessage.class,
|
||||
Boolean.class, /* used as seperator*/
|
||||
|
||||
|
||||
/*---- Protocol ----*/
|
||||
TakerProtocol.class,
|
||||
TakerAsSellerProtocol.class,
|
||||
CreateTakeOfferFeeTx.class,
|
||||
SendRequestDepositTxInputsMessage.class,
|
||||
TakerSendsRequestDepositTxInputsMessage.class,
|
||||
|
||||
ProcessRequestTakerDepositPaymentMessage.class,
|
||||
TakerProcessRequestSellerDepositPaymentMessage.class,
|
||||
VerifyOffererAccount.class,
|
||||
CreateAndSignContract.class,
|
||||
CreateAndSignDepositTx.class,
|
||||
SendRequestPublishDepositTxMessage.class,
|
||||
TakerCreatesAndSignContract.class,
|
||||
TakerCreatesAndSignsDepositTx.class,
|
||||
TakerSendsRequestPublishDepositTxMessage.class,
|
||||
|
||||
ProcessDepositTxPublishedMessage.class,
|
||||
CommitDepositTx.class,
|
||||
TakerProcessDepositTxPublishedMessage.class,
|
||||
TakerCommitDepositTx.class,
|
||||
|
||||
ProcessFiatTransferStartedMessage.class,
|
||||
TakerProcessFiatTransferStartedMessage.class,
|
||||
|
||||
SignAndPublishPayoutTx.class,
|
||||
TakerSignsAndPublishPayoutTx.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.ViewModel;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.trade.OffererTrade;
|
||||
import io.bitsquare.trade.TakerTrade;
|
||||
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||
import io.bitsquare.trade.Trade;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
@ -71,8 +71,8 @@ class ClosedTradesViewModel extends ActivatableWithDataModel<ClosedTradesDataMod
|
||||
String getState(ClosedTradesListItem item) {
|
||||
if (item != null && item.getTrade() != null) {
|
||||
Trade.LifeCycleState lifeCycleState = item.getTrade().lifeCycleStateProperty().get();
|
||||
if (lifeCycleState instanceof TakerTrade.TakerLifeCycleState) {
|
||||
switch ((TakerTrade.TakerLifeCycleState) lifeCycleState) {
|
||||
if (lifeCycleState instanceof TakerAsBuyerTrade.LifeCycleState) {
|
||||
switch ((TakerAsBuyerTrade.LifeCycleState) lifeCycleState) {
|
||||
case COMPLETED:
|
||||
return "Completed";
|
||||
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.");
|
||||
}
|
||||
}
|
||||
else if (lifeCycleState instanceof OffererTrade.OffererLifeCycleState) {
|
||||
switch ((OffererTrade.OffererLifeCycleState) lifeCycleState) {
|
||||
else if (lifeCycleState instanceof OffererAsSellerTrade.LifeCycleState) {
|
||||
switch ((OffererAsSellerTrade.LifeCycleState) lifeCycleState) {
|
||||
case OFFER_CANCELED:
|
||||
return "Canceled";
|
||||
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 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.gui.components.Popups;
|
||||
import io.bitsquare.offer.Offer;
|
||||
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||
import io.bitsquare.trade.OffererTrade;
|
||||
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||
import io.bitsquare.trade.TakerTrade;
|
||||
import io.bitsquare.trade.Trade;
|
||||
import io.bitsquare.trade.TradeManager;
|
||||
@ -35,6 +37,8 @@ import com.google.inject.Inject;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
@ -65,8 +69,8 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
||||
final StringProperty txId = new SimpleStringProperty();
|
||||
final IntegerProperty selectedIndex = new SimpleIntegerProperty(-1);
|
||||
|
||||
final ObjectProperty<TakerTrade.TakerProcessState> takerProcessState = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<OffererTrade.OffererProcessState> offererProcessState = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Trade.ProcessState> takerProcessState = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Trade.ProcessState> offererProcessState = new SimpleObjectProperty<>();
|
||||
|
||||
@Inject
|
||||
public PendingTradesDataModel(TradeManager tradeManager, WalletService walletService, User user) {
|
||||
@ -115,10 +119,10 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
||||
isOfferer = getTrade().getOffer().getP2PSigPubKey().equals(user.getP2PSigPubKey());
|
||||
|
||||
Trade trade = getTrade();
|
||||
if (trade instanceof TakerTrade)
|
||||
takerProcessState.bind(((TakerTrade) trade).processStateProperty());
|
||||
if (trade instanceof TakerAsSellerTrade)
|
||||
takerProcessState.bind(trade.processStateProperty());
|
||||
else
|
||||
offererProcessState.bind(((OffererTrade) trade).processStateProperty());
|
||||
offererProcessState.bind(trade.processStateProperty());
|
||||
|
||||
log.trace("selectTrade trade.stateProperty().get() " + trade.processStateProperty().get());
|
||||
|
||||
@ -127,11 +131,11 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
||||
}
|
||||
|
||||
void fiatPaymentStarted() {
|
||||
((OffererTrade) getTrade()).onFiatPaymentStarted();
|
||||
((OffererAsBuyerTrade) getTrade()).onFiatPaymentStarted();
|
||||
}
|
||||
|
||||
void fiatPaymentReceived() {
|
||||
((TakerTrade) getTrade()).onFiatPaymentReceived();
|
||||
((TakerAsSellerTrade) getTrade()).onFiatPaymentReceived();
|
||||
}
|
||||
|
||||
void withdraw(String toAddress) {
|
||||
@ -180,8 +184,9 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
||||
return isOfferer;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Trade getTrade() {
|
||||
return selectedItem.getTrade();
|
||||
return selectedItem != null ? selectedItem.getTrade() : null;
|
||||
}
|
||||
|
||||
Coin getTotalFees() {
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
package io.bitsquare.gui.main.portfolio.pending;
|
||||
|
||||
import io.bitsquare.trade.OffererTrade;
|
||||
import io.bitsquare.trade.TakerTrade;
|
||||
import io.bitsquare.trade.Trade;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
@ -51,11 +53,17 @@ public class PendingTradesListItem {
|
||||
}
|
||||
|
||||
public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
|
||||
return trade.tradeAmountProperty();
|
||||
if (trade instanceof TakerTrade)
|
||||
return ((TakerTrade) trade).tradeAmountProperty();
|
||||
else
|
||||
return ((OffererTrade) trade).tradeAmountProperty();
|
||||
}
|
||||
|
||||
public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() {
|
||||
return trade.tradeVolumeProperty();
|
||||
if (trade instanceof TakerTrade)
|
||||
return ((TakerTrade) trade).tradeVolumeProperty();
|
||||
else
|
||||
return ((OffererTrade) trade).tradeVolumeProperty();
|
||||
}
|
||||
|
||||
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.validation.BtcAddressValidator;
|
||||
import io.bitsquare.locale.BSResources;
|
||||
import io.bitsquare.trade.OffererTrade;
|
||||
import io.bitsquare.trade.TakerTrade;
|
||||
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.utils.Fiat;
|
||||
@ -240,79 +242,160 @@ class PendingTradesViewModel extends ActivatableWithDataModel<PendingTradesDataM
|
||||
}
|
||||
|
||||
private void updateTakerState() {
|
||||
TakerTrade.TakerProcessState 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;
|
||||
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 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_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 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;
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateOffererState() {
|
||||
OffererTrade.OffererProcessState 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;
|
||||
if (dataModel.getTrade() instanceof OffererAsBuyerTrade) {
|
||||
OffererAsBuyerTrade.ProcessState processState = (OffererAsBuyerTrade.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 FIAT_PAYMENT_STARTED:
|
||||
viewState.set(ViewState.OFFERER_BUYER_WAIT_CONFIRM_PAYMENT_RECEIVED);
|
||||
break;
|
||||
|
||||
case PAYOUT_PUBLISHED:
|
||||
viewState.set(ViewState.OFFERER_BUYER_COMPLETED);
|
||||
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;
|
||||
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;
|
||||
default:
|
||||
log.warn("unhandled viewState " + processState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
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.gui.Navigation;
|
||||
import io.bitsquare.gui.components.InputTextField;
|
||||
import io.bitsquare.gui.components.Popups;
|
||||
import io.bitsquare.gui.main.MainView;
|
||||
import io.bitsquare.gui.main.trade.createoffer.CreateOfferView;
|
||||
import io.bitsquare.gui.main.trade.offerbook.OfferBookView;
|
||||
@ -128,13 +127,6 @@ public abstract class TradeView extends ActivatableView<TabPane, Void> {
|
||||
OfferActionHandler offerActionHandler = new OfferActionHandler() {
|
||||
@Override
|
||||
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.price = price;
|
||||
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
|
||||
// in different graphs
|
||||
takeOfferView = (TakeOfferView) view;
|
||||
takeOfferView.initWithData(direction, amount, offer);
|
||||
takeOfferView.initWithData(amount, offer);
|
||||
takeOfferPane = ((TakeOfferView) view).getRoot();
|
||||
final Tab tab = new Tab("Take offer");
|
||||
takeOfferView.setCloseHandler(() -> {
|
||||
|
@ -75,7 +75,7 @@ class CreateOfferDataModel implements Activatable, DataModel {
|
||||
|
||||
private final String offerId;
|
||||
|
||||
@Nullable private Offer.Direction direction = null;
|
||||
private Offer.Direction direction;
|
||||
private AddressEntry addressEntry;
|
||||
|
||||
final StringProperty requestPlaceOfferErrorMessage = new SimpleStringProperty();
|
||||
@ -211,8 +211,12 @@ class CreateOfferDataModel implements Activatable, DataModel {
|
||||
}
|
||||
|
||||
void calculateTotalToPay() {
|
||||
if (securityDepositAsCoin.get() != null)
|
||||
totalToPayAsCoin.set(offerFeeAsCoin.get().add(networkFeeAsCoin.get()).add(securityDepositAsCoin.get()));
|
||||
if (securityDepositAsCoin.get() != null) {
|
||||
if (direction == Offer.Direction.BUY)
|
||||
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;
|
||||
}
|
||||
|
||||
@SuppressWarnings("NullableProblems")
|
||||
void setDirection(Offer.Direction direction) {
|
||||
// direction can not be changed once it is initially set
|
||||
checkNotNull(direction);
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
WalletService getWalletService() {
|
||||
return walletService;
|
||||
}
|
||||
@ -270,4 +267,9 @@ class CreateOfferDataModel implements Activatable, DataModel {
|
||||
public Boolean 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"/>
|
||||
</GridPane.margin>
|
||||
<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">
|
||||
<padding>
|
||||
<Insets top="-5.0"/>
|
||||
@ -64,7 +64,7 @@
|
||||
<Insets right="10.0" top="20.0"/>
|
||||
</GridPane.margin>
|
||||
<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"/>
|
||||
<HBox>
|
||||
<InputTextField fx:id="amountTextField" id="text-input-with-currency-text-field"
|
||||
@ -125,8 +125,7 @@
|
||||
</HBox>
|
||||
</VBox>
|
||||
|
||||
<InfoDisplay gridPane="$gridPane" onAction="#onOpenGeneralHelp" rowIndex="2"
|
||||
text="%createOffer.amountPriceBox.info"/>
|
||||
<InfoDisplay fx:id="amountPriceBoxInfo" gridPane="$gridPane" onAction="#onOpenGeneralHelp" rowIndex="2"/>
|
||||
|
||||
<Button fx:id="showPaymentInfoScreenButton" text="%createOffer.amountPriceBox.next" id="show-details-button"
|
||||
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.portfolio.PortfolioView;
|
||||
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.util.ImageUtil;
|
||||
import io.bitsquare.locale.BSResources;
|
||||
@ -80,14 +81,14 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
@FXML AddressTextField addressTextField;
|
||||
@FXML BalanceTextField balanceTextField;
|
||||
@FXML ProgressIndicator placeOfferSpinner;
|
||||
@FXML InfoDisplay advancedInfoDisplay, fundsBoxInfoDisplay;
|
||||
@FXML InfoDisplay amountPriceBoxInfo, advancedInfoDisplay, fundsBoxInfoDisplay;
|
||||
@FXML TitledGroupBg priceAmountPane, payFundsPane, showDetailsPane;
|
||||
@FXML Button showPaymentInfoScreenButton, showAdvancedSettingsButton, placeOfferButton;
|
||||
@FXML InputTextField amountTextField, minAmountTextField, priceTextField, volumeTextField;
|
||||
@FXML TextField acceptedArbitratorsTextField, totalToPayTextField, bankAccountTypeTextField,
|
||||
bankAccountCurrencyTextField, bankAccountCountyTextField, acceptedCountriesTextField,
|
||||
acceptedLanguagesTextField;
|
||||
@FXML Label buyLabel, addressLabel, balanceLabel, totalToPayLabel, totalToPayInfoIconLabel, bankAccountTypeLabel,
|
||||
@FXML Label buyLabel, amountToTradeLabel, addressLabel, balanceLabel, totalToPayLabel, totalToPayInfoIconLabel, bankAccountTypeLabel,
|
||||
bankAccountCurrencyLabel, bankAccountCountyLabel, acceptedCountriesLabel, acceptedCountriesLabelIcon,
|
||||
acceptedLanguagesLabel, acceptedLanguagesLabelIcon, acceptedArbitratorsLabel,
|
||||
acceptedArbitratorsLabelIcon, amountBtcLabel, priceFiatLabel, volumeFiatLabel, minAmountBtcLabel,
|
||||
@ -116,8 +117,8 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
protected void initialize() {
|
||||
setupListeners();
|
||||
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()));
|
||||
}
|
||||
|
||||
@ -292,10 +293,10 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
|
||||
model.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> {
|
||||
// TODO temp just for testing
|
||||
// newValue = false;
|
||||
// close();
|
||||
//navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class, OffersView.class);
|
||||
|
||||
newValue = false;
|
||||
close();
|
||||
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class, OffersView.class);
|
||||
|
||||
if (newValue) {
|
||||
overlayManager.blurContent();
|
||||
|
||||
@ -336,20 +337,17 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
minAmountBtcLabel.textProperty().bind(model.btcCode);
|
||||
|
||||
priceDescriptionLabel.textProperty().bind(createStringBinding(() ->
|
||||
BSResources.get("createOffer.amountPriceBox.priceDescription",
|
||||
model.fiatCode.get()),
|
||||
model.fiatCode));
|
||||
volumeDescriptionLabel.textProperty().bind(createStringBinding(() ->
|
||||
BSResources.get("createOffer.amountPriceBox.volumeDescription",
|
||||
model.fiatCode.get()),
|
||||
model.fiatCode));
|
||||
BSResources.get("createOffer.amountPriceBox.priceDescription", model.fiatCode.get()), model.fiatCode));
|
||||
|
||||
volumeDescriptionLabel.textProperty().bind(createStringBinding(() -> model.volumeDescriptionLabel.get(), model.fiatCode, model.volumeDescriptionLabel));
|
||||
|
||||
buyLabel.textProperty().bind(model.directionLabel);
|
||||
|
||||
amountToTradeLabel.textProperty().bind(model.amountToTradeLabel);
|
||||
amountTextField.textProperty().bindBidirectional(model.amount);
|
||||
minAmountTextField.textProperty().bindBidirectional(model.minAmount);
|
||||
priceTextField.textProperty().bindBidirectional(model.price);
|
||||
volumeTextField.textProperty().bindBidirectional(model.volume);
|
||||
amountPriceBoxInfo.textProperty().bind(model.amountPriceBoxInfo);
|
||||
|
||||
totalToPayTextField.textProperty().bind(model.totalToPay);
|
||||
|
||||
@ -471,19 +469,25 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
infoGridPane.setVgap(5);
|
||||
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"),
|
||||
model.securityDeposit.get());
|
||||
addPayInfoEntry(infoGridPane, 1, BSResources.get("createOffer.fundsBox.offerFee"),
|
||||
addPayInfoEntry(infoGridPane, i++, BSResources.get("createOffer.fundsBox.offerFee"),
|
||||
model.offerFee.get());
|
||||
addPayInfoEntry(infoGridPane, 2, BSResources.get("createOffer.fundsBox.networkFee"),
|
||||
addPayInfoEntry(infoGridPane, i++, BSResources.get("createOffer.fundsBox.networkFee"),
|
||||
model.networkFee.get());
|
||||
Separator separator = new Separator();
|
||||
separator.setOrientation(Orientation.HORIZONTAL);
|
||||
separator.setStyle("-fx-background: #666;");
|
||||
GridPane.setConstraints(separator, 1, 3);
|
||||
GridPane.setConstraints(separator, 1, i++);
|
||||
infoGridPane.getChildren().add(separator);
|
||||
addPayInfoEntry(infoGridPane, 4, BSResources.get("createOffer.fundsBox.total"),
|
||||
addPayInfoEntry(infoGridPane, i++, BSResources.get("createOffer.fundsBox.total"),
|
||||
model.totalToPay.get());
|
||||
totalToPayInfoPopover = new PopOver(infoGridPane);
|
||||
if (totalToPayInfoIconLabel.getScene() != null) {
|
||||
|
@ -50,13 +50,18 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||
private final BSFormatter formatter;
|
||||
private final FiatValidator fiatValidator;
|
||||
|
||||
|
||||
final StringProperty amount = new SimpleStringProperty();
|
||||
final StringProperty minAmount = new SimpleStringProperty();
|
||||
final StringProperty price = new SimpleStringProperty();
|
||||
final StringProperty volume = new SimpleStringProperty();
|
||||
final StringProperty volumeDescriptionLabel = new SimpleStringProperty();
|
||||
final StringProperty amountPriceBoxInfo = new SimpleStringProperty();
|
||||
final StringProperty securityDeposit = new SimpleStringProperty();
|
||||
final StringProperty tradeAmount = new SimpleStringProperty();
|
||||
final StringProperty totalToPay = new SimpleStringProperty();
|
||||
final StringProperty directionLabel = new SimpleStringProperty();
|
||||
final StringProperty amountToTradeLabel = new SimpleStringProperty();
|
||||
final StringProperty offerFee = new SimpleStringProperty();
|
||||
final StringProperty networkFee = new SimpleStringProperty();
|
||||
final StringProperty bankAccountType = new SimpleStringProperty();
|
||||
@ -113,9 +118,21 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||
|
||||
// setOfferBookFilter is a one time call
|
||||
void initWithData(Offer.Direction direction, Coin amount, Fiat price) {
|
||||
dataModel.setDirection(direction);
|
||||
directionLabel.set(dataModel.getDirection() == Offer.Direction.BUY ? BSResources.get("shared.buy") : BSResources.get
|
||||
("shared.sell"));
|
||||
dataModel.initWithData( direction, amount, price);
|
||||
|
||||
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
|
||||
boolean amountValid = false;
|
||||
@ -327,6 +344,9 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||
securityDeposit.bind(createStringBinding(() -> formatter.formatCoinWithCode(dataModel.securityDepositAsCoin.get()),
|
||||
dataModel.securityDepositAsCoin));
|
||||
|
||||
tradeAmount.bind(createStringBinding(() -> formatter.formatCoinWithCode(dataModel.amountAsCoin.get()),
|
||||
dataModel.amountAsCoin));
|
||||
|
||||
totalToPayAsCoin.bind(dataModel.totalToPayAsCoin);
|
||||
|
||||
offerFee.bind(createStringBinding(() -> formatter.formatCoinWithCode(dataModel.offerFeeAsCoin.get()),
|
||||
@ -407,4 +427,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||
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();
|
||||
|
||||
//TODO temp for testing
|
||||
/* amountTextField.setText("1");
|
||||
amountTextField.setText("1");
|
||||
priceTextField.setText("300");
|
||||
volumeTextField.setText("300");*/
|
||||
volumeTextField.setText("300");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -227,8 +227,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
||||
offerActionHandler.takeOffer(model.getAmountAsCoin(), model.getPriceAsCoin(), offer);
|
||||
}
|
||||
else {
|
||||
Popups.openInfoPopup("Not implemented yet",
|
||||
"At the moment you can only take offers in the Sell BTC screen.");
|
||||
offerActionHandler.takeOffer(model.getAmountAsCoin(), model.getPriceAsCoin(), offer);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -98,6 +98,7 @@ class TakeOfferDataModel implements Activatable, DataModel {
|
||||
|
||||
void initWithData(Coin amount, Offer offer) {
|
||||
this.offer = offer;
|
||||
securityDepositAsCoin.set(offer.getSecurityDeposit());
|
||||
|
||||
if (amount != null &&
|
||||
!amount.isGreaterThan(offer.getAmount()) &&
|
||||
@ -107,8 +108,7 @@ class TakeOfferDataModel implements Activatable, DataModel {
|
||||
else {
|
||||
amountAsCoin.set(offer.getAmount());
|
||||
}
|
||||
|
||||
securityDepositAsCoin.set(offer.getSecurityDeposit());
|
||||
|
||||
calculateVolume();
|
||||
calculateTotalToPay();
|
||||
|
||||
@ -143,17 +143,15 @@ class TakeOfferDataModel implements Activatable, DataModel {
|
||||
}
|
||||
|
||||
void calculateTotalToPay() {
|
||||
try {
|
||||
if (securityDepositAsCoin.get() != null) {
|
||||
totalToPayAsCoin.set(offerFeeAsCoin.get().add(amountAsCoin.get()).add(networkFeeAsCoin.get()).add
|
||||
(securityDepositAsCoin.get()));
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// Should be never reached
|
||||
log.error(t.toString());
|
||||
}
|
||||
if (getDirection() == Offer.Direction.SELL)
|
||||
totalToPayAsCoin.set(offerFeeAsCoin.get().add(networkFeeAsCoin.get()).add(securityDepositAsCoin.get()));
|
||||
else
|
||||
totalToPayAsCoin.set(offerFeeAsCoin.get().add(networkFeeAsCoin.get()).add(securityDepositAsCoin.get()).add(amountAsCoin.get()));
|
||||
}
|
||||
|
||||
Offer.Direction getDirection() {
|
||||
return offer.getDirection();
|
||||
}
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
boolean isMinAmountLessOrEqualAmount() {
|
||||
|
@ -67,8 +67,7 @@
|
||||
<Insets right="10.0" top="20.0"/>
|
||||
</GridPane.margin>
|
||||
<VBox spacing="4">
|
||||
<Label id="input-description-label" text="%takeOffer.amountPriceBox.amountDescription"
|
||||
prefWidth="170"/>
|
||||
<Label fx:id="amountDescriptionLabel" id="input-description-label" prefWidth="170"/>
|
||||
<HBox>
|
||||
<InputTextField fx:id="amountTextField" id="text-input-with-currency-text-field"
|
||||
promptText="%takeOffer.amount.prompt" prefWidth="170"
|
||||
@ -120,8 +119,7 @@
|
||||
style=" -fx-alignment: center;"/>
|
||||
</VBox>
|
||||
|
||||
<InfoDisplay gridPane="$gridPane" onAction="#onOpenGeneralHelp" rowIndex="2"
|
||||
text="%takeOffer.amountPriceBox.info"/>
|
||||
<InfoDisplay fx:id="amountPriceBoxInfoDisplay" gridPane="$gridPane" onAction="#onOpenGeneralHelp" rowIndex="2"/>
|
||||
|
||||
<Label fx:id="isOfferAvailableLabel" text="%takeOffer.fundsBox.isOfferAvailable" GridPane.rowIndex="3">
|
||||
<GridPane.margin>
|
||||
@ -179,8 +177,7 @@
|
||||
</GridPane.margin>
|
||||
</BalanceTextField>
|
||||
|
||||
<InfoDisplay fx:id="fundsBoxInfoDisplay" gridPane="$gridPane" onAction="#onOpenFundingHelp" rowIndex="7"
|
||||
text="%takeOffer.fundsBox.info" visible="false"/>
|
||||
<InfoDisplay fx:id="fundsBoxInfoDisplay" gridPane="$gridPane" onAction="#onOpenFundingHelp" rowIndex="7" visible="false"/>
|
||||
|
||||
<HBox spacing="10" GridPane.columnIndex="1" GridPane.rowIndex="8">
|
||||
<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.dialog.Dialog;
|
||||
|
||||
import static javafx.beans.binding.Bindings.createStringBinding;
|
||||
|
||||
@FxmlView
|
||||
public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOfferViewModel> {
|
||||
|
||||
@ -76,13 +78,13 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
@FXML AddressTextField addressTextField;
|
||||
@FXML BalanceTextField balanceTextField;
|
||||
@FXML ProgressIndicator takeOfferSpinner, isOfferAvailableProgressIndicator;
|
||||
@FXML InfoDisplay advancedInfoDisplay, fundsBoxInfoDisplay;
|
||||
@FXML InfoDisplay amountPriceBoxInfoDisplay, advancedInfoDisplay, fundsBoxInfoDisplay;
|
||||
@FXML TitledGroupBg priceAmountPane, payFundsPane, showDetailsPane;
|
||||
@FXML Button showPaymentInfoScreenButton, showAdvancedSettingsButton, takeOfferButton;
|
||||
@FXML TextField priceTextField, volumeTextField, acceptedArbitratorsTextField, totalToPayTextField,
|
||||
bankAccountTypeTextField, bankAccountCurrencyTextField, bankAccountCountyTextField,
|
||||
acceptedCountriesTextField, acceptedLanguagesTextField;
|
||||
@FXML Label isOfferAvailableLabel, buyLabel, addressLabel, amountRangeTextField, balanceLabel, totalToPayLabel,
|
||||
@FXML Label isOfferAvailableLabel, buyLabel, addressLabel, amountDescriptionLabel, amountRangeTextField, balanceLabel, totalToPayLabel,
|
||||
totalToPayInfoIconLabel,
|
||||
bankAccountTypeLabel, bankAccountCurrencyLabel, bankAccountCountyLabel, acceptedCountriesLabel,
|
||||
acceptedLanguagesLabel, acceptedArbitratorsLabel, amountBtcLabel, priceDescriptionLabel,
|
||||
@ -118,16 +120,17 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
model.errorMessage.removeListener(errorMessageChangeListener);
|
||||
}
|
||||
|
||||
public void initWithData(Offer.Direction direction, Coin amount, Offer offer) {
|
||||
model.initWithData(direction, amount, offer);
|
||||
public void initWithData(Coin amount, Offer offer) {
|
||||
model.initWithData(amount, offer);
|
||||
|
||||
if (direction == Offer.Direction.BUY)
|
||||
if (offer.getDirection() == Offer.Direction.SELL)
|
||||
imageView.setId("image-buy-large");
|
||||
else
|
||||
imageView.setId("image-sell-large");
|
||||
|
||||
priceDescriptionLabel.setText(BSResources.get("takeOffer.amountPriceBox.priceDescription", 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());
|
||||
|
||||
@ -144,6 +147,8 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
acceptedLanguagesTextField.setText(model.getAcceptedLanguages());
|
||||
acceptedArbitratorsTextField.setText(model.getAcceptedArbitratorIds());
|
||||
|
||||
amountPriceBoxInfoDisplay.textProperty().bind(model.amountPriceBoxInfo);
|
||||
fundsBoxInfoDisplay.textProperty().bind(model.fundsBoxInfoDisplay);
|
||||
showCheckAvailabilityScreen();
|
||||
}
|
||||
|
||||
@ -243,9 +248,9 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
|
||||
model.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> {
|
||||
// TODO temp just for testing
|
||||
/* newValue = false;
|
||||
close();*/
|
||||
//navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
|
||||
newValue = false;
|
||||
close();
|
||||
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
|
||||
|
||||
if (newValue) {
|
||||
overlayManager.blurContent();
|
||||
@ -287,7 +292,9 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
volumeTextField.textProperty().bindBidirectional(model.volume);
|
||||
totalToPayTextField.textProperty().bind(model.totalToPay);
|
||||
addressTextField.amountAsCoinProperty().bind(model.totalToPayAsCoin);
|
||||
|
||||
amountDescriptionLabel.textProperty().bind(model.amountDescription);
|
||||
|
||||
|
||||
// Validation
|
||||
amountTextField.validationResultProperty().bind(model.amountValidationResult);
|
||||
|
||||
@ -429,22 +436,27 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
infoGridPane.setVgap(5);
|
||||
infoGridPane.setPadding(new Insets(10, 10, 10, 10));
|
||||
|
||||
addPayInfoEntry(infoGridPane, 0,
|
||||
BSResources.get("takeOffer.fundsBox.amount"),
|
||||
model.getAmount());
|
||||
addPayInfoEntry(infoGridPane, 1,
|
||||
int i = 0;
|
||||
if (model.isSeller()) {
|
||||
addPayInfoEntry(infoGridPane, i++,
|
||||
BSResources.get("takeOffer.fundsBox.amount"),
|
||||
model.getAmount());
|
||||
}
|
||||
|
||||
|
||||
addPayInfoEntry(infoGridPane, i++,
|
||||
BSResources.get("takeOffer.fundsBox.securityDeposit"),
|
||||
model.securityDeposit.get());
|
||||
addPayInfoEntry(infoGridPane, 2, BSResources.get("takeOffer.fundsBox.offerFee"),
|
||||
addPayInfoEntry(infoGridPane, i++, BSResources.get("takeOffer.fundsBox.offerFee"),
|
||||
model.getOfferFee());
|
||||
addPayInfoEntry(infoGridPane, 3, BSResources.get("takeOffer.fundsBox.networkFee"),
|
||||
addPayInfoEntry(infoGridPane, i++, BSResources.get("takeOffer.fundsBox.networkFee"),
|
||||
model.getNetworkFee());
|
||||
Separator separator = new Separator();
|
||||
separator.setOrientation(Orientation.HORIZONTAL);
|
||||
separator.setStyle("-fx-background: #666;");
|
||||
GridPane.setConstraints(separator, 1, 4);
|
||||
GridPane.setConstraints(separator, 1, i++);
|
||||
infoGridPane.getChildren().add(separator);
|
||||
addPayInfoEntry(infoGridPane, 5, BSResources.get("takeOffer.fundsBox.total"),
|
||||
addPayInfoEntry(infoGridPane, i++, BSResources.get("takeOffer.fundsBox.total"),
|
||||
model.totalToPay.get());
|
||||
totalToPayInfoPopover = new PopOver(infoGridPane);
|
||||
if (totalToPayInfoIconLabel.getScene() != null) {
|
||||
|
@ -26,6 +26,8 @@ import io.bitsquare.gui.util.validation.InputValidator;
|
||||
import io.bitsquare.locale.BSResources;
|
||||
import io.bitsquare.locale.CurrencyUtil;
|
||||
import io.bitsquare.offer.Offer;
|
||||
import io.bitsquare.trade.TakerAsBuyerTrade;
|
||||
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||
|
||||
import org.bitcoinj.core.Address;
|
||||
import org.bitcoinj.core.Coin;
|
||||
@ -54,7 +56,6 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||
DETAILS_SCREEN
|
||||
}
|
||||
|
||||
private String fiatCode;
|
||||
private String amountRange;
|
||||
private String price;
|
||||
private String directionLabel;
|
||||
@ -85,7 +86,11 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||
final StringProperty transactionId = new SimpleStringProperty();
|
||||
final StringProperty errorMessage = 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 isTakeOfferSpinnerVisible = new SimpleBooleanProperty(false);
|
||||
@ -115,18 +120,31 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
directionLabel = direction == Offer.Direction.BUY ?
|
||||
BSResources.get("shared.buy") : BSResources.get("shared.sell");
|
||||
directionLabel = offer.getDirection() == Offer.Direction.SELL ?
|
||||
BSResources.get("shared.buyBitcoin") : BSResources.get("shared.sellBitcoin");
|
||||
|
||||
fiatCode = offer.getCurrencyCode();
|
||||
fiatCode.set(offer.getCurrencyCode());
|
||||
if (!dataModel.isMinAmountLessOrEqualAmount()) {
|
||||
amountValidationResult.set(new InputValidator.ValidationResult(false,
|
||||
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()));
|
||||
|
||||
amountRange = formatter.formatCoinWithCode(offer.getMinAmount()) + " - " +
|
||||
@ -210,39 +228,74 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||
dataModel.takeOffer((takerTrade) -> {
|
||||
takerTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
|
||||
log.debug("takerTrade state = " + newValue);
|
||||
|
||||
String msg = "";
|
||||
if (takerTrade.getErrorMessage() != null)
|
||||
msg = "\nError message: " + takerTrade.getErrorMessage();
|
||||
|
||||
switch (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 (takerTrade instanceof TakerAsBuyerTrade) {
|
||||
switch ((TakerAsBuyerTrade.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;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
@ -255,6 +308,10 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||
});
|
||||
}
|
||||
|
||||
boolean isSeller() {
|
||||
return dataModel.getDirection() == Offer.Direction.BUY;
|
||||
}
|
||||
|
||||
void securityDepositInfoDisplayed() {
|
||||
dataModel.securityDepositInfoDisplayed();
|
||||
}
|
||||
@ -307,7 +364,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
|
||||
}
|
||||
|
||||
String getFiatCode() {
|
||||
return fiatCode;
|
||||
return fiatCode.get();
|
||||
}
|
||||
|
||||
String getAmount() {
|
||||
|
@ -24,6 +24,6 @@ public class Colors {
|
||||
public static final Paint LIGHT_GREY = Color.valueOf("#CCCCCC");
|
||||
public static final Paint MID_GREY = Color.valueOf("#666666");
|
||||
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.storage.Storage;
|
||||
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 org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.TransactionConfidence;
|
||||
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.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
@ -43,12 +36,10 @@ import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
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.
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ -59,26 +50,10 @@ public class OffererTrade extends Trade implements Serializable {
|
||||
// Enum
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public enum OffererLifeCycleState implements LifeCycleState {
|
||||
OFFER_OPEN,
|
||||
OFFER_RESERVED,
|
||||
OFFER_CANCELED,
|
||||
PENDING,
|
||||
COMPLETED,
|
||||
FAILED
|
||||
public interface LifeCycleState extends Trade.LifeCycleState {
|
||||
}
|
||||
|
||||
public enum OffererProcessState implements ProcessState {
|
||||
UNDEFINED,
|
||||
DEPOSIT_PUBLISHED,
|
||||
DEPOSIT_CONFIRMED,
|
||||
|
||||
FIAT_PAYMENT_STARTED,
|
||||
|
||||
PAYOUT_PUBLISHED,
|
||||
|
||||
MESSAGE_SENDING_FAILED,
|
||||
EXCEPTION
|
||||
public interface ProcessState extends Trade.ProcessState {
|
||||
}
|
||||
|
||||
|
||||
@ -86,31 +61,23 @@ public class OffererTrade extends Trade implements Serializable {
|
||||
// Fields
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Transient/Immutable
|
||||
transient private ObjectProperty<OffererProcessState> processStateProperty;
|
||||
transient private ObjectProperty<OffererLifeCycleState> lifeCycleStateProperty;
|
||||
|
||||
// Mutable
|
||||
private Coin tradeAmount;
|
||||
private Peer tradingPeer;
|
||||
private OffererProcessState processState;
|
||||
private OffererLifeCycleState lifeCycleState;
|
||||
protected Coin tradeAmount;
|
||||
protected Peer tradingPeer;
|
||||
transient protected ObjectProperty<Coin> tradeAmountProperty;
|
||||
transient protected ObjectProperty<Fiat> tradeVolumeProperty;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, initialization
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public OffererTrade(Offer offer, Storage<? extends TradeList> storage) {
|
||||
protected OffererTrade(Offer offer, Storage<? extends TradeList> storage) {
|
||||
super(offer, storage);
|
||||
log.trace("Created by constructor");
|
||||
|
||||
processState = OffererProcessState.UNDEFINED;
|
||||
lifeCycleState = OffererLifeCycleState.OFFER_OPEN;
|
||||
|
||||
processStateProperty = new SimpleObjectProperty<>(processState);
|
||||
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
|
||||
|
||||
initStates();
|
||||
initStateProperties();
|
||||
tradeAmountProperty = new SimpleObjectProperty<>();
|
||||
tradeVolumeProperty = new SimpleObjectProperty<>();
|
||||
}
|
||||
@ -119,87 +86,24 @@ public class OffererTrade extends Trade implements Serializable {
|
||||
in.defaultReadObject();
|
||||
log.trace("Created from serialized form.");
|
||||
|
||||
processStateProperty = new SimpleObjectProperty<>(processState);
|
||||
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
|
||||
|
||||
tradeAmountProperty = new SimpleObjectProperty<>();
|
||||
tradeVolumeProperty = new SimpleObjectProperty<>();
|
||||
|
||||
if (tradeAmount != null) {
|
||||
tradeAmountProperty.set(tradeAmount);
|
||||
tradeVolumeProperty.set(getTradeVolume());
|
||||
}
|
||||
initStateProperties();
|
||||
initAmountProperty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProcessModel createProcessModel() {
|
||||
public ProcessModel createProcessModel() {
|
||||
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
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public OffererProcessModel getProcessModel() {
|
||||
return (OffererProcessModel) processModel;
|
||||
}
|
||||
|
||||
public void setTradingPeer(Peer tradingPeer) {
|
||||
this.tradingPeer = tradingPeer;
|
||||
}
|
||||
@ -230,30 +134,27 @@ public class OffererTrade extends Trade implements Serializable {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
|
||||
return tradeAmountProperty;
|
||||
}
|
||||
|
||||
public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() {
|
||||
return tradeVolumeProperty;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Protected
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected void setupConfidenceListener() {
|
||||
assert depositTx != null;
|
||||
TransactionConfidence transactionConfidence = depositTx.getConfidence();
|
||||
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);
|
||||
}
|
||||
protected void initAmountProperty() {
|
||||
tradeAmountProperty = new SimpleObjectProperty<>();
|
||||
tradeVolumeProperty = new SimpleObjectProperty<>();
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull Throwable t) {
|
||||
t.printStackTrace();
|
||||
log.error(t.getMessage());
|
||||
Throwables.propagate(t);
|
||||
}
|
||||
});
|
||||
if (tradeAmount != null) {
|
||||
tradeAmountProperty.set(tradeAmount);
|
||||
tradeVolumeProperty.set(getTradeVolume());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -261,8 +162,6 @@ public class OffererTrade extends Trade implements Serializable {
|
||||
return "OffererTrade{" +
|
||||
"tradeAmount=" + tradeAmount +
|
||||
", tradingPeer=" + tradingPeer +
|
||||
", processState=" + processState +
|
||||
", lifeCycleState=" + lifeCycleState +
|
||||
'}';
|
||||
super.toString();
|
||||
}
|
||||
}
|
||||
|
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.storage.Storage;
|
||||
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 org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.TransactionConfidence;
|
||||
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.Serializable;
|
||||
|
||||
@ -40,12 +33,10 @@ import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
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.
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ -56,28 +47,10 @@ public class TakerTrade extends Trade implements Serializable {
|
||||
// Enum
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public enum TakerLifeCycleState implements LifeCycleState {
|
||||
PENDING,
|
||||
COMPLETED,
|
||||
FAILED
|
||||
public interface LifeCycleState extends Trade.LifeCycleState {
|
||||
}
|
||||
|
||||
public enum TakerProcessState implements 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
|
||||
public interface ProcessState extends Trade.ProcessState {
|
||||
}
|
||||
|
||||
|
||||
@ -85,78 +58,43 @@ public class TakerTrade extends Trade implements Serializable {
|
||||
// Fields
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Transient/Immutable
|
||||
transient private ObjectProperty<TakerProcessState> processStateProperty;
|
||||
transient private ObjectProperty<TakerLifeCycleState> lifeCycleStateProperty;
|
||||
|
||||
// Immutable
|
||||
private final Coin tradeAmount;
|
||||
private final Peer tradingPeer;
|
||||
|
||||
// Mutable
|
||||
private TakerProcessState processState;
|
||||
private TakerLifeCycleState lifeCycleState;
|
||||
protected final Coin tradeAmount;
|
||||
protected final Peer tradingPeer;
|
||||
transient protected ObjectProperty<Coin> tradeAmountProperty;
|
||||
transient protected ObjectProperty<Fiat> tradeVolumeProperty;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, initialization
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public TakerTrade(Offer offer, Coin tradeAmount, Peer tradingPeer,
|
||||
Storage<? extends TradeList> storage) {
|
||||
protected TakerTrade(Offer offer, Coin tradeAmount, Peer tradingPeer,
|
||||
Storage<? extends TradeList> storage) {
|
||||
super(offer, storage);
|
||||
log.trace("Created by constructor");
|
||||
|
||||
this.tradeAmount = tradeAmount;
|
||||
this.tradingPeer = tradingPeer;
|
||||
|
||||
processState = TakerProcessState.UNDEFINED;
|
||||
lifeCycleState = TakerLifeCycleState.PENDING;
|
||||
|
||||
processStateProperty = new SimpleObjectProperty<>(processState);
|
||||
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
|
||||
|
||||
tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount);
|
||||
tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume());
|
||||
initStates();
|
||||
initStateProperties();
|
||||
initAmountProperty();
|
||||
}
|
||||
|
||||
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
in.defaultReadObject();
|
||||
log.trace("Created from serialized form.");
|
||||
|
||||
processStateProperty = new SimpleObjectProperty<>(processState);
|
||||
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
|
||||
|
||||
tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount);
|
||||
tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume());
|
||||
initStateProperties();
|
||||
initAmountProperty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProcessModel createProcessModel() {
|
||||
public ProcessModel createProcessModel() {
|
||||
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
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -175,70 +113,26 @@ public class TakerTrade extends Trade implements Serializable {
|
||||
return tradingPeer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyObjectProperty<TakerProcessState> processStateProperty() {
|
||||
return processStateProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyObjectProperty<TakerLifeCycleState> lifeCycleStateProperty() {
|
||||
return lifeCycleStateProperty;
|
||||
}
|
||||
|
||||
public TakerProcessModel getProcessModel() {
|
||||
return (TakerProcessModel) processModel;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setter for Mutable objects
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setLifeCycleState(TakerLifeCycleState lifeCycleState) {
|
||||
this.lifeCycleState = lifeCycleState;
|
||||
lifeCycleStateProperty.set(lifeCycleState);
|
||||
public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
|
||||
return tradeAmountProperty;
|
||||
}
|
||||
|
||||
public void setProcessState(TakerProcessState processState) {
|
||||
this.processState = processState;
|
||||
processStateProperty.set(processState);
|
||||
|
||||
if (processState == TakerProcessState.EXCEPTION) {
|
||||
setLifeCycleState(TakerLifeCycleState.FAILED);
|
||||
disposeProtocol();
|
||||
}
|
||||
public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() {
|
||||
return tradeVolumeProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThrowable(Throwable throwable) {
|
||||
super.setThrowable(throwable);
|
||||
setProcessState(TakerTrade.TakerProcessState.EXCEPTION);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Protected
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected void setupConfidenceListener() {
|
||||
assert depositTx != null;
|
||||
TransactionConfidence transactionConfidence = depositTx.getConfidence();
|
||||
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);
|
||||
}
|
||||
});
|
||||
protected void initAmountProperty() {
|
||||
tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount);
|
||||
tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -246,8 +140,6 @@ public class TakerTrade extends Trade implements Serializable {
|
||||
return "TakerTrade{" +
|
||||
"tradeAmount=" + tradeAmount +
|
||||
", tradingPeer=" + tradingPeer +
|
||||
", processState=" + processState +
|
||||
", lifeCycleState=" + lifeCycleState +
|
||||
'}';
|
||||
super.toString();
|
||||
}
|
||||
}
|
||||
|
@ -33,8 +33,14 @@ import io.bitsquare.user.User;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.bitcoinj.core.TransactionConfidence;
|
||||
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.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
@ -45,6 +51,9 @@ import javax.annotation.Nullable;
|
||||
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -64,10 +73,10 @@ abstract public class Trade extends Model implements Serializable {
|
||||
// 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 protected ObjectProperty<ProcessState> processStateProperty;
|
||||
transient protected ObjectProperty<LifeCycleState> lifeCycleStateProperty;
|
||||
|
||||
transient private Storage<? extends TradeList> storage;
|
||||
transient protected Protocol protocol;
|
||||
|
||||
@ -85,6 +97,8 @@ abstract public class Trade extends Model implements Serializable {
|
||||
protected final ProcessModel processModel;
|
||||
|
||||
// Mutable
|
||||
protected ProcessState processState;
|
||||
protected LifeCycleState lifeCycleState;
|
||||
private MailboxMessage mailboxMessage;
|
||||
protected Transaction depositTx;
|
||||
private Contract contract;
|
||||
@ -96,15 +110,13 @@ abstract public class Trade extends Model implements Serializable {
|
||||
// Transient/Mutable
|
||||
transient private String errorMessage;
|
||||
transient private Throwable throwable;
|
||||
transient protected ObjectProperty<Coin> tradeAmountProperty;
|
||||
transient protected ObjectProperty<Fiat> tradeVolumeProperty;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, initialization
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Trade(Offer offer, Storage<? extends TradeList> storage) {
|
||||
protected Trade(Offer offer, Storage<? extends TradeList> storage) {
|
||||
log.trace("Created by constructor");
|
||||
this.offer = offer;
|
||||
this.storage = storage;
|
||||
@ -141,18 +153,6 @@ abstract public class Trade extends Model implements Serializable {
|
||||
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.
|
||||
public void updateDepositTxFromWallet(TradeWalletService tradeWalletService) {
|
||||
@ -163,6 +163,7 @@ abstract public class Trade extends Model implements Serializable {
|
||||
public void setDepositTx(Transaction tx) {
|
||||
this.depositTx = tx;
|
||||
setupConfidenceListener();
|
||||
storage.queueUpForSave();
|
||||
}
|
||||
|
||||
public void disposeProtocol() {
|
||||
@ -180,7 +181,57 @@ abstract public class Trade extends Model implements Serializable {
|
||||
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();
|
||||
}
|
||||
|
||||
public ReadOnlyObjectProperty<Coin> tradeAmountProperty() {
|
||||
return tradeAmountProperty;
|
||||
}
|
||||
|
||||
|
||||
public ReadOnlyObjectProperty<Fiat> tradeVolumeProperty() {
|
||||
return tradeVolumeProperty;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
abstract public Coin getTradeAmount();
|
||||
|
||||
@Nullable
|
||||
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
|
||||
public String toString() {
|
||||
return "Trade{" +
|
||||
"throwable=" + throwable +
|
||||
return ", protocol=" + protocol +
|
||||
", offer=" + offer +
|
||||
", date=" + date +
|
||||
", processModel=" + processModel +
|
||||
", processState=" + processState +
|
||||
", lifeCycleState=" + lifeCycleState +
|
||||
", mailboxMessage=" + mailboxMessage +
|
||||
", depositTx=" + depositTx +
|
||||
", contract=" + contract +
|
||||
", contractAsJson='" + contractAsJson + '\'' +
|
||||
", takerContractSignature='" + takerContractSignature + '\'' +
|
||||
", offererContractSignature='" + offererContractSignature + '\'' +
|
||||
", payoutTx=" + payoutTx +
|
||||
", errorMessage='" + errorMessage + '\'' +
|
||||
", processModel=" + processModel +
|
||||
", throwable=" + throwable +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -56,6 +56,7 @@ import com.google.common.util.concurrent.FutureCallback;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -90,7 +91,7 @@ public class TradeManager {
|
||||
private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>();
|
||||
private final Storage<TradeList> pendingTradesStorage;
|
||||
private final Storage<TradeList> openOfferTradesStorage;
|
||||
private final TradeList<OffererTrade> openOfferTrades;
|
||||
private final TradeList<OffererAsBuyerTrade> openOfferTrades;
|
||||
private final TradeList<Trade> pendingTrades;
|
||||
private final TradeList<Trade> closedTrades;
|
||||
|
||||
@ -149,24 +150,42 @@ public class TradeManager {
|
||||
// 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.
|
||||
public void onAllServicesInitialized() {
|
||||
for (OffererTrade offererTrade : openOfferTrades) {
|
||||
Offer offer = offererTrade.getOffer();
|
||||
for (OffererAsBuyerTrade OffererAsBuyerTrade : openOfferTrades) {
|
||||
Offer offer = OffererAsBuyerTrade.getOffer();
|
||||
// We add own offers to offerbook when we go online again
|
||||
offerBookService.addOffer(offer,
|
||||
() -> log.debug("Successful removed open offer from DHT"),
|
||||
(message, throwable) -> log.error("Remove open offer from DHT failed. " + message));
|
||||
setupDepositPublishedListener(offererTrade);
|
||||
offererTrade.setStorage(openOfferTradesStorage);
|
||||
initTrade(offererTrade);
|
||||
setupDepositPublishedListener(OffererAsBuyerTrade);
|
||||
OffererAsBuyerTrade.setStorage(openOfferTradesStorage);
|
||||
initTrade(OffererAsBuyerTrade);
|
||||
|
||||
}
|
||||
List<Trade> failedTrades = new ArrayList<>();
|
||||
for (Trade trade : pendingTrades) {
|
||||
// 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
|
||||
// continue the trade, but that might fail.
|
||||
trade.setStorage(pendingTradesStorage);
|
||||
trade.updateDepositTxFromWallet(tradeWalletService);
|
||||
initTrade(trade);
|
||||
|
||||
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.updateDepositTxFromWallet(tradeWalletService);
|
||||
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
|
||||
@ -210,8 +229,8 @@ public class TradeManager {
|
||||
log.debug("shutDown");
|
||||
shutDownRequested = true;
|
||||
// we remove own offers form offerbook when we go offline
|
||||
for (OffererTrade offererTrade : openOfferTrades) {
|
||||
Offer offer = offererTrade.getOffer();
|
||||
for (OffererAsBuyerTrade OffererAsBuyerTrade : openOfferTrades) {
|
||||
Offer offer = OffererAsBuyerTrade.getOffer();
|
||||
offerBookService.removeOfferAtShutDown(offer);
|
||||
}
|
||||
}
|
||||
@ -258,23 +277,23 @@ public class TradeManager {
|
||||
}
|
||||
|
||||
private void handlePlaceOfferResult(Transaction transaction, Offer offer, TransactionResultHandler resultHandler) {
|
||||
OffererTrade offererTrade = new OffererTrade(offer, openOfferTradesStorage);
|
||||
openOfferTrades.add(offererTrade);
|
||||
initTrade(offererTrade);
|
||||
setupDepositPublishedListener(offererTrade);
|
||||
OffererAsBuyerTrade offererAsBuyerTrade = new OffererAsBuyerTrade(offer, openOfferTradesStorage);
|
||||
openOfferTrades.add(offererAsBuyerTrade);
|
||||
initTrade(offererAsBuyerTrade);
|
||||
setupDepositPublishedListener(offererAsBuyerTrade);
|
||||
resultHandler.handleResult(transaction);
|
||||
}
|
||||
|
||||
private void setupDepositPublishedListener(OffererTrade offererTrade) {
|
||||
offererTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
|
||||
log.debug("offererTrade state = " + newValue);
|
||||
if (newValue == OffererTrade.OffererProcessState.DEPOSIT_PUBLISHED) {
|
||||
removeOpenOffer(offererTrade.getOffer(),
|
||||
private void setupDepositPublishedListener(OffererAsBuyerTrade offererAsBuyerTrade) {
|
||||
offererAsBuyerTrade.processStateProperty().addListener((ov, oldValue, newValue) -> {
|
||||
log.debug("OffererAsBuyerTrade state = " + newValue);
|
||||
if (newValue == OffererAsBuyerTrade.ProcessState.DEPOSIT_PUBLISHED) {
|
||||
removeOpenOffer(offererAsBuyerTrade.getOffer(),
|
||||
() -> log.debug("remove offer was successful"),
|
||||
log::error,
|
||||
false);
|
||||
pendingTrades.add(offererTrade);
|
||||
offererTrade.setStorage(pendingTradesStorage);
|
||||
pendingTrades.add(offererAsBuyerTrade);
|
||||
offererAsBuyerTrade.setStorage(pendingTradesStorage);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -290,15 +309,15 @@ public class TradeManager {
|
||||
offerBookService.removeOffer(offer,
|
||||
() -> {
|
||||
offer.setState(Offer.State.REMOVED);
|
||||
Optional<OffererTrade> offererTradeOptional = openOfferTrades.stream().filter(e -> e.getId().equals(offer.getId())).findAny();
|
||||
if (offererTradeOptional.isPresent()) {
|
||||
OffererTrade offererTrade = offererTradeOptional.get();
|
||||
openOfferTrades.remove(offererTrade);
|
||||
Optional<OffererAsBuyerTrade> OffererAsBuyerTradeOptional = openOfferTrades.stream().filter(e -> e.getId().equals(offer.getId())).findAny();
|
||||
if (OffererAsBuyerTradeOptional.isPresent()) {
|
||||
OffererAsBuyerTrade offererAsBuyerTrade = OffererAsBuyerTradeOptional.get();
|
||||
openOfferTrades.remove(offererAsBuyerTrade);
|
||||
|
||||
if (isCancelRequest) {
|
||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_CANCELED);
|
||||
closedTrades.add(offererTrade);
|
||||
offererTrade.disposeProtocol();
|
||||
offererAsBuyerTrade.setLifeCycleState(OffererAsBuyerTrade.LifeCycleState.OFFER_CANCELED);
|
||||
closedTrades.add(offererAsBuyerTrade);
|
||||
offererAsBuyerTrade.disposeProtocol();
|
||||
}
|
||||
}
|
||||
|
||||
@ -351,7 +370,7 @@ public class TradeManager {
|
||||
takeOfferResultHandler) {
|
||||
disposeCheckOfferAvailabilityRequest(offer);
|
||||
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);
|
||||
pendingTrades.add(takerTrade);
|
||||
takerTrade.takeAvailableOffer();
|
||||
@ -371,7 +390,7 @@ public class TradeManager {
|
||||
// TODO handle overpaid securityDeposit
|
||||
Coin amountToWithdraw = trade.getSecurityDeposit();
|
||||
assert trade.getTradeAmount() != null;
|
||||
if (trade instanceof OffererTrade)
|
||||
if (trade instanceof OffererAsBuyerTrade)
|
||||
amountToWithdraw = amountToWithdraw.add(trade.getTradeAmount());
|
||||
|
||||
FutureCallback<Transaction> callback = new FutureCallback<Transaction>() {
|
||||
@ -379,10 +398,10 @@ public class TradeManager {
|
||||
public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
|
||||
if (transaction != null) {
|
||||
log.info("onWithdraw onSuccess tx ID:" + transaction.getHashAsString());
|
||||
if (trade instanceof OffererTrade)
|
||||
((OffererTrade) trade).setLifeCycleState(OffererTrade.OffererLifeCycleState.COMPLETED);
|
||||
if (trade instanceof OffererAsBuyerTrade)
|
||||
((OffererAsBuyerTrade) trade).setLifeCycleState(OffererAsBuyerTrade.LifeCycleState.COMPLETED);
|
||||
else
|
||||
((TakerTrade) trade).setLifeCycleState(TakerTrade.TakerLifeCycleState.COMPLETED);
|
||||
((TakerAsSellerTrade) trade).setLifeCycleState(TakerAsSellerTrade.LifeCycleState.COMPLETED);
|
||||
|
||||
pendingTrades.remove(trade);
|
||||
closedTrades.add(trade);
|
||||
@ -421,7 +440,7 @@ public class TradeManager {
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public ObservableList<OffererTrade> getOpenOfferTrades() {
|
||||
public ObservableList<OffererAsBuyerTrade> getOpenOfferTrades() {
|
||||
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.
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public final byte[] offererSignature;
|
||||
public final byte[] buyerSignature;
|
||||
public final Coin offererPayoutAmount;
|
||||
public final Coin takerPayoutAmount;
|
||||
public final String offererPayoutAddress;
|
||||
public final String buyerPayoutAddress;
|
||||
|
||||
public FiatTransferStartedMessage(String tradeId,
|
||||
byte[] offererSignature,
|
||||
byte[] buyerSignature,
|
||||
Coin offererPayoutAmount,
|
||||
Coin takerPayoutAmount,
|
||||
String offererPayoutAddress) {
|
||||
String buyerPayoutAddress) {
|
||||
super(tradeId);
|
||||
this.offererSignature = offererSignature;
|
||||
this.buyerSignature = buyerSignature;
|
||||
this.offererPayoutAmount = offererPayoutAmount;
|
||||
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.Peer;
|
||||
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.availability.messages.ReportOfferAvailabilityMessage;
|
||||
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.TradeMessage;
|
||||
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.CreateAndSignPayoutTx;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.CreateOffererDepositTxInputs;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessPayoutTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessRequestDepositTxInputsMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessRequestPublishDepositTxMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendRequestTakerDepositPaymentMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendFiatTransferStartedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendDepositTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SignAndPublishDepositTx;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyAndSignContract;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererCommitsPayoutTx;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererCreatesAndSignPayoutTx;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererCreatesDepositTxInputs;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererProcessPayoutTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererProcessRequestDepositTxInputsMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererProcessRequestPublishDepositTxMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSendsDepositTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSendsFiatTransferStartedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSendsRequestSellerDepositPaymentMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.OffererSignsAndPublishDepositTx;
|
||||
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.VerifyTakerAccount;
|
||||
|
||||
@ -51,21 +51,21 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import static io.bitsquare.util.Validator.*;
|
||||
|
||||
public class OffererProtocol implements Protocol {
|
||||
private static final Logger log = LoggerFactory.getLogger(OffererProtocol.class);
|
||||
public class OffererAsBuyerProtocol implements Protocol {
|
||||
private static final Logger log = LoggerFactory.getLogger(OffererAsBuyerProtocol.class);
|
||||
|
||||
private final MessageHandler messageHandler;
|
||||
private final OffererTrade offererTrade;
|
||||
private MessageHandler messageHandler;
|
||||
private final OffererAsBuyerTrade offererAsBuyerTrade;
|
||||
private final OffererProcessModel offererTradeProcessModel;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public OffererProtocol(OffererTrade model) {
|
||||
public OffererAsBuyerProtocol(OffererAsBuyerTrade model) {
|
||||
log.debug("New OffererProtocol " + this);
|
||||
this.offererTrade = model;
|
||||
offererTradeProcessModel = offererTrade.getProcessModel();
|
||||
this.offererAsBuyerTrade = model;
|
||||
offererTradeProcessModel = offererAsBuyerTrade.getProcessModel();
|
||||
messageHandler = this::handleMessage;
|
||||
|
||||
offererTradeProcessModel.getMessageService().addMessageHandler(messageHandler);
|
||||
@ -90,7 +90,10 @@ public class OffererProtocol implements Protocol {
|
||||
public void cleanup() {
|
||||
log.debug("cleanup " + this);
|
||||
|
||||
offererTradeProcessModel.getMessageService().removeMessageHandler(messageHandler);
|
||||
if (messageHandler != null) {
|
||||
offererTradeProcessModel.getMessageService().removeMessageHandler(messageHandler);
|
||||
messageHandler = null;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -106,7 +109,7 @@ public class OffererProtocol implements Protocol {
|
||||
// to take the
|
||||
// offer
|
||||
// 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);
|
||||
offererTradeProcessModel.getMessageService().sendMessage(sender, reportOfferAvailabilityMessage, new SendMessageListener() {
|
||||
@Override
|
||||
@ -131,16 +134,17 @@ public class OffererProtocol implements Protocol {
|
||||
private void handleRequestDepositTxInputsMessage(RequestDepositTxInputsMessage tradeMessage, Peer taker) {
|
||||
checkTradeId(offererTradeProcessModel.getId(), tradeMessage);
|
||||
offererTradeProcessModel.setTradeMessage(tradeMessage);
|
||||
offererTrade.setTradingPeer(taker);
|
||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_RESERVED);
|
||||
offererAsBuyerTrade.setTradingPeer(taker);
|
||||
|
||||
TaskRunner<OffererTrade> taskRunner = new TaskRunner<>(offererTrade,
|
||||
offererAsBuyerTrade.setLifeCycleState(OffererAsBuyerTrade.LifeCycleState.OFFER_RESERVED);
|
||||
|
||||
TaskRunner<OffererAsBuyerTrade> taskRunner = new TaskRunner<>(offererAsBuyerTrade,
|
||||
() -> log.debug("taskRunner at handleRequestDepositTxInputsMessage completed"),
|
||||
this::handleTaskRunnerFault);
|
||||
taskRunner.addTasks(
|
||||
ProcessRequestDepositTxInputsMessage.class,
|
||||
CreateOffererDepositTxInputs.class,
|
||||
SendRequestTakerDepositPaymentMessage.class
|
||||
OffererProcessRequestDepositTxInputsMessage.class,
|
||||
OffererCreatesDepositTxInputs.class,
|
||||
OffererSendsRequestSellerDepositPaymentMessage.class
|
||||
);
|
||||
taskRunner.run();
|
||||
}
|
||||
@ -148,15 +152,15 @@ public class OffererProtocol implements Protocol {
|
||||
private void handleRequestPublishDepositTxMessage(RequestPublishDepositTxMessage tradeMessage) {
|
||||
offererTradeProcessModel.setTradeMessage(tradeMessage);
|
||||
|
||||
TaskRunner<OffererTrade> taskRunner = new TaskRunner<>(offererTrade,
|
||||
TaskRunner<OffererAsBuyerTrade> taskRunner = new TaskRunner<>(offererAsBuyerTrade,
|
||||
() -> log.debug("taskRunner at handleRequestPublishDepositTxMessage completed"),
|
||||
this::handleTaskRunnerFault);
|
||||
taskRunner.addTasks(
|
||||
ProcessRequestPublishDepositTxMessage.class,
|
||||
OffererProcessRequestPublishDepositTxMessage.class,
|
||||
VerifyTakerAccount.class,
|
||||
VerifyAndSignContract.class,
|
||||
SignAndPublishDepositTx.class,
|
||||
SendDepositTxPublishedMessage.class
|
||||
OffererVerifiesAndSignsContract.class,
|
||||
OffererSignsAndPublishDepositTx.class,
|
||||
OffererSendsDepositTxPublishedMessage.class
|
||||
);
|
||||
taskRunner.run();
|
||||
}
|
||||
@ -168,13 +172,13 @@ public class OffererProtocol implements Protocol {
|
||||
|
||||
// User clicked the "bank transfer started" button
|
||||
public void onFiatPaymentStarted() {
|
||||
TaskRunner<OffererTrade> taskRunner = new TaskRunner<>(offererTrade,
|
||||
TaskRunner<OffererAsBuyerTrade> taskRunner = new TaskRunner<>(offererAsBuyerTrade,
|
||||
() -> log.debug("taskRunner at handleBankTransferStartedUIEvent completed"),
|
||||
this::handleTaskRunnerFault);
|
||||
taskRunner.addTasks(
|
||||
CreateAndSignPayoutTx.class,
|
||||
VerifyTakeOfferFeePayment.class,
|
||||
SendFiatTransferStartedMessage.class
|
||||
OffererCreatesAndSignPayoutTx.class,
|
||||
OffererSendsFiatTransferStartedMessage.class
|
||||
);
|
||||
taskRunner.run();
|
||||
}
|
||||
@ -187,7 +191,7 @@ public class OffererProtocol implements Protocol {
|
||||
private void handlePayoutTxPublishedMessage(PayoutTxPublishedMessage tradeMessage) {
|
||||
offererTradeProcessModel.setTradeMessage(tradeMessage);
|
||||
|
||||
TaskRunner<OffererTrade> taskRunner = new TaskRunner<>(offererTrade,
|
||||
TaskRunner<OffererAsBuyerTrade> taskRunner = new TaskRunner<>(offererAsBuyerTrade,
|
||||
() -> {
|
||||
log.debug("taskRunner at handlePayoutTxPublishedMessage completed");
|
||||
// we are done!
|
||||
@ -195,8 +199,8 @@ public class OffererProtocol implements Protocol {
|
||||
},
|
||||
this::handleTaskRunnerFault);
|
||||
|
||||
taskRunner.addTasks(ProcessPayoutTxPublishedMessage.class);
|
||||
taskRunner.addTasks(CommitPayoutTx.class);
|
||||
taskRunner.addTasks(OffererProcessPayoutTxPublishedMessage.class);
|
||||
taskRunner.addTasks(OffererCommitsPayoutTx.class);
|
||||
taskRunner.run();
|
||||
}
|
||||
|
||||
@ -211,7 +215,7 @@ public class OffererProtocol implements Protocol {
|
||||
TradeMessage tradeMessage = (TradeMessage) message;
|
||||
nonEmptyStringOf(tradeMessage.tradeId);
|
||||
|
||||
if (tradeMessage.tradeId.equals(offererTrade.getId())) {
|
||||
if (tradeMessage.tradeId.equals(offererAsBuyerTrade.getId())) {
|
||||
if (tradeMessage instanceof RequestIsOfferAvailableMessage) {
|
||||
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 org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.bitcoinj.core.TransactionOutput;
|
||||
import org.bitcoinj.crypto.DeterministicKey;
|
||||
|
||||
@ -36,8 +37,6 @@ import java.security.PublicKey;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -57,7 +56,8 @@ public class Offerer implements Serializable {
|
||||
private Coin payoutAmount;
|
||||
private List<TransactionOutput> connectedOutputsForAllInputs;
|
||||
private List<TransactionOutput> outputs; // used to verify amounts with change outputs
|
||||
|
||||
private Transaction preparedDepositTx;
|
||||
private PublicKey p2pSigPublicKey;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, initialization
|
||||
@ -99,6 +99,10 @@ public class Offerer implements Serializable {
|
||||
return user.getP2PSigPubKey();
|
||||
}
|
||||
|
||||
public PublicKey getP2pEncryptPublicKey() {
|
||||
return user.getP2PEncryptPubKey();
|
||||
}
|
||||
|
||||
public PublicKey getP2pEncryptPubKey() {
|
||||
return user.getP2PEncryptPubKey();
|
||||
}
|
||||
@ -124,7 +128,7 @@ public class Offerer implements Serializable {
|
||||
// Getter/Setter for Mutable objects
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Nullable
|
||||
|
||||
public List<TransactionOutput> getOutputs() {
|
||||
return outputs;
|
||||
}
|
||||
@ -133,7 +137,6 @@ public class Offerer implements Serializable {
|
||||
this.outputs = outputs;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public byte[] getPayoutTxSignature() {
|
||||
return payoutTxSignature;
|
||||
}
|
||||
@ -142,7 +145,6 @@ public class Offerer implements Serializable {
|
||||
this.payoutTxSignature = payoutTxSignature;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Coin getPayoutAmount() {
|
||||
return payoutAmount;
|
||||
}
|
||||
@ -151,7 +153,6 @@ public class Offerer implements Serializable {
|
||||
this.payoutAmount = payoutAmount;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<TransactionOutput> getConnectedOutputsForAllInputs() {
|
||||
return connectedOutputsForAllInputs;
|
||||
}
|
||||
@ -160,6 +161,22 @@ public class Offerer implements Serializable {
|
||||
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
|
||||
public String toString() {
|
||||
return "Offerer{" +
|
||||
@ -172,4 +189,6 @@ public class Offerer implements Serializable {
|
||||
", outputs=" + outputs +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ import io.bitsquare.p2p.MessageService;
|
||||
import io.bitsquare.trade.protocol.trade.ProcessModel;
|
||||
import io.bitsquare.user.User;
|
||||
|
||||
import org.bitcoinj.core.Transaction;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
|
||||
@ -47,6 +49,7 @@ public class OffererProcessModel extends ProcessModel implements Serializable {
|
||||
|
||||
// Mutable
|
||||
private String takeOfferFeeTxId;
|
||||
private Transaction payoutTx;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -99,6 +102,13 @@ public class OffererProcessModel extends ProcessModel implements Serializable {
|
||||
this.takeOfferFeeTxId = takeOfferFeeTxId;
|
||||
}
|
||||
|
||||
public Transaction getPayoutTx() {
|
||||
return payoutTx;
|
||||
}
|
||||
|
||||
public void setPayoutTx(Transaction payoutTx) {
|
||||
this.payoutTx = payoutTx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@ -108,4 +118,6 @@ public class OffererProcessModel extends ProcessModel implements Serializable {
|
||||
", takeOfferFeeTxId='" + takeOfferFeeTxId + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ public class Taker implements Serializable {
|
||||
// Mutable
|
||||
private String accountId;
|
||||
private FiatAccount fiatAccount;
|
||||
private PublicKey p2pSigPublicKey;
|
||||
private PublicKey p2pSigPubKey;
|
||||
private PublicKey p2pEncryptPubKey;
|
||||
private String contractAsJson;
|
||||
private String contractSignature;
|
||||
@ -53,7 +53,8 @@ public class Taker implements Serializable {
|
||||
private List<TransactionOutput> connectedOutputsForAllInputs;
|
||||
private String payoutAddressString;
|
||||
private byte[] tradeWalletPubKey;
|
||||
|
||||
private List<TransactionOutput> outputs;
|
||||
private byte[] signature;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, initialization
|
||||
@ -89,12 +90,12 @@ public class Taker implements Serializable {
|
||||
this.fiatAccount = fiatAccount;
|
||||
}
|
||||
|
||||
public PublicKey getP2pSigPublicKey() {
|
||||
return p2pSigPublicKey;
|
||||
public PublicKey getP2pSigPubKey() {
|
||||
return p2pSigPubKey;
|
||||
}
|
||||
|
||||
public void setP2pSigPublicKey(PublicKey p2pSigPublicKey) {
|
||||
this.p2pSigPublicKey = p2pSigPublicKey;
|
||||
public void setP2pSigPubKey(PublicKey p2pSigPubKey) {
|
||||
this.p2pSigPubKey = p2pSigPubKey;
|
||||
}
|
||||
|
||||
public PublicKey getP2pEncryptPubKey() {
|
||||
@ -161,13 +162,28 @@ public class Taker implements Serializable {
|
||||
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
|
||||
public String toString() {
|
||||
return "Taker{" +
|
||||
"accountId='" + accountId + '\'' +
|
||||
", fiatAccount=" + fiatAccount +
|
||||
", p2pSigPublicKey=" + p2pSigPublicKey +
|
||||
", p2pSigPublicKey=" + p2pSigPubKey +
|
||||
", p2pEncryptPubKey=" + p2pEncryptPubKey +
|
||||
", contractAsJson='" + contractAsJson + '\'' +
|
||||
", contractSignature='" + contractSignature + '\'' +
|
||||
@ -178,4 +194,6 @@ public class Taker implements Serializable {
|
||||
", 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.LoggerFactory;
|
||||
|
||||
public class CommitPayoutTx extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(CommitPayoutTx.class);
|
||||
public class OffererCommitsPayoutTx extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(OffererCommitsPayoutTx.class);
|
||||
|
||||
public CommitPayoutTx(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
public OffererCommitsPayoutTx(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
super(taskHandler, offererTradeProcessModel);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||
|
||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||
import io.bitsquare.offer.Offer;
|
||||
import io.bitsquare.trade.OffererTrade;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
@ -25,10 +26,10 @@ import org.bitcoinj.core.Coin;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CreateAndSignPayoutTx extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(CreateAndSignPayoutTx.class);
|
||||
public class OffererCreatesAndSignPayoutTx extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(OffererCreatesAndSignPayoutTx.class);
|
||||
|
||||
public CreateAndSignPayoutTx(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
public OffererCreatesAndSignPayoutTx(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
super(taskHandler, offererTradeProcessModel);
|
||||
}
|
||||
|
||||
@ -37,10 +38,16 @@ public class CreateAndSignPayoutTx extends OffererTradeTask {
|
||||
try {
|
||||
assert offererTrade.getTradeAmount() != null;
|
||||
Coin securityDeposit = offererTrade.getSecurityDeposit();
|
||||
Coin offererPayoutAmount = offererTrade.getTradeAmount().add(securityDeposit);
|
||||
@SuppressWarnings("UnnecessaryLocalVariable") Coin takerPayoutAmount = securityDeposit;
|
||||
|
||||
Coin offererPayoutAmount = securityDeposit;
|
||||
if (offererTrade.getOffer().getDirection() == Offer.Direction.BUY)
|
||||
offererPayoutAmount = offererPayoutAmount.add(offererTrade.getTradeAmount());
|
||||
|
||||
byte[] offererPayoutTxSignature = offererTradeProcessModel.getTradeWalletService().offererCreatesAndSignsPayoutTx(
|
||||
Coin takerPayoutAmount = securityDeposit;
|
||||
if (offererTrade.getOffer().getDirection() == Offer.Direction.SELL)
|
||||
takerPayoutAmount = takerPayoutAmount.add(offererTrade.getTradeAmount());
|
||||
|
||||
byte[] offererPayoutTxSignature = offererTradeProcessModel.getTradeWalletService().createAndSignPayoutTx(
|
||||
offererTrade.getDepositTx(),
|
||||
offererPayoutAmount,
|
||||
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.TradeWalletService;
|
||||
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;
|
||||
@ -27,10 +29,10 @@ import org.bitcoinj.core.Coin;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CreateOffererDepositTxInputs extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(CreateOffererDepositTxInputs.class);
|
||||
public class OffererCreatesDepositTxInputs extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(OffererCreatesDepositTxInputs.class);
|
||||
|
||||
public CreateOffererDepositTxInputs(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
public OffererCreatesDepositTxInputs(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
super(taskHandler, offererTradeProcessModel);
|
||||
}
|
||||
|
||||
@ -38,8 +40,8 @@ public class CreateOffererDepositTxInputs extends OffererTradeTask {
|
||||
protected void doRun() {
|
||||
try {
|
||||
log.debug("offererTrade.id" + offererTrade.getId());
|
||||
Coin offererInputAmount = offererTrade.getSecurityDeposit().add(FeePolicy.TX_FEE);
|
||||
TradeWalletService.Result result = offererTradeProcessModel.getTradeWalletService().createOffererDepositTxInputs(offererInputAmount,
|
||||
Coin inputAmount = offererTrade.getSecurityDeposit().add(FeePolicy.TX_FEE);
|
||||
TradeWalletService.Result result = offererTradeProcessModel.getTradeWalletService().createOffererDepositTxInputs(inputAmount,
|
||||
offererTradeProcessModel.offerer.getAddressEntry());
|
||||
|
||||
offererTradeProcessModel.offerer.setConnectedOutputsForAllInputs(result.getConnectedOutputsForAllInputs());
|
||||
@ -49,7 +51,14 @@ public class CreateOffererDepositTxInputs extends OffererTradeTask {
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
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.PayoutTxPublishedMessage;
|
||||
|
||||
@ -27,10 +29,10 @@ import org.slf4j.LoggerFactory;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static io.bitsquare.util.Validator.checkTradeId;
|
||||
|
||||
public class ProcessPayoutTxPublishedMessage extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(ProcessPayoutTxPublishedMessage.class);
|
||||
public class OffererProcessPayoutTxPublishedMessage extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(OffererProcessPayoutTxPublishedMessage.class);
|
||||
|
||||
public ProcessPayoutTxPublishedMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
public OffererProcessPayoutTxPublishedMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
super(taskHandler, offererTradeProcessModel);
|
||||
}
|
||||
|
||||
@ -43,8 +45,11 @@ public class ProcessPayoutTxPublishedMessage extends OffererTradeTask {
|
||||
|
||||
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();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
@ -18,6 +18,8 @@
|
||||
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.RequestDepositTxInputsMessage;
|
||||
|
||||
@ -27,10 +29,10 @@ import org.slf4j.LoggerFactory;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static io.bitsquare.util.Validator.*;
|
||||
|
||||
public class ProcessRequestDepositTxInputsMessage extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(ProcessRequestDepositTxInputsMessage.class);
|
||||
public class OffererProcessRequestDepositTxInputsMessage extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(OffererProcessRequestDepositTxInputsMessage.class);
|
||||
|
||||
public ProcessRequestDepositTxInputsMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
public OffererProcessRequestDepositTxInputsMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
super(taskHandler, offererTradeProcessModel);
|
||||
}
|
||||
|
||||
@ -49,7 +51,12 @@ public class ProcessRequestDepositTxInputsMessage extends OffererTradeTask {
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
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.RequestPublishDepositTxMessage;
|
||||
|
||||
@ -27,10 +29,10 @@ import org.slf4j.LoggerFactory;
|
||||
import static com.google.common.base.Preconditions.*;
|
||||
import static io.bitsquare.util.Validator.*;
|
||||
|
||||
public class ProcessRequestPublishDepositTxMessage extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(ProcessRequestPublishDepositTxMessage.class);
|
||||
public class OffererProcessRequestPublishDepositTxMessage extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(OffererProcessRequestPublishDepositTxMessage.class);
|
||||
|
||||
public ProcessRequestPublishDepositTxMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
public OffererProcessRequestPublishDepositTxMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
super(taskHandler, offererTradeProcessModel);
|
||||
}
|
||||
|
||||
@ -43,7 +45,7 @@ public class ProcessRequestPublishDepositTxMessage extends OffererTradeTask {
|
||||
|
||||
offererTradeProcessModel.taker.setFiatAccount(checkNotNull(message.takerFiatAccount));
|
||||
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.setContractAsJson(nonEmptyStringOf(message.takerContractAsJson));
|
||||
offererTradeProcessModel.taker.setContractSignature(nonEmptyStringOf(message.takerContractSignature));
|
||||
@ -56,7 +58,12 @@ public class ProcessRequestPublishDepositTxMessage extends OffererTradeTask {
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
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);
|
||||
}
|
||||
}
|
@ -19,16 +19,18 @@ 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.DepositTxPublishedMessage;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SendDepositTxPublishedMessage extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(SendDepositTxPublishedMessage.class);
|
||||
public class OffererSendsDepositTxPublishedMessage extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(OffererSendsDepositTxPublishedMessage.class);
|
||||
|
||||
public SendDepositTxPublishedMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
public OffererSendsDepositTxPublishedMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
super(taskHandler, offererTradeProcessModel);
|
||||
}
|
||||
|
||||
@ -48,7 +50,12 @@ public class SendDepositTxPublishedMessage extends OffererTradeTask {
|
||||
public void handleFault() {
|
||||
appendToErrorMessage("Sending DepositTxPublishedMessage failed");
|
||||
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();
|
||||
}
|
||||
});
|
@ -19,16 +19,18 @@ 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.FiatTransferStartedMessage;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SendFiatTransferStartedMessage extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(SendFiatTransferStartedMessage.class);
|
||||
public class OffererSendsFiatTransferStartedMessage extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(OffererSendsFiatTransferStartedMessage.class);
|
||||
|
||||
public SendFiatTransferStartedMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
public OffererSendsFiatTransferStartedMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
super(taskHandler, offererTradeProcessModel);
|
||||
}
|
||||
|
||||
@ -42,13 +44,20 @@ public class SendFiatTransferStartedMessage extends OffererTradeTask {
|
||||
offererTradeProcessModel.offerer.getAddressEntry().getAddressString());
|
||||
|
||||
offererTradeProcessModel.getMessageService().sendMessage(offererTrade.getTradingPeer(), tradeMessage,
|
||||
offererTradeProcessModel.taker.getP2pSigPublicKey(),
|
||||
offererTradeProcessModel.taker.getP2pSigPubKey(),
|
||||
offererTradeProcessModel.taker.getP2pEncryptPubKey(),
|
||||
new SendMessageListener() {
|
||||
@Override
|
||||
public void handleResult() {
|
||||
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();
|
||||
}
|
||||
|
||||
@ -56,7 +65,14 @@ public class SendFiatTransferStartedMessage extends OffererTradeTask {
|
||||
public void handleFault() {
|
||||
appendToErrorMessage("Sending FiatTransferStartedMessage failed");
|
||||
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();
|
||||
}
|
||||
});
|
@ -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.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.RequestTakerDepositPaymentMessage;
|
||||
import io.bitsquare.trade.protocol.trade.messages.RequestPublishDepositTxMessage;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SendRequestTakerDepositPaymentMessage extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(SendRequestTakerDepositPaymentMessage.class);
|
||||
public class OffererSendsRequestPublishDepositTxMessage extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(OffererSendsRequestPublishDepositTxMessage.class);
|
||||
|
||||
public SendRequestTakerDepositPaymentMessage(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
super(taskHandler, offererTradeProcessModel);
|
||||
public OffererSendsRequestPublishDepositTxMessage(TaskRunner taskHandler, OffererTrade model) {
|
||||
super(taskHandler, model);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
try {
|
||||
RequestTakerDepositPaymentMessage tradeMessage = new RequestTakerDepositPaymentMessage(
|
||||
RequestPublishDepositTxMessage tradeMessage = new RequestPublishDepositTxMessage(
|
||||
offererTradeProcessModel.getId(),
|
||||
offererTradeProcessModel.offerer.getConnectedOutputsForAllInputs(),
|
||||
offererTradeProcessModel.offerer.getOutputs(),
|
||||
offererTradeProcessModel.offerer.getTradeWalletPubKey(),
|
||||
offererTradeProcessModel.offerer.getP2pSigPubKey(),
|
||||
offererTradeProcessModel.offerer.getP2pEncryptPubKey(),
|
||||
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() {
|
||||
@Override
|
||||
public void handleResult() {
|
||||
log.trace("RequestTakerDepositPaymentMessage successfully arrived at peer");
|
||||
complete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFault() {
|
||||
appendToErrorMessage("Sending RequestTakerDepositPaymentMessage failed");
|
||||
appendToErrorMessage("Sending RequestOffererPublishDepositTxMessage failed");
|
||||
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();
|
||||
}
|
||||
});
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
offererTrade.setThrowable(t);
|
||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
|
||||
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;
|
||||
|
||||
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;
|
||||
@ -31,34 +31,35 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SignAndPublishDepositTx extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(SignAndPublishDepositTx.class);
|
||||
public class OffererSignsAndPublishPayoutTx extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(OffererSignsAndPublishPayoutTx.class);
|
||||
|
||||
public SignAndPublishDepositTx(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
super(taskHandler, offererTradeProcessModel);
|
||||
public OffererSignsAndPublishPayoutTx(TaskRunner taskHandler, OffererTrade model) {
|
||||
super(taskHandler, model);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
try {
|
||||
Coin offererInputAmount = offererTrade.getSecurityDeposit().add(FeePolicy.TX_FEE);
|
||||
offererTradeProcessModel.getTradeWalletService().offererSignsAndPublishDepositTx(
|
||||
offererTradeProcessModel.taker.getPreparedDepositTx(),
|
||||
offererTradeProcessModel.offerer.getConnectedOutputsForAllInputs(),
|
||||
offererTradeProcessModel.taker.getConnectedOutputsForAllInputs(),
|
||||
offererTradeProcessModel.offerer.getOutputs(),
|
||||
offererInputAmount,
|
||||
offererTradeProcessModel.getTradeWalletService().signAndPublishPayoutTx(
|
||||
offererTrade.getDepositTx(),
|
||||
offererTradeProcessModel.taker.getSignature(),
|
||||
offererTradeProcessModel.offerer.getPayoutAmount(),
|
||||
offererTradeProcessModel.taker.getPayoutAmount(),
|
||||
offererTradeProcessModel.taker.getPayoutAddressString(),
|
||||
offererTradeProcessModel.offerer.getAddressEntry(),
|
||||
offererTradeProcessModel.offerer.getTradeWalletPubKey(),
|
||||
offererTradeProcessModel.taker.getTradeWalletPubKey(),
|
||||
offererTradeProcessModel.getArbitratorPubKey(),
|
||||
new FutureCallback<Transaction>() {
|
||||
@Override
|
||||
public void onSuccess(Transaction transaction) {
|
||||
log.trace("offererSignAndPublishTx succeeded " + transaction);
|
||||
offererTradeProcessModel.setPayoutTx(transaction);
|
||||
|
||||
offererTrade.setDepositTx(transaction);
|
||||
offererTrade.setProcessState(OffererTrade.OffererProcessState.DEPOSIT_PUBLISHED);
|
||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.PENDING);
|
||||
if (offererTrade instanceof OffererAsBuyerTrade)
|
||||
offererTrade.setProcessState(OffererAsBuyerTrade.ProcessState.PAYOUT_PUBLISHED);
|
||||
else if (offererTrade instanceof OffererAsSellerTrade)
|
||||
offererTrade.setProcessState(OffererAsSellerTrade.ProcessState.PAYOUT_PUBLISHED);
|
||||
|
||||
complete();
|
||||
}
|
||||
@ -67,14 +68,12 @@ public class SignAndPublishDepositTx extends OffererTradeTask {
|
||||
public void onFailure(@NotNull Throwable t) {
|
||||
t.printStackTrace();
|
||||
offererTrade.setThrowable(t);
|
||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
|
||||
failed(t);
|
||||
}
|
||||
});
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
offererTrade.setThrowable(t);
|
||||
offererTrade.setLifeCycleState(OffererTrade.OffererLifeCycleState.OFFER_OPEN);
|
||||
failed(t);
|
||||
}
|
||||
}
|
@ -19,16 +19,18 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||
|
||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||
import io.bitsquare.trade.Contract;
|
||||
import io.bitsquare.trade.OffererAsBuyerTrade;
|
||||
import io.bitsquare.trade.OffererAsSellerTrade;
|
||||
import io.bitsquare.trade.OffererTrade;
|
||||
import io.bitsquare.util.Utilities;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class VerifyAndSignContract extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(VerifyAndSignContract.class);
|
||||
public class OffererVerifiesAndSignsContract extends OffererTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(OffererVerifiesAndSignsContract.class);
|
||||
|
||||
public VerifyAndSignContract(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
public OffererVerifiesAndSignsContract(TaskRunner taskHandler, OffererTrade offererTradeProcessModel) {
|
||||
super(taskHandler, offererTradeProcessModel);
|
||||
}
|
||||
|
||||
@ -44,7 +46,7 @@ public class VerifyAndSignContract extends OffererTradeTask {
|
||||
offererTradeProcessModel.offerer.getFiatAccount(),
|
||||
offererTradeProcessModel.taker.getFiatAccount(),
|
||||
offererTradeProcessModel.offerer.getP2pSigPubKey(),
|
||||
offererTradeProcessModel.taker.getP2pSigPublicKey());
|
||||
offererTradeProcessModel.taker.getP2pSigPubKey());
|
||||
String contractAsJson = Utilities.objectToJson(contract);
|
||||
String signature = offererTradeProcessModel.getSignatureService().signMessage(offererTradeProcessModel.offerer.getRegistrationKeyPair(),
|
||||
contractAsJson);
|
||||
@ -58,7 +60,12 @@ public class VerifyAndSignContract extends OffererTradeTask {
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
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);
|
||||
}
|
||||
}
|
@ -18,6 +18,8 @@
|
||||
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 org.slf4j.Logger;
|
||||
@ -47,12 +49,21 @@ public class VerifyTakerAccount extends OffererTradeTask {
|
||||
}
|
||||
else {
|
||||
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) {
|
||||
t.printStackTrace();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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.MessageHandler;
|
||||
import io.bitsquare.p2p.Peer;
|
||||
import io.bitsquare.trade.TakerAsSellerTrade;
|
||||
import io.bitsquare.trade.TakerTrade;
|
||||
import io.bitsquare.trade.protocol.Protocol;
|
||||
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
|
||||
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.taker.models.TakerProcessModel;
|
||||
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.ProcessDepositTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.ProcessFiatTransferStartedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.ProcessRequestTakerDepositPaymentMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendPayoutTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendRequestDepositTxInputsMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendRequestPublishDepositTxMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SignAndPublishPayoutTx;
|
||||
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.TakerProcessDepositTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerProcessFiatTransferStartedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerProcessRequestSellerDepositPaymentMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSendsPayoutTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSendsRequestDepositTxInputsMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSendsRequestPublishDepositTxMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerSignsAndPublishPayoutTx;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOfferFeePayment;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOffererAccount;
|
||||
|
||||
@ -49,10 +50,10 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import static io.bitsquare.util.Validator.nonEmptyStringOf;
|
||||
|
||||
public class TakerProtocol implements Protocol {
|
||||
private static final Logger log = LoggerFactory.getLogger(TakerProtocol.class);
|
||||
public class TakerAsSellerProtocol implements Protocol {
|
||||
private static final Logger log = LoggerFactory.getLogger(TakerAsSellerProtocol.class);
|
||||
|
||||
private final TakerTrade takerTrade;
|
||||
private final TakerAsSellerTrade takerAsSellerTrade;
|
||||
private final TakerProcessModel takerTradeProcessModel;
|
||||
private final MessageHandler messageHandler;
|
||||
|
||||
@ -61,9 +62,9 @@ public class TakerProtocol implements Protocol {
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public TakerProtocol(TakerTrade takerTrade) {
|
||||
public TakerAsSellerProtocol(TakerAsSellerTrade takerTrade) {
|
||||
log.debug("New SellerAsTakerProtocol " + this);
|
||||
this.takerTrade = takerTrade;
|
||||
this.takerAsSellerTrade = takerTrade;
|
||||
takerTradeProcessModel = takerTrade.getProcessModel();
|
||||
|
||||
messageHandler = this::handleMessage;
|
||||
@ -95,14 +96,14 @@ public class TakerProtocol implements Protocol {
|
||||
}
|
||||
|
||||
public void takeAvailableOffer() {
|
||||
TaskRunner<TakerTrade> taskRunner = new TaskRunner<>(takerTrade,
|
||||
TaskRunner<TakerTrade> taskRunner = new TaskRunner<>(takerAsSellerTrade,
|
||||
() -> log.debug("taskRunner at takeAvailableOffer completed"),
|
||||
this::handleTaskRunnerFault);
|
||||
|
||||
taskRunner.addTasks(
|
||||
CreateTakeOfferFeeTx.class,
|
||||
BroadcastTakeOfferFeeTx.class,
|
||||
SendRequestDepositTxInputsMessage.class
|
||||
TakerSendsRequestDepositTxInputsMessage.class
|
||||
);
|
||||
taskRunner.run();
|
||||
}
|
||||
@ -112,19 +113,19 @@ public class TakerProtocol implements Protocol {
|
||||
// Incoming message handling
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void handleRequestTakerDepositPaymentMessage(RequestTakerDepositPaymentMessage tradeMessage) {
|
||||
private void handleRequestTakerDepositPaymentMessage(RequestPayDepositMessage tradeMessage) {
|
||||
takerTradeProcessModel.setTradeMessage(tradeMessage);
|
||||
|
||||
TaskRunner<TakerTrade> taskRunner = new TaskRunner<>(takerTrade,
|
||||
TaskRunner<TakerTrade> taskRunner = new TaskRunner<>(takerAsSellerTrade,
|
||||
() -> log.debug("taskRunner at handleTakerDepositPaymentRequestMessage completed"),
|
||||
this::handleTaskRunnerFault);
|
||||
|
||||
taskRunner.addTasks(
|
||||
ProcessRequestTakerDepositPaymentMessage.class,
|
||||
TakerProcessRequestSellerDepositPaymentMessage.class,
|
||||
VerifyOffererAccount.class,
|
||||
CreateAndSignContract.class,
|
||||
CreateAndSignDepositTx.class,
|
||||
SendRequestPublishDepositTxMessage.class
|
||||
TakerCreatesAndSignContract.class,
|
||||
TakerCreatesAndSignsDepositTx.class,
|
||||
TakerSendsRequestPublishDepositTxMessage.class
|
||||
);
|
||||
taskRunner.run();
|
||||
}
|
||||
@ -132,13 +133,13 @@ public class TakerProtocol implements Protocol {
|
||||
private void handleDepositTxPublishedMessage(DepositTxPublishedMessage tradeMessage) {
|
||||
takerTradeProcessModel.setTradeMessage(tradeMessage);
|
||||
|
||||
TaskRunner<TakerTrade> taskRunner = new TaskRunner<>(takerTrade,
|
||||
TaskRunner<TakerAsSellerTrade> taskRunner = new TaskRunner<>(takerAsSellerTrade,
|
||||
() -> log.debug("taskRunner at handleDepositTxPublishedMessage completed"),
|
||||
this::handleTaskRunnerFault);
|
||||
|
||||
taskRunner.addTasks(
|
||||
ProcessDepositTxPublishedMessage.class,
|
||||
CommitDepositTx.class
|
||||
TakerProcessDepositTxPublishedMessage.class,
|
||||
TakerCommitDepositTx.class
|
||||
);
|
||||
taskRunner.run();
|
||||
}
|
||||
@ -146,11 +147,11 @@ public class TakerProtocol implements Protocol {
|
||||
private void handleFiatTransferStartedMessage(FiatTransferStartedMessage tradeMessage) {
|
||||
takerTradeProcessModel.setTradeMessage(tradeMessage);
|
||||
|
||||
TaskRunner<TakerTrade> taskRunner = new TaskRunner<>(takerTrade,
|
||||
TaskRunner<TakerAsSellerTrade> taskRunner = new TaskRunner<>(takerAsSellerTrade,
|
||||
() -> log.debug("taskRunner at handleFiatTransferStartedMessage completed"),
|
||||
this::handleTaskRunnerFault);
|
||||
|
||||
taskRunner.addTasks(ProcessFiatTransferStartedMessage.class);
|
||||
taskRunner.addTasks(TakerProcessFiatTransferStartedMessage.class);
|
||||
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
|
||||
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");
|
||||
|
||||
@ -173,9 +174,9 @@ public class TakerProtocol implements Protocol {
|
||||
this::handleTaskRunnerFault);
|
||||
|
||||
taskRunner.addTasks(
|
||||
SignAndPublishPayoutTx.class,
|
||||
VerifyOfferFeePayment.class,
|
||||
SendPayoutTxPublishedMessage.class
|
||||
TakerSignsAndPublishPayoutTx.class,
|
||||
TakerSendsPayoutTxPublishedMessage.class
|
||||
);
|
||||
taskRunner.run();
|
||||
}
|
||||
@ -191,8 +192,8 @@ public class TakerProtocol implements Protocol {
|
||||
nonEmptyStringOf(tradeMessage.tradeId);
|
||||
|
||||
if (tradeMessage.tradeId.equals(takerTradeProcessModel.getId())) {
|
||||
if (tradeMessage instanceof RequestTakerDepositPaymentMessage) {
|
||||
handleRequestTakerDepositPaymentMessage((RequestTakerDepositPaymentMessage) tradeMessage);
|
||||
if (tradeMessage instanceof RequestPayDepositMessage) {
|
||||
handleRequestTakerDepositPaymentMessage((RequestPayDepositMessage) tradeMessage);
|
||||
}
|
||||
else if (tradeMessage instanceof DepositTxPublishedMessage) {
|
||||
handleDepositTxPublishedMessage((DepositTxPublishedMessage) tradeMessage);
|
@ -20,6 +20,7 @@ package io.bitsquare.trade.protocol.trade.taker.models;
|
||||
import io.bitsquare.fiat.FiatAccount;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.bitcoinj.core.TransactionOutput;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -56,6 +57,10 @@ public class Offerer implements Serializable {
|
||||
private String accountId;
|
||||
private PublicKey p2pSigPublicKey;
|
||||
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;
|
||||
}
|
||||
|
||||
@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
|
||||
public String toString() {
|
||||
|
@ -56,7 +56,8 @@ public class Taker implements Serializable {
|
||||
private List<TransactionOutput> connectedOutputsForAllInputs;
|
||||
private Coin payoutAmount;
|
||||
private Transaction preparedDepositTx;
|
||||
|
||||
private List<TransactionOutput> outputs; // used to verify amounts with change outputs
|
||||
private byte[] payoutTxSignature;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor, initialization
|
||||
@ -118,6 +119,10 @@ public class Taker implements Serializable {
|
||||
return getAddressEntry().getPubKey();
|
||||
}
|
||||
|
||||
public PublicKey getP2pEncryptPubKey() {
|
||||
return user.getP2PEncryptPubKey();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getter/Setter for Mutable objects
|
||||
@ -150,6 +155,24 @@ public class Taker implements Serializable {
|
||||
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
|
||||
public String toString() {
|
||||
return "Taker{" +
|
||||
@ -161,4 +184,6 @@ public class Taker implements Serializable {
|
||||
", preparedDepositTx=" + preparedDepositTx +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
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 org.bitcoinj.core.Transaction;
|
||||
@ -45,9 +47,11 @@ public class BroadcastTakeOfferFeeTx extends TakerTradeTask {
|
||||
public void onSuccess(Transaction transaction) {
|
||||
log.debug("Take offer fee published successfully. Transaction ID = " + transaction.getHashAsString());
|
||||
|
||||
takerTrade.setProcessState(TakerTrade.TakerProcessState.TAKE_OFFER_FEE_PUBLISHED);
|
||||
|
||||
complete();
|
||||
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();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -55,7 +59,11 @@ public class BroadcastTakeOfferFeeTx extends TakerTradeTask {
|
||||
t.printStackTrace();
|
||||
appendToErrorMessage("Take offer fee payment failed. Maybe your network connection was lost. Please try again.");
|
||||
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);
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
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 org.bitcoinj.core.Transaction;
|
||||
@ -39,7 +41,11 @@ public class CreateTakeOfferFeeTx extends TakerTradeTask {
|
||||
.getAddressEntry());
|
||||
|
||||
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();
|
||||
} catch (Throwable t) {
|
||||
|
@ -25,10 +25,10 @@ import org.bitcoinj.core.Transaction;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CommitDepositTx extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(CommitDepositTx.class);
|
||||
public class TakerCommitDepositTx extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(TakerCommitDepositTx.class);
|
||||
|
||||
public CommitDepositTx(TaskRunner taskHandler, TakerTrade model) {
|
||||
public TakerCommitDepositTx(TaskRunner taskHandler, TakerTrade 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.LoggerFactory;
|
||||
|
||||
public class CreateAndSignContract extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(CreateAndSignContract.class);
|
||||
public class TakerCreatesAndSignContract extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(TakerCreatesAndSignContract.class);
|
||||
|
||||
public CreateAndSignContract(TaskRunner taskHandler, TakerTrade model) {
|
||||
public TakerCreatesAndSignContract(TaskRunner taskHandler, TakerTrade model) {
|
||||
super(taskHandler, model);
|
||||
}
|
||||
|
@ -27,10 +27,10 @@ import org.bitcoinj.core.Coin;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CreateAndSignDepositTx extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(CreateAndSignDepositTx.class);
|
||||
public class TakerCreatesAndSignsDepositTx extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(TakerCreatesAndSignsDepositTx.class);
|
||||
|
||||
public CreateAndSignDepositTx(TaskRunner taskHandler, TakerTrade model) {
|
||||
public TakerCreatesAndSignsDepositTx(TaskRunner taskHandler, TakerTrade model) {
|
||||
super(taskHandler, model);
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ public class CreateAndSignDepositTx extends TakerTradeTask {
|
||||
protected void doRun() {
|
||||
try {
|
||||
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());
|
||||
|
||||
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;
|
||||
|
||||
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.DepositTxPublishedMessage;
|
||||
|
||||
@ -27,10 +29,10 @@ import org.slf4j.LoggerFactory;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static io.bitsquare.util.Validator.checkTradeId;
|
||||
|
||||
public class ProcessDepositTxPublishedMessage extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(ProcessDepositTxPublishedMessage.class);
|
||||
public class TakerProcessDepositTxPublishedMessage extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(TakerProcessDepositTxPublishedMessage.class);
|
||||
|
||||
public ProcessDepositTxPublishedMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||
public TakerProcessDepositTxPublishedMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||
super(taskHandler, model);
|
||||
}
|
||||
|
||||
@ -42,7 +44,11 @@ public class ProcessDepositTxPublishedMessage extends TakerTradeTask {
|
||||
checkNotNull(message);
|
||||
|
||||
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();
|
||||
} catch (Throwable t) {
|
@ -18,6 +18,8 @@
|
||||
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.FiatTransferStartedMessage;
|
||||
|
||||
@ -27,10 +29,10 @@ import org.slf4j.LoggerFactory;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static io.bitsquare.util.Validator.*;
|
||||
|
||||
public class ProcessFiatTransferStartedMessage extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(ProcessFiatTransferStartedMessage.class);
|
||||
public class TakerProcessFiatTransferStartedMessage extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(TakerProcessFiatTransferStartedMessage.class);
|
||||
|
||||
public ProcessFiatTransferStartedMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||
public TakerProcessFiatTransferStartedMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||
super(taskHandler, model);
|
||||
}
|
||||
|
||||
@ -41,11 +43,15 @@ public class ProcessFiatTransferStartedMessage extends TakerTradeTask {
|
||||
checkTradeId(takerTradeProcessModel.getId(), message);
|
||||
checkNotNull(message);
|
||||
|
||||
takerTradeProcessModel.offerer.setSignature(checkNotNull(message.offererSignature));
|
||||
takerTradeProcessModel.offerer.setSignature(checkNotNull(message.buyerSignature));
|
||||
takerTradeProcessModel.offerer.setPayoutAmount(positiveCoinOf(nonZeroCoinOf(message.offererPayoutAmount)));
|
||||
takerTradeProcessModel.taker.setPayoutAmount(positiveCoinOf(nonZeroCoinOf(message.takerPayoutAmount)));
|
||||
takerTradeProcessModel.offerer.setPayoutAddressString(nonEmptyStringOf(message.offererPayoutAddress));
|
||||
takerTrade.setProcessState(TakerTrade.TakerProcessState.FIAT_PAYMENT_STARTED);
|
||||
takerTradeProcessModel.offerer.setPayoutAddressString(nonEmptyStringOf(message.buyerPayoutAddress));
|
||||
|
||||
if (takerTrade instanceof TakerAsBuyerTrade)
|
||||
takerTrade.setProcessState(TakerAsBuyerTrade.ProcessState.FIAT_PAYMENT_STARTED);
|
||||
else if (takerTrade instanceof TakerAsSellerTrade)
|
||||
takerTrade.setProcessState(TakerAsSellerTrade.ProcessState.FIAT_PAYMENT_STARTED);
|
||||
|
||||
complete();
|
||||
} 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.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.LoggerFactory;
|
||||
@ -27,28 +27,28 @@ import org.slf4j.LoggerFactory;
|
||||
import static com.google.common.base.Preconditions.*;
|
||||
import static io.bitsquare.util.Validator.*;
|
||||
|
||||
public class ProcessRequestTakerDepositPaymentMessage extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(ProcessRequestTakerDepositPaymentMessage.class);
|
||||
public class TakerProcessRequestSellerDepositPaymentMessage extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(TakerProcessRequestSellerDepositPaymentMessage.class);
|
||||
|
||||
public ProcessRequestTakerDepositPaymentMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||
public TakerProcessRequestSellerDepositPaymentMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||
super(taskHandler, model);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doRun() {
|
||||
try {
|
||||
RequestTakerDepositPaymentMessage message = (RequestTakerDepositPaymentMessage) takerTradeProcessModel.getTradeMessage();
|
||||
RequestPayDepositMessage message = (RequestPayDepositMessage) takerTradeProcessModel.getTradeMessage();
|
||||
checkTradeId(takerTradeProcessModel.getId(), message);
|
||||
checkNotNull(message);
|
||||
|
||||
takerTradeProcessModel.offerer.setConnectedOutputsForAllInputs(checkNotNull(message.offererConnectedOutputsForAllInputs));
|
||||
checkArgument(message.offererConnectedOutputsForAllInputs.size() > 0);
|
||||
takerTradeProcessModel.offerer.setOutputs(checkNotNull(message.offererOutputs));
|
||||
takerTradeProcessModel.offerer.setTradeWalletPubKey(checkNotNull(message.offererTradeWalletPubKey));
|
||||
takerTradeProcessModel.offerer.setP2pSigPublicKey(checkNotNull(message.offererP2PSigPublicKey));
|
||||
takerTradeProcessModel.offerer.setP2pEncryptPubKey(checkNotNull(message.offererP2PEncryptPublicKey));
|
||||
takerTradeProcessModel.offerer.setFiatAccount(checkNotNull(message.offererFiatAccount));
|
||||
takerTradeProcessModel.offerer.setAccountId(nonEmptyStringOf(message.offererAccountId));
|
||||
takerTradeProcessModel.offerer.setConnectedOutputsForAllInputs(checkNotNull(message.buyerConnectedOutputsForAllInputs));
|
||||
checkArgument(message.buyerConnectedOutputsForAllInputs.size() > 0);
|
||||
takerTradeProcessModel.offerer.setOutputs(checkNotNull(message.buyerOutputs));
|
||||
takerTradeProcessModel.offerer.setTradeWalletPubKey(checkNotNull(message.buyerTradeWalletPubKey));
|
||||
takerTradeProcessModel.offerer.setP2pSigPublicKey(checkNotNull(message.buyerP2PSigPublicKey));
|
||||
takerTradeProcessModel.offerer.setP2pEncryptPubKey(checkNotNull(message.buyerP2PEncryptPublicKey));
|
||||
takerTradeProcessModel.offerer.setFiatAccount(checkNotNull(message.buyerFiatAccount));
|
||||
takerTradeProcessModel.offerer.setAccountId(nonEmptyStringOf(message.buyerAccountId));
|
||||
|
||||
complete();
|
||||
} 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.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.PayoutTxPublishedMessage;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SendPayoutTxPublishedMessage extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(SendPayoutTxPublishedMessage.class);
|
||||
public class TakerSendsPayoutTxPublishedMessage extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(TakerSendsPayoutTxPublishedMessage.class);
|
||||
|
||||
public SendPayoutTxPublishedMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||
public TakerSendsPayoutTxPublishedMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||
super(taskHandler, model);
|
||||
}
|
||||
|
||||
@ -51,7 +53,12 @@ public class SendPayoutTxPublishedMessage extends TakerTradeTask {
|
||||
public void handleFault() {
|
||||
appendToErrorMessage("Sending PayoutTxPublishedMessage failed");
|
||||
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();
|
||||
}
|
||||
});
|
@ -19,6 +19,8 @@ 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.RequestDepositTxInputsMessage;
|
||||
|
||||
@ -27,10 +29,10 @@ import javafx.application.Platform;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SendRequestDepositTxInputsMessage extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(SendRequestDepositTxInputsMessage.class);
|
||||
public class TakerSendsRequestDepositTxInputsMessage extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(TakerSendsRequestDepositTxInputsMessage.class);
|
||||
|
||||
public SendRequestDepositTxInputsMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||
public TakerSendsRequestDepositTxInputsMessage(TaskRunner taskHandler, TakerTrade 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.
|
||||
if (retryCounter == 0) {
|
||||
retryCounter++;
|
||||
Platform.runLater(SendRequestDepositTxInputsMessage.this::doRun);
|
||||
Platform.runLater(TakerSendsRequestDepositTxInputsMessage.this::doRun);
|
||||
}
|
||||
else {
|
||||
appendToErrorMessage("Sending TakeOfferFeePayedMessage to offerer failed. Maybe the network connection was " +
|
||||
@ -68,7 +70,12 @@ public class SendRequestDepositTxInputsMessage extends TakerTradeTask {
|
||||
"or cancel that trade.");
|
||||
|
||||
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();
|
||||
}
|
@ -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.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.RequestPublishDepositTxMessage;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SendRequestPublishDepositTxMessage extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(SendRequestPublishDepositTxMessage.class);
|
||||
public class TakerSendsRequestPublishDepositTxMessage extends TakerTradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(TakerSendsRequestPublishDepositTxMessage.class);
|
||||
|
||||
public SendRequestPublishDepositTxMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||
public TakerSendsRequestPublishDepositTxMessage(TaskRunner taskHandler, TakerTrade model) {
|
||||
super(taskHandler, model);
|
||||
}
|
||||
|
||||
@ -58,7 +60,11 @@ public class SendRequestPublishDepositTxMessage extends TakerTradeTask {
|
||||
public void handleFault() {
|
||||
appendToErrorMessage("Sending RequestOffererPublishDepositTxMessage failed");
|
||||
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();
|
||||
}
|
@ -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…
Reference in New Issue
Block a user