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; 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.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
import io.bitsquare.btc.IWalletFacade; import io.bitsquare.btc.WalletFacade;
import io.bitsquare.di.BitSquareModule; import io.bitsquare.di.BitSquareModule;
import io.bitsquare.di.GuiceFXMLLoader; import io.bitsquare.di.GuiceFXMLLoader;
import io.bitsquare.setup.ISetup; import io.bitsquare.gui.util.Localisation;
import io.bitsquare.setup.MockSetup; import io.bitsquare.settings.Startup;
import io.bitsquare.storage.Storage;
import io.bitsquare.user.User;
import javafx.application.Application; import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.stage.Stage; import javafx.stage.Stage;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.IOException;
public class BitSquare extends Application public class BitSquare extends Application
{ {
private static final Logger log = LoggerFactory.getLogger(BitSquare.class); private static final Logger log = LoggerFactory.getLogger(BitSquare.class);
private IWalletFacade walletFacade; private WalletFacade walletFacade;
public static void main(String[] args) public static void main(String[] args)
{ {
@ -34,23 +29,30 @@ public class BitSquare extends Application
@Override @Override
public void start(Stage stage) throws Exception 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. final Injector injector = Guice.createInjector(new BitSquareModule());
//GuiUtils.handleCrashesOnThisThread(); walletFacade = injector.getInstance(WalletFacade.class);
try
{ // apply stored data
init(stage); final User user = injector.getInstance(User.class);
} catch (Throwable t) final Storage storage = injector.getInstance(Storage.class);
{ user.updateFromStorage((User) storage.read(user.getClass().getName()));
// Nicer message for the case where the block store file is locked.
if (Throwables.getRootCause(t) instanceof BlockStoreException) //TODO remove
{ final Startup setup = injector.getInstance(Startup.class);
//GuiUtils.informationalAlert("Already running", "This application is already running and cannot be started twice."); setup.applyPersistedData();
}
else stage.setTitle("BitSquare");
{
throw t; 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 @Override
@ -60,38 +62,4 @@ public class BitSquare extends Application
super.stop(); 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; 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 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; package io.bitsquare.btc;
import com.google.bitcoin.core.Transaction;
import java.math.BigInteger; import java.math.BigInteger;
public class Fees 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_CREATION_FEE = new BigInteger("500000");
public static BigInteger OFFER_TAKER_FEE = OFFER_CREATION_FEE; public static BigInteger OFFER_TAKER_FEE = OFFER_CREATION_FEE;
public static BigInteger BTC_NETWORK_FEE = new BigInteger("10000"); 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 public class KeyPair
{ {
//TODO just for mock, remove later
private String pubKey; private String pubKey;
private String privKey; private String privKey;

View file

@ -1,40 +1,61 @@
package io.bitsquare.btc; package io.bitsquare.btc;
import com.google.bitcoin.core.Address; import com.google.bitcoin.core.*;
import com.google.bitcoin.core.NetworkParameters;
import com.google.bitcoin.core.PeerEventListener;
import com.google.bitcoin.core.Wallet;
import com.google.bitcoin.kits.WalletAppKit; import com.google.bitcoin.kits.WalletAppKit;
import com.google.bitcoin.params.MainNetParams; import com.google.bitcoin.params.MainNetParams;
import com.google.bitcoin.params.RegTestParams; import com.google.bitcoin.params.RegTestParams;
import com.google.bitcoin.utils.Threading;
import com.google.inject.Inject; import com.google.inject.Inject;
import io.bitsquare.crypto.CryptoFacade;
import javafx.application.Platform;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import wallettemplate.Main;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID; 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 static final Logger log = LoggerFactory.getLogger(WalletFacade.class);
private NetworkParameters networkParameters; private NetworkParameters networkParameters;
private WalletAppKit walletAppKit; 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 @Inject
public WalletFacade(NetworkParameters networkParameters, WalletAppKit walletAppKit) public WalletFacade(NetworkParameters networkParameters, WalletAppKit walletAppKit, CryptoFacade cryptoFacade, BlockChainFacade blockChainFacade)
{ {
this.networkParameters = networkParameters; this.networkParameters = networkParameters;
this.walletAppKit = walletAppKit; this.walletAppKit = walletAppKit;
this.cryptoFacade = cryptoFacade;
balance = new BigInteger("100000000"); this.blockChainFacade = blockChainFacade;
} }
@Override public void initWallet()
public void initWallet(PeerEventListener peerEventListener)
{ {
// 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()) if (networkParameters == RegTestParams.get())
{ {
walletAppKit.connectToLocalHost(); // You should run a regtest mode bitcoind locally. 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 // 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. // or progress widget to keep the user engaged whilst we initialise, but we don't.
walletAppKit.setDownloadListener(peerEventListener) walletAppKit.setDownloadListener(new BlockChainDownloadListener())
.setBlockingStartup(false) .setBlockingStartup(false)
.setUserAgent("BitSquare", "1.0"); .setUserAgent("BitSquare", "1.0");
walletAppKit.startAsync(); walletAppKit.startAsync();
@ -62,45 +83,103 @@ public class WalletFacade implements IWalletFacade
log.info(walletAppKit.wallet().toString()); log.info(walletAppKit.wallet().toString());
} }
@Override
public void terminateWallet() public void terminateWallet()
{ {
walletAppKit.stopAsync(); walletAppKit.stopAsync();
walletAppKit.awaitTerminated(); 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() public BigInteger getBalance()
{ {
return walletAppKit.wallet().getBalance(Wallet.BalanceType.ESTIMATED); return walletAppKit.wallet().getBalance(Wallet.BalanceType.ESTIMATED);
} }
@Override
public String getAddress() public String getAddress()
{ {
return walletAppKit.wallet().getKeys().get(0).toAddress(networkParameters).toString(); return walletAppKit.wallet().getKeys().get(0).toAddress(networkParameters).toString();
} }
@Override // account registration
public boolean pay(BigInteger satoshisToPay, String destinationAddress) public Address getAccountRegistrationAddress()
{ {
if (getBalance().subtract(satoshisToPay).longValue() > 0) return getAccountRegistrationWallet().getAddress();
{
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;
} }
public String getAccountRegistrationPubKey()
{
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 @Override
public KeyPair createNewAddress() protected void doneDownload()
{ {
//MOCK super.doneDownload();
return new KeyPair(UUID.randomUUID().toString(), UUID.randomUUID().toString()); 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.core.NetworkParameters;
import com.google.bitcoin.kits.WalletAppKit; import com.google.bitcoin.kits.WalletAppKit;
import com.google.bitcoin.params.MainNetParams; import com.google.bitcoin.params.MainNetParams;
import com.google.bitcoin.params.RegTestParams;
import com.google.bitcoin.params.TestNet3Params; import com.google.bitcoin.params.TestNet3Params;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Inject; 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.Named;
import com.google.inject.name.Names; import com.google.inject.name.Names;
import io.bitsquare.btc.BlockChainFacade; import io.bitsquare.btc.BlockChainFacade;
import io.bitsquare.btc.IWalletFacade;
import io.bitsquare.btc.WalletFacade; import io.bitsquare.btc.WalletFacade;
import io.bitsquare.crypto.ICryptoFacade; import io.bitsquare.crypto.CryptoFacade;
import io.bitsquare.crypto.MockCryptoFacade;
import io.bitsquare.msg.IMessageFacade;
import io.bitsquare.msg.MessageFacade; import io.bitsquare.msg.MessageFacade;
import io.bitsquare.settings.OrderBookFilterSettings; import io.bitsquare.settings.OrderBookFilterSettings;
import io.bitsquare.settings.Settings; import io.bitsquare.settings.Settings;
import io.bitsquare.setup.ISetup; import io.bitsquare.settings.Startup;
import io.bitsquare.setup.MockSetup; import io.bitsquare.storage.Storage;
import io.bitsquare.storage.IStorage; import io.bitsquare.trade.Trading;
import io.bitsquare.storage.SimpleStorage; import io.bitsquare.trade.orderbook.OrderBook;
import io.bitsquare.trade.TradingFacade;
import io.bitsquare.trade.orderbook.IOrderBook;
import io.bitsquare.trade.orderbook.MockOrderBook;
import io.bitsquare.trade.orderbook.OrderBookFilter; import io.bitsquare.trade.orderbook.OrderBookFilter;
import io.bitsquare.user.User; import io.bitsquare.user.User;
@ -35,31 +28,29 @@ import java.io.File;
public class BitSquareModule extends AbstractModule public class BitSquareModule extends AbstractModule
{ {
@Override @Override
protected void configure() protected void configure()
{ {
bind(ISetup.class).to(MockSetup.class).asEagerSingleton(); bind(Startup.class).asEagerSingleton();
bind(User.class).asEagerSingleton(); bind(User.class).asEagerSingleton();
bind(IOrderBook.class).to(MockOrderBook.class).asEagerSingleton(); bind(OrderBook.class).asEagerSingleton();
bind(IStorage.class).to(SimpleStorage.class).asEagerSingleton(); bind(Storage.class).asEagerSingleton();
bind(Settings.class).asEagerSingleton(); bind(Settings.class).asEagerSingleton();
bind(OrderBookFilter.class).asEagerSingleton(); bind(OrderBookFilter.class).asEagerSingleton();
bind(OrderBookFilterSettings.class).asEagerSingleton(); bind(OrderBookFilterSettings.class).asEagerSingleton();
bind(ICryptoFacade.class).to(MockCryptoFacade.class).asEagerSingleton(); bind(CryptoFacade.class).asEagerSingleton();
bind(IWalletFacade.class).to(WalletFacade.class).asEagerSingleton(); bind(WalletFacade.class).asEagerSingleton();
bind(BlockChainFacade.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(NetworkParameters.class).toProvider(NetworkParametersProvider.class).asEagerSingleton();
bind(WalletAppKit.class).toProvider(WalletAppKitProvider.class).asEagerSingleton(); bind(WalletAppKit.class).toProvider(WalletAppKitProvider.class).asEagerSingleton();
} }
} }
class WalletAppKitProvider implements Provider<WalletAppKit> class WalletAppKitProvider implements Provider<WalletAppKit>
@ -94,15 +85,12 @@ class NetworkParametersProvider implements Provider<NetworkParameters>
switch (networkType) switch (networkType)
{ {
case IWalletFacade.MAIN_NET: case WalletFacade.MAIN_NET:
result = MainNetParams.get(); result = MainNetParams.get();
break; break;
case IWalletFacade.TEST_NET: case WalletFacade.TEST_NET:
result = TestNet3Params.get(); result = TestNet3Params.get();
break; break;
case IWalletFacade.REG_TEST_NET:
result = RegTestParams.get();
break;
} }
return result; return result;
} }

View file

@ -2,6 +2,10 @@ package io.bitsquare.di;
import com.google.inject.Injector; import com.google.inject.Injector;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.util.BuilderFactory;
import java.net.URL;
import java.util.ResourceBundle;
/** /**
* Guice support for fxml controllers * Guice support for fxml controllers
@ -11,18 +15,39 @@ public class GuiceFXMLLoader extends FXMLLoader
private static Injector injector = null; private static Injector injector = null;
public static void setInjector(Injector injector)
{
GuiceFXMLLoader.injector = injector;
}
public GuiceFXMLLoader() 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) if (GuiceFXMLLoader.injector != null)
setControllerFactory(new GuiceControllerFactory(GuiceFXMLLoader.injector)); 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; package io.bitsquare.gui;
import com.google.bitcoin.core.DownloadListener;
import com.google.inject.Inject; import com.google.inject.Inject;
import io.bitsquare.BitSquare; import io.bitsquare.btc.DownloadListener;
import io.bitsquare.btc.IWalletFacade; import io.bitsquare.btc.WalletFacade;
import io.bitsquare.di.GuiceFXMLLoader; 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.trade.TradeController;
import io.bitsquare.gui.util.Formatter; import io.bitsquare.gui.util.Formatter;
import io.bitsquare.gui.util.Icons; import io.bitsquare.gui.util.Icons;
import io.bitsquare.gui.util.Localisation;
import io.bitsquare.settings.Settings; import io.bitsquare.settings.Settings;
import io.bitsquare.trade.Direction; import io.bitsquare.trade.Direction;
import io.bitsquare.trade.orderbook.OrderBookFilter; import io.bitsquare.trade.orderbook.OrderBookFilter;
import javafx.animation.FadeTransition; import io.bitsquare.user.User;
import javafx.animation.Interpolator;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox; import javafx.scene.layout.*;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.util.Duration;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -38,28 +35,36 @@ import java.util.Currency;
import java.util.Date; import java.util.Date;
import java.util.ResourceBundle; 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 static final Logger log = LoggerFactory.getLogger(MainController.class);
private Settings settings; private Settings settings;
private User user;
private OrderBookFilter orderBookFilter; private OrderBookFilter orderBookFilter;
private IWalletFacade walletFacade; private WalletFacade walletFacade;
private IChildController childController; private ChildController childController;
private ToggleGroup toggleGroup; private ToggleGroup toggleGroup;
private ToggleButton prevToggleButton; private ToggleButton prevToggleButton;
private Image prevToggleButtonIcon; private Image prevToggleButtonIcon;
public ProgressBar networkSyncProgressBar; // public ProgressBar networkSyncProgressBar;
public Label networkSyncInfoLabel; //public Label networkSyncInfoLabel;
private Pane setupView;
private SetupController setupController;
@FXML @FXML
public Pane contentPane; public Pane contentPane;
public HBox leftNavPane, rightNavPane, footerContainer; public HBox leftNavPane, rightNavPane;
public StackPane rootContainer;
public AnchorPane anchorPane;
private NetworkSyncPane networkSyncPane;
@Inject @Inject
public MainController(Settings settings, OrderBookFilter orderBookFilter, IWalletFacade walletFacade) public MainController(Settings settings, User user, OrderBookFilter orderBookFilter, WalletFacade walletFacade)
{ {
this.settings = settings; this.settings = settings;
this.user = user;
this.orderBookFilter = orderBookFilter; this.orderBookFilter = orderBookFilter;
this.walletFacade = walletFacade; this.walletFacade = walletFacade;
} }
@ -67,21 +72,49 @@ public class MainController implements Initializable, INavigationController
@Override @Override
public void initialize(URL url, ResourceBundle rb) 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(); buildNavigation();
if (user.getAccountID() != null)
buildFooter(); {
anchorPane.getChildren().add(networkSyncPane);
}
else
{
buildSetupView();
anchorPane.setOpacity(0);
setupController.setNetworkSyncPane(networkSyncPane);
rootContainer.getChildren().add(setupView);
}
} }
@Override @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 try
{ {
Node view = loader.load(BitSquare.class.getResourceAsStream(fxmlView)); final Node view = loader.load();
contentPane.getChildren().setAll(view); contentPane.getChildren().setAll(view);
childController = loader.getController(); childController = loader.getController();
childController.setNavigationController(this); childController.setNavigationController(this);
@ -91,10 +124,23 @@ public class MainController implements Initializable, INavigationController
e.printStackTrace(); e.printStackTrace();
} }
return null; 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"); childController = navigateToView(fxmlView, direction == Direction.BUY ? "Orderbook Buy" : "Orderbook Sell");
if (childController instanceof TradeController && direction != null) if (childController instanceof TradeController && direction != null)
@ -104,36 +150,40 @@ public class MainController implements Initializable, INavigationController
return childController; 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() private void buildNavigation()
{ {
toggleGroup = new ToggleGroup(); toggleGroup = new ToggleGroup();
ToggleButton homeButton = addNavButton(leftNavPane, "Overview", Icons.HOME, Icons.HOME, INavigationController.HOME); ToggleButton homeButton = addNavButton(leftNavPane, "Overview", Icons.HOME, Icons.HOME, NavigationController.HOME);
ToggleButton buyButton = addNavButton(leftNavPane, "Buy BTC", Icons.NAV_BUY, Icons.NAV_BUY_ACTIVE, INavigationController.TRADE, Direction.BUY); 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, INavigationController.TRADE, Direction.SELL); ToggleButton sellButton = addNavButton(leftNavPane, "Sell BTC", Icons.NAV_SELL, Icons.NAV_SELL_ACTIVE, NavigationController.TRADE, Direction.SELL);
addNavButton(leftNavPane, "Orders", Icons.ORDERS, Icons.ORDERS, INavigationController.ORDERS); addNavButton(leftNavPane, "Orders", Icons.ORDERS, Icons.ORDERS, NavigationController.ORDERS);
addNavButton(leftNavPane, "History", Icons.HISTORY, Icons.HISTORY, INavigationController.HISTORY); addNavButton(leftNavPane, "History", Icons.HISTORY, Icons.HISTORY, NavigationController.HISTORY);
addNavButton(leftNavPane, "Funds", Icons.FUNDS, Icons.FUNDS, INavigationController.FUNDS); addNavButton(leftNavPane, "Funds", Icons.FUNDS, Icons.FUNDS, NavigationController.FUNDS);
addNavButton(leftNavPane, "Message", Icons.MSG, Icons.MSG, INavigationController.MSG); addNavButton(leftNavPane, "Message", Icons.MSG, Icons.MSG, NavigationController.MSG);
addBalanceInfo(rightNavPane); addBalanceInfo(rightNavPane);
addCurrencyComboBox(); addCurrencyComboBox();
addNavButton(rightNavPane, "Settings", Icons.SETTINGS, Icons.SETTINGS, INavigationController.SETTINGS); addNavButton(rightNavPane, "Settings", Icons.SETTINGS, Icons.SETTINGS, NavigationController.SETTINGS);
sellButton.fire(); sellButton.fire();
//homeButton.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) private ToggleButton addNavButton(Pane parent, String title, String iconId, String iconIdActivated, String navTarget)
{ {
return addNavButton(parent, title, iconId, iconIdActivated, navTarget, null); 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) private ToggleButton addNavButton(Pane parent, String title, String iconId, String iconIdActivated, String navTarget, Direction direction)
{ {
Pane pane = new Pane(); Pane pane = new Pane();
pane.setPrefSize(50,50); pane.setPrefSize(50, 50);
ToggleButton toggleButton = new ToggleButton("", Icons.getIconImageView(iconId)); ToggleButton toggleButton = new ToggleButton("", Icons.getIconImageView(iconId));
toggleButton.setToggleGroup(toggleGroup); toggleButton.setToggleGroup(toggleGroup);
toggleButton.setId("nav-button"); toggleButton.setId("nav-button");
toggleButton.setPrefSize(50,50); toggleButton.setPrefSize(50, 50);
toggleButton.setOnAction(e -> { toggleButton.setOnAction(e -> {
if (prevToggleButton != null) if (prevToggleButton != null)
{ {
@ -184,7 +234,6 @@ public class MainController implements Initializable, INavigationController
TextField balanceLabel = new TextField(); TextField balanceLabel = new TextField();
balanceLabel.setEditable(false); balanceLabel.setEditable(false);
balanceLabel.setMouseTransparent(true); balanceLabel.setMouseTransparent(true);
//balanceLabel.setPrefHeight(30);
balanceLabel.setPrefWidth(90); balanceLabel.setPrefWidth(90);
balanceLabel.setId("nav-balance-label"); balanceLabel.setId("nav-balance-label");
balanceLabel.setText(Formatter.formatSatoshis(walletFacade.getBalance(), false)); balanceLabel.setText(Formatter.formatSatoshis(walletFacade.getBalance(), false));
@ -216,7 +265,6 @@ public class MainController implements Initializable, INavigationController
Pane holder = new Pane(); Pane holder = new Pane();
ComboBox currencyComboBox = new ComboBox(FXCollections.observableArrayList(settings.getAllCurrencies())); ComboBox currencyComboBox = new ComboBox(FXCollections.observableArrayList(settings.getAllCurrencies()));
currencyComboBox.setLayoutY(12); currencyComboBox.setLayoutY(12);
currencyComboBox.setId("nav-currency-combobox");
currencyComboBox.setValue(Settings.getCurrency()); currencyComboBox.setValue(Settings.getCurrency());
currencyComboBox.valueProperty().addListener(new ChangeListener<Currency>() currencyComboBox.valueProperty().addListener(new ChangeListener<Currency>()
@ -232,39 +280,5 @@ public class MainController implements Initializable, INavigationController
rightNavPane.getChildren().add(holder); 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"?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<AnchorPane id="root-pane" minHeight="300" minWidth="400" prefHeight="600" prefWidth="800" <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" 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"> 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">
<children>
<HBox fx:id="leftNavPane" spacing="10" AnchorPane.leftAnchor="0" AnchorPane.topAnchor="0"/> <HBox fx:id="leftNavPane" spacing="10" AnchorPane.leftAnchor="0" AnchorPane.topAnchor="0"/>
<HBox fx:id="rightNavPane" spacing="10" AnchorPane.rightAnchor="10" 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 id="content-pane" fx:id="contentPane" AnchorPane.bottomAnchor="20" AnchorPane.leftAnchor="0"
AnchorPane.rightAnchor="0" AnchorPane.topAnchor="60"/> AnchorPane.rightAnchor="0" AnchorPane.topAnchor="60"/>
<HBox fx:id="footerContainer" prefHeight="20" spacing="10" AnchorPane.leftAnchor="10" </AnchorPane>
AnchorPane.bottomAnchor="0"/> </StackPane>
</children>
</AnchorPane>

View file

@ -1,8 +1,10 @@
package io.bitsquare.gui; 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 HOME = "/io/bitsquare/gui/home/HomeView.fxml";
public static final String TRADE = "/io/bitsquare/gui/trade/TradeView.fxml"; public static final String TRADE = "/io/bitsquare/gui/trade/TradeView.fxml";
public static final String ORDERS = "/io/bitsquare/gui/orders/OrdersView.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__PROCESS = "/io/bitsquare/gui/trade/tradeprocess/TradeProcessView.fxml";
public static final String TRADE__CREATE_OFFER = "/io/bitsquare/gui/trade/offer/CreateOfferView.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 public class ProcessStepBar<T> extends Control
{ {
private List<ProcessStepItem> processStepItems;
private List<ProcessStepItem> processStepItems = null;
public ProcessStepBar()
{
}
public ProcessStepBar(List<ProcessStepItem> processStepItems) public ProcessStepBar(List<ProcessStepItem> processStepItems)
{ {
@ -20,6 +27,13 @@ public class ProcessStepBar<T> extends Control
return new ProcessStepBarSkin<>(this); return new ProcessStepBarSkin<>(this);
} }
public void setProcessStepItems(List<ProcessStepItem> processStepItems)
{
this.processStepItems = processStepItems;
if (getSkin() != null)
((ProcessStepBarSkin) getSkin()).dataChanged();
}
List<ProcessStepItem> getProcessStepItems() List<ProcessStepItem> getProcessStepItems()
{ {
return processStepItems; return processStepItems;

View file

@ -34,6 +34,18 @@ public class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, B
controller = getSkinnable(); controller = getSkinnable();
applyData();
}
public void dataChanged()
{
applyData();
}
private void applyData()
{
if (controller.getProcessStepItems() != null)
{
int i = 0; int i = 0;
labelWithBorders = new ArrayList<>(); labelWithBorders = new ArrayList<>();
int size = controller.getProcessStepItems().size(); int size = controller.getProcessStepItems().size();
@ -51,6 +63,7 @@ public class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, B
currentLabelWithBorder.select(); currentLabelWithBorder.select();
} }
}
public void next() public void next()
{ {
@ -89,6 +102,7 @@ public class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, B
} }
} }
public static class LabelWithBorder extends Label public static class LabelWithBorder extends Label
{ {
private final double arrowWidth = 10; private final double arrowWidth = 10;

View file

@ -3,9 +3,9 @@ package io.bitsquare.gui.funds;
import com.google.inject.Inject; import com.google.inject.Inject;
import de.jensd.fx.fontawesome.AwesomeDude; import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon; import de.jensd.fx.fontawesome.AwesomeIcon;
import io.bitsquare.btc.IWalletFacade; import io.bitsquare.btc.WalletFacade;
import io.bitsquare.gui.IChildController; import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.INavigationController; import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.util.Formatter; import io.bitsquare.gui.util.Formatter;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
@ -20,11 +20,11 @@ import java.net.URL;
import java.util.ResourceBundle; import java.util.ResourceBundle;
public class FundsController implements Initializable, IChildController public class FundsController implements Initializable, ChildController
{ {
private INavigationController navigationController; private NavigationController navigationController;
private IWalletFacade walletFacade; private WalletFacade walletFacade;
@FXML @FXML
public Pane rootContainer; public Pane rootContainer;
@ -36,7 +36,7 @@ public class FundsController implements Initializable, IChildController
public Label copyIcon; public Label copyIcon;
@Inject @Inject
public FundsController(IWalletFacade walletFacade) public FundsController(WalletFacade walletFacade)
{ {
this.walletFacade = walletFacade; this.walletFacade = walletFacade;
@ -58,7 +58,7 @@ public class FundsController implements Initializable, IChildController
} }
@Override @Override
public void setNavigationController(INavigationController navigationController) public void setNavigationController(NavigationController navigationController)
{ {
this.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 io.bitsquare.gui.components.HSpacer?>
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.layout.*?>
<?import javafx.scene.layout.HBox?>
<AnchorPane fx:controller="io.bitsquare.gui.funds.FundsController" <AnchorPane fx:controller="io.bitsquare.gui.funds.FundsController"
xmlns:fx="http://javafx.com/fxml" fx:id="rootContainer"> 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"/> <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"> <HBox spacing="5" AnchorPane.topAnchor="40" AnchorPane.leftAnchor="10">
<Label text="Funds address:" > <Label text="Funds address:">
<padding> <padding>
<Insets bottom="0.0" left="0.0" right="0.0" top="5.0"/> <Insets bottom="0.0" left="0.0" right="0.0" top="5.0"/>
</padding> </padding>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,8 +1,8 @@
package io.bitsquare.gui.trade.orderbook; package io.bitsquare.gui.trade.orderbook;
import com.google.inject.Inject; import com.google.inject.Inject;
import io.bitsquare.gui.IChildController; import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.INavigationController; import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.trade.offer.CreateOfferController; import io.bitsquare.gui.trade.offer.CreateOfferController;
import io.bitsquare.gui.trade.tradeprocess.TradeProcessController; import io.bitsquare.gui.trade.tradeprocess.TradeProcessController;
import io.bitsquare.gui.util.Converter; 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.gui.util.Icons;
import io.bitsquare.settings.Settings; import io.bitsquare.settings.Settings;
import io.bitsquare.trade.Direction; import io.bitsquare.trade.Direction;
import io.bitsquare.trade.orderbook.IOrderBook; import io.bitsquare.trade.orderbook.OrderBook;
import io.bitsquare.trade.orderbook.MockOrderBook;
import io.bitsquare.trade.orderbook.OrderBookFilter; import io.bitsquare.trade.orderbook.OrderBookFilter;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
@ -34,10 +33,10 @@ import java.text.ParseException;
import java.util.Arrays; import java.util.Arrays;
import java.util.ResourceBundle; import java.util.ResourceBundle;
public class OrderBookController implements Initializable, IChildController public class OrderBookController implements Initializable, ChildController
{ {
private INavigationController navigationController; private NavigationController navigationController;
private IOrderBook orderBook; private OrderBook orderBook;
private Settings settings; private Settings settings;
private OrderBookListItem selectedOrderBookListItem; private OrderBookListItem selectedOrderBookListItem;
@ -65,7 +64,7 @@ public class OrderBookController implements Initializable, IChildController
private ImageView tradeButtonImageView; private ImageView tradeButtonImageView;
@Inject @Inject
public OrderBookController(IOrderBook orderBook, OrderBookFilter orderBookFilter, Settings settings) public OrderBookController(OrderBook orderBook, OrderBookFilter orderBookFilter, Settings settings)
{ {
this.orderBook = orderBook; this.orderBook = orderBook;
this.orderBookFilter = orderBookFilter; this.orderBookFilter = orderBookFilter;
@ -121,7 +120,7 @@ public class OrderBookController implements Initializable, IChildController
} }
@Override @Override
public void setNavigationController(INavigationController navigationController) public void setNavigationController(NavigationController navigationController)
{ {
this.navigationController = navigationController; this.navigationController = navigationController;
} }
@ -154,7 +153,7 @@ public class OrderBookController implements Initializable, IChildController
private void openTradeTab(OrderBookListItem orderBookListItem) private void openTradeTab(OrderBookListItem orderBookListItem)
{ {
String title = orderBookListItem.getOffer().getDirection() == Direction.BUY ? "Trade: Sell Bitcoin" : "Trade: Buy Bitcoin"; 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(); double requestedAmount = orderBookListItem.getOffer().getAmount();
if (!amount.getText().equals("")) if (!amount.getText().equals(""))
@ -173,7 +172,7 @@ public class OrderBookController implements Initializable, IChildController
holderPane.getChildren().add(createOfferButton); holderPane.getChildren().add(createOfferButton);
createOfferButton.setOnAction(e -> { 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); ((CreateOfferController) nextController).setOrderBookFilter(orderBookFilter);
}); });
} }
@ -202,16 +201,17 @@ public class OrderBookController implements Initializable, IChildController
private void createFilterPane() private void createFilterPane()
{ {
MockOrderBook mockOrderBook = new MockOrderBook(settings); OrderBook mockOrderBook = new OrderBook(settings);
orderBookFilter.setOfferConstraints(mockOrderBook.getRandomOfferConstraints()); 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, "Countries: ", orderBookFilter.getOfferConstraints().getCountries(), settings.getAllCountries());
OrderBookFilterTextItemBuilder.build(filterPane, "Languages: ", orderBookFilter.getOfferConstraints().getLanguages(), settings.getAllLanguages()); 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, "Collateral: ", Arrays.asList(String.valueOf(orderBookFilter.getOfferConstraints().getCollateral())), settings.getAllCollaterals());
OrderBookFilterTextItemBuilder.build(filterPane, "Arbitrator: ", Arrays.asList(orderBookFilter.getOfferConstraints().getArbitrator()), settings.getAllArbitrators()); OrderBookFilterTextItemBuilder.build(filterPane, "Arbitrator: ", Arrays.asList(orderBookFilter.getOfferConstraints().getArbitrator()), settings.getAllArbitrators());
} }
private double textInputToNumber(String oldValue, String newValue) private double textInputToNumber(String oldValue, String newValue)
{ {
//TODO use regex.... or custom textfield component //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 com.google.inject.Inject;
import io.bitsquare.btc.BtcFormatter; import io.bitsquare.btc.BtcFormatter;
import io.bitsquare.btc.Fees; import io.bitsquare.btc.Fees;
import io.bitsquare.gui.IChildController; import io.bitsquare.gui.ChildController;
import io.bitsquare.gui.INavigationController; import io.bitsquare.gui.NavigationController;
import io.bitsquare.gui.components.VSpacer; import io.bitsquare.gui.components.VSpacer;
import io.bitsquare.gui.components.processbar.ProcessStepBar; import io.bitsquare.gui.components.processbar.ProcessStepBar;
import io.bitsquare.gui.components.processbar.ProcessStepItem; import io.bitsquare.gui.components.processbar.ProcessStepItem;
import io.bitsquare.gui.util.Colors; import io.bitsquare.gui.util.*;
import io.bitsquare.gui.util.Converter;
import io.bitsquare.gui.util.Formatter;
import io.bitsquare.gui.util.Utils;
import io.bitsquare.trade.*; import io.bitsquare.trade.*;
import io.bitsquare.user.User; import io.bitsquare.user.User;
import javafx.animation.AnimationTimer; import javafx.animation.AnimationTimer;
@ -30,14 +27,14 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.ResourceBundle; 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 Offer offer;
private Trade trade; private Trade trade;
private Contract contract; private Contract contract;
private INavigationController navigationController; private NavigationController navigationController;
private List<ProcessStepItem> processStepItems = new ArrayList(); private List<ProcessStepItem> processStepItems = new ArrayList();
private double requestedAmount; private double requestedAmount;
@ -58,13 +55,13 @@ public class TradeProcessController implements Initializable, IChildController
public AnchorPane rootContainer; public AnchorPane rootContainer;
@Inject @Inject
public TradeProcessController(TradingFacade tradingFacade) public TradeProcessController(Trading trading)
{ {
this.tradingFacade = tradingFacade; this.trading = trading;
} }
@Override @Override
public void setNavigationController(INavigationController navigationController) public void setNavigationController(NavigationController navigationController)
{ {
this.navigationController = navigationController; this.navigationController = navigationController;
} }
@ -79,9 +76,9 @@ public class TradeProcessController implements Initializable, IChildController
this.offer = offer; this.offer = offer;
this.requestedAmount = requestedAmount; this.requestedAmount = requestedAmount;
trade = tradingFacade.createNewTrade(offer); trade = trading.createNewTrade(offer);
trade.setRequestedAmount(requestedAmount); 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(takerIsSelling() ? "Sell BTC" : "Buy BTC", Colors.BLUE));
processStepItems.add(new ProcessStepItem("Bank transfer", Colors.BLUE)); processStepItems.add(new ProcessStepItem("Bank transfer", Colors.BLUE));
@ -138,7 +135,7 @@ public class TradeProcessController implements Initializable, IChildController
// Payment Process // Payment Process
private void sendTakeOfferRequest() private void sendTakeOfferRequest()
{ {
tradingFacade.sendTakeOfferRequest(trade); trading.sendTakeOfferRequest(trade);
feedbackLabel.setText("Request take offer confirmation from peer."); feedbackLabel.setText("Request take offer confirmation from peer.");
Utils.setTimeout(500, (AnimationTimer animationTimer) -> { Utils.setTimeout(500, (AnimationTimer animationTimer) -> {
onTakeOfferRequestConfirmed(); onTakeOfferRequestConfirmed();
@ -149,7 +146,7 @@ public class TradeProcessController implements Initializable, IChildController
private void onTakeOfferRequestConfirmed() private void onTakeOfferRequestConfirmed()
{ {
tradingFacade.payOfferFee(trade); trading.payOfferFee(trade);
feedbackLabel.setText("Request offer fee payment confirmation from peer."); feedbackLabel.setText("Request offer fee payment confirmation from peer.");
Utils.setTimeout(500, (AnimationTimer animationTimer) -> { Utils.setTimeout(500, (AnimationTimer animationTimer) -> {
@ -161,7 +158,7 @@ public class TradeProcessController implements Initializable, IChildController
private void onOfferFeePaymentConfirmed() private void onOfferFeePaymentConfirmed()
{ {
tradingFacade.requestOffererDetailData(); trading.requestOffererDetailData();
feedbackLabel.setText("Request detail data from peer."); feedbackLabel.setText("Request detail data from peer.");
Utils.setTimeout(500, (AnimationTimer animationTimer) -> { Utils.setTimeout(500, (AnimationTimer animationTimer) -> {
onUserDetailsReceived(); onUserDetailsReceived();
@ -172,8 +169,8 @@ public class TradeProcessController implements Initializable, IChildController
private void onUserDetailsReceived() private void onUserDetailsReceived()
{ {
tradingFacade.signContract(contract); trading.signContract(contract);
tradingFacade.payToDepositTx(trade); trading.payToDepositTx(trade);
buildWaitBankTransfer(); buildWaitBankTransfer();
} }
@ -207,7 +204,7 @@ public class TradeProcessController implements Initializable, IChildController
private void releaseBTC() private void releaseBTC()
{ {
processStepBar.next(); processStepBar.next();
tradingFacade.releaseBTC(trade); trading.releaseBTC(trade);
vBox.getChildren().remove(infoLabel); vBox.getChildren().remove(infoLabel);
@ -220,8 +217,8 @@ public class TradeProcessController implements Initializable, IChildController
summaryGridPane.setHgap(5); summaryGridPane.setHgap(5);
summaryGridPane.setPadding(new Insets(5, 5, 5, 5)); summaryGridPane.setPadding(new Insets(5, 5, 5, 5));
addLabel(summaryGridPane, "You have payed:", getTotalToPay(), ++row); FormBuilder.addLabel(summaryGridPane, "You have payed:", getTotalToPay(), ++row);
addLabel(summaryGridPane, "You have received:\n ", getTotalToReceive(), ++row); FormBuilder.addLabel(summaryGridPane, "You have received:\n ", getTotalToReceive(), ++row);
TitledPane summaryTitlePane = new TitledPane("Trade summary:", summaryGridPane); TitledPane summaryTitlePane = new TitledPane("Trade summary:", summaryGridPane);
summaryTitlePane.setCollapsible(false); summaryTitlePane.setCollapsible(false);
@ -233,7 +230,7 @@ public class TradeProcessController implements Initializable, IChildController
TabPane tabPane = ((TabPane) (rootContainer.getParent().getParent())); TabPane tabPane = ((TabPane) (rootContainer.getParent().getParent()));
tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem()); tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem());
navigationController.navigateToView(INavigationController.TRADE__ORDER_BOOK, "Orderbook"); navigationController.navigateToView(NavigationController.TRADE__ORDER_BOOK, "Orderbook");
} }
private void buildStep1() private void buildStep1()
@ -248,7 +245,7 @@ public class TradeProcessController implements Initializable, IChildController
offerDetailsGridPane.setHgap(5); offerDetailsGridPane.setHgap(5);
offerDetailsGridPane.setPadding(new Insets(5, 5, 5, 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 -> { amountTextField.textProperty().addListener(e -> {
setTotal(); setTotal();
setVolume(); setVolume();
@ -261,14 +258,14 @@ public class TradeProcessController implements Initializable, IChildController
offerDetailsGridPane.add(new Label("(" + offer.getAmount() + "BTC - " + offer.getMinAmount() + "BTC)"), 2, row); offerDetailsGridPane.add(new Label("(" + offer.getAmount() + "BTC - " + offer.getMinAmount() + "BTC)"), 2, row);
addLabel(offerDetailsGridPane, "Price:", Formatter.formatPriceWithCurrencyPair(offer.getPrice(), offer.getCurrency()), ++row); FormBuilder.addLabel(offerDetailsGridPane, "Price:", Formatter.formatPriceWithCurrencyPair(offer.getPrice(), offer.getCurrency()), ++row);
totalLabel = addLabel(offerDetailsGridPane, "Total:", "", ++row); totalLabel = FormBuilder.addLabel(offerDetailsGridPane, "Total:", "", ++row);
setTotal(); setTotal();
collateralLabel1 = addLabel(offerDetailsGridPane, "Collateral:", Formatter.formatCollateral(offer.getOfferConstraints().getCollateral(), getAmount()), ++row); collateralLabel1 = FormBuilder.addLabel(offerDetailsGridPane, "Collateral:", Formatter.formatCollateral(offer.getOfferConstraints().getCollateral(), getAmount()), ++row);
addLabel(offerDetailsGridPane, "Offer fee:", Formatter.formatSatoshis(Fees.OFFER_CREATION_FEE, true), ++row); FormBuilder.addLabel(offerDetailsGridPane, "Offer fee:", Formatter.formatSatoshis(Fees.OFFER_CREATION_FEE, true), ++row);
addVSpacer(offerDetailsGridPane, ++row); FormBuilder.addVSpacer(offerDetailsGridPane, ++row);
totalToPayLabel = addLabel(offerDetailsGridPane, "You pay:", getTotalToPay(), ++row); totalToPayLabel = FormBuilder.addLabel(offerDetailsGridPane, "You pay:", getTotalToPay(), ++row);
totalToReceiveLabel = addLabel(offerDetailsGridPane, "You receive:\n ", getTotalToReceive(), ++row); totalToReceiveLabel = FormBuilder.addLabel(offerDetailsGridPane, "You receive:\n ", getTotalToReceive(), ++row);
offerDetailsTitlePane = new TitledPane(takerIsSelling() ? "Sell Bitcoin" : "Buy Bitcoin", offerDetailsGridPane); offerDetailsTitlePane = new TitledPane(takerIsSelling() ? "Sell Bitcoin" : "Buy Bitcoin", offerDetailsGridPane);
offerDetailsTitlePane.setCollapsible(false); offerDetailsTitlePane.setCollapsible(false);
@ -282,41 +279,41 @@ public class TradeProcessController implements Initializable, IChildController
contractGridPane.setHgap(5); contractGridPane.setHgap(5);
contractGridPane.setPadding(new Insets(5, 5, 5, 5)); contractGridPane.setPadding(new Insets(5, 5, 5, 5));
row = 0; row = 0;
addHeaderLabel(contractGridPane, "Offer details:", row); FormBuilder.addHeaderLabel(contractGridPane, "Offer details:", row);
addLabel(contractGridPane, "Offer ID:", offer.getUid().toString(), ++row); FormBuilder.addLabel(contractGridPane, "Offer ID:", offer.getUid().toString(), ++row);
addLabel(contractGridPane, "Offer type:", Formatter.formatDirection((offer.getDirection() == Direction.BUY ? Direction.SELL : Direction.BUY), false), ++row); FormBuilder.addLabel(contractGridPane, "Offer type:", Formatter.formatDirection((offer.getDirection() == Direction.BUY ? Direction.SELL : Direction.BUY), false), ++row);
amountLabel = addLabel(contractGridPane, "Amount:", Formatter.formatAmount(getAmount()), ++row); amountLabel = FormBuilder.addLabel(contractGridPane, "Amount:", Formatter.formatAmount(getAmount()), ++row);
volumeLabel = addLabel(contractGridPane, "Volume:", "", ++row); volumeLabel = FormBuilder.addLabel(contractGridPane, "Volume:", "", ++row);
setVolume(); setVolume();
addLabel(contractGridPane, "Price:", Formatter.formatPriceWithCurrencyPair(offer.getPrice(), offer.getCurrency()), ++row); FormBuilder.addLabel(contractGridPane, "Price:", Formatter.formatPriceWithCurrencyPair(offer.getPrice(), offer.getCurrency()), ++row);
collateralLabel2 = addLabel(contractGridPane, "Collateral:", "", ++row); collateralLabel2 = FormBuilder.addLabel(contractGridPane, "Collateral:", "", ++row);
setCollateral(); setCollateral();
addLabel(contractGridPane, "Language:", Formatter.formatList(offerConstraints.getLanguages()), ++row); FormBuilder.addLabel(contractGridPane, "Language:", Formatter.formatList(offerConstraints.getLanguages()), ++row);
addLabel(contractGridPane, "Arbitrator:", offerConstraints.getArbitrator(), ++row); FormBuilder.addLabel(contractGridPane, "Arbitrator:", offerConstraints.getArbitrator(), ++row);
// addLabel(contractGridPane, "Identity verification:", Formatter.formatList(offerConstraints.getIdentityVerifications()), ++row); // FormBuilder.addLabel(contractGridPane, "Identity verification:", Formatter.formatList(offerConstraints.getIdentityVerifications()), ++row);
addLabel(contractGridPane, "Bank transfer reference ID:", "Purchase xyz 01.04.2014", ++row); FormBuilder.addLabel(contractGridPane, "Bank transfer reference ID:", "Purchase xyz 01.04.2014", ++row);
addVSpacer(contractGridPane, ++row); FormBuilder.addVSpacer(contractGridPane, ++row);
addHeaderLabel(contractGridPane, "Offerer data:", ++row); FormBuilder.addHeaderLabel(contractGridPane, "Offerer data:", ++row);
addLabel(contractGridPane, "Account ID:", offerer.getAccountID(), ++row); FormBuilder.addLabel(contractGridPane, "Account ID:", offerer.getAccountID(), ++row);
addLabel(contractGridPane, "Messaging ID:", offerer.getMessageID(), ++row); FormBuilder.addLabel(contractGridPane, "Messaging ID:", offerer.getMessageID(), ++row);
addLabel(contractGridPane, "Country:", offerer.getCountry(), ++row); FormBuilder.addLabel(contractGridPane, "Country:", offerer.getCountry(), ++row);
offererPubKeyLabel = addLabel(contractGridPane, "Payment public key:", contract.getOffererPubKey(), ++row); offererPubKeyLabel = FormBuilder.addLabel(contractGridPane, "Payment public key:", contract.getOffererPubKey(), ++row);
addLabel(contractGridPane, "Bank transfer type:", offerer.getBankDetails().getBankTransferType(), ++row); FormBuilder.addLabel(contractGridPane, "Bank transfer type:", offerer.getCurrentBankAccount().getBankAccountType().toString(), ++row);
offererAccountPrimaryID = addLabel(contractGridPane, "Bank account IBAN:", offerer.getBankDetails().getAccountPrimaryID(), ++row); offererAccountPrimaryID = FormBuilder.addLabel(contractGridPane, "Bank account IBAN:", offerer.getCurrentBankAccount().getAccountPrimaryID(), ++row);
offererAccountSecondaryIDLabel = addLabel(contractGridPane, "Bank account BIC:", offerer.getBankDetails().getAccountSecondaryID(), ++row); offererAccountSecondaryIDLabel = FormBuilder.addLabel(contractGridPane, "Bank account BIC:", offerer.getCurrentBankAccount().getAccountSecondaryID(), ++row);
offererAccountHolderNameLabel = addLabel(contractGridPane, "Bank account holder:", offerer.getBankDetails().getAccountHolderName(), ++row); offererAccountHolderNameLabel = FormBuilder.addLabel(contractGridPane, "Bank account holder:", offerer.getCurrentBankAccount().getAccountHolderName(), ++row);
addVSpacer(contractGridPane, ++row); FormBuilder.addVSpacer(contractGridPane, ++row);
addHeaderLabel(contractGridPane, "Offer taker data:", ++row); FormBuilder.addHeaderLabel(contractGridPane, "Offer taker data:", ++row);
addLabel(contractGridPane, "Account ID:", taker.getAccountID(), ++row); FormBuilder.addLabel(contractGridPane, "Account ID:", taker.getAccountID(), ++row);
addLabel(contractGridPane, "Messaging ID:", taker.getMessageID(), ++row); FormBuilder.addLabel(contractGridPane, "Messaging ID:", taker.getMessageID(), ++row);
addLabel(contractGridPane, "Country:", taker.getCountry(), ++row); FormBuilder.addLabel(contractGridPane, "Country:", taker.getCountry(), ++row);
addLabel(contractGridPane, "Payment public key:", contract.getTakerPubKey(), ++row); FormBuilder.addLabel(contractGridPane, "Payment public key:", contract.getTakerPubKey(), ++row);
addLabel(contractGridPane, "Bank transfer type:", taker.getBankDetails().getBankTransferType(), ++row); FormBuilder.addLabel(contractGridPane, "Bank transfer type:", taker.getCurrentBankAccount().getBankAccountType().toString(), ++row);
addLabel(contractGridPane, "Bank account IBAN:", taker.getBankDetails().getAccountPrimaryID(), ++row); FormBuilder.addLabel(contractGridPane, "Bank account IBAN:", taker.getCurrentBankAccount().getAccountPrimaryID(), ++row);
addLabel(contractGridPane, "Bank account BIC:", taker.getBankDetails().getAccountSecondaryID(), ++row); FormBuilder.addLabel(contractGridPane, "Bank account BIC:", taker.getCurrentBankAccount().getAccountSecondaryID(), ++row);
addLabel(contractGridPane, "Bank account holder:", taker.getBankDetails().getAccountHolderName(), ++row); FormBuilder.addLabel(contractGridPane, "Bank account holder:", taker.getCurrentBankAccount().getAccountHolderName(), ++row);
ScrollPane scrollPane = new ScrollPane(); ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(contractGridPane); scrollPane.setContent(contractGridPane);
@ -338,35 +335,6 @@ public class TradeProcessController implements Initializable, IChildController
rootContainer.getChildren().addAll(vBox, contractTitlePane); 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() private void setTotal()
{ {
totalLabel.setText(Formatter.formatVolume(getVolume())); 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 SELL = "/images/sell.png";
public static final String REMOVE = "/images/remove_minus_9.png"; public static final String REMOVE = "/images/remove_minus_9.png";
public static final String ADD = "/images/list.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) public static Image getIconImage(String iconName)
{ {
@ -30,4 +45,44 @@ public class Icons
{ {
return new ImageView(new Image(Icons.class.getResourceAsStream(iconName))); 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.PropertyResourceBundle;
import java.util.ResourceBundle; 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) public static String get(String key)
{ {
ResourceBundle bundle = ResourceBundle.getBundle("i18n.displayStrings", new UTF8Control()); return Localisation.getResourceBundle().getString(key);
return bundle.getString(key);
} }
public static String get(String key, String... arguments) public static String get(String key, String... arguments)
{ {
String entry = ResourceBundle.getBundle("i18n.displayStrings", new UTF8Control()).getString(key); return MessageFormat.format(Localisation.get(key), arguments);
return MessageFormat.format(entry, arguments);
} }
} }
class UTF8Control extends ResourceBundle.Control 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; this.payload = contract;
} }
public String toString()
{
return type + ": " + Utils.convertToJson(payload);
}
public String getType() public String getType()
{ {
return type; 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.Logger;
import org.slf4j.LoggerFactory; 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); private static final Logger log = LoggerFactory.getLogger(MessageFacade.class);
@Override
public void broadcast(Message message) public void broadcast(Message message)
{ {
log.info(message.toString()); log.info(message.toString());
} }
@Override
public void send(Message message, String receiverPubKey) public void send(Message message, String receiverPubKey)
{ {
log.info(message.toString() + "/" + receiverPubKey); log.info(message.toString() + "/" + receiverPubKey);
} }
@Override
public void registerListener(String listenerPubKey) public void registerListener(String listenerPubKey)
{ {
log.info(listenerPubKey); log.info(listenerPubKey);

View file

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

View file

@ -1,7 +1,8 @@
package io.bitsquare.settings; package io.bitsquare.settings;
import com.google.inject.Inject; 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 io.bitsquare.trade.orderbook.OrderBookFilter;
import java.util.ArrayList; import java.util.ArrayList;
@ -10,10 +11,12 @@ import java.util.Locale;
public class Settings public class Settings
{ {
public static Locale locale = Locale.ENGLISH; public static Locale locale = Locale.ENGLISH;
public static Currency currency = Currency.getInstance("USD"); public static Currency currency = Currency.getInstance("USD");
private IStorage storage;
private Storage storage;
private OrderBookFilter orderBookFilter; private OrderBookFilter orderBookFilter;
public static Locale getLocale() public static Locale getLocale()
@ -27,13 +30,14 @@ public class Settings
} }
@Inject @Inject
public Settings(IStorage storage, OrderBookFilter orderBookFilter) public Settings(Storage storage, OrderBookFilter orderBookFilter)
{ {
this.storage = storage;
this.orderBookFilter = orderBookFilter; this.orderBookFilter = orderBookFilter;
locale = Locale.ENGLISH; locale = Locale.ENGLISH;
currency = Currency.getInstance("USD"); currency = Currency.getInstance("USD");
this.storage = storage;
currency = (Currency) storage.read("Settings.currency"); currency = (Currency) storage.read("Settings.currency");
if (currency == null) if (currency == null)
@ -66,16 +70,16 @@ public class Settings
return currencies; return currencies;
} }
public ArrayList<String> getAllBankTransferTypes() public ArrayList<BankAccountType> getAllBankAccountTypes()
{ {
ArrayList<String> bankTransferTypes = new ArrayList<>(); ArrayList<BankAccountType> bankTransferTypes = new ArrayList<>();
bankTransferTypes.add("SEPA"); bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.SEPA, "IBAN", "BIC"));
bankTransferTypes.add("Wire"); bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.WIRE, "Prim_todo", "Sec_todo"));
bankTransferTypes.add("International"); bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.INTERNATIONAL, "Prim_todo", "Sec_todo"));
bankTransferTypes.add("OKPay"); bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.OK_PAY, "Prim_todo", "Sec_todo"));
bankTransferTypes.add("Netteller"); bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.NET_TELLER, "Prim_todo", "Sec_todo"));
bankTransferTypes.add("Perfect Money"); bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.PERFECT_MONEY, "Prim_todo", "Sec_todo"));
bankTransferTypes.add("Any"); bankTransferTypes.add(new BankAccountType(BankAccountType.BankAccountTypeEnum.OTHER, "Prim_todo", "Sec_todo"));
return bankTransferTypes; return bankTransferTypes;
} }
@ -184,4 +188,5 @@ public class Settings
return orderBookFilter; 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; package io.bitsquare.storage;
import io.bitsquare.user.User;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -10,17 +11,18 @@ import java.util.Map;
/** /**
* Simple storage solution for serialized data * 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 preferencesFileName = "preferences.ser";
private final String storageFile; private final String storageFile;
private DataVO dataVO; 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(); dataVO = readDataVO();
if (dataVO == null) 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) public void write(String key, Object value)
{ {
log.info("Write object with key = " + key + " / value = " + value); log.info("Write object with key = " + key + " / value = " + value);
@ -39,8 +52,6 @@ public class SimpleStorage implements IStorage
writeDataVO(dataVO); writeDataVO(dataVO);
} }
@Override
public Object read(String key) public Object read(String key)
{ {
dataVO = readDataVO(); dataVO = readDataVO();
@ -87,9 +98,14 @@ public class SimpleStorage implements IStorage
} }
return dataVO; return dataVO;
} }
} }
class DataVO implements Serializable class DataVO implements Serializable
{ {
private static final long serialVersionUID = -1127046445783201376L;
public Map<String, Object> dict; public Map<String, Object> dict;
} }

View file

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

View file

@ -2,11 +2,11 @@ package io.bitsquare.trade;
import com.google.inject.Inject; import com.google.inject.Inject;
import io.bitsquare.btc.BlockChainFacade; import io.bitsquare.btc.BlockChainFacade;
import io.bitsquare.btc.IWalletFacade;
import io.bitsquare.btc.KeyPair; import io.bitsquare.btc.KeyPair;
import io.bitsquare.crypto.ICryptoFacade; import io.bitsquare.btc.WalletFacade;
import io.bitsquare.msg.IMessageFacade; import io.bitsquare.crypto.CryptoFacade;
import io.bitsquare.msg.Message; import io.bitsquare.msg.Message;
import io.bitsquare.msg.MessageFacade;
import io.bitsquare.settings.Settings; import io.bitsquare.settings.Settings;
import io.bitsquare.user.User; import io.bitsquare.user.User;
import io.bitsquare.util.Utils; 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) * 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, Offer> offers = new HashMap<>();
private final HashMap<String, Trade> trades = new HashMap<>(); private final HashMap<String, Trade> trades = new HashMap<>();
private final HashMap<String, Contract> contracts = new HashMap<>(); private final HashMap<String, Contract> contracts = new HashMap<>();
private User user; private User user;
private IMessageFacade messageFacade; private MessageFacade messageFacade;
private BlockChainFacade blockChainFacade; private BlockChainFacade blockChainFacade;
private IWalletFacade walletFacade; private WalletFacade walletFacade;
private ICryptoFacade cryptoFacade; private CryptoFacade cryptoFacade;
private Settings settings; private Settings settings;
@Inject @Inject
public TradingFacade(User user, public Trading(User user,
Settings settings, Settings settings,
IMessageFacade messageFacade, MessageFacade messageFacade,
BlockChainFacade blockChainFacade, BlockChainFacade blockChainFacade,
IWalletFacade walletFacade, WalletFacade walletFacade,
ICryptoFacade cryptoFacade) CryptoFacade cryptoFacade)
{ {
this.user = user; this.user = user;
this.settings = settings; this.settings = settings;
@ -97,7 +97,7 @@ public class TradingFacade
String contractAsJson = Utils.convertToJson(contract); String contractAsJson = Utils.convertToJson(contract);
contract.getTrade().setJsonRepresentation(contractAsJson); 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; package io.bitsquare.trade.orderbook;
import com.google.inject.Inject; 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.trade.orderbook.OrderBookListItem;
import io.bitsquare.gui.util.Converter; import io.bitsquare.gui.util.Converter;
import io.bitsquare.gui.util.Formatter; import io.bitsquare.gui.util.Formatter;
@ -8,7 +10,6 @@ import io.bitsquare.settings.Settings;
import io.bitsquare.trade.Direction; import io.bitsquare.trade.Direction;
import io.bitsquare.trade.Offer; import io.bitsquare.trade.Offer;
import io.bitsquare.trade.OfferConstraints; import io.bitsquare.trade.OfferConstraints;
import io.bitsquare.user.BankDetails;
import io.bitsquare.user.User; import io.bitsquare.user.User;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
@ -17,13 +18,13 @@ import javafx.collections.transformation.FilteredList;
import java.util.*; import java.util.*;
import java.util.function.Predicate; import java.util.function.Predicate;
public class MockOrderBook implements IOrderBook public class OrderBook
{ {
private ObservableList<OrderBookListItem> orderBookListItems; private ObservableList<OrderBookListItem> orderBookListItems;
private Settings settings; private Settings settings;
@Inject @Inject
public MockOrderBook(Settings settings) public OrderBook(Settings settings)
{ {
this.settings = settings; this.settings = settings;
orderBookListItems = FXCollections.observableArrayList(); orderBookListItems = FXCollections.observableArrayList();
@ -33,7 +34,6 @@ public class MockOrderBook implements IOrderBook
} }
} }
@Override
public ObservableList<OrderBookListItem> getFilteredList(OrderBookFilter orderBookFilter) public ObservableList<OrderBookListItem> getFilteredList(OrderBookFilter orderBookFilter)
{ {
FilteredList filtered = orderBookListItems.filtered(new Predicate<OrderBookListItem>() FilteredList filtered = orderBookListItems.filtered(new Predicate<OrderBookListItem>()
@ -100,10 +100,13 @@ public class MockOrderBook implements IOrderBook
minAmount = Converter.convertToDouble(Formatter.formatAmount(minAmount)); minAmount = Converter.convertToDouble(Formatter.formatAmount(minAmount));
String country = getCountries().get(0); String country = getCountries().get(0);
BankDetails bankDetails = new BankDetails(); BankAccountType bankAccountType = getBankTransferTypes().get(0);
String bankTransferType = getBankTransferTypes().get(0); BankAccount bankAccount = new BankAccount(bankAccountType);
bankDetails.setBankTransferType(bankTransferType); User offerer = new User();
User offerer = new User(UUID.randomUUID().toString(), UUID.randomUUID().toString(), country, bankDetails); offerer.setAccountID(UUID.randomUUID().toString());
offerer.setMessageID(UUID.randomUUID().toString());
offerer.setCountry(country);
offerer.addBankAccount(bankAccount);
Direction direction = Direction.BUY; Direction direction = Direction.BUY;
double price = 500 + Math.random() * 50; double price = 500 + Math.random() * 50;
@ -148,9 +151,9 @@ public class MockOrderBook implements IOrderBook
return randomizeStrings(settings.getAllLanguages(), false); 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() private List<String> getArbitrators()
@ -163,6 +166,15 @@ public class MockOrderBook implements IOrderBook
return randomizeStrings(settings.getAllCollaterals(), false); 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) 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 com.google.inject.Inject;
import io.bitsquare.btc.BlockChainFacade; import io.bitsquare.btc.BlockChainFacade;
import io.bitsquare.btc.IWalletFacade; import io.bitsquare.btc.WalletFacade;
import io.bitsquare.msg.IMessageFacade; import io.bitsquare.msg.MessageFacade;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class PaymentProcess public class PaymentProcess
{ {
private static final Logger log = LoggerFactory.getLogger(PaymentProcess.class); private static final Logger log = LoggerFactory.getLogger(PaymentProcess.class);
private IMessageFacade messageService; private MessageFacade messageService;
private BlockChainFacade bitcoinServices; private BlockChainFacade bitcoinServices;
protected String offererDepositPubKey; protected String offererDepositPubKey;
@ -26,20 +26,20 @@ public class PaymentProcess
protected String takerOutputPayment; protected String takerOutputPayment;
protected String multiSigAddress; protected String multiSigAddress;
private IWalletFacade wallet; private WalletFacade wallet;
public PaymentProcess() public PaymentProcess()
{ {
} }
@Inject @Inject
public void setMessageService(IMessageFacade messageService) public void setMessageService(MessageFacade messageService)
{ {
this.messageService = messageService; this.messageService = messageService;
} }
@Inject @Inject
public void setWallet(IWalletFacade wallet) public void setWallet(WalletFacade wallet)
{ {
this.wallet = 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; 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 accountID;
private String messageID; private String messageID;
private boolean isOnline; private boolean online;
private BankDetails bankDetails; private BankAccount currentBankAccount = null;
private String country;
public User(String accountID, String messageID, String country, BankDetails bankDetails) private Map<String, BankAccount> bankAccounts = new HashMap<>();
{ private String country;
this.accountID = accountID;
this.messageID = messageID;
this.country = country;
this.bankDetails = bankDetails;
}
public User() 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() public String getMessageID()
{ {
return messageID; return messageID;
@ -50,25 +98,15 @@ public class User
return country; return country;
} }
public BankAccount getCurrentBankAccount()
public BankDetails getBankDetails()
{ {
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"));
}
}