Skip to content

Commit 12e3e45

Browse files
committed
refactor(onramp): consolidate external wallet onramp into single controller
Merge ExternalWalletOnRampManager into ExternalWalletOnRampController to align with the app-wide pattern of a single @ActivityRetainedScoped controller provided via CompositionLocal from MainActivity. Remove ViewModel intermediary for service provision and simplify Handler to take a single controller param.
1 parent f69c521 commit 12e3e45

18 files changed

Lines changed: 1035 additions & 978 deletions

File tree

apps/flipcash/app/src/main/kotlin/com/flipcash/app/MainActivity.kt

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ import com.flipcash.app.appsettings.LocalAppSettings
1616
import com.flipcash.app.bill.customization.BillPlaygroundController
1717
import com.flipcash.app.bill.customization.LocalBillPlaygroundController
1818
import com.flipcash.app.billing.BillingClient
19-
import com.flipcash.app.billing.LocalBillingClient
2019
import com.flipcash.app.core.LocalUserManager
2120
import com.flipcash.app.core.verification.email.EmailCodeChannel
2221
import com.flipcash.app.core.verification.email.LocalEmailCodeChannel
22+
import com.flipcash.app.onramp.ExternalWalletOnRampController
23+
import com.flipcash.app.onramp.LocalExternalWalletOnRampController
2324
import com.flipcash.app.featureflags.FeatureFlagController
2425
import com.flipcash.app.featureflags.LocalFeatureFlags
2526
import com.flipcash.app.internal.ui.App
@@ -36,10 +37,7 @@ import com.flipcash.app.updates.LocalAppUpdater
3637
import com.flipcash.services.user.UserManager
3738
import com.getcode.libs.analytics.LocalAnalytics
3839
import com.getcode.opencode.compose.LocalExchange
39-
import com.getcode.opencode.compose.LocalTransactionController
40-
import com.getcode.opencode.controllers.TransactionController
4140
import com.getcode.opencode.exchange.Exchange
42-
import com.getcode.solana.rpc.RpcConfig
4341
import com.getcode.ui.testing.LocalUiTesting
4442
import com.getcode.util.permissions.PermissionChecker
4543
import com.getcode.util.permissions.ProvidePermissionChecker
@@ -49,8 +47,6 @@ import com.getcode.util.resources.ResourceHelper
4947
import com.getcode.util.resources.SettingsHelper
5048
import com.getcode.util.vibration.LocalVibrator
5149
import com.getcode.util.vibration.Vibrator
52-
import com.getcode.utils.CurrencyUtils
53-
import com.getcode.utils.LocalCurrencyUtils
5450
import com.getcode.utils.network.LocalNetworkObserver
5551
import com.getcode.utils.network.NetworkConnectivityListener
5652
import dagger.hilt.android.AndroidEntryPoint
@@ -74,9 +70,6 @@ class MainActivity : FragmentActivity() {
7470
@Inject
7571
lateinit var networkObserver: NetworkConnectivityListener
7672

77-
@Inject
78-
lateinit var currencyUtils: CurrencyUtils
79-
8073
@Inject
8174
lateinit var vibrator: Vibrator
8275

@@ -110,9 +103,6 @@ class MainActivity : FragmentActivity() {
110103
@Inject
111104
lateinit var analytics: FlipcashAnalyticsService
112105

113-
@Inject
114-
lateinit var solanaRpcConfig: RpcConfig
115-
116106
@Inject
117107
lateinit var phoneUtils: PhoneUtils
118108

@@ -123,10 +113,10 @@ class MainActivity : FragmentActivity() {
123113
lateinit var appUpdater: AppUpdateController
124114

125115
@Inject
126-
lateinit var transactionController: TransactionController
116+
lateinit var emailCodeChannel: EmailCodeChannel
127117

128118
@Inject
129-
lateinit var emailCodeChannel: EmailCodeChannel
119+
lateinit var externalWalletOnRampController: ExternalWalletOnRampController
130120

131121
override fun onCreate(savedInstanceState: Bundle?) {
132122
super.onCreate(savedInstanceState)
@@ -140,27 +130,24 @@ class MainActivity : FragmentActivity() {
140130
LocalNetworkObserver provides networkObserver,
141131
LocalExchange provides exchange,
142132
LocalAnalytics provides analytics,
143-
LocalCurrencyUtils provides currencyUtils,
144133
LocalVibrator provides vibrator,
145134
LocalRouter provides router,
146135
LocalUserManager provides userManager,
147136
LocalSessionController provides sessionController,
148-
LocalBillingClient provides billing,
149137
LocalShareController provides shareController,
150138
LocalAppSettings provides appSettingsCoordinator,
151139
LocalFeatureFlags provides featureFlagController,
152-
LocalTransactionController provides transactionController,
153140
LocalPhoneUtils provides phoneUtils,
154141
LocalBillPlaygroundController provides billPlaygroundController,
155142
LocalAppUpdater provides appUpdater,
156143
LocalEmailCodeChannel provides emailCodeChannel,
144+
LocalExternalWalletOnRampController provides externalWalletOnRampController,
157145
LocalUiTesting provides intent.getBooleanExtra(UI_TEST, false),
158146
) {
159147
ProvidePermissionChecker(permissionChecker) {
160148
Rinku {
161149
App(
162150
tipsEngine = tipsEngine,
163-
solanaRpcConfig = solanaRpcConfig,
164151
)
165152
}
166153
}

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

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import androidx.compose.ui.semantics.semantics
2424
import androidx.compose.ui.semantics.testTagsAsResourceId
2525
import androidx.compose.ui.unit.dp
2626
import androidx.lifecycle.Lifecycle
27-
import androidx.lifecycle.compose.LocalLifecycleOwner
2827
import androidx.lifecycle.compose.collectAsStateWithLifecycle
2928
import androidx.navigation3.runtime.NavBackStack
3029
import androidx.navigation3.runtime.NavKey
@@ -42,8 +41,7 @@ import com.flipcash.app.internal.ui.navigation.decorators.rememberNavBlockingOve
4241
import com.flipcash.app.internal.ui.navigation.decorators.rememberNavMessagingEntryDecorator
4342
import com.flipcash.app.onramp.CoinbaseOnRampHandler
4443
import com.flipcash.app.onramp.ExternalWalletOnRampHandler
45-
import com.flipcash.app.onramp.LocalExternalWalletState
46-
import com.flipcash.app.onramp.rememberExternalWalletState
44+
import com.flipcash.app.onramp.LocalExternalWalletOnRampController
4745
import com.flipcash.app.router.LocalRouter
4846
import com.flipcash.app.session.LocalSessionController
4947
import com.flipcash.app.theme.FlipcashTheme
@@ -57,7 +55,6 @@ import com.getcode.navigation.core.rememberCodeNavigator
5755
import com.getcode.navigation.extensions.getActivityScopedViewModel
5856
import com.getcode.navigation.results.rememberNavResultStateRegistry
5957
import com.getcode.navigation.scenes.ModalBottomSheetSceneStrategy
60-
import com.getcode.solana.rpc.RpcConfig
6158
import com.getcode.theme.CodeTheme
6259
import com.getcode.ui.biometrics.LocalBiometricsState
6360
import com.getcode.ui.biometrics.rememberBiometricsState
@@ -77,7 +74,6 @@ import dev.theolm.rinku.compose.ext.DeepLinkListener
7774
@Composable
7875
internal fun App(
7976
tipsEngine: TipsEngine,
80-
solanaRpcConfig: RpcConfig,
8177
) {
8278
val router = LocalRouter.current!!
8379
val analytics = rememberAnalytics()
@@ -119,13 +115,9 @@ internal fun App(
119115
)
120116

121117
val barManager = rememberBarManager()
122-
val externalWalletOnRamp = rememberExternalWalletState(solanaRpcConfig)
123118

124-
CompositionLocalProvider(
125-
LocalExternalWalletState provides externalWalletOnRamp
126-
) {
127-
BillPlaygroundScaffold {
128-
TipScaffold(tipsEngine = tipsEngine) {
119+
BillPlaygroundScaffold {
120+
TipScaffold(tipsEngine = tipsEngine) {
129121
val backStack = remember { NavBackStack<NavKey>(AppRoute.Loading) }
130122
val resultStateRegistry = rememberNavResultStateRegistry()
131123
val codeNavigator = rememberCodeNavigator(
@@ -149,8 +141,7 @@ internal fun App(
149141
LocalSharedTransitionScope provides this,
150142
) {
151143
ExternalWalletOnRampHandler(
152-
state = externalWalletOnRamp,
153-
lifecycleOwner = LocalLifecycleOwner.current,
144+
controller = LocalExternalWalletOnRampController.current,
154145
navigator = codeNavigator,
155146
) {
156147
CoinbaseOnRampHandler(
@@ -242,6 +233,7 @@ internal fun App(
242233
}
243234

244235
val emailCodeChannel = LocalEmailCodeChannel.current
236+
val externalWalletController = LocalExternalWalletOnRampController.current
245237
LaunchedEffect(deepLink) {
246238
val link = deepLink ?: return@LaunchedEffect
247239

@@ -268,7 +260,7 @@ internal fun App(
268260
}
269261
}
270262

271-
is DeeplinkAction.ExternalWallet -> externalWalletOnRamp.handleWalletDeeplink(
263+
is DeeplinkAction.ExternalWallet -> externalWalletController.handleWalletDeeplink(
272264
action.type
273265
)
274266

@@ -341,6 +333,4 @@ internal fun App(
341333
}
342334
}
343335
}
344-
}
345-
346336

apps/flipcash/features/onramp/src/main/kotlin/com/flipcash/app/onramp/OnRampCustomAmountScreen.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,12 @@ fun OnRampCustomAmountScreen(mint: Mint) {
4444
}
4545
}
4646

47-
val externalWalletOnRamp = LocalExternalWalletState.current
47+
val externalWalletOnRampController = LocalExternalWalletOnRampController.current
4848
LaunchedEffect(viewModel) {
4949
viewModel.eventFlow
5050
.filterIsInstance<OnRampViewModel.Event.CreateAndSendTransactionToWallet>()
5151
.map { it.amount }
52-
.onEach { externalWalletOnRamp.amount = it }
52+
.onEach { externalWalletOnRampController.setAmount(it) }
5353
.launchIn(this)
5454
}
5555

apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/SwapEntryContent.kt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import com.flipcash.app.core.AppRoute
1313
import com.flipcash.app.core.tokens.SwapPurpose
1414
import com.flipcash.app.core.tokens.SwapResult
1515
import com.flipcash.app.core.tokens.SwapStep
16-
import com.flipcash.app.onramp.LocalExternalWalletState
16+
import com.flipcash.app.onramp.LocalExternalWalletOnRampController
1717
import com.flipcash.app.tokens.internal.SwapEntryScreenContent
1818
import com.flipcash.app.tokens.ui.SwapViewModel
1919
import com.flipcash.features.tokens.R
@@ -32,7 +32,7 @@ internal fun SwapEntryContent(
3232
val flowNavigator = rememberFlowNavigator<SwapStep, SwapResult>()
3333
val viewModel = flowSharedViewModel<SwapViewModel>()
3434
val state by viewModel.stateFlow.collectAsStateWithLifecycle()
35-
val externalWalletOnRamp = LocalExternalWalletState.current
35+
val externalWalletOnRampController = LocalExternalWalletOnRampController.current
3636

3737
Column(
3838
modifier = Modifier.fillMaxSize(),
@@ -74,8 +74,8 @@ internal fun SwapEntryContent(
7474
viewModel.eventFlow
7575
.filterIsInstance<SwapViewModel.Event.CreateAndSendTransactionToWallet>()
7676
.onEach { (token, amount) ->
77-
externalWalletOnRamp.tokenToPurchase = token
78-
externalWalletOnRamp.amount = amount
77+
externalWalletOnRampController.setTokenToPurchase(token)
78+
externalWalletOnRampController.setAmount(amount)
7979
}.launchIn(this)
8080
}
8181

@@ -97,13 +97,13 @@ internal fun SwapEntryContent(
9797
}
9898

9999
// Navigate to pending processing step from ExternalWalletOnRampHandler
100-
val pendingNav = externalWalletOnRamp.pendingNavigation
101-
LaunchedEffect(pendingNav) {
102-
if (pendingNav is AppRoute.Token.TxProcessing) {
103-
flowNavigator.navigateTo(
104-
SwapStep.Processing(pendingNav.swapId, pendingNav.awaitExternalWallet)
105-
)
106-
externalWalletOnRamp.pendingNavigation = null
100+
LaunchedEffect(Unit) {
101+
externalWalletOnRampController.pendingNavigation.collect { nav ->
102+
if (nav is AppRoute.Token.TxProcessing) {
103+
flowNavigator.navigateTo(
104+
SwapStep.Processing(nav.swapId, nav.awaitExternalWallet)
105+
)
106+
}
107107
}
108108
}
109109
}

apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenInfoScreen.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import com.flipcash.app.analytics.Button
1515
import com.flipcash.app.analytics.rememberAnalytics
1616
import com.flipcash.app.core.AppRoute
1717
import com.flipcash.app.core.ui.TokenIconWithName
18-
import com.flipcash.app.onramp.LocalExternalWalletState
18+
import com.flipcash.app.onramp.LocalExternalWalletOnRampController
1919
import com.flipcash.app.tokens.internal.TokenInfoScreen
2020
import com.flipcash.app.tokens.ui.TokenInfoViewModel
2121
import com.flipcash.features.tokens.R
@@ -40,7 +40,7 @@ fun TokenInfoScreen(
4040
fromDeeplink: Boolean,
4141
) {
4242
val navigator = LocalCodeNavigator.current
43-
val externalWalletOnRamp = LocalExternalWalletState.current
43+
val externalWalletOnRampController = LocalExternalWalletOnRampController.current
4444

4545
Column(
4646
modifier = Modifier.fillMaxSize(),
@@ -121,17 +121,17 @@ fun TokenInfoScreen(
121121
.filterIsInstance<TokenInfoViewModel.Event.ConnectPhantomWallet>()
122122
.onEach { delay(300.scaled(animationScale)) }
123123
.onEach {
124-
externalWalletOnRamp.start(AppRoute.Token.Info(mint), OnRampProvider.Phantom)
124+
externalWalletOnRampController.start(AppRoute.Token.Info(mint), OnRampProvider.Phantom)
125125
}.launchIn(this)
126126
}
127127

128128
// Navigate to pending routes from ExternalWalletOnRampHandler using the
129129
// sheet's inner navigator (which the handler can't access directly).
130-
val pendingNav = externalWalletOnRamp.pendingNavigation
131-
LaunchedEffect(pendingNav) {
132-
if (pendingNav is AppRoute.Token.Swap) {
133-
navigator.push(pendingNav)
134-
externalWalletOnRamp.pendingNavigation = null
130+
LaunchedEffect(Unit) {
131+
externalWalletOnRampController.pendingNavigation.collect { nav ->
132+
if (nav is AppRoute.Token.Swap) {
133+
navigator.push(nav)
134+
}
135135
}
136136
}
137137
}

apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenTxProcessingScreen.kt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import androidx.hilt.navigation.compose.hiltViewModel
1212
import com.flipcash.app.core.AppRoute
1313
import com.flipcash.app.core.tokens.SwapResult
1414
import com.flipcash.app.core.tokens.SwapStep
15-
import com.flipcash.app.onramp.LocalExternalWalletState
16-
import com.flipcash.app.onramp.internal.ExternalWalletState
15+
import com.flipcash.app.onramp.ExternalWalletOnRampState
16+
import com.flipcash.app.onramp.LocalExternalWalletOnRampController
1717
import com.flipcash.app.tokens.internal.TokenTxProcessingScreen
1818
import com.flipcash.app.tokens.ui.SwapViewModel
1919
import com.flipcash.app.tokens.ui.SwapViewModel.Event
@@ -46,17 +46,17 @@ internal fun SwapProcessingContent(
4646
)
4747

4848
if (awaitExternalWallet) {
49-
val externalWalletState = LocalExternalWalletState.current
49+
val controller = LocalExternalWalletOnRampController.current
5050
LaunchedEffect(viewModel, swapId) {
51-
val terminalState = snapshotFlow { externalWalletState.deeplinkState }
52-
.firstOrNull { it == ExternalWalletState.TRANSACTED || it == ExternalWalletState.IDLE }
51+
val terminalState = controller.state
52+
.firstOrNull { it is ExternalWalletOnRampState.Transacted || it is ExternalWalletOnRampState.Idle }
5353

54-
if (terminalState != ExternalWalletState.TRANSACTED) {
54+
if (terminalState !is ExternalWalletOnRampState.Transacted) {
5555
flowNavigator.back()
5656
return@LaunchedEffect
5757
}
5858

59-
externalWalletState.reset()
59+
controller.reset()
6060
viewModel.dispatchEvent(Event.OnSwapIdChanged(swapId))
6161

6262
snapshotFlow { viewModel.stateFlow.value.processingProgress }
@@ -110,17 +110,17 @@ fun TokenTxProcessingScreen(
110110
)
111111

112112
if (awaitExternalWallet) {
113-
val externalWalletState = LocalExternalWalletState.current
113+
val controller = LocalExternalWalletOnRampController.current
114114
LaunchedEffect(viewModel, swapId) {
115-
val terminalState = snapshotFlow { externalWalletState.deeplinkState }
116-
.firstOrNull { it == ExternalWalletState.TRANSACTED || it == ExternalWalletState.IDLE }
115+
val terminalState = controller.state
116+
.firstOrNull { it is ExternalWalletOnRampState.Transacted || it is ExternalWalletOnRampState.Idle }
117117

118-
if (terminalState != ExternalWalletState.TRANSACTED) {
118+
if (terminalState !is ExternalWalletOnRampState.Transacted) {
119119
navigator.pop()
120120
return@LaunchedEffect
121121
}
122122

123-
externalWalletState.reset()
123+
controller.reset()
124124
viewModel.dispatchEvent(Event.OnSwapIdChanged(swapId))
125125

126126
snapshotFlow { viewModel.stateFlow.value.processingProgress }

apps/flipcash/shared/google-play-billing/src/main/kotlin/com/flipcash/app/billing/BillingClient.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,4 @@ object StubBillingClient: BillingClient {
6060
delay(1.seconds)
6161
_eventFlow.emit(IapPaymentEvent.OnSuccess(product.productId))
6262
}
63-
}
64-
65-
val LocalBillingClient = staticCompositionLocalOf<BillingClient> { StubBillingClient }
63+
}

0 commit comments

Comments
 (0)