mirror of
https://codeberg.org/r4v3r23/mysu.git
synced 2024-11-14 01:21:54 +00:00
WIP: Polyseed. Polyseed wallets currently have offsets enforced due to a bug in ANONERO's polyseed implementation
This commit is contained in:
parent
f6876b866e
commit
fc853dc55d
13 changed files with 358 additions and 29 deletions
|
@ -79,6 +79,14 @@ add_library(wallet STATIC IMPORTED)
|
||||||
set_target_properties(wallet PROPERTIES IMPORTED_LOCATION
|
set_target_properties(wallet PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libwallet.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libwallet.a)
|
||||||
|
|
||||||
|
add_library(polyseed STATIC IMPORTED)
|
||||||
|
set_target_properties(polyseed PROPERTIES IMPORTED_LOCATION
|
||||||
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libpolyseed.a)
|
||||||
|
|
||||||
|
add_library(polyseed-wrapper STATIC IMPORTED)
|
||||||
|
set_target_properties(polyseed-wrapper PROPERTIES IMPORTED_LOCATION
|
||||||
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libpolyseed_wrapper.a)
|
||||||
|
|
||||||
add_library(cryptonote_core STATIC IMPORTED)
|
add_library(cryptonote_core STATIC IMPORTED)
|
||||||
set_target_properties(cryptonote_core PROPERTIES IMPORTED_LOCATION
|
set_target_properties(cryptonote_core PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libcryptonote_core.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libcryptonote_core.a)
|
||||||
|
@ -155,6 +163,10 @@ add_library(net STATIC IMPORTED)
|
||||||
set_target_properties(net PROPERTIES IMPORTED_LOCATION
|
set_target_properties(net PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libnet.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libnet.a)
|
||||||
|
|
||||||
|
add_library(utf8proc STATIC IMPORTED)
|
||||||
|
set_target_properties(utf8proc PROPERTIES IMPORTED_LOCATION
|
||||||
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libutf8proc.a)
|
||||||
|
|
||||||
add_library(hardforks STATIC IMPORTED)
|
add_library(hardforks STATIC IMPORTED)
|
||||||
set_target_properties(hardforks PROPERTIES IMPORTED_LOCATION
|
set_target_properties(hardforks PROPERTIES IMPORTED_LOCATION
|
||||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libhardforks.a)
|
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libhardforks.a)
|
||||||
|
@ -198,6 +210,9 @@ target_link_libraries( monerujo
|
||||||
cryptonote_core
|
cryptonote_core
|
||||||
cryptonote_basic
|
cryptonote_basic
|
||||||
cryptonote_format_utils_basic
|
cryptonote_format_utils_basic
|
||||||
|
polyseed
|
||||||
|
polyseed-wrapper
|
||||||
|
utf8proc
|
||||||
mnemonics
|
mnemonics
|
||||||
ringct
|
ringct
|
||||||
ringct_basic
|
ringct_basic
|
||||||
|
|
|
@ -347,6 +347,41 @@ Java_net_mynero_wallet_model_WalletManager_createWalletJ(JNIEnv *env, jobject in
|
||||||
return reinterpret_cast<jlong>(wallet);
|
return reinterpret_cast<jlong>(wallet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL
|
||||||
|
Java_net_mynero_wallet_model_WalletManager_createWalletPolyseedJ(JNIEnv *env, jobject instance,
|
||||||
|
jstring path, jstring password, jstring passpharse,
|
||||||
|
jstring language,
|
||||||
|
jint networkType) {
|
||||||
|
std::string seed_words;
|
||||||
|
std::string err;
|
||||||
|
bool _polyseedCreate = Monero::Wallet::createPolyseed(seed_words, err);
|
||||||
|
if (!_polyseedCreate) {
|
||||||
|
LOGE("Failed to polyseedCreate");
|
||||||
|
}
|
||||||
|
|
||||||
|
// wallet->createPolyseed(seed_words, err);
|
||||||
|
|
||||||
|
const char *_path = env->GetStringUTFChars(path, nullptr);
|
||||||
|
const char *_password = env->GetStringUTFChars(password, nullptr);
|
||||||
|
const char *_passpharse = env->GetStringUTFChars(passpharse, nullptr);
|
||||||
|
const char *_language = env->GetStringUTFChars(language, nullptr); // NOT USED ANYMORE?????
|
||||||
|
Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
|
||||||
|
Monero::Wallet *wallet =
|
||||||
|
Monero::WalletManagerFactory::getWalletManager()->createWalletFromPolyseed(
|
||||||
|
std::string(_path),
|
||||||
|
std::string(_password),
|
||||||
|
_networkType,
|
||||||
|
seed_words,
|
||||||
|
std::string(_passpharse), true);
|
||||||
|
|
||||||
|
env->ReleaseStringUTFChars(path, _path);
|
||||||
|
env->ReleaseStringUTFChars(password, _password);
|
||||||
|
env->ReleaseStringUTFChars(language, _language);
|
||||||
|
env->ReleaseStringUTFChars(passpharse, _passpharse);
|
||||||
|
return reinterpret_cast<jlong>(wallet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT jlong JNICALL
|
JNIEXPORT jlong JNICALL
|
||||||
Java_net_mynero_wallet_model_WalletManager_openWalletJ(JNIEnv *env, jobject instance,
|
Java_net_mynero_wallet_model_WalletManager_openWalletJ(JNIEnv *env, jobject instance,
|
||||||
jstring path, jstring password,
|
jstring path, jstring password,
|
||||||
|
@ -395,6 +430,33 @@ Java_net_mynero_wallet_model_WalletManager_recoveryWalletJ(JNIEnv *env, jobject
|
||||||
return reinterpret_cast<jlong>(wallet);
|
return reinterpret_cast<jlong>(wallet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL
|
||||||
|
Java_net_mynero_wallet_model_WalletManager_recoveryWalletPolyseedJ(JNIEnv *env, jobject instance,
|
||||||
|
jstring path, jstring password,
|
||||||
|
jstring mnemonic, jstring offset,
|
||||||
|
jint networkType) {
|
||||||
|
const char *_path = env->GetStringUTFChars(path, nullptr);
|
||||||
|
const char *_password = env->GetStringUTFChars(password, nullptr);
|
||||||
|
const char *_mnemonic = env->GetStringUTFChars(mnemonic, nullptr);
|
||||||
|
const char *_offset = env->GetStringUTFChars(offset, nullptr);
|
||||||
|
Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
|
||||||
|
|
||||||
|
Monero::Wallet *wallet =
|
||||||
|
Monero::WalletManagerFactory::getWalletManager()->createWalletFromPolyseed(
|
||||||
|
std::string(_path),
|
||||||
|
std::string(_password),
|
||||||
|
_networkType,
|
||||||
|
std::string(_mnemonic),
|
||||||
|
std::string(_offset), false);
|
||||||
|
|
||||||
|
env->ReleaseStringUTFChars(path, _path);
|
||||||
|
env->ReleaseStringUTFChars(password, _password);
|
||||||
|
env->ReleaseStringUTFChars(mnemonic, _mnemonic);
|
||||||
|
env->ReleaseStringUTFChars(offset, _offset);
|
||||||
|
return reinterpret_cast<jlong>(wallet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT jlong JNICALL
|
JNIEXPORT jlong JNICALL
|
||||||
Java_net_mynero_wallet_model_WalletManager_createWalletFromKeysJ(JNIEnv *env, jobject instance,
|
Java_net_mynero_wallet_model_WalletManager_createWalletFromKeysJ(JNIEnv *env, jobject instance,
|
||||||
jstring path, jstring password,
|
jstring path, jstring password,
|
||||||
|
@ -645,11 +707,55 @@ JNIEXPORT jstring JNICALL
|
||||||
Java_net_mynero_wallet_model_Wallet_getSeed(JNIEnv *env, jobject instance, jstring seedOffset) {
|
Java_net_mynero_wallet_model_Wallet_getSeed(JNIEnv *env, jobject instance, jstring seedOffset) {
|
||||||
const char *_seedOffset = env->GetStringUTFChars(seedOffset, nullptr);
|
const char *_seedOffset = env->GetStringUTFChars(seedOffset, nullptr);
|
||||||
Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
|
Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
|
||||||
jstring seed = env->NewStringUTF(wallet->seed(std::string(_seedOffset)).c_str());
|
|
||||||
|
std::string _seed;
|
||||||
|
std::string seedOffsetStr(_seedOffset);
|
||||||
|
bool _getPolyseed = wallet->getPolyseed(_seed, seedOffsetStr);
|
||||||
|
|
||||||
|
if (_getPolyseed) {
|
||||||
|
LOGD("_getPolyseed: true");
|
||||||
|
} else {
|
||||||
|
LOGD("_getPolyseed: false");
|
||||||
|
LOGE("wallet->getSeed() %s", wallet->errorString().c_str());
|
||||||
|
LOGD("Falling back to normal, boring, seed");
|
||||||
|
_seed = wallet->seed(std::string(_seedOffset));
|
||||||
|
}
|
||||||
|
|
||||||
env->ReleaseStringUTFChars(seedOffset, _seedOffset);
|
env->ReleaseStringUTFChars(seedOffset, _seedOffset);
|
||||||
|
|
||||||
|
jstring seed = env->NewStringUTF(_seed.c_str());
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jstring JNICALL
|
||||||
|
Java_net_mynero_wallet_model_Wallet_getLegacySeed(JNIEnv *env, jobject instance, jstring seedOffset) {
|
||||||
|
const char *_seedOffset = env->GetStringUTFChars(seedOffset, nullptr);
|
||||||
|
Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
|
||||||
|
|
||||||
|
std::string _seed;
|
||||||
|
std::string seedOffsetStr(_seedOffset);
|
||||||
|
_seed = wallet->seed(std::string(_seedOffset));
|
||||||
|
|
||||||
|
env->ReleaseStringUTFChars(seedOffset, _seedOffset);
|
||||||
|
|
||||||
|
jstring seed = env->NewStringUTF(_seed.c_str());
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL
|
||||||
|
Java_net_mynero_wallet_model_Wallet_isPolyseedSupported(JNIEnv *env, jobject instance, jstring seedOffset) {
|
||||||
|
const char *_seedOffset = env->GetStringUTFChars(seedOffset, nullptr);
|
||||||
|
Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
|
||||||
|
|
||||||
|
std::string _seed;
|
||||||
|
std::string seedOffsetStr(_seedOffset);
|
||||||
|
bool _getPolyseed = wallet->getPolyseed(_seed, seedOffsetStr);
|
||||||
|
|
||||||
|
env->ReleaseStringUTFChars(seedOffset, _seedOffset);
|
||||||
|
return _getPolyseed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL
|
JNIEXPORT jstring JNICALL
|
||||||
Java_net_mynero_wallet_model_Wallet_getSeedLanguage(JNIEnv *env, jobject instance) {
|
Java_net_mynero_wallet_model_Wallet_getSeedLanguage(JNIEnv *env, jobject instance) {
|
||||||
Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
|
Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
|
||||||
|
|
|
@ -198,6 +198,17 @@ public class OnboardingFragment extends Fragment implements NodeSelectionBottomS
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable editable) {
|
public void afterTextChanged(Editable editable) {
|
||||||
String text = editable.toString();
|
String text = editable.toString();
|
||||||
|
OnboardingViewModel.SeedType seedType = mViewModel.getMnemonicType(text);
|
||||||
|
if(seedType == OnboardingViewModel.SeedType.LEGACY) {
|
||||||
|
seedOffsetCheckbox.setVisibility(View.VISIBLE);
|
||||||
|
walletRestoreHeightEditText.setVisibility(View.VISIBLE);
|
||||||
|
walletPasswordEditText.setHint(getString(R.string.password_optional));
|
||||||
|
} else {
|
||||||
|
seedOffsetCheckbox.setVisibility(View.GONE);
|
||||||
|
walletRestoreHeightEditText.setVisibility(View.GONE);
|
||||||
|
walletPasswordEditText.setHint(getString(R.string.password_non_optional));
|
||||||
|
}
|
||||||
|
|
||||||
if (text.isEmpty()) {
|
if (text.isEmpty()) {
|
||||||
createWalletButton.setText(R.string.create_wallet);
|
createWalletButton.setText(R.string.create_wallet);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -71,6 +71,7 @@ public class OnboardingViewModel extends ViewModel {
|
||||||
String offset = useOffset ? walletPassword : "";
|
String offset = useOffset ? walletPassword : "";
|
||||||
if (!walletPassword.isEmpty()) {
|
if (!walletPassword.isEmpty()) {
|
||||||
if(!walletPassword.equals(confirmedPassword)) {
|
if(!walletPassword.equals(confirmedPassword)) {
|
||||||
|
_enableCreateButton.setValue(true);
|
||||||
mainActivity.runOnUiThread(() -> Toast.makeText(mainActivity, application.getString(R.string.invalid_confirmed_password), Toast.LENGTH_SHORT).show());
|
mainActivity.runOnUiThread(() -> Toast.makeText(mainActivity, application.getString(R.string.invalid_confirmed_password), Toast.LENGTH_SHORT).show());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -84,11 +85,21 @@ public class OnboardingViewModel extends ViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (walletSeed.isEmpty()) {
|
if (walletSeed.isEmpty()) {
|
||||||
Wallet tmpWallet = createTempWallet(mainActivity.getApplicationInfo().dataDir); //we do this to get seed, then recover wallet so we can use seed offset
|
if(offset.isEmpty()) {
|
||||||
wallet = WalletManager.getInstance().recoveryWallet(walletFile, walletPassword, tmpWallet.getSeed(""), offset, restoreHeight);
|
mainActivity.runOnUiThread(() -> {
|
||||||
|
_enableCreateButton.setValue(true);
|
||||||
|
Toast.makeText(mainActivity, application.getString(R.string.invalid_empty_passphrase), Toast.LENGTH_SHORT).show();
|
||||||
|
});
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (!checkMnemonic(walletSeed)) {
|
wallet = WalletManager.getInstance().createWalletPolyseed(walletFile, walletPassword, offset, Constants.MNEMONIC_LANGUAGE);
|
||||||
mainActivity.runOnUiThread(() -> Toast.makeText(mainActivity, application.getString(R.string.invalid_mnemonic_code), Toast.LENGTH_SHORT).show());
|
}
|
||||||
|
} else {
|
||||||
|
if (getMnemonicType(walletSeed) == SeedType.UNKNOWN) {
|
||||||
|
mainActivity.runOnUiThread(() -> {
|
||||||
|
_enableCreateButton.setValue(true);
|
||||||
|
Toast.makeText(mainActivity, application.getString(R.string.invalid_mnemonic_code), Toast.LENGTH_SHORT).show();
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!restoreHeightText.isEmpty()) {
|
if (!restoreHeightText.isEmpty()) {
|
||||||
|
@ -99,7 +110,7 @@ public class OnboardingViewModel extends ViewModel {
|
||||||
Wallet.Status walletStatus = wallet.getStatus();
|
Wallet.Status walletStatus = wallet.getStatus();
|
||||||
wallet.close();
|
wallet.close();
|
||||||
boolean ok = walletStatus.isOk();
|
boolean ok = walletStatus.isOk();
|
||||||
walletFile.delete(); // cache is broken for some reason when recovering wallets. delete the file here. this happens in monerujo too.
|
//walletFile.delete(); // cache is broken for some reason when recovering wallets. delete the file here. this happens in monerujo too.
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
((MainActivity)mainActivity).init(walletFile, walletPassword);
|
((MainActivity)mainActivity).init(walletFile, walletPassword);
|
||||||
|
@ -119,12 +130,20 @@ public class OnboardingViewModel extends ViewModel {
|
||||||
return RestoreHeight.getInstance().getHeight(restoreDate.getTime());
|
return RestoreHeight.getInstance().getHeight(restoreDate.getTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Wallet createTempWallet(String dir) {
|
public SeedType getMnemonicType(String seed) {
|
||||||
File tmpWalletFile = new File(dir, Constants.WALLET_NAME + "_tmp");
|
String[] words = seed.split("\\s");
|
||||||
return WalletManager.getInstance().createWallet(tmpWalletFile, "", Constants.MNEMONIC_LANGUAGE, 0);
|
if(words.length == 16) {
|
||||||
|
return SeedType.POLYSEED;
|
||||||
|
} else if (words.length == 25){
|
||||||
|
return SeedType.LEGACY;
|
||||||
|
} else {
|
||||||
|
return SeedType.UNKNOWN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkMnemonic(String seed) {
|
public enum SeedType {
|
||||||
return (seed.split("\\s").length == 25);
|
LEGACY,
|
||||||
|
POLYSEED,
|
||||||
|
UNKNOWN
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package net.mynero.wallet.model;
|
package net.mynero.wallet.model;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
@ -94,6 +95,10 @@ public class Wallet {
|
||||||
|
|
||||||
public native String getSeed(String offset);
|
public native String getSeed(String offset);
|
||||||
|
|
||||||
|
public native String getLegacySeed(String offset);
|
||||||
|
|
||||||
|
public native boolean isPolyseedSupported(String offset);
|
||||||
|
|
||||||
public native String getSeedLanguage();
|
public native String getSeedLanguage();
|
||||||
|
|
||||||
public native void setSeedLanguage(String language);
|
public native void setSeedLanguage(String language);
|
||||||
|
@ -189,10 +194,42 @@ public class Wallet {
|
||||||
|
|
||||||
// virtual std::string keysFilename() const = 0;
|
// virtual std::string keysFilename() const = 0;
|
||||||
public boolean init(long upper_transaction_size_limit) {
|
public boolean init(long upper_transaction_size_limit) {
|
||||||
return initJ(WalletManager.getInstance().getDaemonAddress(), upper_transaction_size_limit,
|
String daemon_address = WalletManager.getInstance().getDaemonAddress();
|
||||||
WalletManager.getInstance().getDaemonUsername(),
|
String daemon_username = WalletManager.getInstance().getDaemonUsername();
|
||||||
WalletManager.getInstance().getDaemonPassword(), WalletManager.getInstance().getProxy());
|
String daemon_password = WalletManager.getInstance().getDaemonPassword();
|
||||||
|
String proxy_address = WalletManager.getInstance().getProxy();
|
||||||
|
Log.d("Wallet.java", "init(");
|
||||||
|
if (daemon_address != null) {
|
||||||
|
Log.d("Wallet.java", daemon_address.toString());
|
||||||
|
} else {
|
||||||
|
Log.d("Wallet.java", "daemon_address == null");
|
||||||
|
daemon_address = "";
|
||||||
}
|
}
|
||||||
|
Log.d("Wallet.java", "upper_transaction_size_limit = 0 (probably)");
|
||||||
|
if (daemon_username != null) {
|
||||||
|
Log.d("Wallet.java", daemon_username.toString());
|
||||||
|
} else {
|
||||||
|
Log.d("Wallet.java", "daemon_username == null");
|
||||||
|
daemon_username = "";
|
||||||
|
}
|
||||||
|
if (daemon_password != null) {
|
||||||
|
Log.d("Wallet.java", daemon_password.toString());
|
||||||
|
} else {
|
||||||
|
Log.d("Wallet.java", "daemon_password == null");
|
||||||
|
daemon_password = "";
|
||||||
|
}
|
||||||
|
if (proxy_address != null) {
|
||||||
|
Log.d("Wallet.java", proxy_address.toString());
|
||||||
|
} else {
|
||||||
|
Log.d("Wallet.java", "proxy_address == null");
|
||||||
|
proxy_address = "";
|
||||||
|
}
|
||||||
|
Log.d("Wallet.java", ");");
|
||||||
|
return initJ(daemon_address, upper_transaction_size_limit,
|
||||||
|
daemon_username, daemon_password,
|
||||||
|
proxy_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private native boolean initJ(String daemon_address, long upper_transaction_size_limit,
|
private native boolean initJ(String daemon_address, long upper_transaction_size_limit,
|
||||||
String daemon_username, String daemon_password, String proxy);
|
String daemon_username, String daemon_password, String proxy);
|
||||||
|
|
|
@ -136,6 +136,18 @@ public class WalletManager {
|
||||||
|
|
||||||
private native long createWalletJ(String path, String password, String language, int networkType);
|
private native long createWalletJ(String path, String password, String language, int networkType);
|
||||||
|
|
||||||
|
public Wallet createWalletPolyseed(File aFile, String password, String passphrase, String language) {
|
||||||
|
long walletHandle = createWalletPolyseedJ(aFile.getAbsolutePath(), password, passphrase, language, getNetworkType().getValue());
|
||||||
|
Wallet wallet = new Wallet(walletHandle);
|
||||||
|
manageWallet(wallet);
|
||||||
|
if (wallet.getStatus().isOk()) {
|
||||||
|
wallet.setPassword(password); // this rewrites the keys file (which contains the restore height)
|
||||||
|
} else
|
||||||
|
Timber.e(wallet.getStatus().toString());
|
||||||
|
return wallet;
|
||||||
|
}
|
||||||
|
private native long createWalletPolyseedJ(String path, String password, String passphrase, String language, int networkType);
|
||||||
|
|
||||||
public Wallet openAccount(String path, int accountIndex, String password) {
|
public Wallet openAccount(String path, int accountIndex, String password) {
|
||||||
long walletHandle = openWalletJ(path, password, getNetworkType().getValue());
|
long walletHandle = openWalletJ(path, password, getNetworkType().getValue());
|
||||||
Wallet wallet = new Wallet(walletHandle, accountIndex);
|
Wallet wallet = new Wallet(walletHandle, accountIndex);
|
||||||
|
@ -169,6 +181,20 @@ public class WalletManager {
|
||||||
String mnemonic, String offset,
|
String mnemonic, String offset,
|
||||||
int networkType, long restoreHeight);
|
int networkType, long restoreHeight);
|
||||||
|
|
||||||
|
public Wallet recoveryWalletPolyseed(File aFile, String password,
|
||||||
|
String mnemonic, String offset) {
|
||||||
|
long walletHandle = recoveryWalletPolyseedJ(aFile.getAbsolutePath(), password,
|
||||||
|
mnemonic, offset,
|
||||||
|
getNetworkType().getValue());
|
||||||
|
Wallet wallet = new Wallet(walletHandle);
|
||||||
|
manageWallet(wallet);
|
||||||
|
return wallet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private native long recoveryWalletPolyseedJ(String path, String password,
|
||||||
|
String mnemonic, String offset,
|
||||||
|
int networkType);
|
||||||
|
|
||||||
public Wallet createWalletWithKeys(File aFile, String password, String language, long restoreHeight,
|
public Wallet createWalletWithKeys(File aFile, String password, String language, long restoreHeight,
|
||||||
String addressString, String viewKeyString, String spendKeyString) {
|
String addressString, String viewKeyString, String spendKeyString) {
|
||||||
long walletHandle = createWalletFromKeysJ(aFile.getAbsolutePath(), password,
|
long walletHandle = createWalletFromKeysJ(aFile.getAbsolutePath(), password,
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/edittext_bg"
|
android:background="@drawable/edittext_bg"
|
||||||
android:hint="@string/password_optional"
|
android:hint="@string/password_non_optional"
|
||||||
android:inputType="textPassword"
|
android:inputType="textPassword"
|
||||||
android:minHeight="48dp"
|
android:minHeight="48dp"
|
||||||
app:layout_constraintBottom_toTopOf="@id/wallet_password_confirm_edittext"
|
app:layout_constraintBottom_toTopOf="@id/wallet_password_confirm_edittext"
|
||||||
|
@ -56,21 +56,12 @@
|
||||||
android:hint="@string/password_confirm"
|
android:hint="@string/password_confirm"
|
||||||
android:inputType="textPassword"
|
android:inputType="textPassword"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintBottom_toTopOf="@id/seed_offset_checkbox"
|
app:layout_constraintBottom_toTopOf="@id/advanced_settings_dropdown_textview"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/wallet_password_edittext"
|
app:layout_constraintTop_toBottomOf="@id/wallet_password_edittext"
|
||||||
tools:visibility="gone" />
|
tools:visibility="gone" />
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/seed_offset_checkbox"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="48dp"
|
|
||||||
android:text="@string/use_password_as_seed_offset"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/wallet_password_confirm_edittext"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/advanced_settings_dropdown_textview"
|
android:id="@+id/advanced_settings_dropdown_textview"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -85,7 +76,7 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintHorizontal_bias="0.0"
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/seed_offset_checkbox" />
|
app:layout_constraintTop_toBottomOf="@id/wallet_password_confirm_edittext" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/advanced_settings_chevron_imageview"
|
android:id="@+id/advanced_settings_chevron_imageview"
|
||||||
|
@ -131,6 +122,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
android:paddingStart="16dp"
|
android:paddingStart="16dp"
|
||||||
android:paddingEnd="16dp"
|
android:paddingEnd="16dp"
|
||||||
tools:text="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
tools:text="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||||
|
@ -140,6 +132,7 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintHorizontal_bias="0.0"
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/wallet_seed_edittext"
|
||||||
app:layout_constraintTop_toBottomOf="@id/show_xmrchan_switch"
|
app:layout_constraintTop_toBottomOf="@id/show_xmrchan_switch"
|
||||||
tools:ignore="SpeakableTextPresentCheck" />
|
tools:ignore="SpeakableTextPresentCheck" />
|
||||||
|
|
||||||
|
@ -148,7 +141,6 @@
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="16dp"
|
android:layout_marginBottom="16dp"
|
||||||
android:layout_marginTop="32dp"
|
|
||||||
android:background="@drawable/edittext_bg"
|
android:background="@drawable/edittext_bg"
|
||||||
android:hint="@string/recovery_phrase_optional"
|
android:hint="@string/recovery_phrase_optional"
|
||||||
android:minHeight="48dp"
|
android:minHeight="48dp"
|
||||||
|
@ -165,11 +157,23 @@
|
||||||
android:hint="@string/restore_height_optional"
|
android:hint="@string/restore_height_optional"
|
||||||
android:inputType="number"
|
android:inputType="number"
|
||||||
android:minHeight="48dp"
|
android:minHeight="48dp"
|
||||||
app:layout_constraintBottom_toTopOf="@id/tor_onboarding_switch"
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/seed_offset_checkbox"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/wallet_seed_edittext" />
|
app:layout_constraintTop_toBottomOf="@id/wallet_seed_edittext" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/seed_offset_checkbox"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="48dp"
|
||||||
|
android:text="@string/use_password_as_seed_offset"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/tor_onboarding_switch"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/wallet_restore_height_edittext"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tor_onboarding_switch_label"
|
android:id="@+id/tor_onboarding_switch_label"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
@ -189,7 +193,7 @@
|
||||||
android:minWidth="48dp"
|
android:minWidth="48dp"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/wallet_restore_height_edittext" />
|
app:layout_constraintTop_toBottomOf="@id/seed_offset_checkbox" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/wallet_proxy_settings_layout"
|
android:id="@+id/wallet_proxy_settings_layout"
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
<string name="error_creating_tx">Error creating: %1$s</string>
|
<string name="error_creating_tx">Error creating: %1$s</string>
|
||||||
<string name="create_wallet">Create wallet</string>
|
<string name="create_wallet">Create wallet</string>
|
||||||
<string name="invalid_mnemonic_code">Invalid mnemonic</string>
|
<string name="invalid_mnemonic_code">Invalid mnemonic</string>
|
||||||
|
<string name="invalid_empty_passphrase">Please enter a password</string>
|
||||||
<string name="invalid_confirmed_password">Passwords do not match</string>
|
<string name="invalid_confirmed_password">Passwords do not match</string>
|
||||||
<string name="copied_to_clipboard">Copied to clipboard</string>
|
<string name="copied_to_clipboard">Copied to clipboard</string>
|
||||||
<string name="street_mode">Street mode (hide balances)</string>
|
<string name="street_mode">Street mode (hide balances)</string>
|
||||||
|
@ -50,6 +51,7 @@
|
||||||
<string name="recovery_phrase_optional">Recovery phrase (optional)</string>
|
<string name="recovery_phrase_optional">Recovery phrase (optional)</string>
|
||||||
<string name="restore_height_optional">Restore height (optional)</string>
|
<string name="restore_height_optional">Restore height (optional)</string>
|
||||||
<string name="password_optional">Password (optional)</string>
|
<string name="password_optional">Password (optional)</string>
|
||||||
|
<string name="password_non_optional">Enter a password</string>
|
||||||
<string name="password_confirm">Confirm password</string>
|
<string name="password_confirm">Confirm password</string>
|
||||||
<string name="password">Password</string>
|
<string name="password">Password</string>
|
||||||
<string name="label">Label</string>
|
<string name="label">Label</string>
|
||||||
|
|
|
@ -158,6 +158,27 @@ RUN set -x \
|
||||||
&& make -j${NPROC} \
|
&& make -j${NPROC} \
|
||||||
&& make install
|
&& make install
|
||||||
|
|
||||||
|
# polyseed
|
||||||
|
RUN git clone https://github.com/tevador/polyseed.git
|
||||||
|
RUN set -x \
|
||||||
|
&& cd polyseed \
|
||||||
|
&& git reset --hard b7c35bb3c6b91e481ecb04fc235eaff69c507fa1 \
|
||||||
|
&& CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} . \
|
||||||
|
&& make \
|
||||||
|
&& make install
|
||||||
|
|
||||||
|
# utf8proc
|
||||||
|
RUN git clone https://github.com/JuliaStrings/utf8proc -b v2.8.0
|
||||||
|
RUN set -x \
|
||||||
|
&& cd utf8proc \
|
||||||
|
&& git reset --hard 1cb28a66ca79a0845e99433fd1056257456cef8b \
|
||||||
|
&& mkdir build \
|
||||||
|
&& cd build \
|
||||||
|
&& rm -rf ../CMakeCache.txt ../CMakeFiles/ \
|
||||||
|
&& CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} .. \
|
||||||
|
&& make \
|
||||||
|
&& make install
|
||||||
|
|
||||||
COPY . /src
|
COPY . /src
|
||||||
RUN set -x \
|
RUN set -x \
|
||||||
&& cd /src \
|
&& cd /src \
|
||||||
|
|
|
@ -158,6 +158,27 @@ RUN set -x \
|
||||||
&& make -j${NPROC} \
|
&& make -j${NPROC} \
|
||||||
&& make install
|
&& make install
|
||||||
|
|
||||||
|
# polyseed
|
||||||
|
RUN git clone https://github.com/tevador/polyseed.git
|
||||||
|
RUN set -x \
|
||||||
|
&& cd polyseed \
|
||||||
|
&& git reset --hard b7c35bb3c6b91e481ecb04fc235eaff69c507fa1 \
|
||||||
|
&& CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} . \
|
||||||
|
&& make \
|
||||||
|
&& make install
|
||||||
|
|
||||||
|
# utf8proc
|
||||||
|
RUN git clone https://github.com/JuliaStrings/utf8proc -b v2.8.0
|
||||||
|
RUN set -x \
|
||||||
|
&& cd utf8proc \
|
||||||
|
&& git reset --hard 1cb28a66ca79a0845e99433fd1056257456cef8b \
|
||||||
|
&& mkdir build \
|
||||||
|
&& cd build \
|
||||||
|
&& rm -rf ../CMakeCache.txt ../CMakeFiles/ \
|
||||||
|
&& CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} .. \
|
||||||
|
&& make \
|
||||||
|
&& make install
|
||||||
|
|
||||||
COPY . /src
|
COPY . /src
|
||||||
RUN set -x \
|
RUN set -x \
|
||||||
&& cd /src \
|
&& cd /src \
|
||||||
|
|
|
@ -158,6 +158,27 @@ RUN set -x \
|
||||||
&& make -j${NPROC} \
|
&& make -j${NPROC} \
|
||||||
&& make install
|
&& make install
|
||||||
|
|
||||||
|
# polyseed
|
||||||
|
RUN git clone https://github.com/tevador/polyseed.git
|
||||||
|
RUN set -x \
|
||||||
|
&& cd polyseed \
|
||||||
|
&& git reset --hard b7c35bb3c6b91e481ecb04fc235eaff69c507fa1 \
|
||||||
|
&& CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} . \
|
||||||
|
&& make \
|
||||||
|
&& make install
|
||||||
|
|
||||||
|
# utf8proc
|
||||||
|
RUN git clone https://github.com/JuliaStrings/utf8proc -b v2.8.0
|
||||||
|
RUN set -x \
|
||||||
|
&& cd utf8proc \
|
||||||
|
&& git reset --hard 1cb28a66ca79a0845e99433fd1056257456cef8b \
|
||||||
|
&& mkdir build \
|
||||||
|
&& cd build \
|
||||||
|
&& rm -rf ../CMakeCache.txt ../CMakeFiles/ \
|
||||||
|
&& CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} .. \
|
||||||
|
&& make \
|
||||||
|
&& make install
|
||||||
|
|
||||||
COPY . /src
|
COPY . /src
|
||||||
RUN set -x \
|
RUN set -x \
|
||||||
&& cd /src \
|
&& cd /src \
|
||||||
|
|
|
@ -158,6 +158,27 @@ RUN set -x \
|
||||||
&& make -j${NPROC} \
|
&& make -j${NPROC} \
|
||||||
&& make install
|
&& make install
|
||||||
|
|
||||||
|
# polyseed
|
||||||
|
RUN git clone https://github.com/tevador/polyseed.git
|
||||||
|
RUN set -x \
|
||||||
|
&& cd polyseed \
|
||||||
|
&& git reset --hard b7c35bb3c6b91e481ecb04fc235eaff69c507fa1 \
|
||||||
|
&& CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} . \
|
||||||
|
&& make \
|
||||||
|
&& make install
|
||||||
|
|
||||||
|
# utf8proc
|
||||||
|
RUN git clone https://github.com/JuliaStrings/utf8proc -b v2.8.0
|
||||||
|
RUN set -x \
|
||||||
|
&& cd utf8proc \
|
||||||
|
&& git reset --hard 1cb28a66ca79a0845e99433fd1056257456cef8b \
|
||||||
|
&& mkdir build \
|
||||||
|
&& cd build \
|
||||||
|
&& rm -rf ../CMakeCache.txt ../CMakeFiles/ \
|
||||||
|
&& CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} .. \
|
||||||
|
&& make \
|
||||||
|
&& make install
|
||||||
|
|
||||||
COPY . /src
|
COPY . /src
|
||||||
RUN set -x \
|
RUN set -x \
|
||||||
&& cd /src \
|
&& cd /src \
|
||||||
|
|
|
@ -745,6 +745,10 @@ struct Wallet
|
||||||
static void warning(const std::string &category, const std::string &str);
|
static void warning(const std::string &category, const std::string &str);
|
||||||
static void error(const std::string &category, const std::string &str);
|
static void error(const std::string &category, const std::string &str);
|
||||||
|
|
||||||
|
virtual bool getPolyseed(std::string &seed, std::string &passphrase) const = 0;
|
||||||
|
static bool createPolyseed(std::string &seed_words, std::string &err, const std::string &language = "English");
|
||||||
|
static std::vector<std::pair<std::string, std::string>> getPolyseedLanguages();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief StartRefresh - Start/resume refresh thread (refresh every 10 seconds)
|
* @brief StartRefresh - Start/resume refresh thread (refresh every 10 seconds)
|
||||||
*/
|
*/
|
||||||
|
@ -1304,6 +1308,27 @@ struct WalletManager
|
||||||
uint64_t kdf_rounds = 1,
|
uint64_t kdf_rounds = 1,
|
||||||
WalletListener * listener = nullptr) = 0;
|
WalletListener * listener = nullptr) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief creates a wallet from a polyseed mnemonic phrase
|
||||||
|
* \param path Name of the wallet file to be created
|
||||||
|
* \param password Password of wallet file
|
||||||
|
* \param nettype Network type
|
||||||
|
* \param mnemonic Polyseed mnemonic
|
||||||
|
* \param passphrase Optional seed offset passphrase
|
||||||
|
* \param newWallet Whether it is a new wallet
|
||||||
|
* \param restoreHeight Override the embedded restore height
|
||||||
|
* \param kdf_rounds Number of rounds for key derivation function
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual Wallet * createWalletFromPolyseed(const std::string &path,
|
||||||
|
const std::string &password,
|
||||||
|
NetworkType nettype,
|
||||||
|
const std::string &mnemonic,
|
||||||
|
const std::string &passphrase = "",
|
||||||
|
bool newWallet = true,
|
||||||
|
uint64_t restore_height = 0,
|
||||||
|
uint64_t kdf_rounds = 1) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Closes wallet. In case operation succeeded, wallet object deleted. in case operation failed, wallet object not deleted
|
* \brief Closes wallet. In case operation succeeded, wallet object deleted. in case operation failed, wallet object not deleted
|
||||||
* \param wallet previously opened / created wallet instance
|
* \param wallet previously opened / created wallet instance
|
||||||
|
|
Loading…
Reference in a new issue