Skip to content

Commit

Permalink
Increment to version 4.0.30
Browse files Browse the repository at this point in the history
  • Loading branch information
angelix committed Jun 11, 2024
1 parent d5efa67 commit 423aa14
Show file tree
Hide file tree
Showing 21 changed files with 357 additions and 103 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [4.0.30] - 2024-06-10

### Added
- Re-enable expired 2FA UTXOs

### Changed
- Update to Kotlin 2.0.0
- Updated project dependencies
- Bump GDK to version 0.71.3
- Bump Breez to version 0.4.2-rc1
- Hide fee selection on Liquid if fee estimation is network default
- Refactor various UI elements

### Fixed
- Fix Authenticator app 2FA setup

## [4.0.29] - 2024-05-23

### Changed
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.blockstream.common.data

import cafe.adriel.voyager.core.lifecycle.JavaSerializable
import com.blockstream.common.Parcelable
import com.blockstream.common.Parcelize
import com.blockstream.common.BITS_UNIT
import com.blockstream.common.BTC_UNIT
import com.blockstream.common.MBTC_UNIT
import com.blockstream.common.Parcelable
import com.blockstream.common.Parcelize
import com.blockstream.common.SATOSHI_UNIT
import com.blockstream.common.UBTC_UNIT
import com.blockstream.common.extensions.assetTicker
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ fun ByteArray.reverseBytes(): ByteArray {
}

fun Transaction.getConfirmationsMax(session: GdkSession): Int {
if(isLoadingTransaction) return 0
return getConfirmations(session.block(network).value.height).coerceAtMost((if (network.isLiquid) 3 else 7)).toInt()
}

Expand Down Expand Up @@ -92,7 +91,7 @@ fun Network.needs2faActivation(session: GdkSession): Boolean {
}

fun Account.hasExpiredUtxos(session: GdkSession): Boolean {
return isMultisig && session.expired2FA.value.contains(this)
return !session.isWatchOnly && isMultisig && session.expired2FA.value.contains(this)
}

