change address added

This commit is contained in:
Manfred Karrer 2014-06-26 16:57:23 +02:00
parent 0545148f74
commit dc9141ca19
12 changed files with 163 additions and 104 deletions

View File

@ -31,8 +31,6 @@ import java.util.*;
import java.util.concurrent.ExecutionException;
import static com.google.bitcoin.script.ScriptOpCodes.OP_RETURN;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
public class WalletFacade
{
@ -177,7 +175,7 @@ public class WalletFacade
addressEntryList.add(registrationAddressEntry);
saveAddressInfoList();
getNewTradeAddressInfo();
getNewTradeAddressEntry();
}
}
@ -257,7 +255,7 @@ public class WalletFacade
{
AddressEntry arbitratorDepositAddressEntry = getAddressInfoByAddressContext(AddressEntry.AddressContext.ARBITRATOR_DEPOSIT);
if (arbitratorDepositAddressEntry == null)
arbitratorDepositAddressEntry = getNewArbitratorDepositAddressInfo();
arbitratorDepositAddressEntry = getNewArbitratorDepositAddressEntry();
return arbitratorDepositAddressEntry;
}
@ -276,7 +274,7 @@ public class WalletFacade
if (filteredList != null && filteredList.size() > 0)
return filteredList.get(0);
else
return getNewTradeAddressInfo();
return getNewTradeAddressEntry();
}
private AddressEntry getAddressInfoByAddressContext(AddressEntry.AddressContext addressContext)
@ -314,12 +312,12 @@ public class WalletFacade
// Create new AddressInfo objects
///////////////////////////////////////////////////////////////////////////////////////////
public AddressEntry getNewTradeAddressInfo()
public AddressEntry getNewTradeAddressEntry()
{
return getNewAddressInfo(AddressEntry.AddressContext.TRADE);
return getNewAddressEntry(AddressEntry.AddressContext.TRADE);
}
private AddressEntry getNewAddressInfo(AddressEntry.AddressContext addressContext)
private AddressEntry getNewAddressEntry(AddressEntry.AddressContext addressContext)
{
ECKey key = new ECKey();
wallet.addKey(key);
@ -330,11 +328,20 @@ public class WalletFacade
return addressEntry;
}
private AddressEntry getNewArbitratorDepositAddressInfo()
private AddressEntry getNewArbitratorDepositAddressEntry()
{
return getNewAddressInfo(AddressEntry.AddressContext.ARBITRATOR_DEPOSIT);
return getNewAddressEntry(AddressEntry.AddressContext.ARBITRATOR_DEPOSIT);
}
private AddressEntry getAddressEntryByAddressString(String address)
{
for (AddressEntry addressEntry : addressEntryList)
{
if (addressEntry.getAddressString().equals(address))
return addressEntry;
}
return null;
}
///////////////////////////////////////////////////////////////////////////////////////////
// TransactionConfidence
@ -369,7 +376,26 @@ public class WalletFacade
private TransactionConfidence getTransactionConfidence(Transaction tx, Address address)
{
List<TransactionOutput> mergedOutputs = getOutputsWithConnectedOutputs(tx);
List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
for (int i = 0; i < mergedOutputs.size(); i++)
{
TransactionOutput transactionOutput = mergedOutputs.get(i);
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH())
{
Address outputAddress = transactionOutput.getScriptPubKey().getToAddress(params);
if (address.equals(outputAddress))
{
transactionConfidenceList.add(tx.getConfidence());
}
}
}
return getMostRecentConfidence(transactionConfidenceList);
}
private List<TransactionOutput> getOutputsWithConnectedOutputs(Transaction tx)
{
List<TransactionOutput> transactionOutputs = tx.getOutputs();
List<TransactionOutput> connectedOutputs = new ArrayList<>();
@ -386,20 +412,7 @@ public class WalletFacade
List<TransactionOutput> mergedOutputs = new ArrayList<>();
mergedOutputs.addAll(transactionOutputs);
mergedOutputs.addAll(connectedOutputs);
for (int i = 0; i < mergedOutputs.size(); i++)
{
TransactionOutput transactionOutput = mergedOutputs.get(i);
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH())
{
Address outputAddress = transactionOutput.getScriptPubKey().getToAddress(params);
if (address.equals(outputAddress))
{
transactionConfidenceList.add(tx.getConfidence());
}
}
}
return getMostRecentConfidence(transactionConfidenceList);
return mergedOutputs;
}
private TransactionConfidence getMostRecentConfidence(List<TransactionConfidence> transactionConfidenceList)
@ -431,26 +444,31 @@ public class WalletFacade
return transactionConfidence != null && transactionConfidence.getConfidenceType().equals(TransactionConfidence.ConfidenceType.BUILDING);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Balance
///////////////////////////////////////////////////////////////////////////////////////////
public BigInteger getBalanceForAddress(Address address)
{
LinkedList<TransactionOutput> all = wallet.calculateAllSpendCandidates(true);
BigInteger value = BigInteger.ZERO;
for (TransactionOutput transactionOutput : all)
return getBalance(wallet.calculateAllSpendCandidates(true), address);
}
private BigInteger getBalance(LinkedList<TransactionOutput> transactionOutputs, Address address)
{
BigInteger balance = BigInteger.ZERO;
for (TransactionOutput transactionOutput : transactionOutputs)
{
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH())
{
Address addressOutput = transactionOutput.getScriptPubKey().getToAddress(params);
if (addressOutput.equals(address))
{
value = value.add(transactionOutput.getValue());
balance = balance.add(transactionOutput.getValue());
}
}
}
return value;
return balance;
}
private void notifyBalanceListeners(Transaction tx)
@ -458,38 +476,9 @@ public class WalletFacade
for (int i = 0; i < balanceListeners.size(); i++)
{
BalanceListener balanceListener = balanceListeners.get(i);
List<TransactionOutput> transactionOutputs = tx.getOutputs();
for (int n = 0; n < transactionOutputs.size(); n++)
{
TransactionOutput transactionOutput = transactionOutputs.get(n);
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH())
{
Address address = transactionOutput.getScriptPubKey().getToAddress(params);
log.debug("notifyBalanceListeners transactionOutput address/balanceListener.getAddress() " + address.toString() + " / " + balanceListener.getAddress().toString());
if (address.equals(balanceListener.getAddress()))
{
balanceListener.onBalanceChanged(getBalanceForAddress(address));
}
}
}
List<TransactionInput> transactionInputs = tx.getInputs();
for (int n = 0; n < transactionInputs.size(); n++)
{
TransactionInput transactionInput = transactionInputs.get(n);
TransactionOutput transactionOutput = transactionInput.getConnectedOutput();
log.debug("notifyBalanceListeners transactionInput.getConnectedOutput() " + transactionInput.getConnectedOutput());
if (transactionOutput != null && (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH()))
{
Address address = transactionOutput.getScriptPubKey().getToAddress(params);
log.debug("notifyBalanceListeners transactionInput address/balanceListener.getAddress() " + address.toString() + " / " + balanceListener.getAddress().toString());
if (address.equals(balanceListener.getAddress()))
{
balanceListener.onBalanceChanged(getBalanceForAddress(address));
}
}
}
BigInteger balance = getBalanceForAddress(balanceListener.getAddress());
balanceListener.onBalanceChanged(balance);
}
}
@ -620,19 +609,21 @@ public class WalletFacade
// Withdrawal
///////////////////////////////////////////////////////////////////////////////////////////
public String sendFunds(AddressEntry withdrawFromAddressEntry, String withdrawToAddress, BigInteger amount, FutureCallback<Transaction> callback) throws AddressFormatException, InsufficientMoneyException, IllegalArgumentException
public String sendFunds(String withdrawFromAddress,
String withdrawToAddress,
String changeAddress,
BigInteger amount,
FutureCallback<Transaction> callback) throws AddressFormatException, InsufficientMoneyException, IllegalArgumentException
{
checkNotNull(withdrawFromAddressEntry);
checkArgument(withdrawToAddress.length() > 0);
checkArgument(amount.compareTo(FeePolicy.TX_FEE) > 0);
Transaction tx = new Transaction(params);
tx.addOutput(amount.subtract(FeePolicy.TX_FEE), new Address(params, withdrawToAddress));
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx);
// we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to wait for 1 confirmation)
sendRequest.coinSelector = new AddressBasedCoinSelector(params, withdrawFromAddressEntry, true);
sendRequest.changeAddress = withdrawFromAddressEntry.getAddress();
sendRequest.coinSelector = new AddressBasedCoinSelector(params, getAddressEntryByAddressString(withdrawFromAddress), true);
sendRequest.changeAddress = getAddressEntryByAddressString(changeAddress).getAddress();
Wallet.SendResult sendResult = wallet.sendCoins(sendRequest);
Futures.addCallback(sendResult.broadcastComplete, callback);

