Skip to content

Commit 28cfa74

Browse files
committed
Merge branch 'feature/MOBILE-155-2' into 0.44.0
2 parents 4a063db + f93b03a commit 28cfa74

67 files changed

Lines changed: 1934 additions & 203 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ dependencies {
300300
implementation "androidx.navigation:navigation-ui-ktx:$navigation_ktx_version"
301301

302302
//Compose Navigation
303-
implementation "androidx.navigation:navigation-compose:$navigation_ktx_version"
303+
implementation libs.androidx.navigation.compose
304304
implementation "com.google.accompanist:accompanist-navigation-animation:$accompanist_version"
305305

306306
api 'com.journeyapps:zxing-android-embedded:4.3.0'

app/src/main/java/cash/p/terminal/core/App.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import cash.p.terminal.core.managers.RestoreSettingsManager
3737
import cash.p.terminal.core.managers.SolanaKitManager
3838
import cash.p.terminal.core.managers.SolanaRpcSourceManager
3939
import cash.p.terminal.core.managers.SpamManager
40-
import cash.p.terminal.core.managers.SystemInfoManager
4140
import cash.p.terminal.core.managers.TermsManager
4241
import cash.p.terminal.core.managers.TokenAutoEnableManager
4342
import cash.p.terminal.core.managers.TonAccountManager
@@ -51,7 +50,6 @@ import cash.p.terminal.core.managers.UserManager
5150
import cash.p.terminal.core.managers.WalletActivator
5251
import cash.p.terminal.core.managers.WordsManager
5352
import cash.p.terminal.core.managers.ZcashBirthdayProvider
54-
import cash.p.terminal.core.managers.MoneroKitManager
5553
import cash.p.terminal.core.providers.AppConfigProvider
5654
import cash.p.terminal.core.providers.CexProviderManager
5755
import cash.p.terminal.core.providers.FeeRateProvider
@@ -289,7 +287,7 @@ class App : CoreApp(), WorkConfiguration.Provider, ImageLoaderFactory {
289287
TonAccountManager(accountManager, walletManager, tonKitManager, tokenAutoEnableManager)
290288
tonAccountManager.start()
291289

292-
systemInfoManager = SystemInfoManager(appConfigProvider)
290+
systemInfoManager = get()
293291
connectivityManager = ConnectivityManager(backgroundManager)
294292
val adapterFactory: AdapterFactory = get()
295293

app/src/main/java/cash/p/terminal/core/ILocalStorage.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,5 +96,7 @@ interface ILocalStorage {
9696
fun setStackingUnpaid(wallet: Wallet, unpaid: BigDecimal)
9797
fun getStackingUnpaid(wallet: Wallet): BigDecimal?
9898

99+
var isSystemPinRequired: Boolean
100+
99101
fun clear()
100102
}

app/src/main/java/cash/p/terminal/core/Interfaces.kt

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import cash.p.terminal.wallet.Token
2828
import cash.p.terminal.wallet.entities.BalanceData
2929
import cash.p.terminal.wallet.entities.TokenQuery
3030
import cash.z.ecc.android.sdk.model.FirstClassByteArray
31+
import io.horizontalsystems.bitcoincore.storage.UtxoFilters
3132
import io.horizontalsystems.core.logger.AppLogger
3233
import io.horizontalsystems.solanakit.models.FullTransaction
3334
import io.horizontalsystems.tonkit.FriendlyAddress
@@ -141,17 +142,23 @@ interface ISendBitcoinAdapter {
141142
address: String?,
142143
memo: String?,
143144
unspentOutputs: List<UnspentOutputInfo>?,
144-
pluginData: Map<Byte, IPluginData>?
145+
pluginData: Map<Byte, IPluginData>?,
146+
dustThreshold: Int?,
147+
changeToFirstInput: Boolean,
148+
utxoFilters: UtxoFilters
145149
): BigDecimal
146150

147-
fun minimumSendAmount(address: String?): BigDecimal?
151+
fun minimumSendAmount(address: String?, dustThreshold: Int?): BigDecimal?
148152
fun bitcoinFeeInfo(
149153
amount: BigDecimal,
150154
feeRate: Int,
151155
address: String?,
152156
memo: String?,
153157
unspentOutputs: List<UnspentOutputInfo>?,
154-
pluginData: Map<Byte, IPluginData>?
158+
pluginData: Map<Byte, IPluginData>?,
159+
dustThreshold: Int?,
160+
changeToFirstInput: Boolean,
161+
filters: UtxoFilters
155162
): BitcoinFeeInfo?
156163

157164
fun validate(address: String, pluginData: Map<Byte, IPluginData>?)
@@ -164,6 +171,9 @@ interface ISendBitcoinAdapter {
164171
pluginData: Map<Byte, IPluginData>?,
165172
transactionSorting: TransactionDataSortMode?,
166173
rbfEnabled: Boolean,
174+
dustThreshold: Int?,
175+
changeToFirstInput: Boolean,
176+
utxoFilters: UtxoFilters,
167177
logger: AppLogger
168178
): String
169179
}

app/src/main/java/cash/p/terminal/core/adapters/BitcoinAdapter.kt

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cash.p.terminal.core.adapters
33
import cash.p.terminal.core.App
44
import cash.p.terminal.core.ISendBitcoinAdapter
55
import cash.p.terminal.core.UnsupportedAccountException
6+
import cash.p.terminal.core.derivation
67
import cash.p.terminal.wallet.entities.UsedAddress
78
import cash.p.terminal.core.purpose
89
import cash.p.terminal.entities.transactionrecords.TransactionRecord
@@ -12,7 +13,6 @@ import io.horizontalsystems.bitcoincore.BitcoinCore
1213
import io.horizontalsystems.bitcoincore.models.BalanceInfo
1314
import io.horizontalsystems.bitcoincore.models.BlockInfo
1415
import io.horizontalsystems.bitcoincore.models.TransactionInfo
15-
import io.horizontalsystems.bitcoincore.storage.UnspentOutputInfo
1616
import io.horizontalsystems.bitcoinkit.BitcoinKit
1717
import io.horizontalsystems.bitcoinkit.BitcoinKit.NetworkType
1818
import io.horizontalsystems.core.BackgroundManager
@@ -90,9 +90,6 @@ class BitcoinAdapter(
9090
// ignored for now
9191
}
9292

93-
override val unspentOutputs: List<UnspentOutputInfo>
94-
get() = kit.unspentOutputs
95-
9693
override val blockchainType = BlockchainType.Bitcoin
9794

9895
override fun usedAddresses(change: Boolean): List<UsedAddress> =
@@ -175,5 +172,46 @@ class BitcoinAdapter(
175172
fun clear(walletId: String) {
176173
BitcoinKit.clear(App.instance, NetworkType.MainNet, walletId)
177174
}
175+
176+
fun firstAddress(accountType: AccountType, tokenType: TokenType): String {
177+
when (accountType) {
178+
is AccountType.Mnemonic -> {
179+
val seed = accountType.seed
180+
val derivation = tokenType.derivation ?: throw IllegalArgumentException()
181+
182+
val address = BitcoinKit.firstAddress(
183+
seed,
184+
derivation.purpose,
185+
NetworkType.MainNet
186+
)
187+
188+
return address.stringValue
189+
}
190+
is AccountType.HdExtendedKey -> {
191+
val key = accountType.hdExtendedKey
192+
val derivation = tokenType.derivation ?: throw IllegalArgumentException()
193+
val address = BitcoinKit.firstAddress(
194+
key,
195+
derivation.purpose,
196+
NetworkType.MainNet
197+
)
198+
199+
return address.stringValue
200+
}
201+
is AccountType.BitcoinAddress -> {
202+
return accountType.address
203+
}
204+
is AccountType.HardwareCard,
205+
is AccountType.Cex,
206+
is AccountType.EvmAddress,
207+
is AccountType.EvmPrivateKey,
208+
is AccountType.MnemonicMonero,
209+
is AccountType.SolanaAddress,
210+
is AccountType.TonAddress,
211+
is AccountType.TronAddress,
212+
is AccountType.ZCashUfvKey -> throw UnsupportedAccountException()
213+
}
214+
215+
}
178216
}
179217
}

