summaryrefslogtreecommitdiff
path: root/libbridge/src/main/cpp/wallet2_api_c.cpp
diff options
context:
space:
mode:
authorCzarek Nakamoto <cyjan@mrcyjanek.net>2023-12-26 21:43:14 +0100
committerCzarek Nakamoto <cyjan@mrcyjanek.net>2023-12-26 21:43:14 +0100
commit0f612f0bbe592c750d66985caab81a8245d03993 (patch)
treeefa32af249727b78c42b6788c51f6944907cf782 /libbridge/src/main/cpp/wallet2_api_c.cpp
Initial commit
Diffstat (limited to 'libbridge/src/main/cpp/wallet2_api_c.cpp')
-rw-r--r--libbridge/src/main/cpp/wallet2_api_c.cpp1722
1 files changed, 1722 insertions, 0 deletions
diff --git a/libbridge/src/main/cpp/wallet2_api_c.cpp b/libbridge/src/main/cpp/wallet2_api_c.cpp
new file mode 100644
index 0000000..8a74b48
--- /dev/null
+++ b/libbridge/src/main/cpp/wallet2_api_c.cpp
@@ -0,0 +1,1722 @@
+/**
+ * Copyright (c) 2017 m2049r
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <inttypes.h>
+#include "wallet2_api_c.h"
+#include "wallet2_api.h"
+
+//TODO explicit casting jlong, jint, jboolean to avoid warnings
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <android/log.h>
+#define LOG_TAG "WalletNDK"
+#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,__VA_ARGS__)
+#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , LOG_TAG,__VA_ARGS__)
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , LOG_TAG,__VA_ARGS__)
+#define LOGW(...) __android_log_print(ANDROID_LOG_WARN , LOG_TAG,__VA_ARGS__)
+#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , LOG_TAG,__VA_ARGS__)
+
+static JavaVM *cachedJVM;
+static jclass class_String;
+static jclass class_ArrayList;
+static jclass class_WalletListener;
+static jclass class_CoinsInfo;
+static jclass class_TransactionInfo;
+static jclass class_Transfer;
+static jclass class_Ledger;
+static jclass class_WalletStatus;
+
+std::mutex _listenerMutex;
+
+//void jstringToString(JNIEnv *env, std::string &str, jstring jstr) {
+// if (!jstr) return;
+// const int len = env->GetStringUTFLength(jstr);
+// const char *chars = env->GetStringUTFChars(jstr, nullptr);
+// str.assign(chars, len);
+// env->ReleaseStringUTFChars(jstr, chars);
+//}
+
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
+ cachedJVM = jvm;
+ LOGI("JNI_OnLoad");
+ JNIEnv *jenv;
+ if (jvm->GetEnv(reinterpret_cast<void **>(&jenv), JNI_VERSION_1_6) != JNI_OK) {
+ return -1;
+ }
+ //LOGI("JNI_OnLoad ok");
+
+ class_String = static_cast<jclass>(jenv->NewGlobalRef(
+ jenv->FindClass("java/lang/String")));
+ class_ArrayList = static_cast<jclass>(jenv->NewGlobalRef(
+ jenv->FindClass("java/util/ArrayList")));
+ class_CoinsInfo = static_cast<jclass>(jenv->NewGlobalRef(
+ jenv->FindClass("com/m2049r/xmrwallet/model/CoinsInfo")));
+ class_TransactionInfo = static_cast<jclass>(jenv->NewGlobalRef(
+ jenv->FindClass("com/m2049r/xmrwallet/model/TransactionInfo")));
+ class_Transfer = static_cast<jclass>(jenv->NewGlobalRef(
+ jenv->FindClass("com/m2049r/xmrwallet/model/Transfer")));
+ class_WalletListener = static_cast<jclass>(jenv->NewGlobalRef(
+ jenv->FindClass("com/m2049r/xmrwallet/model/WalletListener")));
+ class_Ledger = static_cast<jclass>(jenv->NewGlobalRef(
+ jenv->FindClass("com/m2049r/xmrwallet/ledger/Ledger")));
+ class_WalletStatus = static_cast<jclass>(jenv->NewGlobalRef(
+ jenv->FindClass("com/m2049r/xmrwallet/model/Wallet$Status")));
+ return JNI_VERSION_1_6;
+}
+#ifdef __cplusplus
+}
+#endif
+
+int attachJVM(JNIEnv **jenv) {
+ int envStat = cachedJVM->GetEnv((void **) jenv, JNI_VERSION_1_6);
+ if (envStat == JNI_EDETACHED) {
+ if (cachedJVM->AttachCurrentThread(jenv, nullptr) != 0) {
+ LOGE("Failed to attach");
+ return JNI_ERR;
+ }
+ } else if (envStat == JNI_EVERSION) {
+ LOGE("GetEnv: version not supported");
+ return JNI_ERR;
+ }
+ //LOGI("envStat=%i", envStat);
+ return envStat;
+}
+
+void detachJVM(JNIEnv *jenv, int envStat) {
+ //LOGI("envStat=%i", envStat);
+ if (jenv->ExceptionCheck()) {
+ jenv->ExceptionDescribe();
+ }
+
+ if (envStat == JNI_EDETACHED) {
+ cachedJVM->DetachCurrentThread();
+ }
+}
+
+struct MyWalletListener : Monero::WalletListener {
+ jobject jlistener;
+
+ MyWalletListener(JNIEnv *env, jobject aListener) {
+ LOGD("Created MyListener");
+ jlistener = env->NewGlobalRef(aListener);;
+ }
+
+ ~MyWalletListener() {
+ LOGD("Destroyed MyListener");
+ };
+
+ void deleteGlobalJavaRef(JNIEnv *env) {
+ std::lock_guard<std::mutex> lock(_listenerMutex);
+ env->DeleteGlobalRef(jlistener);
+ jlistener = nullptr;
+ }
+
+ /**
+ * @brief updated - generic callback, called when any event (sent/received/block reveived/etc) happened with the wallet;
+ */
+ void updated() {
+ std::lock_guard<std::mutex> lock(_listenerMutex);
+ if (jlistener == nullptr) return;
+ LOGD("updated");
+ JNIEnv *jenv;
+ int envStat = attachJVM(&jenv);
+ if (envStat == JNI_ERR) return;
+
+ jmethodID listenerClass_updated = jenv->GetMethodID(class_WalletListener, "updated", "()V");
+ jenv->CallVoidMethod(jlistener, listenerClass_updated);
+
+ detachJVM(jenv, envStat);
+ }
+
+
+ /**
+ * @brief moneySpent - called when money spent
+ * @param txId - transaction id
+ * @param amount - amount
+ */
+ void moneySpent(const std::string &txId, uint64_t amount) {
+ std::lock_guard<std::mutex> lock(_listenerMutex);
+ if (jlistener == nullptr) return;
+ LOGD("moneySpent %"
+ PRIu64, amount);
+ }
+
+ /**
+ * @brief moneyReceived - called when money received
+ * @param txId - transaction id
+ * @param amount - amount
+ */
+ void moneyReceived(const std::string &txId, uint64_t amount) {
+ std::lock_guard<std::mutex> lock(_listenerMutex);
+ if (jlistener == nullptr) return;
+ LOGD("moneyReceived %"
+ PRIu64, amount);
+ }
+
+ /**
+ * @brief unconfirmedMoneyReceived - called when payment arrived in tx pool
+ * @param txId - transaction id
+ * @param amount - amount
+ */
+ void unconfirmedMoneyReceived(const std::string &txId, uint64_t amount) {
+ std::lock_guard<std::mutex> lock(_listenerMutex);
+ if (jlistener == nullptr) return;
+ LOGD("unconfirmedMoneyReceived %"
+ PRIu64, amount);
+ }
+
+ /**
+ * @brief newBlock - called when new block received
+ * @param height - block height
+ */
+ void newBlock(uint64_t height) {
+ std::lock_guard<std::mutex> lock(_listenerMutex);
+ if (jlistener == nullptr) return;
+ //LOGD("newBlock");
+ JNIEnv *jenv;
+ int envStat = attachJVM(&jenv);
+ if (envStat == JNI_ERR) return;
+
+ jlong h = static_cast<jlong>(height);
+ jmethodID listenerClass_newBlock = jenv->GetMethodID(class_WalletListener, "newBlock",
+ "(J)V");
+ jenv->CallVoidMethod(jlistener, listenerClass_newBlock, h);
+
+ detachJVM(jenv, envStat);
+ }
+
+/**
+ * @brief refreshed - called when wallet refreshed by background thread or explicitly refreshed by calling "refresh" synchronously
+ */
+ void refreshed() {
+ std::lock_guard<std::mutex> lock(_listenerMutex);
+ if (jlistener == nullptr) return;
+ LOGD("refreshed");
+ JNIEnv *jenv;
+
+ int envStat = attachJVM(&jenv);
+ if (envStat == JNI_ERR) return;
+
+ jmethodID listenerClass_refreshed = jenv->GetMethodID(class_WalletListener, "refreshed",
+ "()V");
+ jenv->CallVoidMethod(jlistener, listenerClass_refreshed);
+ detachJVM(jenv, envStat);
+ }
+};
+
+
+//// helper methods
+std::vector<std::string> java2cpp(JNIEnv *env, jobject arrayList) {
+
+ jmethodID java_util_ArrayList_size = env->GetMethodID(class_ArrayList, "size", "()I");
+ jmethodID java_util_ArrayList_get = env->GetMethodID(class_ArrayList, "get",
+ "(I)Ljava/lang/Object;");
+
+ jint len = env->CallIntMethod(arrayList, java_util_ArrayList_size);
+ std::vector<std::string> result;
+ result.reserve(len);
+ for (jint i = 0; i < len; i++) {
+ jstring element = static_cast<jstring>(env->CallObjectMethod(arrayList,
+ java_util_ArrayList_get, i));
+ const char *pchars = env->GetStringUTFChars(element, nullptr);
+ result.emplace_back(pchars);
+ env->ReleaseStringUTFChars(element, pchars);
+ env->DeleteLocalRef(element);
+ }
+ return result;
+}
+
+jobject cpp2java(JNIEnv *env, const std::vector<std::string> &vector) {
+
+ jmethodID java_util_ArrayList_ = env->GetMethodID(class_ArrayList, "<init>", "(I)V");
+ jmethodID java_util_ArrayList_add = env->GetMethodID(class_ArrayList, "add",
+ "(Ljava/lang/Object;)Z");
+
+ jobject result = env->NewObject(class_ArrayList, java_util_ArrayList_,
+ static_cast<jint> (vector.size()));
+ for (const std::string &s: vector) {
+ jstring element = env->NewStringUTF(s.c_str());
+ env->CallBooleanMethod(result, java_util_ArrayList_add, element);
+ env->DeleteLocalRef(element);
+ }
+ return result;
+}
+
+/// end helpers
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+// void* MONERO_createWalletJ(const char* path, const char* password, const char* language, int networkType);
+void* MONERO_createWalletJ(const char* path, const char* password, const char* language, int networkType) {
+ Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
+
+ std::cout << "WE GOT OUT\n";
+
+ std::string _path(path);
+ std::string _password(password);
+ std::string _language(language);
+ std::cout << "_path = " << _path << "\n";
+ std::cout << "_password = " << _password << "\n";
+ std::cout << "_language = " << _language << "\n";
+
+ Monero::Wallet *wallet =
+ Monero::WalletManagerFactory::getWalletManager()->createWallet(
+ _path,
+ _password,
+ _language,
+ _networkType);
+
+ int status;
+ std::string errorString;
+ wallet->statusWithErrorString(status, errorString);
+
+ std::cout << status << " - " << errorString << "\n";
+
+ return reinterpret_cast<void*>(wallet);
+}
+
+
+
+
+/**********************************/
+/********** WalletManager *********/
+/**********************************/
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_createWalletJ(JNIEnv *env, jobject instance,
+ jstring path, jstring password,
+ jstring language,
+ jint networkType) {
+ const char *_path = env->GetStringUTFChars(path, nullptr);
+ const char *_password = env->GetStringUTFChars(password, nullptr);
+ const char *_language = env->GetStringUTFChars(language, nullptr);
+ Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
+
+ Monero::Wallet *wallet =
+ Monero::WalletManagerFactory::getWalletManager()->createWallet(
+ std::string(_path),
+ std::string(_password),
+ std::string(_language),
+ _networkType);
+
+ env->ReleaseStringUTFChars(path, _path);
+ env->ReleaseStringUTFChars(password, _password);
+ env->ReleaseStringUTFChars(language, _language);
+ return reinterpret_cast<jlong>(wallet);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_openWalletJ(JNIEnv *env, jobject instance,
+ jstring path, jstring password,
+ jint networkType) {
+ const char *_path = env->GetStringUTFChars(path, nullptr);
+ const char *_password = env->GetStringUTFChars(password, nullptr);
+ Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
+
+ Monero::Wallet *wallet =
+ Monero::WalletManagerFactory::getWalletManager()->openWallet(
+ std::string(_path),
+ std::string(_password),
+ _networkType);
+
+ env->ReleaseStringUTFChars(path, _path);
+ env->ReleaseStringUTFChars(password, _password);
+ return reinterpret_cast<jlong>(wallet);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_recoveryWalletJ(JNIEnv *env, jobject instance,
+ jstring path, jstring password,
+ jstring mnemonic, jstring offset,
+ jint networkType,
+ jlong restoreHeight) {
+ 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()->recoveryWallet(
+ std::string(_path),
+ std::string(_password),
+ std::string(_mnemonic),
+ _networkType,
+ (uint64_t) restoreHeight,
+ 1, // kdf_rounds
+ std::string(_offset));
+
+ env->ReleaseStringUTFChars(path, _path);
+ env->ReleaseStringUTFChars(password, _password);
+ env->ReleaseStringUTFChars(mnemonic, _mnemonic);
+ env->ReleaseStringUTFChars(offset, _offset);
+ return reinterpret_cast<jlong>(wallet);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_createWalletFromKeysJ(JNIEnv *env, jobject instance,
+ jstring path, jstring password,
+ jstring language,
+ jint networkType,
+ jlong restoreHeight,
+ jstring addressString,
+ jstring viewKeyString,
+ jstring spendKeyString) {
+ const char *_path = env->GetStringUTFChars(path, nullptr);
+ const char *_password = env->GetStringUTFChars(password, nullptr);
+ const char *_language = env->GetStringUTFChars(language, nullptr);
+ Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
+ const char *_addressString = env->GetStringUTFChars(addressString, nullptr);
+ const char *_viewKeyString = env->GetStringUTFChars(viewKeyString, nullptr);
+ const char *_spendKeyString = env->GetStringUTFChars(spendKeyString, nullptr);
+
+ Monero::Wallet *wallet =
+ Monero::WalletManagerFactory::getWalletManager()->createWalletFromKeys(
+ std::string(_path),
+ std::string(_password),
+ std::string(_language),
+ _networkType,
+ (uint64_t) restoreHeight,
+ std::string(_addressString),
+ std::string(_viewKeyString),
+ std::string(_spendKeyString));
+
+ env->ReleaseStringUTFChars(path, _path);
+ env->ReleaseStringUTFChars(password, _password);
+ env->ReleaseStringUTFChars(language, _language);
+ env->ReleaseStringUTFChars(addressString, _addressString);
+ env->ReleaseStringUTFChars(viewKeyString, _viewKeyString);
+ env->ReleaseStringUTFChars(spendKeyString, _spendKeyString);
+ return reinterpret_cast<jlong>(wallet);
+}
+
+
+// virtual void setSubaddressLookahead(uint32_t major, uint32_t minor) = 0;
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_createWalletFromDeviceJ(JNIEnv *env, jobject instance,
+ jstring path,
+ jstring password,
+ jint networkType,
+ jstring deviceName,
+ jlong restoreHeight,
+ jstring subaddressLookahead) {
+ const char *_path = env->GetStringUTFChars(path, nullptr);
+ const char *_password = env->GetStringUTFChars(password, nullptr);
+ Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
+ const char *_deviceName = env->GetStringUTFChars(deviceName, nullptr);
+ const char *_subaddressLookahead = env->GetStringUTFChars(subaddressLookahead, nullptr);
+
+ Monero::Wallet *wallet =
+ Monero::WalletManagerFactory::getWalletManager()->createWalletFromDevice(
+ std::string(_path),
+ std::string(_password),
+ _networkType,
+ std::string(_deviceName),
+ (uint64_t) restoreHeight,
+ std::string(_subaddressLookahead));
+
+ env->ReleaseStringUTFChars(path, _path);
+ env->ReleaseStringUTFChars(password, _password);
+ env->ReleaseStringUTFChars(deviceName, _deviceName);
+ env->ReleaseStringUTFChars(subaddressLookahead, _subaddressLookahead);
+ return reinterpret_cast<jlong>(wallet);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_walletExists(JNIEnv *env, jobject instance,
+ jstring path) {
+ const char *_path = env->GetStringUTFChars(path, nullptr);
+ bool exists =
+ Monero::WalletManagerFactory::getWalletManager()->walletExists(std::string(_path));
+ env->ReleaseStringUTFChars(path, _path);
+ return static_cast<jboolean>(exists);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_verifyWalletPassword(JNIEnv *env, jobject instance,
+ jstring keys_file_name,
+ jstring password,
+ jboolean watch_only) {
+ const char *_keys_file_name = env->GetStringUTFChars(keys_file_name, nullptr);
+ const char *_password = env->GetStringUTFChars(password, nullptr);
+ bool passwordOk =
+ Monero::WalletManagerFactory::getWalletManager()->verifyWalletPassword(
+ std::string(_keys_file_name), std::string(_password), watch_only);
+ env->ReleaseStringUTFChars(keys_file_name, _keys_file_name);
+ env->ReleaseStringUTFChars(password, _password);
+ return static_cast<jboolean>(passwordOk);
+}
+
+//virtual int queryWalletHardware(const std::string &keys_file_name, const std::string &password) const = 0;
+JNIEXPORT jint JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_queryWalletDeviceJ(JNIEnv *env, jobject instance,
+ jstring keys_file_name,
+ jstring password) {
+ const char *_keys_file_name = env->GetStringUTFChars(keys_file_name, nullptr);
+ const char *_password = env->GetStringUTFChars(password, nullptr);
+ Monero::Wallet::Device device_type;
+ bool ok = Monero::WalletManagerFactory::getWalletManager()->
+ queryWalletDevice(device_type, std::string(_keys_file_name), std::string(_password));
+ env->ReleaseStringUTFChars(keys_file_name, _keys_file_name);
+ env->ReleaseStringUTFChars(password, _password);
+ if (ok)
+ return static_cast<jint>(device_type);
+ else
+ return -1;
+}
+
+JNIEXPORT jobject JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_findWallets(JNIEnv *env, jobject instance,
+ jstring path) {
+ const char *_path = env->GetStringUTFChars(path, nullptr);
+ std::vector<std::string> walletPaths =
+ Monero::WalletManagerFactory::getWalletManager()->findWallets(std::string(_path));
+ env->ReleaseStringUTFChars(path, _path);
+ return cpp2java(env, walletPaths);
+}
+
+//TODO virtual bool checkPayment(const std::string &address, const std::string &txid, const std::string &txkey, const std::string &daemon_address, uint64_t &received, uint64_t &height, std::string &error) const = 0;
+
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_setDaemonAddressJ(JNIEnv *env, jobject instance,
+ jstring address) {
+ const char *_address = env->GetStringUTFChars(address, nullptr);
+ Monero::WalletManagerFactory::getWalletManager()->setDaemonAddress(std::string(_address));
+ env->ReleaseStringUTFChars(address, _address);
+}
+
+// returns whether the daemon can be reached, and its version number
+JNIEXPORT jint JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_getDaemonVersion(JNIEnv *env,
+ jobject instance) {
+ uint32_t version;
+ bool isConnected =
+ Monero::WalletManagerFactory::getWalletManager()->connected(&version);
+ if (!isConnected) version = 0;
+ return version;
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_getBlockchainHeight(JNIEnv *env, jobject instance) {
+ return Monero::WalletManagerFactory::getWalletManager()->blockchainHeight();
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_getBlockchainTargetHeight(JNIEnv *env,
+ jobject instance) {
+ return Monero::WalletManagerFactory::getWalletManager()->blockchainTargetHeight();
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_getNetworkDifficulty(JNIEnv *env, jobject instance) {
+ return Monero::WalletManagerFactory::getWalletManager()->networkDifficulty();
+}
+
+JNIEXPORT jdouble JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_getMiningHashRate(JNIEnv *env, jobject instance) {
+ return Monero::WalletManagerFactory::getWalletManager()->miningHashRate();
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_getBlockTarget(JNIEnv *env, jobject instance) {
+ return Monero::WalletManagerFactory::getWalletManager()->blockTarget();
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_isMining(JNIEnv *env, jobject instance) {
+ return static_cast<jboolean>(Monero::WalletManagerFactory::getWalletManager()->isMining());
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_startMining(JNIEnv *env, jobject instance,
+ jstring address,
+ jboolean background_mining,
+ jboolean ignore_battery) {
+ const char *_address = env->GetStringUTFChars(address, nullptr);
+ bool success =
+ Monero::WalletManagerFactory::getWalletManager()->startMining(std::string(_address),
+ background_mining,
+ ignore_battery);
+ env->ReleaseStringUTFChars(address, _address);
+ return static_cast<jboolean>(success);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_stopMining(JNIEnv *env, jobject instance) {
+ return static_cast<jboolean>(Monero::WalletManagerFactory::getWalletManager()->stopMining());
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_resolveOpenAlias(JNIEnv *env, jobject instance,
+ jstring address,
+ jboolean dnssec_valid) {
+ const char *_address = env->GetStringUTFChars(address, nullptr);
+ bool _dnssec_valid = (bool) dnssec_valid;
+ std::string resolvedAlias =
+ Monero::WalletManagerFactory::getWalletManager()->resolveOpenAlias(
+ std::string(_address),
+ _dnssec_valid);
+ env->ReleaseStringUTFChars(address, _address);
+ return env->NewStringUTF(resolvedAlias.c_str());
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_setProxy(JNIEnv *env, jobject instance,
+ jstring address) {
+ const char *_address = env->GetStringUTFChars(address, nullptr);
+ bool rc =
+ Monero::WalletManagerFactory::getWalletManager()->setProxy(std::string(_address));
+ env->ReleaseStringUTFChars(address, _address);
+ return rc;
+}
+
+
+//TODO static std::tuple<bool, std::string, std::string, std::string, std::string> checkUpdates(const std::string &software, const std::string &subdir);
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_closeJ(JNIEnv *env, jobject instance,
+ jobject walletInstance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, walletInstance);
+ bool closeSuccess = Monero::WalletManagerFactory::getWalletManager()->closeWallet(wallet,
+ false);
+ if (closeSuccess) {
+ MyWalletListener *walletListener = getHandle<MyWalletListener>(env, walletInstance,
+ "listenerHandle");
+ if (walletListener != nullptr) {
+ walletListener->deleteGlobalJavaRef(env);
+ delete walletListener;
+ }
+ }
+ LOGD("wallet closed");
+ return static_cast<jboolean>(closeSuccess);
+}
+
+
+
+
+/**********************************/
+/************ Wallet **************/
+/**********************************/
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getSeed(JNIEnv *env, jobject instance, jstring seedOffset) {
+ const char *_seedOffset = env->GetStringUTFChars(seedOffset, nullptr);
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ jstring seed = env->NewStringUTF(wallet->seed(std::string(_seedOffset)).c_str());
+ env->ReleaseStringUTFChars(seedOffset, _seedOffset);
+ return seed;
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getSeedLanguage(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return env->NewStringUTF(wallet->getSeedLanguage().c_str());
+}
+
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_setSeedLanguage(JNIEnv *env, jobject instance,
+ jstring language) {
+ const char *_language = env->GetStringUTFChars(language, nullptr);
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ wallet->setSeedLanguage(std::string(_language));
+ env->ReleaseStringUTFChars(language, _language);
+}
+
+JNIEXPORT jint JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getStatusJ(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return wallet->status();
+}
+
+jobject newWalletStatusInstance(JNIEnv *env, int status, const std::string &errorString) {
+ jmethodID init = env->GetMethodID(class_WalletStatus, "<init>",
+ "(ILjava/lang/String;)V");
+ jstring _errorString = env->NewStringUTF(errorString.c_str());
+ jobject instance = env->NewObject(class_WalletStatus, init, status, _errorString);
+ env->DeleteLocalRef(_errorString);
+ return instance;
+}
+
+
+JNIEXPORT jobject JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_statusWithErrorString(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+
+ int status;
+ std::string errorString;
+ wallet->statusWithErrorString(status, errorString);
+
+ return newWalletStatusInstance(env, status, errorString);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_setPassword(JNIEnv *env, jobject instance,
+ jstring password) {
+ const char *_password = env->GetStringUTFChars(password, nullptr);
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ bool success = wallet->setPassword(std::string(_password));
+ env->ReleaseStringUTFChars(password, _password);
+ return static_cast<jboolean>(success);
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getAddressJ(JNIEnv *env, jobject instance,
+ jint accountIndex,
+ jint addressIndex) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return env->NewStringUTF(
+ wallet->address((uint32_t) accountIndex, (uint32_t) addressIndex).c_str());
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getPath(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return env->NewStringUTF(wallet->path().c_str());
+}
+
+JNIEXPORT jint JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_nettype(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return wallet->nettype();
+}
+
+//TODO virtual void hardForkInfo(uint8_t &version, uint64_t &earliest_height) const = 0;
+//TODO virtual bool useForkRules(uint8_t version, int64_t early_blocks) const = 0;
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getIntegratedAddress(JNIEnv *env, jobject instance,
+ jstring payment_id) {
+ const char *_payment_id = env->GetStringUTFChars(payment_id, nullptr);
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ std::string address = wallet->integratedAddress(_payment_id);
+ env->ReleaseStringUTFChars(payment_id, _payment_id);
+ return env->NewStringUTF(address.c_str());
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getSecretViewKey(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return env->NewStringUTF(wallet->secretViewKey().c_str());
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getSecretSpendKey(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return env->NewStringUTF(wallet->secretSpendKey().c_str());
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_store(JNIEnv *env, jobject instance,
+ jstring path) {
+ const char *_path = env->GetStringUTFChars(path, nullptr);
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ bool success = wallet->store(std::string(_path));
+ if (!success) {
+ LOGE("store() %s", wallet->errorString().c_str());
+ }
+ env->ReleaseStringUTFChars(path, _path);
+ return static_cast<jboolean>(success);
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getFilename(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return env->NewStringUTF(wallet->filename().c_str());
+}
+
+// virtual std::string keysFilename() const = 0;
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_initJ(JNIEnv *env, jobject instance,
+ jstring daemon_address,
+ jlong upper_transaction_size_limit,
+ jstring daemon_username, jstring daemon_password) {
+ const char *_daemon_address = env->GetStringUTFChars(daemon_address, nullptr);
+ const char *_daemon_username = env->GetStringUTFChars(daemon_username, nullptr);
+ const char *_daemon_password = env->GetStringUTFChars(daemon_password, nullptr);
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ bool status = wallet->init(_daemon_address, (uint64_t) upper_transaction_size_limit,
+ _daemon_username,
+ _daemon_password);
+ env->ReleaseStringUTFChars(daemon_address, _daemon_address);
+ env->ReleaseStringUTFChars(daemon_username, _daemon_username);
+ env->ReleaseStringUTFChars(daemon_password, _daemon_password);
+ return static_cast<jboolean>(status);
+}
+
+// virtual bool createWatchOnly(const std::string &path, const std::string &password, const std::string &language) const = 0;
+
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_setRestoreHeight(JNIEnv *env, jobject instance,
+ jlong height) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ wallet->setRefreshFromBlockHeight((uint64_t) height);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getRestoreHeight(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return wallet->getRefreshFromBlockHeight();
+}
+
+// virtual void setRecoveringFromSeed(bool recoveringFromSeed) = 0;
+// virtual bool connectToDaemon() = 0;
+
+JNIEXPORT jint JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getConnectionStatusJ(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return wallet->connected();
+}
+//TODO virtual void setTrustedDaemon(bool arg) = 0;
+//TODO virtual bool trustedDaemon() const = 0;
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_setProxy(JNIEnv *env, jobject instance,
+ jstring address) {
+ const char *_address = env->GetStringUTFChars(address, nullptr);
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ bool rc = wallet->setProxy(std::string(_address));
+ env->ReleaseStringUTFChars(address, _address);
+ return rc;
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getBalance(JNIEnv *env, jobject instance,
+ jint accountIndex) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return wallet->balance((uint32_t) accountIndex);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getBalanceAll(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return wallet->balanceAll();
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getUnlockedBalance(JNIEnv *env, jobject instance,
+ jint accountIndex) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return wallet->unlockedBalance((uint32_t) accountIndex);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getUnlockedBalanceAll(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return wallet->unlockedBalanceAll();
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_isWatchOnly(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return static_cast<jboolean>(wallet->watchOnly());
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getBlockChainHeight(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return wallet->blockChainHeight();
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getApproximateBlockChainHeight(JNIEnv *env,
+ jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return wallet->approximateBlockChainHeight();
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getDaemonBlockChainHeight(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return wallet->daemonBlockChainHeight();
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getDaemonBlockChainTargetHeight(JNIEnv *env,
+ jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return wallet->daemonBlockChainTargetHeight();
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_isSynchronizedJ(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return static_cast<jboolean>(wallet->synchronized());
+}
+
+JNIEXPORT jint JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getDeviceTypeJ(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ Monero::Wallet::Device device_type = wallet->getDeviceType();
+ return static_cast<jint>(device_type);
+}
+
+//void cn_slow_hash(const void *data, size_t length, char *hash); // from crypto/hash-ops.h
+JNIEXPORT jbyteArray JNICALL
+Java_com_m2049r_xmrwallet_util_KeyStoreHelper_slowHash(JNIEnv *env, jclass clazz,
+ jbyteArray data, jint brokenVariant) {
+ char hash[HASH_SIZE];
+ jsize size = env->GetArrayLength(data);
+ if ((brokenVariant > 0) && (size < 200 /*sizeof(union hash_state)*/)) {
+ return nullptr;
+ }
+
+ jbyte *buffer = env->GetByteArrayElements(data, nullptr);
+ switch (brokenVariant) {
+ case 1:
+ slow_hash_broken(buffer, hash, 1);
+ break;
+ case 2:
+ slow_hash_broken(buffer, hash, 0);
+ break;
+ default: // not broken
+ slow_hash(buffer, (size_t) size, hash);
+ }
+ env->ReleaseByteArrayElements(data, buffer, JNI_ABORT); // do not update java byte[]
+ jbyteArray result = env->NewByteArray(HASH_SIZE);
+ env->SetByteArrayRegion(result, 0, HASH_SIZE, (jbyte *) hash);
+ return result;
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getDisplayAmount(JNIEnv *env, jclass clazz,
+ jlong amount) {
+ return env->NewStringUTF(Monero::Wallet::displayAmount(amount).c_str());
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getAmountFromString(JNIEnv *env, jclass clazz,
+ jstring amount) {
+ const char *_amount = env->GetStringUTFChars(amount, nullptr);
+ uint64_t x = Monero::Wallet::amountFromString(_amount);
+ env->ReleaseStringUTFChars(amount, _amount);
+ return x;
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getAmountFromDouble(JNIEnv *env, jclass clazz,
+ jdouble amount) {
+ return Monero::Wallet::amountFromDouble(amount);
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_generatePaymentId(JNIEnv *env, jclass clazz) {
+ return env->NewStringUTF(Monero::Wallet::genPaymentId().c_str());
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_isPaymentIdValid(JNIEnv *env, jclass clazz,
+ jstring payment_id) {
+ const char *_payment_id = env->GetStringUTFChars(payment_id, nullptr);
+ bool isValid = Monero::Wallet::paymentIdValid(_payment_id);
+ env->ReleaseStringUTFChars(payment_id, _payment_id);
+ return static_cast<jboolean>(isValid);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_isAddressValid(JNIEnv *env, jclass clazz,
+ jstring address, jint networkType) {
+ const char *_address = env->GetStringUTFChars(address, nullptr);
+ Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
+ bool isValid = Monero::Wallet::addressValid(_address, _networkType);
+ env->ReleaseStringUTFChars(address, _address);
+ return static_cast<jboolean>(isValid);
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getPaymentIdFromAddress(JNIEnv *env, jclass clazz,
+ jstring address,
+ jint networkType) {
+ Monero::NetworkType _networkType = static_cast<Monero::NetworkType>(networkType);
+ const char *_address = env->GetStringUTFChars(address, nullptr);
+ std::string payment_id = Monero::Wallet::paymentIdFromAddress(_address, _networkType);
+ env->ReleaseStringUTFChars(address, _address);
+ return env->NewStringUTF(payment_id.c_str());
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getMaximumAllowedAmount(JNIEnv *env, jclass clazz) {
+ return Monero::Wallet::maximumAllowedAmount();
+}
+
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_startRefresh(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ wallet->startRefresh();
+}
+
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_pauseRefresh(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ wallet->pauseRefresh();
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_refresh(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return static_cast<jboolean>(wallet->refresh());
+}
+
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_refreshAsync(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ wallet->refreshAsync();
+}
+
+//TODO virtual bool rescanBlockchain() = 0;
+
+//virtual void rescanBlockchainAsync() = 0;
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_rescanBlockchainAsyncJ(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ wallet->rescanBlockchainAsync();
+}
+
+
+//TODO virtual void setAutoRefreshInterval(int millis) = 0;
+//TODO virtual int autoRefreshInterval() const = 0;
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_createTransactionMultDest(JNIEnv *env, jobject instance,
+ jobjectArray destinations,
+ jstring payment_id,
+ jlongArray amounts,
+ jint mixin_count,
+ jint priority,
+ jint accountIndex,
+ jintArray subaddresses) {
+ std::vector<std::string> dst_addr;
+ std::vector<uint64_t> amount;
+
+ int destSize = env->GetArrayLength(destinations);
+ assert(destSize == env->GetArrayLength(amounts));
+ jlong *_amounts = env->GetLongArrayElements(amounts, nullptr);
+ for (int i = 0; i < destSize; i++) {
+ jstring dest = (jstring) env->GetObjectArrayElement(destinations, i);
+ const char *_dest = env->GetStringUTFChars(dest, nullptr);
+ dst_addr.emplace_back(_dest);
+ env->ReleaseStringUTFChars(dest, _dest);
+ amount.emplace_back((uint64_t) _amounts[i]);
+ }
+ env->ReleaseLongArrayElements(amounts, _amounts, 0);
+
+ std::set<uint32_t> subaddr_indices;
+ if (subaddresses != nullptr) {
+ int subaddrSize = env->GetArrayLength(subaddresses);
+ jint *_subaddresses = env->GetIntArrayElements(subaddresses, nullptr);
+ for (int i = 0; i < subaddrSize; i++) {
+ subaddr_indices.insert((uint32_t) _subaddresses[i]);
+ }
+ env->ReleaseIntArrayElements(subaddresses, _subaddresses, 0);
+ }
+
+ const char *_payment_id = env->GetStringUTFChars(payment_id, nullptr);
+
+ Monero::PendingTransaction::Priority _priority =
+ static_cast<Monero::PendingTransaction::Priority>(priority);
+
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+
+ Monero::PendingTransaction *tx =
+ wallet->createTransactionMultDest(dst_addr, _payment_id,
+ amount, (uint32_t) mixin_count,
+ _priority,
+ (uint32_t) accountIndex,
+ subaddr_indices);
+
+ env->ReleaseStringUTFChars(payment_id, _payment_id);
+ return reinterpret_cast<jlong>(tx);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_createTransactionJ(JNIEnv *env, jobject instance,
+ jstring dst_addr, jstring payment_id,
+ jlong amount, jint mixin_count,
+ jint priority,
+ jint accountIndex) {
+
+ const char *_dst_addr = env->GetStringUTFChars(dst_addr, nullptr);
+ const char *_payment_id = env->GetStringUTFChars(payment_id, nullptr);
+ Monero::PendingTransaction::Priority _priority =
+ static_cast<Monero::PendingTransaction::Priority>(priority);
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+
+ Monero::PendingTransaction *tx = wallet->createTransaction(_dst_addr, _payment_id,
+ amount, (uint32_t) mixin_count,
+ _priority,
+ (uint32_t) accountIndex);
+
+ env->ReleaseStringUTFChars(dst_addr, _dst_addr);
+ env->ReleaseStringUTFChars(payment_id, _payment_id);
+ return reinterpret_cast<jlong>(tx);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_createSweepTransaction(JNIEnv *env, jobject instance,
+ jstring dst_addr, jstring payment_id,
+ jint mixin_count,
+ jint priority,
+ jint accountIndex) {
+
+ const char *_dst_addr = env->GetStringUTFChars(dst_addr, nullptr);
+ const char *_payment_id = env->GetStringUTFChars(payment_id, nullptr);
+ Monero::PendingTransaction::Priority _priority =
+ static_cast<Monero::PendingTransaction::Priority>(priority);
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+
+ Monero::optional<uint64_t> empty;
+
+ Monero::PendingTransaction *tx = wallet->createTransaction(_dst_addr, _payment_id,
+ empty, (uint32_t) mixin_count,
+ _priority,
+ (uint32_t) accountIndex);
+
+ env->ReleaseStringUTFChars(dst_addr, _dst_addr);
+ env->ReleaseStringUTFChars(payment_id, _payment_id);
+ return reinterpret_cast<jlong>(tx);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_createSweepUnmixableTransactionJ(JNIEnv *env,
+ jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ Monero::PendingTransaction *tx = wallet->createSweepUnmixableTransaction();
+ return reinterpret_cast<jlong>(tx);
+}
+
+//virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) = 0;
+//virtual bool submitTransaction(const std::string &fileName) = 0;
+
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_disposeTransaction(JNIEnv *env, jobject instance,
+ jobject pendingTransaction) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ Monero::PendingTransaction *_pendingTransaction =
+ getHandle<Monero::PendingTransaction>(env, pendingTransaction);
+ wallet->disposeTransaction(_pendingTransaction);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_estimateTransactionFee(JNIEnv *env, jobject instance,
+ jobjectArray addresses,
+ jlongArray amounts,
+ jint priority) {
+
+ std::vector<std::pair<std::string, uint64_t>> destinations;
+
+ int destSize = env->GetArrayLength(addresses);
+ assert(destSize == env->GetArrayLength(amounts));
+ jlong *_amounts = env->GetLongArrayElements(amounts, nullptr);
+ for (int i = 0; i < destSize; i++) {
+ std::pair<std::string, uint64_t> pair;
+ jstring dest = (jstring) env->GetObjectArrayElement(addresses, i);
+ const char *_dest = env->GetStringUTFChars(dest, nullptr);
+ pair.first = _dest;
+ env->ReleaseStringUTFChars(dest, _dest);
+ pair.second = ((uint64_t) _amounts[i]);
+ destinations.emplace_back(pair);
+ }
+ env->ReleaseLongArrayElements(amounts, _amounts, 0);
+
+ Monero::PendingTransaction::Priority _priority =
+ static_cast<Monero::PendingTransaction::Priority>(priority);
+
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+
+ return static_cast<jlong>(wallet->estimateTransactionFee(destinations, _priority));
+}
+
+//virtual bool exportKeyImages(const std::string &filename) = 0;
+//virtual bool importKeyImages(const std::string &filename) = 0;
+
+
+//virtual TransactionHistory * history() const = 0;
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getHistoryJ(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return reinterpret_cast<jlong>(wallet->history());
+}
+
+//virtual AddressBook * addressBook() const = 0;
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getCoinsJ(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return reinterpret_cast<jlong>(wallet->coins());
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_setListenerJ(JNIEnv *env, jobject instance,
+ jobject javaListener) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ wallet->setListener(nullptr); // clear old listener
+ // delete old listener
+ MyWalletListener *oldListener = getHandle<MyWalletListener>(env, instance,
+ "listenerHandle");
+ if (oldListener != nullptr) {
+ oldListener->deleteGlobalJavaRef(env);
+ delete oldListener;
+ }
+ if (javaListener == nullptr) {
+ LOGD("null listener");
+ return 0;
+ } else {
+ MyWalletListener *listener = new MyWalletListener(env, javaListener);
+ wallet->setListener(listener);
+ return reinterpret_cast<jlong>(listener);
+ }
+}
+
+JNIEXPORT jint JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getDefaultMixin(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return wallet->defaultMixin();
+}
+
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_setDefaultMixin(JNIEnv *env, jobject instance, jint mixin) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return wallet->setDefaultMixin(mixin);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_setUserNote(JNIEnv *env, jobject instance,
+ jstring txid, jstring note) {
+
+ const char *_txid = env->GetStringUTFChars(txid, nullptr);
+ const char *_note = env->GetStringUTFChars(note, nullptr);
+
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+
+ bool success = wallet->setUserNote(_txid, _note);
+
+ env->ReleaseStringUTFChars(txid, _txid);
+ env->ReleaseStringUTFChars(note, _note);
+
+ return static_cast<jboolean>(success);
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getUserNote(JNIEnv *env, jobject instance,
+ jstring txid) {
+
+ const char *_txid = env->GetStringUTFChars(txid, nullptr);
+
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+
+ std::string note = wallet->getUserNote(_txid);
+
+ env->ReleaseStringUTFChars(txid, _txid);
+ return env->NewStringUTF(note.c_str());
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getTxKey(JNIEnv *env, jobject instance,
+ jstring txid) {
+
+ const char *_txid = env->GetStringUTFChars(txid, nullptr);
+
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+
+ std::string txKey = wallet->getTxKey(_txid);
+
+ env->ReleaseStringUTFChars(txid, _txid);
+ return env->NewStringUTF(txKey.c_str());
+}
+
+//virtual void addSubaddressAccount(const std::string& label) = 0;
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_addAccount(JNIEnv *env, jobject instance,
+ jstring label) {
+
+ const char *_label = env->GetStringUTFChars(label, nullptr);
+
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ wallet->addSubaddressAccount(_label);
+
+ env->ReleaseStringUTFChars(label, _label);
+}
+
+//virtual std::string getSubaddressLabel(uint32_t accountIndex, uint32_t addressIndex) const = 0;
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getSubaddressLabel(JNIEnv *env, jobject instance,
+ jint accountIndex, jint addressIndex) {
+
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+
+ std::string label = wallet->getSubaddressLabel((uint32_t) accountIndex,
+ (uint32_t) addressIndex);
+
+ return env->NewStringUTF(label.c_str());
+}
+
+//virtual void setSubaddressLabel(uint32_t accountIndex, uint32_t addressIndex, const std::string &label) = 0;
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_setSubaddressLabel(JNIEnv *env, jobject instance,
+ jint accountIndex, jint addressIndex,
+ jstring label) {
+
+ const char *_label = env->GetStringUTFChars(label, nullptr);
+
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ wallet->setSubaddressLabel(accountIndex, addressIndex, _label);
+
+ env->ReleaseStringUTFChars(label, _label);
+}
+
+// virtual size_t numSubaddressAccounts() const = 0;
+JNIEXPORT jint JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getNumAccounts(JNIEnv *env, jobject instance) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return static_cast<jint>(wallet->numSubaddressAccounts());
+}
+
+//virtual size_t numSubaddresses(uint32_t accountIndex) const = 0;
+JNIEXPORT jint JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getNumSubaddresses(JNIEnv *env, jobject instance,
+ jint accountIndex) {
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ return static_cast<jint>(wallet->numSubaddresses(accountIndex));
+}
+
+//virtual void addSubaddress(uint32_t accountIndex, const std::string &label) = 0;
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_addSubaddress(JNIEnv *env, jobject instance,
+ jint accountIndex,
+ jstring label) {
+
+ const char *_label = env->GetStringUTFChars(label, nullptr);
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ wallet->addSubaddress(accountIndex, _label);
+ env->ReleaseStringUTFChars(label, _label);
+}
+
+/*JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_Wallet_getLastSubaddress(JNIEnv *env, jobject instance,
+ jint accountIndex) {
+
+ Monero::Wallet *wallet = getHandle<Monero::Wallet>(env, instance);
+ size_t num = wallet->numSubaddresses(accountIndex);
+ //wallet->subaddress()->getAll()[num]->getAddress().c_str()
+ Monero::Subaddress *s = wallet->subaddress();
+ s->refresh(accountIndex);
+ std::vector<Monero::SubaddressRow *> v = s->getAll();
+ return env->NewStringUTF(v[num - 1]->getAddress().c_str());
+}
+*/
+//virtual std::string signMessage(const std::string &message) = 0;
+//virtual bool verifySignedMessage(const std::string &message, const std::string &addres, const std::string &signature) const = 0;
+
+//virtual bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &tvAmount, std::string &tx_description, std::string &recipient_name, std::vector<std::string> &unknown_parameters, std::string &error) = 0;
+//virtual bool rescanSpent() = 0;
+
+
+// TransactionHistory
+JNIEXPORT jint JNICALL
+Java_com_m2049r_xmrwallet_model_TransactionHistory_getCount(JNIEnv *env, jobject instance) {
+ Monero::TransactionHistory *history = getHandle<Monero::TransactionHistory>(env,
+ instance);
+ return history->count();
+}
+
+jobject newTransferInstance(JNIEnv *env, uint64_t amount, const std::string &address) {
+ jmethodID c = env->GetMethodID(class_Transfer, "<init>",
+ "(JLjava/lang/String;)V");
+ jstring _address = env->NewStringUTF(address.c_str());
+ jobject transfer = env->NewObject(class_Transfer, c, static_cast<jlong> (amount), _address);
+ env->DeleteLocalRef(_address);
+ return transfer;
+}
+
+jobject newTransferList(JNIEnv *env, Monero::TransactionInfo *info) {
+ const std::vector<Monero::TransactionInfo::Transfer> &transfers = info->transfers();
+ if (transfers.empty()) { // don't create empty Lists
+ return nullptr;
+ }
+ // make new ArrayList
+ jmethodID java_util_ArrayList_ = env->GetMethodID(class_ArrayList, "<init>", "(I)V");
+ jmethodID java_util_ArrayList_add = env->GetMethodID(class_ArrayList, "add",
+ "(Ljava/lang/Object;)Z");
+ jobject result = env->NewObject(class_ArrayList, java_util_ArrayList_,
+ static_cast<jint> (transfers.size()));
+ // create Transfer objects and stick them in the List
+ for (const Monero::TransactionInfo::Transfer &s: transfers) {
+ jobject element = newTransferInstance(env, s.amount, s.address);
+ env->CallBooleanMethod(result, java_util_ArrayList_add, element);
+ env->DeleteLocalRef(element);
+ }
+ return result;
+}
+
+jobject newTransactionInfo(JNIEnv *env, Monero::TransactionInfo *info) {
+ jmethodID c = env->GetMethodID(class_TransactionInfo, "<init>",
+ "(IZZJJJLjava/lang/String;JLjava/lang/String;IIJJLjava/lang/String;Ljava/util/List;)V");
+ jobject transfers = newTransferList(env, info);
+ jstring _hash = env->NewStringUTF(info->hash().c_str());
+ jstring _paymentId = env->NewStringUTF(info->paymentId().c_str());
+ jstring _label = env->NewStringUTF(info->label().c_str());
+ uint32_t subaddrIndex = 0;
+ if (info->direction() == Monero::TransactionInfo::Direction_In)
+ subaddrIndex = *(info->subaddrIndex().begin());
+ jobject result = env->NewObject(class_TransactionInfo, c,
+ info->direction(),
+ info->isPending(),
+ info->isFailed(),
+ static_cast<jlong> (info->amount()),
+ static_cast<jlong> (info->fee()),
+ static_cast<jlong> (info->blockHeight()),
+ _hash,
+ static_cast<jlong> (info->timestamp()),
+ _paymentId,
+ static_cast<jint> (info->subaddrAccount()),
+ static_cast<jint> (subaddrIndex),
+ static_cast<jlong> (info->confirmations()),
+ static_cast<jlong> (info->unlockTime()),
+ _label,
+ transfers);
+ env->DeleteLocalRef(transfers);
+ env->DeleteLocalRef(_hash);
+ env->DeleteLocalRef(_paymentId);
+ return result;
+}
+
+#include <stdio.h>
+#include <stdlib.h>
+
+// Coins
+
+jobject newCoinsInfo(JNIEnv *env, Monero::CoinsInfo *info) {
+ jstring _hash = env->NewStringUTF(info->hash().c_str());
+
+ jmethodID c = env->GetMethodID(class_CoinsInfo, "<init>", "(IIJJLjava/lang/String;ZZJZ)V");
+ jobject result = env->NewObject(class_CoinsInfo, c,
+ static_cast<jint> (info->subaddrAccount()),
+ static_cast<jint> (info->subaddrIndex()),
+ static_cast<jlong> (info->amount()),
+ static_cast<jlong> (info->blockHeight()),
+ _hash,
+ info->spent(),
+ info->frozen(),
+ static_cast<jlong> (info->unlockTime()),
+ info->unlocked());
+ env->DeleteLocalRef(_hash);
+ return result;
+}
+
+jobject coinsInfoArrayList(JNIEnv *env, const std::vector<Monero::CoinsInfo *> &vector,
+ uint32_t accountIndex, bool unspentOnly) {
+
+ jmethodID java_util_ArrayList_ = env->GetMethodID(class_ArrayList, "<init>", "(I)V");
+ jmethodID java_util_ArrayList_add = env->GetMethodID(class_ArrayList, "add",
+ "(Ljava/lang/Object;)Z");
+
+ jobject arrayList = env->NewObject(class_ArrayList, java_util_ArrayList_,
+ static_cast<jint> (vector.size()));
+ for (Monero::CoinsInfo *s: vector) {
+ if (s->subaddrAccount() != accountIndex) continue;
+ if (s->spent() && unspentOnly) continue;
+ jobject info = newCoinsInfo(env, s);
+ env->CallBooleanMethod(arrayList, java_util_ArrayList_add, info);
+ env->DeleteLocalRef(info);
+ }
+ return arrayList;
+}
+
+JNIEXPORT jint JNICALL
+Java_com_m2049r_xmrwallet_model_Coins_getCount(JNIEnv *env, jobject instance) {
+ Monero::Coins *coins = getHandle<Monero::Coins>(env, instance);
+ return coins->count();
+}
+
+JNIEXPORT jobject JNICALL
+Java_com_m2049r_xmrwallet_model_Coins_refresh(JNIEnv *env, jobject instance, jint accountIndex,
+ jboolean unspentOnly) {
+ Monero::Coins *coins = getHandle<Monero::Coins>(env, instance);
+ coins->refresh();
+ return coinsInfoArrayList(env, coins->getAll(), (uint32_t) accountIndex, unspentOnly);
+}
+
+jobject
+transactionInfoArrayList(JNIEnv *env, const std::vector<Monero::TransactionInfo *> &vector,
+ uint32_t accountIndex) {
+
+ jmethodID java_util_ArrayList_ = env->GetMethodID(class_ArrayList, "<init>", "(I)V");
+ jmethodID java_util_ArrayList_add = env->GetMethodID(class_ArrayList, "add",
+ "(Ljava/lang/Object;)Z");
+
+ jobject arrayList = env->NewObject(class_ArrayList, java_util_ArrayList_,
+ static_cast<jint> (vector.size()));
+ for (Monero::TransactionInfo *s: vector) {
+ if (s->subaddrAccount() != accountIndex) continue;
+ jobject info = newTransactionInfo(env, s);
+ env->CallBooleanMethod(arrayList, java_util_ArrayList_add, info);
+ env->DeleteLocalRef(info);
+ }
+ return arrayList;
+}
+
+JNIEXPORT jobject JNICALL
+Java_com_m2049r_xmrwallet_model_TransactionHistory_refreshJ(JNIEnv *env, jobject instance,
+ jint accountIndex) {
+ Monero::TransactionHistory *history = getHandle<Monero::TransactionHistory>(env,
+ instance);
+ history->refresh();
+ return transactionInfoArrayList(env, history->getAll(), (uint32_t) accountIndex);
+}
+
+// TransactionInfo is implemented in Java - no need here
+
+JNIEXPORT jint JNICALL
+Java_com_m2049r_xmrwallet_model_PendingTransaction_getStatusJ(JNIEnv *env, jobject instance) {
+ Monero::PendingTransaction *tx = getHandle<Monero::PendingTransaction>(env, instance);
+ return tx->status();
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_PendingTransaction_getErrorString(JNIEnv *env, jobject instance) {
+ Monero::PendingTransaction *tx = getHandle<Monero::PendingTransaction>(env, instance);
+ return env->NewStringUTF(tx->errorString().c_str());
+}
+
+// commit transaction or save to file if filename is provided.
+JNIEXPORT jboolean JNICALL
+Java_com_m2049r_xmrwallet_model_PendingTransaction_commit(JNIEnv *env, jobject instance,
+ jstring filename, jboolean overwrite) {
+
+ const char *_filename = env->GetStringUTFChars(filename, nullptr);
+
+ Monero::PendingTransaction *tx = getHandle<Monero::PendingTransaction>(env, instance);
+ bool success = tx->commit(_filename, overwrite);
+
+ env->ReleaseStringUTFChars(filename, _filename);
+ return static_cast<jboolean>(success);
+}
+
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_PendingTransaction_getAmount(JNIEnv *env, jobject instance) {
+ Monero::PendingTransaction *tx = getHandle<Monero::PendingTransaction>(env, instance);
+ return static_cast<jlong>(tx->amount());
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_PendingTransaction_getDust(JNIEnv *env, jobject instance) {
+ Monero::PendingTransaction *tx = getHandle<Monero::PendingTransaction>(env, instance);
+ return static_cast<jlong>(tx->dust());
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_PendingTransaction_getFee(JNIEnv *env, jobject instance) {
+ Monero::PendingTransaction *tx = getHandle<Monero::PendingTransaction>(env, instance);
+ return static_cast<jlong>(tx->fee());
+}
+
+// TODO this returns a vector of strings - deal with this later - for now return first one
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_PendingTransaction_getFirstTxIdJ(JNIEnv *env, jobject instance) {
+ Monero::PendingTransaction *tx = getHandle<Monero::PendingTransaction>(env, instance);
+ std::vector<std::string> txids = tx->txid();
+ if (!txids.empty())
+ return env->NewStringUTF(txids.front().c_str());
+ else
+ return nullptr;
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_m2049r_xmrwallet_model_PendingTransaction_getTxCount(JNIEnv *env, jobject instance) {
+ Monero::PendingTransaction *tx = getHandle<Monero::PendingTransaction>(env, instance);
+ return static_cast<jlong>(tx->txCount());
+}
+
+
+// these are all in Monero::Wallet - which I find wrong, so they are here!
+//static void init(const char *argv0, const char *default_log_base_name);
+//static void debug(const std::string &category, const std::string &str);
+//static void info(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);
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_initLogger(JNIEnv *env, jclass clazz,
+ jstring argv0,
+ jstring default_log_base_name) {
+
+ const char *_argv0 = env->GetStringUTFChars(argv0, nullptr);
+ const char *_default_log_base_name = env->GetStringUTFChars(default_log_base_name, nullptr);
+
+ Monero::Wallet::init(_argv0, _default_log_base_name);
+
+ env->ReleaseStringUTFChars(argv0, _argv0);
+ env->ReleaseStringUTFChars(default_log_base_name, _default_log_base_name);
+}
+
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_logDebug(JNIEnv *env, jclass clazz,
+ jstring category, jstring message) {
+
+ const char *_category = env->GetStringUTFChars(category, nullptr);
+ const char *_message = env->GetStringUTFChars(message, nullptr);
+
+ Monero::Wallet::debug(_category, _message);
+
+ env->ReleaseStringUTFChars(category, _category);
+ env->ReleaseStringUTFChars(message, _message);
+}
+
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_logInfo(JNIEnv *env, jclass clazz,
+ jstring category, jstring message) {
+
+ const char *_category = env->GetStringUTFChars(category, nullptr);
+ const char *_message = env->GetStringUTFChars(message, nullptr);
+
+ Monero::Wallet::info(_category, _message);
+
+ env->ReleaseStringUTFChars(category, _category);
+ env->ReleaseStringUTFChars(message, _message);
+}
+
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_logWarning(JNIEnv *env, jclass clazz,
+ jstring category, jstring message) {
+
+ const char *_category = env->GetStringUTFChars(category, nullptr);
+ const char *_message = env->GetStringUTFChars(message, nullptr);
+
+ Monero::Wallet::warning(_category, _message);
+
+ env->ReleaseStringUTFChars(category, _category);
+ env->ReleaseStringUTFChars(message, _message);
+}
+
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_logError(JNIEnv *env, jclass clazz,
+ jstring category, jstring message) {
+
+ const char *_category = env->GetStringUTFChars(category, nullptr);
+ const char *_message = env->GetStringUTFChars(message, nullptr);
+
+ Monero::Wallet::error(_category, _message);
+
+ env->ReleaseStringUTFChars(category, _category);
+ env->ReleaseStringUTFChars(message, _message);
+}
+
+JNIEXPORT void JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_setLogLevel(JNIEnv *env, jclass clazz,
+ jint level) {
+ Monero::WalletManagerFactory::setLogLevel(level);
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_m2049r_xmrwallet_model_WalletManager_moneroVersion(JNIEnv *env, jclass clazz) {
+ return env->NewStringUTF(MONERO_VERSION);
+}
+
+//
+// Ledger Stuff
+//
+
+/**
+ * @brief LedgerExchange - exchange data with Ledger Device
+ * @param command - buffer for data to send
+ * @param cmd_len - length of send to send
+ * @param response - buffer for received data
+ * @param max_resp_len - size of receive buffer
+ *
+ * @return length of received data in response or -1 if error
+ */
+int LedgerExchange(
+ unsigned char *command,
+ unsigned int cmd_len,
+ unsigned char *response,
+ unsigned int max_resp_len) {
+ LOGD("LedgerExchange");
+ JNIEnv *jenv;
+ int envStat = attachJVM(&jenv);
+ if (envStat == JNI_ERR) return -1;
+
+ jmethodID exchangeMethod = jenv->GetStaticMethodID(class_Ledger, "Exchange", "([B)[B");
+
+ jsize sendLen = static_cast<jsize>(cmd_len);
+ jbyteArray dataSend = jenv->NewByteArray(sendLen);
+ jenv->SetByteArrayRegion(dataSend, 0, sendLen, (jbyte *) command);
+ jbyteArray dataRecv = (jbyteArray) jenv->CallStaticObjectMethod(class_Ledger, exchangeMethod,
+ dataSend);
+ jenv->DeleteLocalRef(dataSend);
+ if (dataRecv == nullptr) {
+ detachJVM(jenv, envStat);
+ LOGD("LedgerExchange SCARD_E_NO_READERS_AVAILABLE");
+ return -1;
+ }
+ jsize len = jenv->GetArrayLength(dataRecv);
+ LOGD("LedgerExchange SCARD_S_SUCCESS %u/%d", cmd_len, len);
+ if (len <= max_resp_len) {
+ jenv->GetByteArrayRegion(dataRecv, 0, len, (jbyte *) response);
+ jenv->DeleteLocalRef(dataRecv);
+ detachJVM(jenv, envStat);
+ return static_cast<int>(len);;
+ } else {
+ jenv->DeleteLocalRef(dataRecv);
+ detachJVM(jenv, envStat);
+ LOGE("LedgerExchange SCARD_E_INSUFFICIENT_BUFFER");
+ return -1;
+ }
+}
+
+/**
+ * @brief LedgerFind - find Ledger Device and return it's name
+ * @param buffer - buffer for name of found device
+ * @param len - length of buffer
+ * @return 0 - success
+ * -1 - no device connected / found
+ * -2 - JVM not found
+ */
+int LedgerFind(char *buffer, size_t len) {
+ LOGD("LedgerName");
+ JNIEnv *jenv;
+ int envStat = attachJVM(&jenv);
+ if (envStat == JNI_ERR) return -2;
+
+ jmethodID nameMethod = jenv->GetStaticMethodID(class_Ledger, "Name", "()Ljava/lang/String;");
+ jstring name = (jstring) jenv->CallStaticObjectMethod(class_Ledger, nameMethod);
+
+ int ret;
+ if (name != nullptr) {
+ const char *_name = jenv->GetStringUTFChars(name, nullptr);
+ strncpy(buffer, _name, len);
+ jenv->ReleaseStringUTFChars(name, _name);
+ buffer[len - 1] = 0; // terminate in case _name is bigger
+ ret = 0;
+ LOGD("LedgerName is %s", buffer);
+ } else {
+ buffer[0] = 0;
+ ret = -1;
+ }
+
+ detachJVM(jenv, envStat);
+ return ret;
+}
+
+#ifdef __cplusplus
+}
+#endif