Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature(dashpay): display coinjoin mixing info #1224

Merged
merged 26 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8d9bca3
chore: update to dashj 20.0.0-CJ-SNAPSHOT
HashEngineering Oct 6, 2023
0fd636e
Merge branch 'dashpay' of https://github.com/dashevo/dash-wallet into…
HashEngineering Oct 12, 2023
bde8fab
feat: use CoinJoinConfig for Mixing Mode (none, interm, adv)
HashEngineering Oct 23, 2023
cd74d68
fix: fix block explorer for devnet
HashEngineering Oct 30, 2023
6d2e40a
feat: make SendCoinsTaskRunner coinjoin aware
HashEngineering Oct 30, 2023
af903e0
tests: fix DatabaseMigrationTest
HashEngineering Oct 30, 2023
4ec8988
feat(coinjoin): mix entire balance
HashEngineering Oct 30, 2023
7da5e2d
tests: add mock of CoinJoinConfig
HashEngineering Oct 30, 2023
b7291d1
fix: remove BlockchainServiceExt and further simplify CoinJoinService
HashEngineering Nov 2, 2023
b6a6c83
feat(coinjoin): add mixing information
HashEngineering Nov 3, 2023
40b2cbd
Merge branch 'dashpay-coinjoin-wallet' of https://github.com/dashevo/…
HashEngineering Nov 3, 2023
57e83ad
fix: always run CoinJoinService and simplify
HashEngineering Nov 6, 2023
e952edb
Calculate MAX amount correctly
HashEngineering Nov 6, 2023
5a88e77
Merge branch 'dashpay-coinjoin-wallet' of https://github.com/dashevo/…
HashEngineering Nov 6, 2023
5c48cda
feat(coinjoin): update settings progress
HashEngineering Nov 7, 2023
dcb0166
fix: coinjoin transactions to not make fees
HashEngineering Nov 7, 2023
9204cb6
Merge branch 'dashpay' of https://github.com/dashevo/dash-wallet into…
HashEngineering Nov 9, 2023
d516a96
Merge branch 'dashpay-coinjoin-wallet' of https://github.com/dashevo/…
HashEngineering Nov 9, 2023
140f8a0
fix: update mixing pane
HashEngineering Nov 10, 2023
f418943
fix: return change
HashEngineering Nov 10, 2023
bfd6e45
fix: add mixing notification
HashEngineering Nov 10, 2023
bbd9915
tests: update MainViewModelTest
HashEngineering Nov 11, 2023
045a5ea
fix(coinjoin): don't stop the coinjoin manager
HashEngineering Nov 15, 2023
e382c68
fix(coinjoin): consider sync status as part of update balance
HashEngineering Nov 20, 2023
faa4a07
chore: remove comment and add private
HashEngineering Nov 21, 2023
f661e13
Merge branch 'dashpay' of https://github.com/dashevo/dash-wallet into…
HashEngineering Nov 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,11 @@ open class DatabaseMigrationTest {
private val service = ServiceName.CrowdNode
}

private val migrations = arrayOf(AppDatabaseMigrations.migration11To17, AppDatabaseMigrations.migration17To18)
private val migrations = arrayOf(
AppDatabaseMigrations.migration11To12,
AppDatabaseMigrations.migration12To17,
AppDatabaseMigrations.migration17To18
)

