Merge branch 'develop' of github.com:Agorise/crystal-wallet-android into develop

This commit is contained in:
Severiano Jaramillo 2018-11-28 16:24:19 -06:00
commit 0dd9aecbf3
22 changed files with 366 additions and 254 deletions

View file

@ -22,8 +22,8 @@ android {
applicationId "cy.agorise.crystalwallet"
minSdkVersion 21
targetSdkVersion 27
versionCode 4
versionName "0.4M.alpha"
versionCode 5
versionName "0.5M.alpha"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
@ -87,6 +87,7 @@ dependencies {
implementation 'com.jakewharton:butterknife:8.8.1'
implementation 'com.github.bilthon:graphenej:0.4.6'
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
implementation 'com.github.sjaramillo10:AnimatedTabLayout:1.0.3'
implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0'
@ -125,4 +126,7 @@ dependencies {
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
debugImplementation 'com.amitshekhar.android:debug-db:1.0.4'
implementation 'com.google.zxing:core:3.2.1'
implementation 'com.journeyapps:zxing-android-embedded:3.2.0@aar'
}

View file

@ -17,6 +17,7 @@ import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
import cy.agorise.crystalwallet.fragments.ImportAccountOptionsFragment;
import cy.agorise.crystalwallet.viewmodels.AccountSeedListViewModel;
@ -69,6 +70,9 @@ public class IntroActivity extends CustomActivity {
}
} );
this.getApplication().registerActivityLifecycleCallbacks(CrystalSecurityMonitor.getInstance(this));
//Checks if the user has any seed created
AccountSeedListViewModel accountSeedListViewModel = ViewModelProviders.of(this).get(AccountSeedListViewModel.class);

View file

