mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-08-14 17:35:27 -04:00
support funding tabs: receive, send, transactions
This commit is contained in:
parent
c71c61d1bb
commit
fb3745c6df
18 changed files with 432 additions and 723 deletions
|
@ -171,7 +171,7 @@ class CoreWalletsService {
|
|||
|
||||
String getXmrNewSubaddress() {
|
||||
accountService.checkAccountOpen();
|
||||
return xmrWalletService.getWallet().createSubaddress(0).getAddress();
|
||||
return xmrWalletService.getNewAddressEntry().getAddressString();
|
||||
}
|
||||
|
||||
List<MoneroTxWallet> getXmrTxs() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue