Skip to content

Commit a545374

Browse files
committed
feat: add coinbase onramp for google pay behind beta flag
beginning to feature work Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent 17da4aa commit a545374

39 files changed

Lines changed: 804 additions & 440 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ fun appEntryProvider(
142142
neededCurrency = key.neededAmount?.currencyCode,
143143
)
144144
}
145-
annotatedEntry<AppRoute.OnRamp.AmountEntry> { OnRampCustomAmountScreen() }
145+
annotatedEntry<AppRoute.OnRamp.AmountEntry> { key -> OnRampCustomAmountScreen(key.mint) }
146146

147147
// Menu
148148
annotatedEntry<AppRoute.Menu.AppSettings> { AppSettingsScreen() }

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import com.flipcash.app.core.tokens.TokenPurpose
77
import com.flipcash.app.core.tokens.TokenSwapPurpose
88
import com.getcode.navigation.NonDismissableRoute
99
import com.getcode.navigation.NonDraggableRoute
10-
import com.getcode.navigation.Sheet
1110
import com.getcode.opencode.internal.solana.model.SwapId
1211
import com.getcode.opencode.model.financial.Fiat
1312
import com.getcode.solana.keys.Mint
@@ -96,7 +95,8 @@ sealed interface AppRoute : NavKey, Parcelable {
9695
val neededAmount: Fiat? = null,
9796
) : OnRamp
9897

99-
@Serializable data object AmountEntry: OnRamp
98+
@Serializable
99+
data class AmountEntry(val mint: Mint? = null) : OnRamp
100100
}
101101

102102
@Serializable

apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/verification/email/EmailDeeplinkOrigin.kt

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import com.flipcash.app.core.AppRoute
44
import com.getcode.ed25519.Ed25519
55
import com.getcode.opencode.model.financial.Fiat
66
import com.getcode.opencode.utils.base64
7+
import com.getcode.solana.keys.Mint
8+
import com.getcode.solana.keys.base58
79
import com.getcode.utils.base58
810
import com.getcode.utils.decodeBase58
911
import com.getcode.utils.decodeBase64
@@ -20,9 +22,10 @@ sealed class EmailDeeplinkOrigin {
2022
fun serialize(): String {
2123
return when (this) {
2224
is OnRamp -> {
23-
val amountString = amount?.let { Json.Default.encodeToString(Fiat.Companion.serializer(), it) }
25+
val amountString = amount?.let { Json.encodeToString(Fiat.Companion.serializer(), it) }
2426
when (source) {
2527
is AppRoute.Sheets.Menu -> "onramp|menu|$amountString"
28+
is AppRoute.OnRamp.AmountEntry -> "onramp|amountentry|${source.mint?.base58()}"
2629

2730
else -> "onramp|null|$amountString"
2831
}
@@ -35,8 +38,8 @@ sealed class EmailDeeplinkOrigin {
3538
companion object {
3639
fun fromRoute(route: AppRoute?): EmailDeeplinkOrigin? {
3740
return when (route) {
38-
is AppRoute.OnRamp.ProviderList -> {
39-
OnRamp(route.from, route.neededAmount)
41+
is AppRoute.OnRamp.AmountEntry -> {
42+
OnRamp(route)
4043
}
4144

4245
is AppRoute.Menu.MyAccount -> MyAccount
@@ -51,12 +54,19 @@ sealed class EmailDeeplinkOrigin {
5154
"onramp" -> {
5255
val source = when (splits[1]) {
5356
"menu" -> AppRoute.Sheets.Menu
54-
57+
"amountentry" -> {
58+
println("deeplink origin amountentry")
59+
val mint = splits.getOrNull(2)?.let {
60+
println("deeplink mint = $it")
61+
Mint(it)
62+
}
63+
AppRoute.OnRamp.AmountEntry(mint)
64+
}
5565
else -> null
5666
}
5767

5868
val amount =
59-
splits.getOrNull(3)?.let { Json.Default.decodeFromString(Fiat.Companion.serializer(), it) }
69+
splits.getOrNull(3)?.let { Json.decodeFromString(Fiat.Companion.serializer(), it) }
6070

6171
OnRamp(source, amount)
6272
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="80dp"
3+
android:height="38.1dp"
4+
android:viewportWidth="80"
5+
android:viewportHeight="38.1">
6+
<path
7+
android:pathData="M37.8,19.7V29h-3V6h7.8c1.9,0 3.7,0.7 5.1,2c1.4,1.2 2.1,3 2.1,4.9c0,1.9 -0.7,3.6 -2.1,4.9c-1.4,1.3 -3.1,2 -5.1,2L37.8,19.7L37.8,19.7zM37.8,8.8v8h5c1.1,0 2.2,-0.4 2.9,-1.2c1.6,-1.5 1.6,-4 0.1,-5.5c0,0 -0.1,-0.1 -0.1,-0.1c-0.8,-0.8 -1.8,-1.3 -2.9,-1.2L37.8,8.8L37.8,8.8z"
8+
android:fillColor="#5F6368"/>
9+
<path
10+
android:pathData="M56.7,12.8c2.2,0 3.9,0.6 5.2,1.8s1.9,2.8 1.9,4.8V29H61v-2.2h-0.1c-1.2,1.8 -2.9,2.7 -4.9,2.7c-1.7,0 -3.2,-0.5 -4.4,-1.5c-1.1,-1 -1.8,-2.4 -1.8,-3.9c0,-1.6 0.6,-2.9 1.8,-3.9c1.2,-1 2.9,-1.4 4.9,-1.4c1.8,0 3.2,0.3 4.3,1v-0.7c0,-1 -0.4,-2 -1.2,-2.6c-0.8,-0.7 -1.8,-1.1 -2.9,-1.1c-1.7,0 -3,0.7 -3.9,2.1l-2.6,-1.6C51.8,13.8 53.9,12.8 56.7,12.8zM52.9,24.2c0,0.8 0.4,1.5 1,1.9c0.7,0.5 1.5,0.8 2.3,0.8c1.2,0 2.4,-0.5 3.3,-1.4c1,-0.9 1.5,-2 1.5,-3.2c-0.9,-0.7 -2.2,-1.1 -3.9,-1.1c-1.2,0 -2.2,0.3 -3,0.9C53.3,22.6 52.9,23.3 52.9,24.2z"
11+
android:fillColor="#5F6368"/>
12+
<path
13+
android:pathData="M80,13.3l-9.9,22.7h-3l3.7,-7.9l-6.5,-14.7h3.2l4.7,11.3h0.1l4.6,-11.3H80z"
14+
android:fillColor="#5F6368"/>
15+
<path
16+
android:pathData="M25.9,17.7c0,-0.9 -0.1,-1.8 -0.2,-2.7H13.2v5.1h7.1c-0.3,1.6 -1.2,3.1 -2.6,4v3.3H22C24.5,25.1 25.9,21.7 25.9,17.7z"
17+
android:fillColor="#4285F4"/>
18+
<path
19+
android:pathData="M13.2,30.6c3.6,0 6.6,-1.2 8.8,-3.2l-4.3,-3.3c-1.2,0.8 -2.7,1.3 -4.5,1.3c-3.4,0 -6.4,-2.3 -7.4,-5.5H1.4v3.4C3.7,27.8 8.2,30.6 13.2,30.6z"
20+
android:fillColor="#34A853"/>
21+
<path
22+
android:pathData="M5.8,19.9c-0.6,-1.6 -0.6,-3.4 0,-5.1v-3.4H1.4c-1.9,3.7 -1.9,8.1 0,11.9L5.8,19.9z"
23+
android:fillColor="#FBBC04"/>
24+
<path
25+
android:pathData="M13.2,9.4c1.9,0 3.7,0.7 5.1,2l0,0l3.8,-3.8c-2.4,-2.2 -5.6,-3.5 -8.8,-3.4c-5,0 -9.6,2.8 -11.8,7.3l4.4,3.4C6.8,11.7 9.8,9.4 13.2,9.4z"
26+
android:fillColor="#EA4335"/>
27+
</vector>

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,8 @@
400400

401401
<string name="prompt_title_selectPurchaseMethod">Select Purchase Method</string>
402402
<string name="action_useCashReservesWithBalance">USDF (%1$s)</string>
403+
<string name="action_debitCardWithPrefix">Debit Card with</string>
404+
<string name="action_paySuffix">Pay</string>
403405

404406
<string name="error_title_buySellFailed">Something Went Wrong</string>
405407
<string name="error_description_buySellFailed">Please try again</string>

apps/flipcash/features/balance/src/main/kotlin/com/flipcash/app/balance/internal/BalanceScreenContent.kt

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,15 @@ internal fun BalanceScreen(
4343
viewModel: BalanceViewModel,
4444
tokenViewModel: SelectTokenViewModel,
4545
) {
46-
val walletState by viewModel.stateFlow.collectAsStateWithLifecycle()
4746
val tokenState by tokenViewModel.stateFlow.collectAsStateWithLifecycle()
4847
BalanceScreenContent(
49-
walletState = walletState,
5048
tokenState = tokenState,
5149
dispatchEvent = viewModel::dispatchEvent
5250
)
5351
}
5452

5553
@Composable
5654
private fun BalanceScreenContent(
57-
walletState: BalanceViewModel.State,
5855
tokenState: SelectTokenViewModel.State,
5956
dispatchEvent: (BalanceViewModel.Event) -> Unit
6057
) {
@@ -68,20 +65,7 @@ private fun BalanceScreenContent(
6865
dispatchEvent(BalanceViewModel.Event.OpenCurrencySelection)
6966
}
7067

71-
if (walletState.quickActionsEnabled) {
72-
AddCashRow(
73-
modifier = Modifier
74-
.fillMaxWidth()
75-
.padding(
76-
horizontal = CodeTheme.dimens.inset,
77-
vertical = CodeTheme.dimens.grid.x4,
78-
),
79-
onAddCash = { dispatchEvent(BalanceViewModel.Event.OnAddCashClicked) },
80-
onWithdraw = { dispatchEvent(BalanceViewModel.Event.OnWithdrawClicked) },
81-
)
82-
} else {
83-
Spacer(modifier = Modifier.padding(CodeTheme.dimens.grid.x2))
84-
}
68+
Spacer(modifier = Modifier.padding(CodeTheme.dimens.grid.x2))
8569

8670
val tokens = remember(tokenState.tokens) { tokenState.tokens }
8771

@@ -188,7 +172,6 @@ private fun Preview_BalanceScreen_Empty() {
188172
) {
189173
Box(modifier = Modifier.background(CodeTheme.colors.background)) {
190174
BalanceScreenContent(
191-
walletState = BalanceViewModel.State(),
192175
tokenState = SelectTokenViewModel.State(
193176
purpose = TokenPurpose.Balance,
194177
tokens = emptyList()

apps/flipcash/features/balance/src/main/kotlin/com/flipcash/app/balance/internal/BalanceViewModel.kt

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,19 @@ import javax.inject.Inject
2727
@HiltViewModel
2828
internal class BalanceViewModel @Inject constructor(
2929
userManager: UserManager,
30-
onrampController: OnRampAmountController,
31-
analytics: FlipcashAnalyticsService,
3230
) : BaseViewModel2<BalanceViewModel.State, BalanceViewModel.Event>(
3331
initialState = State(),
3432
updateStateForEvent = updateStateForEvent
3533
) {
3634
data class State(
3735
val preferredOnRampProvider: OnRampProvider? = null,
38-
val quickActionsEnabled: Boolean = false,
3936
)
4037

4138
sealed interface Event {
4239
data class OnPreferredOnRampProviderChanged(val provider: OnRampProvider?) : Event
4340

4441
data object OpenCurrencySelection : Event
4542

46-
data object OnAddCashClicked : Event
47-
data object OpenOnRampAmountModal : Event
48-
data object OnWithdrawClicked : Event
4943
data class OpenScreen(val screen: AppRoute) : Event
5044
}
5145

@@ -58,45 +52,6 @@ internal class BalanceViewModel @Inject constructor(
5852
dispatchEvent(Event.OnPreferredOnRampProviderChanged(provider))
5953
}
6054
.launchIn(viewModelScope)
61-
62-
eventFlow
63-
.filterIsInstance<Event.OnAddCashClicked>()
64-
.onEach {
65-
analytics.openOnramp(Analytics.OnrampSource.Balance)
66-
val provider = stateFlow.value.preferredOnRampProvider
67-
if (provider is OnRampProvider.Coinbase && provider.type == OnRampType.Virtual) {
68-
// has coinbase provider supporting google pay - pop selection for quick add
69-
dispatchEvent(Event.OpenOnRampAmountModal)
70-
}
71-
}.launchIn(viewModelScope)
72-
73-
eventFlow
74-
.filterIsInstance<Event.OnWithdrawClicked>()
75-
.onEach {
76-
dispatchEvent(
77-
Event.OpenScreen(
78-
AppRoute.Sheets.TokenSelection(TokenPurpose.Withdraw)
79-
)
80-
)
81-
}.launchIn(viewModelScope)
82-
83-
eventFlow
84-
.filterIsInstance<Event.OpenOnRampAmountModal>()
85-
.map { onrampController.requestAmountSelection(OnRampProvider.Coinbase(OnRampType.Virtual)) }
86-
.flatMapLatest {
87-
onrampController.confirmationEvents.take(1)
88-
}.onEach { event ->
89-
when (event) {
90-
is ConfirmationEvent.OnConfirmationSuccess -> {
91-
when (event.amount) {
92-
OnRampAmount.Custom -> dispatchEvent(Event.OpenScreen(AppRoute.OnRamp.AmountEntry))
93-
is OnRampAmount.Predefined -> Unit
94-
}
95-
}
96-
97-
ConfirmationEvent.Cancelled -> Unit
98-
}
99-
}.launchIn(viewModelScope)
10055
}
10156

10257
internal companion object {
@@ -106,10 +61,6 @@ internal class BalanceViewModel @Inject constructor(
10661
is Event.OnPreferredOnRampProviderChanged -> { state ->
10762
state.copy(preferredOnRampProvider = event.provider)
10863
}
109-
110-
Event.OnAddCashClicked -> { state -> state }
111-
Event.OpenOnRampAmountModal -> { state -> state }
112-
Event.OnWithdrawClicked -> { state -> state }
11364
is Event.OpenScreen -> { state -> state }
11465
}
11566
}

apps/flipcash/features/cash/src/main/kotlin/com/flipcash/app/cash/internal/CashScreenViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ internal class CashScreenViewModel @Inject constructor(
343343
when (event) {
344344
is ConfirmationEvent.OnConfirmationSuccess -> {
345345
when (event.amount) {
346-
OnRampAmount.Custom -> dispatchEvent(Event.OpenScreen(AppRoute.OnRamp.AmountEntry))
346+
OnRampAmount.Custom -> dispatchEvent(Event.OpenScreen(AppRoute.OnRamp.AmountEntry()))
347347
is OnRampAmount.Predefined -> Unit
348348
}
349349
}

apps/flipcash/features/contact-verification/src/main/kotlin/com/flipcash/app/contact/verification/VerificationFlowScreen.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.flipcash.app.contact.verification
22

3-
import android.content.Context
43
import androidx.compose.animation.AnimatedContent
54
import androidx.compose.animation.slideInHorizontally
65
import androidx.compose.animation.slideOutHorizontally
@@ -205,7 +204,7 @@ private fun buildStartingScreens(
205204
emailVerificationCode: String?,
206205
): List<VerificationInternalScreen> {
207206
if (includePhone && includeEmail) {
208-
return listOf(VerificationInternalScreen.Intro(origin is AppRoute.OnRamp.ProviderList))
207+
return listOf(VerificationInternalScreen.Intro(origin is AppRoute.OnRamp.AmountEntry))
209208
}
210209
if (includePhone) {
211210
return listOf(VerificationInternalScreen.PhoneEntry)

apps/flipcash/features/menu/src/main/kotlin/com/flipcash/app/menu/internal/MenuScreenViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ internal class MenuScreenViewModel @Inject constructor(
157157
when (event) {
158158
is ConfirmationEvent.OnConfirmationSuccess -> {
159159
when (event.amount) {
160-
OnRampAmount.Custom -> dispatchEvent(Event.OpenScreen(AppRoute.OnRamp.AmountEntry))
160+
OnRampAmount.Custom -> dispatchEvent(Event.OpenScreen(AppRoute.OnRamp.AmountEntry()))
161161
is OnRampAmount.Predefined -> Unit
162162
}
163163
}

0 commit comments

Comments
 (0)