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 subscribe If needs to follow the address (Real time)
*/
public static void getTransactionFromAddress(CryptoCoin cryptoCoin, String address, boolean subscribe){
if(!transactionGetters.containsKey(cryptoCoin)){
public static void getTransactionFromAddress(CryptoCoin cryptoCoin, String address, boolean subscribe, HasTransactionListener listener){
/*if(!transactionGetters.containsKey(cryptoCoin)){
transactionGetters.put(cryptoCoin,new GetTransactionByAddress(cryptoCoin,CryptoNetManager.getURL(cryptoCoin.getCryptoNet()),PATH));
}
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(!transactionFollowers.containsKey(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.List;
import cy.agorise.crystalwallet.apigenerator.InsightApiGenerator;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.AddressTxi;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Txi;
import cy.agorise.crystalwallet.enums.CryptoCoin;
@ -35,14 +36,17 @@ public class GetTransactionByAddress extends Thread implements Callback<AddressT
private boolean inProcess = false;
private InsightApiGenerator.HasTransactionListener listener;
/**
* 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.cryptoNet = cryptoNet;
this.mServerUrl = 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) {
inProcess = false;
if (response.isSuccessful()) {
boolean changed = false;
AddressTxi addressTxi = response.body();
if(listener != null) {
if (addressTxi.items.length > 0 ) {
listener.hasTransaction(true);
}else{
listener.hasTransaction(false);
}
}
for (Txi txi : addressTxi.items) {
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'")
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' ")
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.Vin;
import cy.agorise.crystalwallet.apigenerator.insightapi.models.Vout;
import cy.agorise.crystalwallet.dao.BitcoinAddressDao;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.models.AccountSeed;
@ -77,18 +78,69 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
}
@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
public void onNewRequest(CryptoNetInfoRequest request) {
//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){
this.getNextAddress((NextBitcoinAccountAddressRequest) request);
}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){
CryptoCurrency currency = db.cryptoCurrencyDao().getByNameAndCryptoNet(this.cryptoCoin.name(), this.cryptoCoin.getCryptoNet().name());
if (currency == null) {
@ -392,7 +459,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
String addressString =addrKey.toAddress(this.cryptoCoin.getParameters()).toString();
address.setAddress(addressString);
db.bitcoinAddressDao().insertBitcoinAddresses(address);
InsightApiGenerator.getTransactionFromAddress(this.cryptoCoin,addressString,true);
InsightApiGenerator.getTransactionFromAddress(this.cryptoCoin,addressString,true, null);
request.setAddress(addressString);
request.setStatus(NextBitcoinAccountAddressRequest.StatusCode.SUCCEEDED);
@ -430,4 +497,37 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
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));
}
}
}
}