Create and import Bitcoin Like Account request implementation

This commit is contained in:
hvarona 2018-10-31 23:14:13 -04:00
parent 5965528abe
commit 51498192c6
4 changed files with 133 additions and 9 deletions

View file

@ -22,12 +22,17 @@ public class InsightApiGenerator {
* @param address The address String * @param address The address String
* @param subscribe If needs to follow the address (Real time) * @param subscribe If needs to follow the address (Real time)
*/ */
public static void getTransactionFromAddress(CryptoCoin cryptoCoin, String address, boolean subscribe){ public static void getTransactionFromAddress(CryptoCoin cryptoCoin, String address, boolean subscribe, HasTransactionListener listener){
if(!transactionGetters.containsKey(cryptoCoin)){ /*if(!transactionGetters.containsKey(cryptoCoin)){
transactionGetters.put(cryptoCoin,new GetTransactionByAddress(cryptoCoin,CryptoNetManager.getURL(cryptoCoin.getCryptoNet()),PATH)); transactionGetters.put(cryptoCoin,new GetTransactionByAddress(cryptoCoin,CryptoNetManager.getURL(cryptoCoin.getCryptoNet()),PATH));
} }
transactionGetters.get(cryptoCoin).addAddress(address); transactionGetters.get(cryptoCoin).addAddress(address);
transactionGetters.get(cryptoCoin).start(); transactionGetters.get(cryptoCoin).start();*/
GetTransactionByAddress transByAddr = new GetTransactionByAddress(cryptoCoin,CryptoNetManager.getURL(cryptoCoin.getCryptoNet()),PATH);
transByAddr.addAddress(address);
transByAddr.start();
if(subscribe){ if(subscribe){
if(!transactionFollowers.containsKey(cryptoCoin)){ if(!transactionFollowers.containsKey(cryptoCoin)){
transactionFollowers.put(cryptoCoin,new AddressesActivityWatcher(CryptoNetManager.getURL(cryptoCoin.getCryptoNet()),PATH,cryptoCoin)); transactionFollowers.put(cryptoCoin,new AddressesActivityWatcher(CryptoNetManager.getURL(cryptoCoin.getCryptoNet()),PATH,cryptoCoin));
@ -80,4 +85,8 @@ public class InsightApiGenerator {
} }
}); });
} }
public interface HasTransactionListener{
public void hasTransaction(boolean value);
}
} }

View file

