diff --git a/apps/easypid/src/features/menu/FunkeAboutScreen.tsx b/apps/easypid/src/features/menu/FunkeAboutScreen.tsx
index beaf3533..b8f245e3 100644
--- a/apps/easypid/src/features/menu/FunkeAboutScreen.tsx
+++ b/apps/easypid/src/features/menu/FunkeAboutScreen.tsx
@@ -4,11 +4,22 @@ import React from 'react'
import { TextBackButton } from 'packages/app'
import { Linking } from 'react-native'
+import { useIsFunkeWallet } from '@easypid/hooks/useFeatureFlag'
import pj from '../../../package.json'
+const TEXT_FUNKE = `This app was created by Animo Solutions in the context of the SPRIN-D Funke ‘EUDI Wallet Prototypes’. It
+ serves as a prototype for future wallet providers. All code is available under Apache 2.0.`
+
+const TEXT_PARADYM =
+ 'This app was created by Animo Solutions as a companion app for Paradym. All code is available under Apache 2.0.'
+
export function FunkeAboutScreen() {
+ const isFunkeWallet = useIsFunkeWallet()
+
const openContact = () => {
- Linking.openURL('mailto:ana@animo.id?subject=Reach out from Funke EUDI Wallet')
+ Linking.openURL(
+ `mailto:ana@animo.id?subject=Reach out from ${isFunkeWallet ? 'Funke EUDI Wallet' : 'Paradym Wallet'}`
+ )
}
const openPrivacyPolicy = () => {
@@ -20,15 +31,13 @@ export function FunkeAboutScreen() {
-
- This app was created by Animo Solutions in the context of the SPRIN-D Funke ‘EUDI Wallet Prototypes’. It
- serves as a prototype for future wallet providers. All code is available under Apache 2.0.
-
+ {isFunkeWallet ? TEXT_FUNKE : TEXT_PARADYM}
- For more information on the project visit sprind.org or reach out to{' '}
+ For more information, reach out to{' '}
ana@animo.id
+ .
@@ -40,7 +49,7 @@ export function FunkeAboutScreen() {
onPress={openPrivacyPolicy}
/>
- EasyPID version: {pj.version}
+ Paradym Wallet version: {pj.version}
diff --git a/apps/easypid/src/features/menu/FunkeMenuScreen.tsx b/apps/easypid/src/features/menu/FunkeMenuScreen.tsx
index 826e1b79..135e0364 100644
--- a/apps/easypid/src/features/menu/FunkeMenuScreen.tsx
+++ b/apps/easypid/src/features/menu/FunkeMenuScreen.tsx
@@ -15,6 +15,7 @@ import {
} from '@package/ui'
import { usePidCredential } from '@easypid/hooks'
+import { useFeatureFlag } from '@easypid/hooks/useFeatureFlag'
import { useWalletReset } from '@easypid/hooks/useWalletReset'
import { TextBackButton } from '@package/app'
import { Link } from 'expo-router'
@@ -53,28 +54,31 @@ export function FunkeMenuScreen() {
const { handleScroll, isScrolledByOffset, scrollEventThrottle } = useScrollViewPosition()
const onResetWallet = useWalletReset()
const { credential } = usePidCredential()
+ const hasEidCardFeatureFlag = useFeatureFlag('EID_CARD')
- const idItem = credential ? (
-
- ) : (
-
- )
+ const idItem = hasEidCardFeatureFlag ? (
+ credential ? (
+
+ ) : (
+
+ )
+ ) : null
return (
diff --git a/apps/easypid/src/features/onboarding/onboardingContext.tsx b/apps/easypid/src/features/onboarding/onboardingContext.tsx
index 820bd686..88c55aa5 100644
--- a/apps/easypid/src/features/onboarding/onboardingContext.tsx
+++ b/apps/easypid/src/features/onboarding/onboardingContext.tsx
@@ -2,6 +2,7 @@ import { sendCommand } from '@animo-id/expo-ausweis-sdk'
import type { SdJwtVcHeader } from '@credo-ts/core'
import { type AppAgent, initializeAppAgent, useSecureUnlock } from '@easypid/agent'
import { setWalletServiceProviderPin } from '@easypid/crypto/WalletServiceProviderClient'
+import { useFeatureFlag } from '@easypid/hooks/useFeatureFlag'
import { ReceivePidUseCaseCFlow } from '@easypid/use-cases/ReceivePidUseCaseCFlow'
import type {
CardScanningErrorDetails,
@@ -14,7 +15,6 @@ import {
type OnboardingPage,
type OnboardingStep,
SIMULATOR_PIN,
- pidSetupSteps,
} from '@easypid/utils/sharedPidSetup'
import {
BiometricAuthenticationCancelledError,
@@ -34,99 +34,9 @@ import { Linking, Platform } from 'react-native'
import type { PidSdJwtVcAttributes } from '../../hooks'
import { addReceivedActivity } from '../activity/activityRecord'
import { useHasFinishedOnboarding } from './hasFinishedOnboarding'
-import { OnboardingBiometrics } from './screens/biometrics'
-import { OnboardingIntroductionSteps } from './screens/introduction-steps'
-import OnboardingPinEnter from './screens/pin'
-import { OnboardingWalletExplanation } from './screens/wallet-explanation'
-import OnboardingWelcome from './screens/welcome'
+import { onboardingSteps } from './steps'
import { useShouldUseCloudHsm } from './useShouldUseCloudHsm'
-export const onboardingSteps = [
- {
- step: 'welcome',
- alternativeFlow: false,
- progress: 0,
- page: {
- type: 'fullscreen',
- },
- Screen: OnboardingWelcome,
- },
- {
- step: 'wallet-explanation',
- alternativeFlow: false,
- progress: 0.1,
- page: {
- animation: 'delayed',
- type: 'content',
- title: '',
- },
- Screen: OnboardingWalletExplanation,
- },
-
- {
- step: 'introduction-steps',
- alternativeFlow: false,
- progress: 20,
- page: {
- animation: 'delayed',
- type: 'content',
- title: 'Set up your wallet',
- subtitle: 'Before you can use the app, we will guide you through these steps.',
- },
- Screen: OnboardingIntroductionSteps,
- },
-
- {
- step: 'pin',
- alternativeFlow: false,
- progress: 30,
- page: {
- type: 'content',
- title: 'Choose a 6-digit PIN',
- subtitle: 'This PIN secures your identity wallet. You enter it every time you share data.',
- animationKey: 'pin',
- },
- Screen: OnboardingPinEnter,
- },
- {
- step: 'pin-reenter',
- alternativeFlow: false,
- progress: 30,
- page: {
- type: 'content',
- title: 'Repeat your PIN',
- subtitle: 'This PIN secures your identity wallet. You enter it every time you share data.',
- animationKey: 'pin',
- },
- Screen: OnboardingPinEnter,
- },
- {
- step: 'biometrics',
- alternativeFlow: false,
- progress: 40,
- page: {
- type: 'content',
- title: 'Set up biometrics',
- subtitle:
- 'Activate the biometrics functionality of your phone to make sure only you can enter your wallet and share data.',
- },
- Screen: OnboardingBiometrics,
- },
- {
- step: 'biometrics-disabled',
- progress: 40,
- alternativeFlow: true,
- page: {
- type: 'content',
- title: 'You need to enable biometrics',
- subtitle:
- 'To continue, make sure your device has biometric protection enabled, and that EasyPID is allowed to use biometrics.',
- },
- Screen: OnboardingBiometrics,
- },
- ...pidSetupSteps,
-] as const satisfies Array
-
export type OnboardingContext = {
currentStep: OnboardingStep['step']
progress: number
@@ -166,6 +76,7 @@ export function OnboardingContextProvider({
showScanModal: true,
})
const [eidCardRequestedAccessRights, setEidCardRequestedAccessRights] = useState()
+ const hasEidCardFeatureFlag = useFeatureFlag('EID_CARD')
const currentStep = onboardingSteps.find((step) => step.step === currentStepName)
if (!currentStep) throw new Error(`Invalid step ${currentStepName}`)
@@ -236,7 +147,7 @@ export function OnboardingContextProvider({
// Allows bypassing the eID card and use a simulator card
const isSimulatorPinCode = pin === SIMULATOR_PIN
- if (isSimulatorPinCode) {
+ if (isSimulatorPinCode && hasEidCardFeatureFlag) {
toast.show('Simulator eID card activated', {
customData: {
preset: 'success',
@@ -677,7 +588,7 @@ export function OnboardingContextProvider({
} else if (currentStep.step === 'biometrics') {
screen =
} else if (currentStep.step === 'biometrics-disabled') {
- screen =
+ screen =
} else if (currentStep.step === 'data-protection') {
screen =
} else if (currentStep.step === 'id-card-requested-attributes') {
diff --git a/apps/easypid/src/features/onboarding/screens/welcome.tsx b/apps/easypid/src/features/onboarding/screens/welcome.tsx
index 00081121..ebd5c266 100644
--- a/apps/easypid/src/features/onboarding/screens/welcome.tsx
+++ b/apps/easypid/src/features/onboarding/screens/welcome.tsx
@@ -1,18 +1,5 @@
-import {
- Blob,
- Button,
- FlexPage,
- Heading,
- HeroIcons,
- IconContainer,
- Image,
- Paragraph,
- Stack,
- XStack,
- YStack,
-} from '@package/ui'
+import { Blob, Button, FlexPage, Heading, Image, Paragraph, Stack, XStack, YStack } from '@package/ui'
import type React from 'react'
-import { Alert } from 'react-native'
import appIcon from '../../../../assets/icon.png'
@@ -28,43 +15,33 @@ export default function OnboardingWelcome({ goToNextStep }: OnboardingWelcomePro
-
+
+
+
-
-
-
- }
- onPress={() => {
- Alert.alert(
- 'This is the EasyPID wallet',
- '\nThis is your digital wallet. With it, you can store and share information about yourself.'
- )
- }}
- />
-
-
-
- Paradym Wallet
-
- This is your digital wallet. With it, you can store and share information about yourself.
-
-
-
-
- Get Started
-
-
+
+
+
+ Paradym Wallet
+
+ This is your digital wallet. With it, you can store and share information about yourself.
+
+
+
+ Get Started
+
+
)
diff --git a/apps/easypid/src/features/onboarding/steps.ts b/apps/easypid/src/features/onboarding/steps.ts
new file mode 100644
index 00000000..773fd95d
--- /dev/null
+++ b/apps/easypid/src/features/onboarding/steps.ts
@@ -0,0 +1,155 @@
+import { useFeatureFlag } from '@easypid/hooks/useFeatureFlag'
+import { type OnboardingStep, pidSetupSteps } from '@easypid/utils/sharedPidSetup'
+import { OnboardingBiometrics } from './screens/biometrics'
+import { OnboardingIntroductionSteps } from './screens/introduction-steps'
+import OnboardingPinEnter from './screens/pin'
+import { OnboardingWalletExplanation } from './screens/wallet-explanation'
+import OnboardingWelcome from './screens/welcome'
+
+export const onboardingSteps = useFeatureFlag('EID_CARD')
+ ? ([
+ {
+ step: 'welcome',
+ alternativeFlow: false,
+ progress: 0,
+ page: {
+ type: 'fullscreen',
+ },
+ Screen: OnboardingWelcome,
+ },
+ {
+ step: 'wallet-explanation',
+ alternativeFlow: false,
+ progress: 0.1,
+ page: {
+ animation: 'delayed',
+ type: 'content',
+ title: '',
+ },
+ Screen: OnboardingWalletExplanation,
+ },
+ {
+ step: 'introduction-steps',
+ alternativeFlow: false,
+ progress: 20,
+ page: {
+ animation: 'delayed',
+ type: 'content',
+ title: 'Set up your wallet',
+ subtitle: 'Before you can use the app, we will guide you through these steps.',
+ },
+ Screen: OnboardingIntroductionSteps,
+ },
+
+ {
+ step: 'pin',
+ alternativeFlow: false,
+ progress: 30,
+ page: {
+ type: 'content',
+ title: 'Choose a 6-digit PIN',
+ subtitle: 'This PIN secures your identity wallet. You enter it every time you share data.',
+ animationKey: 'pin',
+ },
+ Screen: OnboardingPinEnter,
+ },
+ {
+ step: 'pin-reenter',
+ alternativeFlow: false,
+ progress: 30,
+ page: {
+ type: 'content',
+ title: 'Repeat your PIN',
+ subtitle: 'This PIN secures your identity wallet. You enter it every time you share data.',
+ animationKey: 'pin',
+ },
+ Screen: OnboardingPinEnter,
+ },
+ {
+ step: 'biometrics',
+ alternativeFlow: false,
+ progress: 40,
+ page: {
+ type: 'content',
+ title: 'Set up biometrics',
+ subtitle:
+ 'Activate the biometrics functionality of your phone to make sure only you can enter your wallet and share data.',
+ },
+ Screen: OnboardingBiometrics,
+ },
+ {
+ step: 'biometrics-disabled',
+ progress: 40,
+ alternativeFlow: true,
+ page: {
+ type: 'content',
+ title: 'You need to enable biometrics',
+ subtitle:
+ 'To continue, make sure your device has biometric protection enabled, and that EasyPID is allowed to use biometrics.',
+ animation: 'delayed',
+ },
+ Screen: OnboardingBiometrics,
+ },
+ ...pidSetupSteps,
+ ] as const satisfies Array)
+ : ([
+ {
+ step: 'welcome',
+ alternativeFlow: false,
+ progress: 0,
+ page: {
+ type: 'fullscreen',
+ },
+ Screen: OnboardingWelcome,
+ },
+ {
+ step: 'pin',
+ alternativeFlow: false,
+ progress: 33,
+ page: {
+ type: 'content',
+ title: 'Choose a 6-digit PIN',
+ subtitle: 'This PIN secures your wallet. You enter it every time you share data.',
+ animationKey: 'pin',
+ animation: 'delayed',
+ },
+ Screen: OnboardingPinEnter,
+ },
+ {
+ step: 'pin-reenter',
+ alternativeFlow: false,
+ progress: 33,
+ page: {
+ type: 'content',
+ title: 'Repeat your PIN',
+ subtitle: 'This PIN secures your wallet. You enter it every time you share data.',
+ animationKey: 'pin',
+ },
+ Screen: OnboardingPinEnter,
+ },
+ {
+ step: 'biometrics',
+ alternativeFlow: false,
+ progress: 66,
+ page: {
+ type: 'content',
+ title: 'Set up biometrics',
+ subtitle:
+ 'Activate the biometrics functionality of your phone to make sure only you can enter your wallet and share data.',
+ },
+ Screen: OnboardingBiometrics,
+ },
+ {
+ step: 'biometrics-disabled',
+ progress: 66,
+ alternativeFlow: true,
+ page: {
+ type: 'content',
+ title: 'You need to enable biometrics',
+ animation: 'delayed',
+ subtitle:
+ 'To continue, make sure your device has biometric protection enabled, and that Paradym Wallet is allowed to use biometrics.',
+ },
+ Screen: OnboardingBiometrics,
+ },
+ ] as const satisfies Array)
diff --git a/apps/easypid/src/features/pid/FunkePidSetupScreen.tsx b/apps/easypid/src/features/pid/FunkePidSetupScreen.tsx
index be05f48d..7138e227 100644
--- a/apps/easypid/src/features/pid/FunkePidSetupScreen.tsx
+++ b/apps/easypid/src/features/pid/FunkePidSetupScreen.tsx
@@ -3,6 +3,7 @@ import { type SdJwtVcHeader, SdJwtVcRecord } from '@credo-ts/core'
import { useSecureUnlock } from '@easypid/agent'
import { InvalidPinError } from '@easypid/crypto/error'
import type { PidSdJwtVcAttributes } from '@easypid/hooks'
+import { useFeatureFlag } from '@easypid/hooks/useFeatureFlag'
import { ReceivePidUseCaseCFlow } from '@easypid/use-cases/ReceivePidUseCaseCFlow'
import type {
CardScanningErrorDetails,
@@ -37,6 +38,7 @@ export function FunkePidSetupScreen() {
const toast = useToastController()
const pushToWallet = usePushToWallet()
const secureUnlock = useSecureUnlock()
+ const hasEidCardFeatureFlag = useFeatureFlag('EID_CARD')
const [idCardPin, setIdCardPin] = useState()
const [receivePidUseCase, setReceivePidUseCase] = useState()
@@ -123,6 +125,17 @@ export function FunkePidSetupScreen() {
onEnterPinRef.current.onEnterPin = onEnterPin
}, [onEnterPin])
+ useEffect(() => {
+ if (!hasEidCardFeatureFlag) {
+ toast.show('This feature is not supported in this version of the app.', { customData: { preset: 'warning' } })
+ pushToWallet()
+ }
+ }, [hasEidCardFeatureFlag, toast, pushToWallet])
+
+ if (!hasEidCardFeatureFlag) {
+ return null
+ }
+
const onIdCardStart = async ({
walletPin,
allowSimulatorCard,
diff --git a/apps/easypid/src/features/wallet/FunkeWalletScreen.tsx b/apps/easypid/src/features/wallet/FunkeWalletScreen.tsx
index 1b21e57f..adbe5195 100644
--- a/apps/easypid/src/features/wallet/FunkeWalletScreen.tsx
+++ b/apps/easypid/src/features/wallet/FunkeWalletScreen.tsx
@@ -10,6 +10,7 @@ import {
Paragraph,
ScrollView,
Spacer,
+ Stack,
XStack,
YStack,
useSpringify,
@@ -18,6 +19,7 @@ import {
import { useRouter } from 'expo-router'
import { useFirstNameFromPidCredential } from '@easypid/hooks'
+import { useFeatureFlag } from '@easypid/hooks/useFeatureFlag'
import { useHaptics } from '@package/app/src/hooks'
import { Platform } from 'react-native'
import { FadeIn } from 'react-native-reanimated'
@@ -31,6 +33,7 @@ export function FunkeWalletScreen() {
const toast = useToastController()
const { userName, isLoading } = useFirstNameFromPidCredential()
+ const hasEidCardFeatureFlag = useFeatureFlag('EID_CARD')
const pushToMenu = withHaptics(() => push('/menu'))
const pushToScanner = withHaptics(() => push('/scan'))
@@ -86,17 +89,22 @@ export function FunkeWalletScreen() {
onPress={pushToOffline}
/>
-
- {userName ? (
-
- How does it work?
-
- ) : (
-
- Setup your ID
-
- )}
-
+
+ {hasEidCardFeatureFlag ? (
+
+ {userName ? (
+
+ How does it work?
+
+ ) : (
+
+ Setup your ID
+
+ )}
+
+ ) : (
+
+ )}
diff --git a/apps/easypid/src/hooks/useFeatureFlag.tsx b/apps/easypid/src/hooks/useFeatureFlag.tsx
index e7009d5c..678a5513 100644
--- a/apps/easypid/src/hooks/useFeatureFlag.tsx
+++ b/apps/easypid/src/hooks/useFeatureFlag.tsx
@@ -5,3 +5,11 @@ import type { FeatureKey } from '../config/features'
export const useFeatureFlag = (featureKey: FeatureKey) => {
return APP_CONFIGS[CURRENT_APP_TYPE]?.[featureKey] ?? false
}
+
+export const useIsFunkeWallet = () => {
+ return CURRENT_APP_TYPE === 'FUNKE_WALLET'
+}
+
+export const useIsParadymWallet = () => {
+ return CURRENT_APP_TYPE === 'PARADYM_WALLET'
+}
diff --git a/packages/ui/src/components/PinPad.tsx b/packages/ui/src/components/PinPad.tsx
index 0ba431c2..690dc0d2 100644
--- a/packages/ui/src/components/PinPad.tsx
+++ b/packages/ui/src/components/PinPad.tsx
@@ -108,6 +108,7 @@ export const PinPad = ({ onPressPinNumber, useBiometricsPad, disabled, biometric
// biome-ignore lint/suspicious/noArrayIndexKey:
key={rowIndex}
borderTopWidth="$0.5"
+ borderBottomWidth={rowIndex === pinValues.length - 1 ? '$0.5' : 0}
bc="$grey-200"
borderColor="$grey-200"
w="100%"