diff --git a/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt b/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt index 7b23e8b09..a0f5c628e 100644 --- a/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt +++ b/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt @@ -96,6 +96,7 @@ fun appEntryProvider( // Sheets (inner content — wrapped in Main.Sheet by navigateTo()) annotatedEntry { key -> CashScreen(key.mint, key.fromTokenInfo) } + annotatedEntry { } annotatedEntry { key -> TokenSelectScreen(key.purpose) } annotatedEntry { BalanceScreen() } annotatedEntry { ShareAppScreen() } diff --git a/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt b/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt index 75e154124..3eb8d4d8a 100644 --- a/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt +++ b/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt @@ -110,6 +110,9 @@ sealed interface AppRoute : NavKey, Parcelable { data class TokenSelection(val purpose: TokenPurpose) : Sheets @Serializable data class Give(val mint: Mint? = null, val fromTokenInfo: Boolean = false) : Sheets + + @Serializable + data object Send: Sheets @Serializable data object Wallet : Sheets @Serializable diff --git a/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/navigation/NavBarButton.kt b/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/navigation/NavBarButton.kt index df7647e53..27a910bf3 100644 --- a/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/navigation/NavBarButton.kt +++ b/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/navigation/NavBarButton.kt @@ -4,9 +4,10 @@ enum class NavBarButton { Give, Wallet, Discover, + Send, ; companion object { - val defaultOrder = listOf(Give, Wallet, Discover) + val defaultOrder = listOf(Discover, Give, Send, Wallet,) } } diff --git a/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/ui/NavigationBar.kt b/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/ui/NavigationBar.kt index e086cfdd5..7c46a3ec2 100644 --- a/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/ui/NavigationBar.kt +++ b/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/ui/NavigationBar.kt @@ -132,6 +132,14 @@ fun NavigationBar( badgeCount = 0, onClick = { onButtonClick(NavBarButton.Discover) } ) + + NavBarButton.Send -> BottomBarAction( + modifier = buttonModifier, + label = stringResource(R.string.action_send), + painter = painterResource(R.drawable.ic_send_outlined), + badgeCount = 0, + onClick = { onButtonClick(NavBarButton.Send) } + ) } } } diff --git a/apps/flipcash/core/src/main/res/values/strings.xml b/apps/flipcash/core/src/main/res/values/strings.xml index 2282dab20..02f489531 100644 --- a/apps/flipcash/core/src/main/res/values/strings.xml +++ b/apps/flipcash/core/src/main/res/values/strings.xml @@ -376,6 +376,7 @@ You Receive Give + Send Transaction History Transaction History Market Cap diff --git a/apps/flipcash/features/direct-send/.gitignore b/apps/flipcash/features/direct-send/.gitignore new file mode 100644 index 000000000..9f2a07880 --- /dev/null +++ b/apps/flipcash/features/direct-send/.gitignore @@ -0,0 +1,2 @@ +build/ +.gradle/ diff --git a/apps/flipcash/features/direct-send/build.gradle.kts b/apps/flipcash/features/direct-send/build.gradle.kts new file mode 100644 index 000000000..961c145ab --- /dev/null +++ b/apps/flipcash/features/direct-send/build.gradle.kts @@ -0,0 +1,24 @@ +plugins { + alias(libs.plugins.flipcash.android.feature) +} + +android { + namespace = "${Gradle.flipcashNamespace}.features.directsend" +} + +dependencies { + testImplementation(kotlin("test")) + testImplementation(libs.bundles.unit.testing) + testImplementation(libs.mockito.kotlin) + testImplementation(libs.robolectric) + testImplementation(project(":libs:test-utils")) + + implementation(libs.kotlin.stdlib) + implementation(project(":apps:flipcash:shared:analytics")) + implementation(project(":apps:flipcash:shared:session")) + implementation(project(":apps:flipcash:shared:tokens")) + implementation(project(":libs:datetime")) + implementation(project(":libs:logging")) + implementation(project(":libs:messaging")) + implementation(project(":libs:permissions:bindings")) +} diff --git a/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/accesskey/AccessKeyScreen.kt b/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/accesskey/AccessKeyScreen.kt index 51d89cdfe..77a012f55 100644 --- a/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/accesskey/AccessKeyScreen.kt +++ b/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/accesskey/AccessKeyScreen.kt @@ -12,13 +12,11 @@ import com.flipcash.app.login.internal.AccessKeyScreen import com.flipcash.features.login.R import com.getcode.navigation.core.LocalCodeNavigator import com.getcode.ui.components.AppBarWithTitle -import com.getcode.util.permissions.rememberNotificationPermission @Composable fun AccessKeyScreen() { val viewModel = hiltViewModel() val navigator = LocalCodeNavigator.current - val notificationPermissions = rememberNotificationPermission() Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, @@ -33,11 +31,21 @@ fun AccessKeyScreen() { if (requiresIap) { navigator.push(AppRoute.Onboarding.Purchase()) } else { - if (notificationPermissions.isPermanentlyDenied) { - navigator.push(AppRoute.Onboarding.NotificationPermissionRationale(true)) + val target = if (viewModel.isPhoneNumberSendEnabled) { + AppRoute.Onboarding.ContactPermission(postCreate = true) } else { - navigator.push(AppRoute.Onboarding.NotificationPermission(true)) + AppRoute.Onboarding.NotificationPermission(postCreate = true) } + + navigator.push( + AppRoute.Verification( + origin = AppRoute.Onboarding.AccessKey, + includePhone = true, + includeEmail = false, + target = target, + fullScreen = true, + ) + ) } } } diff --git a/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/accesskey/LoginAccessKeyViewModel.kt b/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/accesskey/LoginAccessKeyViewModel.kt index 7c545c92d..6edc6b0dc 100644 --- a/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/accesskey/LoginAccessKeyViewModel.kt +++ b/apps/flipcash/features/login/src/main/kotlin/com/flipcash/app/login/accesskey/LoginAccessKeyViewModel.kt @@ -6,6 +6,8 @@ import com.flipcash.app.analytics.Button import com.flipcash.app.analytics.FlipcashAnalyticsService import com.flipcash.app.auth.AuthManager import com.flipcash.app.core.storage.MediaSaver +import com.flipcash.app.featureflags.FeatureFlag +import com.flipcash.app.featureflags.FeatureFlagController import com.flipcash.app.userflags.UserFlagsCoordinator import com.flipcash.services.user.UserManager import com.getcode.libs.qr.QRCodeGenerator @@ -25,10 +27,15 @@ class LoginAccessKeyViewModel @Inject constructor( mediaSaver: MediaSaver, userManager: UserManager, private val userFlags: UserFlagsCoordinator, + private val featureFlags: FeatureFlagController, private val authManager: AuthManager, private val analytics: FlipcashAnalyticsService, ): BaseAccessKeyViewModel(resources, mnemonicManager, mediaSaver, userManager, qrCodeGenerator) { + val isPhoneNumberSendEnabled: Boolean + get() = featureFlags.observe(FeatureFlag.PhoneNumberSend).value || + userFlags.resolvedFlags.value.enablePhoneNumberSend.effectiveValue + suspend fun onWroteDownInstead(): Result { trackButton(Button.WroteAccessKey) uiFlow.update { it.copy(skipState = LoadingSuccessState(loading = true)) } diff --git a/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/ScannerDecorItem.kt b/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/ScannerDecorItem.kt index 78a182089..6a776bf77 100644 --- a/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/ScannerDecorItem.kt +++ b/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/ScannerDecorItem.kt @@ -10,4 +10,5 @@ sealed class ScannerDecorItem(val screen: AppRoute) { data object Menu : ScannerDecorItem(AppRoute.Sheets.Menu) data object Logo: ScannerDecorItem(AppRoute.Sheets.ShareApp) data object Discover: ScannerDecorItem(AppRoute.Token.Discovery) + data object Send: ScannerDecorItem(AppRoute.Sheets.Send) } \ No newline at end of file diff --git a/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/ui/components/DecorView.kt b/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/ui/components/DecorView.kt index 25690a041..681cc38ac 100644 --- a/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/ui/components/DecorView.kt +++ b/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/ui/components/DecorView.kt @@ -58,9 +58,9 @@ internal fun DecorView( state: SessionState, billState: BillState, isPaused: Boolean, + modifier: Modifier = Modifier, isPinching: Boolean = false, zoomRatio: Float = 1f, - modifier: Modifier = Modifier, onAction: (ScannerDecorItem) -> Unit, ) { val billPlayground = LocalBillPlaygroundController.current diff --git a/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/ui/components/ScannerNavigationBar.kt b/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/ui/components/ScannerNavigationBar.kt index c2dc068bb..0fa687779 100644 --- a/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/ui/components/ScannerNavigationBar.kt +++ b/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/ui/components/ScannerNavigationBar.kt @@ -31,9 +31,14 @@ internal fun ScannerNavigationBar( NavBarConfig.deserialize(navBarConfigString) } + val effectiveConfig = remember(config, state.isPhoneNumberSendEnabled) { + if (state.isPhoneNumberSendEnabled) config + else config.copy(order = config.order.filter { it != NavBarButton.Send }) + } + NavigationBar( modifier = modifier, - config = config, + config = effectiveConfig, state = NavigationBarState( notificationUnreadCount = state.notificationUnreadCount, showToast = billState.showToast && billState.toast != null, @@ -45,6 +50,7 @@ internal fun ScannerNavigationBar( NavBarButton.Give -> ScannerDecorItem.Give NavBarButton.Wallet -> ScannerDecorItem.Wallet NavBarButton.Discover -> ScannerDecorItem.Discover + NavBarButton.Send -> ScannerDecorItem.Send } onAction(item) }, diff --git a/apps/flipcash/features/userflags/src/main/kotlin/com/flipcash/app/userflags/internal/UserFlagsViewModel.kt b/apps/flipcash/features/userflags/src/main/kotlin/com/flipcash/app/userflags/internal/UserFlagsViewModel.kt index 5f68994c3..9ebf55f59 100644 --- a/apps/flipcash/features/userflags/src/main/kotlin/com/flipcash/app/userflags/internal/UserFlagsViewModel.kt +++ b/apps/flipcash/features/userflags/src/main/kotlin/com/flipcash/app/userflags/internal/UserFlagsViewModel.kt @@ -45,6 +45,10 @@ internal class UserFlagsViewModel @Inject constructor( R.string.label_flag_requiresPurchaseForAccount, flags.data.requiresIapForRegistration.effectiveValue ), + ReadOnlyEntry( + R.string.label_flag_enablePhoneNumberSend, + flags.data.enablePhoneNumberSend.effectiveValue + ), ) else -> emptyList() diff --git a/apps/flipcash/shared/contacts/src/main/kotlin/com/flipcash/app/contacts/ContactCoordinator.kt b/apps/flipcash/shared/contacts/src/main/kotlin/com/flipcash/app/contacts/ContactCoordinator.kt index d93df3c72..370d4da8b 100644 --- a/apps/flipcash/shared/contacts/src/main/kotlin/com/flipcash/app/contacts/ContactCoordinator.kt +++ b/apps/flipcash/shared/contacts/src/main/kotlin/com/flipcash/app/contacts/ContactCoordinator.kt @@ -17,6 +17,7 @@ import com.flipcash.services.controllers.ResolverController import com.flipcash.services.models.CheckSyncError import com.flipcash.services.models.ContactMethod import com.flipcash.services.models.DeltaUploadError +import com.flipcash.services.models.GetContactsError import com.getcode.opencode.model.accounts.AccountCluster import com.getcode.opencode.providers.SessionListener import com.getcode.solana.keys.Checksum @@ -332,7 +333,13 @@ class ContactCoordinator @Inject constructor( _state.update { it.copy(flipcashE164s = flipcashE164s) } trace(tag = TAG, message = "Found ${flipcashE164s.size} contacts on Flipcash", type = TraceType.Process) }?.onFailure { error -> - trace(tag = TAG, message = "GetFlipcashContacts failed: ${error.message}", type = TraceType.Error) + if (error is GetContactsError.NotFound) { + dao.clearFlipcashStatus() + _state.update { it.copy(flipcashE164s = emptySet()) } + trace(tag = TAG, message = "No contacts on Flipcash yet", type = TraceType.Process) + } else { + trace(tag = TAG, message = "GetFlipcashContacts failed: ${error.message}", type = TraceType.Error) + } } } catch (e: Exception) { trace(tag = TAG, message = "GetFlipcashContacts exception: ${e.message}", error = e, type = TraceType.Error) diff --git a/apps/flipcash/shared/featureflags/src/main/kotlin/com/flipcash/app/featureflags/FeatureFlag.kt b/apps/flipcash/shared/featureflags/src/main/kotlin/com/flipcash/app/featureflags/FeatureFlag.kt index e64b02724..64e3b444e 100644 --- a/apps/flipcash/shared/featureflags/src/main/kotlin/com/flipcash/app/featureflags/FeatureFlag.kt +++ b/apps/flipcash/shared/featureflags/src/main/kotlin/com/flipcash/app/featureflags/FeatureFlag.kt @@ -179,6 +179,15 @@ sealed interface FeatureFlag { override val persistLogOut: Boolean = true } + @FeatureFlagMarker + data object PhoneNumberSend : FeatureFlag { + override val key: String = "phone_number_send_enabled" + override val default: Boolean = false + override val launched: Boolean = false + override val visible: Boolean = true + override val persistLogOut: Boolean = true + } + @FeatureFlagMarker data object NavBar : FeatureFlag { override val key: String = "nav_bar_config" @@ -219,6 +228,7 @@ val FeatureFlag<*>.title: String FeatureFlag.DepositUsdc -> "Deposit USDC" FeatureFlag.BackgroundReset -> "Background Reset" FeatureFlag.ContactPickerMode -> "Contact Picker Mode" + FeatureFlag.PhoneNumberSend -> "Phone Number Send" FeatureFlag.NavBar -> "Navigation Bar" } @@ -241,6 +251,7 @@ val FeatureFlag<*>.message: String FeatureFlag.DepositUsdc -> "When enabled, you'll gain the ability to deposit USDC directly from any external wallet app instead of purchasing a currency first and sell" FeatureFlag.BackgroundReset -> "Automatically returns the app to the camera screen after a period of inactivity with the app in the background" FeatureFlag.ContactPickerMode -> "When enabled, contacts will be accessed via the system contact picker instead of requesting full READ_CONTACTS permission" + FeatureFlag.PhoneNumberSend -> "When enabled, you'll gain the ability to send cash directly to contacts via phone number" FeatureFlag.NavBar -> "Customize the order and labels of navigation bar buttons" } diff --git a/apps/flipcash/shared/session/src/main/kotlin/com/flipcash/app/session/SessionController.kt b/apps/flipcash/shared/session/src/main/kotlin/com/flipcash/app/session/SessionController.kt index f073c1af7..c808fcffa 100644 --- a/apps/flipcash/shared/session/src/main/kotlin/com/flipcash/app/session/SessionController.kt +++ b/apps/flipcash/shared/session/src/main/kotlin/com/flipcash/app/session/SessionController.kt @@ -44,6 +44,7 @@ data class SessionState( val isRemoteSendLoading: Boolean = false, val notificationUnreadCount: Int = 0, val tokens: List = emptyList(), + val isPhoneNumberSendEnabled: Boolean = false, ) val LocalSessionController = staticCompositionLocalOf { null } \ No newline at end of file diff --git a/apps/flipcash/shared/session/src/main/kotlin/com/flipcash/app/session/internal/RealSessionController.kt b/apps/flipcash/shared/session/src/main/kotlin/com/flipcash/app/session/internal/RealSessionController.kt index 228d127ae..6592f49ea 100644 --- a/apps/flipcash/shared/session/src/main/kotlin/com/flipcash/app/session/internal/RealSessionController.kt +++ b/apps/flipcash/shared/session/src/main/kotlin/com/flipcash/app/session/internal/RealSessionController.kt @@ -63,6 +63,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -196,6 +197,13 @@ class RealSessionController @Inject constructor( _state.update { it.copy(tokens = tokens) } }.launchIn(scope) + combine( + featureFlagController.observe(FeatureFlag.PhoneNumberSend), + userManager.state.map { it.flags?.enablePhoneNumberSend == true } + ) { beta, server -> beta || server } + .onEach { enabled -> _state.update { it.copy(isPhoneNumberSendEnabled = enabled) } } + .launchIn(scope) + // Retry updateUserFlags when network is restored networkObserver.state .map { it.connected } diff --git a/apps/flipcash/shared/session/src/test/kotlin/com/flipcash/app/session/internal/SessionControllerGiftCardErrorTest.kt b/apps/flipcash/shared/session/src/test/kotlin/com/flipcash/app/session/internal/SessionControllerGiftCardErrorTest.kt index 86eb8055f..a2410ab74 100644 --- a/apps/flipcash/shared/session/src/test/kotlin/com/flipcash/app/session/internal/SessionControllerGiftCardErrorTest.kt +++ b/apps/flipcash/shared/session/src/test/kotlin/com/flipcash/app/session/internal/SessionControllerGiftCardErrorTest.kt @@ -108,10 +108,11 @@ class SessionControllerGiftCardErrorTest { toastController = mockk(relaxed = true), billingClient = mockk(relaxed = true), tokenCoordinator = tokenCoordinator, + contactCoordinator = mockk(relaxed = true), featureFlagController = mockk(relaxed = true), analytics = analytics, - appSettingsCoordinator = mockk(relaxed = true), usdcSweep = mockk(relaxed = true), + appSettingsCoordinator = mockk(relaxed = true), ) } diff --git a/apps/flipcash/shared/userflags/src/main/kotlin/com/flipcash/app/userflags/ResolvedUserFlags.kt b/apps/flipcash/shared/userflags/src/main/kotlin/com/flipcash/app/userflags/ResolvedUserFlags.kt index 616ef6ab9..42903fc14 100644 --- a/apps/flipcash/shared/userflags/src/main/kotlin/com/flipcash/app/userflags/ResolvedUserFlags.kt +++ b/apps/flipcash/shared/userflags/src/main/kotlin/com/flipcash/app/userflags/ResolvedUserFlags.kt @@ -31,6 +31,7 @@ data class ResolvedUserFlags( val newCurrencyFeeAmount: ResolvedFlag, val withdrawalFeeAmount: ResolvedFlag, val usdcOnRampLiquidityPool: ResolvedFlag, + val enablePhoneNumberSend: ResolvedFlag, ) internal fun UserFlags.resolve(overrides: Overrides): ResolvedUserFlags = ResolvedUserFlags( @@ -44,5 +45,6 @@ internal fun UserFlags.resolve(overrides: Overrides): ResolvedUserFlags = Resolv newCurrencyPurchaseAmount = ResolvedFlag(newCurrencyPurchaseAmount, overrides.newCurrencyPurchaseAmount), newCurrencyFeeAmount = ResolvedFlag(newCurrencyFeeAmount, overrides.newCurrencyPurchaseAmount), withdrawalFeeAmount = ResolvedFlag(withdrawalFeeAmount, overrides.withdrawalFeeAmount), - usdcOnRampLiquidityPool = ResolvedFlag(preferredUsdcOnRampLiquidityPool, overrides.preferredUsdcOnRampLiquidityPool) + usdcOnRampLiquidityPool = ResolvedFlag(preferredUsdcOnRampLiquidityPool, overrides.preferredUsdcOnRampLiquidityPool), + enablePhoneNumberSend = ResolvedFlag(enablePhoneNumberSend, FieldOverride.None), ) \ No newline at end of file diff --git a/apps/flipcash/shared/userflags/src/main/res/values/strings.xml b/apps/flipcash/shared/userflags/src/main/res/values/strings.xml index f6137bcd3..2ac0fba1d 100644 --- a/apps/flipcash/shared/userflags/src/main/res/values/strings.xml +++ b/apps/flipcash/shared/userflags/src/main/res/values/strings.xml @@ -17,4 +17,5 @@ Withdrawal Fee Amount Enter amount Preferred USDC On-Ramp Liquidity Pool + Phone Number Send Enabled \ No newline at end of file diff --git a/definitions/flipcash/protos/src/main/proto/account/v1/flipcash_account_service.proto b/definitions/flipcash/protos/src/main/proto/account/v1/flipcash_account_service.proto index 7f8e6b247..3e8f225a2 100644 --- a/definitions/flipcash/protos/src/main/proto/account/v1/flipcash_account_service.proto +++ b/definitions/flipcash/protos/src/main/proto/account/v1/flipcash_account_service.proto @@ -157,4 +157,7 @@ message UserFlags { // The preferred USDC liquidity pool for external wallet on ramp flows UsdcLiquidityPool preferred_on_ramp_usdc_liquidity_pool = 11; + + // Whether the send by phone number feature is enabled + bool enable_phone_number_send = 12; } diff --git a/definitions/flipcash/protos/src/main/proto/contact/v1/contact_list_service.proto b/definitions/flipcash/protos/src/main/proto/contact/v1/contact_list_service.proto index c78e4e273..9276a6c82 100644 --- a/definitions/flipcash/protos/src/main/proto/contact/v1/contact_list_service.proto +++ b/definitions/flipcash/protos/src/main/proto/contact/v1/contact_list_service.proto @@ -9,7 +9,6 @@ import "validate/validate.proto"; option go_package = "github.com/code-payments/flipcash2-protobuf-api/generated/go/contact/v1;contactpb"; option java_package = "com.codeinc.flipcash.gen.contact.v1"; -option objc_class_prefix = "FPBContactV1"; // ContactList manages a user's contact list and surfaces which contacts are // Flipcash users. diff --git a/definitions/flipcash/protos/src/main/proto/contact/v1/model.proto b/definitions/flipcash/protos/src/main/proto/contact/v1/model.proto index c6a62e8c0..c6f79bbd5 100644 --- a/definitions/flipcash/protos/src/main/proto/contact/v1/model.proto +++ b/definitions/flipcash/protos/src/main/proto/contact/v1/model.proto @@ -7,7 +7,6 @@ import "validate/validate.proto"; option go_package = "github.com/code-payments/flipcash2-protobuf-api/generated/go/contact/v1;contactpb"; option java_package = "com.codeinc.flipcash.gen.contact.v1"; -option objc_class_prefix = "FPBContactV1"; message FlipcashContact { phone.v1.PhoneNumber phone = 1 [(validate.rules).message.required = true]; diff --git a/services/flipcash/src/main/kotlin/com/flipcash/services/internal/domain/UserFlagsMapper.kt b/services/flipcash/src/main/kotlin/com/flipcash/services/internal/domain/UserFlagsMapper.kt index 3d8591e80..f4f123caf 100644 --- a/services/flipcash/src/main/kotlin/com/flipcash/services/internal/domain/UserFlagsMapper.kt +++ b/services/flipcash/src/main/kotlin/com/flipcash/services/internal/domain/UserFlagsMapper.kt @@ -25,7 +25,8 @@ internal class UserFlagsMapper @Inject constructor(): newCurrencyPurchaseAmount = Fiat(quarks = from.newCurrencyPurchaseAmount), newCurrencyFeeAmount = Fiat(quarks = from.newCurrencyFeeAmount), withdrawalFeeAmount = Fiat(quarks = from.withdrawalFeeAmount), - preferredUsdcOnRampLiquidityPool = from.preferredOnRampUsdcLiquidityPool.toDomain() + preferredUsdcOnRampLiquidityPool = from.preferredOnRampUsdcLiquidityPool.toDomain(), + enablePhoneNumberSend = from.enablePhoneNumberSend, ) } } diff --git a/services/flipcash/src/main/kotlin/com/flipcash/services/models/UserFlags.kt b/services/flipcash/src/main/kotlin/com/flipcash/services/models/UserFlags.kt index 6d58daddc..6a8478780 100644 --- a/services/flipcash/src/main/kotlin/com/flipcash/services/models/UserFlags.kt +++ b/services/flipcash/src/main/kotlin/com/flipcash/services/models/UserFlags.kt @@ -17,6 +17,7 @@ data class UserFlags( val newCurrencyFeeAmount: Fiat, val withdrawalFeeAmount: Fiat, val preferredUsdcOnRampLiquidityPool: UsdcLiquidtyPool, + val enablePhoneNumberSend: Boolean, ) { companion object { val Default = UserFlags( @@ -31,6 +32,7 @@ data class UserFlags( newCurrencyFeeAmount = Fiat.MAX_VALUE, withdrawalFeeAmount = Fiat.Zero, preferredUsdcOnRampLiquidityPool = UsdcLiquidtyPool.Unknown, + enablePhoneNumberSend = false, ) } } \ No newline at end of file diff --git a/services/flipcash/src/test/kotlin/com/flipcash/services/internal/domain/UserFlagsMapperTest.kt b/services/flipcash/src/test/kotlin/com/flipcash/services/internal/domain/UserFlagsMapperTest.kt index 7b76bafe3..55ac8890d 100644 --- a/services/flipcash/src/test/kotlin/com/flipcash/services/internal/domain/UserFlagsMapperTest.kt +++ b/services/flipcash/src/test/kotlin/com/flipcash/services/internal/domain/UserFlagsMapperTest.kt @@ -127,6 +127,17 @@ class UserFlagsMapperTest { assertEquals(5_000_000L, result.newCurrencyPurchaseAmount.quarks) } + @Test + fun `maps enable phone number send`() { + val proto = userFlags { + enablePhoneNumberSend = true + } + + val result = mapper.map(proto) + + assertTrue(result.enablePhoneNumberSend) + } + @Test fun `maps minimum version`() { val proto = userFlags { diff --git a/settings.gradle.kts b/settings.gradle.kts index 1c225aba7..6212ce594 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -90,6 +90,7 @@ include( ":apps:flipcash:features:deposit", ":apps:flipcash:features:advanced", ":apps:flipcash:features:currency-creator", + ":apps:flipcash:features:direct-send", ":apps:flipcash:features:device-logs", ":apps:flipcash:features:myaccount", ":apps:flipcash:features:backupkey",