Phase 3: Wallet panel UI and full /pay flow wiring

- Add WalletPanelView with 4 tabs (Overview, Assets, History, Settings)
- Overview tab shows balance, QR code for receiving, and Send ADA button
- Assets tab shows native tokens held at address
- History tab shows recent transactions with explorer links
- Settings tab shows address, network, and backup/delete options

- Add NativeAsset and TxSummary models to wallet API
- Add getAddressAssets() and getAddressTransactions() to CardanoClient
- Implement new methods in KoiosCardanoClient and FakeCardanoClient

- Add wallet button to MessagesViewTopBar (DM rooms only)
- Add isDmRoom to MessagesState for conditional UI
- Wire navigateToWallet() callback through to MessagesFlowNode
- Add NavTarget.WalletPanel and WalletPanelNode integration

- Add string resources for wallet panel UI

Known limitations:
- Uses Chart icon as placeholder for wallet (Compound lacks wallet icon)
- Wallet setup flow not implemented (TODO)
- Transaction amounts in history need additional API calls to calculate
This commit is contained in:
Kayos 2026-03-28 09:23:58 -07:00
parent b867fa783e
commit e33c87c164
24 changed files with 1685 additions and 1 deletions

View file

@ -8,8 +8,10 @@ package io.element.android.features.wallet.test
import io.element.android.features.wallet.api.CardanoClient
import io.element.android.features.wallet.api.CardanoException
import io.element.android.features.wallet.api.NativeAsset
import io.element.android.features.wallet.api.ProtocolParameters
import io.element.android.features.wallet.api.TxStatus
import io.element.android.features.wallet.api.TxSummary
import io.element.android.features.wallet.api.Utxo
/**
@ -27,6 +29,8 @@ class FakeCardanoClient : CardanoClient {
var utxos = mutableMapOf<String, List<Utxo>>()
var transactionStatuses = mutableMapOf<String, TxStatus>()
var submittedTransactions = mutableListOf<SubmittedTx>()
var assets = mutableMapOf<String, List<NativeAsset>>()
var transactions = mutableMapOf<String, List<TxSummary>>()
// Error simulation
var shouldFailWithNetworkError = false
@ -53,6 +57,10 @@ class FakeCardanoClient : CardanoClient {
private set
var getProtocolParametersCallCount = 0
private set
var getAddressAssetsCallCount = 0
private set
var getAddressTransactionsCallCount = 0
private set
/**
* Represents a submitted transaction for testing.
@ -145,6 +153,32 @@ class FakeCardanoClient : CardanoClient {
return Result.success(protocolParameters)
}
override suspend fun getAddressAssets(address: String): Result<List<NativeAsset>> {
getAddressAssetsCallCount++
if (shouldFailWithNetworkError) {
return Result.failure(CardanoException.NetworkException("Simulated network error"))
}
if (shouldFailWithRateLimit) {
return Result.failure(CardanoException.RateLimitException(retryAfterMs = 1000L))
}
return Result.success(assets[address] ?: emptyList())
}
override suspend fun getAddressTransactions(address: String, limit: Int): Result<List<TxSummary>> {
getAddressTransactionsCallCount++
if (shouldFailWithNetworkError) {
return Result.failure(CardanoException.NetworkException("Simulated network error"))
}
if (shouldFailWithRateLimit) {
return Result.failure(CardanoException.RateLimitException(retryAfterMs = 1000L))
}
return Result.success(transactions[address]?.take(limit) ?: emptyList())
}
// Helper methods for test setup
/**
@ -212,6 +246,8 @@ class FakeCardanoClient : CardanoClient {
utxos.clear()
transactionStatuses.clear()
submittedTransactions.clear()
assets.clear()
transactions.clear()
shouldFailWithNetworkError = false
shouldFailWithRateLimit = false
submitShouldFail = false
@ -221,6 +257,8 @@ class FakeCardanoClient : CardanoClient {
submitTxCallCount = 0
getTxStatusCallCount = 0
getProtocolParametersCallCount = 0
getAddressAssetsCallCount = 0
getAddressTransactionsCallCount = 0
protocolParameters = ProtocolParameters(
minFeeA = 44L,
minFeeB = 155381L,