account registration

This commit is contained in:
Manfred Karrer 2014-04-28 00:14:10 +02:00
parent 28521c11a0
commit 38199b9b5f
85 changed files with 1736 additions and 730 deletions

Binary file not shown.

View File

@ -1,30 +1,25 @@
package io.bitsquare;
import com.google.bitcoin.store.BlockStoreException;
import com.google.bitcoin.utils.BriefLogFormatter;
import com.google.bitcoin.utils.Threading;
import com.google.common.base.Throwables;
import com.google.inject.Guice;
import com.google.inject.Injector;
import io.bitsquare.btc.IWalletFacade;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.di.BitSquareModule;
import io.bitsquare.di.GuiceFXMLLoader;
import io.bitsquare.setup.ISetup;
import io.bitsquare.setup.MockSetup;
import io.bitsquare.gui.util.Localisation;
import io.bitsquare.settings.Startup;
import io.bitsquare.storage.Storage;
import io.bitsquare.user.User;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public class BitSquare extends Application
{
private static final Logger log = LoggerFactory.getLogger(BitSquare.class);
private IWalletFacade walletFacade;
private WalletFacade walletFacade;
public static void main(String[] args)
{
@ -34,23 +29,30 @@ public class BitSquare extends Application
@Override
public void start(Stage stage) throws Exception
{
// Show the crash dialog for any exceptions that we don't handle and that hit the main loop.
//GuiUtils.handleCrashesOnThisThread();
try
{
init(stage);
} catch (Throwable t)
{
// Nicer message for the case where the block store file is locked.
if (Throwables.getRootCause(t) instanceof BlockStoreException)
{
//GuiUtils.informationalAlert("Already running", "This application is already running and cannot be started twice.");
}
else
{
throw t;
}
}
final Injector injector = Guice.createInjector(new BitSquareModule());
walletFacade = injector.getInstance(WalletFacade.class);
// apply stored data
final User user = injector.getInstance(User.class);
final Storage storage = injector.getInstance(Storage.class);
user.updateFromStorage((User) storage.read(user.getClass().getName()));
//TODO remove
final Startup setup = injector.getInstance(Startup.class);
setup.applyPersistedData();
stage.setTitle("BitSquare");
GuiceFXMLLoader.setInjector(injector);
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource("/io/bitsquare/gui/MainView.fxml"), Localisation.getResourceBundle());
final Parent mainView = loader.load();
final Scene scene = new Scene(mainView, 800, 600);
stage.setScene(scene);
final String global = getClass().getResource("/io/bitsquare/gui/global.css").toExternalForm();
scene.getStylesheets().setAll(global);
stage.show();
}
@Override
@ -60,38 +62,4 @@ public class BitSquare extends Application
super.stop();
}
private void init(Stage stage) throws IOException
{
// Make log output concise.
BriefLogFormatter.init();
// Tell bitcoinj to run event handlers on the JavaFX UI thread. This keeps things simple and means
// we cannot forget to switch threads when adding event handlers. Unfortunately, the DownloadListener
// we give to the app kit is currently an exception and runs on a library thread. It'll get fixed in
// a future version.
Threading.USER_THREAD = Platform::runLater;
final Injector injector = Guice.createInjector(new BitSquareModule());
walletFacade = injector.getInstance(IWalletFacade.class);
final ISetup setup = injector.getInstance(MockSetup.class);
setup.applyPersistedData();
stage.setTitle("BitSquare");
// main view
final GuiceFXMLLoader loader = new GuiceFXMLLoader(injector);
final Parent mainView = loader.load(BitSquare.class.getResourceAsStream("/io/bitsquare/gui/MainView.fxml"));
final Scene scene = new Scene(mainView, 800, 600);
stage.setScene(scene);
// apply css
final String global = getClass().getResource("/io/bitsquare/gui/global.css").toExternalForm();
// final String textValidation = getClass().getResource("/wallettemplate/utils/text-validation.css").toExternalForm();
//scene.getStylesheets().setAll(global, textValidation);
scene.getStylesheets().setAll(global);
stage.show();
}
}

View File

@ -0,0 +1,67 @@
package io.bitsquare.bank;
import java.io.Serializable;
public class BankAccount implements Serializable
{
private static final long serialVersionUID = 1792577576443221268L;
public BankAccountType bankAccountType;
public String accountPrimaryID;
public String accountSecondaryID;
public String accountHolderName;
private String uid;
// TODO just for mock yet
public BankAccount(BankAccountType bankAccountType)
{
this.bankAccountType = bankAccountType;
}
public BankAccount(BankAccountType bankAccountType, String accountPrimaryID, String accountSecondaryID, String accountHolderName)
{
this.bankAccountType = bankAccountType;
this.accountPrimaryID = accountPrimaryID;
this.accountSecondaryID = accountSecondaryID;
this.accountHolderName = accountHolderName;
uid = bankAccountType + "_" + accountPrimaryID + "_" + accountSecondaryID + "_" + accountHolderName;
}
public String getAccountPrimaryID()
{
return accountPrimaryID;
}
public String getAccountSecondaryID()
{
return accountSecondaryID;
}
public String getAccountHolderName()
{
return accountHolderName;
}
public BankAccountType getBankAccountType()
{
return bankAccountType;
}
public String getUid()
{
return uid;
}
@Override
public String toString()
{
return "BankAccount{" +
"bankAccountType=" + bankAccountType +
", accountPrimaryID='" + accountPrimaryID + '\'' +
", accountSecondaryID='" + accountSecondaryID + '\'' +
", accountHolderName='" + accountHolderName + '\'' +
'}';
}
}

View File

@ -0,0 +1,47 @@
package io.bitsquare.bank;
import java.io.Serializable;
public class BankAccountType implements Serializable
{
private static final long serialVersionUID = -8772708150197835288L;
private BankAccountTypeEnum type;
private String primaryIDName;
private String secondaryIDName;
public BankAccountType(BankAccountTypeEnum type, String primaryIDName, String secondaryIDName)
{
this.type = type;
this.primaryIDName = primaryIDName;
this.secondaryIDName = secondaryIDName;
}
public BankAccountTypeEnum getType()
{
return type;
}
public String getPrimaryIDName()
{
return primaryIDName;
}
public String getSecondaryIDName()
{
return secondaryIDName;
}
@Override
public String toString()
{
//TODO localisation
return type.toString();
}
public static enum BankAccountTypeEnum
{
SEPA, WIRE, INTERNATIONAL, OK_PAY, NET_TELLER, PERFECT_MONEY, OTHER
}
}

View File

@ -0,0 +1,197 @@
package io.bitsquare.btc;
import com.google.bitcoin.core.*;
import com.google.bitcoin.script.Script;
import com.google.bitcoin.script.ScriptBuilder;
import com.google.bitcoin.store.UnreadableWalletException;
import com.google.bitcoin.store.WalletProtobufSerializer;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigInteger;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static com.google.bitcoin.script.ScriptOpCodes.OP_RETURN;
public class AccountRegistrationWallet extends Wallet implements WalletEventListener
{
private static final Logger log = LoggerFactory.getLogger(AccountRegistrationWallet.class);
private NetworkParameters networkParameters;
public AccountRegistrationWallet(NetworkParameters networkParameters, BlockChain chain, PeerGroup peerGroup)
{
super(networkParameters);
this.networkParameters = networkParameters;
File walletFile = new File(".", "bitsquare_account_reg" + ".wallet");
if (walletFile.exists())
{
try
{
FileInputStream walletStream = new FileInputStream(walletFile);
new WalletProtobufSerializer().readWallet(WalletProtobufSerializer.parseToProto(walletStream), this);
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (UnreadableWalletException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
}
else
{
addKey(new ECKey());
}
chain.addWallet(this);
peerGroup.addWallet(this);
autosaveToFile(walletFile, 1, TimeUnit.SECONDS, null);
}
public Address getAddress()
{
return getKey().toAddress(networkParameters);
}
public ECKey getKey()
{
return getKeys().get(0);
}
public void saveToBlockchain(byte[] dataToEmbed) throws InsufficientMoneyException
{
Script script = new ScriptBuilder()
.op(OP_RETURN)
.data(dataToEmbed)
.build();
Transaction transaction = new Transaction(networkParameters);
TransactionOutput dataOutput = new TransactionOutput(networkParameters,
transaction,
Transaction.MIN_NONDUST_OUTPUT,
script.getProgram());
transaction.addOutput(dataOutput);
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(transaction);
// give fee to miners yet. Later it could be spent to other traders via lottery...
sendRequest.fee = Fees.ACCOUNT_REGISTRATION_FEE;
Wallet.SendResult sendResult = sendCoins(sendRequest);
//TODO
Futures.addCallback(sendResult.broadcastComplete, new FutureCallback<Transaction>()
{
@Override
public void onSuccess(Transaction result)
{
log.info("sendResult onSuccess:" + result.toString());
// Platform.runLater(overlayUi::done);
}
@Override
public void onFailure(Throwable t)
{
log.warn("sendResult onFailure:" + t.toString());
// We died trying to empty the wallet.
// crashAlert(t);
}
});
//TODO
sendResult.tx.getConfidence().addEventListener((tx, reason) -> {
//if (reason == TransactionConfidence.Listener.ChangeReason.SEEN_PEERS)
//updateTitleForBroadcast();
});
}
public int getConfirmations()
{
// TODO just a quick impl. need to be checked if it works for all cases...
Set<Transaction> transactions = getTransactions(true);
if (transactions != null && transactions.size() == 1)
{
Transaction transaction = transactions.iterator().next();
final int lastBlockSeenHeight = getLastBlockSeenHeight();
int appearedAtChainHeight = 0;
if (transaction.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING)
appearedAtChainHeight = transaction.getConfidence().getAppearedAtChainHeight();
final int numberOfBlocksEmbedded = lastBlockSeenHeight - appearedAtChainHeight + 1;
if (numberOfBlocksEmbedded > 0)
return numberOfBlocksEmbedded;
else
return 0;
}
return 0;
}
public int getNumberOfPeersSeenTx()
{
// TODO just a quick impl. need to be checked if it works for all cases...
Set<Transaction> transactions = getTransactions(true);
if (transactions != null && transactions.size() == 1)
{
Transaction transaction = transactions.iterator().next();
return (transaction == null || transaction.getConfidence() == null) ? 0 : transaction.getConfidence().numBroadcastPeers();
}
return 0;
}
//TODO those handlers are not called yet...
@Override
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance)
{
log.info("onCoinsReceived");
}
@Override
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance)
{
log.info("onCoinsSent");
}
@Override
public void onReorganize(Wallet wallet)
{
log.info("onReorganize");
}
@Override
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx)
{
log.info("onTransactionConfidenceChanged");
}
@Override
public void onWalletChanged(Wallet wallet)
{
log.info("onWalletChanged");
}
@Override
public void onKeysAdded(Wallet wallet, List<ECKey> keys)
{
log.info("onKeysAdded");
}
@Override
public void onScriptsAdded(Wallet wallet, List<Script> scripts)
{
log.info("onScriptsAdded");
}
}

View File

@ -3,7 +3,9 @@ package io.bitsquare.btc;
import com.google.inject.Inject;
/**
* Gateway to blockchain
* That facade delivers blockchain functionality from the bitcoinJ library
* Code from BitcoinJ must not be used outside that facade.
* That way a change of the library will only affect that class.
*/
public class BlockChainFacade
{
@ -13,5 +15,32 @@ public class BlockChainFacade
}
public boolean verifyAddressInBlockChain(String hashAsHexStringToVerify, String address)
{
return findAddressInBlockChain(address)
&& getDataForTxWithAddress(hashAsHexStringToVerify, address)
&& isFeePayed(address);
}
private boolean findAddressInBlockChain(String address)
{
// TODO
// lookup for address in blockchain
return true;
}
private boolean getDataForTxWithAddress(String hashToVerify, String address)
{
// TODO
// check if data after OP_RETURN match hashToVerify
return true;
}
private boolean isFeePayed(String address)
{
// TODO
// check if fee is payed
return true;
}
}

View File

@ -0,0 +1,10 @@
package io.bitsquare.btc;
import java.util.Date;
public interface DownloadListener
{
void progress(double percent, int blocksSoFar, Date date);
void doneDownload();
}

View File

@ -1,11 +1,14 @@
package io.bitsquare.btc;
import com.google.bitcoin.core.Transaction;
import java.math.BigInteger;
public class Fees
{
public static BigInteger ACCOUNT_REGISTRATION_FEE = Transaction.MIN_NONDUST_OUTPUT;// Utils.toNanoCoins("0.001");
public static BigInteger OFFER_CREATION_FEE = new BigInteger("500000");
public static BigInteger OFFER_TAKER_FEE = OFFER_CREATION_FEE;
public static BigInteger BTC_NETWORK_FEE = new BigInteger("10000");
}

View File

@ -1,34 +0,0 @@
package io.bitsquare.btc;
import com.google.bitcoin.core.PeerEventListener;
import java.math.BigInteger;
public interface IWalletFacade
{
public static final String MAIN_NET = "MAIN_NET";
public static final String TEST_NET = "TEST_NET";
public static final String REG_TEST_NET = "REG_TEST_NET";
void initWallet(PeerEventListener peerEventListener);
void terminateWallet();
/**
*
* @return current balance in satoshis
*/
BigInteger getBalance();
/**
*
* @return
*/
String getAddress();
boolean pay(BigInteger satoshisToPay, String destinationAddress);
KeyPair createNewAddress();
}

View File

