mirror of
https://github.com/m2049r/xmrwallet
synced 2024-11-29 10:20:23 +01:00
subaddresses (#322)
This commit is contained in:
parent
091538752b
commit
01e7693425
@ -552,9 +552,11 @@ Java_com_m2049r_xmrwallet_model_Wallet_setPassword(JNIEnv *env, jobject instance
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_getAddressJ(JNIEnv *env, jobject instance,
|
||||
jint accountIndex) {
|
||||
jint accountIndex,
|
||||
jint addressIndex) {
|
||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||
return env->NewStringUTF(wallet->address((uint32_t) accountIndex).c_str());
|
||||
return env->NewStringUTF(
|
||||
wallet->address((uint32_t) accountIndex, (uint32_t) addressIndex).c_str());
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
@ -850,10 +852,10 @@ Java_com_m2049r_xmrwallet_model_Wallet_createTransactionJ(JNIEnv *env, jobject i
|
||||
|
||||
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) {
|
||||
jstring dst_addr, jstring payment_id,
|
||||
jint mixin_count,
|
||||
jint priority,
|
||||
jint accountIndex) {
|
||||
|
||||
const char *_dst_addr = env->GetStringUTFChars(dst_addr, NULL);
|
||||
const char *_payment_id = env->GetStringUTFChars(payment_id, NULL);
|
||||
@ -988,7 +990,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_getTxKey(JNIEnv *env, jobject instance,
|
||||
//virtual void addSubaddressAccount(const std::string& label) = 0;
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_addAccount(JNIEnv *env, jobject instance,
|
||||
jstring label) {
|
||||
jstring label) {
|
||||
|
||||
const char *_label = env->GetStringUTFChars(label, NULL);
|
||||
|
||||
@ -1027,13 +1029,44 @@ Java_com_m2049r_xmrwallet_model_Wallet_setSubaddressLabel(JNIEnv *env, jobject i
|
||||
|
||||
// virtual size_t numSubaddressAccounts() const = 0;
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_numSubaddressAccounts(JNIEnv *env, jobject instance) {
|
||||
Java_com_m2049r_xmrwallet_model_Wallet_getNumAccounts(JNIEnv *env, jobject instance) {
|
||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::Wallet>(env, instance);
|
||||
return wallet->numSubaddressAccounts();
|
||||
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) {
|
||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::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, NULL);
|
||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::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) {
|
||||
|
||||
Bitmonero::Wallet *wallet = getHandle<Bitmonero::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;
|
||||
|
||||
@ -1079,10 +1112,13 @@ jobject newTransferList(JNIEnv *env, Bitmonero::TransactionInfo *info) {
|
||||
|
||||
jobject newTransactionInfo(JNIEnv *env, Bitmonero::TransactionInfo *info) {
|
||||
jmethodID c = env->GetMethodID(class_TransactionInfo, "<init>",
|
||||
"(IZZJJJLjava/lang/String;JLjava/lang/String;IJLjava/util/List;)V");
|
||||
"(IZZJJJLjava/lang/String;JLjava/lang/String;IIJLjava/util/List;)V");
|
||||
jobject transfers = newTransferList(env, info);
|
||||
jstring _hash = env->NewStringUTF(info->hash().c_str());
|
||||
jstring _paymentId = env->NewStringUTF(info->paymentId().c_str());
|
||||
uint32_t subaddrIndex = 0;
|
||||
if (info->direction() == Bitmonero::TransactionInfo::Direction_In)
|
||||
subaddrIndex = *(info->subaddrIndex().begin());
|
||||
jobject result = env->NewObject(class_TransactionInfo, c,
|
||||
info->direction(),
|
||||
info->isPending(),
|
||||
@ -1094,6 +1130,7 @@ jobject newTransactionInfo(JNIEnv *env, Bitmonero::TransactionInfo *info) {
|
||||
static_cast<jlong> (info->timestamp()),
|
||||
_paymentId,
|
||||
info->subaddrAccount(),
|
||||
subaddrIndex,
|
||||
info->confirmations(),
|
||||
transfers);
|
||||
env->DeleteLocalRef(transfers);
|
||||
@ -1104,6 +1141,7 @@ jobject newTransactionInfo(JNIEnv *env, Bitmonero::TransactionInfo *info) {
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
jobject cpp2java(JNIEnv *env, std::vector<Bitmonero::TransactionInfo *> vector) {
|
||||
|
||||
jmethodID java_util_ArrayList_ = env->GetMethodID(class_ArrayList, "<init>", "(I)V");
|
||||
@ -1161,11 +1199,13 @@ Java_com_m2049r_xmrwallet_model_PendingTransaction_getAmount(JNIEnv *env, jobjec
|
||||
Bitmonero::PendingTransaction *tx = getHandle<Bitmonero::PendingTransaction>(env, instance);
|
||||
return tx->amount();
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_PendingTransaction_getDust(JNIEnv *env, jobject instance) {
|
||||
Bitmonero::PendingTransaction *tx = getHandle<Bitmonero::PendingTransaction>(env, instance);
|
||||
return tx->dust();
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_m2049r_xmrwallet_model_PendingTransaction_getFee(JNIEnv *env, jobject instance) {
|
||||
Bitmonero::PendingTransaction *tx = getHandle<Bitmonero::PendingTransaction>(env, instance);
|
||||
|
@ -62,6 +62,7 @@ import timber.log.Timber;
|
||||
public class ReceiveFragment extends Fragment {
|
||||
|
||||
private ProgressBar pbProgress;
|
||||
private TextView tvAddressLabel;
|
||||
private TextView tvAddress;
|
||||
private TextInputLayout etPaymentId;
|
||||
private ExchangeView evAmount;
|
||||
@ -71,6 +72,10 @@ public class ReceiveFragment extends Fragment {
|
||||
private ImageView qrCodeFull;
|
||||
private EditText etDummy;
|
||||
private ImageButton bCopyAddress;
|
||||
private Button bSubaddress;
|
||||
|
||||
private Wallet wallet = null;
|
||||
private boolean isMyWallet = false;
|
||||
|
||||
public interface Listener {
|
||||
void setToolbarButton(int type);
|
||||
@ -87,6 +92,7 @@ public class ReceiveFragment extends Fragment {
|
||||
View view = inflater.inflate(R.layout.fragment_receive, container, false);
|
||||
|
||||
pbProgress = (ProgressBar) view.findViewById(R.id.pbProgress);
|
||||
tvAddressLabel = (TextView) view.findViewById(R.id.tvAddressLabel);
|
||||
tvAddress = (TextView) view.findViewById(R.id.tvAddress);
|
||||
etPaymentId = (TextInputLayout) view.findViewById(R.id.etPaymentId);
|
||||
evAmount = (ExchangeView) view.findViewById(R.id.evAmount);
|
||||
@ -96,6 +102,7 @@ public class ReceiveFragment extends Fragment {
|
||||
qrCodeFull = (ImageView) view.findViewById(R.id.qrCodeFull);
|
||||
etDummy = (EditText) view.findViewById(R.id.etDummy);
|
||||
bCopyAddress = (ImageButton) view.findViewById(R.id.bCopyAddress);
|
||||
bSubaddress = (Button) view.findViewById(R.id.bSubaddress);
|
||||
|
||||
etPaymentId.getEditText().setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||
etDummy.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||
@ -162,6 +169,18 @@ public class ReceiveFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
|
||||
bSubaddress.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
enableSubaddressButton(false);
|
||||
tvAddress.setText(wallet.getNewSubaddress());
|
||||
tvAddressLabel.setText(getString(R.string.generate_address_label_sub,
|
||||
wallet.getNumSubaddresses() - 1));
|
||||
storeWallet();
|
||||
generateQr();
|
||||
}
|
||||
});
|
||||
|
||||
qrCode.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
@ -194,11 +213,25 @@ public class ReceiveFragment extends Fragment {
|
||||
String password = b.getString("password");
|
||||
loadAndShow(path, password);
|
||||
} else {
|
||||
show(walletName, address);
|
||||
if (getActivity() instanceof GenerateReviewFragment.ListenerWithWallet) {
|
||||
wallet = ((GenerateReviewFragment.ListenerWithWallet) getActivity()).getWallet();
|
||||
show();
|
||||
} else {
|
||||
throw new IllegalStateException("no wallet info");
|
||||
}
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
void enableSubaddressButton(boolean enable) {
|
||||
bSubaddress.setEnabled(enable);
|
||||
if (enable) {
|
||||
bSubaddress.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_settings_orange_24dp,0,0);
|
||||
} else {
|
||||
bSubaddress.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_settings_gray_24dp,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
void copyAddress() {
|
||||
Helper.clipBoardCopy(getActivity(), getString(R.string.label_copy_address), tvAddress.getText().toString());
|
||||
Toast.makeText(getActivity(), getString(R.string.message_copy_address), Toast.LENGTH_SHORT).show();
|
||||
@ -228,17 +261,17 @@ public class ReceiveFragment extends Fragment {
|
||||
super.onResume();
|
||||
Timber.d("onResume()");
|
||||
listenerCallback.setToolbarButton(Toolbar.BUTTON_BACK);
|
||||
listenerCallback.setSubtitle(getString(R.string.receive_title));
|
||||
listenerCallback.setSubtitle(wallet.getAccountLabel());
|
||||
generateQr();
|
||||
}
|
||||
|
||||
private boolean isLoaded = false;
|
||||
|
||||
private void show(String name, String address) {
|
||||
Timber.d("name=%s", name);
|
||||
private void show() {
|
||||
Timber.d("name=%s", wallet.getName());
|
||||
isLoaded = true;
|
||||
listenerCallback.setTitle(name);
|
||||
tvAddress.setText(address);
|
||||
listenerCallback.setTitle(wallet.getName());
|
||||
tvAddress.setText(wallet.getAddress());
|
||||
etPaymentId.setEnabled(true);
|
||||
bPaymentId.setEnabled(true);
|
||||
bCopyAddress.setClickable(true);
|
||||
@ -254,18 +287,14 @@ public class ReceiveFragment extends Fragment {
|
||||
|
||||
private class AsyncShow extends AsyncTask<String, Void, Boolean> {
|
||||
String password;
|
||||
String address;
|
||||
String name;
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(String... params) {
|
||||
if (params.length != 2) return false;
|
||||
String walletPath = params[0];
|
||||
password = params[1];
|
||||
Wallet wallet = WalletManager.getInstance().openWallet(walletPath, password);
|
||||
address = wallet.getAddress();
|
||||
name = wallet.getName();
|
||||
wallet.close();
|
||||
wallet = WalletManager.getInstance().openWallet(walletPath, password);
|
||||
isMyWallet = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -274,7 +303,7 @@ public class ReceiveFragment extends Fragment {
|
||||
super.onPostExecute(result);
|
||||
if (!isAdded()) return; // never mind
|
||||
if (result) {
|
||||
show(name, address);
|
||||
show();
|
||||
} else {
|
||||
Toast.makeText(getActivity(), getString(R.string.receive_cannot_open), Toast.LENGTH_LONG).show();
|
||||
hideProgress();
|
||||
@ -282,6 +311,27 @@ public class ReceiveFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
|
||||
private void storeWallet() {
|
||||
new AsyncStore().executeOnExecutor(MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private class AsyncStore extends AsyncTask<String, Void, Boolean> {
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(String... params) {
|
||||
if (params.length != 0) return false;
|
||||
if (wallet != null) wallet.store();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
enableSubaddressButton(true);
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean checkPaymentId() {
|
||||
String paymentId = etPaymentId.getEditText().getText().toString();
|
||||
boolean ok = paymentId.isEmpty() || Wallet.isPaymentIdValid(paymentId);
|
||||
@ -418,4 +468,15 @@ public class ReceiveFragment extends Fragment {
|
||||
Timber.d("onPause()");
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
Timber.d("onDetach()");
|
||||
if ((wallet != null) && (isMyWallet)) {
|
||||
wallet.close();
|
||||
wallet = null;
|
||||
isMyWallet = false;
|
||||
}
|
||||
super.onDetach();
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ public class TxFragment extends Fragment {
|
||||
activityCallback.setSubtitle(getString(R.string.tx_title));
|
||||
activityCallback.setToolbarButton(Toolbar.BUTTON_BACK);
|
||||
|
||||
tvAccount.setText("" + info.subaddrAccount);
|
||||
tvAccount.setText(getString(R.string.tx_account_formatted, info.account, info.subaddress));
|
||||
|
||||
tvTxTimestamp.setText(TS_FORMATTER.format(new Date(info.timestamp * 1000)));
|
||||
tvTxId.setText(info.hash);
|
||||
@ -287,7 +287,10 @@ public class TxFragment extends Fragment {
|
||||
}
|
||||
} else {
|
||||
sb.append("-");
|
||||
dstSb.append(info.direction == TransactionInfo.Direction.Direction_In ? activityCallback.getWalletAddress() : "-");
|
||||
dstSb.append(info.direction ==
|
||||
TransactionInfo.Direction.Direction_In ?
|
||||
activityCallback.getWalletSubaddress(info.account, info.subaddress) :
|
||||
"-");
|
||||
}
|
||||
tvTxTransfers.setText(sb.toString());
|
||||
tvDestination.setText(dstSb.toString());
|
||||
@ -322,7 +325,7 @@ public class TxFragment extends Fragment {
|
||||
Listener activityCallback;
|
||||
|
||||
public interface Listener {
|
||||
String getWalletAddress();
|
||||
String getWalletSubaddress(int accountIndex, int subaddressIndex);
|
||||
|
||||
String getTxKey(String hash);
|
||||
|
||||
|
@ -491,8 +491,8 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||
@Override
|
||||
public boolean onRefreshed(final Wallet wallet, final boolean full) {
|
||||
Timber.d("onRefreshed()");
|
||||
if (numAccounts != wallet.numAccounts()) {
|
||||
numAccounts = wallet.numAccounts();
|
||||
if (numAccounts != wallet.getNumAccounts()) {
|
||||
numAccounts = wallet.getNumAccounts();
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
updateAccountsList();
|
||||
@ -740,8 +740,8 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWalletAddress() {
|
||||
return getWallet().getAddress();
|
||||
public String getWalletSubaddress(int accountIndex, int subaddressIndex) {
|
||||
return getWallet().getSubaddress(accountIndex, subaddressIndex);
|
||||
}
|
||||
|
||||
public String getWalletName() {
|
||||
@ -891,7 +891,7 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||
|
||||
@Override
|
||||
public void onWalletReceive() {
|
||||
startReceive(getWalletAddress());
|
||||
startReceive(getWallet().getAddress());
|
||||
}
|
||||
|
||||
void startReceive(String address) {
|
||||
@ -966,7 +966,8 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||
Helper.getDisplayAmount(wallet.getBalanceAll(), 5)));
|
||||
Menu menu = accountsView.getMenu();
|
||||
menu.removeGroup(R.id.accounts_list);
|
||||
for (int i = 0; i < wallet.numAccounts(); i++) {
|
||||
final int n = wallet.getNumAccounts();
|
||||
for (int i = 0; i < n; i++) {
|
||||
final String label = wallet.getAccountLabel(i);
|
||||
final MenuItem item = menu.add(R.id.accounts_list, getAccountId(i), 2 * i, label);
|
||||
item.setIcon(R.drawable.ic_account_balance_wallet_black_24dp);
|
||||
@ -1050,7 +1051,7 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
||||
switch (id) {
|
||||
case R.id.account_new:
|
||||
getWallet().addAccount();
|
||||
int newIdx = getWallet().numAccounts() - 1;
|
||||
int newIdx = getWallet().getNumAccounts() - 1;
|
||||
getWallet().setAccountIndex(newIdx);
|
||||
Toast.makeText(this,
|
||||
getString(R.string.accounts_new, newIdx),
|
||||
|
@ -166,7 +166,11 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
||||
}
|
||||
|
||||
if ((userNotes.note.isEmpty())) {
|
||||
this.tvPaymentId.setText(infoItem.paymentId.equals("0000000000000000") ? "" : infoItem.paymentId);
|
||||
this.tvPaymentId.setText(infoItem.paymentId.equals("0000000000000000") ?
|
||||
(infoItem.subaddress != 0 ?
|
||||
(context.getString(R.string.tx_subaddress, infoItem.subaddress)) :
|
||||
"") :
|
||||
infoItem.paymentId);
|
||||
} else {
|
||||
this.tvPaymentId.setText(userNotes.note);
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ public class TransactionHistory {
|
||||
Timber.d("refreshed %d", t.size());
|
||||
for (Iterator<TransactionInfo> iterator = t.iterator(); iterator.hasNext(); ) {
|
||||
TransactionInfo info = iterator.next();
|
||||
if (info.subaddrAccount != accountIndex) {
|
||||
if (info.account != accountIndex) {
|
||||
iterator.remove();
|
||||
Timber.d("removed %s", info.hash);
|
||||
} else {
|
||||
|
@ -67,7 +67,8 @@ public class TransactionInfo implements Parcelable, Comparable<TransactionInfo>
|
||||
public String hash;
|
||||
public long timestamp;
|
||||
public String paymentId;
|
||||
public int subaddrAccount;
|
||||
public int account;
|
||||
public int subaddress;
|
||||
public long confirmations;
|
||||
public List<Transfer> transfers;
|
||||
|
||||
@ -84,7 +85,8 @@ public class TransactionInfo implements Parcelable, Comparable<TransactionInfo>
|
||||
String hash,
|
||||
long timestamp,
|
||||
String paymentId,
|
||||
int subaddrAccount,
|
||||
int account,
|
||||
int subaddress,
|
||||
long confirmations,
|
||||
List<Transfer> transfers) {
|
||||
this.direction = Direction.values()[direction];
|
||||
@ -96,7 +98,8 @@ public class TransactionInfo implements Parcelable, Comparable<TransactionInfo>
|
||||
this.hash = hash;
|
||||
this.timestamp = timestamp;
|
||||
this.paymentId = paymentId;
|
||||
this.subaddrAccount = subaddrAccount;
|
||||
this.account = account;
|
||||
this.subaddress = subaddress;
|
||||
this.confirmations = confirmations;
|
||||
this.transfers = transfers;
|
||||
}
|
||||
@ -116,7 +119,8 @@ public class TransactionInfo implements Parcelable, Comparable<TransactionInfo>
|
||||
out.writeString(hash);
|
||||
out.writeLong(timestamp);
|
||||
out.writeString(paymentId);
|
||||
out.writeInt(subaddrAccount);
|
||||
out.writeInt(account);
|
||||
out.writeInt(subaddress);
|
||||
out.writeLong(confirmations);
|
||||
out.writeList(transfers);
|
||||
out.writeString(txKey);
|
||||
@ -143,7 +147,8 @@ public class TransactionInfo implements Parcelable, Comparable<TransactionInfo>
|
||||
hash = in.readString();
|
||||
timestamp = in.readLong();
|
||||
paymentId = in.readString();
|
||||
subaddrAccount = in.readInt();
|
||||
account = in.readInt();
|
||||
subaddress = in.readInt();
|
||||
confirmations = in.readLong();
|
||||
transfers = in.readArrayList(Transfer.class.getClassLoader());
|
||||
txKey = in.readString();
|
||||
|
@ -19,6 +19,9 @@ package com.m2049r.xmrwallet.model;
|
||||
import com.m2049r.xmrwallet.data.TxData;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
@ -86,10 +89,22 @@ public class Wallet {
|
||||
public native boolean setPassword(String password);
|
||||
|
||||
public String getAddress() {
|
||||
return getAddressJ(accountIndex);
|
||||
return getAddress(accountIndex);
|
||||
}
|
||||
|
||||
private native String getAddressJ(int accountIndex);
|
||||
public String getAddress(int accountIndex) {
|
||||
return getAddressJ(accountIndex, 0);
|
||||
}
|
||||
|
||||
public String getSubaddress(int addressIndex) {
|
||||
return getAddressJ(accountIndex, addressIndex);
|
||||
}
|
||||
|
||||
public String getSubaddress(int accountIndex, int addressIndex) {
|
||||
return getAddressJ(accountIndex, addressIndex);
|
||||
}
|
||||
|
||||
private native String getAddressJ(int accountIndex, int addressIndex);
|
||||
|
||||
public native String getPath();
|
||||
|
||||
@ -109,7 +124,9 @@ public class Wallet {
|
||||
public native String getSecretSpendKey();
|
||||
|
||||
public boolean store() {
|
||||
return store("");
|
||||
final boolean ok = store("");
|
||||
Timber.d("stored");
|
||||
return ok;
|
||||
}
|
||||
|
||||
public native boolean store(String path);
|
||||
@ -323,17 +340,21 @@ public class Wallet {
|
||||
public String getAccountLabel(int accountIndex) {
|
||||
String label = getSubaddressLabel(accountIndex, 0);
|
||||
if (label.equals(NEW_ACCOUNT_NAME)) {
|
||||
String address = getAddressJ(accountIndex);
|
||||
String address = getAddress(accountIndex);
|
||||
int len = address.length();
|
||||
return address.substring(0, 6) +
|
||||
"\u2026" + address.substring(len - 6, len);
|
||||
} else return label;
|
||||
}
|
||||
|
||||
public String getSubaddressLabel(int addressIndex) {
|
||||
return getSubaddressLabel(accountIndex, addressIndex);
|
||||
}
|
||||
|
||||
public native String getSubaddressLabel(int accountIndex, int addressIndex);
|
||||
|
||||
public void setAccountLabel(String label) {
|
||||
setSubaddressLabel(accountIndex, 0, label);
|
||||
setAccountLabel(accountIndex, label);
|
||||
}
|
||||
|
||||
public void setAccountLabel(int accountIndex, String label) {
|
||||
@ -342,9 +363,30 @@ public class Wallet {
|
||||
|
||||
public native void setSubaddressLabel(int accountIndex, int addressIndex, String label);
|
||||
|
||||
public int numAccounts() {
|
||||
return numSubaddressAccounts();
|
||||
public native int getNumAccounts();
|
||||
|
||||
public int getNumSubaddresses() {
|
||||
return getNumSubaddresses(accountIndex);
|
||||
}
|
||||
|
||||
public native int getNumSubaddresses(int accountIndex);
|
||||
|
||||
public String getNewSubaddress() {
|
||||
return getNewSubaddress(accountIndex);
|
||||
}
|
||||
|
||||
public String getNewSubaddress(int accountIndex) {
|
||||
String timeStamp = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss", Locale.US).format(new Date());
|
||||
addSubaddress(accountIndex, timeStamp);
|
||||
String subaddress = getLastSubaddress(accountIndex);
|
||||
Timber.d("%d: %s", getNumSubaddresses(accountIndex) - 1, subaddress);
|
||||
return subaddress;
|
||||
}
|
||||
|
||||
public native void addSubaddress(int accountIndex, String label);
|
||||
|
||||
public String getLastSubaddress(int accountIndex) {
|
||||
return getSubaddress(accountIndex, getNumSubaddresses(accountIndex) - 1);
|
||||
}
|
||||
|
||||
public native int numSubaddressAccounts();
|
||||
}
|
||||
|
9
app/src/main/res/drawable/ic_settings_gray_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_settings_gray_24dp.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path
|
||||
android:fillColor="@color/moneroGray"
|
||||
android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z" />
|
||||
</vector>
|
@ -24,11 +24,13 @@
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
<FrameLayout
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvAddressLabel"
|
||||
style="@style/MoneroLabel.Heading"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
@ -39,20 +41,44 @@
|
||||
android:id="@+id/bCopyAddress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginEnd="80dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:clickable="false"
|
||||
android:src="@drawable/ic_content_nocopy_black_24dp" />
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvAddress"
|
||||
style="@style/MoneroText.Medium"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
tools:text="9wZnnNctRc7RaLya1rxykH21dUwfQpNGmVLjAvkvqe7nKT2Mw848AJNGMunW5xjoSZ5vCCU3uDnUoVqSSHxzRtQBE3f6crx" />
|
||||
android:layout_marginTop="8dp"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="10">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvAddress"
|
||||
style="@style/MoneroText.Medium"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="10"
|
||||
android:textAlignment="center"
|
||||
tools:text="9wZnnNctRc7RaLya1rxykH21dUwfQpNGmVLjAvkvqe7nKT2Mw848AJNGMunW5xjoSZ5vCCU3uDnUoVqSSHxzRtQBE3f6crx" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bSubaddress"
|
||||
style="@style/MoneroText.Button.Small"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_weight="0"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:drawableTop="@drawable/ic_settings_orange_24dp"
|
||||
android:text="@string/send_generate_paymentid_hint"
|
||||
android:textColor="@color/moneroGray"
|
||||
android:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.m2049r.xmrwallet.widget.ExchangeView
|
||||
android:id="@+id/evAmount"
|
||||
@ -96,7 +122,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="0"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:drawableTop="@drawable/ic_settings_orange_24dp"
|
||||
android:text="@string/send_generate_paymentid_hint"
|
||||
android:textColor="@color/moneroGray"
|
||||
@ -122,10 +148,10 @@
|
||||
android:visibility="invisible" />
|
||||
|
||||
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_margin="16dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="16dp"
|
||||
android:clickable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
card_view:cardCornerRadius="2dp"
|
||||
|
@ -318,4 +318,6 @@
|
||||
<string name="accounts_new">Added new account #%1$d</string>
|
||||
<string name="tx_account">Account #</string>
|
||||
<string name="send_sweepall">Send all confirmed funds in this account!</string>
|
||||
<string name="tx_subaddress">Subaddress #%1$d</string>
|
||||
<string name="generate_address_label_sub">Public Subaddress #%1$d</string>
|
||||
</resources>
|
||||
|
@ -303,4 +303,6 @@
|
||||
<string name="accounts_new">Added new account #%1$d</string>
|
||||
<string name="tx_account">Account #</string>
|
||||
<string name="send_sweepall">Send all confirmed funds in this account!</string>
|
||||
<string name="tx_subaddress">Subaddress #%1$d</string>
|
||||
<string name="generate_address_label_sub">Public Subaddress #%1$d</string>
|
||||
</resources>
|
||||
|
@ -321,4 +321,6 @@
|
||||
<string name="accounts_new">Nouveau Compte #%1$d ajouté</string>
|
||||
<string name="tx_account">Compte #</string>
|
||||
<string name="send_sweepall">Send all confirmed funds in this account!</string>
|
||||
<string name="tx_subaddress">Subaddress #%1$d</string>
|
||||
<string name="generate_address_label_sub">Public Subaddress #%1$d</string>
|
||||
</resources>
|
||||
|
@ -319,4 +319,6 @@
|
||||
<string name="accounts_new">Added new account #%1$d</string>
|
||||
<string name="tx_account">Account #</string>
|
||||
<string name="send_sweepall">Send all confirmed funds in this account!</string>
|
||||
<string name="tx_subaddress">Subaddress #%1$d</string>
|
||||
<string name="generate_address_label_sub">Public Subaddress #%1$d</string>
|
||||
</resources>
|
||||
|
@ -317,4 +317,6 @@
|
||||
<string name="accounts_new">Added new account #%1$d</string>
|
||||
<string name="tx_account">Account #</string>
|
||||
<string name="send_sweepall">Send all confirmed funds in this account!</string>
|
||||
<string name="tx_subaddress">Subaddress #%1$d</string>
|
||||
<string name="generate_address_label_sub">Public Subaddress #%1$d</string>
|
||||
</resources>
|
||||
|
@ -315,4 +315,6 @@
|
||||
<string name="accounts_new">Added new account #%1$d</string>
|
||||
<string name="tx_account">Account #</string>
|
||||
<string name="send_sweepall">Send all confirmed funds in this account!</string>
|
||||
<string name="tx_subaddress">Subaddress #%1$d</string>
|
||||
<string name="generate_address_label_sub">Public Subaddress #%1$d</string>
|
||||
</resources>
|
||||
|
@ -316,4 +316,6 @@
|
||||
<string name="accounts_new">Added new account #%1$d</string>
|
||||
<string name="tx_account">Account #</string>
|
||||
<string name="send_sweepall">Send all confirmed funds in this account!</string>
|
||||
<string name="tx_subaddress">Subaddress #%1$d</string>
|
||||
<string name="generate_address_label_sub">Public Subaddress #%1$d</string>
|
||||
</resources>
|
||||
|
@ -216,6 +216,7 @@
|
||||
<string name="generate_mnemonic_hint">25-Word Mnemonic Seed</string>
|
||||
<string name="generate_restoreheight_hint">Restore Height or Date (YYYY-MM-DD)</string>
|
||||
|
||||
<string name="generate_address_label_sub">Public Subaddress #%1$d</string>
|
||||
<string name="generate_address_label">Public Address</string>
|
||||
<string name="generate_viewkey_label">View Key</string>
|
||||
<string name="generate_spendkey_label">Spend Key</string>
|
||||
@ -365,4 +366,6 @@
|
||||
<string name="accounts_drawer_new">Create Account</string>
|
||||
<string name="accounts_drawer_title">Accounts</string>
|
||||
|
||||
<string name="tx_subaddress">Subaddress #%1$d</string>
|
||||
<string name="tx_account_formatted" translatable="false">(%1$d, %2$d)</string>
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user