Sweep selected outputs

This commit is contained in:
pokkst 2022-09-22 06:07:39 -05:00
parent 3076777c53
commit af5076ce7d
No known key found for this signature in database
GPG key ID: 90C2ED85E67A50FF
7 changed files with 80 additions and 25 deletions

View file

@ -230,6 +230,25 @@ std::vector<std::string> java2cpp(JNIEnv *env, jobject arrayList) {
return result;
}
std::set<std::string> java2cpp_set(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::set<std::string> result;
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(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");
@ -961,8 +980,8 @@ Java_net_mynero_wallet_model_Wallet_createTransactionJ(JNIEnv *env, jobject inst
jstring dst_addr, jstring payment_id,
jlong amount, jint mixin_count,
jint priority,
jint accountIndex) {
jint accountIndex, jobject key_images) {
const std::set<std::string> _key_images = java2cpp_set(env, key_images);
const char *_dst_addr = env->GetStringUTFChars(dst_addr, nullptr);
const char *_payment_id = env->GetStringUTFChars(payment_id, nullptr);
Monero::PendingTransaction::Priority _priority =
@ -972,7 +991,7 @@ Java_net_mynero_wallet_model_Wallet_createTransactionJ(JNIEnv *env, jobject inst
Monero::PendingTransaction *tx = wallet->createTransaction(_dst_addr, _payment_id,
amount, (uint32_t) mixin_count,
_priority,
(uint32_t) accountIndex);
(uint32_t) accountIndex, {}, _key_images);
env->ReleaseStringUTFChars(dst_addr, _dst_addr);
env->ReleaseStringUTFChars(payment_id, _payment_id);
@ -1013,8 +1032,8 @@ Java_net_mynero_wallet_model_Wallet_createSweepTransaction(JNIEnv *env, jobject
jstring dst_addr, jstring payment_id,
jint mixin_count,
jint priority,
jint accountIndex) {
jint accountIndex, jobject key_images) {
const std::set<std::string> _key_images = java2cpp_set(env, key_images);
const char *_dst_addr = env->GetStringUTFChars(dst_addr, nullptr);
const char *_payment_id = env->GetStringUTFChars(payment_id, nullptr);
Monero::PendingTransaction::Priority _priority =
@ -1026,7 +1045,7 @@ Java_net_mynero_wallet_model_Wallet_createSweepTransaction(JNIEnv *env, jobject
Monero::PendingTransaction *tx = wallet->createTransaction(_dst_addr, _payment_id,
empty, (uint32_t) mixin_count,
_priority,
(uint32_t) accountIndex);
(uint32_t) accountIndex, {}, _key_images);
env->ReleaseStringUTFChars(dst_addr, _dst_addr);
env->ReleaseStringUTFChars(payment_id, _payment_id);
@ -1064,9 +1083,13 @@ Java_net_mynero_wallet_model_Wallet_getCoinsJ(JNIEnv *env, jobject instance) {
jobject newCoinsInfo(JNIEnv *env, Monero::CoinsInfo *info) {
jmethodID c = env->GetMethodID(class_CoinsInfo, "<init>",
"(J)V");
"(JZLjava/lang/String;)V");
jstring _key_image = env->NewStringUTF(info->keyImage().c_str());
jobject result = env->NewObject(class_CoinsInfo, c,
static_cast<jlong> (info->globalOutputIndex()));
static_cast<jlong> (info->globalOutputIndex()),
info->spent(),
_key_image);
env->DeleteLocalRef(_key_image);
return result;
}

View file

@ -23,6 +23,9 @@ import net.mynero.wallet.model.PendingTransaction;
import net.mynero.wallet.model.Wallet;
import net.mynero.wallet.util.Helper;
import java.util.ArrayList;
import java.util.List;
// https://stackoverflow.com/questions/2139134/how-to-send-an-object-from-one-android-activity-to-another-using-intents
public class TxData implements Parcelable {
@ -41,6 +44,7 @@ public class TxData implements Parcelable {
private int mixin;
private PendingTransaction.Priority priority;
private UserNotes userNotes;
private ArrayList<String> preferredInputs;
public TxData() {
}
@ -50,16 +54,19 @@ public class TxData implements Parcelable {
this.amount = txData.amount;
this.mixin = txData.mixin;
this.priority = txData.priority;
this.preferredInputs = txData.preferredInputs;
}
public TxData(String dstAddr,
long amount,
int mixin,
PendingTransaction.Priority priority) {
PendingTransaction.Priority priority,
ArrayList<String> preferredInputs) {
this.dstAddr = dstAddr;
this.amount = amount;
this.mixin = mixin;
this.priority = priority;
this.preferredInputs = preferredInputs;
}
protected TxData(Parcel in) {
@ -67,7 +74,7 @@ public class TxData implements Parcelable {
amount = in.readLong();
mixin = in.readInt();
priority = PendingTransaction.Priority.fromInteger(in.readInt());
in.readStringList(preferredInputs);
}
public String getDestinationAddress() {
@ -94,6 +101,10 @@ public class TxData implements Parcelable {
return 1.0 * amount / Helper.ONE_XMR;
}
public ArrayList<String> getPreferredInputs() {
return preferredInputs;
}
public int getMixin() {
return mixin;
}

View file

@ -56,7 +56,9 @@ public class ReceiveBottomSheetDialog extends BottomSheetDialogFragment {
List<CoinsInfo> coins = WalletManager.getInstance().getWallet().getCoins().getAll();
System.out.println("COINS::");
for(CoinsInfo coinsInfo : coins) {
System.out.println(coinsInfo.getGlobalOutputIndex());
if(!coinsInfo.isSpent()) {
System.out.println(coinsInfo.getKeyImage());
}
}
}

View file

@ -30,9 +30,13 @@ public class CoinsInfo implements Parcelable {
}
long globalOutputIndex;
boolean spent;
String keyImage;
public CoinsInfo(long globalOutputIndex) {
public CoinsInfo(long globalOutputIndex, boolean spent, String keyImage) {
this.globalOutputIndex = globalOutputIndex;
this.spent = spent;
this.keyImage = keyImage;
}
protected CoinsInfo(Parcel in) {
@ -55,6 +59,14 @@ public class CoinsInfo implements Parcelable {
return globalOutputIndex;
}
public boolean isSpent() {
return spent;
}
public String getKeyImage() {
return keyImage;
}
@Override
public int describeContents() {
return 0;

View file

@ -24,6 +24,7 @@ import net.mynero.wallet.data.TxData;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
@ -276,32 +277,31 @@ public class Wallet {
return createTransaction(
txData.getDestinationAddress(),
txData.getAmount(),
txData.getMixin(),
txData.getPriority());
txData.getPriority(),
txData.getPreferredInputs());
}
public PendingTransaction createTransaction(String dst_addr,
long amount, int mixin_count,
PendingTransaction.Priority priority) {
long amount, PendingTransaction.Priority priority, ArrayList<String> key_images) {
disposePendingTransaction();
int _priority = priority.getValue();
long txHandle =
(amount == SWEEP_ALL ?
createSweepTransaction(dst_addr, "", mixin_count, _priority,
accountIndex) :
createTransactionJ(dst_addr, "", amount, mixin_count, _priority,
accountIndex));
createSweepTransaction(dst_addr, "", 0, _priority,
accountIndex, key_images) :
createTransactionJ(dst_addr, "", amount, 0, _priority,
accountIndex, key_images));
pendingTransaction = new PendingTransaction(txHandle);
return pendingTransaction;
}
private native long createTransactionJ(String dst_addr, String payment_id,
long amount, int mixin_count,
int priority, int accountIndex);
int priority, int accountIndex, ArrayList<String> key_images);
private native long createSweepTransaction(String dst_addr, String payment_id,
int mixin_count,
int priority, int accountIndex);
int priority, int accountIndex, ArrayList<String> key_images);
private native long createTransactionSingleJ(String key_image, String dst_addr, int priority);

View file

@ -28,6 +28,9 @@ import net.mynero.wallet.model.WalletListener;
import net.mynero.wallet.model.WalletManager;
import net.mynero.wallet.util.Constants;
import java.util.ArrayList;
import java.util.List;
/**
* Handy class for starting a new thread that has a looper. The looper can then be
@ -121,7 +124,9 @@ public class MoneroHandlerThread extends Thread implements WalletListener {
public PendingTransaction createTx(String address, String amountStr, boolean sendAll, PendingTransaction.Priority feePriority) {
long amount = sendAll ? SWEEP_ALL : Wallet.getAmountFromString(amountStr);
return wallet.createTransaction(new TxData(address, amount, 0, feePriority));
ArrayList<String> preferredInputs = new ArrayList<>();
preferredInputs.add("");
return wallet.createTransaction(new TxData(address, amount, 0, feePriority, preferredInputs));
}
public boolean sendTx(PendingTransaction pendingTx) {

View file

@ -886,7 +886,8 @@ struct Wallet
optional<std::vector<uint64_t>> amount, uint32_t mixin_count,
PendingTransaction::Priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
std::set<uint32_t> subaddr_indices = {}) = 0;
std::set<uint32_t> subaddr_indices = {},
const std::set<std::string> &preferred_inputs = {}) = 0;
/*!
* \brief createTransaction creates transaction. if dst_addr is an integrated address, payment_id is ignored
@ -905,7 +906,8 @@ struct Wallet
optional<uint64_t> amount, uint32_t mixin_count,
PendingTransaction::Priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
std::set<uint32_t> subaddr_indices = {}) = 0;
std::set<uint32_t> subaddr_indices = {},
const std::set<std::string> &preferred_inputs = {}) = 0;
/*!
* \brief createTransactionSingle creates transaction with single input