@ -219,7 +219,7 @@ public abstract class BitsharesFaucetApiGenerator {
public interface IWebService {
@Headers({"Content-Type: application/json"})
@POST("/api/v1/accounts")
@POST("/faucet/api/v1/accounts")
Call<RegisterAccountResponse> getReg(@Body Map<String, HashMap> params);
}

View file

@ -75,7 +75,7 @@ public class InsightApiGenerator {
GetEstimateFee.getEstimateFee(CryptoNetManager.getURL(cryptoCoin.getCryptoNet()),
new GetEstimateFee.estimateFeeListener() {
@Override
public void estimateFee(long value) {
public void estimateFee(double value) {
request.listener.success(value,request.getId());
}

View file

@ -65,9 +65,14 @@ public class BroadcastTransaction extends Thread implements Callback<Txi> {
*/
@Override
public void run() {
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
Call<Txi> broadcastTransaction = service.broadcastTransaction(this.mPath,this.mRawTx);
broadcastTransaction.enqueue(this);
try {
InsightApiService service = this.mServiceGenerator.getService(InsightApiService.class);
Call<Txi> broadcastTransaction = service.broadcastTransaction(this.mPath, this.mRawTx);
broadcastTransaction.enqueue(this);
}catch(Exception e){
e.printStackTrace();
}
}
public interface BroadCastTransactionListener{

View file

@ -35,7 +35,7 @@ public abstract class GetEstimateFee {
call.enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
listener.estimateFee((long) (response.body().get("2").getAsDouble()));
listener.estimateFee((double) (response.body().get("2").getAsDouble()));
}
@ -46,12 +46,13 @@ public abstract class GetEstimateFee {
}
});
}catch(Exception e){
e.printStackTrace();
listener.fail();
}
}
public static interface estimateFeeListener{
public void estimateFee(long value);
public void estimateFee(double value);
public void fail();
}

View file

@ -52,8 +52,10 @@ public class CrystalApplication extends Application {
public static final String BITCOIN_SERVER_URLS[] ={
"https://insight.bitpay.com/",
"https://testnet.blockexplorer.com/"
"https://test-insight.bitpay.com",
//"https://testnet.blockexplorer.com/",
//"https://insight.bitpay.com/"
};
public static final CryptoCurrency BITCOIN_CURRENCY = new CryptoCurrency("BTC",CryptoNet.BITCOIN,8);
@ -135,6 +137,11 @@ public class CrystalApplication extends Application {
resources.updateConfiguration(configuration, dm);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
Intent intent = new Intent(getApplicationContext(), CrystalWalletService.class);
startService(intent);
}

View file

@ -175,6 +175,8 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
if(onResponsePattern != null){
PatternRequestActivity.setOnResponse(onResponsePattern);
}
} else {
onResponsePattern.onSuccess();
}
if (intent != null) {
intent.putExtra("ACTIVITY_TYPE", "PASSWORD_REQUEST");

View file

@ -72,10 +72,10 @@ public abstract class CrystalDatabase extends RoomDatabase {
Room.databaseBuilder(context,
CrystalDatabase.class, "CrystalWallet.db")
.allowMainThreadQueries()
.addMigrations(MIGRATION_2_3)
.addMigrations(MIGRATION_3_4)
.addMigrations(MIGRATION_4_5)
.addMigrations(MIGRATION_5_6)
//.addMigrations(MIGRATION_2_3)
//.addMigrations(MIGRATION_3_4)
//.addMigrations(MIGRATION_4_5)
//.addMigrations(MIGRATION_5_6)
.build();
}
return instance;

View file

@ -27,6 +27,7 @@ import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
@ -35,6 +36,7 @@ import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.journeyapps.barcodescanner.BarcodeEncoder;
import butterknife.OnClick;
import cy.agorise.crystalwallet.enums.CryptoCoin;
@ -84,6 +86,8 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
TextView tvAssetError;
@BindView(R.id.ivQrCode)
ImageView ivQrCode;
@BindView(R.id.pbQrCode)
ProgressBar pbQrCode;
@BindView(R.id.tvCancel)
TextView tvCancel;
@ -106,6 +110,8 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
private AsyncTask qrCodeTask;
private Double lastAmount = -1.0;
public static ReceiveTransactionFragment newInstance(long cryptoNetAccountId) {
ReceiveTransactionFragment f = new ReceiveTransactionFragment();
@ -337,144 +343,147 @@ public class ReceiveTransactionFragment extends DialogFragment implements UIVali
}
public void createQrCode(){
Double amount = 0.0;
final Double amount;
try{
amount = Double.valueOf(this.etAmount.getText().toString());
} catch(NumberFormatException e){
lastAmount = -1.0;
Log.e("ReceiveFragment","Amount casting error.");
return;
}
CryptoNetAccount toAccountSelected = (CryptoNetAccount) spTo.getSelectedItem();
if (this.cryptoNetAccount.getCryptoNet() == CryptoNet.BITSHARES) {
/*
* this is only for graphene accounts.
*
**/
GrapheneAccount grapheneAccountSelected = new GrapheneAccount(toAccountSelected);
grapheneAccountSelected.loadInfo(db.grapheneAccountInfoDao().getByAccountId(toAccountSelected.getId()));
this.invoiceItems.clear();
this.invoiceItems.add(
new LineItem("transfer", 1, amount)
);
LineItem items[] = new LineItem[this.invoiceItems.size()];
items = this.invoiceItems.toArray(items);
this.invoice.setLineItems(items);
this.invoice.setTo(grapheneAccountSelected.getName());
this.invoice.setCurrency(this.cryptoCurrency.getName());
if (!amount.equals(lastAmount)) {
pbQrCode.setVisibility(View.VISIBLE);
lastAmount = amount;
CryptoNetAccount toAccountSelected = (CryptoNetAccount) spTo.getSelectedItem();
if (this.qrCodeTask != null) {
this.qrCodeTask.cancel(true);
}
this.qrCodeTask = new AsyncTask<Object, Void, Void>() {
if (this.cryptoNetAccount.getCryptoNet() == CryptoNet.BITSHARES) {
/*
* this is only for graphene accounts.
*
**/
GrapheneAccount grapheneAccountSelected = new GrapheneAccount(toAccountSelected);
grapheneAccountSelected.loadInfo(db.grapheneAccountInfoDao().getByAccountId(toAccountSelected.getId()));
@Override
protected Void doInBackground(Object... voids) {
try {
final Bitmap bitmap = textToImageEncode(Invoice.toQrCode(invoice));
if (!this.isCancelled()) {
ReceiveTransactionFragment.this.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
ivQrCode.setImageBitmap(bitmap);
}
});
}
} catch (WriterException e) {
Log.e("ReceiveFragment", "Error creating QrCode");
}
return null;
}
};
this.invoiceItems.clear();
this.invoiceItems.add(
new LineItem("transfer", 1, amount)
);
this.qrCodeTask.execute(null, null, null);
} else {
final CryptoCoin cryptoCoin = CryptoCoin.getByCryptoNet(this.cryptoNetAccount.getCryptoNet()).get(0);
LineItem items[] = new LineItem[this.invoiceItems.size()];
items = this.invoiceItems.toArray(items);
this.invoice.setLineItems(items);
this.invoice.setTo(grapheneAccountSelected.getName());
this.invoice.setCurrency(this.cryptoCurrency.getName());
//final NextBitcoinAccountAddressRequest addressRequest = new NextBitcoinAccountAddressRequest(this.cryptoNetAccount, cryptoCoin, getContext());
//if (this.qrCodeTask != null) {
// this.qrCodeTask.cancel(true);
//}
//addressRequest.setListener(new CryptoNetInfoRequestListener() {
// @Override
// public void onCarryOut() {
// if (addressRequest.getStatus() == NextBitcoinAccountAddressRequest.StatusCode.SUCCEEDED){
final CalculateBitcoinUriRequest uriRequest = new CalculateBitcoinUriRequest(cryptoCoin, cryptoNetAccount, getContext(), amount);
this.qrCodeTask = new AsyncTask<Object, Void, Void>() {
uriRequest.setListener(new CryptoNetInfoRequestListener(){
@Override
public void onCarryOut(){
if (uriRequest.getUri() != null){
qrCodeTask = new AsyncTask<Object, Void, Void>() {
@Override
protected Void doInBackground(Object... voids) {
try {
final Bitmap bitmap = textToImageEncode(Invoice.toQrCode(invoice));
@Override
protected Void doInBackground(Object... voids) {
try {
final Bitmap bitmap = textToImageEncode(uriRequest.getUri());
if (!this.isCancelled()) {
ReceiveTransactionFragment.this.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
ivQrCode.setImageBitmap(bitmap);
}
});
}
} catch (WriterException e) {
Log.e("ReceiveFragment", "Error creating QrCode");
}
return null;
}
};
qrCodeTask.execute(null, null, null);
} else {
Log.e("ReceiveFragment", "Error obtaining the uri");
}
if (!this.isCancelled()) {
ReceiveTransactionFragment.this.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
ivQrCode.setImageBitmap(bitmap);
pbQrCode.setVisibility(View.GONE);
}
});
}
});
} catch (WriterException e) {
Log.e("ReceiveFragment", "Error creating QrCode");
}
return null;
}
};
this.qrCodeTask.execute(null, null, null);
} else {
final CryptoCoin cryptoCoin = CryptoCoin.getByCryptoNet(this.cryptoNetAccount.getCryptoNet()).get(0);
final CalculateBitcoinUriRequest uriRequest = new CalculateBitcoinUriRequest(cryptoCoin, cryptoNetAccount, getContext(), amount);
uriRequest.setListener(new CryptoNetInfoRequestListener() {
@Override
public void onCarryOut() {
if (uriRequest.getUri() != null) {
qrCodeTask = new AsyncTask<Object, Void, Void>() {
@Override
protected Void doInBackground(Object... voids) {
try {
final Bitmap bitmap = textToImageEncode(uriRequest.getUri());
if (!this.isCancelled()) {
ReceiveTransactionFragment.this.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
//Double amountNow = -1.0;
//try{
// amountNow = Double.valueOf(etAmount.getText().toString());
//} catch(NumberFormatException e){
//}
//if (amountNow >= 0) {
if (amount.equals(lastAmount)) {
if (!isCancelled()) {
ivQrCode.setImageBitmap(bitmap);
pbQrCode.setVisibility(View.GONE);
}
}
//}
}
});
}
} catch (WriterException e) {
Log.e("ReceiveFragment", "Error creating QrCode");
}
return null;
}
};
qrCodeTask.execute(null, null, null);
} else {
Log.e("ReceiveFragment", "Error obtaining the uri");
}
}
});
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
CryptoNetInfoRequests.getInstance().addRequest(uriRequest);
// } else {
// Toast.makeText(getContext(),"Error creating address",Toast.LENGTH_SHORT);
// }
// }
//});
}
});
thread.start();
}
}
}
Bitmap textToImageEncode(String Value) throws WriterException {
//TODO: do this in another thread
BitMatrix bitMatrix;
Bitmap bitmap = null;
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
try {
bitMatrix = new MultiFormatWriter().encode(
Value,
BarcodeFormat.DATA_MATRIX.QR_CODE,
ivQrCode.getWidth(), ivQrCode.getHeight(), null
);
} catch (IllegalArgumentException Illegalargumentexception) {
return null;
}
int bitMatrixWidth = bitMatrix.getWidth();
int bitMatrixHeight = bitMatrix.getHeight();
int[] pixels = new int[bitMatrixWidth * bitMatrixHeight];
for (int y = 0; y < bitMatrixHeight; y++) {
int offset = y * bitMatrixWidth;
for (int x = 0; x < bitMatrixWidth; x++) {
pixels[offset + x] = bitMatrix.get(x, y) ?
getResources().getColor(R.color.QRCodeBlackColor):getResources().getColor(R.color.QRCodeWhiteColor);
}
BitMatrix bitMatrix = multiFormatWriter.encode(Value, BarcodeFormat.QR_CODE, ivQrCode.getWidth(), ivQrCode.getHeight());
BarcodeEncoder barcodeEncoder = new BarcodeEncoder();
bitmap = barcodeEncoder.createBitmap(bitMatrix);
} catch (WriterException e) {
e.printStackTrace();
}
Bitmap bitmap = Bitmap.createBitmap(bitMatrixWidth, bitMatrixHeight, Bitmap.Config.ARGB_4444);
bitmap.setPixels(pixels, 0, ivQrCode.getWidth(), 0, 0, bitMatrixWidth, bitMatrixHeight);
return bitmap;
}
}

