feat_androidx_migration
dtvv 2018-10-24 02:02:26 -05:00
commit 8e55afad55
6 changed files with 65 additions and 107 deletions

View File

@ -18,11 +18,9 @@ public class InsightApiGenerator {
* Fecth all the transaciton for a giving address
* @param cryptoCoin the crypto net of the address
* @param address The address String
* @param request the request api to response
* @param subscribe If needs to follow the address (Real time)
*/
public static void getTransactionFromAddress(CryptoCoin cryptoCoin, String address,
ApiRequest request, boolean subscribe){
public static void getTransactionFromAddress(CryptoCoin cryptoCoin, String address, boolean subscribe){
if(!transactionGetters.containsKey(cryptoCoin)){
transactionGetters.put(cryptoCoin,new GetTransactionByAddress(cryptoCoin,CryptoNetManager.getURL(cryptoCoin.getCryptoNet())));
}

View File

@ -31,6 +31,9 @@ public interface BitcoinAddressDao {
@Query("SELECT MAX(ba.address_index) FROM bitcoin_address ba WHERE ba.account_id = :accountId and ba.is_change = 'true' ")
long getLastChangeAddress(long accountId);
@Query("SELECT MAX(ba.address_index) FROM bitcoin_address ba WHERE ba.account_id = :accountId and ba.is_change = 'false' ")
long getLastExternalAddress(long accountId);
@Insert(onConflict = OnConflictStrategy.REPLACE)
public long[] insertBitcoinAddresses(BitcoinAddress... addresses);
}

View File

@ -1,6 +1,5 @@
package cy.agorise.crystalwallet.manager;
import android.accounts.Account;
import android.content.Context;
import org.bitcoinj.core.Address;
@ -26,7 +25,6 @@ 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.application.CrystalApplication;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.models.AccountSeed;
@ -37,11 +35,11 @@ import cy.agorise.crystalwallet.models.CryptoCoinBalance;
import cy.agorise.crystalwallet.models.CryptoCoinTransaction;
import cy.agorise.crystalwallet.models.CryptoCurrency;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.models.GTxIO;
import cy.agorise.crystalwallet.models.GeneralCoinAddress;
import cy.agorise.crystalwallet.requestmanagers.BitcoinSendRequest;
import cy.agorise.crystalwallet.requestmanagers.CreateBitcoinAccountRequest;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequest;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestsListener;
import cy.agorise.crystalwallet.requestmanagers.GeneralAccountSendRequest;
import cy.agorise.crystalwallet.requestmanagers.NextBitcoinAccountAddressRequest;
import cy.agorise.graphenej.Util;
public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInfoRequestsListener {
@ -85,9 +83,14 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
@Override
public void onNewRequest(CryptoNetInfoRequest request) {
if(Arrays.asList(SUPPORTED_COINS).contains(request.getCoin())){
if(request instanceof GeneralAccountSendRequest){
this.send((GeneralAccountSendRequest)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){
}else if(request instanceof NextBitcoinAccountAddressRequest){
this.getNextAddress((NextBitcoinAccountAddressRequest) request);
}else{
System.out.println("Invalid " +this.cryptoCoin.getLabel() + " request ");
}
@ -255,7 +258,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
db.cryptoCoinBalanceDao().insertCryptoCoinBalance(balance);
}
public void send(final GeneralAccountSendRequest request){
public void send(final BitcoinSendRequest request){
//TODO check server connection
//TODO validate to address
@ -271,19 +274,19 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
db.bitcoinTransactionDao();
List<BitcoinTransactionGTxIO> utxos = getUtxos(request.getAccount().getId(),db);
List<BitcoinTransactionGTxIO> utxos = getUtxos(request.getSourceAccount().getId(),db);
if(currentAmount< request.getAmount() + fee){
request.setStatus(GeneralAccountSendRequest.StatusCode.NO_BALANCE);
request.setStatus(BitcoinSendRequest.StatusCode.NO_BALANCE);
return;
}
AccountSeed seed = db.accountSeedDao().findById(request.getAccount().getSeedId());
AccountSeed seed = db.accountSeedDao().findById(request.getSourceAccount().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(request.getAccount().getAccountIndex(), true));
new ChildNumber(request.getSourceAccount().getAccountIndex(), true));
DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(0, false));
DeterministicKey changeKey = HDKeyDerivation.deriveChildKey(accountKey,
@ -309,7 +312,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
//Change address
long remain = currentAmount - request.getAmount() - fee;
if( remain > 0 ) {
long index = db.bitcoinAddressDao().getLastChangeAddress(request.getAccount().getId());
long index = db.bitcoinAddressDao().getLastChangeAddress(request.getSourceAccount().getId());
BitcoinAddress btAddress = db.bitcoinAddressDao().getChangeByIndex(index);
Address changeAddr;
if(btAddress != null && db.bitcoinTransactionDao().getGtxIOByAddress(btAddress.getAddress()).size()<=0){
@ -323,7 +326,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
}
btAddress = new BitcoinAddress();
btAddress.setIndex(index);
btAddress.setAccountId(request.getAccount().getId());
btAddress.setAccountId(request.getSourceAccount().getId());
btAddress.setChange(true);
btAddress.setAddress(HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false)).toAddress(cryptoCoin.getParameters()).toString());
db.bitcoinAddressDao().insertBitcoinAddresses(btAddress);
@ -342,7 +345,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
if(btAddress.isChange()){
addrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false));
}else{
addrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), true));
addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) btAddress.getIndex(), true));
}
tx.addSignedInput(outPoint, script, addrKey, Transaction.SigHash.ALL, true);
}
@ -350,24 +353,51 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
InsightApiGenerator.broadcastTransaction(cryptoCoin,Util.bytesToHex(tx.bitcoinSerialize()),new ApiRequest(1, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
request.setStatus(GeneralAccountSendRequest.StatusCode.SUCCEEDED);
request.setStatus(BitcoinSendRequest.StatusCode.SUCCEEDED);
}
@Override
public void fail(int idPetition) {
request.setStatus(GeneralAccountSendRequest.StatusCode.PETITION_FAILED);
request.setStatus(BitcoinSendRequest.StatusCode.PETITION_FAILED);
}
}));
}
@Override
public void fail(int idPetition) {
request.setStatus(GeneralAccountSendRequest.StatusCode.NO_FEE);
request.setStatus(BitcoinSendRequest.StatusCode.NO_FEE);
}
}));
}
private void getNextAddress(NextBitcoinAccountAddressRequest request){
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
long index = db.bitcoinAddressDao().getLastExternalAddress(request.getAccount().getId());
index++;
AccountSeed seed = db.accountSeedDao().findById(request.getAccount().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(request.getAccount().getAccountIndex(), true));
DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(0, false));
ECKey addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) index, true));
BitcoinAddress address = new BitcoinAddress();
address.setChange(false);
address.setAccountId(request.getAccount().getId());
address.setIndex(index);
String addressString =addrKey.toAddress(this.cryptoCoin.getParameters()).toString();
address.setAddress(addressString);
db.bitcoinAddressDao().insertBitcoinAddresses(address);
InsightApiGenerator.getTransactionFromAddress(this.cryptoCoin,addressString,true);
request.setAddress(addressString);
request.setStatus(NextBitcoinAccountAddressRequest.StatusCode.SUCCEEDED);
}
private List<BitcoinTransactionGTxIO> getUtxos(long accountId, CrystalDatabase db){
List<BitcoinTransactionGTxIO> answer = new ArrayList<>();
List<BitcoinTransactionGTxIO> bTGTxI = new ArrayList<>();

View File

@ -21,6 +21,8 @@ public class BitcoinSendRequest extends CryptoNetInfoRequest {
SUCCEEDED,
NO_INTERNET,
NO_SERVER_CONNECTION,
NO_BALANCE,
NO_FEE,
PETITION_FAILED
}

View File

@ -1,85 +0,0 @@
package cy.agorise.crystalwallet.requestmanagers;
import android.content.Context;
import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
public class GeneralAccountSendRequest extends CryptoNetInfoRequest {
/**
* The status code of this request
*/
public enum StatusCode{
NOT_STARTED,
SUCCEEDED,
NO_INTERNET,
NO_SERVER_CONNECTION,
BAD_TO_ADDRESS,
NO_FEE,
NO_BALANCE,
PETITION_FAILED
}
// The app context
private Context mContext;
//The soruce Account
private CryptoNetAccount mAccount;
// The destination account address
private String mToAccount;
// The amount of the transaction
private long mAmount;
// The memo, can be null
private String mMemo;
// The state of this request
private StatusCode status = StatusCode.NOT_STARTED;
public GeneralAccountSendRequest(CryptoCoin coin, Context context, CryptoNetAccount account, String toAccount, long amount, String memo) {
super(coin);
this.mContext = context;
this.mAccount = account;
this.mToAccount = toAccount;
this.mAmount = amount;
this.mMemo = memo;
}
public GeneralAccountSendRequest(CryptoCoin coin, Context context, CryptoNetAccount account, String toAccount, long amount) {
this(coin,context,account,toAccount,amount,null);
}
public Context getContext() {
return mContext;
}
public CryptoNetAccount getAccount() {
return mAccount;
}
public String getToAccount() {
return mToAccount;
}
public long getAmount() {
return mAmount;
}
public String getMemo() {
return mMemo;
}
public void validate(){
if ((this.status != StatusCode.NOT_STARTED)){
this._fireOnCarryOutEvent();
}
}
public void setStatus(StatusCode code){
this.status = code;
this._fireOnCarryOutEvent();
}
public StatusCode getStatus() {
return status;
}
}

View File

@ -19,6 +19,8 @@ public class NextBitcoinAccountAddressRequest extends CryptoNetInfoRequest {
private CryptoCoin cryptoCoin;
private Context context;
private String address = null;
/**
* The status code of this request
*/
@ -62,4 +64,12 @@ public class NextBitcoinAccountAddressRequest extends CryptoNetInfoRequest {
public StatusCode getStatus() {
return status;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}