@ -5,6 +5,7 @@ import android.util.Log;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import cy.agorise.crystalwallet.apigenerator.InsightApiGenerator;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.AddressTxi; import cy.agorise.crystalwallet.apigenerator.insightapi.models.AddressTxi;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Txi; import cy.agorise.crystalwallet.apigenerator.insightapi.models.Txi;
import cy.agorise.crystalwallet.enums.CryptoCoin; import cy.agorise.crystalwallet.enums.CryptoCoin;
@ -35,14 +36,17 @@ public class GetTransactionByAddress extends Thread implements Callback<AddressT
private boolean inProcess = false; private boolean inProcess = false;
private InsightApiGenerator.HasTransactionListener listener;
/** /**
* Basic consturcotr * Basic consturcotr
*/ */
public GetTransactionByAddress(CryptoCoin cryptoNet, String serverUrl,String path) { public GetTransactionByAddress(CryptoCoin cryptoNet, String serverUrl, String path, InsightApiGenerator.HasTransactionListener listener) {
this.mPath = path; this.mPath = path;
this.cryptoNet = cryptoNet; this.cryptoNet = cryptoNet;
this.mServerUrl = serverUrl; this.mServerUrl = serverUrl;
this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl); this.mServiceGenerator = new InsightApiServiceGenerator(serverUrl);
this.listener = listener;
} }
/** /**
@ -63,13 +67,21 @@ public class GetTransactionByAddress extends Thread implements Callback<AddressT
public void onResponse(Call<AddressTxi> call, Response<AddressTxi> response) { public void onResponse(Call<AddressTxi> call, Response<AddressTxi> response) {
inProcess = false; inProcess = false;
if (response.isSuccessful()) { if (response.isSuccessful()) {
boolean changed = false;
AddressTxi addressTxi = response.body(); AddressTxi addressTxi = response.body();
if(listener != null) {
if (addressTxi.items.length > 0 ) {
listener.hasTransaction(true);
}else{
listener.hasTransaction(false);
}
}
for (Txi txi : addressTxi.items) { for (Txi txi : addressTxi.items) {
GeneralAccountManager.getAccountManager(this.cryptoNet).processTxi(txi); GeneralAccountManager.getAccountManager(this.cryptoNet).processTxi(txi);
} }
}else{
listener.hasTransaction(false);
} }
} }

View file

@ -28,6 +28,9 @@ public interface BitcoinAddressDao {
@Query("SELECT * FROM bitcoin_address ba WHERE ba.address_index = :index and ba.is_change = 'true'") @Query("SELECT * FROM bitcoin_address ba WHERE ba.address_index = :index and ba.is_change = 'true'")
BitcoinAddress getChangeByIndex(long index); BitcoinAddress getChangeByIndex(long index);
@Query("SELECT * FROM bitcoin_address ba WHERE ba.address_index = :index and ba.is_change = 'false'")
BitcoinAddress getExternalByIndex(long index);
@Query("SELECT MAX(ba.address_index) FROM bitcoin_address ba WHERE ba.account_id = :accountId and ba.is_change = 'true' ") @Query("SELECT MAX(ba.address_index) FROM bitcoin_address ba WHERE ba.account_id = :accountId and ba.is_change = 'true' ")
long getLastChangeAddress(long accountId); long getLastChangeAddress(long accountId);

View file

@ -25,6 +25,7 @@ import cy.agorise.crystalwallet.apigenerator.InsightApiGenerator;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Txi; import cy.agorise.crystalwallet.apigenerator.insightapi.models.Txi;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vin; import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vin;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vout; import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vout;
import cy.agorise.crystalwallet.dao.BitcoinAddressDao;
import cy.agorise.crystalwallet.dao.CrystalDatabase; import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.enums.CryptoCoin; import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.models.AccountSeed; import cy.agorise.crystalwallet.models.AccountSeed;
@ -77,18 +78,69 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
} }
@Override @Override
public void loadAccountFromDB(CryptoNetAccount account, Context context) { public void loadAccountFromDB(final CryptoNetAccount account, Context context) {
final CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
AccountSeed seed = db.accountSeedDao().findById(account.getSeedId());
DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(),
new ChildNumber(44, true));
DeterministicKey coinKey = HDKeyDerivation.deriveChildKey(purposeKey,
new ChildNumber(cryptoCoin.getCoinNumber(), true));
DeterministicKey accountKey = HDKeyDerivation.deriveChildKey(coinKey,
new ChildNumber(account.getAccountIndex(), true));
final DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(0, false));
final DeterministicKey changeKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(1, false));
long indexExternal = db.bitcoinAddressDao().getLastExternalAddress(account.getId());
if(indexExternal > 0){
for(int i = 0; i < indexExternal;i++){
BitcoinAddress address = db.bitcoinAddressDao().getExternalByIndex(i);
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,address.getAddress(),true,null);
}
}else {
ECKey externalAddrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) 0, true));
BitcoinAddress address = new BitcoinAddress();
address.setChange(false);
address.setAccountId(account.getId());
address.setIndex(0);
String addressString =externalAddrKey.toAddress(this.cryptoCoin.getParameters()).toString();
address.setAddress(addressString);
db.bitcoinAddressDao().insertBitcoinAddresses(address);
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,addressString,true,
new CheckAddressForTransaction(db.bitcoinAddressDao(),account.getId(),externalKey,false,0));
}
long indexChange = db.bitcoinAddressDao().getLastChangeAddress(account.getId());
if(indexChange > 0){
for(int i = 0; i < indexChange;i++){
BitcoinAddress address = db.bitcoinAddressDao().getChangeByIndex(i);
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,address.getAddress(),true,null);
}
}else {
ECKey changeAddrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) 0, true));
BitcoinAddress address = new BitcoinAddress();
address.setChange(true);
address.setAccountId(account.getId());
address.setIndex(0);
String addressString =changeAddrKey.toAddress(this.cryptoCoin.getParameters()).toString();
address.setAddress(addressString);
db.bitcoinAddressDao().insertBitcoinAddresses(address);
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,addressString,true,
new CheckAddressForTransaction(db.bitcoinAddressDao(),account.getId(),externalKey,true,0));
}
} }
@Override @Override
public void onNewRequest(CryptoNetInfoRequest request) { public void onNewRequest(CryptoNetInfoRequest request) {
//if(Arrays.asList(SUPPORTED_COINS).contains(request.getCoin())){ //if(Arrays.asList(SUPPORTED_COINS).contains(request.getCoin())){
if(request.getCoin().equals(this.cryptoCoin)){ if(request.getCoin().equals(this.cryptoCoin)){
if(request instanceof BitcoinSendRequest) { if(request instanceof BitcoinSendRequest) {
this.send((BitcoinSendRequest) request);
}else if(request instanceof CreateBitcoinAccountRequest){ }else if(request instanceof CreateBitcoinAccountRequest){
this.createGeneralAccount((CreateBitcoinAccountRequest) request);
}else if(request instanceof NextBitcoinAccountAddressRequest){ }else if(request instanceof NextBitcoinAccountAddressRequest){
this.getNextAddress((NextBitcoinAccountAddressRequest) request); this.getNextAddress((NextBitcoinAccountAddressRequest) request);
}else{ }else{
@ -235,6 +287,21 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
} }
} }
private void createGeneralAccount(CreateBitcoinAccountRequest request){
CrystalDatabase db = CrystalDatabase.getAppDatabase(this.context);
CryptoNetAccount account = new CryptoNetAccount();
account.setAccountIndex(0);
account.setCryptoNet(this.cryptoCoin.getCryptoNet());
account.setName(request.getAccountSeed().getName());
account.setSeedId(request.getAccountSeed().getId());
long idAccount = db.cryptoNetAccountDao().insertCryptoNetAccount(account)[0];
account.setId(idAccount);
loadAccountFromDB(account,request.getContext());
request.setStatus(CreateBitcoinAccountRequest.StatusCode.SUCCEEDED);
}
private void updateBalance(CryptoCoinTransaction ccTransaction, long amount, CrystalDatabase db){ 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.name(), this.cryptoCoin.getCryptoNet().name());
if (currency == null) { if (currency == null) {
@ -392,7 +459,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
String addressString =addrKey.toAddress(this.cryptoCoin.getParameters()).toString(); String addressString =addrKey.toAddress(this.cryptoCoin.getParameters()).toString();
address.setAddress(addressString); address.setAddress(addressString);
db.bitcoinAddressDao().insertBitcoinAddresses(address); db.bitcoinAddressDao().insertBitcoinAddresses(address);
InsightApiGenerator.getTransactionFromAddress(this.cryptoCoin,addressString,true); InsightApiGenerator.getTransactionFromAddress(this.cryptoCoin,addressString,true, null);
request.setAddress(addressString); request.setAddress(addressString);
request.setStatus(NextBitcoinAccountAddressRequest.StatusCode.SUCCEEDED); request.setStatus(NextBitcoinAccountAddressRequest.StatusCode.SUCCEEDED);
@ -430,4 +497,37 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
return answer; return answer;
} }
class CheckAddressForTransaction implements InsightApiGenerator.HasTransactionListener{
BitcoinAddressDao bitcoinAddressDao;
long idAccount;
DeterministicKey addressKey;
boolean isChange;
int lastIndex;
public CheckAddressForTransaction(BitcoinAddressDao bitcoinAddressDao, long idAccount, DeterministicKey addressKey, boolean isChange, int lastIndex) {
this.bitcoinAddressDao = bitcoinAddressDao;
this.idAccount = idAccount;
this.addressKey = addressKey;
this.isChange = isChange;
this.lastIndex = lastIndex;
}
@Override
public void hasTransaction(boolean value) {
if(value){
ECKey externalAddrKey = HDKeyDerivation.deriveChildKey(addressKey, new ChildNumber(lastIndex+1, true));
BitcoinAddress address = new BitcoinAddress();
address.setChange(isChange);
address.setAccountId(idAccount);
address.setIndex(lastIndex+1);
String addressString =externalAddrKey.toAddress(cryptoCoin.getParameters()).toString();
address.setAddress(addressString);
bitcoinAddressDao.insertBitcoinAddresses(address);
InsightApiGenerator.getTransactionFromAddress(cryptoCoin,addressString,true,
new CheckAddressForTransaction(bitcoinAddressDao,idAccount,addressKey,isChange,lastIndex+1));
}
}
}
} }