crystal-wallet-android/app/src/main/java/cy/agorise/crystalwallet/models/AccountSeed.java

166 lines
4.7 KiB
Java
Raw Normal View History

2017-09-08 00:31:38 +00:00
package cy.agorise.crystalwallet.models;
2017-09-13 21:52:36 +00:00
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
2018-01-07 03:21:46 +00:00
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
2018-11-18 15:44:30 +00:00
import org.bitcoinj.core.Base58;
2018-01-07 03:21:46 +00:00
import org.bitcoinj.core.ECKey;
import org.bitcoinj.crypto.HDKeyDerivation;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
2018-11-18 15:44:30 +00:00
import java.util.Arrays;
2018-01-07 03:21:46 +00:00
import cy.agorise.crystalwallet.enums.SeedType;
2018-01-07 03:21:46 +00:00
import cy.agorise.crystalwallet.models.seed.BIP39;
import cy.agorise.graphenej.BrainKey;
import static cy.agorise.crystalwallet.enums.SeedType.BRAINKEY;
2017-09-08 00:31:38 +00:00
/**
2017-09-13 21:52:36 +00:00
* Represents a type of crypto seed for HD wallets
*
2017-09-08 00:31:38 +00:00
* Created by Henry Varona on 6/9/2017.
*/
2017-09-10 23:13:32 +00:00
@Entity(tableName = "account_seed")
2017-09-08 00:31:38 +00:00
public class AccountSeed {
2017-09-13 21:52:36 +00:00
/**
* The id on the database
*/
2017-09-08 00:31:38 +00:00
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
private long mId;
2017-09-08 00:31:38 +00:00
2017-09-13 21:52:36 +00:00
/**
* The name or tag of this seed
*/
2017-09-08 00:31:38 +00:00
@ColumnInfo(name = "name")
private String mName;
2017-09-13 21:52:36 +00:00
/**
* The bytes of the master seed
*/
2017-09-08 00:31:38 +00:00
@ColumnInfo(name = "master_seed")
private String mMasterSeed;
/**
* The type of this seed: BIP39, BRAINKEY
*/
private SeedType type;
public long getId() {
2017-09-08 00:31:38 +00:00
return mId;
}
public void setId(long id){
2017-09-08 00:31:38 +00:00
this.mId = id;
}
public String getName() {
return mName;
}
public void setName(String mName) {
this.mName = mName;
}
public String getMasterSeed() {
return mMasterSeed;
}
public void setMasterSeed(String mMasterSeed) {
this.mMasterSeed = mMasterSeed;
}
public SeedType getType() {
return type;
}
public void setType(SeedType type) {
this.type = type;
}
public static final DiffUtil.ItemCallback<AccountSeed> DIFF_CALLBACK = new DiffUtil.ItemCallback<AccountSeed>() {
@Override
public boolean areItemsTheSame(
@NonNull AccountSeed oldAccountSeed, @NonNull AccountSeed newAccountSeed) {
return oldAccountSeed.getId() == newAccountSeed.getId();
}
@Override
public boolean areContentsTheSame(
@NonNull AccountSeed oldAccountSeed, @NonNull AccountSeed newAccountSeed) {
return oldAccountSeed.equals(newAccountSeed);
}
};
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
2017-09-08 00:31:38 +00:00
AccountSeed that = (AccountSeed) o;
if (mId != that.mId) return false;
return mMasterSeed.equals(that.mMasterSeed);
}
2018-01-07 03:21:46 +00:00
public static AccountSeed getAccountSeed(SeedType type, Context context){
BufferedReader reader = null;
switch (type) {
case BRAINKEY:
try {
reader = new BufferedReader(new InputStreamReader(context.getAssets().open("brainkeydict.txt"), "UTF-8"));
String dictionary = reader.readLine();
String brainKeySuggestion = BrainKey.suggest(dictionary);
AccountSeed seed = new AccountSeed();
seed.setMasterSeed(brainKeySuggestion);
seed.setType(BRAINKEY);
return seed;
} catch (IOException e) {
e.printStackTrace();
}
2018-11-18 15:44:30 +00:00
break;
2018-01-07 03:21:46 +00:00
case BIP39:
try {
reader = new BufferedReader(new InputStreamReader(context.getAssets().open("bip39dict.txt"), "UTF-8"));
String dictionary = reader.readLine();
//TODO save in db
return new BIP39(dictionary.split(","));
} catch (IOException e) {
e.printStackTrace();
}
2018-11-18 15:44:30 +00:00
break;
2018-01-07 03:21:46 +00:00
}
return null;
}
public ECKey getPrivateKey(){
switch (this.type) {
case BRAINKEY:
return new BrainKey(this.mMasterSeed,0).getPrivateKey();
case BIP39:
return HDKeyDerivation.createMasterPrivateKey(new BIP39(mId, mMasterSeed).getSeed());
2018-11-18 15:44:30 +00:00
case WIF:
byte[] decoded = Base58.decode(this.mMasterSeed);
byte[] privKey = Arrays.copyOfRange(decoded, 1, decoded.length - 4);
byte[] checksum = Arrays.copyOfRange(decoded, decoded.length - 4, decoded.length);
//TODO calculate chekcsum
while(privKey.length>32){
privKey = Arrays.copyOfRange(privKey,0,privKey.length-1);
}
return ECKey.fromPrivate(privKey);
2018-01-07 03:21:46 +00:00
}
return null;
}
2017-09-08 00:31:38 +00:00
}