Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions apps/flipcash/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ dependencies {
implementation(project(":apps:flipcash:shared:notifications"))
implementation(project(":apps:flipcash:shared:onramp:coinbase"))
implementation(project(":apps:flipcash:shared:onramp:deeplinks"))
implementation(libs.phantom.connect) {
exclude(group = "com.ionspin.kotlin", module = "multiplatform-crypto-libsodium-bindings-android-debug")
}
implementation(project(":apps:flipcash:shared:payments"))
implementation(project(":apps:flipcash:shared:permissions"))
implementation(project(":apps:flipcash:shared:phone"))
Expand Down
48 changes: 13 additions & 35 deletions apps/flipcash/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,6 @@
<action android:name="android.intent.action.VIEW" />
<data android:host="phantom.app" />
</intent>

<intent>
<action android:name="android.intent.action.VIEW" />
<data android:host="backpack.app" />
</intent>

<intent>
<action android:name="android.intent.action.VIEW" />
<data android:host="solflare.com" />
</intent>
</queries>

<application
Expand Down Expand Up @@ -82,8 +72,6 @@
<data android:pathPattern="/login.*" />
<data android:pathPattern="/token.*" />
<data android:pathPattern="/verify.*" />
<data android:pathPattern="/external/.*/connected" />
<data android:pathPattern="/external/.*/signed" />
</intent-filter>

<!-- send.flipcash.com App Links -->
Expand Down Expand Up @@ -160,29 +148,6 @@
android:scheme="https" />
</intent-filter>

<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="app.flipcash.com"
android:pathPattern="/external/.*/connected"
android:scheme="https" />
</intent-filter>

<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="app.flipcash.com"
android:pathPattern="/external/.*/signed"
android:scheme="https" />
</intent-filter>

<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
Expand Down Expand Up @@ -232,6 +197,19 @@
</intent-filter>
</activity>

<activity
android:name="dev.bmcreations.phantom.connect.wallet.PhantomWalletCallbackActivity"
android:exported="true"
android:launchMode="singleTask"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="app.flipcash.com" android:path="/phantom-wallet-callback" />
</intent-filter>
</activity>

<!--
Prompt Google Play services to install the backported photo picker module
https://developer.android.com/training/data-storage/shared/photopicker#device-availability
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.flipcash.app.auth.AuthManager
import com.flipcash.app.currency.PreferredCurrencyController
import com.getcode.opencode.repositories.EventRepository
import com.getcode.utils.trace
import dev.bmcreations.phantom.connect.PhantomSdk
import dagger.hilt.android.HiltAndroidApp
import javax.inject.Inject

Expand All @@ -41,7 +42,7 @@ class FlipcashApp : Application(), Configuration.Provider, SingletonImageLoader.

override fun onCreate() {
super.onCreate()

PhantomSdk.init(this)
authManager.init()

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import com.flipcash.app.billing.BillingClient
import com.flipcash.app.core.LocalUserManager
import com.flipcash.app.core.verification.email.EmailCodeChannel
import com.flipcash.app.core.verification.email.LocalEmailCodeChannel
import com.flipcash.app.onramp.ExternalWalletOnRampController
import com.flipcash.app.onramp.LocalExternalWalletOnRampController
import com.flipcash.app.onramp.LocalCoinbaseOnRampController
import com.flipcash.app.onramp.CoinbaseOnRampController
import com.flipcash.app.featureflags.FeatureFlagController
Expand Down Expand Up @@ -117,9 +115,6 @@ class MainActivity : FragmentActivity() {
@Inject
lateinit var emailCodeChannel: EmailCodeChannel

@Inject
lateinit var externalWalletOnRampController: ExternalWalletOnRampController

@Inject
lateinit var coinbaseOnRampController: CoinbaseOnRampController

Expand All @@ -146,7 +141,6 @@ class MainActivity : FragmentActivity() {
LocalBillPlaygroundController provides billPlaygroundController,
LocalAppUpdater provides appUpdater,
LocalEmailCodeChannel provides emailCodeChannel,
LocalExternalWalletOnRampController provides externalWalletOnRampController,
LocalCoinbaseOnRampController provides coinbaseOnRampController,
LocalUiTesting provides intent.getBooleanExtra(UI_TEST, false),
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ import com.flipcash.app.internal.ui.navigation.appEntryProvider
import com.flipcash.app.internal.ui.navigation.decorators.rememberNavBlockingOverlayEntryDecorator
import com.flipcash.app.internal.ui.navigation.decorators.rememberNavMessagingEntryDecorator
import com.flipcash.app.onramp.CoinbaseOnRampHandler
import com.flipcash.app.onramp.ExternalWalletOnRampHandler
import com.flipcash.app.onramp.LocalExternalWalletOnRampController
import com.flipcash.app.router.LocalRouter
import com.flipcash.app.session.LocalSessionController
import com.flipcash.app.theme.FlipcashTheme
Expand Down Expand Up @@ -149,7 +147,6 @@ internal fun App(
LocalScrimController provides scrimController,
LocalSharedTransitionScope provides this,
) {
ExternalWalletOnRampHandler(navigator = codeNavigator) {
CoinbaseOnRampHandler {
AppNavHost(
navigator = codeNavigator,
Expand Down Expand Up @@ -235,10 +232,8 @@ internal fun App(

ScrimOverlay(scrimController)
}
}

val emailCodeChannel = LocalEmailCodeChannel.current
val externalWalletController = LocalExternalWalletOnRampController.current
LaunchedEffect(deepLink) {
val link = deepLink ?: return@LaunchedEffect

Expand Down Expand Up @@ -267,10 +262,6 @@ internal fun App(
}
}

is DeeplinkAction.ExternalWallet -> externalWalletController.handleWalletDeeplink(
action.type
)

is DeeplinkAction.Login -> viewModel.handleLoginEntropy(
action.entropy,
onSwitchAccount = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ fun appEntryProvider(
SwapFlowScreen(route = key, resultStateRegistry = resultStateRegistry)
}
annotatedEntry<AppRoute.Token.TxProcessing> { key ->
TokenTxProcessingScreen(key.swapId, key.swapPurpose, key.amount, key.awaitExternalWallet, key.isFundingShortfall)
TokenTxProcessingScreen(key.swapId, key.swapPurpose, key.amount, key.isFundingShortfall)
}
annotatedEntry<AppRoute.Token.Discovery> { TokenDiscoveryScreen() }
annotatedEntry<AppRoute.Token.CurrencyCreator> { key ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ sealed interface AppRoute : NavKey, Parcelable {
val swapId: SwapId,
val swapPurpose: SwapPurpose? = null,
val amount: VerifiedFiat? = null,
val awaitExternalWallet: Boolean = false,
val isFundingShortfall: Boolean = false,
) : Token, NonDismissableRoute, NonDraggableRoute

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.flipcash.app.core.navigation

sealed interface DeeplinkAction {
data class Navigate(val routes: List<com.flipcash.app.core.AppRoute>) : DeeplinkAction
data class ExternalWallet(val type: DeeplinkType) : DeeplinkAction
data class Login(val entropy: String) : DeeplinkAction
data class OpenCashLink(val entropy: String) : DeeplinkAction
data object None : DeeplinkAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@ package com.flipcash.app.core.navigation

import android.net.Uri
import android.os.Parcelable
import com.flipcash.app.core.onramp.deeplinks.WalletDeeplinkConnectionResult
import com.flipcash.app.core.onramp.deeplinks.ExternalWalletDeeplinkError
import com.flipcash.app.core.onramp.deeplinks.OnRampDeeplinkOrigin
import com.flipcash.app.core.onramp.deeplinks.WalletDeeplinkSigningResult
import com.getcode.ed25519.Ed25519
import com.getcode.solana.keys.Mint
import com.getcode.vendor.Base58
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable

Expand All @@ -21,24 +15,6 @@ sealed interface DeeplinkType: Parcelable {

@Serializable data class TokenInfo(val mint: Mint): DeeplinkType, Navigatable

sealed interface ExternalWalletStep {
val origin: OnRampDeeplinkOrigin
}

@Serializable
data class ExternalWalletConnection(
override val origin: OnRampDeeplinkOrigin,
val result: WalletDeeplinkConnectionResult?,
val error: ExternalWalletDeeplinkError? = null
): DeeplinkType, ExternalWalletStep, Navigatable

@Serializable
data class ExternalWalletSignedTransaction(
override val origin: OnRampDeeplinkOrigin,
val result: WalletDeeplinkSigningResult?,
val error: ExternalWalletDeeplinkError? = null
): DeeplinkType, ExternalWalletStep, Navigatable

@Serializable
data class EmailVerification(
val email: String,
Expand Down Expand Up @@ -88,4 +64,4 @@ sealed interface Key {
}

private operator fun Regex.contains(text: String?): Boolean =
text?.let { this.matches(it) } ?: false
text?.let { this.matches(it) } ?: false
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@
package com.flipcash.app.core.onramp.deeplinks

import android.os.Parcelable
import com.flipcash.app.core.AppRoute
import com.getcode.ed25519.Ed25519
import com.getcode.opencode.model.core.ID
import com.getcode.opencode.utils.base64
import com.getcode.opencode.utils.base64UrlSafe
import com.getcode.solana.keys.Mint
import com.getcode.solana.keys.PublicKey
import com.getcode.solana.keys.base58
import com.getcode.utils.base58
import com.getcode.utils.decodeBase58
import com.getcode.utils.decodeBase64
import com.getcode.utils.serializer.ByteListAsBase64Serializer
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand All @@ -31,101 +20,3 @@ data class ExternallySignedTransaction(
@SerialName("transaction")
val serializedTransaction: String,
): Parcelable

@Serializable
@Parcelize
sealed class OnRampDeeplinkOrigin: Parcelable {
@Serializable @Parcelize
data object Menu : OnRampDeeplinkOrigin()

@Serializable @Parcelize
data class Give(val tokenAddress: Mint?) : OnRampDeeplinkOrigin()

@Serializable @Parcelize
data object Wallet: OnRampDeeplinkOrigin()

@Serializable @Parcelize
data class TokenInfo(val mint: Mint): OnRampDeeplinkOrigin()

@Serializable @Parcelize
data object Reserves: OnRampDeeplinkOrigin()

@Serializable @Parcelize
data object CurrencyCreator: OnRampDeeplinkOrigin()


fun forUri(): String {
return when(this) {
Menu -> "menu"
is Give -> "give-${tokenAddress?.base58()?.base64UrlSafe}"
Wallet -> "wallet"
is TokenInfo -> "token-${mint.base58().base64UrlSafe}"
Reserves -> "reserves"
CurrencyCreator -> "currency-creator"
}.lowercase()
}

companion object Companion {
fun fromRoute(route: AppRoute?): OnRampDeeplinkOrigin? {
return when (route) {
is AppRoute.Sheets.Menu -> Menu
is AppRoute.Sheets.Give -> Give(route.mint)
is AppRoute.Sheets.Wallet -> Wallet
is AppRoute.Token.Info -> {
if (route.mint == Mint.usdf) Reserves else TokenInfo(route.mint)
}
is AppRoute.Token.CurrencyCreator -> CurrencyCreator

else -> null
}
}

fun fromString(value: String?): OnRampDeeplinkOrigin? {
return when {
value == "menu" -> Menu
value?.startsWith("give-") == true -> {
val tokenAddress = value.removePrefix("give-").decodeBase64().base58
val mint = runCatching {
Mint(tokenAddress)
}.getOrNull() ?: return null
Give(mint)
}
value == "wallet" -> Wallet
value == "reserves" -> Reserves
value == "currency-creator" -> CurrencyCreator
value?.startsWith("token-") == true -> {
val mintString = value.removePrefix("token-").decodeBase64().base58
val mint = runCatching {
Mint(mintString)
}.onFailure { it.printStackTrace() }.getOrNull() ?: return null

TokenInfo(mint)
}

else -> return null
}
}
}
}

@Serializable
@Parcelize
data class WalletDeeplinkConnectionResult(
@Serializable(with = ByteListAsBase64Serializer::class) val encryptionPublicKey: List<Byte>,
@Serializable(with = ByteListAsBase64Serializer::class) val nonce: List<Byte>,
@Serializable(with = ByteListAsBase64Serializer::class) val encryptedData: List<Byte>
): Parcelable

@Serializable
@Parcelize
data class WalletDeeplinkSigningResult(
@Serializable(with = ByteListAsBase64Serializer::class) val nonce: List<Byte>,
@Serializable(with = ByteListAsBase64Serializer::class) val encryptedData: List<Byte>,
): Parcelable

@Serializable
@Parcelize
data class ExternalWalletDeeplinkError(
val errorCode: String,
val errorMessage: String,
): Parcelable
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@ import androidx.compose.foundation.text.appendInlineContent
import androidx.compose.material.ButtonColors
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
Expand All @@ -36,9 +33,7 @@ fun buildExternalWalletButtonLabel(
colors: ButtonColors = ButtonState.Filled.colors(),
): AnnotatedButtonLabel {
val (title, icon) = when (provider) {
OnRampProvider.Backpack -> stringResource(R.string.label_backpack) to painterResource(R.drawable.ic_backpack_wallet)
OnRampProvider.Phantom -> stringResource(R.string.label_phantom) to painterResource(R.drawable.ic_phantom_wallet)
OnRampProvider.Solflare -> stringResource(R.string.label_solflare) to painterResource(R.drawable.ic_solflare_wallet)
}

val currentIsEnabled by rememberUpdatedState(isEnabled)
Expand Down Expand Up @@ -74,4 +69,4 @@ fun buildExternalWalletButtonLabel(
}
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,5 @@ sealed interface SwapStep : FlowStep, Parcelable {
@Serializable
data class Processing(
val swapId: SwapId,
val awaitExternalWallet: Boolean = false,
) : SwapStep, NonDismissableRoute, NonDraggableRoute
}
Loading
Loading