@Rule
@JvmField
Expand Down
16 changes: 16 additions & 0 deletions wallet/res/drawable/ic_mixing_icon.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="38dp"
android:height="38dp"
android:viewportWidth="38"
android:viewportHeight="38">
<path
android:pathData="M19,0L19,0A19,19 0,0 1,38 19L38,19A19,19 0,0 1,19 38L19,38A19,19 0,0 1,0 19L0,19A19,19 0,0 1,19 0z"
android:fillColor="#008DE4"
android:fillAlpha="0.1"/>
<path
android:pathData="M19,30C17.497,30 16.081,29.712 14.751,29.137C13.428,28.562 12.26,27.768 11.246,26.754C10.232,25.74 9.438,24.572 8.863,23.249C8.288,21.919 8,20.503 8,19C8,17.497 8.288,16.085 8.863,14.762C9.438,13.432 10.229,12.26 11.235,11.246C12.249,10.232 13.417,9.438 14.74,8.863C16.07,8.288 17.487,8 18.989,8C20.492,8 21.908,8.288 23.238,8.863C24.568,9.438 25.74,10.232 26.754,11.246C27.768,12.26 28.562,13.432 29.137,14.762C29.712,16.085 30,17.497 30,19C30,20.503 29.712,21.919 29.137,23.249C28.562,24.572 27.768,25.74 26.754,26.754C25.74,27.768 24.568,28.562 23.238,29.137C21.915,29.712 20.503,30 19,30Z"
android:fillColor="#008DE4"/>
<path
android:pathData="M16.627,16.681C17.152,16.681 17.605,16.491 17.986,16.11C18.375,15.721 18.569,15.265 18.569,14.74C18.569,14.208 18.375,13.755 17.986,13.381C17.605,13 17.152,12.81 16.627,12.81C16.095,12.81 15.639,13 15.258,13.381C14.884,13.755 14.697,14.208 14.697,14.74C14.697,15.265 14.884,15.721 15.258,16.11C15.632,16.491 16.088,16.681 16.627,16.681ZM21.383,16.681C21.915,16.681 22.368,16.491 22.742,16.11C23.123,15.721 23.314,15.265 23.314,14.74C23.314,14.208 23.123,13.755 22.742,13.381C22.368,13 21.915,12.81 21.383,12.81C20.858,12.81 20.402,13 20.014,13.381C19.633,13.755 19.442,14.208 19.442,14.74C19.442,15.265 19.633,15.721 20.014,16.11C20.402,16.491 20.858,16.681 21.383,16.681ZM14.266,20.93C14.79,20.93 15.24,20.74 15.614,20.359C15.995,19.978 16.185,19.525 16.185,19C16.185,18.475 15.995,18.022 15.614,17.641C15.24,17.253 14.79,17.059 14.266,17.059C13.734,17.059 13.274,17.253 12.885,17.641C12.504,18.022 12.314,18.475 12.314,19C12.314,19.525 12.504,19.978 12.885,20.359C13.266,20.74 13.726,20.93 14.266,20.93ZM19.011,20.93C19.536,20.93 19.989,20.74 20.37,20.359C20.751,19.978 20.941,19.525 20.941,19C20.941,18.475 20.751,18.022 20.37,17.641C19.989,17.253 19.536,17.059 19.011,17.059C18.479,17.059 18.022,17.253 17.641,17.641C17.26,18.022 17.07,18.475 17.07,19C17.07,19.525 17.26,19.978 17.641,20.359C18.022,20.74 18.479,20.93 19.011,20.93ZM23.756,20.93C24.281,20.93 24.734,20.74 25.115,20.359C25.503,19.978 25.697,19.525 25.697,19C25.697,18.475 25.503,18.022 25.115,17.641C24.734,17.253 24.281,17.059 23.756,17.059C23.224,17.059 22.767,17.253 22.386,17.641C22.012,18.022 21.826,18.475 21.826,19C21.826,19.525 22.012,19.978 22.386,20.359C22.767,20.74 23.224,20.93 23.756,20.93ZM16.627,25.19C17.152,25.19 17.605,25.003 17.986,24.629C18.375,24.248 18.569,23.792 18.569,23.26C18.569,22.728 18.375,22.271 17.986,21.89C17.605,21.509 17.152,21.318 16.627,21.318C16.095,21.318 15.639,21.509 15.258,21.89C14.884,22.271 14.697,22.728 14.697,23.26C14.697,23.784 14.884,24.237 15.258,24.618C15.632,24.999 16.088,25.19 16.627,25.19ZM21.383,25.19C21.915,25.19 22.368,25.003 22.742,24.629C23.123,24.248 23.314,23.792 23.314,23.26C23.314,22.728 23.123,22.271 22.742,21.89C22.368,21.509 21.915,21.318 21.383,21.318C20.858,21.318 20.402,21.509 20.014,21.89C19.633,22.271 19.442,22.728 19.442,23.26C19.442,23.792 19.633,24.248 20.014,24.629C20.402,25.003 20.858,25.19 21.383,25.19Z"
android:fillColor="#ffffff"/>
</vector>
8 changes: 4 additions & 4 deletions wallet/res/layout/activity_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@
<TextView
android:id="@+id/coinjoin_title"
style="@style/Body2.Medium"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/coinjoin"
android:layout_height="27dp"
android:layout_marginStart="22dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/coinjoin_icon"
android:text="@string/coinjoin"
app:layout_constraintBottom_toTopOf="@id/coinjoin_subtitle"
app:layout_constraintStart_toEndOf="@id/coinjoin_icon"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />

<TextView
Expand Down
10 changes: 10 additions & 0 deletions wallet/res/layout/home_content.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="14dp" />

<include
android:id="@+id/mixing_status_pane"
layout="@layout/mixing_status_pane"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
tools:visibility="visible"
android:layout_marginBottom="14dp" />

</LinearLayout>
</LinearLayout>

Expand Down
70 changes: 70 additions & 0 deletions wallet/res/layout/mixing_status_pane.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="wrap_content"
android:layout_width="match_parent">

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/mixing_status_pane2"
android:layout_width="match_parent"
android:layout_height="58dp"
android:background="@drawable/white_background_rounded">

<ImageView
android:id="@+id/mixing_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:src="@drawable/ic_mixing_icon"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/mixing_mode"
style="@style/Overline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="@string/coinjoin_mixing"
app:layout_constraintStart_toEndOf="@id/mixing_icon"
app:layout_constraintTop_toTopOf="@id/mixing_icon" />

<TextView
android:id="@+id/balance"
style="@style/Overline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="3dp"
app:layout_constraintEnd_toStartOf="@id/dash_icon"
app:layout_constraintTop_toTopOf="@id/mixing_mode"
tools:text="0.012 of 0.028 DASH" />

<ImageView
android:id="@+id/dash_icon"
android:layout_width="11dp"
android:layout_height="11dp"
android:layout_gravity="center_vertical"
android:layout_marginTop="3dp"
android:layout_marginEnd="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/mixing_mode"
app:srcCompat="@drawable/ic_dash"
app:tint="@color/content_primary" />

<ProgressBar
android:id="@+id/mixing_progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="8dp"
android:progress="50"
app:layout_constraintEnd_toEndOf="@id/dash_icon"
app:layout_constraintStart_toEndOf="@id/mixing_icon"
app:layout_constraintTop_toBottomOf="@id/mixing_mode" />

</androidx.constraintlayout.widget.ConstraintLayout>