View file

@ -591,7 +591,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
/*
* If exists mode scurity show it and valide events in case of success or fail
* */
CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity(), new OnResponse() {
CrystalSecurityMonitor.getInstance(this.getActivity()).callPasswordRequest(this.getActivity(), new OnResponse() {
@Override
public void onSuccess() {
@ -611,6 +611,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
}
});
//CryptoNetInfoRequests.getInstance().addRequest(sendRequest);
}
}

View file

@ -90,6 +90,11 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(fetch)[0];
fetch.setId(idAccount);
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(fetch));
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
if(seed.getName() == null || seed.getName().isEmpty()){
seed.setName(grapheneAccount.getName());
db.accountSeedDao().insertAccountSeed(seed);
}
subscribeBitsharesAccount(fetch.getId(),fetch.getAccountId(),context);
request.success(fetch);
}
@ -130,6 +135,11 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
long[] idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount);
grapheneAccount.setId(idAccount[0]);
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
if(seed.getName() == null || seed.getName().isEmpty()){
seed.setName(grapheneAccount.getName());
db.accountSeedDao().insertAccountSeed(seed);
}
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
}
@ -149,6 +159,11 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount)[0];
grapheneAccount.setId(idAccount);
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
if(seed.getName() == null || seed.getName().isEmpty()){
seed.setName(grapheneAccount.getName());
db.accountSeedDao().insertAccountSeed(seed);
}
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
}
@ -162,6 +177,11 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(grapheneAccount)[0];
grapheneAccount.setId(idAccount);
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(new GrapheneAccountInfo(grapheneAccount));
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
if(seed.getName() == null || seed.getName().isEmpty()){
seed.setName(grapheneAccount.getName());
db.accountSeedDao().insertAccountSeed(seed);
}
subscribeBitsharesAccount(grapheneAccount.getId(), grapheneAccount.getAccountId(), context);
}
}
@ -182,6 +202,11 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
info.setAccountId(fetch.getAccountId());
grapheneAccount.setAccountId(fetch.getAccountId());
db.grapheneAccountInfoDao().insertGrapheneAccountInfo(info);
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
if(seed.getName() == null || seed.getName().isEmpty()){
seed.setName(grapheneAccount.getName());
db.accountSeedDao().insertAccountSeed(seed);
}
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
}
@ -212,6 +237,11 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
}
});
}else{
AccountSeed seed = db.accountSeedDao().findById(grapheneAccount.getSeedId());
if(seed.getName() == null || seed.getName().isEmpty()){
seed.setName(grapheneAccount.getName());
db.accountSeedDao().insertAccountSeed(seed);
}
subscribeBitsharesAccount(grapheneAccount.getId(),grapheneAccount.getAccountId(),context);
}
}