View File

@ -119,7 +119,7 @@ public class DepositController implements Initializable, ChildController, Hibern
@FXML
public void onAddNewTradeAddress(ActionEvent actionEvent)
{
addressList.add(new DepositListItem(walletFacade.getNewTradeAddressInfo(), walletFacade));
addressList.add(new DepositListItem(walletFacade.getNewTradeAddressEntry(), walletFacade));
}

View File

@ -43,7 +43,6 @@ public class WithdrawalController implements Initializable, ChildController, Hib
private WalletFacade walletFacade;
protected ObservableList<WithdrawalListItem> addressList;
private AddressEntry selectedAddressEntry;
@FXML
private TableView tableView;
@ -52,7 +51,7 @@ public class WithdrawalController implements Initializable, ChildController, Hib
@FXML
private Button addNewAddressButton;
@FXML
private TextField withdrawFromTextField, withdrawToTextField, amountTextField;
private TextField withdrawFromTextField, withdrawToTextField, amountTextField, changeAddressTextField;
///////////////////////////////////////////////////////////////////////////////////////////
@ -88,13 +87,13 @@ public class WithdrawalController implements Initializable, ChildController, Hib
{
if (newValue != null)
{
BitSquareValidator.resetTextFields(withdrawFromTextField, withdrawToTextField, amountTextField);
BitSquareValidator.resetTextFields(withdrawFromTextField, withdrawToTextField, amountTextField, changeAddressTextField);
if (newValue.getBalance().compareTo(BigInteger.ZERO) > 0)
{
amountTextField.setText(BtcFormatter.satoshiToString(newValue.getBalance()));
selectedAddressEntry = newValue.getAddressEntry();
withdrawFromTextField.setText(newValue.getAddressEntry().getAddressString());
changeAddressTextField.setText(newValue.getAddressEntry().getAddressString());
}
else
{
@ -161,7 +160,7 @@ public class WithdrawalController implements Initializable, ChildController, Hib
{
try
{
BitSquareValidator.textFieldsNotEmpty(amountTextField, withdrawFromTextField, withdrawToTextField);
BitSquareValidator.textFieldsNotEmpty(amountTextField, withdrawFromTextField, withdrawToTextField, changeAddressTextField);
BitSquareValidator.textFieldsHasDoubleValueWithReset(amountTextField);
BigInteger amount = BtcFormatter.stringValueToSatoshis(amountTextField.getText());
@ -172,7 +171,7 @@ public class WithdrawalController implements Initializable, ChildController, Hib
@Override
public void onSuccess(Transaction transaction)
{
BitSquareValidator.resetTextFields(withdrawFromTextField, withdrawToTextField, amountTextField);
BitSquareValidator.resetTextFields(withdrawFromTextField, withdrawToTextField, amountTextField, changeAddressTextField);
log.info("onWithdraw onSuccess txid:" + transaction.getHashAsString());
}
@ -194,7 +193,7 @@ public class WithdrawalController implements Initializable, ChildController, Hib
{
try
{
walletFacade.sendFunds(selectedAddressEntry, withdrawToTextField.getText(), amount, callback);
walletFacade.sendFunds(withdrawFromTextField.getText(), withdrawToTextField.getText(), changeAddressTextField.getText(), amount, callback);
} catch (AddressFormatException e)
{
Popups.openErrorPopup("Address invalid", "The address is not correct. Please check the address format.");

View File

@ -35,10 +35,13 @@
<Label text="Withdraw from address:" GridPane.rowIndex="1"/>
<TextField fx:id="withdrawFromTextField" promptText="Select a source address from the table" GridPane.rowIndex="1" GridPane.columnIndex="1"/>
<Label text="Withdraw to address:" GridPane.rowIndex="2"/>
<TextField fx:id="withdrawToTextField" GridPane.rowIndex="2" GridPane.columnIndex="1"/>
<Label text="Change address:" GridPane.rowIndex="2"/>
<TextField fx:id="changeAddressTextField" GridPane.rowIndex="2" GridPane.columnIndex="1"/>
<Button text="Withdraw" defaultButton="true" onAction="#onWithdraw" GridPane.rowIndex="3" GridPane.columnIndex="1"/>
<Label text="Withdraw to address:" GridPane.rowIndex="3"/>
<TextField fx:id="withdrawToTextField" GridPane.rowIndex="3" GridPane.columnIndex="1"/>
<Button text="Withdraw" defaultButton="true" onAction="#onWithdraw" GridPane.rowIndex="4" GridPane.columnIndex="1"/>
</children>
<columnConstraints>

View File

@ -97,7 +97,11 @@
-fx-alignment: center;
}
.table-view .table-row-cell:selected .text {
.table-view .text {
-fx-fill: black;
}
.table-view .table-row-cell:selected .table-row-cell:row-selection .table-row-cell:cell-selection .text {
-fx-fill: white;
}

View File

@ -8,6 +8,7 @@ import io.bitsquare.btc.BtcFormatter;
import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.Hibernate;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
import io.bitsquare.gui.util.BitSquareConverter;
@ -42,7 +43,7 @@ import java.net.URL;
import java.util.Random;
import java.util.ResourceBundle;
public class CreateOfferController implements Initializable, ChildController
public class CreateOfferController implements Initializable, ChildController, Hibernate
{
private static final Logger log = LoggerFactory.getLogger(CreateOfferController.class);
@ -160,6 +161,22 @@ public class CreateOfferController implements Initializable, ChildController
}
///////////////////////////////////////////////////////////////////////////////////////////
// Interface implementation: Hibernate
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void sleep()
{
cleanup();
}
@Override
public void awake()
{
}
///////////////////////////////////////////////////////////////////////////////////////////
// UI Handlers
///////////////////////////////////////////////////////////////////////////////////////////

View File

@ -6,9 +6,6 @@ import io.bitsquare.trade.Offer;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
* Wrapper for observable properties used by orderbook table view
*/
public class OrderBookListItem
{
protected final StringProperty price = new SimpleStringProperty();

View File

@ -2,6 +2,7 @@ package io.bitsquare.gui.orders.closed;
import com.google.inject.Inject;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.Hibernate;
import io.bitsquare.gui.NavigationController;
import javafx.fxml.Initializable;
import org.slf4j.Logger;
@ -10,7 +11,7 @@ import org.slf4j.LoggerFactory;
import java.net.URL;
import java.util.ResourceBundle;
public class ClosedTradeController implements Initializable, ChildController
public class ClosedTradeController implements Initializable, ChildController, Hibernate
{
private static final Logger log = LoggerFactory.getLogger(ClosedTradeController.class);
@ -51,6 +52,23 @@ public class ClosedTradeController implements Initializable, ChildController
log.debug("cleanup" + this);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Interface implementation: Hibernate
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void sleep()
{
cleanup();
}
@Override
public void awake()
{
}
///////////////////////////////////////////////////////////////////////////////////////////
// GUI Event handlers
///////////////////////////////////////////////////////////////////////////////////////////

View File

@ -2,6 +2,7 @@ package io.bitsquare.gui.orders.offer;
import com.google.inject.Inject;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.Hibernate;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.util.Icons;
import io.bitsquare.trade.Offer;
@ -26,10 +27,10 @@ import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
public class OfferController implements Initializable, ChildController
public class OfferController implements Initializable, ChildController, Hibernate
{
private static final Logger log = LoggerFactory.getLogger(OfferController.class);
protected ObservableList<OfferListItem> offerListItems = FXCollections.observableArrayList();
protected ObservableList<OfferListItem> offerListItems;
@FXML
private TableColumn<String, OfferListItem> offerIdColumn, dateColumn, amountColumn, priceColumn, volumeColumn, removeColumn;
@ -56,16 +57,9 @@ public class OfferController implements Initializable, ChildController
@Override
public void initialize(URL url, ResourceBundle rb)
{
awake();
setOfferIdColumnColumnCellFactory();
setRemoveColumnCellFactory();
Map<String, Offer> offerMap = trading.getOffers();
List<Offer> offerList = new ArrayList<>(offerMap.values());
for (int i = 0; i < offerList.size(); i++)
{
offerListItems.add(new OfferListItem(offerList.get(i)));
}
offerTable.setItems(offerListItems);
offerTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
}
@ -85,6 +79,31 @@ public class OfferController implements Initializable, ChildController
log.debug("cleanup" + this);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Interface implementation: Hibernate
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void sleep()
{
cleanup();
}
@Override
public void awake()
{
offerListItems = FXCollections.observableArrayList();
Map<String, Offer> offerMap = trading.getOffers();
List<Offer> offerList = new ArrayList<>(offerMap.values());
for (int i = 0; i < offerList.size(); i++)
{
offerListItems.add(new OfferListItem(offerList.get(i)));
}
offerTable.setItems(offerListItems);
}
///////////////////////////////////////////////////////////////////////////////////////////
// GUI Event handlers
///////////////////////////////////////////////////////////////////////////////////////////

View File

@ -9,26 +9,19 @@ import javafx.beans.property.StringProperty;
import java.text.DateFormat;
import java.util.Locale;
/**
* Wrapper for observable properties used by orderbook table view
*/
public class OfferListItem
{
protected final StringProperty price = new SimpleStringProperty();
protected final StringProperty amount = new SimpleStringProperty();
protected final StringProperty date = new SimpleStringProperty();
protected final StringProperty volume = new SimpleStringProperty();
private final String offerId;
protected Offer offer;
public OfferListItem(Offer offer)
{
this.offer = offer;
DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.DEFAULT, Locale.getDefault());
DateFormat timeFormatter = DateFormat.getTimeInstance(DateFormat.DEFAULT, Locale.getDefault());
this.date.set(dateFormatter.format(offer.getCreationDate()) + " " + timeFormatter.format(offer.getCreationDate()));

View File

@ -34,10 +34,10 @@
</TableColumn>
<TableColumn text="Volume (Min.)" fx:id="volumeColumn" minWidth="70" sortable="false">
<cellValueFactory>
<PropertyValueFactory property="price"/>
<PropertyValueFactory property="volume"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Status" fx:id="removeColumn" minWidth="70" sortable="false"/>
<TableColumn text="" fx:id="removeColumn" minWidth="50" sortable="false"/>
</columns>
</TableView>

View File

@ -2,6 +2,7 @@ package io.bitsquare.gui.orders.pending;
import com.google.inject.Inject;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.Hibernate;
import io.bitsquare.gui.NavigationController;
import javafx.fxml.Initializable;
import org.slf4j.Logger;
@ -10,7 +11,7 @@ import org.slf4j.LoggerFactory;
import java.net.URL;
import java.util.ResourceBundle;
public class PendingTradeController implements Initializable, ChildController
public class PendingTradeController implements Initializable, ChildController, Hibernate
{
private static final Logger log = LoggerFactory.getLogger(PendingTradeController.class);
@ -51,6 +52,23 @@ public class PendingTradeController implements Initializable, ChildController
log.debug("cleanup" + this);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Interface implementation: Hibernate
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void sleep()
{
cleanup();
}
@Override
public void awake()
{
}
///////////////////////////////////////////////////////////////////////////////////////////
// GUI Event handlers
///////////////////////////////////////////////////////////////////////////////////////////