</RelativeLayout>
5 changes: 4 additions & 1 deletion wallet/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,11 @@
<string name="coinjoin_advanced_time">Multiple hours</string>
<string name="coinjoin_start">Start Mixing</string>
<string name="coinjoin_stop">Stop Mixing</string>
<string name="coinjoin_mixing">Mixing</string>
<string name="coinjoin_progress">Mixing · %1$s of %2$s</string>
<string name="coinjoin_progress_balance">%1$s of %2$s</string>
<string name="coinjoin_progress_finished">Fully Mixed</string>
<string name="coinjoin_change_level_confirmation">Are you sure you want to change the privacy level?</string>
<string name="coinjoin_stop_mixing_title">Are you sure you want to stop mixing?</string>
<string name="coinjoin_stop_mixing_message">Any funds that have been mixed will be combined with your un mixed funds</string>
<string name="coinjoin_stop_mixing_message">Any funds that have been mixed will be combined with your unmixed funds</string>
</resources>
2 changes: 1 addition & 1 deletion wallet/schnapps/res/values/values.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<item>µtDASH, no decimal places</item>
</string-array>
<string-array name="preferences_block_explorer_values">
<item>https://insight.bintang.networks.dash.org:3002/insight</item>
<item>https://insight.ouzo.networks.dash.org:3002/insight</item>
</string-array>
<string-array name="preferences_block_explorer_labels">
<item>Insight Devnet Block Explorer</item>
Expand Down
18 changes: 18 additions & 0 deletions wallet/src/de/schildbach/wallet/data/CoinJoinConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ import android.content.Context
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import de.schildbach.wallet.service.CoinJoinMode
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
import org.dash.wallet.common.WalletDataProvider
import org.dash.wallet.common.data.BaseConfig
import javax.inject.Inject
Expand All @@ -34,10 +39,23 @@ open class CoinJoinConfig @Inject constructor(
) : BaseConfig(context, PREFERENCES_NAME, walletDataProvider) {
companion object {
const val PREFERENCES_NAME = "coinjoin"
val COINJOIN_MODE = stringPreferencesKey("coinjoin_mode")
val COINJOIN_ROUNDS = intPreferencesKey("coinjoin_rounds")
val COINJOIN_SESSIONS = intPreferencesKey("coinjoin_sessions")
val COINJOIN_MULTISESSION = booleanPreferencesKey("coinjoin_multisession")
val COINJOIN_AMOUNT = longPreferencesKey("coinjoin_amount")
val FIRST_TIME_INFO_SHOWN = booleanPreferencesKey("first_time_info_shown")
}

fun observeMode(): Flow<CoinJoinMode> {
return observe(COINJOIN_MODE).map { mode -> mode?.let { CoinJoinMode.valueOf(mode) } ?: CoinJoinMode.NONE }
}

suspend fun getMode(): CoinJoinMode {
return get(COINJOIN_MODE).let { mode -> mode?.let { CoinJoinMode.valueOf(it) } ?: CoinJoinMode.NONE }
}

suspend fun setMode(mode: CoinJoinMode) {
set(COINJOIN_MODE, mode.toString())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ data class BlockchainIdentityData(var creationState: CreationState = CreationSta
enum class CreationState {
NONE, // this should always be the first value
UPGRADING_WALLET,
MIXING_FUNDS,
CREDIT_FUNDING_TX_CREATING,
CREDIT_FUNDING_TX_SENDING,
CREDIT_FUNDING_TX_SENT,
Expand Down
6 changes: 4 additions & 2 deletions wallet/src/de/schildbach/wallet/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import de.schildbach.wallet.WalletApplication
import de.schildbach.wallet.data.CoinJoinConfig
import de.schildbach.wallet.payments.ConfirmTransactionLauncher
import de.schildbach.wallet.payments.SendCoinsTaskRunner
import de.schildbach.wallet.security.SecurityFunctions
Expand Down Expand Up @@ -99,9 +100,10 @@ abstract class AppModule {
walletData: WalletDataProvider,
walletApplication: WalletApplication,
securityFunctions: SecurityFunctions,
packageInfoProvider: PackageInfoProvider
packageInfoProvider: PackageInfoProvider,
coinJoinConfig: CoinJoinConfig
): SendPaymentService {
val realService = SendCoinsTaskRunner(walletData, walletApplication, securityFunctions, packageInfoProvider)
val realService = SendCoinsTaskRunner(walletData, walletApplication, securityFunctions, packageInfoProvider, coinJoinConfig)

return if (BuildConfig.FLAVOR.lowercase() == "prod") {
realService
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2023 Dash Core Group.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package de.schildbach.wallet.payments

import org.bitcoinj.coinjoin.CoinJoinCoinSelector
import org.bitcoinj.core.Coin
import org.bitcoinj.core.TransactionOutput
import org.bitcoinj.wallet.CoinSelection
import org.bitcoinj.wallet.Wallet

// refactor this class and derive it from MaxOutputAmountCoinSelector
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this meant to be TODO?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it was a TODO, but now it is done. I will remove this.

class MaxOutputAmountCoinJoinCoinSelector(wallet: Wallet): MaxOutputAmountCoinSelector() {

val coinJoinCoinSelector = CoinJoinCoinSelector(wallet)

override fun select(target: Coin, candidates: MutableList<TransactionOutput>): CoinSelection {
val coinJoinCandidates = coinJoinCoinSelector.select(target, candidates)
return super.select(coinJoinCandidates.valueGathered, coinJoinCandidates.gathered.toMutableList())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import org.bitcoinj.core.VarInt
import org.bitcoinj.wallet.CoinSelection
import org.bitcoinj.wallet.CoinSelector

class MaxOutputAmountCoinSelector: CoinSelector {
open class MaxOutputAmountCoinSelector: CoinSelector {
companion object {
private const val TX_OUTPUT_SIZE = 34 // estimated size for a typical transaction output
private const val TX_INPUT_SIZE = 148 // estimated size for a typical compact pubkey transaction input
Expand Down
49 changes: 38 additions & 11 deletions wallet/src/de/schildbach/wallet/payments/SendCoinsTaskRunner.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,20 @@
package de.schildbach.wallet.payments

import androidx.annotation.VisibleForTesting
import androidx.lifecycle.viewModelScope
import de.schildbach.wallet.WalletApplication
import de.schildbach.wallet.data.CoinJoinConfig
import de.schildbach.wallet.data.PaymentIntent
import de.schildbach.wallet.payments.parsers.PaymentIntentParser
import de.schildbach.wallet.security.SecurityFunctions
import de.schildbach.wallet.security.SecurityGuard
import de.schildbach.wallet.service.CoinJoinMode
import de.schildbach.wallet.service.PackageInfoProvider
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import okhttp3.CacheControl
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
Expand All @@ -34,7 +41,6 @@ import okio.IOException
import org.bitcoin.protocols.payments.Protos
import org.bitcoin.protocols.payments.Protos.Payment
import org.bitcoinj.coinjoin.CoinJoinCoinSelector
import org.bitcoinj.coinjoin.UnmixedZeroConfCoinSelector
import org.bitcoinj.core.*
import org.bitcoinj.crypto.IKey
import org.bitcoinj.crypto.KeyCrypterException
Expand All @@ -57,12 +63,25 @@ class SendCoinsTaskRunner @Inject constructor(
private val walletData: WalletDataProvider,
private val walletApplication: WalletApplication,
private val securityFunctions: SecurityFunctions,
private val packageInfoProvider: PackageInfoProvider
private val packageInfoProvider: PackageInfoProvider,
coinJoinConfig: CoinJoinConfig
) : SendPaymentService {
companion object {
private const val WALLET_EXCEPTION_MESSAGE = "this method can't be used before creating the wallet"
private val log = LoggerFactory.getLogger(SendCoinsTaskRunner::class.java)
}
private var coinJoinSend = false
private val coroutineScope = CoroutineScope(Dispatchers.IO)

init {
coinJoinConfig
.observeMode()
.filterNotNull()
.onEach { mode ->
coinJoinSend = mode != CoinJoinMode.NONE
}
.launchIn(coroutineScope)
}

@Throws(LeftoverBalanceException::class)
override suspend fun sendCoins(
Expand Down Expand Up @@ -233,18 +252,17 @@ class SendCoinsTaskRunner @Inject constructor(
mayEditAmount: Boolean,
paymentIntent: PaymentIntent,
signInputs: Boolean,
forceEnsureMinRequiredFee: Boolean,
coinJoin: Boolean = false
forceEnsureMinRequiredFee: Boolean
): SendRequest {
val wallet = walletData.wallet ?: throw RuntimeException(WALLET_EXCEPTION_MESSAGE)
val sendRequest = paymentIntent.toSendRequest()
sendRequest.coinSelector = getCoinSelector(coinJoin)
sendRequest.coinSelector = getCoinSelector()
sendRequest.useInstantSend = false
sendRequest.feePerKb = Constants.ECONOMIC_FEE
sendRequest.ensureMinRequiredFee = forceEnsureMinRequiredFee
sendRequest.signInputs = signInputs

val walletBalance = wallet.getBalance(MaxOutputAmountCoinSelector())
val walletBalance = wallet.getBalance(getMaxOutputCoinSelector())
sendRequest.emptyWallet = mayEditAmount && walletBalance == paymentIntent.amount

return sendRequest
Expand All @@ -256,15 +274,14 @@ class SendCoinsTaskRunner @Inject constructor(
amount: Coin,
coinSelector: CoinSelector? = null,
emptyWallet: Boolean = false,
forceMinFee: Boolean = true,
coinJoin: Boolean = false
forceMinFee: Boolean = true
): SendRequest {
return SendRequest.to(address, amount).apply {
this.feePerKb = Constants.ECONOMIC_FEE
this.ensureMinRequiredFee = forceMinFee
this.emptyWallet = emptyWallet

val selector = coinSelector ?: getCoinSelector(coinJoin)
val selector = coinSelector ?: getCoinSelector()
this.coinSelector = selector

if (selector is ByAddressCoinSelector) {
Expand All @@ -273,10 +290,20 @@ class SendCoinsTaskRunner @Inject constructor(
}
}

private fun getCoinSelector(coinJoin: Boolean) = if (coinJoin) {
private fun getCoinSelector() = if (coinJoinSend) {
// mixed only
CoinJoinCoinSelector(walletData.wallet)
} else {
UnmixedZeroConfCoinSelector(walletData.wallet)
// collect all coins, mixed and unmixed
ZeroConfCoinSelector.get()
}

private fun getMaxOutputCoinSelector() = if (coinJoinSend) {
// mixed only
MaxOutputAmountCoinJoinCoinSelector(walletData.wallet!!)
} else {
// collect all coins, mixed and unmixed
MaxOutputAmountCoinSelector()
}

@Throws(LeftoverBalanceException::class)
Expand Down
Loading
Loading