[#319] Adopt Zatoshi API
This commit is contained in:
parent
13ab487118
commit
362d2f94ab
|
@ -10,6 +10,7 @@ import cash.z.ecc.android.ext.tryWithWarning
|
|||
import cash.z.ecc.android.feedback.FeedbackCoordinator
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||
import cash.z.ecc.android.sdk.internal.Twig
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
||||
import cash.z.ecc.android.util.twig
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
@ -32,7 +33,7 @@ class ZcashWalletApp : Application(), CameraXConfig.Provider {
|
|||
var creationMeasured: Boolean = false
|
||||
|
||||
/** The amount of transparent funds that need to accumulate before autoshielding is triggered */
|
||||
val autoshieldThreshold: Long = ZcashSdk.ZATOSHI_PER_ZEC // 1 ZEC
|
||||
val autoshieldThreshold: Long = Zatoshi.ZATOSHI_PER_ZEC // 1 ZEC
|
||||
|
||||
/**
|
||||
* Intentionally private Scope for use with launching Feedback jobs. The feedback object has the
|
||||
|
|
|
@ -28,7 +28,7 @@ inline fun <reified VM : ViewModel> BaseFragment<*>.activityViewModel(isSynchron
|
|||
return cached
|
||||
?: scopedFactory<VM>(isSynchronizerScope)?.let { factory ->
|
||||
ViewModelProvider(this@activityViewModel.mainActivity!!, factory)[VM::class.java]
|
||||
}
|
||||
}!!
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import cash.z.ecc.android.ext.ConversionsUniform.LONG_SCALE
|
|||
import cash.z.ecc.android.ext.ConversionsUniform.SHORT_FORMATTER
|
||||
import cash.z.ecc.android.sdk.ext.Conversions
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import java.math.BigDecimal
|
||||
import java.math.MathContext
|
||||
import java.math.RoundingMode
|
||||
|
@ -25,7 +26,7 @@ import java.util.Locale
|
|||
*
|
||||
*/
|
||||
object ConversionsUniform {
|
||||
val ONE_ZEC_IN_ZATOSHI = BigDecimal(ZcashSdk.ZATOSHI_PER_ZEC, MathContext.DECIMAL128)
|
||||
val ONE_ZEC_IN_ZATOSHI = BigDecimal(Zatoshi.ZATOSHI_PER_ZEC, MathContext.DECIMAL128)
|
||||
val LONG_SCALE = 8
|
||||
val SHORT_SCALE = 4
|
||||
val SHORT_FORMATTER = from(SHORT_SCALE, SHORT_SCALE)
|
||||
|
@ -47,11 +48,11 @@ object WalletZecFormmatter {
|
|||
fun toZatoshi(zecString: String): Long? {
|
||||
return toBigDecimal(zecString)?.multiply(Conversions.ONE_ZEC_IN_ZATOSHI, MathContext.DECIMAL128)?.toLong()
|
||||
}
|
||||
fun toZecStringShort(zatoshi: Long?): String {
|
||||
return SHORT_FORMATTER.format((zatoshi ?: 0).toZec())
|
||||
fun toZecStringShort(amount: Zatoshi?): String {
|
||||
return SHORT_FORMATTER.format((amount ?: Zatoshi(0)).toZec())
|
||||
}
|
||||
fun toZecStringFull(zatoshi: Long?): String {
|
||||
return formatFull((zatoshi ?: 0).toZec())
|
||||
fun toZecStringFull(amount: Zatoshi?): String {
|
||||
return formatFull((amount ?: Zatoshi(0)).toZec())
|
||||
}
|
||||
fun formatFull(zec: BigDecimal): String {
|
||||
return FULL_FORMATTER.format(zec)
|
||||
|
@ -68,8 +69,8 @@ object WalletZecFormmatter {
|
|||
}
|
||||
|
||||
// convert a zatoshi value to ZEC as a BigDecimal
|
||||
private fun Long?.toZec(): BigDecimal =
|
||||
BigDecimal(this ?: 0L, MathContext.DECIMAL128)
|
||||
private fun Zatoshi?.toZec(): BigDecimal =
|
||||
BigDecimal(this?.value ?: 0L, MathContext.DECIMAL128)
|
||||
.divide(ConversionsUniform.ONE_ZEC_IN_ZATOSHI)
|
||||
.setScale(LONG_SCALE, ConversionsUniform.roundingMode)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import android.widget.EditText
|
|||
import android.widget.TextView
|
||||
import cash.z.ecc.android.sdk.ext.convertZecToZatoshi
|
||||
import cash.z.ecc.android.sdk.ext.safelyConvertToBigDecimal
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.util.twig
|
||||
|
||||
fun EditText.onEditorActionDone(block: (EditText) -> Unit) {
|
||||
|
@ -72,9 +73,9 @@ inline fun EditText.limitDecimalPlaces(max: Int) {
|
|||
})
|
||||
}
|
||||
|
||||
fun TextView.convertZecToZatoshi(): Long? {
|
||||
fun TextView.convertZecToZatoshi(): Zatoshi? {
|
||||
return try {
|
||||
text.toString().safelyConvertToBigDecimal()?.convertZecToZatoshi() ?: null
|
||||
text.toString().safelyConvertToBigDecimal()?.convertZecToZatoshi()
|
||||
} catch (t: Throwable) {
|
||||
twig("Failed to convert text to Zatoshi: $text")
|
||||
null
|
||||
|
|
|
@ -3,6 +3,7 @@ package cash.z.ecc.android.ext
|
|||
import android.content.Context
|
||||
import android.os.Build
|
||||
import androidx.fragment.app.Fragment
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.sdk.type.WalletBalance
|
||||
import cash.z.ecc.android.util.Bush
|
||||
import cash.z.ecc.android.util.Twig
|
||||
|
@ -32,8 +33,8 @@ fun <T> String.distribute(chunks: Int, block: (Int, String) -> T) {
|
|||
|
||||
fun Boolean.asString(ifTrue: String = "", ifFalse: String = "") = if (this) ifTrue else ifFalse
|
||||
|
||||
inline val WalletBalance.pending: Long
|
||||
get() = (this.totalZatoshi - this.availableZatoshi).coerceAtLeast(0)
|
||||
inline val WalletBalance.pending: Zatoshi
|
||||
get() = (this.total - this.available)
|
||||
|
||||
inline fun <R> tryWithWarning(message: String = "", block: () -> R): R? {
|
||||
return try {
|
||||
|
|
|
@ -24,6 +24,7 @@ import cash.z.ecc.android.sdk.ext.toAbbreviatedAddress
|
|||
import cash.z.ecc.android.sdk.type.WalletBalance
|
||||
import cash.z.ecc.android.ui.base.BaseFragment
|
||||
import cash.z.ecc.android.util.twig
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class HistoryFragment : BaseFragment<FragmentHistoryBinding>() {
|
||||
|
@ -51,22 +52,22 @@ class HistoryFragment : BaseFragment<FragmentHistoryBinding>() {
|
|||
override fun onResume() {
|
||||
twig("HistoryFragment.onResume")
|
||||
super.onResume()
|
||||
viewModel.balance.collectWith(resumedScope) {
|
||||
viewModel.balance.filterNotNull().collectWith(resumedScope) {
|
||||
onBalanceUpdated(it)
|
||||
}
|
||||
viewModel.transactions.collectWith(resumedScope) { onTransactionsUpdated(it) }
|
||||
}
|
||||
|
||||
private fun onBalanceUpdated(balance: WalletBalance) {
|
||||
if (balance.availableZatoshi < 0) {
|
||||
if (balance.available.value < 0) {
|
||||
binding.textBalanceAvailable.text = "Updating"
|
||||
return
|
||||
}
|
||||
|
||||
binding.textBalanceAvailable.text = WalletZecFormmatter.toZecStringShort(balance.availableZatoshi)
|
||||
binding.textBalanceAvailable.text = WalletZecFormmatter.toZecStringShort(balance.available)
|
||||
val change = balance.pending
|
||||
binding.textBalanceDescription.apply {
|
||||
goneIf(change <= 0L)
|
||||
goneIf(change.value <= 0L)
|
||||
val changeString = WalletZecFormmatter.toZecStringFull(change)
|
||||
val expecting = R.string.home_banner_expecting.toAppString(true)
|
||||
val symbol = getString(R.string.symbol)
|
||||
|
|
|
@ -13,7 +13,9 @@ import cash.z.ecc.android.lockbox.LockBox
|
|||
import cash.z.ecc.android.sdk.SdkSynchronizer
|
||||
import cash.z.ecc.android.sdk.Synchronizer
|
||||
import cash.z.ecc.android.sdk.db.entity.ConfirmedTransaction
|
||||
import cash.z.ecc.android.sdk.db.entity.valueInZatoshi
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.ui.util.MemoUtil
|
||||
import cash.z.ecc.android.ui.util.toUtf8Memo
|
||||
import cash.z.ecc.android.util.twig
|
||||
|
@ -77,7 +79,7 @@ class HistoryViewModel @Inject constructor() : ViewModel() {
|
|||
else -> null
|
||||
}
|
||||
isMined = tx?.minedHeight != null && tx.minedHeight > synchronizer.network.saplingActivationHeight
|
||||
topValue = if (tx == null) "" else "\$${WalletZecFormmatter.toZecStringFull(tx.value)}"
|
||||
topValue = if (tx == null) "" else "\$${WalletZecFormmatter.toZecStringFull(tx.valueInZatoshi)}"
|
||||
minedHeight = String.format("%,d", tx?.minedHeight ?: 0)
|
||||
val flags =
|
||||
DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_SHOW_YEAR or DateUtils.FORMAT_ABBREV_MONTH
|
||||
|
@ -124,7 +126,7 @@ class HistoryViewModel @Inject constructor() : ViewModel() {
|
|||
true -> {
|
||||
topLabel = getString(R.string.transaction_story_inbound)
|
||||
bottomLabel = getString(R.string.transaction_story_inbound_total)
|
||||
bottomValue = "\$${WalletZecFormmatter.toZecStringFull(tx?.value)}"
|
||||
bottomValue = "\$${WalletZecFormmatter.toZecStringFull(tx?.valueInZatoshi)}"
|
||||
iconRotation = 315f
|
||||
source = getString(R.string.transaction_story_to_shielded)
|
||||
address = MemoUtil.findAddressInMemo(tx, (synchronizer as SdkSynchronizer)::isValidAddress)
|
||||
|
@ -132,7 +134,7 @@ class HistoryViewModel @Inject constructor() : ViewModel() {
|
|||
false -> {
|
||||
topLabel = getString(R.string.transaction_story_outbound)
|
||||
bottomLabel = getString(R.string.transaction_story_outbound_total)
|
||||
bottomValue = "\$${WalletZecFormmatter.toZecStringFull(tx?.value?.plus(ZcashSdk.MINERS_FEE_ZATOSHI))}"
|
||||
bottomValue = "\$${WalletZecFormmatter.toZecStringFull(Zatoshi((tx?.valueInZatoshi?.value ?: 0) + ZcashSdk.MINERS_FEE.value))}"
|
||||
iconRotation = 135f
|
||||
fee = "+ 0.00001 network fee"
|
||||
source = getString(R.string.transaction_story_from_shielded)
|
||||
|
|
|
@ -15,6 +15,7 @@ import cash.z.ecc.android.ext.toAppColor
|
|||
import cash.z.ecc.android.ext.toAppInt
|
||||
import cash.z.ecc.android.ext.toColoredSpan
|
||||
import cash.z.ecc.android.sdk.db.entity.ConfirmedTransaction
|
||||
import cash.z.ecc.android.sdk.db.entity.valueInZatoshi
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||
import cash.z.ecc.android.sdk.ext.isShielded
|
||||
import cash.z.ecc.android.sdk.ext.toAbbreviatedAddress
|
||||
|
@ -59,7 +60,7 @@ class TransactionViewHolder<T : ConfirmedTransaction>(itemView: View) : Recycler
|
|||
onTransactionLongPressed(this)
|
||||
true
|
||||
}
|
||||
amountZec = WalletZecFormmatter.toZecStringShort(value)
|
||||
amountZec = WalletZecFormmatter.toZecStringShort(valueInZatoshi)
|
||||
// TODO: these might be good extension functions
|
||||
val timestamp = formatter.format(blockTimeInSeconds * 1000L)
|
||||
val isMined = blockTimeInSeconds != 0L
|
||||
|
@ -122,7 +123,7 @@ class TransactionViewHolder<T : ConfirmedTransaction>(itemView: View) : Recycler
|
|||
}
|
||||
}
|
||||
// sanitize amount
|
||||
if (value < ZcashSdk.MINERS_FEE_ZATOSHI * 10) amountDisplay = "< 0.0001"
|
||||
if (value < ZcashSdk.MINERS_FEE.value * 10) amountDisplay = "< 0.0001"
|
||||
else if (amountZec.length > 10) { // 10 allows 3 digits to the left and 6 to the right of the decimal
|
||||
amountDisplay = str(R.string.transaction_instruction_tap)
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ class BalanceDetailFragment : BaseFragment<FragmentBalanceDetailBinding>() {
|
|||
} else {
|
||||
val toast = when {
|
||||
// if funds exist but they're all unconfirmed
|
||||
(viewModel.latestBalance?.transparentBalance?.totalZatoshi ?: 0) > 0 -> {
|
||||
(viewModel.latestBalance?.transparentBalance?.total?.value ?: 0) > 0 -> {
|
||||
"Please wait for more confirmations"
|
||||
}
|
||||
viewModel.latestBalance?.hasData() == true -> {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package cash.z.ecc.android.ui.home
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import cash.z.ecc.android.ext.pending
|
||||
import cash.z.ecc.android.lockbox.LockBox
|
||||
import cash.z.ecc.android.sdk.Synchronizer
|
||||
import cash.z.ecc.android.sdk.block.CompactBlockProcessor
|
||||
|
@ -10,10 +9,10 @@ import cash.z.ecc.android.sdk.db.entity.isMined
|
|||
import cash.z.ecc.android.sdk.db.entity.isSubmitSuccess
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||
import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.sdk.type.WalletBalance
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combineTransform
|
||||
import kotlinx.coroutines.flow.map
|
||||
import javax.inject.Inject
|
||||
|
||||
class BalanceDetailViewModel @Inject constructor() : ViewModel() {
|
||||
|
@ -53,40 +52,40 @@ class BalanceDetailViewModel @Inject constructor() : ViewModel() {
|
|||
}
|
||||
|
||||
data class BalanceModel(
|
||||
val shieldedBalance: WalletBalance = WalletBalance(),
|
||||
val transparentBalance: WalletBalance = WalletBalance(),
|
||||
val shieldedBalance: WalletBalance?,
|
||||
val transparentBalance: WalletBalance?,
|
||||
var showAvailable: Boolean = false
|
||||
) {
|
||||
/** Whether to make calculations based on total or available zatoshi */
|
||||
|
||||
val canAutoShield: Boolean = transparentBalance.availableZatoshi > ZcashSdk.MINERS_FEE_ZATOSHI
|
||||
val canAutoShield: Boolean = (transparentBalance?.available?.value ?: 0L) > ZcashSdk.MINERS_FEE.value
|
||||
|
||||
val balanceShielded: String
|
||||
get() {
|
||||
return if (showAvailable) shieldedBalance.availableZatoshi.toDisplay()
|
||||
else shieldedBalance.totalZatoshi.toDisplay()
|
||||
return if (showAvailable) shieldedBalance?.available.toDisplay()
|
||||
else shieldedBalance?.total.toDisplay()
|
||||
}
|
||||
|
||||
val balanceTransparent: String
|
||||
get() {
|
||||
return if (showAvailable) transparentBalance.availableZatoshi.toDisplay()
|
||||
else transparentBalance.totalZatoshi.toDisplay()
|
||||
return if (showAvailable) transparentBalance?.available.toDisplay()
|
||||
else transparentBalance?.total.toDisplay()
|
||||
}
|
||||
|
||||
val balanceTotal: String
|
||||
get() {
|
||||
return if (showAvailable) (shieldedBalance.availableZatoshi + transparentBalance.availableZatoshi).toDisplay()
|
||||
else (shieldedBalance.totalZatoshi + transparentBalance.totalZatoshi).toDisplay()
|
||||
return if (showAvailable) ((shieldedBalance?.available ?: Zatoshi(0)) + (transparentBalance?.available ?: Zatoshi(0))).toDisplay()
|
||||
else ((shieldedBalance?.total ?: Zatoshi(0)) + (transparentBalance?.total ?: Zatoshi(0))).toDisplay()
|
||||
}
|
||||
|
||||
val paddedShielded get() = pad(balanceShielded)
|
||||
val paddedTransparent get() = pad(balanceTransparent)
|
||||
val paddedTotal get() = pad(balanceTotal)
|
||||
val maxLength get() = maxOf(balanceShielded.length, balanceTransparent.length, balanceTotal.length)
|
||||
val hasPending = shieldedBalance.availableZatoshi != shieldedBalance.totalZatoshi ||
|
||||
transparentBalance.availableZatoshi != transparentBalance.totalZatoshi
|
||||
private fun Long.toDisplay(): String {
|
||||
return convertZatoshiToZecString(8, 8)
|
||||
val hasPending = (null != shieldedBalance && shieldedBalance.available != shieldedBalance.total) ||
|
||||
(null != transparentBalance && transparentBalance.available != transparentBalance.total)
|
||||
private fun Zatoshi?.toDisplay(): String {
|
||||
return this?.convertZatoshiToZecString(8, 8) ?: "0"
|
||||
}
|
||||
|
||||
private fun pad(balance: String): String {
|
||||
|
@ -100,11 +99,7 @@ class BalanceDetailViewModel @Inject constructor() : ViewModel() {
|
|||
}
|
||||
|
||||
fun hasData(): Boolean {
|
||||
val default = WalletBalance()
|
||||
return shieldedBalance.availableZatoshi != default.availableZatoshi ||
|
||||
shieldedBalance.totalZatoshi != default.totalZatoshi ||
|
||||
shieldedBalance.availableZatoshi != default.availableZatoshi ||
|
||||
shieldedBalance.totalZatoshi != default.totalZatoshi
|
||||
return shieldedBalance != null || transparentBalance != null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,12 +110,12 @@ class BalanceDetailViewModel @Inject constructor() : ViewModel() {
|
|||
) {
|
||||
val pendingUnconfirmed = pending.filter { it.isSubmitSuccess() && it.isMined() && !it.isConfirmed(info.lastScannedHeight) }
|
||||
val pendingUnmined = pending.filter { it.isSubmitSuccess() && !it.isMined() }
|
||||
val pendingShieldedBalance = balances.shieldedBalance.pending
|
||||
val pendingTransparentBalance = balances.transparentBalance.pending
|
||||
val pendingShieldedBalance = balances.shieldedBalance?.pending
|
||||
val pendingTransparentBalance = balances.transparentBalance?.pending
|
||||
val hasUnconfirmed = pendingUnconfirmed.isNotEmpty()
|
||||
val hasUnmined = pendingUnmined.isNotEmpty()
|
||||
val hasPendingShieldedBalance = pendingShieldedBalance > 0L
|
||||
val hasPendingTransparentBalance = pendingTransparentBalance > 0L
|
||||
val hasPendingShieldedBalance = (pendingShieldedBalance?.value ?: 0L) > 0L
|
||||
val hasPendingTransparentBalance = (pendingTransparentBalance?.value ?: 0L) > 0L
|
||||
val missingBlocks = (info.networkBlockHeight - info.lastScannedHeight).coerceAtLeast(0)
|
||||
|
||||
private fun PendingTransaction.isConfirmed(networkBlockHeight: Int): Boolean {
|
||||
|
|
|
@ -42,6 +42,7 @@ import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
|
|||
import cash.z.ecc.android.sdk.ext.convertZecToZatoshi
|
||||
import cash.z.ecc.android.sdk.ext.onFirstWith
|
||||
import cash.z.ecc.android.sdk.ext.safelyConvertToBigDecimal
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.ui.base.BaseFragment
|
||||
import cash.z.ecc.android.ui.home.HomeFragment.BannerAction.CANCEL
|
||||
import cash.z.ecc.android.ui.home.HomeFragment.BannerAction.CLEAR
|
||||
|
@ -154,7 +155,7 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
|||
if (::uiModel.isInitialized) {
|
||||
twig("uiModel exists! it has pendingSend=${uiModel.pendingSend} ZEC while the sendViewModel=${sendViewModel.zatoshiAmount} zats")
|
||||
// if the model already existed, cool but let the sendViewModel be the source of truth for the amount
|
||||
onModelUpdated(null, uiModel.copy(pendingSend = WalletZecFormmatter.toZecStringFull(sendViewModel.zatoshiAmount.coerceAtLeast(0))))
|
||||
onModelUpdated(null, uiModel.copy(pendingSend = WalletZecFormmatter.toZecStringFull(sendViewModel.zatoshiAmount ?: Zatoshi(0L))))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,8 +279,8 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
|||
binding.buttonSendAmount.disabledIf(amount == "0")
|
||||
}
|
||||
|
||||
fun setAvailable(availableBalance: Long = -1L, totalBalance: Long = -1L, availableTransparentBalance: Long = -1L, unminedCount: Int = 0) {
|
||||
val missingBalance = availableBalance < 0
|
||||
fun setAvailable(availableBalance: Zatoshi?, totalBalance: Zatoshi?, availableTransparentBalance: Zatoshi?, unminedCount: Int = 0) {
|
||||
val missingBalance = availableBalance == null
|
||||
val availableString = if (missingBalance) getString(R.string.home_button_send_updating) else WalletZecFormmatter.toZecStringFull(availableBalance)
|
||||
binding.textBalanceAvailable.text = availableString
|
||||
binding.textBalanceAvailable.transparentIf(missingBalance)
|
||||
|
@ -288,7 +289,7 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
|||
goneIf(missingBalance)
|
||||
text = when {
|
||||
unminedCount > 0 -> "(excludes $unminedCount unconfirmed ${if (unminedCount > 1) "transactions" else "transaction"})"
|
||||
availableBalance != -1L && (availableBalance < totalBalance) -> {
|
||||
availableBalance != null && totalBalance != null && (availableBalance.value < totalBalance.value) -> {
|
||||
val change = WalletZecFormmatter.toZecStringFull(totalBalance - availableBalance)
|
||||
val symbol = getString(R.string.symbol)
|
||||
"(${getString(R.string.home_banner_expecting)} +$change $symbol)".toColoredSpan(R.color.text_light, "+$change")
|
||||
|
@ -296,7 +297,7 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
|||
else -> getString(R.string.home_instruction_enter_amount)
|
||||
}
|
||||
}
|
||||
binding.imageTransparentAvailable.goneIf(availableTransparentBalance <= 0)
|
||||
binding.imageTransparentAvailable.goneIf(availableTransparentBalance == null)
|
||||
}
|
||||
|
||||
fun setBanner(message: String = "", action: BannerAction = CLEAR) {
|
||||
|
@ -348,8 +349,8 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
|||
if (old.processorInfo.lastScanRange != new.processorInfo.lastScanRange) append("${innerComma()}lastScanRange=${new.processorInfo.lastScanRange}")
|
||||
append(")")
|
||||
}
|
||||
if (old.saplingBalance.availableZatoshi != new.saplingBalance.availableZatoshi) append("${maybeComma()}availableBalance=${new.saplingBalance.availableZatoshi}")
|
||||
if (old.saplingBalance.totalZatoshi != new.saplingBalance.totalZatoshi) append("${maybeComma()}totalBalance=${new.saplingBalance.totalZatoshi}")
|
||||
if (old.saplingBalance?.available != new.saplingBalance?.available) append("${maybeComma()}availableBalance=${new.saplingBalance?.available}")
|
||||
if (old.saplingBalance?.total != new.saplingBalance?.total) append("${maybeComma()}totalBalance=${new.saplingBalance?.total}")
|
||||
if (old.pendingSend != new.pendingSend) append("${maybeComma()}pendingSend=${new.pendingSend}")
|
||||
append(")")
|
||||
}
|
||||
|
@ -359,7 +360,7 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
|||
}
|
||||
|
||||
private fun onSyncing(uiModel: HomeViewModel.UiModel) {
|
||||
setAvailable()
|
||||
setAvailable(null, null, null)
|
||||
}
|
||||
|
||||
private fun onSynced(uiModel: HomeViewModel.UiModel) {
|
||||
|
@ -368,7 +369,7 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
|||
onNoFunds()
|
||||
} else {
|
||||
setBanner("")
|
||||
setAvailable(uiModel.saplingBalance.availableZatoshi, uiModel.saplingBalance.totalZatoshi, uiModel.transparentBalance.availableZatoshi, uiModel.unminedCount)
|
||||
setAvailable(uiModel.saplingBalance?.available, uiModel.saplingBalance?.total, uiModel.transparentBalance?.available, uiModel.unminedCount)
|
||||
}
|
||||
autoShield(uiModel)
|
||||
}
|
||||
|
@ -392,9 +393,9 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
|||
}
|
||||
|
||||
// troubleshooting logs
|
||||
if (uiModel.transparentBalance.availableZatoshi > 0) {
|
||||
twig("Transparent funds are available but not enough to autoshield. Available: ${uiModel.transparentBalance.availableZatoshi.convertZatoshiToZecString(10)} Required: ${ZcashWalletApp.instance.autoshieldThreshold.convertZatoshiToZecString(8)}")
|
||||
} else if (uiModel.transparentBalance.totalZatoshi > 0) {
|
||||
if ((uiModel.transparentBalance?.available?.value ?: 0) > 0) {
|
||||
twig("Transparent funds are available but not enough to autoshield. Available: ${uiModel.transparentBalance?.available.convertZatoshiToZecString(10)} Required: ${Zatoshi(ZcashWalletApp.instance.autoshieldThreshold).convertZatoshiToZecString(8)}")
|
||||
} else if ((uiModel.transparentBalance?.total?.value ?: 0) > 0) {
|
||||
twig("Transparent funds have been received but they require 10 confirmations for autoshielding.")
|
||||
} else if (!canAutoshield) {
|
||||
twig("Could not autoshield probably because the last one occurred too recently")
|
||||
|
@ -437,6 +438,8 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
|||
// TODO: trigger banner / balance update
|
||||
onNoFunds()
|
||||
}
|
||||
BannerAction.NONE -> TODO()
|
||||
CLEAR -> TODO()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,9 +448,9 @@ class HomeFragment : BaseFragment<FragmentHomeBinding>() {
|
|||
}
|
||||
|
||||
private fun monitorUiModelChanges() {
|
||||
val existingAmount = sendViewModel.zatoshiAmount.coerceAtLeast(0)
|
||||
val existingAmount = sendViewModel.zatoshiAmount ?: Zatoshi(0)
|
||||
viewModel.initializeMaybe(WalletZecFormmatter.toZecStringFull(existingAmount))
|
||||
if (existingAmount == 0L) onClearAmount()
|
||||
if (existingAmount.value == 0L) onClearAmount()
|
||||
viewModel.uiModels.runningReduce { old, new ->
|
||||
onModelUpdated(old, new)
|
||||
new
|
||||
|
|
|
@ -14,8 +14,8 @@ import cash.z.ecc.android.sdk.block.CompactBlockProcessor
|
|||
import cash.z.ecc.android.sdk.db.entity.PendingTransaction
|
||||
import cash.z.ecc.android.sdk.db.entity.isMined
|
||||
import cash.z.ecc.android.sdk.db.entity.isSubmitSuccess
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk.MINERS_FEE_ZATOSHI
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk.ZATOSHI_PER_ZEC
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk.MINERS_FEE
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.sdk.type.WalletBalance
|
||||
import cash.z.ecc.android.util.twig
|
||||
import kotlinx.coroutines.channels.ConflatedBroadcastChannel
|
||||
|
@ -97,13 +97,13 @@ class HomeViewModel @Inject constructor() : ViewModel() {
|
|||
UiModel(
|
||||
status = flows[0] as Synchronizer.Status,
|
||||
processorInfo = flows[1] as CompactBlockProcessor.ProcessorInfo,
|
||||
orchardBalance = flows[2] as WalletBalance,
|
||||
saplingBalance = flows[3] as WalletBalance,
|
||||
transparentBalance = flows[4] as WalletBalance,
|
||||
orchardBalance = flows[2] as WalletBalance?,
|
||||
saplingBalance = flows[3] as WalletBalance?,
|
||||
transparentBalance = flows[4] as WalletBalance?,
|
||||
pendingSend = flows[5] as String,
|
||||
unminedCount = unminedCount
|
||||
)
|
||||
}.onStart { emit(UiModel()) }
|
||||
}.onStart { emit(UiModel(orchardBalance = null, saplingBalance = null, transparentBalance = null)) }
|
||||
}.conflate()
|
||||
}
|
||||
|
||||
|
@ -119,16 +119,16 @@ class HomeViewModel @Inject constructor() : ViewModel() {
|
|||
data class UiModel(
|
||||
val status: Synchronizer.Status = DISCONNECTED,
|
||||
val processorInfo: CompactBlockProcessor.ProcessorInfo = CompactBlockProcessor.ProcessorInfo(),
|
||||
val orchardBalance: WalletBalance = WalletBalance(),
|
||||
val saplingBalance: WalletBalance = WalletBalance(),
|
||||
val transparentBalance: WalletBalance = WalletBalance(),
|
||||
val orchardBalance: WalletBalance?,
|
||||
val saplingBalance: WalletBalance?,
|
||||
val transparentBalance: WalletBalance?,
|
||||
val pendingSend: String = "0",
|
||||
val unminedCount: Int = 0
|
||||
) {
|
||||
// Note: the wallet is effectively empty if it cannot cover the miner's fee
|
||||
val hasFunds: Boolean get() = saplingBalance.availableZatoshi > (MINERS_FEE_ZATOSHI.toDouble() / ZATOSHI_PER_ZEC) // 0.00001
|
||||
val hasSaplingBalance: Boolean get() = saplingBalance.totalZatoshi > 0
|
||||
val hasAutoshieldFunds: Boolean get() = transparentBalance.availableZatoshi >= ZcashWalletApp.instance.autoshieldThreshold
|
||||
val hasFunds: Boolean get() = (saplingBalance?.available?.value ?: 0) > (MINERS_FEE.value.toDouble() / Zatoshi.ZATOSHI_PER_ZEC) // 0.00001
|
||||
val hasSaplingBalance: Boolean get() = (saplingBalance?.total?.value ?: 0) > 0L
|
||||
val hasAutoshieldFunds: Boolean get() = (transparentBalance?.available?.value ?: 0) >= ZcashWalletApp.instance.autoshieldThreshold
|
||||
val isSynced: Boolean get() = status == SYNCED
|
||||
val isSendEnabled: Boolean get() = isSynced && hasFunds
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import cash.z.ecc.android.sdk.db.entity.isFailedEncoding
|
|||
import cash.z.ecc.android.sdk.db.entity.isFailure
|
||||
import cash.z.ecc.android.sdk.db.entity.isSubmitSuccess
|
||||
import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.sdk.type.WalletBalance
|
||||
import cash.z.ecc.android.ui.base.BaseFragment
|
||||
import cash.z.ecc.android.ui.util.AddressPartNumberSpan
|
||||
|
@ -219,15 +220,15 @@ class AwesomeFragment : BaseFragment<FragmentAwesomeBinding>() {
|
|||
}
|
||||
|
||||
private fun onBalanceUpdated(
|
||||
balance: WalletBalance = WalletBalance(0, 0),
|
||||
balance: WalletBalance = WalletBalance(Zatoshi(0), Zatoshi(0)),
|
||||
utxoCount: Int = 0
|
||||
) {
|
||||
lastBalance = balance
|
||||
twig("TRANSPARENT BALANCE: ${balance.availableZatoshi} / ${balance.totalZatoshi}")
|
||||
binding.textStatus.text = if (balance.availableZatoshi > 0L) {
|
||||
twig("TRANSPARENT BALANCE: ${balance.available} / ${balance.total}")
|
||||
binding.textStatus.text = if (balance.available.value > 0L) {
|
||||
binding.buttonAction.isActivated = true
|
||||
binding.buttonAction.isEnabled = true
|
||||
"Balance: ᙇ${balance.availableZatoshi.convertZatoshiToZecString(8)}"
|
||||
"Balance: ᙇ${balance.available.convertZatoshiToZecString(8)}"
|
||||
} else {
|
||||
binding.buttonAction.isActivated = false
|
||||
binding.buttonAction.isEnabled = true
|
||||
|
@ -239,7 +240,7 @@ class AwesomeFragment : BaseFragment<FragmentAwesomeBinding>() {
|
|||
appendStatus(if (utxoCount == 1) "transaction!" else "transactions!")
|
||||
}
|
||||
|
||||
balance.pending.takeIf { it > 0 }?.let {
|
||||
balance.pending.takeIf { it.value > 0 }?.let {
|
||||
appendStatus("\n\n(ᙇ${it.convertZatoshiToZecString()} pending confirmation)")
|
||||
}
|
||||
}
|
||||
|
@ -267,7 +268,7 @@ class AwesomeFragment : BaseFragment<FragmentAwesomeBinding>() {
|
|||
model.primaryAction = { onShieldFundsAction() }
|
||||
}
|
||||
else -> {
|
||||
model.status = "Shielding ᙇ${lastBalance?.availableZatoshi.convertZatoshiToZecString()}\n\nPlease do not exit this screen!"
|
||||
model.status = "Shielding ᙇ${lastBalance?.available.convertZatoshiToZecString()}\n\nPlease do not exit this screen!"
|
||||
model.showProgress = true
|
||||
if (isCreating()) {
|
||||
model.canCancel = true
|
||||
|
|
|
@ -11,6 +11,7 @@ import cash.z.ecc.android.sdk.db.entity.isMined
|
|||
import cash.z.ecc.android.sdk.db.entity.isSubmitSuccess
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||
import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||
import cash.z.ecc.android.sdk.type.WalletBalance
|
||||
import cash.z.ecc.android.util.twig
|
||||
|
@ -45,7 +46,7 @@ class AutoShieldViewModel @Inject constructor() : ViewModel() {
|
|||
val statuses get() = combineTransform(synchronizer.saplingBalances, synchronizer.pendingTransactions, synchronizer.processorInfo) { balance, pending, info ->
|
||||
val unconfirmed = pending.filter { !it.isConfirmed(info.networkBlockHeight) }
|
||||
val unmined = pending.filter { it.isSubmitSuccess() && !it.isMined() }
|
||||
val pending = balance.pending
|
||||
val pending = balance?.pending?.value ?: 0
|
||||
emit(StatusModel(unmined, unconfirmed, pending, info.networkBlockHeight))
|
||||
}
|
||||
|
||||
|
@ -96,21 +97,21 @@ class AutoShieldViewModel @Inject constructor() : ViewModel() {
|
|||
}
|
||||
|
||||
data class BalanceModel(
|
||||
val orchardBalance: WalletBalance = WalletBalance(),
|
||||
val saplingBalance: WalletBalance = WalletBalance(),
|
||||
val transparentBalance: WalletBalance = WalletBalance(),
|
||||
val orchardBalance: WalletBalance?,
|
||||
val saplingBalance: WalletBalance?,
|
||||
val transparentBalance: WalletBalance?,
|
||||
) {
|
||||
val balanceShielded: String = saplingBalance.availableZatoshi.toDisplay()
|
||||
val balanceTransparent: String = transparentBalance.availableZatoshi.toDisplay()
|
||||
val balanceTotal: String = (saplingBalance.availableZatoshi + transparentBalance.availableZatoshi).toDisplay()
|
||||
val canAutoShield: Boolean = transparentBalance.availableZatoshi > 0L
|
||||
val balanceShielded: String = saplingBalance?.available.toDisplay()
|
||||
val balanceTransparent: String = transparentBalance?.available.toDisplay()
|
||||
val balanceTotal: String = ((saplingBalance?.available ?: Zatoshi(0)) + (transparentBalance?.available ?: Zatoshi(0))).toDisplay()
|
||||
val canAutoShield: Boolean = (transparentBalance?.available?.value ?: 0) > 0L
|
||||
|
||||
val maxLength = maxOf(balanceShielded.length, balanceTransparent.length, balanceTotal.length)
|
||||
val paddedShielded = pad(balanceShielded)
|
||||
val paddedTransparent = pad(balanceTransparent)
|
||||
val paddedTotal = pad(balanceTotal)
|
||||
|
||||
private fun Long.toDisplay(): String {
|
||||
private fun Zatoshi?.toDisplay(): String {
|
||||
return convertZatoshiToZecString(8, 8)
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import cash.z.ecc.android.sdk.db.entity.isFailedEncoding
|
|||
import cash.z.ecc.android.sdk.db.entity.isFailure
|
||||
import cash.z.ecc.android.sdk.db.entity.isSubmitSuccess
|
||||
import cash.z.ecc.android.sdk.ext.toAbbreviatedAddress
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.ui.base.BaseFragment
|
||||
import cash.z.ecc.android.util.twig
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
|
@ -144,7 +145,8 @@ class SendFinalFragment : BaseFragment<FragmentSendFinalBinding>() {
|
|||
model.showSecondaryButton = true
|
||||
}
|
||||
else -> {
|
||||
model.title = "${getString(R.string.send_final_sending)} ${WalletZecFormmatter.toZecStringFull(value)} ${getString(R.string.symbol)} ${getString(R.string.send_final_to)}\n${toAddress.toAbbreviatedAddress()}"
|
||||
model.title = "${getString(R.string.send_final_sending)} ${WalletZecFormmatter.toZecStringFull(
|
||||
Zatoshi(value))} ${getString(R.string.symbol)} ${getString(R.string.send_final_to)}\n${toAddress.toAbbreviatedAddress()}"
|
||||
model.showProgress = true
|
||||
if (isCreating()) {
|
||||
model.showCloseIcon = false
|
||||
|
|
|
@ -41,6 +41,7 @@ import cash.z.ecc.android.sdk.type.AddressType
|
|||
import cash.z.ecc.android.sdk.type.WalletBalance
|
||||
import cash.z.ecc.android.ui.base.BaseFragment
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
@ -121,7 +122,7 @@ class SendFragment :
|
|||
private fun applyViewModel(model: SendViewModel) {
|
||||
// apply amount
|
||||
val roundedAmount =
|
||||
WalletZecFormmatter.toZecStringFull(model.zatoshiAmount.coerceAtLeast(0L))
|
||||
WalletZecFormmatter.toZecStringFull(model.zatoshiAmount)
|
||||
binding.textSendAmount.text = "\$$roundedAmount"
|
||||
// apply address
|
||||
binding.inputZcashAddress.setText(model.toAddress)
|
||||
|
@ -243,7 +244,7 @@ class SendFragment :
|
|||
override fun onResume() {
|
||||
super.onResume()
|
||||
onPrimaryClipChanged()
|
||||
sendViewModel.synchronizer.saplingBalances.collectWith(resumedScope) {
|
||||
sendViewModel.synchronizer.saplingBalances.filterNotNull().collectWith(resumedScope) {
|
||||
onBalanceUpdated(it)
|
||||
}
|
||||
binding.inputZcashAddress.text.toString().let {
|
||||
|
@ -254,8 +255,8 @@ class SendFragment :
|
|||
private fun onBalanceUpdated(balance: WalletBalance) {
|
||||
// binding.textLayoutAmount.helperText =
|
||||
// "You have ${WalletZecFormmatter.toZecStringFull(balance.availableZatoshi.coerceAtLeast(0L))} available"
|
||||
maxZatoshi = (balance.availableZatoshi - ZcashSdk.MINERS_FEE_ZATOSHI).coerceAtLeast(0L)
|
||||
availableZatoshi = balance.availableZatoshi
|
||||
maxZatoshi = (balance.available - ZcashSdk.MINERS_FEE).value
|
||||
availableZatoshi = balance.available.value
|
||||
}
|
||||
|
||||
override fun onPrimaryClipChanged() {
|
||||
|
|
|
@ -31,6 +31,7 @@ import cash.z.ecc.android.sdk.db.entity.isFailedSubmit
|
|||
import cash.z.ecc.android.sdk.db.entity.isMined
|
||||
import cash.z.ecc.android.sdk.db.entity.isSubmitSuccess
|
||||
import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||
import cash.z.ecc.android.sdk.type.AddressType
|
||||
import cash.z.ecc.android.ui.util.INCLUDE_MEMO_PREFIX_STANDARD
|
||||
|
@ -62,7 +63,7 @@ class SendViewModel @Inject constructor() : ViewModel() {
|
|||
var fromAddress: String = ""
|
||||
var toAddress: String = ""
|
||||
var memo: String = ""
|
||||
var zatoshiAmount: Long = -1L
|
||||
var zatoshiAmount: Zatoshi? = null
|
||||
var includeFromAddress: Boolean = false
|
||||
set(value) {
|
||||
require(!value || (value && !fromAddress.isNullOrEmpty())) {
|
||||
|
@ -86,7 +87,7 @@ class SendViewModel @Inject constructor() : ViewModel() {
|
|||
reportUserInputIssues(memoToSend)
|
||||
return synchronizer.sendToAddress(
|
||||
keys[0],
|
||||
zatoshiAmount,
|
||||
zatoshiAmount!!,
|
||||
toAddress,
|
||||
memoToSend.chunked(ZcashSdk.MAX_MEMO_SIZE).firstOrNull() ?: ""
|
||||
).onEach {
|
||||
|
@ -118,7 +119,7 @@ class SendViewModel @Inject constructor() : ViewModel() {
|
|||
synchronizer.validateAddress(toAddress).isNotValid -> {
|
||||
emit(context.getString(R.string.send_validation_error_address_invalid))
|
||||
}
|
||||
zatoshiAmount < 1 -> {
|
||||
zatoshiAmount?.let { it.value < 1L } ?: false -> {
|
||||
emit(context.getString(R.string.send_validation_error_amount_minimum))
|
||||
}
|
||||
availableZatoshi == null -> {
|
||||
|
@ -127,11 +128,12 @@ class SendViewModel @Inject constructor() : ViewModel() {
|
|||
availableZatoshi == 0L -> {
|
||||
emit(context.getString(R.string.send_validation_error_no_available_funds))
|
||||
}
|
||||
availableZatoshi > 0 && availableZatoshi < ZcashSdk.MINERS_FEE_ZATOSHI -> {
|
||||
availableZatoshi > 0 && availableZatoshi.let { it < ZcashSdk.MINERS_FEE.value } ?: false -> {
|
||||
emit(context.getString(R.string.send_validation_error_dust))
|
||||
}
|
||||
maxZatoshi != null && zatoshiAmount > maxZatoshi -> {
|
||||
emit(context.getString(R.string.send_validation_error_too_much, WalletZecFormmatter.toZecStringFull(maxZatoshi), ZcashWalletApp.instance.getString(R.string.symbol)))
|
||||
maxZatoshi != null && zatoshiAmount?.let { it.value > maxZatoshi } ?: false -> {
|
||||
emit(context.getString(R.string.send_validation_error_too_much,
|
||||
WalletZecFormmatter.toZecStringFull(Zatoshi((maxZatoshi))), ZcashWalletApp.instance.getString(R.string.symbol)))
|
||||
}
|
||||
createMemoToSend().length > ZcashSdk.MAX_MEMO_SIZE -> {
|
||||
emit(context.getString(R.string.send_validation_error_memo_length, ZcashSdk.MAX_MEMO_SIZE))
|
||||
|
@ -151,7 +153,7 @@ class SendViewModel @Inject constructor() : ViewModel() {
|
|||
fromAddress = ""
|
||||
toAddress = ""
|
||||
memo = ""
|
||||
zatoshiAmount = -1L
|
||||
zatoshiAmount = null
|
||||
includeFromAddress = false
|
||||
}
|
||||
|
||||
|
@ -183,9 +185,9 @@ class SendViewModel @Inject constructor() : ViewModel() {
|
|||
private fun reportUserInputIssues(memoToSend: String) {
|
||||
if (toAddress == fromAddress) feedback.report(Issue.SelfSend)
|
||||
when {
|
||||
zatoshiAmount < ZcashSdk.MINERS_FEE_ZATOSHI -> feedback.report(Issue.TinyAmount)
|
||||
zatoshiAmount < 100 -> feedback.report(Issue.MicroAmount)
|
||||
zatoshiAmount == 1L -> feedback.report(Issue.MinimumAmount)
|
||||
(zatoshiAmount?.value ?: 0L) < ZcashSdk.MINERS_FEE.value -> feedback.report(Issue.TinyAmount)
|
||||
(zatoshiAmount?.value ?: 0L) < 100L -> feedback.report(Issue.MicroAmount)
|
||||
(zatoshiAmount ?: 0L) == 1L -> feedback.report(Issue.MinimumAmount)
|
||||
}
|
||||
memoToSend.length.also {
|
||||
when {
|
||||
|
|
|
@ -83,7 +83,7 @@ object Deps {
|
|||
object Zcash {
|
||||
const val ANDROID_WALLET_PLUGINS = "cash.z.ecc.android:zcash-android-wallet-plugins:1.0.0"
|
||||
const val KOTLIN_BIP39 = "cash.z.ecc.android:kotlin-bip39:1.0.1"
|
||||
const val SDK = "cash.z.ecc.android:zcash-android-sdk:1.5.0-beta01"
|
||||
const val SDK = "cash.z.ecc.android:zcash-android-sdk:1.7.0-beta01"
|
||||
}
|
||||
object Misc {
|
||||
const val LOTTIE = "com.airbnb.android:lottie:3.7.0"
|
||||
|
|
|
@ -4,7 +4,7 @@ pluginManagement {
|
|||
}
|
||||
|
||||
plugins {
|
||||
id("com.github.ben-manes.versions") version("0.39.0") apply(false)
|
||||
id("com.github.ben-manes.versions") version ("0.39.0") apply (false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ dependencyResolutionManagement {
|
|||
maven("https://jitpack.io")
|
||||
jcenter()
|
||||
// Uncomment to use a snapshot version of the SDK, e.g. when the SDK version ends in -SNAPSHOT
|
||||
// maven("https://oss.sonatype.org/content/repositories/snapshots") {
|
||||
//maven("https://oss.sonatype.org/content/repositories/snapshots") {
|
||||
// if (isRepoRestrictionEnabled) {
|
||||
// content {
|
||||
// includeGroup("cash.z.ecc.android")
|
||||
|
@ -28,7 +28,7 @@ dependencyResolutionManagement {
|
|||
}
|
||||
}
|
||||
|
||||
rootProject.name="ecc-wallet"
|
||||
rootProject.name = "ecc-wallet"
|
||||
|
||||
includeBuild("build-convention")
|
||||
|
||||
|
|
Loading…
Reference in New Issue