app/src/main/java/cash/p/terminal/core/adapters/BitcoinBaseAdapter.kt

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package cash.p.terminal.core.adapters
22

3+
import cash.p.terminal.core.ISendBitcoinAdapter
34
import cash.p.terminal.core.ITransactionsAdapter
45
import cash.p.terminal.core.UnsupportedFilterException
56
import cash.p.terminal.entities.LastBlockInfo
@@ -35,6 +36,7 @@ import io.horizontalsystems.bitcoincore.rbf.ReplacementTransactionInfo
3536
import io.horizontalsystems.bitcoincore.storage.FullTransaction
3637
import io.horizontalsystems.bitcoincore.storage.UnspentOutput
3738
import io.horizontalsystems.bitcoincore.storage.UnspentOutputInfo
39+
import io.horizontalsystems.bitcoincore.storage.UtxoFilters
3840
import io.horizontalsystems.core.BackgroundManager
3941
import io.horizontalsystems.core.BackgroundManagerState
4042
import io.horizontalsystems.core.entities.BlockchainType
@@ -50,7 +52,6 @@ import kotlinx.coroutines.Dispatchers
5052
import kotlinx.coroutines.cancel
5153
import kotlinx.coroutines.flow.Flow
5254
import kotlinx.coroutines.flow.StateFlow
53-
import kotlinx.coroutines.flow.asStateFlow
5455
import kotlinx.coroutines.flow.emptyFlow
5556
import kotlinx.coroutines.launch
5657
import kotlinx.coroutines.reactive.asFlow
@@ -68,7 +69,7 @@ abstract class BitcoinBaseAdapter(
6869
val wallet: Wallet,
6970
private val confirmationsThreshold: Int,
7071
protected val decimal: Int = 8
71-
) : IAdapter, ITransactionsAdapter, IBalanceAdapter, IReceiveAdapter {
72+
) : IAdapter, ITransactionsAdapter, IBalanceAdapter, IReceiveAdapter, ISendBitcoinAdapter {
7273

7374
private val scope = CoroutineScope(Dispatchers.Default)
7475

@@ -108,6 +109,9 @@ abstract class BitcoinBaseAdapter(
108109
protected val transactionRecordsSubject: PublishSubject<List<TransactionRecord>> =
109110
PublishSubject.create()
110111

112+
final override val unspentOutputs: List<UnspentOutputInfo>
113+
get() = kit.getUnspentOutputs(UtxoFilters())
114+
111115
override val balanceUpdatedFlow: Flow<Unit>
112116
get() = balanceUpdatedSubject.toFlowable(BackpressureStrategy.BUFFER).asFlow()
113117

@@ -309,7 +313,7 @@ abstract class BitcoinBaseAdapter(
309313
}
310314
}
311315

312-
suspend fun send(
316+
override suspend fun send(
313317
amount: BigDecimal,
314318
address: String,
315319
memo: String?,
@@ -318,6 +322,9 @@ abstract class BitcoinBaseAdapter(
318322
pluginData: Map<Byte, IPluginData>?,
319323
transactionSorting: TransactionDataSortMode?,
320324
rbfEnabled: Boolean,
325+
dustThreshold: Int?,
326+
changeToFirstInput: Boolean,
327+
utxoFilters: UtxoFilters,
321328
logger: AppLogger
322329
): String {
323330
logger.info("call btc-kit.send")
@@ -331,44 +338,59 @@ abstract class BitcoinBaseAdapter(
331338
sortType = sortingType,
332339
unspentOutputs = unspentOutputs,
333340
pluginData = pluginData ?: mapOf(),
341+
dustThreshold = dustThreshold,
342+
changeToFirstInput = changeToFirstInput,
343+
filters = utxoFilters,
334344
rbfEnabled = rbfEnabled
335345
)
336346
return sendData.header.uid
337347
}
338348

339-
fun availableBalance(
349+
override fun availableBalance(
340350
feeRate: Int,
341351
address: String?,
342352
memo: String?,
343353
unspentOutputs: List<UnspentOutputInfo>?,
344-
pluginData: Map<Byte, IPluginData>?
354+
pluginData: Map<Byte, IPluginData>?,
355+
dustThreshold: Int?,
356+
changeToFirstInput: Boolean,
357+
utxoFilters: UtxoFilters
345358
): BigDecimal {
346359
return try {
347360
val maximumSpendableValue = kit.maximumSpendableValue(
348-
address, memo, feeRate, unspentOutputs, pluginData
349-
?: mapOf()
361+
address = address,
362+
memo = memo,
363+
feeRate = feeRate,
364+
unspentOutputInfos = unspentOutputs,
365+
pluginData = pluginData ?: mapOf(),
366+
dustThreshold = dustThreshold,
367+
changeToFirstInput = changeToFirstInput,
368+
filters = utxoFilters,
350369
)
351370
satoshiToBTC(maximumSpendableValue, RoundingMode.CEILING)
352371
} catch (e: Exception) {
353372
BigDecimal.ZERO
354373
}
355374
}
356375

357-
fun minimumSendAmount(address: String?): BigDecimal? {
376+
override fun minimumSendAmount(address: String?, dustThreshold: Int?): BigDecimal? {
358377
return try {
359-
satoshiToBTC(kit.minimumSpendableValue(address).toLong(), RoundingMode.CEILING)
378+
satoshiToBTC(kit.minimumSpendableValue(address, dustThreshold).toLong(), RoundingMode.CEILING)
360379
} catch (e: Exception) {
361380
null
362381
}
363382
}
364383

365-
fun bitcoinFeeInfo(
384+
override fun bitcoinFeeInfo(
366385
amount: BigDecimal,
367386
feeRate: Int,
368387
address: String?,
369388
memo: String?,
370389
unspentOutputs: List<UnspentOutputInfo>?,
371-
pluginData: Map<Byte, IPluginData>?
390+
pluginData: Map<Byte, IPluginData>?,
391+
dustThreshold: Int?,
392+
changeToFirstInput: Boolean,
393+
filters: UtxoFilters
372394
): BitcoinFeeInfo? {
373395
return try {
374396
val satoshiAmount = (amount * satoshisInBitcoin).toLong()
@@ -379,7 +401,10 @@ abstract class BitcoinBaseAdapter(
379401
senderPay = true,
380402
feeRate = feeRate,
381403
unspentOutputs = unspentOutputs,
382-
pluginData = pluginData ?: mapOf()
404+
pluginData = pluginData ?: mapOf(),
405+
dustThreshold = dustThreshold,
406+
changeToFirstInput = changeToFirstInput,
407+
filters = filters
383408
).let {
384409
BitcoinFeeInfo(
385410
unspentOutputs = it.unspentOutputs,
@@ -393,7 +418,7 @@ abstract class BitcoinBaseAdapter(
393418
}
394419
}
395420

396-
fun validate(address: String, pluginData: Map<Byte, IPluginData>?) {
421+
override fun validate(address: String, pluginData: Map<Byte, IPluginData>?) {
397422
kit.validateAddress(address, pluginData ?: mapOf())
398423
}
399424

app/src/main/java/cash/p/terminal/core/adapters/BitcoinCashAdapter.kt

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cash.p.terminal.core.adapters
33
import cash.p.terminal.core.App
44
import cash.p.terminal.core.ISendBitcoinAdapter
55
import cash.p.terminal.core.UnsupportedAccountException
6+
import cash.p.terminal.core.bitcoinCashCoinType
67
import cash.p.terminal.wallet.entities.UsedAddress
78
import cash.p.terminal.core.kitCoinType
89
import cash.p.terminal.entities.transactionrecords.TransactionRecord
@@ -15,7 +16,6 @@ import io.horizontalsystems.bitcoincore.BitcoinCore
1516
import io.horizontalsystems.bitcoincore.models.BalanceInfo
1617
import io.horizontalsystems.bitcoincore.models.BlockInfo
1718
import io.horizontalsystems.bitcoincore.models.TransactionInfo
18-
import io.horizontalsystems.bitcoincore.storage.UnspentOutputInfo
1919
import io.horizontalsystems.core.BackgroundManager
2020
import io.horizontalsystems.core.entities.BlockchainType
2121
import cash.p.terminal.wallet.entities.TokenType
@@ -85,9 +85,6 @@ class BitcoinCashAdapter(
8585
// ignored for now
8686
}
8787

88-
override val unspentOutputs: List<UnspentOutputInfo>
89-
get() = kit.unspentOutputs
90-
9188
override val blockchainType = BlockchainType.BitcoinCash
9289

9390
override fun usedAddresses(change: Boolean): List<UsedAddress> =
@@ -174,5 +171,51 @@ class BitcoinCashAdapter(
174171

175172
private fun getNetworkType(kitCoinType: MainNetBitcoinCash.CoinType = MainNetBitcoinCash.CoinType.Type145) =
176173
NetworkType.MainNet(kitCoinType)
174+
175+
fun firstAddress(accountType: AccountType, tokenType: TokenType) : String {
176+
val bitcoinCashCoinType = tokenType.bitcoinCashCoinType ?: throw IllegalArgumentException()
177+
178+
val kitCoinType = when (bitcoinCashCoinType) {
179+
TokenType.AddressType.Type0 -> MainNetBitcoinCash.CoinType.Type0
180+
TokenType.AddressType.Type145 -> MainNetBitcoinCash.CoinType.Type145
181+
}
182+
183+
val networkType = NetworkType.MainNet(kitCoinType)
184+
185+
when (accountType) {
186+
is AccountType.Mnemonic -> {
187+
val seed = accountType.seed
188+
189+
val address = BitcoinCashKit.firstAddress(
190+
seed,
191+
networkType
192+
)
193+
194+
return address.stringValue
195+
}
196+
is AccountType.HdExtendedKey -> {
197+
val key = accountType.hdExtendedKey
198+
val address = BitcoinCashKit.firstAddress(
199+
key,
200+
networkType
201+
)
202+
203+
return address.stringValue
204+
}
205+
is AccountType.BitcoinAddress -> {
206+
return accountType.address
207+
}
208+
209+
is AccountType.Cex,
210+
is AccountType.EvmAddress,
211+
is AccountType.EvmPrivateKey,
212+
is AccountType.HardwareCard,
213+
is AccountType.MnemonicMonero,
214+
is AccountType.SolanaAddress,
215+
is AccountType.TonAddress,
216+
is AccountType.TronAddress,
217+
is AccountType.ZCashUfvKey -> throw UnsupportedAccountException()
218+
}
219+
}
177220
}
178221
}

app/src/main/java/cash/p/terminal/core/adapters/CosantaAdapter.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,6 @@ class CosantaAdapter(
9191
// ignored for now
9292
}
9393

94-
override val unspentOutputs: List<UnspentOutputInfo>
95-
get() = kit.unspentOutputs
96-
9794
override val blockchainType = BlockchainType.Cosanta
9895

9996
override fun usedAddresses(change: Boolean): List<UsedAddress> =

0 commit comments

Comments
 (0)