Flexa hotfixes for balance and transaction failure (#1662)
* Flexa hotfixes for balance and transaction failure * Flexa hotfixes for balance and transaction failure
This commit is contained in:
parent
e638499de8
commit
57cbd3f5f2
|
@ -49,6 +49,7 @@ private fun BalanceWidgetPreview() {
|
||||||
BalanceState.Available(
|
BalanceState.Available(
|
||||||
totalBalance = Zatoshi(1234567891234567L),
|
totalBalance = Zatoshi(1234567891234567L),
|
||||||
spendableBalance = Zatoshi(1234567891234567L),
|
spendableBalance = Zatoshi(1234567891234567L),
|
||||||
|
totalShieldedBalance = Zatoshi(0L),
|
||||||
exchangeRate = ObserveFiatCurrencyResultFixture.new()
|
exchangeRate = ObserveFiatCurrencyResultFixture.new()
|
||||||
),
|
),
|
||||||
isHideBalances = false,
|
isHideBalances = false,
|
||||||
|
@ -74,6 +75,7 @@ private fun BalanceWidgetNotAvailableYetPreview() {
|
||||||
BalanceState.Loading(
|
BalanceState.Loading(
|
||||||
totalBalance = Zatoshi(value = 0L),
|
totalBalance = Zatoshi(value = 0L),
|
||||||
spendableBalance = Zatoshi(value = 0L),
|
spendableBalance = Zatoshi(value = 0L),
|
||||||
|
totalShieldedBalance = Zatoshi(0L),
|
||||||
exchangeRate = ObserveFiatCurrencyResultFixture.new()
|
exchangeRate = ObserveFiatCurrencyResultFixture.new()
|
||||||
),
|
),
|
||||||
isHideBalances = false,
|
isHideBalances = false,
|
||||||
|
@ -98,6 +100,7 @@ private fun BalanceWidgetHiddenAmountPreview() {
|
||||||
BalanceState.Loading(
|
BalanceState.Loading(
|
||||||
totalBalance = Zatoshi(0L),
|
totalBalance = Zatoshi(0L),
|
||||||
spendableBalance = Zatoshi(0L),
|
spendableBalance = Zatoshi(0L),
|
||||||
|
totalShieldedBalance = Zatoshi(0L),
|
||||||
exchangeRate = ObserveFiatCurrencyResultFixture.new()
|
exchangeRate = ObserveFiatCurrencyResultFixture.new()
|
||||||
),
|
),
|
||||||
isHideBalances = true,
|
isHideBalances = true,
|
||||||
|
@ -111,6 +114,7 @@ private fun BalanceWidgetHiddenAmountPreview() {
|
||||||
|
|
||||||
sealed interface BalanceState {
|
sealed interface BalanceState {
|
||||||
val totalBalance: Zatoshi
|
val totalBalance: Zatoshi
|
||||||
|
val totalShieldedBalance: Zatoshi
|
||||||
val spendableBalance: Zatoshi
|
val spendableBalance: Zatoshi
|
||||||
val exchangeRate: ExchangeRateState
|
val exchangeRate: ExchangeRateState
|
||||||
|
|
||||||
|
@ -118,19 +122,22 @@ sealed interface BalanceState {
|
||||||
override val exchangeRate: ExchangeRateState
|
override val exchangeRate: ExchangeRateState
|
||||||
) : BalanceState {
|
) : BalanceState {
|
||||||
override val totalBalance: Zatoshi = Zatoshi(0L)
|
override val totalBalance: Zatoshi = Zatoshi(0L)
|
||||||
|
override val totalShieldedBalance: Zatoshi = Zatoshi(0L)
|
||||||
override val spendableBalance: Zatoshi = Zatoshi(0L)
|
override val spendableBalance: Zatoshi = Zatoshi(0L)
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Loading(
|
data class Loading(
|
||||||
override val totalBalance: Zatoshi,
|
override val totalBalance: Zatoshi,
|
||||||
override val spendableBalance: Zatoshi,
|
override val spendableBalance: Zatoshi,
|
||||||
override val exchangeRate: ExchangeRateState
|
override val exchangeRate: ExchangeRateState,
|
||||||
|
override val totalShieldedBalance: Zatoshi
|
||||||
) : BalanceState
|
) : BalanceState
|
||||||
|
|
||||||
data class Available(
|
data class Available(
|
||||||
override val totalBalance: Zatoshi,
|
override val totalBalance: Zatoshi,
|
||||||
override val spendableBalance: Zatoshi,
|
override val spendableBalance: Zatoshi,
|
||||||
override val exchangeRate: ExchangeRateState
|
override val exchangeRate: ExchangeRateState,
|
||||||
|
override val totalShieldedBalance: Zatoshi
|
||||||
) : BalanceState
|
) : BalanceState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,8 @@ fun WalletSnapshot.canSpend(amount: Zatoshi): Boolean = spendableBalance() >= am
|
||||||
|
|
||||||
fun WalletSnapshot.totalBalance() = orchardBalance.total + saplingBalance.total + transparentBalance
|
fun WalletSnapshot.totalBalance() = orchardBalance.total + saplingBalance.total + transparentBalance
|
||||||
|
|
||||||
|
fun WalletSnapshot.totalShieldedBalance() = orchardBalance.total + saplingBalance.total
|
||||||
|
|
||||||
// Note that considering both to be spendable is subject to change.
|
// Note that considering both to be spendable is subject to change.
|
||||||
// The user experience could be confusing, and in the future we might prefer to ask users
|
// The user experience could be confusing, and in the future we might prefer to ask users
|
||||||
// to transfer their balance to the latest balance type to make it spendable.
|
// to transfer their balance to the latest balance type to make it spendable.
|
||||||
|
|
|
@ -7,6 +7,7 @@ import co.electriccoin.zcash.ui.common.model.hasChangePending
|
||||||
import co.electriccoin.zcash.ui.common.model.hasValuePending
|
import co.electriccoin.zcash.ui.common.model.hasValuePending
|
||||||
import co.electriccoin.zcash.ui.common.model.spendableBalance
|
import co.electriccoin.zcash.ui.common.model.spendableBalance
|
||||||
import co.electriccoin.zcash.ui.common.model.totalBalance
|
import co.electriccoin.zcash.ui.common.model.totalBalance
|
||||||
|
import co.electriccoin.zcash.ui.common.model.totalShieldedBalance
|
||||||
import co.electriccoin.zcash.ui.common.wallet.ExchangeRateState
|
import co.electriccoin.zcash.ui.common.wallet.ExchangeRateState
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -49,7 +50,8 @@ class BalanceRepositoryImpl(
|
||||||
BalanceState.Loading(
|
BalanceState.Loading(
|
||||||
totalBalance = snapshot.totalBalance(),
|
totalBalance = snapshot.totalBalance(),
|
||||||
spendableBalance = snapshot.spendableBalance(),
|
spendableBalance = snapshot.spendableBalance(),
|
||||||
exchangeRate = exchangeRateUsd
|
exchangeRate = exchangeRateUsd,
|
||||||
|
totalShieldedBalance = snapshot.totalShieldedBalance()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +59,8 @@ class BalanceRepositoryImpl(
|
||||||
BalanceState.Available(
|
BalanceState.Available(
|
||||||
totalBalance = snapshot.totalBalance(),
|
totalBalance = snapshot.totalBalance(),
|
||||||
spendableBalance = snapshot.spendableBalance(),
|
spendableBalance = snapshot.spendableBalance(),
|
||||||
exchangeRate = exchangeRateUsd
|
exchangeRate = exchangeRateUsd,
|
||||||
|
totalShieldedBalance = snapshot.totalShieldedBalance()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,17 +41,19 @@ class FlexaRepositoryImpl(
|
||||||
Twig.info { "Flexa initialized" }
|
Twig.info { "Flexa initialized" }
|
||||||
|
|
||||||
balanceRepository.state
|
balanceRepository.state
|
||||||
.map { it.spendableBalance }
|
.map { it.totalShieldedBalance to it.spendableBalance }
|
||||||
.collect {
|
.collect { (total, available) ->
|
||||||
|
val totalZec = total.convertZatoshiToZec().toDouble()
|
||||||
|
val availableZec = available.convertZatoshiToZec().toDouble()
|
||||||
Flexa.updateAssetAccounts(
|
Flexa.updateAssetAccounts(
|
||||||
arrayListOf(
|
arrayListOf(
|
||||||
createFlexaAccount(
|
createFlexaAccount(
|
||||||
zecBalance = it.convertZatoshiToZec().toDouble()
|
total = totalZec,
|
||||||
|
available = availableZec
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
Twig.info { "Flexa updated by total:$totalZec available:$availableZec" }
|
||||||
Twig.info { "Flexa updated by ${it.convertZatoshiToZec().toDouble()}" }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +71,7 @@ class FlexaRepositoryImpl(
|
||||||
FlexaTheme(
|
FlexaTheme(
|
||||||
useDynamicColorScheme = true,
|
useDynamicColorScheme = true,
|
||||||
),
|
),
|
||||||
assetAccounts = arrayListOf(createFlexaAccount(DEFAULT_ZEC_BALANCE)),
|
assetAccounts = arrayListOf(createFlexaAccount(DEFAULT_BALANCE, DEFAULT_BALANCE)),
|
||||||
webViewThemeConfig =
|
webViewThemeConfig =
|
||||||
"{\n" +
|
"{\n" +
|
||||||
" \"android\": {\n" +
|
" \"android\": {\n" +
|
||||||
|
@ -94,22 +96,25 @@ class FlexaRepositoryImpl(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createFlexaAccount(zecBalance: Double) =
|
private fun createFlexaAccount(
|
||||||
AssetAccount(
|
total: Double,
|
||||||
displayName = "",
|
available: Double
|
||||||
icon = "https://flexa.network/static/4bbb1733b3ef41240ca0f0675502c4f7/d8419/flexa-logo%403x.png",
|
) = AssetAccount(
|
||||||
availableAssets =
|
displayName = "",
|
||||||
listOf(
|
icon = "https://flexa.network/static/4bbb1733b3ef41240ca0f0675502c4f7/d8419/flexa-logo%403x.png",
|
||||||
AvailableAsset(
|
availableAssets =
|
||||||
assetId = "bip122:00040fe8ec8471911baa1db1266ea15d/slip44:133",
|
listOf(
|
||||||
balance = zecBalance,
|
AvailableAsset(
|
||||||
symbol = "ZEC",
|
assetId = "bip122:00040fe8ec8471911baa1db1266ea15d/slip44:133",
|
||||||
icon = "https://cryptologos.cc/logos/zcash-zec-logo.png"
|
balance = total,
|
||||||
)
|
balanceAvailable = available,
|
||||||
),
|
symbol = "ZEC",
|
||||||
custodyModel = CustodyModel.LOCAL,
|
icon = "https://z.cash/wp-content/uploads/2023/11/Brandmark-Yellow.png",
|
||||||
assetAccountHash = UUID.randomUUID().toString().toSha256()
|
)
|
||||||
)
|
),
|
||||||
|
custodyModel = CustodyModel.LOCAL,
|
||||||
|
assetAccountHash = UUID.randomUUID().toString().toSha256()
|
||||||
|
)
|
||||||
|
|
||||||
private fun String.toSha256() =
|
private fun String.toSha256() =
|
||||||
MessageDigest.getInstance("SHA-256")
|
MessageDigest.getInstance("SHA-256")
|
||||||
|
@ -117,4 +122,4 @@ class FlexaRepositoryImpl(
|
||||||
.fold("") { str, value -> str + "%02x".format(value) }
|
.fold("") { str, value -> str + "%02x".format(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val DEFAULT_ZEC_BALANCE = .0
|
private const val DEFAULT_BALANCE = .0
|
||||||
|
|
|
@ -8,15 +8,18 @@ object BalanceStateFixture {
|
||||||
private const val BALANCE_VALUE = 0L
|
private const val BALANCE_VALUE = 0L
|
||||||
|
|
||||||
val TOTAL_BALANCE = Zatoshi(BALANCE_VALUE)
|
val TOTAL_BALANCE = Zatoshi(BALANCE_VALUE)
|
||||||
|
val TOTAL_SHIELDED_BALANCE = Zatoshi(BALANCE_VALUE)
|
||||||
val SPENDABLE_BALANCE = Zatoshi(BALANCE_VALUE)
|
val SPENDABLE_BALANCE = Zatoshi(BALANCE_VALUE)
|
||||||
|
|
||||||
fun new(
|
fun new(
|
||||||
totalBalance: Zatoshi = TOTAL_BALANCE,
|
totalBalance: Zatoshi = TOTAL_BALANCE,
|
||||||
|
totalShieldedBalance: Zatoshi = TOTAL_SHIELDED_BALANCE,
|
||||||
spendableBalance: Zatoshi = SPENDABLE_BALANCE,
|
spendableBalance: Zatoshi = SPENDABLE_BALANCE,
|
||||||
exchangeRate: ExchangeRateState = ObserveFiatCurrencyResultFixture.new()
|
exchangeRate: ExchangeRateState = ObserveFiatCurrencyResultFixture.new()
|
||||||
) = BalanceState.Available(
|
) = BalanceState.Available(
|
||||||
totalBalance = totalBalance,
|
totalBalance = totalBalance,
|
||||||
spendableBalance = spendableBalance,
|
spendableBalance = spendableBalance,
|
||||||
exchangeRate = exchangeRate
|
exchangeRate = exchangeRate,
|
||||||
|
totalShieldedBalance = totalShieldedBalance
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,7 @@ private fun HistoryListComposablePreview() {
|
||||||
BalanceState.Available(
|
BalanceState.Available(
|
||||||
totalBalance = Zatoshi(value = 123_000_000L),
|
totalBalance = Zatoshi(value = 123_000_000L),
|
||||||
spendableBalance = Zatoshi(value = 123_000_000L),
|
spendableBalance = Zatoshi(value = 123_000_000L),
|
||||||
|
totalShieldedBalance = Zatoshi(value = 123_000_000L),
|
||||||
exchangeRate =
|
exchangeRate =
|
||||||
ExchangeRateState.Data(
|
ExchangeRateState.Data(
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
|
|
|
@ -166,7 +166,7 @@ class IntegrationsViewModel(
|
||||||
}.onSuccess { proposal ->
|
}.onSuccess { proposal ->
|
||||||
Twig.debug { "Transaction proposal successful: ${proposal.toPrettyString()}" }
|
Twig.debug { "Transaction proposal successful: ${proposal.toPrettyString()}" }
|
||||||
val result = submitTransactions(proposal = proposal, spendingKey = getSpendingKey())
|
val result = submitTransactions(proposal = proposal, spendingKey = getSpendingKey())
|
||||||
when (result.first) {
|
when (val output = result.first) {
|
||||||
SubmitResult.Success -> {
|
SubmitResult.Success -> {
|
||||||
Twig.debug { "Transaction successful $result" }
|
Twig.debug { "Transaction successful $result" }
|
||||||
Flexa.buildSpend()
|
Flexa.buildSpend()
|
||||||
|
@ -175,6 +175,14 @@ class IntegrationsViewModel(
|
||||||
txSignature = result.second.orEmpty()
|
txSignature = result.second.orEmpty()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
is SubmitResult.SimpleTrxFailure.SimpleTrxFailureGrpc -> {
|
||||||
|
Twig.warn { "Transaction grpc failure $result" }
|
||||||
|
Flexa.buildSpend()
|
||||||
|
.transactionSent(
|
||||||
|
commerceSessionId = transaction.getOrNull()?.commerceSessionId.orEmpty(),
|
||||||
|
txSignature = output.result.txIdString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
Twig.error { "Transaction submission failed" }
|
Twig.error { "Transaction submission failed" }
|
||||||
|
|
Loading…
Reference in New Issue