@ -2,6 +2,7 @@ package io.bitsquare.btc;
public class KeyPair
{
//TODO just for mock, remove later
private String pubKey;
private String privKey;

View File

@ -1,40 +1,61 @@
package io.bitsquare.btc;
import com.google.bitcoin.core.Address;
import com.google.bitcoin.core.NetworkParameters;
import com.google.bitcoin.core.PeerEventListener;
import com.google.bitcoin.core.Wallet;
import com.google.bitcoin.core.*;
import com.google.bitcoin.kits.WalletAppKit;
import com.google.bitcoin.params.MainNetParams;
import com.google.bitcoin.params.RegTestParams;
import com.google.bitcoin.utils.Threading;
import com.google.inject.Inject;
import io.bitsquare.crypto.CryptoFacade;
import javafx.application.Platform;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import wallettemplate.Main;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
public class WalletFacade implements IWalletFacade
/**
* That facade delivers wallet functionality from the bitcoinJ library
* Code from BitcoinJ must not be used outside that facade.
* That way a change of the library will only affect that class.
*/
public class WalletFacade
{
public static final String MAIN_NET = "MAIN_NET";
public static final String TEST_NET = "TEST_NET";
private static final Logger log = LoggerFactory.getLogger(WalletFacade.class);
private NetworkParameters networkParameters;
private WalletAppKit walletAppKit;
private CryptoFacade cryptoFacade;
private BlockChainFacade blockChainFacade;
private BigInteger balance;
// that wallet is used only for the registration process
private AccountRegistrationWallet accountRegistrationWallet = null;
private List<DownloadListener> downloadListeners = new ArrayList<>();
@Inject
public WalletFacade(NetworkParameters networkParameters, WalletAppKit walletAppKit)
public WalletFacade(NetworkParameters networkParameters, WalletAppKit walletAppKit, CryptoFacade cryptoFacade, BlockChainFacade blockChainFacade)
{
this.networkParameters = networkParameters;
this.walletAppKit = walletAppKit;
balance = new BigInteger("100000000");
this.cryptoFacade = cryptoFacade;
this.blockChainFacade = blockChainFacade;
}
@Override
public void initWallet(PeerEventListener peerEventListener)
public void initWallet()
{
// Tell bitcoinj to run event handlers on the JavaFX UI thread. This keeps things simple and means
// we cannot forget to switch threads when adding event handlers. Unfortunately, the DownloadListener
// we give to the app kit is currently an exception and runs on a library thread. It'll get fixed in
// a future version.
Threading.USER_THREAD = Platform::runLater;
if (networkParameters == RegTestParams.get())
{
walletAppKit.connectToLocalHost(); // You should run a regtest mode bitcoind locally.
@ -50,7 +71,7 @@ public class WalletFacade implements IWalletFacade
// Now configure and start the appkit. This will take a second or two - we could show a temporary splash screen
// or progress widget to keep the user engaged whilst we initialise, but we don't.
walletAppKit.setDownloadListener(peerEventListener)
walletAppKit.setDownloadListener(new BlockChainDownloadListener())
.setBlockingStartup(false)
.setUserAgent("BitSquare", "1.0");
walletAppKit.startAsync();
@ -62,45 +83,103 @@ public class WalletFacade implements IWalletFacade
log.info(walletAppKit.wallet().toString());
}
@Override
public void terminateWallet()
{
walletAppKit.stopAsync();
walletAppKit.awaitTerminated();
}
@Override
public void addDownloadListener(DownloadListener downloadListener)
{
downloadListeners.add(downloadListener);
}
public void removeDownloadListener(DownloadListener downloadListener)
{
downloadListeners.remove(downloadListener);
}
//MOCK
public KeyPair createNewAddress()
{
return new KeyPair(UUID.randomUUID().toString(), UUID.randomUUID().toString());
}
public BigInteger getBalance()
{
return walletAppKit.wallet().getBalance(Wallet.BalanceType.ESTIMATED);
}
@Override
public String getAddress()
{
return walletAppKit.wallet().getKeys().get(0).toAddress(networkParameters).toString();
}
@Override
public boolean pay(BigInteger satoshisToPay, String destinationAddress)
// account registration
public Address getAccountRegistrationAddress()
{
if (getBalance().subtract(satoshisToPay).longValue() > 0)
{
log.info("Pay " + satoshisToPay.toString() + " Satoshis to " + destinationAddress);
return true;
}
else
{
log.warn("Not enough funds in wallet for paying " + satoshisToPay.toString() + " Satoshis.");
return false;
}
return getAccountRegistrationWallet().getAddress();
}
@Override
public KeyPair createNewAddress()
public String getAccountRegistrationPubKey()
{
//MOCK
return new KeyPair(UUID.randomUUID().toString(), UUID.randomUUID().toString());
return Utils.bytesToHexString(getAccountRegistrationWallet().getKey().getPubKey());
}
}
public BigInteger getAccountRegistrationBalance()
{
return getAccountRegistrationWallet().getBalance(Wallet.BalanceType.ESTIMATED);
}
public int getAccountRegistrationConfirmations()
{
return getAccountRegistrationWallet().getConfirmations();
}
public int getAccountRegistrationNumberOfPeersSeenTx()
{
return getAccountRegistrationWallet().getNumberOfPeersSeenTx();
}
public void sendRegistrationTx(String stringifiedBankAccounts) throws InsufficientMoneyException
{
getAccountRegistrationWallet().saveToBlockchain(cryptoFacade.getEmbeddedAccountRegistrationData(getAccountRegistrationWallet().getKey(), stringifiedBankAccounts));
}
public boolean verifyAccountRegistration(String address, String hashAsHexStringToVerify, byte[] pubKey, String bankAccountIDs, String signatureBankAccountIDs)
{
return cryptoFacade.verifySignature(pubKey, bankAccountIDs, signatureBankAccountIDs)
&& cryptoFacade.verifyHash(hashAsHexStringToVerify, bankAccountIDs, signatureBankAccountIDs)
&& blockChainFacade.verifyAddressInBlockChain(hashAsHexStringToVerify, address);
}
private AccountRegistrationWallet getAccountRegistrationWallet()
{
if (accountRegistrationWallet == null)
accountRegistrationWallet = new AccountRegistrationWallet(networkParameters, walletAppKit.chain(), walletAppKit.peerGroup());
return accountRegistrationWallet;
}
// inner classes
private class BlockChainDownloadListener extends com.google.bitcoin.core.DownloadListener
{
@Override
protected void progress(double percent, int blocksSoFar, Date date)
{
super.progress(percent, blocksSoFar, date);
for (DownloadListener downloadListener : downloadListeners)
downloadListener.progress(percent, blocksSoFar, date);
}
@Override
protected void doneDownload()
{
super.doneDownload();
for (DownloadListener downloadListener : downloadListeners)
downloadListener.doneDownload();
}
}
}

View File

@ -0,0 +1,78 @@
package io.bitsquare.crypto;
import com.google.bitcoin.core.ECKey;
import com.google.bitcoin.core.Utils;
import com.google.common.base.Charsets;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;
import java.security.SignatureException;
import java.util.UUID;
/**
* That facade delivers crypto functionality from the bitcoinJ library
* Code from BitcoinJ must not be used outside that facade.
* That way a change of the library will only affect that class.
*/
public class CryptoFacade
{
private static final Logger log = LoggerFactory.getLogger(CryptoFacade.class);
@Inject
public CryptoFacade()
{
}
public String getRandomID()
{
return UUID.randomUUID().toString();
}
public byte[] getEmbeddedAccountRegistrationData(ECKey registrationKey, String stringifiedBankAccounts)
{
String signedBankAccountIDs = registrationKey.signMessage(stringifiedBankAccounts);
return Utils.sha256hash160(concatenateChunks(stringifiedBankAccounts, signedBankAccountIDs).getBytes(Charsets.UTF_8));
}
// TODO MOCK
public String signContract(String contractAsJson)
{
return contractAsJson;
}
// registration
public boolean verifySignature(byte[] pubKey, String msg, String sig)
{
try
{
ECKey key = new ECKey(null, pubKey, true);
key.verifyMessage(msg, sig);
return true;
} catch (SignatureException e)
{
return false;
}
}
public boolean verifyHash(String hashAsHexStringToVerify, String msg, String sig)
{
String hashAsHexString = Hex.toHexString(createHash(msg, sig));
return hashAsHexString.equals(hashAsHexStringToVerify);
}
private byte[] createHash(String msg, String sig)
{
byte[] hashBytes = concatenateChunks(msg, sig).getBytes(Charsets.UTF_8);
return Utils.sha256hash160(hashBytes);
}
private String concatenateChunks(String stringifiedBankAccounts, String signedBankAccountIDs)
{
return stringifiedBankAccounts + signedBankAccountIDs;
}
}

View File

@ -1,6 +0,0 @@
package io.bitsquare.crypto;
public interface ICryptoFacade
{
String sign(String data);
}

View File

@ -1,16 +0,0 @@
package io.bitsquare.crypto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MockCryptoFacade implements ICryptoFacade
{
private static final Logger log = LoggerFactory.getLogger(MockCryptoFacade.class);
@Override
public String sign(String data)
{
log.info("sign data: " + data);
return "signed contract data";
}
}

View File

@ -4,7 +4,6 @@ package io.bitsquare.di;
import com.google.bitcoin.core.NetworkParameters;
import com.google.bitcoin.kits.WalletAppKit;
import com.google.bitcoin.params.MainNetParams;
import com.google.bitcoin.params.RegTestParams;
import com.google.bitcoin.params.TestNet3Params;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
@ -12,21 +11,15 @@ import com.google.inject.Provider;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
import io.bitsquare.btc.BlockChainFacade;
import io.bitsquare.btc.IWalletFacade;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.crypto.ICryptoFacade;
import io.bitsquare.crypto.MockCryptoFacade;
import io.bitsquare.msg.IMessageFacade;
import io.bitsquare.crypto.CryptoFacade;
import io.bitsquare.msg.MessageFacade;
import io.bitsquare.settings.OrderBookFilterSettings;
import io.bitsquare.settings.Settings;
import io.bitsquare.setup.ISetup;
import io.bitsquare.setup.MockSetup;
import io.bitsquare.storage.IStorage;
import io.bitsquare.storage.SimpleStorage;
import io.bitsquare.trade.TradingFacade;
import io.bitsquare.trade.orderbook.IOrderBook;
import io.bitsquare.trade.orderbook.MockOrderBook;
import io.bitsquare.settings.Startup;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.Trading;
import io.bitsquare.trade.orderbook.OrderBook;
import io.bitsquare.trade.orderbook.OrderBookFilter;
import io.bitsquare.user.User;
@ -35,31 +28,29 @@ import java.io.File;
public class BitSquareModule extends AbstractModule
{
@Override
protected void configure()
{
bind(ISetup.class).to(MockSetup.class).asEagerSingleton();
bind(Startup.class).asEagerSingleton();
bind(User.class).asEagerSingleton();
bind(IOrderBook.class).to(MockOrderBook.class).asEagerSingleton();
bind(IStorage.class).to(SimpleStorage.class).asEagerSingleton();
bind(OrderBook.class).asEagerSingleton();
bind(Storage.class).asEagerSingleton();
bind(Settings.class).asEagerSingleton();
bind(OrderBookFilter.class).asEagerSingleton();
bind(OrderBookFilterSettings.class).asEagerSingleton();
bind(ICryptoFacade.class).to(MockCryptoFacade.class).asEagerSingleton();
bind(IWalletFacade.class).to(WalletFacade.class).asEagerSingleton();
bind(CryptoFacade.class).asEagerSingleton();
bind(WalletFacade.class).asEagerSingleton();
bind(BlockChainFacade.class).asEagerSingleton();
bind(IMessageFacade.class).to(MessageFacade.class).asEagerSingleton();
bind(MessageFacade.class).asEagerSingleton();
bind(TradingFacade.class).asEagerSingleton();
bind(Trading.class).asEagerSingleton();
bind(String.class).annotatedWith(Names.named("networkType")).toInstance(IWalletFacade.TEST_NET);
//bind(String.class).annotatedWith(Names.named("networkType")).toInstance(WalletFacade.MAIN_NET);
bind(String.class).annotatedWith(Names.named("networkType")).toInstance(WalletFacade.TEST_NET);
bind(NetworkParameters.class).toProvider(NetworkParametersProvider.class).asEagerSingleton();
bind(WalletAppKit.class).toProvider(WalletAppKitProvider.class).asEagerSingleton();
}
}
class WalletAppKitProvider implements Provider<WalletAppKit>
@ -94,15 +85,12 @@ class NetworkParametersProvider implements Provider<NetworkParameters>
switch (networkType)
{
case IWalletFacade.MAIN_NET:
case WalletFacade.MAIN_NET:
result = MainNetParams.get();
break;
case IWalletFacade.TEST_NET:
case WalletFacade.TEST_NET:
result = TestNet3Params.get();
break;
case IWalletFacade.REG_TEST_NET:
result = RegTestParams.get();
break;
}
return result;
}

View File

