Skip to content

Commit 21b58df

Browse files
authored
Merge branch 'code/cash' into fcash/release/2025.9.3
2 parents 49d0967 + 95419f3 commit 21b58df

File tree

88 files changed

+2535
-467
lines changed

Some content is hidden

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

88 files changed

+2535
-467
lines changed

apps/flipcash/app/build.gradle.kts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ dependencies {
154154
implementation(project(":apps:flipcash:shared:permissions"))
155155
implementation(project(":apps:flipcash:shared:phone"))
156156
implementation(project(":apps:flipcash:shared:shareable"))
157+
implementation(project(":apps:flipcash:shared:tokens"))
157158
implementation(project(":apps:flipcash:shared:transfers"))
158159
implementation(project(":apps:flipcash:shared:web"))
159160
implementation(project(":apps:flipcash:shared:workers"))
@@ -175,6 +176,7 @@ dependencies {
175176
implementation(project(":apps:flipcash:features:payments"))
176177
implementation(project(":apps:flipcash:features:onramp"))
177178
implementation(project(":apps:flipcash:features:contact-verification"))
179+
implementation(project(":apps:flipcash:features:tokens"))
178180

179181
implementation(project(":libs:crypto:solana"))
180182
implementation(project(":libs:datetime"))
@@ -202,7 +204,7 @@ dependencies {
202204
implementation(Libs.androidx_lifecycle_viewmodel)
203205
implementation(Libs.androidx_navigation_ui)
204206
implementation(Libs.androidx_work)
205-
implementation("androidx.webkit:webkit:1.13.0")
207+
implementation("androidx.webkit:webkit:1.14.0")
206208

207209
//hilt dependency injection
208210
implementation(Libs.hilt)
@@ -216,7 +218,7 @@ dependencies {
216218
testImplementation(Libs.hilt_android_test)
217219
kspTest(Libs.hilt_android_compiler)
218220

219-
androidTestImplementation("io.mockk:mockk:1.13.17")
221+
androidTestImplementation("io.mockk:mockk:1.14.6")
220222

221223
//Jetpack compose
222224
implementation(platform(Libs.compose_bom))
@@ -231,9 +233,6 @@ dependencies {
231233

232234
implementation(Libs.androidx_activity)
233235

234-
implementation(Libs.coil3)
235-
implementation(Libs.coil3_network)
236-
237236
implementation(Libs.androidx_browser)
238237

239238
implementation(Libs.slf4j)

apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import com.flipcash.app.balance.PreloadBalance
1111
import com.flipcash.app.cash.CashScreen
1212
import com.flipcash.app.contact.verification.VerificationFlowScreen
1313
import com.flipcash.app.core.AppRoute
14-
import com.flipcash.app.currency.CurrencySelectionScreen
14+
import com.flipcash.app.currency.RegionSelectionScreen
1515
import com.flipcash.app.deposit.DepositScreen
1616
import com.flipcash.app.lab.LabsScreen
1717
import com.flipcash.app.lab.PreloadLabs
@@ -34,6 +34,7 @@ import com.flipcash.app.pools.create.PoolQuestionScreen
3434
import com.flipcash.app.purchase.PurchaseAccountScreen
3535
import com.flipcash.app.scanner.ScannerScreen
3636
import com.flipcash.app.shareapp.ShareAppScreen
37+
import com.flipcash.app.tokens.SelectTokenScreen
3738
import com.flipcash.app.transfers.TransferInformationalScreen
3839
import com.flipcash.app.withdrawal.WithdrawalConfirmationScreen
3940
import com.flipcash.app.withdrawal.WithdrawalDestinationScreen
@@ -72,8 +73,12 @@ internal fun AppScreenContent(content: @Composable () -> Unit) {
7273
ScannerScreen(it.deeplink)
7374
}
7475

75-
register<AppRoute.Sheets.Give> {
76-
CashScreen()
76+
register<AppRoute.Main.Give> {
77+
CashScreen(it.tokenAddress)
78+
}
79+
80+
register<AppRoute.Sheets.TokenSelection> {
81+
SelectTokenScreen()
7782
}
7883

7984
register<AppRoute.Sheets.Wallet> {
@@ -104,8 +109,8 @@ internal fun AppScreenContent(content: @Composable () -> Unit) {
104109
)
105110
}
106111

107-
register<AppRoute.Main.CurrencySelection> {
108-
CurrencySelectionScreen(it.kind)
112+
register<AppRoute.Main.RegionSelection> {
113+
RegionSelectionScreen(it.kind)
109114
}
110115

111116
register<AppRoute.Sheets.ShareApp> {

apps/flipcash/core/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ dependencies {
6464
implementation(Libs.androidx_credentials_play_auth)
6565
implementation(Libs.androidx_datastore)
6666

67+
api(Libs.coil3)
68+
api(Libs.coil3_network)
69+
6770
api(project(":services:flipcash-compose"))
6871

6972
implementation(project(":libs:messaging"))

apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ package com.flipcash.app.core
22

33
import android.os.Parcelable
44
import cafe.adriel.voyager.core.registry.ScreenProvider
5-
import com.flipcash.app.core.money.CurrencySelectionKind
5+
import com.flipcash.app.core.money.RegionSelectionKind
66
import com.flipcash.app.core.navigation.DeeplinkType
77
import com.flipcash.app.core.transfers.TransferDirection
88
import com.getcode.ed25519.Ed25519
99
import com.getcode.opencode.model.core.ID
1010
import com.getcode.opencode.model.financial.Fiat
11+
import com.getcode.solana.keys.PublicKey
1112
import com.getcode.ui.core.RestrictionType
1213
import kotlinx.parcelize.Parcelize
1314

@@ -34,7 +35,10 @@ sealed interface AppRoute : ScreenProvider, Parcelable {
3435
data class Scanner(val deeplink: DeeplinkType? = null) : Main
3536

3637
// TODO: is there a better place for this to live?
37-
data class CurrencySelection(val kind: CurrencySelectionKind) : Main
38+
data class RegionSelection(val kind: RegionSelectionKind) : Main
39+
40+
41+
data class Give(val tokenAddress: PublicKey?) : Main
3842
}
3943

4044
@Parcelize
@@ -49,7 +53,7 @@ sealed interface AppRoute : ScreenProvider, Parcelable {
4953

5054
@Parcelize
5155
sealed interface Sheets: AppRoute {
52-
data object Give : Sheets
56+
data object TokenSelection: Sheets
5357
data object Wallet : Sheets
5458
data object Menu : Sheets
5559
data object Lab: Sheets

apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/internal/updater/BalanceUpdater.kt renamed to apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/internal/updater/TokenUpdater.kt

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
package com.flipcash.app.core.internal.updater
22

33
import com.flipcash.app.core.updater.NetworkUpdater
4-
import com.getcode.opencode.controllers.BalanceController
4+
import com.getcode.opencode.controllers.TokenController
55
import kotlinx.coroutines.CoroutineScope
66
import kotlinx.coroutines.launch
7-
import java.util.Timer
87
import javax.inject.Inject
98
import kotlin.concurrent.fixedRateTimer
109
import kotlin.time.Duration
11-
import kotlin.time.Duration.Companion.seconds
1210

13-
class BalanceUpdater @Inject constructor(
14-
private val balanceController: BalanceController,
11+
class TokenUpdater @Inject constructor(
12+
private val tokenController: TokenController,
1513
) : NetworkUpdater() {
1614
override fun poll(
1715
key: Any?,
@@ -21,12 +19,12 @@ class BalanceUpdater @Inject constructor(
2119
) {
2220
stop()
2321
updater = fixedRateTimer(
24-
name = "update balance",
22+
name = "update tokens",
2523
initialDelay = startIn.inWholeMilliseconds,
2624
period = frequency.inWholeMilliseconds
2725
) {
2826
scope.launch {
29-
balanceController.fetchBalance()
27+
tokenController.update()
3028
}
3129
}
3230
}

apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/money/CurrencySelectionKind.kt renamed to apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/money/RegionSelectionKind.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.flipcash.app.core.money
22

3-
enum class CurrencySelectionKind {
3+
enum class RegionSelectionKind {
44
Entry,
55
Balance;
66
}

apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/onramp/deeplinks/WalletDeeplinkConnectionResult.kt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import android.os.Parcelable
44
import com.flipcash.app.core.AppRoute
55
import com.getcode.ed25519.Ed25519
66
import com.getcode.opencode.model.core.ID
7+
import com.getcode.opencode.model.financial.Token
78
import com.getcode.opencode.utils.base64
89
import com.getcode.solana.keys.PublicKey
10+
import com.getcode.solana.keys.base58
911
import com.getcode.utils.base58
1012
import com.getcode.utils.decodeBase58
1113
import com.getcode.utils.decodeBase64
@@ -34,7 +36,7 @@ sealed class OnRampDeeplinkOrigin: Parcelable {
3436
data object Menu : OnRampDeeplinkOrigin()
3537

3638
@Parcelize
37-
data object Give: OnRampDeeplinkOrigin()
39+
data class Give(val tokenAddress: PublicKey?) : OnRampDeeplinkOrigin()
3840

3941
@Parcelize
4042
data object Wallet: OnRampDeeplinkOrigin()
@@ -50,7 +52,7 @@ sealed class OnRampDeeplinkOrigin: Parcelable {
5052
is PoolWithId -> "pool-id_${id.base58}"
5153
is PoolWithRendezvous -> "pool-seed_${keyPair.seed.base64}"
5254
Menu -> "menu"
53-
Give -> "give"
55+
is Give -> "give-${tokenAddress?.base58()}"
5456
Wallet -> "wallet"
5557
}.lowercase()
5658
}
@@ -59,7 +61,7 @@ sealed class OnRampDeeplinkOrigin: Parcelable {
5961
fun fromRoute(route: AppRoute?): OnRampDeeplinkOrigin? {
6062
return when (route) {
6163
is AppRoute.Sheets.Menu -> Menu
62-
is AppRoute.Sheets.Give -> Give
64+
is AppRoute.Main.Give -> Give(route.tokenAddress)
6365
is AppRoute.Pool.Details -> {
6466
route.rendezvous?.let { keyPair -> PoolWithRendezvous(keyPair) }
6567
route.poolId?.let { id -> PoolWithId(id) }
@@ -73,7 +75,12 @@ sealed class OnRampDeeplinkOrigin: Parcelable {
7375
fun fromString(value: String?): OnRampDeeplinkOrigin? {
7476
return when {
7577
value == "menu" -> Menu
76-
value == "give" -> Give
78+
value?.startsWith("give-") == true -> {
79+
val tokenAddress = value.removePrefix("give-")
80+
Give(tokenAddress = runCatching {
81+
PublicKey.fromBase58(tokenAddress)
82+
}.getOrNull())
83+
}
7784
value == "wallet" -> Wallet
7885
value?.startsWith("pool-") == true -> {
7986
val idStringWithPrefix = value.removePrefix("pool-")
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package com.flipcash.app.core.ui
2+
3+
import androidx.compose.foundation.clickable
4+
import androidx.compose.foundation.layout.Arrangement
5+
import androidx.compose.foundation.layout.Row
6+
import androidx.compose.foundation.layout.Spacer
7+
import androidx.compose.foundation.layout.padding
8+
import androidx.compose.foundation.layout.size
9+
import androidx.compose.foundation.shape.CircleShape
10+
import androidx.compose.material.Text
11+
import androidx.compose.runtime.Composable
12+
import androidx.compose.ui.Alignment
13+
import androidx.compose.ui.Modifier
14+
import androidx.compose.ui.draw.clip
15+
import coil3.compose.AsyncImage
16+
import coil3.compose.LocalPlatformContext
17+
import coil3.request.ImageRequest
18+
import coil3.request.error
19+
import com.getcode.opencode.model.financial.Fiat
20+
import com.getcode.opencode.model.financial.Token
21+
import com.getcode.opencode.model.financial.TokenWithBalance
22+
import com.getcode.opencode.model.financial.TokenWithLocalizedBalance
23+
import com.getcode.theme.CodeTheme
24+
import com.getcode.ui.components.R
25+
26+
@Composable
27+
fun TokenBalanceRow(
28+
tokenWithBalance: TokenWithLocalizedBalance,
29+
modifier: Modifier = Modifier,
30+
onClick: () -> Unit
31+
) {
32+
val (token, balance) = tokenWithBalance
33+
TokenBalanceRow(
34+
token = token,
35+
balance = balance.converted,
36+
modifier = modifier,
37+
onClick = onClick
38+
)
39+
}
40+
41+
@Composable
42+
fun TokenBalanceRow(
43+
tokenWithBalance: TokenWithBalance,
44+
modifier: Modifier = Modifier,
45+
onClick: () -> Unit
46+
) {
47+
val (token, balance) = tokenWithBalance
48+
TokenBalanceRow(
49+
token = token,
50+
balance = balance,
51+
modifier = modifier,
52+
onClick = onClick
53+
)
54+
}
55+
56+
57+
@Composable
58+
fun TokenBalanceRow(
59+
token: Token,
60+
balance: Fiat,
61+
modifier: Modifier = Modifier,
62+
onClick: () -> Unit
63+
) {
64+
Row(
65+
modifier = Modifier
66+
.clickable(onClick = onClick)
67+
.then(modifier)
68+
.padding(
69+
vertical = CodeTheme.dimens.inset,
70+
),
71+
horizontalArrangement = Arrangement.spacedBy(CodeTheme.dimens.grid.x2),
72+
verticalAlignment = Alignment.CenterVertically,
73+
) {
74+
AsyncImage(
75+
modifier = Modifier
76+
.size(CodeTheme.dimens.staticGrid.x5)
77+
.clip(CircleShape),
78+
model = ImageRequest.Builder(LocalPlatformContext.current)
79+
.data(token.imageUrl)
80+
.error(R.drawable.ic_placeholder_user)
81+
.placeholderMemoryCacheKey(token.symbol)
82+
.build(),
83+
contentDescription = null,
84+
)
85+
86+
Text(
87+
text = token.name,
88+
style = CodeTheme.typography.screenTitle,
89+
color = CodeTheme.colors.textMain,
90+
)
91+
92+
Spacer(Modifier.weight(1f))
93+
94+
Text(
95+
text = balance.formatted(),
96+
style = CodeTheme.typography.screenTitle,
97+
color = CodeTheme.colors.textMain,
98+
)
99+
}
100+
}

apps/flipcash/core/src/main/res/values/strings.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
<string name="error_description_linkExpired">The cash was automatically returned to the sender because it wasn\'t collected within 7 days. Please ask them to send the cash again</string>
5656

5757
<string name="subtitle_balanceIsHeldInUsdStablecoins">Your balance is held in US dollar stablecoins</string>
58+
<string name="subtitle_currentValueOfAllCurrencies">The current value of your currencies</string>
5859
<string name="subtitle_ofUsdStablecoins">of US dollar stablecoins</string>
5960
<string name="subtitle_balanceEmptyState">Ask a friend to give you some cash with Flipcash, or deposit USDC from your crypto exchange or another crypto wallet</string>
6061
<string name="action_depositFunds">Deposit Funds</string>
@@ -402,4 +403,10 @@
402403

403404
<string name="subtitle_addUsdcToWallet">Add Solana USDC to your Flipcash wallet</string>
404405

406+
<string name="title_selectCurrency">Select Currency</string>
407+
<string name="title_selectRegion">Select Region</string>
408+
<string name="title_recentRegions">Recent Regions</string>
409+
<string name="title_otherRegions">Other Regions</string>
410+
<string name="subtitle_searchRegions">Search regions</string>
411+
<string name="title_enterAmount">Enter Amount</string>
405412
</resources>

apps/flipcash/features/balance/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ dependencies {
5656
implementation(project(":apps:flipcash:shared:activityfeed"))
5757
implementation(project(":apps:flipcash:shared:onramp:common"))
5858
implementation(project(":apps:flipcash:shared:featureflags"))
59+
implementation(project(":apps:flipcash:shared:tokens"))
5960
implementation(project(":libs:datetime"))
6061
implementation(project(":libs:logging"))
6162
implementation(project(":libs:messaging"))

0 commit comments

Comments
 (0)