support funding tabs: receive, send, transactions

This commit is contained in:
woodser 2022-07-14 09:05:48 -04:00
parent c71c61d1bb
commit fb3745c6df
18 changed files with 432 additions and 723 deletions

View file

@ -171,7 +171,7 @@ class CoreWalletsService {
String getXmrNewSubaddress() {
accountService.checkAccountOpen();
return xmrWalletService.getWallet().createSubaddress(0).getAddress();
return xmrWalletService.getNewAddressEntry().getAddressString();
}
List<MoneroTxWallet> getXmrTxs() {

View file

@ -25,8 +25,8 @@ public class XmrBalanceListener {
public XmrBalanceListener() {
}
public XmrBalanceListener(Integer accountIndex) {
this.subaddressIndex = accountIndex;
public XmrBalanceListener(Integer subaddressIndex) {
this.subaddressIndex = subaddressIndex;
}
public Integer getSubaddressIndex() {

View file

@ -55,6 +55,7 @@ import monero.wallet.model.MoneroCheckTx;
import monero.wallet.model.MoneroDestination;
import monero.wallet.model.MoneroOutputWallet;
import monero.wallet.model.MoneroSubaddress;
import monero.wallet.model.MoneroTransferQuery;
import monero.wallet.model.MoneroTxConfig;
import monero.wallet.model.MoneroTxQuery;
import monero.wallet.model.MoneroTxWallet;
@ -70,6 +71,7 @@ public class XmrWalletService {
// Monero configuration
// TODO: don't hard code configuration, inject into classes?
public static final int NUM_BLOCKS_UNLOCK = 10;
private static final MoneroNetworkType MONERO_NETWORK_TYPE = getMoneroNetworkType();
private static final MoneroWalletRpcManager MONERO_WALLET_RPC_MANAGER = new MoneroWalletRpcManager();
private static final String MONERO_WALLET_RPC_DIR = System.getProperty("user.dir") + File.separator + ".localnet"; // .localnet contains monero-wallet-rpc and wallet files
@ -634,6 +636,7 @@ public class XmrWalletService {
// clear wallets
wallet = null;
multisigWallets.clear();
walletListeners.clear();
}
private void backupWallet(String walletName) {
@ -649,7 +652,17 @@ public class XmrWalletService {
}
// ----------------------------- LEGACY APP -------------------------------
public XmrAddressEntry getNewAddressEntry() {
return getOrCreateAddressEntry(XmrAddressEntry.Context.AVAILABLE, Optional.empty());
}
public XmrAddressEntry getFreshAddressEntry() {
List<XmrAddressEntry> unusedAddressEntries = getUnusedAddressEntries();
if (unusedAddressEntries.isEmpty()) return getNewAddressEntry();
else return unusedAddressEntries.get(0);
}
public XmrAddressEntry recoverAddressEntry(String offerId, String address, XmrAddressEntry.Context context) {
var available = findAddressEntry(address, XmrAddressEntry.Context.AVAILABLE);
if (!available.isPresent()) return null;
@ -761,12 +774,21 @@ public class XmrWalletService {
return xmrAddressEntryList.getAddressEntriesAsListImmutable();
}
public boolean isSubaddressUnused(int subaddressIndex) {
return subaddressIndex != 0 && getBalanceForSubaddress(subaddressIndex).value == 0;
// return !wallet.getSubaddress(accountIndex, 0).isUsed(); // TODO: isUsed()
// does not include unconfirmed funds
public List<XmrAddressEntry> getUnusedAddressEntries() {
return getAvailableAddressEntries().stream()
.filter(e -> isSubaddressUnused(e.getSubaddressIndex()))
.collect(Collectors.toList());
}
public boolean isSubaddressUnused(int subaddressIndex) {
return getNumTxOutputsForSubaddress(subaddressIndex) == 0;
}
public Coin getBalanceForAddress(String address) {
return getBalanceForSubaddress(wallet.getAddressIndex(address).getIndex());
}
// TODO: Coin represents centineros everywhere, but here it's atomic units. reconcile
public Coin getBalanceForSubaddress(int subaddressIndex) {
// get subaddress balance
@ -786,6 +808,24 @@ public class XmrWalletService {
return Coin.valueOf(balance.longValueExact());
}
public int getNumTxOutputsForSubaddress(int subaddressIndex) {
// get txs with transfers to the subaddress
List<MoneroTxWallet> txs = wallet.getTxs(new MoneroTxQuery()
.setTransferQuery((new MoneroTransferQuery()
.setAccountIndex(0)
.setSubaddressIndex(subaddressIndex)
.setIsIncoming(true)))
.setIncludeOutputs(true));
// count num outputs
int numUnspentOutputs = 0;
for (MoneroTxWallet tx : txs) {
numUnspentOutputs += tx.isConfirmed() ? tx.getOutputs().size() : 1; // TODO: monero-project does not provide outputs for unconfirmed txs
}
return numUnspentOutputs;
}
public Coin getAvailableConfirmedBalance() {
return wallet != null ? Coin.valueOf(wallet.getUnlockedBalance(0).longValueExact()) : Coin.ZERO;
}

View file

@ -26,7 +26,6 @@ import bisq.core.offer.Offer;
import bisq.core.offer.OfferDirection;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.proto.CoreProtoResolver;
import bisq.core.support.dispute.arbitration.arbitrator.Arbitrator;
import bisq.core.support.dispute.mediation.MediationResultState;
import bisq.core.support.dispute.refund.RefundResultState;
import bisq.core.support.messages.ChatMessage;
@ -886,7 +885,7 @@ public abstract class Trade implements Tradable, Model {
// check if deposit txs unlocked
if (txs.get(0).isConfirmed() && txs.get(1).isConfirmed()) {
long unlockHeight = Math.max(txs.get(0).getHeight(), txs.get(0).getHeight()) + 9;
long unlockHeight = Math.max(txs.get(0).getHeight(), txs.get(0).getHeight()) + XmrWalletService.NUM_BLOCKS_UNLOCK - 1;
if (havenoWallet.getHeight() >= unlockHeight) {
setConfirmedState();
return;
@ -926,7 +925,7 @@ public abstract class Trade implements Tradable, Model {
// compute unlock height
if (unlockHeight == null && txs.size() == 2 && txs.get(0).isConfirmed() && txs.get(1).isConfirmed()) {
unlockHeight = Math.max(txs.get(0).getHeight(), txs.get(0).getHeight()) + 9;
unlockHeight = Math.max(txs.get(0).getHeight(), txs.get(0).getHeight()) + XmrWalletService.NUM_BLOCKS_UNLOCK - 1;
}
// check if txs unlocked

View file

@ -25,6 +25,10 @@ public class ParsingUtils {
return centinerosToAtomicUnits(coin.value);
}
public static double coinToXmr(Coin coin) {
return atomicUnitsToXmr(coinToAtomicUnits(coin));
}
public static BigInteger centinerosToAtomicUnits(long centineros) {
return BigInteger.valueOf(centineros).multiply(ParsingUtils.CENTINEROS_AU_MULTIPLIER);
}
@ -39,7 +43,11 @@ public class ParsingUtils {
public static long atomicUnitsToCentineros(BigInteger atomicUnits) {
return atomicUnits.divide(CENTINEROS_AU_MULTIPLIER).longValueExact();
}
}
public static Coin atomicUnitsToCoin(BigInteger atomicUnits) {
return Coin.valueOf(atomicUnitsToCentineros(atomicUnits));
}
public static double atomicUnitsToXmr(BigInteger atomicUnits) {
return new BigDecimal(atomicUnits).divide(new BigDecimal(XMR_AU_MULTIPLIER)).doubleValue();