@ -2,6 +2,10 @@ package io.bitsquare.di;
import com.google.inject.Injector;
import javafx.fxml.FXMLLoader;
import javafx.util.BuilderFactory;
import java.net.URL;
import java.util.ResourceBundle;
/**
* Guice support for fxml controllers
@ -11,18 +15,39 @@ public class GuiceFXMLLoader extends FXMLLoader
private static Injector injector = null;
public static void setInjector(Injector injector)
{
GuiceFXMLLoader.injector = injector;
}
public GuiceFXMLLoader()
{
super();
setupControllerFactory();
}
public GuiceFXMLLoader(URL url)
{
super(url);
setupControllerFactory();
}
public GuiceFXMLLoader(URL url, ResourceBundle resourceBundle)
{
super(url, resourceBundle);
setupControllerFactory();
}
public GuiceFXMLLoader(URL url, ResourceBundle resourceBundle, BuilderFactory builderFactory)
{
super(url, resourceBundle, builderFactory);
setupControllerFactory();
}
private void setupControllerFactory()
{
if (GuiceFXMLLoader.injector != null)
setControllerFactory(new GuiceControllerFactory(GuiceFXMLLoader.injector));
}
public GuiceFXMLLoader(Injector injector)
{
if (GuiceFXMLLoader.injector == null)
{
GuiceFXMLLoader.injector = injector;
setControllerFactory(new GuiceControllerFactory(GuiceFXMLLoader.injector));
}
}
}

View File

@ -0,0 +1,6 @@
package io.bitsquare.gui;
public interface ChildController
{
void setNavigationController(NavigationController navigationController);
}

View File

@ -1,6 +0,0 @@
package io.bitsquare.gui;
public interface IChildController
{
void setNavigationController(INavigationController navigationController);
}

View File

@ -1,34 +1,31 @@
package io.bitsquare.gui;
import com.google.bitcoin.core.DownloadListener;
import com.google.inject.Inject;
import io.bitsquare.BitSquare;
import io.bitsquare.btc.IWalletFacade;
import io.bitsquare.btc.DownloadListener;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.di.GuiceFXMLLoader;
import io.bitsquare.gui.components.NetworkSyncPane;
import io.bitsquare.gui.setup.SetupController;
import io.bitsquare.gui.trade.TradeController;
import io.bitsquare.gui.util.Formatter;
import io.bitsquare.gui.util.Icons;
import io.bitsquare.gui.util.Localisation;
import io.bitsquare.settings.Settings;
import io.bitsquare.trade.Direction;
import io.bitsquare.trade.orderbook.OrderBookFilter;
import javafx.animation.FadeTransition;
import javafx.animation.Interpolator;
import io.bitsquare.user.User;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.util.Duration;
import javafx.scene.layout.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -38,28 +35,36 @@ import java.util.Currency;
import java.util.Date;
import java.util.ResourceBundle;
public class MainController implements Initializable, INavigationController
public class MainController implements Initializable, NavigationController, DownloadListener
{
private static final Logger log = LoggerFactory.getLogger(MainController.class);
private Settings settings;
private User user;
private OrderBookFilter orderBookFilter;
private IWalletFacade walletFacade;
private IChildController childController;
private WalletFacade walletFacade;
private ChildController childController;
private ToggleGroup toggleGroup;
private ToggleButton prevToggleButton;
private Image prevToggleButtonIcon;
public ProgressBar networkSyncProgressBar;
public Label networkSyncInfoLabel;
// public ProgressBar networkSyncProgressBar;
//public Label networkSyncInfoLabel;
private Pane setupView;
private SetupController setupController;
@FXML
public Pane contentPane;
public HBox leftNavPane, rightNavPane, footerContainer;
public HBox leftNavPane, rightNavPane;
public StackPane rootContainer;
public AnchorPane anchorPane;
private NetworkSyncPane networkSyncPane;
@Inject
public MainController(Settings settings, OrderBookFilter orderBookFilter, IWalletFacade walletFacade)
public MainController(Settings settings, User user, OrderBookFilter orderBookFilter, WalletFacade walletFacade)
{
this.settings = settings;
this.user = user;
this.orderBookFilter = orderBookFilter;
this.walletFacade = walletFacade;
}
@ -67,21 +72,49 @@ public class MainController implements Initializable, INavigationController
@Override
public void initialize(URL url, ResourceBundle rb)
{
walletFacade.initWallet(new ProgressBarUpdater());
networkSyncPane = new NetworkSyncPane();
networkSyncPane.setSpacing(10);
networkSyncPane.setPrefHeight(20);
AnchorPane.setBottomAnchor(networkSyncPane, 0.0);
AnchorPane.setLeftAnchor(networkSyncPane, 0.0);
walletFacade.addDownloadListener(this);
walletFacade.initWallet();
buildNavigation();
buildFooter();
if (user.getAccountID() != null)
{
anchorPane.getChildren().add(networkSyncPane);
}
else
{
buildSetupView();
anchorPane.setOpacity(0);
setupController.setNetworkSyncPane(networkSyncPane);
rootContainer.getChildren().add(setupView);
}
}
@Override
public IChildController navigateToView(String fxmlView, String title)
public ChildController navigateToView(String fxmlView, String title)
{
FXMLLoader loader = new GuiceFXMLLoader();
if (setupView != null)
{
anchorPane.getChildren().add(networkSyncPane);
anchorPane.setOpacity(1);
rootContainer.getChildren().remove(setupView);
setupView = null;
setupController = null;
return null;
}
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(fxmlView), Localisation.getResourceBundle());
try
{
Node view = loader.load(BitSquare.class.getResourceAsStream(fxmlView));
final Node view = loader.load();
contentPane.getChildren().setAll(view);
childController = loader.getController();
childController.setNavigationController(this);
@ -91,10 +124,23 @@ public class MainController implements Initializable, INavigationController
e.printStackTrace();
}
return null;
}
public IChildController navigateToView(String fxmlView, Direction direction)
@Override
public void progress(double percent, int blocksSoFar, Date date)
{
if (networkSyncPane != null)
Platform.runLater(() -> networkSyncPane.setProgress(percent));
}
@Override
public void doneDownload()
{
if (networkSyncPane != null)
Platform.runLater(networkSyncPane::doneDownload);
}
public ChildController navigateToView(String fxmlView, Direction direction)
{
childController = navigateToView(fxmlView, direction == Direction.BUY ? "Orderbook Buy" : "Orderbook Sell");
if (childController instanceof TradeController && direction != null)
@ -104,36 +150,40 @@ public class MainController implements Initializable, INavigationController
return childController;
}
private void buildSetupView()
{
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(NavigationController.SETUP), Localisation.getResourceBundle());
try
{
setupView = loader.load();
setupController = loader.getController();
setupController.setNavigationController(this);
} catch (IOException e)
{
e.printStackTrace();
}
}
private void buildNavigation()
{
toggleGroup = new ToggleGroup();
ToggleButton homeButton = addNavButton(leftNavPane, "Overview", Icons.HOME, Icons.HOME, INavigationController.HOME);
ToggleButton buyButton = addNavButton(leftNavPane, "Buy BTC", Icons.NAV_BUY, Icons.NAV_BUY_ACTIVE, INavigationController.TRADE, Direction.BUY);
ToggleButton sellButton = addNavButton(leftNavPane, "Sell BTC", Icons.NAV_SELL, Icons.NAV_SELL_ACTIVE, INavigationController.TRADE, Direction.SELL);
addNavButton(leftNavPane, "Orders", Icons.ORDERS, Icons.ORDERS, INavigationController.ORDERS);
addNavButton(leftNavPane, "History", Icons.HISTORY, Icons.HISTORY, INavigationController.HISTORY);
addNavButton(leftNavPane, "Funds", Icons.FUNDS, Icons.FUNDS, INavigationController.FUNDS);
addNavButton(leftNavPane, "Message", Icons.MSG, Icons.MSG, INavigationController.MSG);
ToggleButton homeButton = addNavButton(leftNavPane, "Overview", Icons.HOME, Icons.HOME, NavigationController.HOME);
ToggleButton buyButton = addNavButton(leftNavPane, "Buy BTC", Icons.NAV_BUY, Icons.NAV_BUY_ACTIVE, NavigationController.TRADE, Direction.BUY);
ToggleButton sellButton = addNavButton(leftNavPane, "Sell BTC", Icons.NAV_SELL, Icons.NAV_SELL_ACTIVE, NavigationController.TRADE, Direction.SELL);
addNavButton(leftNavPane, "Orders", Icons.ORDERS, Icons.ORDERS, NavigationController.ORDERS);
addNavButton(leftNavPane, "History", Icons.HISTORY, Icons.HISTORY, NavigationController.HISTORY);
addNavButton(leftNavPane, "Funds", Icons.FUNDS, Icons.FUNDS, NavigationController.FUNDS);
addNavButton(leftNavPane, "Message", Icons.MSG, Icons.MSG, NavigationController.MSG);
addBalanceInfo(rightNavPane);
addCurrencyComboBox();
addNavButton(rightNavPane, "Settings", Icons.SETTINGS, Icons.SETTINGS, INavigationController.SETTINGS);
addNavButton(rightNavPane, "Settings", Icons.SETTINGS, Icons.SETTINGS, NavigationController.SETTINGS);
sellButton.fire();
//homeButton.fire();
}
private void buildFooter()
{
networkSyncInfoLabel = new Label();
networkSyncInfoLabel.setText("Synchronize with network...");
networkSyncProgressBar = new ProgressBar();
networkSyncProgressBar.setPrefWidth(200);
networkSyncProgressBar.setProgress(-1);
footerContainer.getChildren().addAll(networkSyncProgressBar, networkSyncInfoLabel);
}
private ToggleButton addNavButton(Pane parent, String title, String iconId, String iconIdActivated, String navTarget)
{
return addNavButton(parent, title, iconId, iconIdActivated, navTarget, null);
@ -142,11 +192,11 @@ public class MainController implements Initializable, INavigationController
private ToggleButton addNavButton(Pane parent, String title, String iconId, String iconIdActivated, String navTarget, Direction direction)
{
Pane pane = new Pane();
pane.setPrefSize(50,50);
pane.setPrefSize(50, 50);
ToggleButton toggleButton = new ToggleButton("", Icons.getIconImageView(iconId));
toggleButton.setToggleGroup(toggleGroup);
toggleButton.setId("nav-button");
toggleButton.setPrefSize(50,50);
toggleButton.setPrefSize(50, 50);
toggleButton.setOnAction(e -> {
if (prevToggleButton != null)
{
@ -184,7 +234,6 @@ public class MainController implements Initializable, INavigationController
TextField balanceLabel = new TextField();
balanceLabel.setEditable(false);
balanceLabel.setMouseTransparent(true);
//balanceLabel.setPrefHeight(30);
balanceLabel.setPrefWidth(90);
balanceLabel.setId("nav-balance-label");
balanceLabel.setText(Formatter.formatSatoshis(walletFacade.getBalance(), false));
@ -216,7 +265,6 @@ public class MainController implements Initializable, INavigationController
Pane holder = new Pane();
ComboBox currencyComboBox = new ComboBox(FXCollections.observableArrayList(settings.getAllCurrencies()));
currencyComboBox.setLayoutY(12);
currencyComboBox.setId("nav-currency-combobox");
currencyComboBox.setValue(Settings.getCurrency());
currencyComboBox.valueProperty().addListener(new ChangeListener<Currency>()
@ -232,39 +280,5 @@ public class MainController implements Initializable, INavigationController
rightNavPane.getChildren().add(holder);
}
private void setProgress(double percent)
{
networkSyncProgressBar.setProgress(percent / 100.0);
networkSyncInfoLabel.setText("Synchronize with network: " + (int) percent + "%");
}
private void doneDownload()
{
networkSyncInfoLabel.setText("Sync with network: Done");
FadeTransition fade = new FadeTransition(Duration.millis(700), footerContainer);
fade.setToValue(0.0);
fade.setCycleCount(1);
fade.setInterpolator(Interpolator.EASE_BOTH);
fade.play();
fade.setOnFinished(e -> footerContainer.getChildren().clear());
}
private class ProgressBarUpdater extends DownloadListener
{
@Override
protected void progress(double percent, int blocksSoFar, Date date)
{
super.progress(percent, blocksSoFar, date);
Platform.runLater(() -> MainController.this.setProgress(percent));
}
@Override
protected void doneDownload()
{
super.doneDownload();
Platform.runLater(MainController.this::doneDownload);
}
}
}

View File

@ -1,16 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<AnchorPane id="root-pane" minHeight="300" minWidth="400" prefHeight="600" prefWidth="800"
stylesheets="/io/bitsquare/gui/global.css" xmlns:fx="http://javafx.com/fxml/1"
xmlns="http://javafx.com/javafx/8" fx:controller="io.bitsquare.gui.MainController">
<children>
<StackPane fx:id="rootContainer" minHeight="300" minWidth="400" prefHeight="600" prefWidth="800"
stylesheets="/io/bitsquare/gui/global.css" xmlns:fx="http://javafx.com/fxml/1"
xmlns="http://javafx.com/javafx/8" fx:controller="io.bitsquare.gui.MainController">
<AnchorPane fx:id="anchorPane" id="root-pane" minHeight="300" minWidth="400" prefHeight="600" prefWidth="800">
<HBox fx:id="leftNavPane" spacing="10" AnchorPane.leftAnchor="0" AnchorPane.topAnchor="0"/>
<HBox fx:id="rightNavPane" spacing="10" AnchorPane.rightAnchor="10" AnchorPane.topAnchor="0"/>
<AnchorPane id="content-pane" fx:id="contentPane" AnchorPane.bottomAnchor="20" AnchorPane.leftAnchor="0"
AnchorPane.rightAnchor="0" AnchorPane.topAnchor="60"/>
<HBox fx:id="footerContainer" prefHeight="20" spacing="10" AnchorPane.leftAnchor="10"
AnchorPane.bottomAnchor="0"/>
</children>
</AnchorPane>
</AnchorPane>
</StackPane>

View File

@ -1,8 +1,10 @@
package io.bitsquare.gui;
public interface INavigationController
public interface NavigationController
{
public static final String SETUP = "/io/bitsquare/gui/setup/SetupView.fxml";
public static final String HOME = "/io/bitsquare/gui/home/HomeView.fxml";
public static final String TRADE = "/io/bitsquare/gui/trade/TradeView.fxml";
public static final String ORDERS = "/io/bitsquare/gui/orders/OrdersView.fxml";
@ -15,5 +17,5 @@ public interface INavigationController
public static final String TRADE__PROCESS = "/io/bitsquare/gui/trade/tradeprocess/TradeProcessView.fxml";
public static final String TRADE__CREATE_OFFER = "/io/bitsquare/gui/trade/offer/CreateOfferView.fxml";
IChildController navigateToView(String fxmlView, String title);
ChildController navigateToView(String fxmlView, String title);
}

View File

@ -0,0 +1,44 @@
package io.bitsquare.gui.components;
import javafx.animation.FadeTransition;
import javafx.animation.Interpolator;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.HBox;
import javafx.util.Duration;
public class NetworkSyncPane extends HBox
{
private ProgressBar networkSyncProgressBar;
private Label networkSyncInfoLabel;
public NetworkSyncPane()
{
networkSyncInfoLabel = new Label();
networkSyncInfoLabel.setText("Synchronize with network...");
networkSyncProgressBar = new ProgressBar();
networkSyncProgressBar.setPrefWidth(200);
networkSyncProgressBar.setProgress(-1);
getChildren().addAll(new HSpacer(5), networkSyncProgressBar, networkSyncInfoLabel);
}
public void setProgress(double percent)
{
networkSyncProgressBar.setProgress(percent / 100.0);
networkSyncInfoLabel.setText("Synchronize with network: " + (int) percent + "%");
}
public void doneDownload()
{
networkSyncInfoLabel.setText("Sync with network: Done");
FadeTransition fade = new FadeTransition(Duration.millis(700), this);
fade.setToValue(0.0);
fade.setCycleCount(1);
fade.setInterpolator(Interpolator.EASE_BOTH);
fade.play();
fade.setOnFinished(e -> getChildren().clear());
}
}

View File

@ -7,7 +7,14 @@ import java.util.List;
public class ProcessStepBar<T> extends Control
{
private List<ProcessStepItem> processStepItems;
private List<ProcessStepItem> processStepItems = null;
public ProcessStepBar()
{
}
public ProcessStepBar(List<ProcessStepItem> processStepItems)
{
@ -20,6 +27,13 @@ public class ProcessStepBar<T> extends Control
return new ProcessStepBarSkin<>(this);
}
public void setProcessStepItems(List<ProcessStepItem> processStepItems)
{
this.processStepItems = processStepItems;
if (getSkin() != null)
((ProcessStepBarSkin) getSkin()).dataChanged();
}
List<ProcessStepItem> getProcessStepItems()
{
return processStepItems;

View File

@ -34,22 +34,35 @@ public class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, B
controller = getSkinnable();
int i = 0;
labelWithBorders = new ArrayList<>();
int size = controller.getProcessStepItems().size();
for (Iterator<ProcessStepItem> iterator = controller.getProcessStepItems().iterator(); iterator.hasNext(); )
applyData();
}
public void dataChanged()
{
applyData();
}
private void applyData()
{
if (controller.getProcessStepItems() != null)
{
ProcessStepItem processStepItem = iterator.next();
LabelWithBorder labelWithBorder = new LabelWithBorder(processStepItem, i == 0, i == size - 1);
getChildren().add(labelWithBorder);
labelWithBorders.add(labelWithBorder);
if (i == 0)
currentLabelWithBorder = prevLabelWithBorder = labelWithBorder;
int i = 0;
labelWithBorders = new ArrayList<>();
int size = controller.getProcessStepItems().size();
for (Iterator<ProcessStepItem> iterator = controller.getProcessStepItems().iterator(); iterator.hasNext(); )
{
ProcessStepItem processStepItem = iterator.next();
LabelWithBorder labelWithBorder = new LabelWithBorder(processStepItem, i == 0, i == size - 1);
getChildren().add(labelWithBorder);
labelWithBorders.add(labelWithBorder);
if (i == 0)
currentLabelWithBorder = prevLabelWithBorder = labelWithBorder;
i++;
i++;
}
currentLabelWithBorder.select();
}
currentLabelWithBorder.select();
}
public void next()
@ -89,6 +102,7 @@ public class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, B
}
}
public static class LabelWithBorder extends Label
{
private final double arrowWidth = 10;

View File

@ -3,9 +3,9 @@ package io.bitsquare.gui.funds;
import com.google.inject.Inject;
import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;
import io.bitsquare.btc.IWalletFacade;
import io.bitsquare.gui.IChildController;
import io.bitsquare.gui.INavigationController;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.util.Formatter;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
@ -20,11 +20,11 @@ import java.net.URL;
import java.util.ResourceBundle;
public class FundsController implements Initializable, IChildController
public class FundsController implements Initializable, ChildController
{
private INavigationController navigationController;
private IWalletFacade walletFacade;
private NavigationController navigationController;
private WalletFacade walletFacade;
@FXML
public Pane rootContainer;
@ -36,7 +36,7 @@ public class FundsController implements Initializable, IChildController
public Label copyIcon;
@Inject
public FundsController(IWalletFacade walletFacade)
public FundsController(WalletFacade walletFacade)
{
this.walletFacade = walletFacade;
@ -58,7 +58,7 @@ public class FundsController implements Initializable, IChildController
}
@Override
public void setNavigationController(INavigationController navigationController)
public void setNavigationController(NavigationController navigationController)
{
this.navigationController = navigationController;
@ -67,6 +67,5 @@ public class FundsController implements Initializable, IChildController
}
}

View File

@ -1,15 +1,14 @@
<?import io.bitsquare.gui.components.HSpacer?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:controller="io.bitsquare.gui.funds.FundsController"
xmlns:fx="http://javafx.com/fxml" fx:id="rootContainer">
<Label text="Just one generic address by now for dev...." AnchorPane.topAnchor="10" AnchorPane.leftAnchor="10"/>
<HBox spacing="5" AnchorPane.topAnchor="40" AnchorPane.leftAnchor="10">
<Label text="Funds address:" >
<Label text="Funds address:">
<padding>
<Insets bottom="0.0" left="0.0" right="0.0" top="5.0"/>
</padding>

View File

@ -6,6 +6,15 @@
-fx-background-color: #f4f4f4;
}
#headline-label {
-fx-font-weight: bold;
-fx-font-size: 18;
}
#info-label {
-fx-font-size: 14;
}
/* main nav */
#nav-button {
@ -28,8 +37,12 @@
-fx-text-alignment: left;
}
#copy-icon {
-fx-cursor: hand;
}
#nav-currency-combobox {
#copy-icon:hover {
-fx-text-fill: #0096c9;
}
/* table */
@ -60,6 +73,13 @@
-fx-font-weight: bold;
}
#form-title {
-fx-font-weight: bold;
}
#form-entry-value {
}
/* tabpane */
.tab-pane .tab-label {
-fx-font-size: 15;

View File

@ -1,16 +1,16 @@
package io.bitsquare.gui.history;
import io.bitsquare.gui.IChildController;
import io.bitsquare.gui.INavigationController;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import javafx.fxml.Initializable;
import java.net.URL;
import java.util.ResourceBundle;
public class HistoryController implements Initializable, IChildController
public class HistoryController implements Initializable, ChildController
{
private INavigationController navigationController;
private NavigationController navigationController;
@Override
public void initialize(URL url, ResourceBundle rb)
@ -20,7 +20,7 @@ public class HistoryController implements Initializable, IChildController
}
@Override
public void setNavigationController(INavigationController navigationController)
public void setNavigationController(NavigationController navigationController)
{
this.navigationController = navigationController;
}

View File

@ -1,7 +1,7 @@
package io.bitsquare.gui.home;
import io.bitsquare.gui.IChildController;
import io.bitsquare.gui.INavigationController;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.Pane;
@ -9,9 +9,9 @@ import javafx.scene.layout.Pane;
import java.net.URL;
import java.util.ResourceBundle;
public class HomeController implements Initializable, IChildController
public class HomeController implements Initializable, ChildController
{
private INavigationController navigationController;
private NavigationController navigationController;
@FXML
public Pane rootContainer;
@ -23,7 +23,7 @@ public class HomeController implements Initializable, IChildController
}
@Override
public void setNavigationController(INavigationController navigationController)
public void setNavigationController(NavigationController navigationController)
{
this.navigationController = navigationController;
}

View File

@ -1,5 +1,5 @@
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>
<VBox fx:id="rootContainer" fx:controller="io.bitsquare.gui.home.HomeController" spacing="10"
xmlns:fx="http://javafx.com/fxml">
<Label text="Overview"/>

View File

@ -1,15 +1,15 @@
package io.bitsquare.gui.msg;
import io.bitsquare.gui.IChildController;
import io.bitsquare.gui.INavigationController;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import javafx.fxml.Initializable;
import java.net.URL;
import java.util.ResourceBundle;
public class MsgController implements Initializable, IChildController
public class MsgController implements Initializable, ChildController
{
private INavigationController navigationController;
private NavigationController navigationController;
@Override
public void initialize(URL url, ResourceBundle rb)
@ -18,7 +18,7 @@ public class MsgController implements Initializable, IChildController
}
@Override
public void setNavigationController(INavigationController navigationController)
public void setNavigationController(NavigationController navigationController)
{
this.navigationController = navigationController;
}

View File

@ -1,17 +1,17 @@
package io.bitsquare.gui.orders;
import io.bitsquare.gui.IChildController;
import io.bitsquare.gui.INavigationController;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import javafx.fxml.Initializable;
import java.net.URL;
import java.util.ResourceBundle;
public class OrdersController implements Initializable, IChildController
public class OrdersController implements Initializable, ChildController
{
private INavigationController navigationController;
private NavigationController navigationController;
@Override
public void initialize(URL url, ResourceBundle rb)
@ -21,7 +21,7 @@ public class OrdersController implements Initializable, IChildController
}
@Override
public void setNavigationController(INavigationController navigationController)
public void setNavigationController(NavigationController navigationController)
{
this.navigationController = navigationController;
}

View File

@ -1,17 +1,17 @@
package io.bitsquare.gui.settings;
import io.bitsquare.gui.IChildController;
import io.bitsquare.gui.INavigationController;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import javafx.fxml.Initializable;
import java.net.URL;
import java.util.ResourceBundle;
public class SettingsController implements Initializable, IChildController
public class SettingsController implements Initializable, ChildController
{
private INavigationController navigationController;
private NavigationController navigationController;
@Override
public void initialize(URL url, ResourceBundle rb)
@ -21,7 +21,7 @@ public class SettingsController implements Initializable, IChildController
}
@Override
public void setNavigationController(INavigationController navigationController)
public void setNavigationController(NavigationController navigationController)
{
this.navigationController = navigationController;
}

View File

@ -0,0 +1,293 @@
package io.bitsquare.gui.setup;
import com.google.bitcoin.core.InsufficientMoneyException;
import com.google.inject.Inject;
import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;
import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.crypto.CryptoFacade;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.components.NetworkSyncPane;
import io.bitsquare.gui.components.processbar.ProcessStepBar;
import io.bitsquare.gui.components.processbar.ProcessStepItem;
import io.bitsquare.gui.util.*;
import io.bitsquare.gui.util.Formatter;
import io.bitsquare.settings.Settings;
import io.bitsquare.storage.Storage;
import io.bitsquare.user.User;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URL;
import java.util.*;
public class SetupController implements Initializable, ChildController
{
private static final Logger log = LoggerFactory.getLogger(SetupController.class);
private User user;
private final WalletFacade walletFacade;
private CryptoFacade cryptoFacade;
private Settings settings;
private Storage storage;
private List<ProcessStepItem> processStepItems = new ArrayList();
private NavigationController navigationController;
@FXML
private AnchorPane rootContainer;
@FXML
private Label infoLabel;
@FXML
private ProcessStepBar<String> processStepBar;
@FXML
private GridPane formGridPane;
@FXML
private Button nextButton, skipButton;
@Inject
public SetupController(User user, WalletFacade walletFacade, CryptoFacade cryptoFacade, Settings settings, Storage storage)
{
this.user = user;
this.walletFacade = walletFacade;
this.cryptoFacade = cryptoFacade;
this.settings = settings;
this.storage = storage;
}
public void initialize(URL url, ResourceBundle rb)
{
processStepItems.add(new ProcessStepItem("Fund registration fee", Colors.BLUE));
processStepItems.add(new ProcessStepItem("Add Bank account", Colors.BLUE));
processStepItems.add(new ProcessStepItem("Complete", Colors.BLUE));
processStepBar.setProcessStepItems(processStepItems);
buildStep0();
}
// pass in NetworkSyncPane from parent view
public void setNetworkSyncPane(NetworkSyncPane networkSyncPane)
{
rootContainer.getChildren().add(networkSyncPane);
}
@Override
public void setNavigationController(NavigationController navigationController)
{
this.navigationController = navigationController;
}
private void close()
{
navigationController.navigateToView(NavigationController.HOME, "");
}
// TODO need checks per bankTransferType
private boolean verifyBankAccountData(Object bankTransferTypeSelectedItem, String accountPrimaryID, String accountSecondaryID, String accountHolderName)
{
boolean result = bankTransferTypeSelectedItem != null;
result &= bankTransferTypeSelectedItem.toString().length() > 0;
result &= accountPrimaryID.length() > 0;
result &= accountSecondaryID.length() > 0;
result &= accountHolderName.length() > 0;
result &= Verification.verifyAccountIDsByBankTransferType(bankTransferTypeSelectedItem, accountPrimaryID, accountSecondaryID);
return result;
}
private ImageView getConfirmIcon()
{
int confirmations = walletFacade.getAccountRegistrationConfirmations();
if (confirmations > 0)
return Icons.getIconImageView(Icons.getIconIDForConfirmations(confirmations));
else
return Icons.getIconImageView(Icons.getIconIDForPeersSeenTx(walletFacade.getAccountRegistrationNumberOfPeersSeenTx()));
}
///////////////////////////////////////////////////////////////////////////////////
// GUI BUILDER
///////////////////////////////////////////////////////////////////////////////////
private void buildStep0()
{
infoLabel.setText("You need to pay 0.01 BTC to the registration address.\n" +
"That payment will be used to create a unique account connected with your bank account number.\n" +
"The privacy of your bank account number will be protected and only revealed to your trading partners.\n" +
"The payment will be spent to miners and is needed to store data into the blockchain.\n" +
"Your trading account will be the source for your reputation in the trading platform.");
int row = -1;
TextField addressLabel = FormBuilder.addInputField(formGridPane, "Registration address:", walletFacade.getAccountRegistrationAddress().toString(), ++row);
addressLabel.setEditable(false);
Label copyIcon = new Label("");
formGridPane.add(copyIcon, 2, row);
copyIcon.setId("copy-icon");
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
Tooltip.install(copyIcon, new Tooltip("Copy address to clipboard"));
formGridPane.add(getConfirmIcon(), 3, row);
TextField balanceLabel = FormBuilder.addInputField(formGridPane, "Balance:", Formatter.formatSatoshis(walletFacade.getAccountRegistrationBalance(), true), ++row);
balanceLabel.setEditable(false);
nextButton.setText("Payment done");
skipButton.setText("Register later");
// handlers
copyIcon.setOnMouseClicked(e -> {
Clipboard clipboard = Clipboard.getSystemClipboard();
ClipboardContent content = new ClipboardContent();
content.putString(addressLabel.getText());
clipboard.setContent(content);
});
nextButton.setOnAction(e -> {
processStepBar.next();
buildStep1();
});
skipButton.setOnAction(e -> {
close();
});
}
private void buildStep1()
{
infoLabel.setText("Add at least one Bank account to your trading account.\n" +
"That data will be stored in the blockchain in a way that your privacy is protected.\n" +
"Only your trading partners will be able to read those data, so your privacy will be protected.");
formGridPane.getChildren().clear();
int row = -1;
ComboBox bankTransferTypes = FormBuilder.addComboBox(formGridPane, "Bank account type:", settings.getAllBankAccountTypes(), ++row);
bankTransferTypes.setPromptText("Select");
//TODO dev
bankTransferTypes.getSelectionModel().select(1);
TextField accountHolderName = FormBuilder.addInputField(formGridPane, "Bank account holder name:", "Bob Brown", ++row);
TextField accountPrimaryID = FormBuilder.addInputField(formGridPane, "Bank account primary ID", "dummy IBAN", ++row);
TextField accountSecondaryID = FormBuilder.addInputField(formGridPane, "Bank account secondary ID:", "dummy BIC", ++row);
Button addButton = new Button("Add other Bank account");
formGridPane.add(addButton, 1, ++row);
nextButton.setText("Create account");
skipButton.setText("Register later");
// handlers
bankTransferTypes.valueProperty().addListener(new ChangeListener<Object>()
{
@Override
public void changed(ObservableValue ov, Object oldValue, Object newValue)
{
if (newValue != null && newValue instanceof BankAccountType)
{
BankAccountType bankAccountType = (BankAccountType) newValue;
accountPrimaryID.setText("");
accountPrimaryID.setPromptText(bankAccountType.getPrimaryIDName());
accountSecondaryID.setText("");
accountSecondaryID.setPromptText(bankAccountType.getSecondaryIDName());
}
}
});
addButton.setOnAction(e -> {
if (bankTransferTypes.getSelectionModel() != null && verifyBankAccountData(bankTransferTypes.getSelectionModel().getSelectedItem(), accountPrimaryID.getText(), accountSecondaryID.getText(), accountHolderName.getText()))
{
user.addBankAccount(new BankAccount((BankAccountType) bankTransferTypes.getSelectionModel().getSelectedItem(), accountPrimaryID.getText(), accountSecondaryID.getText(), accountHolderName.getText()));
bankTransferTypes.getSelectionModel().clearSelection();
accountPrimaryID.setText("");
accountPrimaryID.setPromptText("");
accountSecondaryID.setText("");
accountSecondaryID.setPromptText("");
}
});
nextButton.setOnAction(e -> {
if (bankTransferTypes.getSelectionModel() != null && verifyBankAccountData(bankTransferTypes.getSelectionModel().getSelectedItem(), accountPrimaryID.getText(), accountSecondaryID.getText(), accountHolderName.getText()))
user.addBankAccount(new BankAccount((BankAccountType) bankTransferTypes.getSelectionModel().getSelectedItem(), accountPrimaryID.getText(), accountSecondaryID.getText(), accountHolderName.getText()));
if (user.getBankAccounts().size() > 0)
{
try
{
walletFacade.sendRegistrationTx(user.getStringifiedBankAccounts());
user.setAccountID(walletFacade.getAccountRegistrationAddress().toString());
user.setMessageID(walletFacade.getAccountRegistrationPubKey().toString());
storage.saveUser(user);
processStepBar.next();
buildStep2();
} catch (InsufficientMoneyException e1)
{
log.warn(e1.toString());
//e1.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
else
{
log.warn("You need to add a bank account first!");
//TODO warning popup
}
});
skipButton.setOnAction(e -> {
close();
});
}
private void buildStep2()
{
infoLabel.setText("Summary:\n" +
"You have saved following bank accounts with your trading account to the blockchain:");
formGridPane.getChildren().clear();
int row = -1;
Map<String, BankAccount> bankAccounts = user.getBankAccounts();
Iterator iterator = bankAccounts.entrySet().iterator();
int index = 0;
while (iterator.hasNext())
{
FormBuilder.addHeaderLabel(formGridPane, "Bank account " + (index + 1), ++row);
Map.Entry<String, BankAccount> entry = (Map.Entry) iterator.next();
// need to get updated row from subroutine
row = buildBankAccountDetails(entry.getValue(), ++row);
FormBuilder.addVSpacer(formGridPane, ++row);
index++;
}
FormBuilder.addVSpacer(formGridPane, ++row);
FormBuilder.addInputField(formGridPane, "Registration address:", walletFacade.getAccountRegistrationAddress().toString(), ++row).setMouseTransparent(true);
FormBuilder.addInputField(formGridPane, "Balance:", Formatter.formatSatoshis(walletFacade.getAccountRegistrationBalance(), true), ++row).setMouseTransparent(true);
nextButton.setText("Done");
skipButton.setOpacity(0);
// handlers
nextButton.setOnAction(e -> {
close();
});
}
// util
private int buildBankAccountDetails(BankAccount bankAccount, int row)
{
FormBuilder.addInputField(formGridPane, "Bank account holder name:", bankAccount.getAccountHolderName(), ++row).setMouseTransparent(true);
FormBuilder.addInputField(formGridPane, "Bank account type", bankAccount.getBankAccountType().toString(), ++row).setMouseTransparent(true);
FormBuilder.addInputField(formGridPane, "Bank account primary ID", bankAccount.getAccountPrimaryID(), ++row).setMouseTransparent(true);
FormBuilder.addInputField(formGridPane, "Bank account secondary ID:", bankAccount.getAccountSecondaryID(), ++row).setMouseTransparent(true);
return row;
}
}

View File

@ -0,0 +1,31 @@
<?import io.bitsquare.gui.components.processbar.ProcessStepBar?>
<?import io.bitsquare.gui.components.VSpacer?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="rootContainer" fx:controller="io.bitsquare.gui.setup.SetupController"
xmlns:fx="http://javafx.com/fxml" minHeight="300" minWidth="400" prefHeight="600" prefWidth="800">
<ScrollPane fitToWidth="true" AnchorPane.leftAnchor="10" AnchorPane.rightAnchor="10" AnchorPane.topAnchor="10"
AnchorPane.bottomAnchor="30">
<content>
<VBox spacing="10">
<Label text="Setup trading account" id="headline-label"/>
<ProcessStepBar fx:id="processStepBar"/>
<VSpacer prefHeight="10"/>
<Label fx:id="infoLabel"/>
<GridPane fx:id="formGridPane" vgap="5" hgap="5">
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
</padding>
<columnConstraints>
<ColumnConstraints halignment="RIGHT"/>
<ColumnConstraints halignment="LEFT" prefWidth="320"/>
<ColumnConstraints halignment="LEFT"/>
</columnConstraints>
</GridPane>
<Button fx:id="nextButton" defaultButton="true"/>
<Button fx:id="skipButton"/>
</VBox>
</content>
</ScrollPane>
</AnchorPane>

View File

@ -1,13 +1,12 @@
package io.bitsquare.gui.trade;
import io.bitsquare.BitSquare;
import io.bitsquare.di.GuiceFXMLLoader;
import io.bitsquare.gui.IChildController;
import io.bitsquare.gui.INavigationController;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.trade.orderbook.OrderBookController;
import io.bitsquare.gui.util.Localisation;
import io.bitsquare.trade.Direction;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
@ -17,29 +16,29 @@ import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
public class TradeController implements Initializable, INavigationController, IChildController
public class TradeController implements Initializable, NavigationController, ChildController
{
@FXML
private TabPane tabPane;
private IChildController childController;
private ChildController childController;
private boolean orderbookCreated;
private INavigationController navigationController;
private NavigationController navigationController;
private OrderBookController orderBookController;
@Override
public IChildController navigateToView(String fxmlView, String title)
public ChildController navigateToView(String fxmlView, String title)
{
if (fxmlView.equals(INavigationController.TRADE__ORDER_BOOK) && orderbookCreated)
if (fxmlView.equals(NavigationController.TRADE__ORDER_BOOK) && orderbookCreated)
{
tabPane.getSelectionModel().select(0);
return null;
}
FXMLLoader loader = new GuiceFXMLLoader();
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(fxmlView), Localisation.getResourceBundle());
try
{
Pane view = loader.load(BitSquare.class.getResourceAsStream(fxmlView));
Pane view = loader.load();
childController = loader.getController();
childController.setNavigationController(this);
@ -50,7 +49,7 @@ public class TradeController implements Initializable, INavigationController, IC
tab.setContent(view);
tabPane.getTabs().add(tab);
if (fxmlView.equals(INavigationController.TRADE__ORDER_BOOK))
if (fxmlView.equals(NavigationController.TRADE__ORDER_BOOK))
{
tab.setClosable(false);
orderbookCreated = true;
@ -69,11 +68,11 @@ public class TradeController implements Initializable, INavigationController, IC
@Override
public void initialize(URL url, ResourceBundle rb)
{
navigateToView(INavigationController.TRADE__ORDER_BOOK, "Orderbook");
navigateToView(NavigationController.TRADE__ORDER_BOOK, "Orderbook");
}
@Override
public void setNavigationController(INavigationController navigationController)
public void setNavigationController(NavigationController navigationController)
{
this.navigationController = navigationController;

View File

@ -1,8 +1,8 @@
package io.bitsquare.gui.trade.offer;
import com.google.inject.Inject;
import io.bitsquare.gui.IChildController;
import io.bitsquare.gui.INavigationController;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.util.Converter;
import io.bitsquare.gui.util.Formatter;
import io.bitsquare.settings.OrderBookFilterSettings;
@ -10,8 +10,8 @@ import io.bitsquare.settings.Settings;
import io.bitsquare.trade.Direction;
import io.bitsquare.trade.Offer;
import io.bitsquare.trade.OfferConstraints;
import io.bitsquare.trade.TradingFacade;
import io.bitsquare.trade.orderbook.MockOrderBook;
import io.bitsquare.trade.Trading;
import io.bitsquare.trade.orderbook.OrderBook;
import io.bitsquare.trade.orderbook.OrderBookFilter;
import io.bitsquare.user.User;
import javafx.beans.value.ChangeListener;
@ -34,12 +34,12 @@ import java.util.Currency;
import java.util.ResourceBundle;
import java.util.UUID;
public class CreateOfferController implements Initializable, IChildController
public class CreateOfferController implements Initializable, ChildController
{
private static final Logger log = LoggerFactory.getLogger(CreateOfferController.class);
private INavigationController navigationController;
private TradingFacade tradingFacade;
private NavigationController navigationController;
private Trading trading;
private OrderBookFilterSettings orderBookFilterSettings;
private Settings settings;
private User user;
@ -68,9 +68,9 @@ public class CreateOfferController implements Initializable, IChildController
public Button placeOfferButton;
@Inject
public CreateOfferController(TradingFacade tradingFacade, OrderBookFilterSettings orderBookFilterSettings, Settings settings, User user)
public CreateOfferController(Trading trading, OrderBookFilterSettings orderBookFilterSettings, Settings settings, User user)
{
this.tradingFacade = tradingFacade;
this.trading = trading;
this.orderBookFilterSettings = orderBookFilterSettings;
this.settings = settings;
this.user = user;
@ -101,7 +101,7 @@ public class CreateOfferController implements Initializable, IChildController
placeOfferButton.setOnAction(e -> {
// TODO not impl yet. use mocks
OfferConstraints offerConstraints = new MockOrderBook(settings).getRandomOfferConstraints();
OfferConstraints offerConstraints = new OrderBook(settings).getRandomOfferConstraints();
Offer offer = new Offer(UUID.randomUUID(),
direction,
Converter.convertToDouble(price.getText()),
@ -110,17 +110,17 @@ public class CreateOfferController implements Initializable, IChildController
settings.getCurrency(),
user,
offerConstraints);
tradingFacade.placeNewOffer(offer);
trading.placeNewOffer(offer);
TabPane tabPane = ((TabPane) (holderPane.getParent().getParent()));
tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem());
navigationController.navigateToView(INavigationController.TRADE__ORDER_BOOK, "Orderbook");
navigationController.navigateToView(NavigationController.TRADE__ORDER_BOOK, "Orderbook");
});
}
@Override
public void setNavigationController(INavigationController navigationController)
public void setNavigationController(NavigationController navigationController)
{
this.navigationController = navigationController;
}

View File

@ -1,8 +1,8 @@
package io.bitsquare.gui.trade.orderbook;
import com.google.inject.Inject;
import io.bitsquare.gui.IChildController;
import io.bitsquare.gui.INavigationController;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.trade.offer.CreateOfferController;
import io.bitsquare.gui.trade.tradeprocess.TradeProcessController;
import io.bitsquare.gui.util.Converter;
@ -10,8 +10,7 @@ import io.bitsquare.gui.util.Formatter;
import io.bitsquare.gui.util.Icons;
import io.bitsquare.settings.Settings;
import io.bitsquare.trade.Direction;
import io.bitsquare.trade.orderbook.IOrderBook;
import io.bitsquare.trade.orderbook.MockOrderBook;
import io.bitsquare.trade.orderbook.OrderBook;
import io.bitsquare.trade.orderbook.OrderBookFilter;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
@ -34,10 +33,10 @@ import java.text.ParseException;
import java.util.Arrays;
import java.util.ResourceBundle;
public class OrderBookController implements Initializable, IChildController
public class OrderBookController implements Initializable, ChildController
{
private INavigationController navigationController;
private IOrderBook orderBook;
private NavigationController navigationController;
private OrderBook orderBook;
private Settings settings;
private OrderBookListItem selectedOrderBookListItem;
@ -65,7 +64,7 @@ public class OrderBookController implements Initializable, IChildController
private ImageView tradeButtonImageView;
@Inject
public OrderBookController(IOrderBook orderBook, OrderBookFilter orderBookFilter, Settings settings)
public OrderBookController(OrderBook orderBook, OrderBookFilter orderBookFilter, Settings settings)
{
this.orderBook = orderBook;
this.orderBookFilter = orderBookFilter;
@ -121,7 +120,7 @@ public class OrderBookController implements Initializable, IChildController
}
@Override
public void setNavigationController(INavigationController navigationController)
public void setNavigationController(NavigationController navigationController)
{
this.navigationController = navigationController;
}
@ -154,7 +153,7 @@ public class OrderBookController implements Initializable, IChildController
private void openTradeTab(OrderBookListItem orderBookListItem)
{
String title = orderBookListItem.getOffer().getDirection() == Direction.BUY ? "Trade: Sell Bitcoin" : "Trade: Buy Bitcoin";
TradeProcessController tradeProcessController = (TradeProcessController) navigationController.navigateToView(INavigationController.TRADE__PROCESS, title);
TradeProcessController tradeProcessController = (TradeProcessController) navigationController.navigateToView(NavigationController.TRADE__PROCESS, title);
double requestedAmount = orderBookListItem.getOffer().getAmount();
if (!amount.getText().equals(""))
@ -173,7 +172,7 @@ public class OrderBookController implements Initializable, IChildController
holderPane.getChildren().add(createOfferButton);
createOfferButton.setOnAction(e -> {
IChildController nextController = navigationController.navigateToView(INavigationController.TRADE__CREATE_OFFER, "Create offer");
ChildController nextController = navigationController.navigateToView(NavigationController.TRADE__CREATE_OFFER, "Create offer");
((CreateOfferController) nextController).setOrderBookFilter(orderBookFilter);
});
}
@ -202,16 +201,17 @@ public class OrderBookController implements Initializable, IChildController
private void createFilterPane()
{
MockOrderBook mockOrderBook = new MockOrderBook(settings);
OrderBook mockOrderBook = new OrderBook(settings);
orderBookFilter.setOfferConstraints(mockOrderBook.getRandomOfferConstraints());
OrderBookFilterTextItemBuilder.build(filterPane, "Bank transfer types: ", orderBookFilter.getOfferConstraints().getBankTransferTypes(), settings.getAllBankTransferTypes());
//OrderBookFilterTextItemBuilder.build(filterPane, "Bank transfer types: ", orderBookFilter.getOfferConstraints().getBankAccountTypes(), settings.getAllBankAccountTypes());
OrderBookFilterTextItemBuilder.build(filterPane, "Countries: ", orderBookFilter.getOfferConstraints().getCountries(), settings.getAllCountries());
OrderBookFilterTextItemBuilder.build(filterPane, "Languages: ", orderBookFilter.getOfferConstraints().getLanguages(), settings.getAllLanguages());
OrderBookFilterTextItemBuilder.build(filterPane, "Collateral: ", Arrays.asList(String.valueOf(orderBookFilter.getOfferConstraints().getCollateral())), settings.getAllCollaterals());
OrderBookFilterTextItemBuilder.build(filterPane, "Arbitrator: ", Arrays.asList(orderBookFilter.getOfferConstraints().getArbitrator()), settings.getAllArbitrators());
}
private double textInputToNumber(String oldValue, String newValue)
{
//TODO use regex.... or custom textfield component

View File

@ -3,15 +3,12 @@ package io.bitsquare.gui.trade.tradeprocess;
import com.google.inject.Inject;
import io.bitsquare.btc.BtcFormatter;
import io.bitsquare.btc.Fees;
import io.bitsquare.gui.IChildController;
import io.bitsquare.gui.INavigationController;
import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.components.VSpacer;
import io.bitsquare.gui.components.processbar.ProcessStepBar;
import io.bitsquare.gui.components.processbar.ProcessStepItem;
import io.bitsquare.gui.util.Colors;
import io.bitsquare.gui.util.Converter;
import io.bitsquare.gui.util.Formatter;
import io.bitsquare.gui.util.Utils;
import io.bitsquare.gui.util.*;
import io.bitsquare.trade.*;
import io.bitsquare.user.User;
import javafx.animation.AnimationTimer;
@ -30,14 +27,14 @@ import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
public class TradeProcessController implements Initializable, IChildController
public class TradeProcessController implements Initializable, ChildController
{
private TradingFacade tradingFacade;
private Trading trading;
private Offer offer;
private Trade trade;
private Contract contract;
private INavigationController navigationController;
private NavigationController navigationController;
private List<ProcessStepItem> processStepItems = new ArrayList();
private double requestedAmount;
@ -58,13 +55,13 @@ public class TradeProcessController implements Initializable, IChildController
public AnchorPane rootContainer;
@Inject
public TradeProcessController(TradingFacade tradingFacade)
public TradeProcessController(Trading trading)
{
this.tradingFacade = tradingFacade;
this.trading = trading;
}
@Override
public void setNavigationController(INavigationController navigationController)
public void setNavigationController(NavigationController navigationController)
{
this.navigationController = navigationController;
}
@ -79,9 +76,9 @@ public class TradeProcessController implements Initializable, IChildController
this.offer = offer;
this.requestedAmount = requestedAmount;
trade = tradingFacade.createNewTrade(offer);
trade = trading.createNewTrade(offer);
trade.setRequestedAmount(requestedAmount);
contract = tradingFacade.createNewContract(trade);
contract = trading.createNewContract(trade);
processStepItems.add(new ProcessStepItem(takerIsSelling() ? "Sell BTC" : "Buy BTC", Colors.BLUE));
processStepItems.add(new ProcessStepItem("Bank transfer", Colors.BLUE));
@ -138,7 +135,7 @@ public class TradeProcessController implements Initializable, IChildController
// Payment Process
private void sendTakeOfferRequest()
{
tradingFacade.sendTakeOfferRequest(trade);
trading.sendTakeOfferRequest(trade);
feedbackLabel.setText("Request take offer confirmation from peer.");
Utils.setTimeout(500, (AnimationTimer animationTimer) -> {
onTakeOfferRequestConfirmed();
@ -149,7 +146,7 @@ public class TradeProcessController implements Initializable, IChildController
private void onTakeOfferRequestConfirmed()
{
tradingFacade.payOfferFee(trade);
trading.payOfferFee(trade);
feedbackLabel.setText("Request offer fee payment confirmation from peer.");
Utils.setTimeout(500, (AnimationTimer animationTimer) -> {
@ -161,7 +158,7 @@ public class TradeProcessController implements Initializable, IChildController
private void onOfferFeePaymentConfirmed()
{
tradingFacade.requestOffererDetailData();
trading.requestOffererDetailData();
feedbackLabel.setText("Request detail data from peer.");
Utils.setTimeout(500, (AnimationTimer animationTimer) -> {
onUserDetailsReceived();
@ -172,8 +169,8 @@ public class TradeProcessController implements Initializable, IChildController
private void onUserDetailsReceived()
{
tradingFacade.signContract(contract);
tradingFacade.payToDepositTx(trade);
trading.signContract(contract);
trading.payToDepositTx(trade);
buildWaitBankTransfer();
}
@ -207,7 +204,7 @@ public class TradeProcessController implements Initializable, IChildController
private void releaseBTC()
{
processStepBar.next();
tradingFacade.releaseBTC(trade);
trading.releaseBTC(trade);
vBox.getChildren().remove(infoLabel);
@ -220,8 +217,8 @@ public class TradeProcessController implements Initializable, IChildController
summaryGridPane.setHgap(5);
summaryGridPane.setPadding(new Insets(5, 5, 5, 5));
addLabel(summaryGridPane, "You have payed:", getTotalToPay(), ++row);
addLabel(summaryGridPane, "You have received:\n ", getTotalToReceive(), ++row);
FormBuilder.addLabel(summaryGridPane, "You have payed:", getTotalToPay(), ++row);
FormBuilder.addLabel(summaryGridPane, "You have received:\n ", getTotalToReceive(), ++row);
TitledPane summaryTitlePane = new TitledPane("Trade summary:", summaryGridPane);
summaryTitlePane.setCollapsible(false);
@ -233,7 +230,7 @@ public class TradeProcessController implements Initializable, IChildController
TabPane tabPane = ((TabPane) (rootContainer.getParent().getParent()));
tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem());
navigationController.navigateToView(INavigationController.TRADE__ORDER_BOOK, "Orderbook");
navigationController.navigateToView(NavigationController.TRADE__ORDER_BOOK, "Orderbook");
}
private void buildStep1()
@ -248,7 +245,7 @@ public class TradeProcessController implements Initializable, IChildController
offerDetailsGridPane.setHgap(5);
offerDetailsGridPane.setPadding(new Insets(5, 5, 5, 5));
amountTextField = addInputField(offerDetailsGridPane, "Amount (BTC):", Formatter.formatAmount(getAmount()), ++row);
amountTextField = FormBuilder.addInputField(offerDetailsGridPane, "Amount (BTC):", Formatter.formatAmount(getAmount()), ++row);
amountTextField.textProperty().addListener(e -> {
setTotal();
setVolume();
@ -261,14 +258,14 @@ public class TradeProcessController implements Initializable, IChildController
offerDetailsGridPane.add(new Label("(" + offer.getAmount() + "BTC - " + offer.getMinAmount() + "BTC)"), 2, row);
addLabel(offerDetailsGridPane, "Price:", Formatter.formatPriceWithCurrencyPair(offer.getPrice(), offer.getCurrency()), ++row);
totalLabel = addLabel(offerDetailsGridPane, "Total:", "", ++row);
FormBuilder.addLabel(offerDetailsGridPane, "Price:", Formatter.formatPriceWithCurrencyPair(offer.getPrice(), offer.getCurrency()), ++row);
totalLabel = FormBuilder.addLabel(offerDetailsGridPane, "Total:", "", ++row);
setTotal();
collateralLabel1 = addLabel(offerDetailsGridPane, "Collateral:", Formatter.formatCollateral(offer.getOfferConstraints().getCollateral(), getAmount()), ++row);
addLabel(offerDetailsGridPane, "Offer fee:", Formatter.formatSatoshis(Fees.OFFER_CREATION_FEE, true), ++row);
addVSpacer(offerDetailsGridPane, ++row);
totalToPayLabel = addLabel(offerDetailsGridPane, "You pay:", getTotalToPay(), ++row);
totalToReceiveLabel = addLabel(offerDetailsGridPane, "You receive:\n ", getTotalToReceive(), ++row);
collateralLabel1 = FormBuilder.addLabel(offerDetailsGridPane, "Collateral:", Formatter.formatCollateral(offer.getOfferConstraints().getCollateral(), getAmount()), ++row);
FormBuilder.addLabel(offerDetailsGridPane, "Offer fee:", Formatter.formatSatoshis(Fees.OFFER_CREATION_FEE, true), ++row);
FormBuilder.addVSpacer(offerDetailsGridPane, ++row);
totalToPayLabel = FormBuilder.addLabel(offerDetailsGridPane, "You pay:", getTotalToPay(), ++row);
totalToReceiveLabel = FormBuilder.addLabel(offerDetailsGridPane, "You receive:\n ", getTotalToReceive(), ++row);
offerDetailsTitlePane = new TitledPane(takerIsSelling() ? "Sell Bitcoin" : "Buy Bitcoin", offerDetailsGridPane);
offerDetailsTitlePane.setCollapsible(false);
@ -282,41 +279,41 @@ public class TradeProcessController implements Initializable, IChildController
contractGridPane.setHgap(5);
contractGridPane.setPadding(new Insets(5, 5, 5, 5));
row = 0;
addHeaderLabel(contractGridPane, "Offer details:", row);
addLabel(contractGridPane, "Offer ID:", offer.getUid().toString(), ++row);
addLabel(contractGridPane, "Offer type:", Formatter.formatDirection((offer.getDirection() == Direction.BUY ? Direction.SELL : Direction.BUY), false), ++row);
amountLabel = addLabel(contractGridPane, "Amount:", Formatter.formatAmount(getAmount()), ++row);
volumeLabel = addLabel(contractGridPane, "Volume:", "", ++row);
FormBuilder.addHeaderLabel(contractGridPane, "Offer details:", row);
FormBuilder.addLabel(contractGridPane, "Offer ID:", offer.getUid().toString(), ++row);
FormBuilder.addLabel(contractGridPane, "Offer type:", Formatter.formatDirection((offer.getDirection() == Direction.BUY ? Direction.SELL : Direction.BUY), false), ++row);
amountLabel = FormBuilder.addLabel(contractGridPane, "Amount:", Formatter.formatAmount(getAmount()), ++row);
volumeLabel = FormBuilder.addLabel(contractGridPane, "Volume:", "", ++row);
setVolume();
addLabel(contractGridPane, "Price:", Formatter.formatPriceWithCurrencyPair(offer.getPrice(), offer.getCurrency()), ++row);
collateralLabel2 = addLabel(contractGridPane, "Collateral:", "", ++row);
FormBuilder.addLabel(contractGridPane, "Price:", Formatter.formatPriceWithCurrencyPair(offer.getPrice(), offer.getCurrency()), ++row);
collateralLabel2 = FormBuilder.addLabel(contractGridPane, "Collateral:", "", ++row);
setCollateral();
addLabel(contractGridPane, "Language:", Formatter.formatList(offerConstraints.getLanguages()), ++row);
addLabel(contractGridPane, "Arbitrator:", offerConstraints.getArbitrator(), ++row);
// addLabel(contractGridPane, "Identity verification:", Formatter.formatList(offerConstraints.getIdentityVerifications()), ++row);
addLabel(contractGridPane, "Bank transfer reference ID:", "Purchase xyz 01.04.2014", ++row);
FormBuilder.addLabel(contractGridPane, "Language:", Formatter.formatList(offerConstraints.getLanguages()), ++row);
FormBuilder.addLabel(contractGridPane, "Arbitrator:", offerConstraints.getArbitrator(), ++row);
// FormBuilder.addLabel(contractGridPane, "Identity verification:", Formatter.formatList(offerConstraints.getIdentityVerifications()), ++row);
FormBuilder.addLabel(contractGridPane, "Bank transfer reference ID:", "Purchase xyz 01.04.2014", ++row);
addVSpacer(contractGridPane, ++row);
addHeaderLabel(contractGridPane, "Offerer data:", ++row);
addLabel(contractGridPane, "Account ID:", offerer.getAccountID(), ++row);
addLabel(contractGridPane, "Messaging ID:", offerer.getMessageID(), ++row);
addLabel(contractGridPane, "Country:", offerer.getCountry(), ++row);
offererPubKeyLabel = addLabel(contractGridPane, "Payment public key:", contract.getOffererPubKey(), ++row);
addLabel(contractGridPane, "Bank transfer type:", offerer.getBankDetails().getBankTransferType(), ++row);
offererAccountPrimaryID = addLabel(contractGridPane, "Bank account IBAN:", offerer.getBankDetails().getAccountPrimaryID(), ++row);
offererAccountSecondaryIDLabel = addLabel(contractGridPane, "Bank account BIC:", offerer.getBankDetails().getAccountSecondaryID(), ++row);
offererAccountHolderNameLabel = addLabel(contractGridPane, "Bank account holder:", offerer.getBankDetails().getAccountHolderName(), ++row);
FormBuilder.addVSpacer(contractGridPane, ++row);
FormBuilder.addHeaderLabel(contractGridPane, "Offerer data:", ++row);
FormBuilder.addLabel(contractGridPane, "Account ID:", offerer.getAccountID(), ++row);
FormBuilder.addLabel(contractGridPane, "Messaging ID:", offerer.getMessageID(), ++row);
FormBuilder.addLabel(contractGridPane, "Country:", offerer.getCountry(), ++row);
offererPubKeyLabel = FormBuilder.addLabel(contractGridPane, "Payment public key:", contract.getOffererPubKey(), ++row);
FormBuilder.addLabel(contractGridPane, "Bank transfer type:", offerer.getCurrentBankAccount().getBankAccountType().toString(), ++row);
offererAccountPrimaryID = FormBuilder.addLabel(contractGridPane, "Bank account IBAN:", offerer.getCurrentBankAccount().getAccountPrimaryID(), ++row);
offererAccountSecondaryIDLabel = FormBuilder.addLabel(contractGridPane, "Bank account BIC:", offerer.getCurrentBankAccount().getAccountSecondaryID(), ++row);
offererAccountHolderNameLabel = FormBuilder.addLabel(contractGridPane, "Bank account holder:", offerer.getCurrentBankAccount().getAccountHolderName(), ++row);
addVSpacer(contractGridPane, ++row);
addHeaderLabel(contractGridPane, "Offer taker data:", ++row);
addLabel(contractGridPane, "Account ID:", taker.getAccountID(), ++row);
addLabel(contractGridPane, "Messaging ID:", taker.getMessageID(), ++row);
addLabel(contractGridPane, "Country:", taker.getCountry(), ++row);
addLabel(contractGridPane, "Payment public key:", contract.getTakerPubKey(), ++row);
addLabel(contractGridPane, "Bank transfer type:", taker.getBankDetails().getBankTransferType(), ++row);
addLabel(contractGridPane, "Bank account IBAN:", taker.getBankDetails().getAccountPrimaryID(), ++row);
addLabel(contractGridPane, "Bank account BIC:", taker.getBankDetails().getAccountSecondaryID(), ++row);
addLabel(contractGridPane, "Bank account holder:", taker.getBankDetails().getAccountHolderName(), ++row);
FormBuilder.addVSpacer(contractGridPane, ++row);
FormBuilder.addHeaderLabel(contractGridPane, "Offer taker data:", ++row);
FormBuilder.addLabel(contractGridPane, "Account ID:", taker.getAccountID(), ++row);
FormBuilder.addLabel(contractGridPane, "Messaging ID:", taker.getMessageID(), ++row);
FormBuilder.addLabel(contractGridPane, "Country:", taker.getCountry(), ++row);
FormBuilder.addLabel(contractGridPane, "Payment public key:", contract.getTakerPubKey(), ++row);
FormBuilder.addLabel(contractGridPane, "Bank transfer type:", taker.getCurrentBankAccount().getBankAccountType().toString(), ++row);
FormBuilder.addLabel(contractGridPane, "Bank account IBAN:", taker.getCurrentBankAccount().getAccountPrimaryID(), ++row);
FormBuilder.addLabel(contractGridPane, "Bank account BIC:", taker.getCurrentBankAccount().getAccountSecondaryID(), ++row);
FormBuilder.addLabel(contractGridPane, "Bank account holder:", taker.getCurrentBankAccount().getAccountHolderName(), ++row);
ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(contractGridPane);
@ -338,35 +335,6 @@ public class TradeProcessController implements Initializable, IChildController
rootContainer.getChildren().addAll(vBox, contractTitlePane);
}
private Label addLabel(GridPane gridPane, String title, String value, int row)
{
gridPane.add(new Label(title), 0, row);
Label valueLabel = new Label(value);
gridPane.add(valueLabel, 1, row);
return valueLabel;
}
private void addHeaderLabel(GridPane gridPane, String title, int row)
{
Label headerLabel = new Label(title);
headerLabel.setId("form-header-text");
gridPane.add(headerLabel, 0, row);
}
private TextField addInputField(GridPane gridPane, String title, String value, int row)
{
gridPane.add(new Label(title), 0, row);
TextField textField = new TextField(value);
gridPane.add(textField, 1, row);
return textField;
}
private void addVSpacer(GridPane gridPane, int row)
{
gridPane.add(new VSpacer(10), 0, row);
}
private void setTotal()
{
totalLabel.setText(Formatter.formatVolume(getVolume()));

View File

@ -0,0 +1,57 @@
package io.bitsquare.gui.util;
import io.bitsquare.gui.components.VSpacer;
import javafx.collections.FXCollections;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import java.util.List;
public class FormBuilder
{
public static Label addLabel(GridPane gridPane, String title, String value, int row)
{
gridPane.add(new Label(title), 0, row);
Label valueLabel = new Label(value);
gridPane.add(valueLabel, 1, row);
return valueLabel;
}
public static void addHeaderLabel(GridPane gridPane, String title, int row)
{
Label headerLabel = new Label(title);
headerLabel.setId("form-header-text");
gridPane.add(headerLabel, 0, row);
}
public static TextField addInputField(GridPane gridPane, String title, String value, int row)
{
gridPane.add(new Label(title), 0, row);
TextField textField = new TextField(value);
gridPane.add(textField, 1, row);
return textField;
}
public static void addVSpacer(GridPane gridPane, int row)
{
gridPane.add(new VSpacer(10), 0, row);
}
public static Button addButton(GridPane gridPane, String title, int row)
{
Button button = new Button(title);
gridPane.add(button, 0, row);
return button;
}
public static ComboBox addComboBox(GridPane gridPane, String title, List<?> list, int row)
{
gridPane.add(new Label(title), 0, row);
ComboBox comboBox = new ComboBox(FXCollections.observableArrayList(list));
gridPane.add(comboBox, 1, row);
return comboBox;
}
}

View File

@ -20,6 +20,21 @@ public class Icons
public static final String SELL = "/images/sell.png";
public static final String REMOVE = "/images/remove_minus_9.png";
public static final String ADD = "/images/list.png";
public static final String REFRESH = "/images/refresh.png";
public static final String PROGRESS_0_ICON_FILE = "/images/tx/circleProgress0.png";
public static final String PROGRESS_1_ICON_FILE = "/images/tx/circleProgress1.png";
public static final String PROGRESS_2_ICON_FILE = "/images/tx/circleProgress2.png";
public static final String PROGRESS_3_ICON_FILE = "/images/tx/circleProgress3.png";
public static final String PROGRESS_4_ICON_FILE = "/images/tx/circleProgress4.png";
public static final String PROGRESS_5_ICON_FILE = "/images/tx/circleProgress5.png";
public static final String FULL_CONFIRMED = "/images/tx/fullConfirmed.png";
public static final String SHAPE_TRIANGLE_ICON_FILE = "/images/tx/shapeTriangle.png";
public static final String SHAPE_SQUARE_ICON_FILE = "/images/tx/shapeSquare.png";
public static final String SHAPE_PENTAGON_ICON_FILE = "/images/tx/shapePentagon.png";
public static final String SHAPE_HEXAGON_ICON_FILE = "/images/tx/shapeHexagon.png";
public static Image getIconImage(String iconName)
{
@ -30,4 +45,44 @@ public class Icons
{
return new ImageView(new Image(Icons.class.getResourceAsStream(iconName)));
}
public static String getIconIDForConfirmations(int confirmations)
{
switch (confirmations)
{
case 0:
return Icons.PROGRESS_0_ICON_FILE;
case 1:
return Icons.PROGRESS_1_ICON_FILE;
case 2:
return Icons.PROGRESS_2_ICON_FILE;
case 3:
return Icons.PROGRESS_3_ICON_FILE;
case 4:
return Icons.PROGRESS_4_ICON_FILE;
case 5:
return Icons.PROGRESS_5_ICON_FILE;
case 6:
default:
return Icons.FULL_CONFIRMED;
}
}
public static String getIconIDForPeersSeenTx(int numberOfPeersSeenTx)
{
switch (numberOfPeersSeenTx)
{
case 0:
return Icons.PROGRESS_0_ICON_FILE;
case 1:
return Icons.SHAPE_TRIANGLE_ICON_FILE;
case 2:
return Icons.SHAPE_SQUARE_ICON_FILE;
case 3:
return Icons.SHAPE_PENTAGON_ICON_FILE;
case 4:
default:
return Icons.SHAPE_HEXAGON_ICON_FILE;
}
}
}

View File

@ -10,20 +10,22 @@ import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
public class Loc
public class Localisation
{
public static ResourceBundle getResourceBundle()
{
return ResourceBundle.getBundle("i18n.displayStrings", new UTF8Control());
}
public static String get(String key)
{
ResourceBundle bundle = ResourceBundle.getBundle("i18n.displayStrings", new UTF8Control());
return bundle.getString(key);
return Localisation.getResourceBundle().getString(key);
}
public static String get(String key, String... arguments)
{
String entry = ResourceBundle.getBundle("i18n.displayStrings", new UTF8Control()).getString(key);
return MessageFormat.format(entry, arguments);
return MessageFormat.format(Localisation.get(key), arguments);
}
}
class UTF8Control extends ResourceBundle.Control

View File

@ -0,0 +1,77 @@
package io.bitsquare.gui.util;
import javafx.animation.*;
import javafx.application.Platform;
import javafx.scene.Node;
import javafx.scene.effect.GaussianBlur;
import javafx.scene.layout.Pane;
import javafx.util.Duration;
import static com.google.common.base.Preconditions.checkState;
public class Transitions
{
public static final int UI_ANIMATION_TIME_MSEC = 350;
public static void fadeIn(Node ui)
{
fadeIn(ui, UI_ANIMATION_TIME_MSEC);
}
public static void fadeIn(Node ui, int time)
{
FadeTransition ft = new FadeTransition(Duration.millis(UI_ANIMATION_TIME_MSEC), ui);
ft.setFromValue(0.0);
ft.setToValue(1.0);
ft.play();
}
public static Animation fadeOut(Node ui)
{
FadeTransition ft = new FadeTransition(Duration.millis(UI_ANIMATION_TIME_MSEC), ui);
ft.setFromValue(ui.getOpacity());
ft.setToValue(0.0);
ft.play();
return ft;
}
public static Animation fadeOutAndRemove(Node ui, Pane parentPane)
{
Animation animation = fadeOut(ui);
animation.setOnFinished(actionEvent -> parentPane.getChildren().remove(ui));
return animation;
}
public static void blurOut(Node node)
{
blurOut(node, UI_ANIMATION_TIME_MSEC);
}
public static void blurOut(Node node, int time)
{
GaussianBlur blur = new GaussianBlur(0.0);
node.setEffect(blur);
Timeline timeline = new Timeline();
KeyValue kv = new KeyValue(blur.radiusProperty(), 10.0);
KeyFrame kf = new KeyFrame(Duration.millis(time), kv);
timeline.getKeyFrames().add(kf);
timeline.play();
}
public static void blurIn(Node node)
{
GaussianBlur blur = (GaussianBlur) node.getEffect();
Timeline timeline = new Timeline();
KeyValue kv = new KeyValue(blur.radiusProperty(), 0.0);
KeyFrame kf = new KeyFrame(Duration.millis(UI_ANIMATION_TIME_MSEC), kv);
timeline.getKeyFrames().add(kf);
timeline.setOnFinished(actionEvent -> node.setEffect(null));
timeline.play();
}
public static void checkGuiThread()
{
checkState(Platform.isFxApplicationThread());
}
}

View File

@ -0,0 +1,22 @@
package io.bitsquare.gui.util;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Verification
{
private static final Logger log = LoggerFactory.getLogger(Verification.class);
@Inject
public Verification()
{
}
// TODO define rules for prim. and sec. ID per bank account type
public static boolean verifyAccountIDsByBankTransferType(Object bankTransferTypeSelectedItem, String accountPrimaryID, String accountSecondaryID)
{
return true;
}
}

View File

@ -1,13 +0,0 @@
package io.bitsquare.msg;
/**
* Gateway to messaging
*/
public interface IMessageFacade
{
void broadcast(Message message);
void send(Message message, String receiverMsgID);
void registerListener(String listenerPubKey);
}

View File

@ -41,19 +41,15 @@ public class Message
this.payload = contract;
}
public String toString()
{
return type + ": " + Utils.convertToJson(payload);
}
public String getType()
{
return type;
}
public void setType(String type)
public String toString()
{
this.type = type;
return type + ": " + Utils.convertToJson(payload);
}

View File

@ -3,23 +3,25 @@ package io.bitsquare.msg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MessageFacade implements IMessageFacade
/**
* That facade delivers messaging functionality from an external library -> to be defined...
* The external library codebase must not be used outside that facade.
* That way a change of the library will only affect that class.
*/
public class MessageFacade
{
private static final Logger log = LoggerFactory.getLogger(MessageFacade.class);
@Override
public void broadcast(Message message)
{
log.info(message.toString());
}
@Override
public void send(Message message, String receiverPubKey)
{
log.info(message.toString() + "/" + receiverPubKey);
}
@Override
public void registerListener(String listenerPubKey)
{
log.info(listenerPubKey);

View File

@ -1,7 +1,7 @@
package io.bitsquare.settings;
import com.google.inject.Inject;
import io.bitsquare.storage.IStorage;
import io.bitsquare.storage.Storage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -11,12 +11,12 @@ public class OrderBookFilterSettings
{
private static final Logger log = LoggerFactory.getLogger(OrderBookFilterSettings.class);
private IStorage storage;
private Storage storage;
private Currency currency;
private ArrayList<Currency> currencies;
@Inject
public OrderBookFilterSettings(IStorage storage)
public OrderBookFilterSettings(Storage storage)
{
this.storage = storage;

View File

@ -1,7 +1,8 @@
package io.bitsquare.settings;
import com.google.inject.Inject;
import io.bitsquare.storage.IStorage;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.orderbook.OrderBookFilter;
import java.util.ArrayList;
@ -10,10 +11,12 @@ import java.util.Locale;
public class Settings
{
public static Locale locale = Locale.ENGLISH;
public static Currency currency = Currency.getInstance("USD");
private IStorage storage;
private Storage storage;
private OrderBookFilter orderBookFilter;
public static Locale getLocale()
@ -27,13 +30,14 @@ public class Settings
}
@Inject
public Settings(IStorage storage, OrderBookFilter orderBookFilter)
public Settings(Storage storage, OrderBookFilter orderBookFilter)
{
this.storage = storage;
this.orderBookFilter = orderBookFilter;
locale = Locale.ENGLISH;
currency = Currency.getInstance("USD");
this.storage = storage;
currency = (Currency) storage.read("Settings.currency");
if (currency == null)
@ -66,16 +70,16 @@ public class Settings
return currencies;
}
public ArrayList<String> getAllBankTransferTypes()
public ArrayList<BankAccountType> getAllBankAccountTypes()
{
ArrayList<String> bankTransferTypes = new ArrayList<>();
bankTransferTypes.add("SEPA");
bankTransferTypes.add("Wire");
bankTransferTypes.add("International");
bankTransferTypes.add("OKPay");
bankTransferTypes.add("Netteller");
bankTransferTypes.add("Perfect Money");
bankTransferTypes.add("Any");
ArrayList<BankAccountType> bankTransferTypes = new ArrayList<>();
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.SEPA, "IBAN", "BIC"));
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.WIRE, "Prim_todo", "Sec_todo"));
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.INTERNATIONAL, "Prim_todo", "Sec_todo"));
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.OK_PAY, "Prim_todo", "Sec_todo"));
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.NET_TELLER, "Prim_todo", "Sec_todo"));
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.PERFECT_MONEY, "Prim_todo", "Sec_todo"));
bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.OTHER, "Prim_todo", "Sec_todo"));
return bankTransferTypes;
}
@ -184,4 +188,5 @@ public class Settings
return orderBookFilter;
}
}

View File

@ -0,0 +1,32 @@
package io.bitsquare.settings;
import com.google.inject.Inject;
import io.bitsquare.storage.Storage;
import io.bitsquare.trade.Direction;
import io.bitsquare.trade.orderbook.OrderBookFilter;
import io.bitsquare.user.User;
public class Startup
{
private Storage storage;
private User user;
private OrderBookFilter orderBookFilter;
@Inject
public Startup(Storage storage, OrderBookFilter orderBookFilter)
{
this.storage = storage;
this.orderBookFilter = orderBookFilter;
}
public void applyPersistedData()
{
// todo use persistence
orderBookFilter.setAmount(0.0);
orderBookFilter.setPrice(0.0);
orderBookFilter.setDirection(Direction.BUY);
orderBookFilter.setCurrency(Settings.getCurrency());
}
}

View File

@ -1,6 +0,0 @@
package io.bitsquare.setup;
public interface ISetup
{
void applyPersistedData();
}

View File

@ -1,59 +0,0 @@
package io.bitsquare.setup;
import com.google.inject.Inject;
import io.bitsquare.settings.Settings;
import io.bitsquare.storage.IStorage;
import io.bitsquare.trade.Direction;
import io.bitsquare.trade.orderbook.OrderBookFilter;
import io.bitsquare.user.BankDetails;
import io.bitsquare.user.User;
import java.util.UUID;
public class MockSetup implements ISetup
{
private IStorage storage;
private User user;
private OrderBookFilter orderBookFilter;
@Inject
public MockSetup(IStorage storage, User user, OrderBookFilter orderBookFilter)
{
this.storage = storage;
this.user = user;
this.orderBookFilter = orderBookFilter;
}
@Override
public void applyPersistedData()
{
String accountID = (String) storage.read("User.accountID");
if (accountID == null)
{
storage.write("User.accountID", UUID.randomUUID().toString());
storage.write("User.messageID", UUID.randomUUID().toString());
storage.write("User.country", "ES");
storage.write("BankDetails.bankTransferType", "SEPA");
storage.write("BankDetails.accountPrimaryID", "IBAN_12312");
storage.write("BankDetails.accountSecondaryID", "BIC_123123");
storage.write("BankDetails.accountHolderName", "Bob Brown");
}
user.setAccountID((String) storage.read("User.accountID"));
user.setMessageID((String) storage.read("User.messageID"));
user.setCountry((String) storage.read("User.country"));
user.setBankDetails(new BankDetails((String) storage.read("BankDetails.bankTransferType"),
(String) storage.read("BankDetails.accountPrimaryID"),
(String) storage.read("BankDetails.accountSecondaryID"),
(String) storage.read("BankDetails.accountHolderName")));
// todo use persistence
orderBookFilter.setAmount(0.0);
orderBookFilter.setPrice(0.0);
orderBookFilter.setDirection(Direction.BUY);
orderBookFilter.setCurrency(Settings.getCurrency());
}
}

View File

@ -1,8 +0,0 @@
package io.bitsquare.storage;
public interface IStorage
{
void write(String key, Object value);
Object read(String key);
}

View File

@ -1,5 +1,6 @@
package io.bitsquare.storage;
import io.bitsquare.user.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -10,17 +11,18 @@ import java.util.Map;
/**
* Simple storage solution for serialized data
*/
public class SimpleStorage implements IStorage
public class Storage
{
private static final Logger log = LoggerFactory.getLogger(SimpleStorage.class);
private static final Logger log = LoggerFactory.getLogger(Storage.class);
private final String preferencesFileName = "preferences.ser";
private final String storageFile;
private DataVO dataVO;
public SimpleStorage()
public Storage()
{
storageFile = SimpleStorage.class.getProtectionDomain().getCodeSource().getLocation().getFile() + "/" + preferencesFileName;
storageFile = Storage.class.getProtectionDomain().getCodeSource().getLocation().getFile() + "/" + preferencesFileName;
dataVO = readDataVO();
if (dataVO == null)
@ -31,7 +33,18 @@ public class SimpleStorage implements IStorage
}
}
@Override
public void saveUser(User user)
{
write(user.getClass().getName(), user);
}
public void updateUserFromStorage(User user)
{
User savedUser = (User) read(user.getClass().getName());
if (savedUser != null)
user.updateFromStorage(savedUser);
}
public void write(String key, Object value)
{
log.info("Write object with key = " + key + " / value = " + value);
@ -39,8 +52,6 @@ public class SimpleStorage implements IStorage
writeDataVO(dataVO);
}
@Override
public Object read(String key)
{
dataVO = readDataVO();
@ -87,9 +98,14 @@ public class SimpleStorage implements IStorage
}
return dataVO;
}
}
class DataVO implements Serializable
{
private static final long serialVersionUID = -1127046445783201376L;
public Map<String, Object> dict;
}

View File

@ -1,5 +1,7 @@
package io.bitsquare.trade;
import io.bitsquare.bank.BankAccountType;
import java.util.List;
public class OfferConstraints
@ -7,21 +9,21 @@ public class OfferConstraints
private double collateral;
private List<String> countries;
private List<String> languages;
private List<String> bankTransferTypes;
private List<BankAccountType> bankAccountTypes;
private String arbitrator;
private String identityVerification;
public OfferConstraints(List<String> countries,
List<String> languages,
double collateral,
List<String> bankTransferTypes,
List<BankAccountType> bankAccountTypes,
String arbitrator,
String identityVerification)
{
this.countries = countries;
this.languages = languages;
this.collateral = collateral;
this.bankTransferTypes = bankTransferTypes;
this.bankAccountTypes = bankAccountTypes;
this.arbitrator = arbitrator;
this.identityVerification = identityVerification;
}
@ -41,9 +43,9 @@ public class OfferConstraints
return languages;
}
public List<String> getBankTransferTypes()
public List<BankAccountType> getBankAccountTypes()
{
return bankTransferTypes;
return bankAccountTypes;
}
public String getArbitrator()

View File

@ -2,11 +2,11 @@ package io.bitsquare.trade;
import com.google.inject.Inject;
import io.bitsquare.btc.BlockChainFacade;
import io.bitsquare.btc.IWalletFacade;
import io.bitsquare.btc.KeyPair;
import io.bitsquare.crypto.ICryptoFacade;
import io.bitsquare.msg.IMessageFacade;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.crypto.CryptoFacade;
import io.bitsquare.msg.Message;
import io.bitsquare.msg.MessageFacade;
import io.bitsquare.settings.Settings;
import io.bitsquare.user.User;
import io.bitsquare.util.Utils;
@ -19,27 +19,27 @@ import java.util.UUID;
/**
* Main facade for operating with trade domain between GUI and services (msg, btc)
*/
public class TradingFacade
public class Trading
{
private static final Logger log = LoggerFactory.getLogger(TradingFacade.class);
private static final Logger log = LoggerFactory.getLogger(Trading.class);
private final HashMap<String, Offer> offers = new HashMap<>();
private final HashMap<String, Trade> trades = new HashMap<>();
private final HashMap<String, Contract> contracts = new HashMap<>();
private User user;
private IMessageFacade messageFacade;
private MessageFacade messageFacade;
private BlockChainFacade blockChainFacade;
private IWalletFacade walletFacade;
private ICryptoFacade cryptoFacade;
private WalletFacade walletFacade;
private CryptoFacade cryptoFacade;
private Settings settings;
@Inject
public TradingFacade(User user,
Settings settings,
IMessageFacade messageFacade,
BlockChainFacade blockChainFacade,
IWalletFacade walletFacade,
ICryptoFacade cryptoFacade)
public Trading(User user,
Settings settings,
MessageFacade messageFacade,
BlockChainFacade blockChainFacade,
WalletFacade walletFacade,
CryptoFacade cryptoFacade)
{
this.user = user;
this.settings = settings;
@ -97,7 +97,7 @@ public class TradingFacade
String contractAsJson = Utils.convertToJson(contract);
contract.getTrade().setJsonRepresentation(contractAsJson);
contract.getTrade().setSignature(cryptoFacade.sign(contractAsJson));
contract.getTrade().setSignature(cryptoFacade.signContract(contractAsJson));
}
/**

View File

@ -1,9 +0,0 @@
package io.bitsquare.trade.orderbook;
import io.bitsquare.gui.trade.orderbook.OrderBookListItem;
import javafx.collections.ObservableList;
public interface IOrderBook
{
ObservableList<OrderBookListItem> getFilteredList(OrderBookFilter orderBookFilter);
}

View File

@ -1,6 +1,8 @@
package io.bitsquare.trade.orderbook;
import com.google.inject.Inject;
import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.gui.trade.orderbook.OrderBookListItem;
import io.bitsquare.gui.util.Converter;
import io.bitsquare.gui.util.Formatter;
@ -8,7 +10,6 @@ import io.bitsquare.settings.Settings;
import io.bitsquare.trade.Direction;
import io.bitsquare.trade.Offer;
import io.bitsquare.trade.OfferConstraints;
import io.bitsquare.user.BankDetails;
import io.bitsquare.user.User;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
@ -17,13 +18,13 @@ import javafx.collections.transformation.FilteredList;
import java.util.*;
import java.util.function.Predicate;
public class MockOrderBook implements IOrderBook
public class OrderBook
{
private ObservableList<OrderBookListItem> orderBookListItems;
private Settings settings;
@Inject
public MockOrderBook(Settings settings)
public OrderBook(Settings settings)
{
this.settings = settings;
orderBookListItems = FXCollections.observableArrayList();
@ -33,7 +34,6 @@ public class MockOrderBook implements IOrderBook
}
}
@Override
public ObservableList<OrderBookListItem> getFilteredList(OrderBookFilter orderBookFilter)
{
FilteredList filtered = orderBookListItems.filtered(new Predicate<OrderBookListItem>()
@ -100,10 +100,13 @@ public class MockOrderBook implements IOrderBook
minAmount = Converter.convertToDouble(Formatter.formatAmount(minAmount));
String country = getCountries().get(0);
BankDetails bankDetails = new BankDetails();
String bankTransferType = getBankTransferTypes().get(0);
bankDetails.setBankTransferType(bankTransferType);
User offerer = new User(UUID.randomUUID().toString(), UUID.randomUUID().toString(), country, bankDetails);
BankAccountType bankAccountType = getBankTransferTypes().get(0);
BankAccount bankAccount = new BankAccount(bankAccountType);
User offerer = new User();
offerer.setAccountID(UUID.randomUUID().toString());
offerer.setMessageID(UUID.randomUUID().toString());
offerer.setCountry(country);
offerer.addBankAccount(bankAccount);
Direction direction = Direction.BUY;
double price = 500 + Math.random() * 50;
@ -148,9 +151,9 @@ public class MockOrderBook implements IOrderBook
return randomizeStrings(settings.getAllLanguages(), false);
}
private List<String> getBankTransferTypes()
private List<BankAccountType> getBankTransferTypes()
{
return randomizeStrings(settings.getAllBankTransferTypes(), false);
return randomizeBankAccountTypes(settings.getAllBankAccountTypes(), false);
}
private List<String> getArbitrators()
@ -163,6 +166,15 @@ public class MockOrderBook implements IOrderBook
return randomizeStrings(settings.getAllCollaterals(), false);
}
private List<BankAccountType> randomizeBankAccountTypes(List<BankAccountType> list, boolean optional)
{
int e = new Random().nextInt(list.size());
if (!optional && list.size() > 0)
e = Math.max(e, 1);
int s = (e == 0) ? 0 : new Random().nextInt(e);
list = list.subList(s, e);
return list;
}
private List<String> randomizeStrings(List<String> list, boolean optional)
{

View File

@ -2,15 +2,15 @@ package io.bitsquare.trade.payment.process;
import com.google.inject.Inject;
import io.bitsquare.btc.BlockChainFacade;
import io.bitsquare.btc.IWalletFacade;
import io.bitsquare.msg.IMessageFacade;
import io.bitsquare.btc.WalletFacade;
import io.bitsquare.msg.MessageFacade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PaymentProcess
{
private static final Logger log = LoggerFactory.getLogger(PaymentProcess.class);
private IMessageFacade messageService;
private MessageFacade messageService;
private BlockChainFacade bitcoinServices;
protected String offererDepositPubKey;
@ -26,20 +26,20 @@ public class PaymentProcess
protected String takerOutputPayment;
protected String multiSigAddress;
private IWalletFacade wallet;
private WalletFacade wallet;
public PaymentProcess()
{
}
@Inject
public void setMessageService(IMessageFacade messageService)
public void setMessageService(MessageFacade messageService)
{
this.messageService = messageService;
}
@Inject
public void setWallet(IWalletFacade wallet)
public void setWallet(WalletFacade wallet)
{
this.wallet = wallet;
}

View File

@ -1,61 +0,0 @@
package io.bitsquare.user;
public class BankDetails
{
private String bankTransferType;
private String accountPrimaryID;
private String accountSecondaryID;
private String accountHolderName;
public BankDetails(String bankTransferType, String accountPrimaryID, String accountSecondaryID, String accountHolderName)
{
this.bankTransferType = bankTransferType;
this.accountPrimaryID = accountPrimaryID;
this.accountSecondaryID = accountSecondaryID;
this.accountHolderName = accountHolderName;
}
public BankDetails()
{
}
public void setBankTransferType(String bankTransferType)
{
this.bankTransferType = bankTransferType;
}
public String getAccountPrimaryID()
{
return accountPrimaryID;
}
public void setAccountPrimaryID(String accountPrimaryID)
{
this.accountPrimaryID = accountPrimaryID;
}
public String getAccountSecondaryID()
{
return accountSecondaryID;
}
public void setAccountSecondaryID(String accountSecondaryID)
{
this.accountSecondaryID = accountSecondaryID;
}
public String getAccountHolderName()
{
return accountHolderName;
}
public void setAccountHolderName(String accountHolderName)
{
this.accountHolderName = accountHolderName;
}
public String getBankTransferType()
{
return bankTransferType;
}
}

View File

@ -1,25 +1,73 @@
package io.bitsquare.user;
public class User
import io.bitsquare.bank.BankAccount;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class User implements Serializable
{
private static final long serialVersionUID = 7409078808248518638L;
private String accountID;
private String messageID;
private boolean isOnline;
private BankDetails bankDetails;
private String country;
private boolean online;
private BankAccount currentBankAccount = null;
public User(String accountID, String messageID, String country, BankDetails bankDetails)
{
this.accountID = accountID;
this.messageID = messageID;
this.country = country;
this.bankDetails = bankDetails;
}
private Map<String, BankAccount> bankAccounts = new HashMap<>();
private String country;
public User()
{
}
public void updateFromStorage(User savedUser)
{
if (savedUser != null)
{
accountID = savedUser.getAccountID();
messageID = savedUser.getMessageID();
online = savedUser.isOnline();
currentBankAccount = savedUser.getCurrentBankAccount();
bankAccounts = savedUser.getBankAccounts();
country = savedUser.getCountry();
}
}
public String getStringifiedBankAccounts()
{
String bankAccountUIDs = "";
for (Iterator<Map.Entry<String, BankAccount>> iterator = getBankAccounts().entrySet().iterator(); iterator.hasNext(); )
{
Map.Entry entry = iterator.next();
bankAccountUIDs += entry.getValue().toString();
if (iterator.hasNext())
bankAccountUIDs += ", ";
}
return bankAccountUIDs;
}
public void addBankAccount(BankAccount bankAccount)
{
if (currentBankAccount == null)
currentBankAccount = bankAccount;
bankAccounts.put(bankAccount.getUid(), bankAccount);
}
public Map<String, BankAccount> getBankAccounts()
{
return bankAccounts;
}
public BankAccount getBankAccountByUID(String uid)
{
return bankAccounts.get(uid);
}
public String getMessageID()
{
return messageID;
@ -50,25 +98,15 @@ public class User
return country;
}
public BankDetails getBankDetails()
public BankAccount getCurrentBankAccount()
{
return bankDetails;
return currentBankAccount;
}
public void setBankDetails(BankDetails bankDetails)
public boolean isOnline()
{
this.bankDetails = bankDetails;
return online;
}
public boolean getOnline()
{
return isOnline;
}
public void setOnline(boolean online)
{
this.isOnline = online;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 284 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,16 @@
package io.bitsquare.gui.util;
import io.bitsquare.bank.BankAccountType;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
public class VerificationTest
{
@Test
public void testVerifyBankAccountData()
{
// TODO define rules for prim. and sec. ID per bank account type
assertTrue(Verification.verifyAccountIDsByBankTransferType(BankAccountType.BankAccountTypeEnum.SEPA, "DE11876543210000123456", "12345678"));
}
}