View file

@ -327,7 +327,6 @@ public class FileBackupManager implements FileServiceRequestsListener {
public static byte[] decompress(byte[] inputBytes, int which) {
InputStream in = null;
try {
System.out.println("Bytes: "+Util.bytesToHex(inputBytes));
ByteArrayInputStream input = new ByteArrayInputStream(inputBytes);
ByteArrayOutputStream output = new ByteArrayOutputStream(16*2048);
if(which == Util.XZ) {

View file

@ -98,7 +98,19 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
new ChildNumber(1, false));
CryptoCoinBalance balance = new CryptoCoinBalance();
balance.setBalance(0);
long amount = 0;
List<CryptoCoinTransaction> trransactions = db.transactionDao().getByIdAccount(account.getId());
for(CryptoCoinTransaction transaction : trransactions){
if(transaction.isConfirmed()){
if(transaction.getInput()){
amount += transaction.getAmount();
}else{
amount -= transaction.getAmount();
}
}
}
balance.setBalance(amount);
balance.setCryptoCurrencyId(db.cryptoCurrencyDao().getByName(cryptoCoin.getLabel(),cryptoCoin.name()).getId());
balance.setAccountId(account.getId());
db.cryptoCoinBalanceDao().insertCryptoCoinBalance(balance);
@ -115,7 +127,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
address.setChange(false);
address.setAccountId(account.getId());
address.setIndex(0);
String addressString =externalAddrKey.toAddress(this.cryptoCoin.getParameters()).toString();
String addressString = externalAddrKey.toAddress(this.cryptoCoin.getParameters()).toString();
address.setAddress(addressString);
db.bitcoinAddressDao().insertBitcoinAddresses(address);
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,addressString,true,
@ -149,6 +161,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
//if(Arrays.asList(SUPPORTED_COINS).contains(request.getCoin())){
if(request.getCoin().equals(this.cryptoCoin)){
if(request instanceof BitcoinSendRequest) {
this.send((BitcoinSendRequest) request);
}else if(request instanceof CreateBitcoinAccountRequest){
this.createGeneralAccount((CreateBitcoinAccountRequest) request);
}else if(request instanceof NextBitcoinAccountAddressRequest){
@ -171,134 +184,141 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
* @param txi
*/
public void processTxi(Txi txi){
CrystalDatabase db = CrystalDatabase.getAppDatabase(this.context);
List<BitcoinTransaction> btTransactions = db.bitcoinTransactionDao().getTransactionsByTxid(txi.txid);
if(!btTransactions.isEmpty()){
for(BitcoinTransaction btTransaction : btTransactions) {
btTransaction.setConfirmations(txi.confirmations);
CryptoCoinTransaction ccTransaction = db.transactionDao().getById(btTransaction.getCryptoCoinTransactionId());
if (!ccTransaction.isConfirmed() && btTransaction.getConfirmations() >= cryptoCoin.getCryptoNet().getConfirmationsNeeded()) {
ccTransaction.setConfirmed(true);
db.transactionDao().insertTransaction(ccTransaction);
updateBalance(ccTransaction,(ccTransaction.getInput()?1:-1)*ccTransaction.getAmount(),db);
}
try {
System.out.println("GeneralAccountManager processingTxi " + txi.txid);
CrystalDatabase db = CrystalDatabase.getAppDatabase(this.context);
List<BitcoinTransaction> btTransactions = db.bitcoinTransactionDao().getTransactionsByTxid(txi.txid);
if (!btTransactions.isEmpty()) {
System.out.println("GeneralAccountManager Transaction not null " + txi.txid);
for (BitcoinTransaction btTransaction : btTransactions) {
btTransaction.setConfirmations(txi.confirmations);
CryptoCoinTransaction ccTransaction = db.transactionDao().getById(btTransaction.getCryptoCoinTransactionId());
if (!ccTransaction.isConfirmed() && btTransaction.getConfirmations() >= cryptoCoin.getCryptoNet().getConfirmationsNeeded()) {
ccTransaction.setConfirmed(true);
db.transactionDao().insertTransaction(ccTransaction);
updateBalance(ccTransaction, (ccTransaction.getInput() ? 1 : -1) * ccTransaction.getAmount(), db);
}
db.bitcoinTransactionDao().insertBitcoinTransaction(btTransaction);
}
}else {
db.bitcoinTransactionDao().insertBitcoinTransaction(btTransaction);
}
} else {
/*List<CryptoCoinTransaction> ccTransactions = new ArrayList();
btTransactions = new ArrayList();*/ //TODO transactions involving multiples accounts
CryptoCoinTransaction ccTransaction = new CryptoCoinTransaction();
BitcoinTransaction btTransaction = new BitcoinTransaction();
btTransaction.setTxId(txi.txid);
btTransaction.setBlock(txi.blockheight);
btTransaction.setFee((long) (txi.fee * Math.pow(10, cryptoCoin.getPrecision())));
btTransaction.setConfirmations(txi.confirmations);
ccTransaction.setDate(new Date(txi.time * 1000));
if(txi.txlock || txi.confirmations >= cryptoCoin.getCryptoNet().getConfirmationsNeeded()) {
ccTransaction.setConfirmed(true);
}else{
ccTransaction.setConfirmed(false);
}
ccTransaction.setInput(false);
long amount = 0;
//transaction.setAccount(this.mAccount);
//transaction.setType(cryptoCoin);
List<BitcoinTransactionGTxIO> gtxios = new ArrayList();
for (Vin vin : txi.vin) {
BitcoinTransactionGTxIO input = new BitcoinTransactionGTxIO();
String addr = vin.addr;
input.setAddress(addr);
input.setIndex(vin.n);
input.setOutput(true);
input.setAmount((long) (vin.value * Math.pow(10, cryptoCoin.getPrecision())));
input.setOriginalTxId(vin.txid);
input.setScriptHex(vin.scriptSig.hex);
BitcoinAddress address = db.bitcoinAddressDao().getdadress(addr);
if(address != null){
if(ccTransaction.getAccountId() < 0){
ccTransaction.setAccountId(address.getAccountId());
ccTransaction.setFrom(addr);
ccTransaction.setInput(false);
}
if(ccTransaction.getAccountId()== address.getAccountId()){
amount -= vin.value;
}
}
if(ccTransaction.getFrom() == null || ccTransaction.getFrom().isEmpty()){
ccTransaction.setFrom(addr);
}
gtxios.add(input);
}
for (Vout vout : txi.vout) {
if (vout.scriptPubKey.addresses == null || vout.scriptPubKey.addresses.length <= 0) {
CryptoCoinTransaction ccTransaction = new CryptoCoinTransaction();
BitcoinTransaction btTransaction = new BitcoinTransaction();
btTransaction.setTxId(txi.txid);
btTransaction.setBlock(txi.blockheight);
btTransaction.setFee((long) (txi.fee * Math.pow(10, cryptoCoin.getPrecision())));
btTransaction.setConfirmations(txi.confirmations);
ccTransaction.setDate(new Date(txi.time * 1000));
if (txi.txlock || txi.confirmations >= cryptoCoin.getCryptoNet().getConfirmationsNeeded()) {
ccTransaction.setConfirmed(true);
} else {
BitcoinTransactionGTxIO output = new BitcoinTransactionGTxIO();
String addr = vout.scriptPubKey.addresses[0];
output.setAddress(addr);
output.setIndex(vout.n);
output.setOutput(false);
output.setAmount((long) (vout.value * Math.pow(10, cryptoCoin.getPrecision())));
output.setScriptHex(vout.scriptPubKey.hex);
output.setOriginalTxId(txi.txid);
ccTransaction.setConfirmed(false);
}
ccTransaction.setInput(false);
long amount = 0;
//transaction.setAccount(this.mAccount);
//transaction.setType(cryptoCoin);
List<BitcoinTransactionGTxIO> gtxios = new ArrayList();
for (Vin vin : txi.vin) {
BitcoinTransactionGTxIO input = new BitcoinTransactionGTxIO();
String addr = vin.addr;
input.setAddress(addr);
input.setIndex(vin.n);
input.setOutput(true);
input.setAmount((long) (vin.value * Math.pow(10, cryptoCoin.getPrecision())));
input.setOriginalTxId(vin.txid);
input.setScriptHex(vin.scriptSig.hex);
gtxios.add(output);
BitcoinAddress address = db.bitcoinAddressDao().getdadress(addr);
if(address != null){
if(ccTransaction.getAccountId() < 0){
if (address != null) {
if (ccTransaction.getAccountId() < 0) {
ccTransaction.setAccountId(address.getAccountId());
ccTransaction.setInput(true);
ccTransaction.setTo(addr);
ccTransaction.setFrom(addr);
ccTransaction.setInput(false);
}
if(ccTransaction.getAccountId()== address.getAccountId()){
amount += vout.value;
if (ccTransaction.getAccountId() == address.getAccountId()) {
amount -= (long) (vin.value * Math.pow(10, cryptoCoin.getPrecision()));
}
}else{
//TOOD multiple send address
if(ccTransaction.getTo() == null || ccTransaction.getTo().isEmpty()){
ccTransaction.setTo(addr);
}
if (ccTransaction.getFrom() == null || ccTransaction.getFrom().isEmpty()) {
ccTransaction.setFrom(addr);
}
gtxios.add(input);
}
for (Vout vout : txi.vout) {
if (vout.scriptPubKey.addresses == null || vout.scriptPubKey.addresses.length <= 0) {
} else {
BitcoinTransactionGTxIO output = new BitcoinTransactionGTxIO();
String addr = vout.scriptPubKey.addresses[0];
output.setAddress(addr);
output.setIndex(vout.n);
output.setOutput(false);
output.setAmount((long) (vout.value * Math.pow(10, cryptoCoin.getPrecision())));
output.setScriptHex(vout.scriptPubKey.hex);
output.setOriginalTxId(txi.txid);
gtxios.add(output);
BitcoinAddress address = db.bitcoinAddressDao().getdadress(addr);
if (address != null) {
if (ccTransaction.getAccountId() < 0) {
ccTransaction.setAccountId(address.getAccountId());
ccTransaction.setInput(true);
ccTransaction.setTo(addr);
}
if (ccTransaction.getAccountId() == address.getAccountId()) {
amount += (long) (vout.value * Math.pow(10, cryptoCoin.getPrecision()));
}
} else {
//TOOD multiple send address
if (ccTransaction.getTo() == null || ccTransaction.getTo().isEmpty()) {
ccTransaction.setTo(addr);
}
}
}
}
}
ccTransaction.setAmount(amount);
CryptoCurrency currency = db.cryptoCurrencyDao().getByNameAndCryptoNet(this.cryptoCoin.name(), this.cryptoCoin.getCryptoNet().name());
if (currency == null) {
currency = new CryptoCurrency();
currency.setCryptoNet(this.cryptoCoin.getCryptoNet());
currency.setName(this.cryptoCoin.name());
currency.setPrecision(this.cryptoCoin.getPrecision());
long idCurrency = db.cryptoCurrencyDao().insertCryptoCurrency(currency)[0];
currency.setId(idCurrency);
}
ccTransaction.setAmount(amount);
CryptoCurrency currency = db.cryptoCurrencyDao().getByNameAndCryptoNet(this.cryptoCoin.getLabel(), this.cryptoCoin.getCryptoNet().name());
if (currency == null) {
currency = new CryptoCurrency();
currency.setCryptoNet(this.cryptoCoin.getCryptoNet());
currency.setName(this.cryptoCoin.getLabel());
currency.setPrecision(this.cryptoCoin.getPrecision());
long idCurrency = db.cryptoCurrencyDao().insertCryptoCurrency(currency)[0];
currency.setId(idCurrency);
}
ccTransaction.setIdCurrency((int)currency.getId());
ccTransaction.setIdCurrency((int) currency.getId());
long ccId = db.transactionDao().insertTransaction(ccTransaction)[0];
btTransaction.setCryptoCoinTransactionId(ccId);
long btId = db.bitcoinTransactionDao().insertBitcoinTransaction(btTransaction)[0];
for(BitcoinTransactionGTxIO gtxio : gtxios){
gtxio.setBitcoinTransactionId(btId);
db.bitcoinTransactionDao().insertBitcoinTransactionGTxIO(gtxio);
}
long ccId = db.transactionDao().insertTransaction(ccTransaction)[0];
btTransaction.setCryptoCoinTransactionId(ccId);
long btId = db.bitcoinTransactionDao().insertBitcoinTransaction(btTransaction)[0];
for (BitcoinTransactionGTxIO gtxio : gtxios) {
gtxio.setBitcoinTransactionId(btId);
db.bitcoinTransactionDao().insertBitcoinTransactionGTxIO(gtxio);
}
if(ccTransaction.isConfirmed()) {
updateBalance(ccTransaction,amount,db);
if (ccTransaction.isConfirmed()) {
updateBalance(ccTransaction, amount, db);
}
}
}catch(Exception e){
e.printStackTrace();
}
}
@ -318,11 +338,11 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
}
private void updateBalance(CryptoCoinTransaction ccTransaction, long amount, CrystalDatabase db){
CryptoCurrency currency = db.cryptoCurrencyDao().getByNameAndCryptoNet(this.cryptoCoin.name(), this.cryptoCoin.getCryptoNet().name());
CryptoCurrency currency = db.cryptoCurrencyDao().getByNameAndCryptoNet(this.cryptoCoin.getLabel(), this.cryptoCoin.getCryptoNet().name());
if (currency == null) {
currency = new CryptoCurrency();
currency.setCryptoNet(this.cryptoCoin.getCryptoNet());
currency.setName(this.cryptoCoin.name());
currency.setName(this.cryptoCoin.getLabel());
currency.setPrecision(this.cryptoCoin.getPrecision());
long idCurrency = db.cryptoCurrencyDao().insertCryptoCurrency(currency)[0];
currency.setId(idCurrency);
@ -360,7 +380,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
Transaction tx = new Transaction(cryptoCoin.getParameters());
long currentAmount = 0;
long fee = -1;
long feeRate = (Long) answer;
long feeRate = (long)(((double)answer) * Math.pow(10,cryptoCoin.getPrecision()));
fee = 226 * feeRate;
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
@ -535,7 +555,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
System.out.println("GeneralAccountMAnager uri calculated : " + uri.toString());
request.setUri(uri.toString());
request.validate();
//request.validate();
}
private void parseUri(BitcoinUriParseRequest request){

View file

@ -20,9 +20,13 @@ import cy.agorise.crystalwallet.enums.CryptoCoin;
*/
@Entity(
tableName="crypto_coin_transaction",
primaryKeys = {
},
indices={
@Index(value={"account_id"}),
@Index(value={"id_currency"})
@Index(value={"id_currency"}),
@Index(value={"date", "account_id", "id_currency", "from", "to"},unique=true)
},
foreignKeys = {
@ForeignKey(

View file

@ -23,7 +23,7 @@ public class BitcoinCryptoNetVerifier extends CryptoNetVerifier{
CryptoNetManager.verifiedCryptoNetURL(cryptoCoin.getCryptoNet(), url, System.currentTimeMillis() - startTime);
}else{
System.out.println("BitcoinCryptoNetVerifier bad genesis block " + value);
System.out.println("BitcoinCryptoNetVerifier bad genesis block " + value + " " + url);
}
//TODO bad genesis block
}else{

View file

@ -32,7 +32,6 @@ public abstract class CryptoNetManager {
public static String getURL(CryptoNet crypto, int index){
if(TestedURLs.containsKey(crypto) && TestedURLs.get(crypto).size()>index){
System.out.println("Servers url list " + Arrays.toString(TestedURLs.get(crypto).toArray()));
return TestedURLs.get(crypto).get(index).getUrl();
}
System.out.println("Servers " + crypto.getLabel()+" dioesn't have testedurl");

View file

@ -38,7 +38,6 @@ public class GetChainId extends BaseGrapheneHandler {
@Override
public void onTextFrame(WebSocket websocket, WebSocketFrame frame) throws Exception {
System.out.println("<<< "+frame.getPayloadText());
String response = frame.getPayloadText();
Type GetChainIdResponse = new TypeToken<WitnessResponse<String>>(){}.getType();
@ -55,7 +54,5 @@ public class GetChainId extends BaseGrapheneHandler {
@Override
public void onFrameSent(WebSocket websocket, WebSocketFrame frame) throws Exception {
if(frame.isTextFrame())
System.out.println(">>> "+frame.getPayloadText());
}
}

View file

@ -38,7 +38,6 @@ public class GetDatabaseVersion extends BaseGrapheneHandler {
@Override
public void onTextFrame(WebSocket websocket, WebSocketFrame frame) throws Exception {
System.out.println("<<< "+frame.getPayloadText());
String response = frame.getPayloadText();
Type GetChainIdResponse = new TypeToken<WitnessResponse<String>>(){}.getType();
@ -55,8 +54,6 @@ public class GetDatabaseVersion extends BaseGrapheneHandler {
@Override
public void onFrameSent(WebSocket websocket, WebSocketFrame frame) throws Exception {
if(frame.isTextFrame())
System.out.println(">>> "+frame.getPayloadText());
}
public class VersionResponse{

View file

@ -5,6 +5,8 @@ import android.widget.Spinner;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.crystalwallet.models.CryptoCoinBalance;
import cy.agorise.crystalwallet.models.CryptoCurrency;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
@ -29,7 +31,12 @@ public class AmountValidationField extends ValidationField {
public void validate(){
try {
final float newAmountValue = Float.parseFloat(amountField.getText().toString());
final CryptoCurrency cryptoCurrency = (CryptoCurrency)assetSpinner.getSelectedItem();
final CryptoCurrency cryptoCurrency;
if(this.account.getCryptoNet() == CryptoNet.BITSHARES) {
cryptoCurrency = (CryptoCurrency) assetSpinner.getSelectedItem();
}else{
cryptoCurrency = CrystalDatabase.getAppDatabase(amountField.getContext()).cryptoCurrencyDao().getByNameAndCryptoNet(CryptoCoin.getByCryptoNet(this.account.getCryptoNet()).get(0).getLabel(),this.account.getCryptoNet().name());
}
/*
* Validation for the money
@ -66,6 +73,8 @@ public class AmountValidationField extends ValidationField {
setLastValue("");
setMessageForValue("",validator.getContext().getResources().getString(R.string.please_enter_valid_amount));
setValidForValue("", false);
} catch (Exception e ){
e.printStackTrace();
}
}
}

View file

@ -10,7 +10,10 @@ import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import org.apache.commons.codec.binary.StringUtils;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
@ -113,7 +116,12 @@ public class TransactionViewHolder extends RecyclerView.ViewHolder {
CryptoNetAccountViewModel cryptoNetAccountViewModel = ViewModelProviders.of(this.fragment).get(CryptoNetAccountViewModel.class);
cryptoNetAccountViewModel.loadCryptoNetAccount(transaction.getAccountId());
String amountString = String.format("%.2f",transaction.getAmount()/Math.pow(10,cryptoCurrency.getPrecision()));
String pattern = new String(new char[cryptoCurrency.getPrecision()]).replace('\0', '#');
pattern = "#."+pattern;
DecimalFormat df = new DecimalFormat(pattern);
//String amountString = String.format("%.2f",transaction.getAmount()/Math.pow(10,cryptoCurrency.getPrecision()));
String amountString = df.format(transaction.getAmount()/Math.pow(10,cryptoCurrency.getPrecision()));
GeneralSettingListViewModel generalSettingListViewModel = ViewModelProviders.of(this.fragment).get(GeneralSettingListViewModel.class);
GeneralSetting timeZoneSetting = generalSettingListViewModel.getGeneralSettingByName(GeneralSetting.SETTING_NAME_TIME_ZONE);

View file

@ -138,6 +138,22 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvAmountError" />
<ProgressBar
android:id="@+id/pbQrCode"
style="?android:attr/progressBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tvAmountError"
android:layout_alignBottom="@+id/ivQrCode"
android:layout_centerHorizontal="true"
android:layout_marginStart="24dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="24dp"
android:adjustViewBounds="true"
android:contentDescription="@string/qr_code"
android:src="@color/gray"
android:visibility="gone" />
<TextView
android:id="@+id/tvShare"
android:layout_width="wrap_content"