fun String?.isPolicyAsset(network: Network?): Boolean = (this == null || this == network?.policyAsset)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -527,10 +527,15 @@ class GdkSession constructor(
var config = if(useCache) twoFactorConfigStateFlow(network).value else null

if(config == null){
gdk.getTwoFactorConfig(gdkSession(network)).also {
twoFactorConfigStateFlow(network).value = it
twoFactorResetStateFlow(network).value = it.twoFactorReset
config = it
try {
gdk.getTwoFactorConfig(gdkSession(network)).also {
twoFactorConfigStateFlow(network).value = it
twoFactorResetStateFlow(network).value = it.twoFactorReset
config = it
}
} catch (e: Exception) {
e.printStackTrace()
countly.recordException(e)
}
}

Expand Down Expand Up @@ -1242,7 +1247,7 @@ class GdkSession constructor(
}

return loginWithLoginCredentials(
prominentNetwork = supportedNetworks.first(),
prominentNetwork = initNetworks.first(),
initNetworks = initNetworks,
wallet = wallet,
loginCredentialsParams = LoginCredentialsParams.empty,
Expand Down Expand Up @@ -1275,11 +1280,15 @@ class GdkSession constructor(
_disableNotificationHandling = true
_walletActiveEventInvalidated = true

logger.d { "loginWithLoginCredentials prominentNetwork: ${prominentNetwork.id} initNetworks: ${initNetworks?.joinToString(",") { it.id }} " }

val connectedNetworks = connect(
network = prominentNetwork,
initNetworks = initNetworks,
)

logger.d { "loginWithLoginCredentials connected: ${gdkSessions.keys.joinToString(",") { it.id }} " }

device?.deviceState?.onEach {
// Device went offline
if(it == DeviceState.DISCONNECTED){
Expand Down Expand Up @@ -1951,7 +1960,7 @@ class GdkSession constructor(
private fun getLightningTransactions() = lightningSdkOrNull?.getTransactions()?.map {
Transaction.fromPayment(it)
}.let {
Transactions(transactions = it ?: listOf(Transaction.LoadingTransaction))
Transactions(transactions = it ?: listOf())
}

private val accountsAndBalancesMutex = Mutex()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package com.blockstream.common.gdk.data


import com.arkivanov.essenty.parcelable.IgnoredOnParcel
import com.blockstream.common.BTC_POLICY_ASSET
import com.blockstream.common.Parcelable
import com.blockstream.common.Parcelize
import com.blockstream.common.BTC_POLICY_ASSET
import com.blockstream.common.gdk.GdkSession
import com.blockstream.common.gdk.GreenJson
import com.blockstream.common.utils.toAmountLookOrNa
Expand Down Expand Up @@ -230,13 +230,9 @@ data class Transaction constructor(
}

fun getConfirmations(session: GdkSession): Long {
if (isLoadingTransaction) return -1
return getConfirmations(session.block(network).value.height)
}

val isLoadingTransaction
get() = blockHeight == -1L

fun getUnblindedString() = (inputs.mapNotNull { it.getUnblindedString() } + outputs.mapNotNull { it.getUnblindedString() }).joinToString(",")

fun getUnblindedData(): TransactionUnblindedData {
Expand Down Expand Up @@ -289,22 +285,4 @@ data class Transaction constructor(
}
}
}

companion object {
// Create a dummy transaction to describe the loading state (blockHeight == -1)
val LoadingTransaction = Transaction(
blockHeight = -1,
canRBF = false,
createdAtTs = 0,
inputs = listOf(),
outputs = listOf(),
fee = 0,
feeRate = 0,
memo = "",
spvVerified = "",
txHash = "",
type = "",
satoshi = mapOf()
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ data class TransactionConfirmLook(
session = session,
denomination = denomination,
isAddressVerificationOnDevice = isAddressVerificationOnDevice,
showChangeOutputs = session.device?.isLedger == true
showChangeOutputs = isAddressVerificationOnDevice && session.device?.isLedger == true
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import com.blockstream.common.sideeffects.SideEffects
import com.blockstream.common.utils.Loggable
import com.blockstream.common.utils.ifNotNull
import com.blockstream.common.utils.toAmountLook
import com.rickclephas.kmp.observableviewmodel.stateIn
import com.rickclephas.kmp.nativecoroutines.NativeCoroutinesState
import com.rickclephas.kmp.observableviewmodel.stateIn
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
Expand All @@ -39,6 +39,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.sync.Mutex

Expand Down Expand Up @@ -141,7 +142,11 @@ abstract class CreateTransactionViewModelAbstract(
}
}.launchIn(this)

combine(createTransactionParams, denomination) { createTransactionParams, _ ->
combine(
createTransactionParams,
denomination,
merge(flowOf(Unit), session.accountsAndBalanceUpdated), // there is a case where params are equal (lightning), so we need to re-create the transaction
) { createTransactionParams, _, _ ->
createTransaction(params = createTransactionParams, finalCheckBeforeContinue = false)
}.launchIn(this)
}
Expand Down Expand Up @@ -336,17 +341,16 @@ abstract class CreateTransactionViewModelAbstract(
originalParams.copy(memo = it)
} ?: originalParams

var transaction = originalTransaction
val isSwap = transaction.isSwap()
val isSwap = originalTransaction.isSwap()

if (!isSwap) {
var transaction = if (!isSwap) {
// Re-create transaction if not swap
transaction = session.createTransaction(network, params).also { tx ->
session.createTransaction(network, params).also { tx ->
tx.error.takeIf { it.isNotBlank() }?.also {
throw Exception(it)
}
}
}
} else originalTransaction

// If liquid, blind the transaction before signing
if(!transaction.isBump() && !transaction.isSweep() && network.isLiquid){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ import com.blockstream.common.utils.UserInput
import com.blockstream.common.utils.feeRateWithUnit
import com.blockstream.common.utils.ifNotNull
import com.blockstream.common.utils.toAmountLook
import com.rickclephas.kmp.observableviewmodel.stateIn
import com.rickclephas.kmp.nativecoroutines.NativeCoroutinesState
import com.rickclephas.kmp.observableviewmodel.stateIn
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
Expand All @@ -45,7 +45,9 @@ import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import kotlinx.serialization.json.buildJsonObject
import saschpe.kase64.base64DecodedBytes
import kotlin.math.absoluteValue

Expand Down Expand Up @@ -227,8 +229,8 @@ class SendViewModel(
accountAsset,
amount,
isSendAll,

_feePriorityPrimitive,
merge(flowOf(Unit), session.accountsAndBalanceUpdated), // set initial value, watch for wallet balance updates, especially on wallet startup like bip39 uris
) { arr ->
val address = arr[0] as String

Expand Down Expand Up @@ -329,11 +331,15 @@ class SendViewModel(
).let { params ->
CreateTransactionParams(
addressees = listOf(params.toJsonElement()),
addresseesAsParams = listOf(params)
addresseesAsParams = listOf(params),
utxos = buildJsonObject {
// a hack to re-create params when balance changes
session.accountAssets(account).value.policyAsset
}
)
}
} else {
val isGreedy = isSendAll.value ?: false
val isGreedy = isSendAll.value
val satoshi = if (isGreedy) 0 else UserInput.parseUserInputSafe(
session = session,
input = amount.value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import com.blockstream.common.gdk.params.CreateTransactionParams
import com.blockstream.common.utils.Loggable
import com.blockstream.common.utils.feeRateWithUnit
import com.blockstream.common.utils.toAmountLook
import com.rickclephas.kmp.observableviewmodel.stateIn
import com.rickclephas.kmp.nativecoroutines.NativeCoroutinesState
import com.rickclephas.kmp.observableviewmodel.stateIn
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
Expand Down Expand Up @@ -171,7 +171,6 @@ class SweepViewModel(greenWallet: GreenWallet, privateKey: String?, accountAsset
finalCheckBeforeContinue: Boolean
) {
doAsync({
logger.d { "WTF $params" }
if (params == null) {
_amount.value = null
_amountFiat.value = null
Expand Down Expand Up @@ -214,12 +213,10 @@ class SweepViewModel(greenWallet: GreenWallet, privateKey: String?, accountAsset
}, postAction = {

}, onSuccess = {
logger.d { "WTF Success $it" }
createTransaction.value = it
_isValid.value = it != null
_error.value = null
}, onError = {
logger.d { "WTF error $it" }
createTransaction.value = null
_isValid.value = false
_error.value = it.message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ import com.blockstream.common.navigation.NavigateDestinations
import com.blockstream.common.sideeffects.SideEffect
import com.blockstream.common.sideeffects.SideEffects
import com.blockstream.common.utils.randomChars
import com.rickclephas.kmp.observableviewmodel.coroutineScope
import com.rickclephas.kmp.nativecoroutines.NativeCoroutinesState
import com.rickclephas.kmp.observableviewmodel.coroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.StateFlow
Expand Down Expand Up @@ -170,7 +170,6 @@ class WalletSettingsViewModel(
WalletSetting.AutologoutTimeout(settings.altimeout)
)
} else {

list += listOf(
WalletSetting.Text("id_general"),
WalletSetting.DenominationExchangeRate(
Expand All @@ -185,12 +184,6 @@ class WalletSettingsViewModel(
session.activeBitcoinMultisig != null || session.activeLiquidMultisig != null

list += listOfNotNull(
WalletSetting.Text("id_general"),
WalletSetting.DenominationExchangeRate(
unit = settings.networkUnit(session),
currency = settings.pricing.currency,
exchange = settings.pricing.exchange
),
WalletSetting.ArchivedAccounts(session.allAccounts.value.count { it.hidden }),
WalletSetting.WatchOnly,
WalletSetting.Text("id_security"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.blockstream.common.events.Event
import com.blockstream.common.extensions.assetTickerOrNull
import com.blockstream.common.extensions.isNotBlank
import com.blockstream.common.extensions.previewAccountAsset
import com.blockstream.common.extensions.previewTransaction
import com.blockstream.common.extensions.previewWallet
import com.blockstream.common.gdk.data.AccountAsset
import com.blockstream.common.gdk.data.Transaction
Expand Down Expand Up @@ -236,15 +237,15 @@ class TransactionViewModel(transaction: Transaction, greenWallet: GreenWallet) :

_amounts.value = transaction.utxoViews.map {
AmountAssetLook(
amount = it.satoshi.toAmountLookOrNa(
amount = session.starsOrNull ?: it.satoshi.toAmountLookOrNa(
session = session,
assetId = it.assetId,
withUnit = false,
withDirection = true,
withMinimumDigits = true
),
ticker = it.assetId.assetTickerOrNull(session) ?: it.assetId?.substring(0 until 6) ?: "",
fiat = it.satoshi.toAmountLook(
fiat = session.starsOrNull ?: it.satoshi.toAmountLook(
session = session,
assetId = it.assetId,
withUnit = true,
Expand Down Expand Up @@ -345,7 +346,7 @@ class TransactionViewModelPreview(status : TransactionStatus) : TransactionViewM
accountAssetOrNull = previewAccountAsset(),
greenWallet = previewWallet(isHardware = false)
) {
override val transaction: StateFlow<Transaction> = MutableStateFlow(Transaction.LoadingTransaction)
override val transaction: StateFlow<Transaction> = MutableStateFlow(previewTransaction())

override val status: StateFlow<TransactionStatus> = MutableStateFlow(status)
override val type: StateFlow<Transaction.Type> = MutableStateFlow(Transaction.Type.IN)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ getMainnetWalletWithXpubHashId:
SELECT * FROM wallet WHERE xpub_hash_id = ? AND is_testnet = 0;

getWalletWithXpubHashId:
SELECT * FROM wallet WHERE xpub_hash_id = ? AND is_testnet = ? AND is_hardware = ?;
SELECT * FROM wallet WHERE xpub_hash_id = ? AND is_testnet = ? AND is_hardware = ? LIMIT 1;

-- Not currently used, but is here not to miss that getWalletWithHashId returns no wo wallets
getWalletWatchOnlyXpubHashId:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.blockstream.compose

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.fragment.app.FragmentActivity
import com.blockstream.compose.theme.GreenTheme

class GreenActivity : ComponentActivity() {
class GreenActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Expand Down
Loading

0 comments on commit 423aa14

Please sign in to comment.