diff --git a/app/app.tsx b/app/app.tsx
index cf35c1d7e..485f6120b 100644
--- a/app/app.tsx
+++ b/app/app.tsx
@@ -36,7 +36,7 @@ import { FeatureFlagContextProvider } from "./config/feature-flags-context"
import "./utils/logs"
import { GestureHandlerRootView } from "react-native-gesture-handler"
import { Provider } from "react-redux"
-import { store } from "./store/redux"
+import { persistor, store } from "./store/redux"
import PolyfillCrypto from "react-native-webview-crypto"
import { ActivityIndicatorProvider } from "./contexts/ActivityIndicatorContext"
import { BreezProvider } from "./contexts/BreezContext"
@@ -45,6 +45,7 @@ import { NotificationsProvider } from "./components/notification"
import { SafeAreaProvider } from "react-native-safe-area-context"
import { FlashcardProvider } from "./contexts/Flashcard"
import { NostrGroupChatProvider } from "./screens/chat/GroupChat/GroupChatProvider"
+import { PersistGate } from "redux-persist/integration/react"
// FIXME should we only load the currently used local?
// this would help to make the app load faster
@@ -67,14 +68,15 @@ export const App = () => (
-
-
-
-
+
+
+
+
+
@@ -101,10 +103,11 @@ export const App = () => (
-
-
-
-
+
+
+
+
+
diff --git a/app/components/account-upgrade-flow/AddressField.tsx b/app/components/account-upgrade-flow/AddressField.tsx
new file mode 100644
index 000000000..8bc789c04
--- /dev/null
+++ b/app/components/account-upgrade-flow/AddressField.tsx
@@ -0,0 +1,136 @@
+import React, { useEffect, useRef, useState } from "react"
+import { Modal, Platform, TouchableOpacity, View } from "react-native"
+import { makeStyles, Text, useTheme } from "@rneui/themed"
+import {
+ GooglePlacesAutocomplete,
+ GooglePlacesAutocompleteRef,
+} from "react-native-google-places-autocomplete"
+
+// components
+import { PrimaryBtn } from "../buttons"
+
+// env
+import { GOOGLE_PLACE_API_KEY } from "@env"
+
+type Props = {
+ label: string
+ placeholder: string
+ value?: string
+ errorMsg?: string
+ onAddressSelect: (address: string, lat?: number, lng?: number) => void
+}
+
+const AddressField: React.FC = ({
+ label,
+ placeholder,
+ value,
+ errorMsg,
+ onAddressSelect,
+}) => {
+ const styles = useStyles()
+ const { colors } = useTheme().theme
+
+ const ref = useRef(null)
+ const [isFocused, setIsFocused] = useState(false)
+ const [isVisible, setIsVisible] = useState(false)
+
+ useEffect(() => {
+ if (isVisible && ref.current) {
+ ref.current.focus()
+ }
+ }, [isVisible, ref.current])
+
+ return (
+
+
+ {label}
+
+ setIsVisible(true)}>
+
+ {!!value ? value : placeholder}
+
+
+ {!!errorMsg && (
+
+ {errorMsg}
+
+ )}
+ setIsVisible(false)}
+ >
+
+ console.log("Google places auto complete", err)}
+ onNotFound={() => console.log("Google places auto complete not found")}
+ fetchDetails={true}
+ onPress={(data, details) => {
+ setIsVisible(false)
+ onAddressSelect(
+ data.description,
+ details?.geometry.location.lat,
+ details?.geometry.location.lng,
+ )
+ }}
+ query={{
+ key: GOOGLE_PLACE_API_KEY,
+ language: "en",
+ }}
+ styles={{
+ textInput: [
+ styles.googlePlace,
+ isFocused ? { borderColor: colors.primary } : {},
+ ],
+ }}
+ textInputProps={{
+ onFocus: () => setIsFocused(true),
+ onBlur: () => setIsFocused(false),
+ }}
+ />
+ setIsVisible(false)} />
+
+
+
+ )
+}
+
+export default AddressField
+
+const useStyles = makeStyles(({ colors }) => ({
+ container: {
+ marginBottom: 15,
+ },
+ input: {
+ paddingHorizontal: 15,
+ paddingVertical: 20,
+ marginTop: 5,
+ marginBottom: 2,
+ borderRadius: 10,
+ borderWidth: 1,
+ borderColor: colors.grey4,
+ backgroundColor: colors.grey5,
+ },
+ modal: {
+ flex: 1,
+ backgroundColor: colors.white,
+ padding: 20,
+ },
+ googlePlace: {
+ height: Platform.OS === "ios" ? 51 : 60,
+ paddingHorizontal: 15,
+ padding: 20,
+ marginTop: 5,
+ marginBottom: 15,
+ borderWidth: 1,
+ borderRadius: 10,
+ borderColor: colors.grey4,
+ backgroundColor: colors.grey5,
+ fontSize: 16,
+ fontFamily: "Sora-Regular",
+ },
+}))
diff --git a/app/components/account-upgrade-flow/CheckBoxField.tsx b/app/components/account-upgrade-flow/CheckBoxField.tsx
new file mode 100644
index 000000000..f17c6c940
--- /dev/null
+++ b/app/components/account-upgrade-flow/CheckBoxField.tsx
@@ -0,0 +1,58 @@
+import React, { useState } from "react"
+import { View, TouchableOpacity } from "react-native"
+import { Icon, makeStyles, Text, useTheme } from "@rneui/themed"
+import Tooltip from "react-native-walkthrough-tooltip"
+import { useI18nContext } from "@app/i18n/i18n-react"
+
+type Props = {
+ isChecked?: boolean
+ onCheck: () => void
+}
+
+const CheckBoxField: React.FC = ({ isChecked, onCheck }) => {
+ const styles = useStyles()
+ const { colors } = useTheme().theme
+ const { LL } = useI18nContext()
+
+ const [tooltipVisible, setTooltipVisible] = useState(false)
+
+ return (
+
+
+
+ {LL.AccountUpgrade.flashTerminal()}
+
+ {LL.AccountUpgrade.flashTerminalTooltip()}}
+ placement="top"
+ onClose={() => setTooltipVisible(false)}
+ >
+ setTooltipVisible(true)}>
+
+
+
+
+ )
+}
+
+export default CheckBoxField
+
+const useStyles = makeStyles(() => ({
+ container: {
+ flexDirection: "row",
+ alignItems: "center",
+ },
+}))
diff --git a/app/components/account-upgrade-flow/DropDownField.tsx b/app/components/account-upgrade-flow/DropDownField.tsx
new file mode 100644
index 000000000..d4a58fb04
--- /dev/null
+++ b/app/components/account-upgrade-flow/DropDownField.tsx
@@ -0,0 +1,81 @@
+import React from "react"
+import { View } from "react-native"
+import { makeStyles, Text, useTheme } from "@rneui/themed"
+import { Dropdown } from "react-native-element-dropdown"
+import { useI18nContext } from "@app/i18n/i18n-react"
+
+type Props = {
+ label: string
+ placeholder: string
+ data: any[]
+ value: string
+ errorMsg?: string
+ isOptional?: boolean
+ onChange: (val: string) => void
+}
+
+const DropDownField: React.FC = ({
+ label,
+ placeholder,
+ data,
+ value,
+ errorMsg,
+ isOptional,
+ onChange,
+}) => {
+ const styles = useStyles()
+ const { colors } = useTheme().theme
+ const { LL } = useI18nContext()
+
+ return (
+
+
+ {label}
+ {isOptional && (
+
+ {LL.AccountUpgrade.optional()}
+
+ )}
+
+ onChange(item.value)}
+ />
+ {!!errorMsg && (
+
+ {errorMsg}
+
+ )}
+
+ )
+}
+
+export default DropDownField
+
+const useStyles = makeStyles(({ colors }) => ({
+ wrapper: {
+ marginBottom: 15,
+ },
+ dropdown: {
+ padding: 15,
+ marginTop: 5,
+ marginBottom: 2,
+ borderRadius: 10,
+ borderWidth: 1,
+ borderColor: colors.grey4,
+ backgroundColor: colors.grey5,
+ fontSize: 16,
+ fontFamily: "Sora-Regular",
+ },
+ container: {
+ marginTop: 5,
+ },
+}))
diff --git a/app/components/account-upgrade-flow/InputField.tsx b/app/components/account-upgrade-flow/InputField.tsx
new file mode 100644
index 000000000..e804856d3
--- /dev/null
+++ b/app/components/account-upgrade-flow/InputField.tsx
@@ -0,0 +1,77 @@
+import React, { useState } from "react"
+import { makeStyles, Text, useTheme } from "@rneui/themed"
+import { TextInput, TextInputProps, View } from "react-native"
+import { useI18nContext } from "@app/i18n/i18n-react"
+
+type Props = {
+ label: string
+ errorMsg?: string
+ isOptional?: boolean
+} & TextInputProps
+
+const InputField: React.FC = ({
+ label,
+ errorMsg,
+ isOptional,
+ placeholder,
+ value,
+ editable,
+ autoCapitalize,
+ keyboardType,
+ onChangeText,
+}) => {
+ const styles = useStyles()
+ const { colors } = useTheme().theme
+ const { LL } = useI18nContext()
+
+ const [isFocused, setIsFocused] = useState(false)
+
+ return (
+
+
+ {label}
+ {isOptional && (
+
+ {LL.AccountUpgrade.optional()}
+
+ )}
+
+ setIsFocused(true)}
+ onBlur={() => setIsFocused(false)}
+ autoCapitalize={autoCapitalize}
+ keyboardType={keyboardType}
+ />
+ {!!errorMsg && (
+
+ {errorMsg}
+
+ )}
+
+ )
+}
+
+export default InputField
+
+const useStyles = makeStyles(({ colors }) => ({
+ container: {
+ marginBottom: 15,
+ },
+ input: {
+ padding: 15,
+ marginTop: 5,
+ marginBottom: 2,
+ borderRadius: 10,
+ borderWidth: 1,
+ borderColor: colors.grey4,
+ backgroundColor: colors.grey5,
+ fontSize: 16,
+ fontFamily: "Sora-Regular",
+ },
+}))
diff --git a/app/components/account-upgrade-flow/PhoneNumber.tsx b/app/components/account-upgrade-flow/PhoneNumber.tsx
new file mode 100644
index 000000000..7fa6f2b3e
--- /dev/null
+++ b/app/components/account-upgrade-flow/PhoneNumber.tsx
@@ -0,0 +1,139 @@
+import React, { useState } from "react"
+import { TextInput, View } from "react-native"
+import { makeStyles, useTheme, Text } from "@rneui/themed"
+import { TouchableOpacity } from "react-native-gesture-handler"
+import { FlagButtonProps } from "react-native-country-picker-modal/lib/FlagButton"
+import {
+ CountryCode as PhoneNumberCountryCode,
+ getCountryCallingCode,
+} from "libphonenumber-js/mobile"
+import CountryPicker, {
+ CountryCode,
+ DARK_THEME,
+ DEFAULT_THEME,
+ Flag,
+} from "react-native-country-picker-modal"
+
+// hooks
+import { useI18nContext } from "@app/i18n/i18n-react"
+
+type Props = {
+ countryCode?: string
+ phoneNumber?: string
+ errorMsg?: string
+ disabled?: boolean
+ supportedCountries: CountryCode[]
+ setPhoneNumber: (number: string) => void
+ setCountryCode: (countryCode: PhoneNumberCountryCode) => void
+}
+
+const PhoneNumber: React.FC = ({
+ countryCode,
+ phoneNumber,
+ errorMsg,
+ disabled,
+ supportedCountries,
+ setPhoneNumber,
+ setCountryCode,
+}) => {
+ const styles = useStyles()
+ const { mode, colors } = useTheme().theme
+ const { LL } = useI18nContext()
+
+ const [isFocused, setIsFocused] = useState(false)
+
+ const renderCountryCode = ({ countryCode, onOpen }: FlagButtonProps) => {
+ return (
+ countryCode && (
+
+
+
+ +{getCountryCallingCode(countryCode as PhoneNumberCountryCode)}
+
+
+ )
+ )
+ }
+
+ return (
+
+
+ {LL.AccountUpgrade.phoneNumber()}
+
+
+ setCountryCode(country.cca2 as PhoneNumberCountryCode)}
+ renderFlagButton={renderCountryCode}
+ withCallingCodeButton={true}
+ withFilter={true}
+ filterProps={{ autoFocus: true }}
+ withCallingCode={true}
+ />
+ setIsFocused(true)}
+ onBlur={() => setIsFocused(false)}
+ />
+
+ {!!errorMsg && (
+
+ {errorMsg}
+
+ )}
+
+ )
+}
+
+export default PhoneNumber
+
+const useStyles = makeStyles(({ colors }) => ({
+ wrapper: {
+ marginBottom: 15,
+ },
+ container: {
+ flexDirection: "row",
+ marginTop: 5,
+ marginBottom: 2,
+ },
+ countryPicker: {
+ flex: 1,
+ paddingHorizontal: 15,
+ borderRadius: 10,
+ borderWidth: 1,
+ borderColor: colors.grey4,
+ backgroundColor: colors.grey5,
+ flexDirection: "row",
+ alignItems: "center",
+ },
+ input: {
+ flex: 1,
+ padding: 15,
+ borderRadius: 10,
+ borderWidth: 1,
+ borderColor: colors.grey4,
+ backgroundColor: colors.grey5,
+ fontSize: 16,
+ fontFamily: "Sora-Regular",
+ marginLeft: 10,
+ },
+}))
diff --git a/app/components/account-upgrade-flow/PhotoUploadField.tsx b/app/components/account-upgrade-flow/PhotoUploadField.tsx
new file mode 100644
index 000000000..748ff7f1f
--- /dev/null
+++ b/app/components/account-upgrade-flow/PhotoUploadField.tsx
@@ -0,0 +1,278 @@
+import React, { useCallback, useEffect, useRef, useState } from "react"
+import { Alert, Image, Linking, Modal, TouchableOpacity, View } from "react-native"
+import { Icon, makeStyles, Text, useTheme } from "@rneui/themed"
+import { Asset, launchImageLibrary } from "react-native-image-picker"
+import {
+ Camera,
+ CameraRuntimeError,
+ useCameraDevice,
+ useCameraPermission,
+} from "react-native-vision-camera"
+
+// component
+import { Screen } from "../screen"
+import { PrimaryBtn } from "../buttons"
+
+// hooks
+import { useI18nContext } from "@app/i18n/i18n-react"
+import { useSafeAreaInsets } from "react-native-safe-area-context"
+
+// assets
+import PhotoAdd from "@app/assets/icons/photo-add.svg"
+
+// utils
+import { toastShow } from "@app/utils/toast"
+
+const MAX_FILE_SIZE = 5 * 1024 * 1024 // File size limit in bytes (5MB)
+const ALLOWED_FILE_TYPES = ["image/jpeg", "image/png", "image/jpg", "image/heic"]
+
+type Props = {
+ label: string
+ photo?: Asset
+ errorMsg?: string
+ isOptional?: boolean
+ onPhotoUpload: (val: Asset) => void
+ setErrorMsg: (val: string) => void
+}
+
+const PhotoUploadField: React.FC = ({
+ label,
+ photo,
+ errorMsg,
+ isOptional,
+ onPhotoUpload,
+ setErrorMsg,
+}) => {
+ const styles = useStyles()
+ const { colors } = useTheme().theme
+ const { LL } = useI18nContext()
+ const { top, bottom } = useSafeAreaInsets()
+
+ const { hasPermission, requestPermission } = useCameraPermission()
+ const device = useCameraDevice("back", {
+ physicalDevices: ["wide-angle-camera", "telephoto-camera"],
+ })
+
+ const camera = useRef(null)
+ const [isCameraVisible, setIsCameraVisible] = useState(false)
+
+ useEffect(() => {
+ if (!hasPermission) {
+ requestPermission()
+ }
+ }, [hasPermission, requestPermission])
+
+ const openSettings = () => {
+ Linking.openSettings().catch(() => {
+ Alert.alert(LL.ScanningQRCodeScreen.unableToOpenSettings())
+ })
+ }
+
+ const onError = useCallback((error: CameraRuntimeError) => {
+ console.error(error)
+ }, [])
+
+ const showImagePicker = async () => {
+ try {
+ const result = await launchImageLibrary({ mediaType: "photo" })
+ setIsCameraVisible(false)
+ if (result.errorCode === "permission") {
+ toastShow({
+ message: (translations) =>
+ translations.ScanningQRCodeScreen.imageLibraryPermissionsNotGranted(),
+ })
+ }
+ if (
+ result.assets &&
+ result.assets.length > 0 &&
+ result.assets[0].uri &&
+ result.assets[0].type &&
+ result.assets[0].fileSize
+ ) {
+ if (!ALLOWED_FILE_TYPES.includes(result.assets[0].type)) {
+ setErrorMsg("Please upload a valid image (JPG, PNG, or HEIC)")
+ } else if (result?.assets[0]?.fileSize > MAX_FILE_SIZE) {
+ setErrorMsg("File size exceeds 5MB limit")
+ } else {
+ onPhotoUpload(result.assets[0])
+ }
+ }
+ } catch (err: unknown) {
+ console.log("Image Picker Error: ", err)
+ }
+ }
+
+ const takePhoto = async () => {
+ try {
+ const file = await camera?.current?.takePhoto()
+ setIsCameraVisible(false)
+
+ if (file) {
+ const result = await fetch(`file://${file?.path}`)
+ const data = await result.blob()
+
+ if (!ALLOWED_FILE_TYPES.includes(data.type)) {
+ setErrorMsg("Please upload a valid image (JPG, PNG, or HEIC)")
+ } else if (data.size > MAX_FILE_SIZE) {
+ setErrorMsg("File size exceeds 5MB limit")
+ } else {
+ onPhotoUpload({
+ uri: `file://${file?.path}`,
+ type: data.type,
+ fileSize: data.size,
+ fileName: file.path.split("/").pop(),
+ })
+ }
+ }
+ } catch (err) {
+ console.log("Take Photo Error", err)
+ }
+ }
+
+ return (
+
+
+ {label}
+ {isOptional && (
+
+ {LL.AccountUpgrade.optional()}
+
+ )}
+
+ setIsCameraVisible(true)}>
+ {!!photo && }
+
+
+ {!!errorMsg && (
+
+ {errorMsg}
+
+ )}
+ setIsCameraVisible(false)}
+ >
+
+
+ setIsCameraVisible(false)}
+ >
+
+
+
+ {!hasPermission ? (
+ <>
+
+
+ {LL.ScanningQRCodeScreen.permissionCamera()}
+
+
+
+ >
+ ) : device === null || device === undefined ? (
+
+ {LL.ScanningQRCodeScreen.noCamera()}
+
+ ) : (
+
+
+
+
+
+
+
+
+ )}
+
+
+
+
+
+
+
+
+ )
+}
+
+export default PhotoUploadField
+
+const useStyles = makeStyles(({ colors }) => ({
+ wrapper: {
+ marginBottom: 35,
+ },
+ container: {
+ width: "100%",
+ height: 150,
+ alignItems: "center",
+ justifyContent: "center",
+ marginTop: 5,
+ marginBottom: 2,
+ borderRadius: 10,
+ borderWidth: 1,
+ borderColor: colors.grey4,
+ backgroundColor: colors.grey5,
+ overflow: "hidden",
+ },
+ img: {
+ position: "absolute",
+ width: "100%",
+ height: "100%",
+ },
+ row: {
+ flexDirection: "row",
+ justifyContent: "flex-end",
+ backgroundColor: "#000",
+ },
+ close: {
+ paddingHorizontal: 20,
+ paddingVertical: 10,
+ },
+ center: {
+ flex: 1,
+ alignItems: "center",
+ justifyContent: "center",
+ },
+ camera: {
+ flex: 1,
+ },
+ captureWrapper: {
+ position: "absolute",
+ width: "100%",
+ alignItems: "center",
+ bottom: 20,
+ },
+ captureOutline: {
+ borderWidth: 3,
+ borderRadius: 100,
+ borderColor: "#fff",
+ padding: 5,
+ },
+ capture: {
+ width: 50,
+ height: 50,
+ borderRadius: 100,
+ backgroundColor: "#FFF",
+ },
+ permissionMissingText: {
+ width: "80%",
+ textAlign: "center",
+ },
+ photoLibrary: {
+ padding: 20,
+ },
+}))
diff --git a/app/components/account-upgrade-flow/ProgressSteps.tsx b/app/components/account-upgrade-flow/ProgressSteps.tsx
new file mode 100644
index 000000000..e252cf0c9
--- /dev/null
+++ b/app/components/account-upgrade-flow/ProgressSteps.tsx
@@ -0,0 +1,90 @@
+import React from "react"
+import { View } from "react-native"
+import { Icon, makeStyles, Text, useTheme } from "@rneui/themed"
+
+type Props = {
+ numOfSteps: number
+ currentStep: number
+}
+
+const ProgressSteps: React.FC = ({ numOfSteps, currentStep }) => {
+ const styles = useStyles()
+ const { colors } = useTheme().theme
+
+ const renderStep = (i: number) => {
+ if (currentStep === i + 1) {
+ return (
+
+
+ {i + 1}
+
+
+ )
+ } else if (currentStep > i + 1) {
+ return (
+
+ )
+ } else {
+ return (
+
+
+ {i + 1}
+
+
+ )
+ }
+ }
+
+ return (
+
+ {Array(numOfSteps)
+ .fill(0)
+ .map((_, i) => (
+ <>
+ {renderStep(i)}
+ {i + 1 < numOfSteps && (
+
+ )}
+ >
+ ))}
+
+ )
+}
+
+export default ProgressSteps
+
+const useStyles = makeStyles(({ colors }) => ({
+ wrapper: {
+ flexDirection: "row",
+ alignItems: "center",
+ marginHorizontal: 20,
+ marginVertical: 10,
+ },
+ separator: {
+ flex: 1,
+ height: 3,
+ backgroundColor: colors._lightBlue,
+ marginHorizontal: 5,
+ },
+ step: {
+ width: 35,
+ height: 35,
+ alignItems: "center",
+ justifyContent: "center",
+ borderRadius: 1000,
+ borderWidth: 2,
+ borderColor: colors.grey2,
+ },
+ currentStep: {
+ backgroundColor: colors._lightBlue,
+ borderColor: colors._borderBlue,
+ },
+ currentStepText: {
+ color: "#fff",
+ },
+}))
diff --git a/app/components/account-upgrade-flow/index.ts b/app/components/account-upgrade-flow/index.ts
new file mode 100644
index 000000000..68a7decf6
--- /dev/null
+++ b/app/components/account-upgrade-flow/index.ts
@@ -0,0 +1,17 @@
+import PhoneNumber from "./PhoneNumber"
+import InputField from "./InputField"
+import DropDownField from "./DropDownField"
+import PhotoUploadField from "./PhotoUploadField"
+import AddressField from "./AddressField"
+import ProgressSteps from "./ProgressSteps"
+import CheckBoxField from "./CheckBoxField"
+
+export {
+ PhoneNumber,
+ InputField,
+ DropDownField,
+ PhotoUploadField,
+ AddressField,
+ ProgressSteps,
+ CheckBoxField,
+}
diff --git a/app/components/home-screen/QuickStart.tsx b/app/components/home-screen/QuickStart.tsx
index 129de243d..7c63a64a5 100644
--- a/app/components/home-screen/QuickStart.tsx
+++ b/app/components/home-screen/QuickStart.tsx
@@ -15,14 +15,17 @@ import GoldWallet from "@app/assets/illustrations/gold-wallet.svg"
import SecureWallet from "@app/assets/illustrations/secure-wallet.svg"
// components
-import { UpgradeAccountModal } from "../upgrade-account-modal"
import { AdvancedModeModal } from "../advanced-mode-modal"
// hooks
import { useI18nContext } from "@app/i18n/i18n-react"
import { useNavigation } from "@react-navigation/native"
import { usePersistentStateContext } from "@app/store/persistent-state"
-import { AccountLevel, useHomeAuthedQuery } from "@app/graphql/generated"
+import {
+ AccountLevel,
+ useHomeAuthedQuery,
+ useAccountUpgradeRequestStatusQuery,
+} from "@app/graphql/generated"
// utils
import { KEYCHAIN_MNEMONIC_KEY } from "@app/utils/breez-sdk-liquid"
@@ -35,6 +38,7 @@ type RenderItemProps = {
title: string
description: string
image: any
+ pending?: boolean
onPress: () => void
}
index: number
@@ -49,7 +53,6 @@ const QuickStart = () => {
const ref = useRef(null)
const [advanceModalVisible, setAdvanceModalVisible] = useState(false)
- const [upgradeAccountModalVisible, setUpgradeAccountModalVisible] = useState(false)
const [hasRecoveryPhrase, setHasRecoveryPhrase] = useState(false)
const { data, loading } = useHomeAuthedQuery()
@@ -63,13 +66,21 @@ const QuickStart = () => {
if (credentials) setHasRecoveryPhrase(true)
}
+ const { data: upgradeStatusData } = useAccountUpgradeRequestStatusQuery()
+ const upgradePending =
+ upgradeStatusData?.accountUpgradeRequestStatus?.hasPendingRequest ?? false
+
let carouselData = [
{
type: "upgrade",
title: LL.HomeScreen.upgradeTitle(),
- description: LL.HomeScreen.upgradeDesc(),
+ description: upgradePending
+ ? LL.HomeScreen.upgradePendingDesc()
+ : LL.HomeScreen.upgradeDesc(),
image: Account,
- onPress: () => setUpgradeAccountModalVisible(true),
+ pending: upgradePending,
+ onPress: () =>
+ navigation.navigate(upgradePending ? "TestTransaction" : "AccountType"),
},
{
type: "currency",
@@ -124,7 +135,7 @@ const QuickStart = () => {
data?.me?.defaultAccount.level !== AccountLevel.Zero ||
persistentState?.closedQuickStartTypes?.includes("upgrade")
) {
- carouselData = carouselData.filter((el) => el.type !== "upgrade")
+ // carouselData = carouselData.filter((el) => el.type !== "upgrade")
}
if (
persistentState.currencyChanged ||
@@ -179,17 +190,31 @@ const QuickStart = () => {
const renderItem = ({ item, index }: RenderItemProps) => {
const Image = item.image
return (
-
+
{item.title}
+ {item.pending && (
+
+ {` (Pending)`}
+
+ )}
{item.description}
- onHide(item.type)}>
-
-
+ {!item.pending && (
+ onHide(item.type)}>
+
+
+ )}
)
}
@@ -207,10 +232,6 @@ const QuickStart = () => {
loop={carouselData.length !== 1}
containerStyle={{ marginTop: 10 }}
/>
- setUpgradeAccountModalVisible(false)}
- />
;
};
+export type AccountUpgradeRequest = {
+ readonly __typename: 'AccountUpgradeRequest';
+ readonly businessAddress?: Maybe;
+ readonly businessName?: Maybe;
+ readonly currentLevel: AccountLevel;
+ readonly email?: Maybe;
+ readonly fullName: Scalars['String']['output'];
+ /** ERPNext document name */
+ readonly name: Scalars['String']['output'];
+ readonly phoneNumber?: Maybe;
+ readonly requestedLevel: AccountLevel;
+ /** Workflow status of the upgrade request */
+ readonly status: Scalars['String']['output'];
+ readonly username: Scalars['String']['output'];
+};
+
+export type AccountUpgradeRequestPayload = {
+ readonly __typename: 'AccountUpgradeRequestPayload';
+ readonly errors: ReadonlyArray;
+ readonly upgradeRequest?: Maybe;
+};
+
export type AuthTokenPayload = {
readonly __typename: 'AuthTokenPayload';
readonly authToken?: Maybe;
@@ -210,7 +232,7 @@ export type BtcWallet = Wallet & {
readonly __typename: 'BTCWallet';
readonly accountId: Scalars['ID']['output'];
/** A balance stored in BTC. */
- readonly balance: Scalars['SignedAmount']['output'];
+ readonly balance: Scalars['FractionalCentAmount']['output'];
readonly id: Scalars['ID']['output'];
readonly lnurlp?: Maybe;
/** An unconfirmed incoming onchain balance. */
@@ -246,6 +268,22 @@ export type BuildInformation = {
readonly helmRevision?: Maybe;
};
+export type BusinessAccountUpgradeRequestInput = {
+ readonly accountNumber?: InputMaybe;
+ readonly accountType?: InputMaybe;
+ readonly bankBranch?: InputMaybe;
+ readonly bankName?: InputMaybe;
+ readonly businessAddress?: InputMaybe;
+ readonly businessName?: InputMaybe;
+ readonly currency?: InputMaybe;
+ readonly email?: InputMaybe;
+ readonly fullName: Scalars['String']['input'];
+ readonly idDocument?: InputMaybe;
+ readonly level: AccountLevel;
+ readonly phoneNumber?: InputMaybe;
+ readonly terminalRequested?: InputMaybe;
+};
+
export type CallbackEndpoint = {
readonly __typename: 'CallbackEndpoint';
readonly id: Scalars['EndpointId']['output'];
@@ -444,6 +482,22 @@ export type GraphQlApplicationError = Error & {
readonly path?: Maybe>>;
};
+export type IdDocumentUploadUrlGenerateInput = {
+ /** MIME type (image/jpeg, image/png, image/webp) */
+ readonly contentType: Scalars['String']['input'];
+ /** Original filename */
+ readonly filename: Scalars['String']['input'];
+};
+
+export type IdDocumentUploadUrlPayload = {
+ readonly __typename: 'IdDocumentUploadUrlPayload';
+ readonly errors: ReadonlyArray;
+ /** Storage key for the uploaded file (use to generate read URLs) */
+ readonly fileKey?: Maybe;
+ /** Pre-signed URL for uploading the ID document directly to storage */
+ readonly uploadUrl?: Maybe;
+};
+
export type InitiateCashoutInput = {
/** The id of the offer being executed. */
readonly offerId: Scalars['ID']['input'];
@@ -736,12 +790,14 @@ export type Mutation = {
readonly accountEnableNotificationChannel: AccountUpdateNotificationSettingsPayload;
readonly accountUpdateDefaultWalletId: AccountUpdateDefaultWalletIdPayload;
readonly accountUpdateDisplayCurrency: AccountUpdateDisplayCurrencyPayload;
+ readonly businessAccountUpgradeRequest: SuccessPayload;
readonly callbackEndpointAdd: CallbackEndpointAddPayload;
readonly callbackEndpointDelete: SuccessPayload;
readonly captchaCreateChallenge: CaptchaCreateChallengePayload;
readonly captchaRequestAuthCode: SuccessPayload;
readonly deviceNotificationTokenCreate: SuccessPayload;
readonly feedbackSubmit: SuccessPayload;
+ readonly idDocumentUploadUrlGenerate: IdDocumentUploadUrlPayload;
/**
* Start the Cashout process;
* User sends USD to Flash via Ibex and receives USD or JMD to bank account.
@@ -887,6 +943,11 @@ export type MutationAccountUpdateDisplayCurrencyArgs = {
};
+export type MutationBusinessAccountUpgradeRequestArgs = {
+ input: BusinessAccountUpgradeRequestInput;
+};
+
+
export type MutationCallbackEndpointAddArgs = {
input: CallbackEndpointAddInput;
};
@@ -912,6 +973,11 @@ export type MutationFeedbackSubmitArgs = {
};
+export type MutationIdDocumentUploadUrlGenerateArgs = {
+ input: IdDocumentUploadUrlGenerateInput;
+};
+
+
export type MutationInitiateCashoutArgs = {
input: InitiateCashoutInput;
};
@@ -1341,6 +1407,7 @@ export type PublicWallet = {
export type Query = {
readonly __typename: 'Query';
readonly accountDefaultWallet: PublicWallet;
+ readonly accountUpgradeRequest: AccountUpgradeRequestPayload;
readonly beta: Scalars['Boolean']['output'];
/** @deprecated Deprecated in favor of realtimePrice */
readonly btcPrice?: Maybe;
@@ -1704,7 +1771,7 @@ export type UpgradePayload = {
export type UsdWallet = Wallet & {
readonly __typename: 'UsdWallet';
readonly accountId: Scalars['ID']['output'];
- readonly balance: Scalars['SignedAmount']['output'];
+ readonly balance: Scalars['FractionalCentAmount']['output'];
readonly id: Scalars['ID']['output'];
readonly lnurlp?: Maybe;
/** An unconfirmed incoming onchain balance. */
@@ -1962,7 +2029,7 @@ export type UserUpdateUsernamePayload = {
/** A generic wallet which stores value in one of our supported currencies. */
export type Wallet = {
readonly accountId: Scalars['ID']['output'];
- readonly balance: Scalars['SignedAmount']['output'];
+ readonly balance: Scalars['FractionalCentAmount']['output'];
readonly id: Scalars['ID']['output'];
readonly lnurlp?: Maybe;
readonly pendingIncomingBalance: Scalars['SignedAmount']['output'];
@@ -2178,6 +2245,20 @@ export type UserUpdateNpubMutationVariables = Exact<{
export type UserUpdateNpubMutation = { readonly __typename: 'Mutation', readonly userUpdateNpub: { readonly __typename: 'UserUpdateNpubPayload', readonly errors: ReadonlyArray<{ readonly __typename: 'GraphQLApplicationError', readonly code?: string | null }>, readonly user?: { readonly __typename: 'User', readonly id: string, readonly npub?: string | null } | null } };
+export type BusinessAccountUpgradeRequestMutationVariables = Exact<{
+ input: BusinessAccountUpgradeRequestInput;
+}>;
+
+
+export type BusinessAccountUpgradeRequestMutation = { readonly __typename: 'Mutation', readonly businessAccountUpgradeRequest: { readonly __typename: 'SuccessPayload', readonly success?: boolean | null, readonly errors: ReadonlyArray<{ readonly __typename: 'GraphQLApplicationError', readonly message: string, readonly code?: string | null }> } };
+
+export type IdDocumentUploadUrlGenerateMutationVariables = Exact<{
+ input: IdDocumentUploadUrlGenerateInput;
+}>;
+
+
+export type IdDocumentUploadUrlGenerateMutation = { readonly __typename: 'Mutation', readonly idDocumentUploadUrlGenerate: { readonly __typename: 'IdDocumentUploadUrlPayload', readonly fileKey?: string | null, readonly uploadUrl?: string | null, readonly errors: ReadonlyArray<{ readonly __typename: 'GraphQLApplicationError', readonly code?: string | null, readonly message: string }> } };
+
export type AuthQueryVariables = Exact<{ [key: string]: never; }>;
@@ -2286,6 +2367,11 @@ export type NpubByUsernameQueryVariables = Exact<{
export type NpubByUsernameQuery = { readonly __typename: 'Query', readonly npubByUsername?: { readonly __typename: 'npubByUsername', readonly npub?: string | null, readonly username?: string | null } | null };
+export type AccountUpgradeRequestQueryVariables = Exact<{ [key: string]: never; }>;
+
+
+export type AccountUpgradeRequestQuery = { readonly __typename: 'Query', readonly accountUpgradeRequest: { readonly __typename: 'AccountUpgradeRequestPayload', readonly upgradeRequest?: { readonly __typename: 'AccountUpgradeRequest', readonly businessAddress?: string | null, readonly businessName?: string | null, readonly currentLevel: AccountLevel, readonly email?: string | null, readonly fullName: string, readonly name: string, readonly phoneNumber?: string | null, readonly requestedLevel: AccountLevel, readonly status: string, readonly username: string } | null, readonly errors: ReadonlyArray<{ readonly __typename: 'GraphQLApplicationError', readonly code?: string | null, readonly message: string }> } };
+
export type RealtimePriceWsSubscriptionVariables = Exact<{
currency: Scalars['DisplayCurrency']['input'];
}>;
@@ -2293,6 +2379,13 @@ export type RealtimePriceWsSubscriptionVariables = Exact<{
export type RealtimePriceWsSubscription = { readonly __typename: 'Subscription', readonly realtimePrice: { readonly __typename: 'RealtimePricePayload', readonly errors: ReadonlyArray<{ readonly __typename: 'GraphQLApplicationError', readonly message: string }>, readonly realtimePrice?: { readonly __typename: 'RealtimePrice', readonly timestamp: number, readonly denominatorCurrency: string, readonly btcSatPrice: { readonly __typename: 'PriceOfOneSatInMinorUnit', readonly base: number, readonly offset: number }, readonly usdCentPrice: { readonly __typename: 'PriceOfOneUsdCentInMinorUnit', readonly base: number, readonly offset: number } } | null } };
+export type TransactionDetailsQueryVariables = Exact<{
+ input: TransactionDetailsInput;
+}>;
+
+
+export type TransactionDetailsQuery = { readonly __typename: 'Query', readonly transactionDetails: { readonly __typename: 'TransactionDetailsPayload', readonly errors: ReadonlyArray<{ readonly __typename: 'TransactionDetailsError', readonly message: string }>, readonly transactionDetails?: { readonly __typename: 'TransactionDetails', readonly id: string, readonly accountId?: string | null, readonly amount?: number | null, readonly currency?: string | null, readonly status?: string | null, readonly type?: string | null, readonly createdAt?: string | null, readonly updatedAt?: string | null, readonly invoice?: string | null, readonly paymentHash?: string | null, readonly paymentPreimage?: string | null, readonly memo?: string | null, readonly address?: string | null, readonly txid?: string | null, readonly vout?: number | null, readonly confirmations?: number | null, readonly fee?: number | null } | null } };
+
export type NetworkQueryVariables = Exact<{ [key: string]: never; }>;
@@ -2656,13 +2749,6 @@ export type UserTotpRegistrationValidateMutationVariables = Exact<{
export type UserTotpRegistrationValidateMutation = { readonly __typename: 'Mutation', readonly userTotpRegistrationValidate: { readonly __typename: 'UserTotpRegistrationValidatePayload', readonly errors: ReadonlyArray<{ readonly __typename: 'GraphQLApplicationError', readonly message: string }>, readonly me?: { readonly __typename: 'User', readonly totpEnabled: boolean, readonly phone?: string | null, readonly email?: { readonly __typename: 'Email', readonly address?: string | null, readonly verified?: boolean | null } | null } | null } };
-export type TransactionDetailsQueryVariables = Exact<{
- input: TransactionDetailsInput;
-}>;
-
-
-export type TransactionDetailsQuery = { readonly __typename: 'Query', readonly transactionDetails: { readonly __typename: 'TransactionDetailsPayload', readonly errors: ReadonlyArray<{ readonly __typename: 'TransactionDetailsError', readonly message: string }>, readonly transactionDetails?: { readonly __typename: 'TransactionDetails', readonly id: string, readonly accountId?: string | null, readonly amount?: number | null, readonly currency?: string | null, readonly status?: string | null, readonly type?: string | null, readonly createdAt?: string | null, readonly updatedAt?: string | null, readonly invoice?: string | null, readonly paymentHash?: string | null, readonly paymentPreimage?: string | null, readonly memo?: string | null, readonly address?: string | null, readonly txid?: string | null, readonly vout?: number | null, readonly confirmations?: number | null, readonly fee?: number | null } | null } };
-
export type DeviceNotificationTokenCreateMutationVariables = Exact<{
input: DeviceNotificationTokenCreateInput;
}>;
@@ -3697,6 +3783,81 @@ export function useUserUpdateNpubMutation(baseOptions?: Apollo.MutationHookOptio
export type UserUpdateNpubMutationHookResult = ReturnType;
export type UserUpdateNpubMutationResult = Apollo.MutationResult;
export type UserUpdateNpubMutationOptions = Apollo.BaseMutationOptions;
+export const BusinessAccountUpgradeRequestDocument = gql`
+ mutation businessAccountUpgradeRequest($input: BusinessAccountUpgradeRequestInput!) {
+ businessAccountUpgradeRequest(input: $input) {
+ errors {
+ message
+ code
+ }
+ success
+ }
+}
+ `;
+export type BusinessAccountUpgradeRequestMutationFn = Apollo.MutationFunction;
+
+/**
+ * __useBusinessAccountUpgradeRequestMutation__
+ *
+ * To run a mutation, you first call `useBusinessAccountUpgradeRequestMutation` within a React component and pass it any options that fit your needs.
+ * When your component renders, `useBusinessAccountUpgradeRequestMutation` returns a tuple that includes:
+ * - A mutate function that you can call at any time to execute the mutation
+ * - An object with fields that represent the current status of the mutation's execution
+ *
+ * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
+ *
+ * @example
+ * const [businessAccountUpgradeRequestMutation, { data, loading, error }] = useBusinessAccountUpgradeRequestMutation({
+ * variables: {
+ * input: // value for 'input'
+ * },
+ * });
+ */
+export function useBusinessAccountUpgradeRequestMutation(baseOptions?: Apollo.MutationHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useMutation(BusinessAccountUpgradeRequestDocument, options);
+ }
+export type BusinessAccountUpgradeRequestMutationHookResult = ReturnType;
+export type BusinessAccountUpgradeRequestMutationResult = Apollo.MutationResult;
+export type BusinessAccountUpgradeRequestMutationOptions = Apollo.BaseMutationOptions;
+export const IdDocumentUploadUrlGenerateDocument = gql`
+ mutation IdDocumentUploadUrlGenerate($input: IdDocumentUploadUrlGenerateInput!) {
+ idDocumentUploadUrlGenerate(input: $input) {
+ errors {
+ code
+ message
+ }
+ fileKey
+ uploadUrl
+ }
+}
+ `;
+export type IdDocumentUploadUrlGenerateMutationFn = Apollo.MutationFunction;
+
+/**
+ * __useIdDocumentUploadUrlGenerateMutation__
+ *
+ * To run a mutation, you first call `useIdDocumentUploadUrlGenerateMutation` within a React component and pass it any options that fit your needs.
+ * When your component renders, `useIdDocumentUploadUrlGenerateMutation` returns a tuple that includes:
+ * - A mutate function that you can call at any time to execute the mutation
+ * - An object with fields that represent the current status of the mutation's execution
+ *
+ * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
+ *
+ * @example
+ * const [idDocumentUploadUrlGenerateMutation, { data, loading, error }] = useIdDocumentUploadUrlGenerateMutation({
+ * variables: {
+ * input: // value for 'input'
+ * },
+ * });
+ */
+export function useIdDocumentUploadUrlGenerateMutation(baseOptions?: Apollo.MutationHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useMutation(IdDocumentUploadUrlGenerateDocument, options);
+ }
+export type IdDocumentUploadUrlGenerateMutationHookResult = ReturnType;
+export type IdDocumentUploadUrlGenerateMutationResult = Apollo.MutationResult;
+export type IdDocumentUploadUrlGenerateMutationOptions = Apollo.BaseMutationOptions;
export const AuthDocument = gql`
query auth {
me {
@@ -4513,6 +4674,55 @@ export function useNpubByUsernameLazyQuery(baseOptions?: Apollo.LazyQueryHookOpt
export type NpubByUsernameQueryHookResult = ReturnType;
export type NpubByUsernameLazyQueryHookResult = ReturnType;
export type NpubByUsernameQueryResult = Apollo.QueryResult;
+export const AccountUpgradeRequestDocument = gql`
+ query AccountUpgradeRequest {
+ accountUpgradeRequest {
+ upgradeRequest {
+ businessAddress
+ businessName
+ currentLevel
+ email
+ fullName
+ name
+ phoneNumber
+ requestedLevel
+ status
+ username
+ }
+ errors {
+ code
+ message
+ }
+ }
+}
+ `;
+
+/**
+ * __useAccountUpgradeRequestQuery__
+ *
+ * To run a query within a React component, call `useAccountUpgradeRequestQuery` and pass it any options that fit your needs.
+ * When your component renders, `useAccountUpgradeRequestQuery` returns an object from Apollo Client that contains loading, error, and data properties
+ * you can use to render your UI.
+ *
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
+ *
+ * @example
+ * const { data, loading, error } = useAccountUpgradeRequestQuery({
+ * variables: {
+ * },
+ * });
+ */
+export function useAccountUpgradeRequestQuery(baseOptions?: Apollo.QueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useQuery(AccountUpgradeRequestDocument, options);
+ }
+export function useAccountUpgradeRequestLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useLazyQuery(AccountUpgradeRequestDocument, options);
+ }
+export type AccountUpgradeRequestQueryHookResult = ReturnType;
+export type AccountUpgradeRequestLazyQueryHookResult = ReturnType;
+export type AccountUpgradeRequestQueryResult = Apollo.QueryResult;
export const RealtimePriceWsDocument = gql`
subscription realtimePriceWs($currency: DisplayCurrency!) {
realtimePrice(input: {currency: $currency}) {
@@ -4557,6 +4767,62 @@ export function useRealtimePriceWsSubscription(baseOptions: Apollo.SubscriptionH
}
export type RealtimePriceWsSubscriptionHookResult = ReturnType;
export type RealtimePriceWsSubscriptionResult = Apollo.SubscriptionResult;
+export const TransactionDetailsDocument = gql`
+ query transactionDetails($input: TransactionDetailsInput!) {
+ transactionDetails(input: $input) {
+ errors {
+ message
+ }
+ transactionDetails {
+ id
+ accountId
+ amount
+ currency
+ status
+ type
+ createdAt
+ updatedAt
+ invoice
+ paymentHash
+ paymentPreimage
+ memo
+ address
+ txid
+ vout
+ confirmations
+ fee
+ }
+ }
+}
+ `;
+
+/**
+ * __useTransactionDetailsQuery__
+ *
+ * To run a query within a React component, call `useTransactionDetailsQuery` and pass it any options that fit your needs.
+ * When your component renders, `useTransactionDetailsQuery` returns an object from Apollo Client that contains loading, error, and data properties
+ * you can use to render your UI.
+ *
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
+ *
+ * @example
+ * const { data, loading, error } = useTransactionDetailsQuery({
+ * variables: {
+ * input: // value for 'input'
+ * },
+ * });
+ */
+export function useTransactionDetailsQuery(baseOptions: Apollo.QueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useQuery(TransactionDetailsDocument, options);
+ }
+export function useTransactionDetailsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useLazyQuery(TransactionDetailsDocument, options);
+ }
+export type TransactionDetailsQueryHookResult = ReturnType;
+export type TransactionDetailsLazyQueryHookResult = ReturnType;
+export type TransactionDetailsQueryResult = Apollo.QueryResult;
export const NetworkDocument = gql`
query network {
globals {
@@ -6861,62 +7127,6 @@ export function useUserTotpRegistrationValidateMutation(baseOptions?: Apollo.Mut
export type UserTotpRegistrationValidateMutationHookResult = ReturnType;
export type UserTotpRegistrationValidateMutationResult = Apollo.MutationResult;
export type UserTotpRegistrationValidateMutationOptions = Apollo.BaseMutationOptions;
-export const TransactionDetailsDocument = gql`
- query transactionDetails($input: TransactionDetailsInput!) {
- transactionDetails(input: $input) {
- errors {
- message
- }
- transactionDetails {
- id
- accountId
- amount
- currency
- status
- type
- createdAt
- updatedAt
- invoice
- paymentHash
- paymentPreimage
- memo
- address
- txid
- vout
- confirmations
- fee
- }
- }
-}
- `;
-
-/**
- * __useTransactionDetailsQuery__
- *
- * To run a query within a React component, call `useTransactionDetailsQuery` and pass it any options that fit your needs.
- * When your component renders, `useTransactionDetailsQuery` returns an object from Apollo Client that contains loading, error, and data properties
- * you can use to render your UI.
- *
- * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
- *
- * @example
- * const { data, loading, error } = useTransactionDetailsQuery({
- * variables: {
- * input: // value for 'input'
- * },
- * });
- */
-export function useTransactionDetailsQuery(baseOptions: Apollo.QueryHookOptions) {
- const options = {...defaultOptions, ...baseOptions}
- return Apollo.useQuery(TransactionDetailsDocument, options);
- }
-export function useTransactionDetailsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) {
- const options = {...defaultOptions, ...baseOptions}
- return Apollo.useLazyQuery(TransactionDetailsDocument, options);
- }
-export type TransactionDetailsQueryHookResult = ReturnType;
-export type TransactionDetailsLazyQueryHookResult = ReturnType;
-export type TransactionDetailsQueryResult = Apollo.QueryResult;
export const DeviceNotificationTokenCreateDocument = gql`
mutation deviceNotificationTokenCreate($input: DeviceNotificationTokenCreateInput!) {
deviceNotificationTokenCreate(input: $input) {
diff --git a/app/hooks/index.ts b/app/hooks/index.ts
index a9ffe87ce..c457b91ff 100644
--- a/app/hooks/index.ts
+++ b/app/hooks/index.ts
@@ -8,3 +8,4 @@ export * from "./useIbexFee"
export * from "./useFlashcard"
export * from "./useSwap"
export * from "./use-unauthed-price-conversion"
+export * from "./useAccountUpgrade"
diff --git a/app/hooks/useAccountUpgrade.tsx b/app/hooks/useAccountUpgrade.tsx
new file mode 100644
index 000000000..c3441bf68
--- /dev/null
+++ b/app/hooks/useAccountUpgrade.tsx
@@ -0,0 +1,180 @@
+import { useEffect } from "react"
+import { parsePhoneNumber } from "libphonenumber-js"
+
+// hooks
+import { useActivityIndicator } from "./useActivityIndicator"
+import { useAppDispatch, useAppSelector } from "@app/store/redux"
+import {
+ useBusinessAccountUpgradeRequestMutation,
+ HomeAuthedDocument,
+ useIdDocumentUploadUrlGenerateMutation,
+ AccountLevel,
+ useAccountUpgradeRequestQuery,
+} from "@app/graphql/generated"
+
+// store
+import {
+ setAccountUpgrade,
+ setBusinessInfo,
+ setPersonalInfo,
+} from "@app/store/redux/slices/accountUpgradeSlice"
+
+type UpgradeResult = {
+ success: boolean
+ errors?: string[]
+}
+
+export const useAccountUpgrade = () => {
+ const dispatch = useAppDispatch()
+ const { toggleActivityIndicator } = useActivityIndicator()
+ const { accountType, personalInfo, businessInfo, bankInfo } = useAppSelector(
+ (state) => state.accountUpgrade,
+ )
+
+ const { data } = useAccountUpgradeRequestQuery({ fetchPolicy: "cache-and-network" })
+ const upgradeData = data?.accountUpgradeRequest.upgradeRequest
+
+ const [generateIdDocumentUploadUrl] = useIdDocumentUploadUrlGenerateMutation()
+ const [requestAccountUpgrade] = useBusinessAccountUpgradeRequestMutation({
+ refetchQueries: [HomeAuthedDocument],
+ })
+
+ useEffect(() => {
+ if (upgradeData && !personalInfo.fullName) {
+ setAccountUpgradeData()
+ }
+ }, [upgradeData])
+
+ const setAccountUpgradeData = () => {
+ if (upgradeData) {
+ const parsedPhone = upgradeData.phoneNumber
+ ? parsePhoneNumber(upgradeData.phoneNumber)
+ : undefined
+ dispatch(
+ setAccountUpgrade({
+ upgradeCompleted: upgradeData.requestedLevel === AccountLevel.Three,
+ }),
+ )
+ dispatch(
+ setPersonalInfo({
+ fullName: upgradeData.fullName,
+ countryCode: parsedPhone?.country,
+ phoneNumber: parsedPhone?.nationalNumber,
+ email: upgradeData.email,
+ }),
+ )
+ dispatch(
+ setBusinessInfo({
+ businessName: upgradeData.businessName,
+ businessAddress: upgradeData.businessAddress,
+ }),
+ )
+ }
+ }
+
+ const uploadIdDocument = async (): Promise => {
+ const { idDocument } = bankInfo
+ if (!idDocument?.fileName || !idDocument.type || !idDocument.uri) {
+ return null
+ }
+
+ const { data } = await generateIdDocumentUploadUrl({
+ variables: {
+ input: {
+ filename: idDocument.fileName,
+ contentType: idDocument.type,
+ },
+ },
+ })
+
+ if (!data?.idDocumentUploadUrlGenerate.uploadUrl) {
+ throw new Error("Failed to generate upload URL to upload ID Document")
+ }
+
+ await uploadFileToS3(
+ data.idDocumentUploadUrlGenerate.uploadUrl,
+ idDocument.uri,
+ idDocument.type,
+ )
+
+ return data.idDocumentUploadUrlGenerate.fileKey ?? null
+ }
+
+ const submitAccountUpgrade = async (): Promise => {
+ toggleActivityIndicator(true)
+
+ try {
+ const idDocument = await uploadIdDocument()
+
+ const input = {
+ accountNumber: Number(bankInfo.accountNumber),
+ accountType: bankInfo.bankAccountType,
+ bankBranch: bankInfo.bankBranch,
+ bankName: bankInfo.bankName,
+ businessAddress: businessInfo.businessAddress,
+ businessName: businessInfo.businessName,
+ currency: bankInfo.currency,
+ email: personalInfo.email,
+ fullName: personalInfo.fullName || "",
+ idDocument: idDocument,
+ level: accountType || "ONE",
+ terminalRequested: businessInfo.terminalRequested,
+ }
+
+ const { data } = await requestAccountUpgrade({
+ variables: { input },
+ })
+
+ if (data?.businessAccountUpgradeRequest?.errors?.length) {
+ return {
+ success: false,
+ errors: data.businessAccountUpgradeRequest.errors.map((e) => e.message),
+ }
+ }
+ if (accountType === AccountLevel.Three)
+ dispatch(setAccountUpgrade({ upgradeCompleted: true }))
+
+ return {
+ success: data?.businessAccountUpgradeRequest?.success ?? false,
+ }
+ } catch (err) {
+ console.error("Account upgrade failed:", err)
+ return {
+ success: false,
+ errors: [err instanceof Error ? err.message : "Unknown error occurred"],
+ }
+ } finally {
+ toggleActivityIndicator(false)
+ }
+ }
+
+ return { submitAccountUpgrade }
+}
+
+const uploadFileToS3 = async (
+ uploadUrl: string,
+ fileUri: string,
+ contentType: string,
+): Promise => {
+ const blob = await fetch(fileUri).then((res) => res.blob())
+
+ return new Promise((resolve, reject) => {
+ const xhr = new XMLHttpRequest()
+ xhr.open("PUT", uploadUrl, true)
+ xhr.setRequestHeader("Content-Type", contentType)
+
+ xhr.onreadystatechange = () => {
+ if (xhr.readyState === 4) {
+ if (xhr.status >= 200 && xhr.status < 300) {
+ resolve()
+ } else {
+ reject(new Error(`Upload ID Document failed with status ${xhr.status}`))
+ }
+ }
+ }
+
+ xhr.onerror = () => reject(new Error("Network error during upload"))
+
+ xhr.send(blob)
+ })
+}
diff --git a/app/i18n/en/index.ts b/app/i18n/en/index.ts
index 6e0f61c74..72dd9a6f5 100644
--- a/app/i18n/en/index.ts
+++ b/app/i18n/en/index.ts
@@ -550,8 +550,9 @@ const en: BaseTranslation = {
bitcoin: "Bitcoin",
flashcard: "Flashcard",
addFlashcard: "Add Flashcard",
- upgradeTitle: "Add your phone number",
- upgradeDesc: "Backup your cash wallet and increase transaction limits.",
+ upgradeTitle: "Upgrade your account",
+ upgradeDesc: "Unlock your full potential! Upgrade to boost visibility, limits, and payouts.",
+ upgradePendingDesc: "Enter test transaction amount to complete upgrading your account.",
currencyTitle:"Change to your local currency",
currencyDesc: "Review our available currency list and select your currency.",
flashcardTitle: "Get a Flashcard",
@@ -1077,7 +1078,7 @@ const en: BaseTranslation = {
increaseLimits: "Increase your limits",
spendingLimits: "Spending Limits",
spendingLimitsDescription: "The spending limits shown on this page are denominated in USD. For your convenience, we convert these limits into your local currency based on current foreign exchange rates. Please note that the displayed local currency amount may fluctuate as exchange rates are updated in real-time.",
- requestBusiness: "Request Business Account",
+ requestUpgrade: "Request Upgrade",
},
TransactionScreen: {
noTransaction: "No transaction to show",
@@ -1417,7 +1418,7 @@ const en: BaseTranslation = {
createProfilePubkeyMessage: "We couldn't find a profile event attached to this pubkey.",
createProfilePrompt: "Do you want to continue to create?",
createProfileButton: "Create Profile",
- profileNotFound: "We’re looking, but we haven’t been able to find your profile.",
+ profileNotFound: "We're looking, but we haven't been able to find your profile.",
promptToCreateProfile: "Would you like to create one now?",
learnAboutNostr: "Learn about Nostr",
learnAboutNostrSubtext: "Explore this guide to get the most out of nostr chat",
@@ -1436,7 +1437,7 @@ const en: BaseTranslation = {
importNsecDescription: "If you wish to use your own nsec, paste it below.",
profileImportedSuccessfully: "Profile imported successfully",
noProfileFound: "No Nostr Profile Found",
- noProfileDescription: "You haven’t created a Nostr profile yet.\nTap below to create one.",
+ noProfileDescription: "You haven't created a Nostr profile yet.\nTap below to create one.",
creatingProfile: "Creating Profile...",
createNewProfile: "Create New Profile",
findingYou: "Finding You..",
@@ -1465,7 +1466,43 @@ const en: BaseTranslation = {
copied: "Copied",
goToSettings: "Go to settings"
}
- }
+ },
+ AccountUpgrade: {
+ accountType: "Account Type",
+ personal: "Personal",
+ personalDesc: "Secure your wallet with phone and email. Stay safe and recover easily if needed",
+ pro: "Pro",
+ proDesc: "Accept payments and get discovered on the map. Requires a business name and location.",
+ merchant: "Merchant",
+ merchantDesc: "Give rewards, appear on the map, and settle to your bank. ID and bank info required.",
+ personalInfo: "Personal Information",
+ fullName: "Full name",
+ phoneNumber: "Phone Number",
+ email: "Email Address",
+ optional: " (Optional)",
+ validation: "Validation",
+ validationCode: "Validation code",
+ businessInfo: "Business Information",
+ businessName: "Business Name",
+ businessNamePlaceholder: "Enter your business name",
+ businessAddress: "Business Address",
+ businessAddressPlaceholder: "Enter your business address",
+ flashTerminal: "Do you want a Flash terminal?",
+ flashTerminalTooltip: "A Flash Terminal is a smart device that can accept payment via Flash for your business and print receipts. A customer service representative will contact you if you check this box.",
+ bankingInfo: "Banking Information",
+ bankName: "Bank Name",
+ bankNamePlaceholder: "Enter your bank name",
+ bankBranch: "Bank Branch",
+ bankBranchPlaceholder: "Enter your bank branch",
+ bankAccountType: "Account Type",
+ selectBankAccountType: "Select account type",
+ currency: "Currency",
+ selectCurrency: "Select Currency",
+ accountNum: "Account Number",
+ accountNumPlaceholder: "Enter your account number",
+ uploadId: "Upload ID Document",
+ successTitle: "You successfully requested to upgrade your account to {accountType: string}",
+ }
}
export default en
diff --git a/app/i18n/i18n-types.ts b/app/i18n/i18n-types.ts
index 9ab25b6e9..9f1e15e0d 100644
--- a/app/i18n/i18n-types.ts
+++ b/app/i18n/i18n-types.ts
@@ -1721,15 +1721,19 @@ type RootTranslation = {
*/
addFlashcard: string
/**
- * A​d​d​ ​y​o​u​r​ ​p​h​o​n​e​ ​n​u​m​b​e​r
+ * U​p​g​r​a​d​e​ ​y​o​u​r​ ​a​c​c​o​u​n​t
*/
upgradeTitle: string
/**
- * B​a​c​k​u​p​ ​y​o​u​r​ ​c​a​s​h​ ​w​a​l​l​e​t​ ​a​n​d​ ​i​n​c​r​e​a​s​e​ ​t​r​a​n​s​a​c​t​i​o​n​ ​l​i​m​i​t​s​.
+ * U​n​l​o​c​k​ ​y​o​u​r​ ​f​u​l​l​ ​p​o​t​e​n​t​i​a​l​!​ ​U​p​g​r​a​d​e​ ​t​o​ ​b​o​o​s​t​ ​v​i​s​i​b​i​l​i​t​y​,​ ​l​i​m​i​t​s​,​ ​a​n​d​ ​p​a​y​o​u​t​s​.
*/
upgradeDesc: string
/**
- * C​h​a​n​g​e​ ​t​o​ ​y​o​u​r​ ​l​o​c​a​l​ ​c​u​r​r​e​n​c​y
+ * Enter test transaction amount to complete upgrading your account.
+ */
+ upgradePendingDesc: string
+ /**
+ * Change to your local currency
*/
currencyTitle: string
/**
@@ -3487,9 +3491,9 @@ type RootTranslation = {
*/
spendingLimitsDescription: string
/**
- * R​e​q​u​e​s​t​ ​B​u​s​i​n​e​s​s​ ​A​c​c​o​u​n​t
+ * Request Upgrade
*/
- requestBusiness: string
+ requestUpgrade: string
}
TransactionScreen: {
/**
@@ -4593,6 +4597,145 @@ type RootTranslation = {
* T​r​a​n​s​a​c​t​i​o​n​ ​I​D
*/
txId: string
+ },
+ AccountUpgrade: {
+ /**
+ * Account Type
+ */
+ accountType: string
+ /**
+ * Personal
+ */
+ personal: string
+ /**
+ * Secure your wallet with phone and email. Stay safe and recover easily if needed
+ */
+ personalDesc: string
+ /**
+ * Pro
+ */
+ pro: string
+ /**
+ * Accept payments and get discovered on the map. Requires a business name and location.
+ */
+ proDesc: string
+ /**
+ * Merchant
+ */
+ merchant: string
+ /**
+ * Give rewards, appear on the map, and settle to your bank. ID and bank info required.
+ */
+ merchantDesc: string
+ /**
+ * Personal Information
+ */
+ personalInfo: string
+ /**
+ * Full name
+ */
+ fullName: string
+ /**
+ * Phone Number
+ */
+ phoneNumber: string
+ /**
+ * Email Address
+ */
+ email: string
+ /**
+ * Optional
+ */
+ optional: string
+ /**
+ * Validation
+ */
+ validation: string
+ /**
+ * Validation code
+ */
+ validationCode: string
+ /**
+ * Business Information
+ */
+ businessInfo: string
+ /**
+ * Business Name
+ */
+ businessName: string
+ /**
+ * Enter your business name
+ */
+ businessNamePlaceholder: string
+ /**
+ * Business Address
+ */
+ businessAddress: string
+ /**
+ * Enter your business address
+ */
+ businessAddressPlaceholder: string
+ /**
+ * Do you want a Flash terminal?
+ */
+ flashTerminal: string
+ /**
+ * A Flash Terminal is a smart device that can accept payment via Flash for your business and print receipts. A customer service representative will contact you if you check this box.
+ */
+ flashTerminalTooltip: string
+ /**
+ * Banking Information
+ */
+ bankingInfo: string
+ /**
+ * Bank Name
+ */
+ bankName: string
+ /**
+ * Enter your bank name
+ */
+ bankNamePlaceholder: string
+ /**
+ * Bank Branch
+ */
+ bankBranch: string
+ /**
+ * Enter your bank branch
+ */
+ bankBranchPlaceholder: string
+ /**
+ * Account Type
+ */
+ bankAccountType: string
+ /**
+ * Select account type
+ */
+ selectBankAccountType: string,
+ /**
+ * Currency
+ */
+ currency: string
+ /**
+ * Select currency
+ */
+ selectCurrency: string,
+ /**
+ * Account Number
+ */
+ accountNum: string
+ /**
+ * Enter your account number
+ */
+ accountNumPlaceholder: string
+ /**
+ * Upload ID Document
+ */
+ uploadId: string
+ /**
+ * You successfully requested to upgrade your account to {accountType}
+ * @param {string} accountType
+ */
+ successTitle: RequiredParams<'accountType'>
}
Nostr: {
/**
@@ -4799,7 +4942,8 @@ type RootTranslation = {
goToSettings: string
}
}
-}
+ }
+
export type TranslationFunctions = {
GaloyAddressScreen: {
@@ -6479,13 +6623,17 @@ export type TranslationFunctions = {
*/
addFlashcard: () => LocalizedString
/**
- * Add your phone number
+ * Upgrade your account
*/
upgradeTitle: () => LocalizedString
/**
- * Backup your cash wallet and increase transaction limits.
+ * Unlock your full potential! Upgrade to boost visibility, limits, and payouts.
*/
upgradeDesc: () => LocalizedString
+ /**
+ * Enter test transaction amount to complete upgrading your account.
+ */
+ upgradePendingDesc: () => LocalizedString
/**
* Change to your local currency
*/
@@ -8194,9 +8342,9 @@ export type TranslationFunctions = {
*/
spendingLimitsDescription: () => LocalizedString
/**
- * Request Business Account
+ * Request Upgrade
*/
- requestBusiness: () => LocalizedString
+ requestUpgrade: () => LocalizedString
}
TransactionScreen: {
/**
@@ -9309,7 +9457,7 @@ export type TranslationFunctions = {
*/
createProfileButton: () => LocalizedString
/**
- * We’re looking, but we haven’t been able to find your profile.
+ * We're looking, but we haven't been able to find your profile.
*/
profileNotFound: () => LocalizedString
/**
@@ -9381,7 +9529,7 @@ export type TranslationFunctions = {
*/
noProfileFound: () => LocalizedString
/**
- * You haven’t created a Nostr profile yet.
+ * You haven't created a Nostr profile yet.
Tap below to create one.
*/
noProfileDescription: () => LocalizedString
@@ -9480,8 +9628,148 @@ export type TranslationFunctions = {
goToSettings: () => LocalizedString
}
}
+ AccountUpgrade: {
+ /**
+ * Account Type
+ */
+ accountType: () => LocalizedString
+ /**
+ * Personal
+ */
+ personal: () => LocalizedString
+ /**
+ * Secure your wallet with phone and email. Stay safe and recover easily if needed
+ */
+ personalDesc: () => LocalizedString
+ /**
+ * Pro
+ */
+ pro: () => LocalizedString
+ /**
+ * Accept payments and get discovered on the map. Requires a business name and location.
+ */
+ proDesc: () => LocalizedString
+ /**
+ * Merchant
+ */
+ merchant: () => LocalizedString
+ /**
+ * Give rewards, appear on the map, and settle to your bank. ID and bank info required.
+ */
+ merchantDesc: () => LocalizedString
+ /**
+ * Personal Information
+ */
+ personalInfo: () => LocalizedString
+ /**
+ * Full name
+ */
+ fullName: () => LocalizedString
+ /**
+ * Phone Number
+ */
+ phoneNumber: () => LocalizedString
+ /**
+ * Email Address
+ */
+ email: () => LocalizedString
+ /**
+ * (Optional)
+ */
+ optional: () => LocalizedString
+ /**
+ * Validation
+ */
+ validation: () => LocalizedString
+ /**
+ * Validation code
+ */
+ validationCode: () => LocalizedString
+ /**
+ * Business Information
+ */
+ businessInfo: () => LocalizedString
+ /**
+ * Business Name
+ */
+ businessName: () => LocalizedString
+ /**
+ * Enter your business name
+ */
+ businessNamePlaceholder: () => LocalizedString
+ /**
+ * Business Address
+ */
+ businessAddress: () => LocalizedString
+ /**
+ * Enter your business address
+ */
+ businessAddressPlaceholder: () => LocalizedString
+ /**
+ * Do you want a Flash terminal?
+ */
+ flashTerminal: () => LocalizedString
+ /**
+ * A Flash Terminal is a smart device that can accept payment via Flash for your business and print receipts. A customer service representative will contact you if you check this box.
+ */
+ flashTerminalTooltip: () => LocalizedString
+ /**
+ * Banking Information
+ */
+ bankingInfo: () => LocalizedString
+ /**
+ * Bank Name
+ */
+ bankName: () => LocalizedString
+ /**
+ * Enter your bank name
+ */
+ bankNamePlaceholder: () => LocalizedString
+ /**
+ * Bank Branch
+ */
+ bankBranch: () => LocalizedString
+ /**
+ * Enter your bank branch
+ */
+ bankBranchPlaceholder: () => LocalizedString
+ /**
+ * Account Type
+ */
+ bankAccountType: () => LocalizedString
+ /**
+ * Select account type
+ */
+ selectBankAccountType: () => LocalizedString
+ /**
+ * Currency
+ */
+ currency: () => LocalizedString
+ /**
+ * Select Currency
+ */
+ selectCurrency: () => LocalizedString
+ /**
+ * Account Number
+ */
+ accountNum: () => LocalizedString
+ /**
+ * Enter your account number
+ */
+ accountNumPlaceholder: () => LocalizedString
+ /**
+ * Upload ID Document
+ */
+ uploadId: () => LocalizedString
+ /**
+ * You successfully requested to upgrade your account to {accountType}
+ */
+ successTitle: (arg: { accountType: string }) => LocalizedString
+
+ }
}
+
export type Formatters = {
sats: (value: unknown) => unknown
}
diff --git a/app/i18n/raw-i18n/source/en.json b/app/i18n/raw-i18n/source/en.json
index a30c1b94e..b1bf045e1 100644
--- a/app/i18n/raw-i18n/source/en.json
+++ b/app/i18n/raw-i18n/source/en.json
@@ -519,8 +519,9 @@
"bitcoin": "Bitcoin",
"flashcard": "Flashcard",
"addFlashcard": "Add Flashcard",
- "upgradeTitle": "Add your phone number",
- "upgradeDesc": "Backup your cash wallet and increase transaction limits.",
+ "upgradeTitle": "Upgrade your account",
+ "upgradeDesc": "Unlock your full potential! Upgrade to boost visibility, limits, and payouts.",
+ "upgradePendingDesc": "Enter test transaction amount to complete upgrading your account.",
"currencyTitle": "Change to your local currency",
"currencyDesc": "Review our available currency list and select your currency.",
"flashcardTitle": "Get a Flashcard",
@@ -1003,7 +1004,7 @@
"increaseLimits": "Increase your limits",
"spendingLimits": "Spending Limits",
"spendingLimitsDescription": "The spending limits shown on this page are denominated in USD. For your convenience, we convert these limits into your local currency based on current foreign exchange rates. Please note that the displayed local currency amount may fluctuate as exchange rates are updated in real-time.",
- "requestBusiness": "Request Business Account"
+ "requestUpgrade": "Request Upgrade"
},
"TransactionScreen": {
"noTransaction": "No transaction to show",
@@ -1369,5 +1370,41 @@
"copied": "Copied",
"goToSettings": "Go to settings"
}
+ },
+ "AccountUpgrade": {
+ "accountType": "Account Type",
+ "personal": "Personal",
+ "personalDesc": "Secure your wallet with phone and email. Stay safe and recover easily if needed",
+ "pro": "Pro",
+ "proDesc": "Accept payments and get discovered on the map. Requires a business name and location.",
+ "merchant": "Merchant",
+ "merchantDesc": "Give rewards, appear on the map, and settle to your bank. ID and bank info required.",
+ "personalInfo": "Personal Information",
+ "fullName": "Full name",
+ "phoneNumber": "Phone Number",
+ "email": "Email Address",
+ "optional": " (Optional)",
+ "validation": "Validation",
+ "validationCode": "Validation code",
+ "businessInfo": "Business Information",
+ "businessName": "Business Name",
+ "businessNamePlaceholder": "Enter your business name",
+ "businessAddress": "Business Address",
+ "businessAddressPlaceholder": "Enter your business address",
+ "flashTerminal": "Do you want a Flash terminal?",
+ "flashTerminalTooltip": "A Flash Terminal is a smart device that can accept payment via Flash for your business and print receipts. A customer service representative will contact you if you check this box.",
+ "bankingInfo": "Banking Information",
+ "bankName": "Bank Name",
+ "bankNamePlaceholder": "Enter your bank name",
+ "bankBranch": "Bank Branch",
+ "bankBranchPlaceholder": "Enter your bank branch",
+ "bankAccountType": "Account Type",
+ "selectBankAccountType": "Select account type",
+ "currency": "Currency",
+ "selectCurrency": "Select Currency",
+ "accountNum": "Account Number",
+ "accountNumPlaceholder": "Enter your account number",
+ "uploadId": "Upload ID Document",
+ "successTitle": "You successfully requested to upgrade your account to {accountType: string}",
}
}
diff --git a/app/navigation/root-navigator.tsx b/app/navigation/root-navigator.tsx
index e431abb43..1ed372e5c 100644
--- a/app/navigation/root-navigator.tsx
+++ b/app/navigation/root-navigator.tsx
@@ -118,6 +118,14 @@ import { NostrSettingsScreen } from "@app/screens/settings-screen/nostr-settings
import ContactDetailsScreen from "@app/screens/chat/contactDetailsScreen"
import { SupportGroupChatScreen } from "@app/screens/chat/GroupChat/SupportGroupChat"
import Contacts from "@app/screens/chat/contacts"
+import {
+ PersonalInformation,
+ BusinessInformation,
+ BankInformation,
+ AccountType,
+ Validation,
+ Success,
+} from "@app/screens/account-upgrade-flow"
const useStyles = makeStyles(({ colors }) => ({
bottomNavigatorStyle: {
@@ -586,6 +594,36 @@ export const RootStack = () => {
component={SupportGroupChatScreen}
options={{ title: "Group Chat" }}
/>
+
+
+
+
+
+
)
}
diff --git a/app/navigation/stack-param-lists.ts b/app/navigation/stack-param-lists.ts
index cb8e8d321..bf6aae75e 100644
--- a/app/navigation/stack-param-lists.ts
+++ b/app/navigation/stack-param-lists.ts
@@ -154,6 +154,15 @@ export type RootStackParamList = {
Contacts: { userPrivateKey: string }
SignInViaQRCode: undefined
Nip29GroupChat: { groupId: string }
+ AccountType: undefined
+ PersonalInformation: undefined
+ BusinessInformation: undefined
+ BankInformation: undefined
+ Validation: {
+ phone: string
+ channel: PhoneCodeChannelType
+ }
+ AccountUpgradeSuccess: undefined
}
export type ChatStackParamList = {
diff --git a/app/screens/account-upgrade-flow/AccountType.tsx b/app/screens/account-upgrade-flow/AccountType.tsx
new file mode 100644
index 000000000..2946d94fc
--- /dev/null
+++ b/app/screens/account-upgrade-flow/AccountType.tsx
@@ -0,0 +1,103 @@
+import React, { useEffect } from "react"
+import { TouchableOpacity, View } from "react-native"
+import { StackScreenProps } from "@react-navigation/stack"
+import { Icon, makeStyles, Text, useTheme } from "@rneui/themed"
+import { RootStackParamList } from "@app/navigation/stack-param-lists"
+import { AccountLevel } from "@app/graphql/generated"
+
+// components
+import { Screen } from "@app/components/screen"
+import { ProgressSteps } from "@app/components/account-upgrade-flow"
+
+// hooks
+import { useLevel } from "@app/graphql/level-context"
+import { useAccountUpgrade } from "@app/hooks"
+import { useI18nContext } from "@app/i18n/i18n-react"
+
+// store
+import { useAppDispatch } from "@app/store/redux"
+import { setAccountUpgrade } from "@app/store/redux/slices/accountUpgradeSlice"
+
+type Props = StackScreenProps
+
+const AccountType: React.FC = ({ navigation }) => {
+ const dispatch = useAppDispatch()
+ const styles = useStyles()
+ const { colors } = useTheme().theme
+ const { LL } = useI18nContext()
+ const { currentLevel } = useLevel()
+
+ const onPress = (accountType: string) => {
+ const numOfSteps =
+ accountType === AccountLevel.One ? 3 : currentLevel === AccountLevel.Zero ? 5 : 4
+
+ dispatch(setAccountUpgrade({ accountType, numOfSteps }))
+ navigation.navigate("PersonalInformation")
+ }
+
+ const numOfSteps = currentLevel === AccountLevel.Zero ? 3 : 4
+
+ return (
+
+
+ {currentLevel === AccountLevel.Zero && (
+ onPress(AccountLevel.One)}>
+
+
+
+ {LL.AccountUpgrade.personal()}
+
+
+ {LL.AccountUpgrade.personalDesc()}
+
+
+
+
+ )}
+ {(currentLevel === AccountLevel.Zero || currentLevel === AccountLevel.One) && (
+ onPress(AccountLevel.Two)}>
+
+
+
+ {LL.AccountUpgrade.pro()}
+
+
+ {LL.AccountUpgrade.proDesc()}
+
+
+
+
+ )}
+ onPress(AccountLevel.Three)}>
+
+
+
+ {LL.AccountUpgrade.merchant()}
+
+
+ {LL.AccountUpgrade.merchantDesc()}
+
+
+
+
+
+ )
+}
+
+export default AccountType
+
+const useStyles = makeStyles(({ colors }) => ({
+ card: {
+ flexDirection: "row",
+ alignItems: "center",
+ backgroundColor: colors.grey5,
+ padding: 15,
+ marginHorizontal: 20,
+ marginVertical: 10,
+ borderRadius: 20,
+ },
+ textWrapper: {
+ flex: 1,
+ marginHorizontal: 15,
+ },
+}))
diff --git a/app/screens/account-upgrade-flow/BankInformation.tsx b/app/screens/account-upgrade-flow/BankInformation.tsx
new file mode 100644
index 000000000..4ac047269
--- /dev/null
+++ b/app/screens/account-upgrade-flow/BankInformation.tsx
@@ -0,0 +1,198 @@
+import React, { useState } from "react"
+import { ScrollView } from "react-native"
+import { makeStyles } from "@rneui/themed"
+import { StackScreenProps } from "@react-navigation/stack"
+import { RootStackParamList } from "@app/navigation/stack-param-lists"
+
+// components
+import {
+ DropDownField,
+ InputField,
+ PhotoUploadField,
+ ProgressSteps,
+} from "@app/components/account-upgrade-flow"
+import { Screen } from "@app/components/screen"
+import { PrimaryBtn } from "@app/components/buttons"
+
+// hooks
+import { useAccountUpgrade } from "@app/hooks"
+import { useI18nContext } from "@app/i18n/i18n-react"
+
+// store
+import { useAppDispatch, useAppSelector } from "@app/store/redux"
+import { setBankInfo } from "@app/store/redux/slices/accountUpgradeSlice"
+
+// gql
+import { AccountLevel } from "@app/graphql/generated"
+
+const accountTypes = [
+ { label: "Select account type", value: null },
+ { label: "Checking", value: "checking" },
+ { label: "Savings", value: "savings" },
+]
+
+const currencies = [
+ { label: "Select currency", value: null },
+ { label: "USD - US Dollar", value: "usd" },
+ { label: "EUR - Euro", value: "eur" },
+ { label: "JMD - Jamaican Dollar", value: "jmd" },
+ { label: "KYD - Cayman Islands Dollar", value: "kyd" },
+ { label: "ANG - Netherlands Antillean Guilder", value: "ang" },
+ { label: "XCG - Caribbean Guilder", value: "xcg" },
+]
+
+type Props = StackScreenProps
+
+const BankInformation: React.FC = ({ navigation }) => {
+ const dispatch = useAppDispatch()
+ const styles = useStyles()
+ const { LL } = useI18nContext()
+ const { submitAccountUpgrade } = useAccountUpgrade()
+
+ const [nameErr, setNameErr] = useState()
+ const [branchErr, setBranchErr] = useState()
+ const [accountTypeErr, setAccountTypeErr] = useState()
+ const [currencyErr, setCurrencyErr] = useState()
+ const [accountNumErr, setAccountNumErr] = useState()
+ const [idDocumentErr, setIdDocumentErr] = useState()
+ const {
+ accountType,
+ numOfSteps,
+ bankInfo: {
+ bankName,
+ bankBranch,
+ bankAccountType,
+ currency,
+ accountNumber,
+ idDocument,
+ },
+ } = useAppSelector((state) => state.accountUpgrade)
+
+ const onPressNext = async () => {
+ let hasError = false
+ if (accountType === AccountLevel.Three) {
+ if (!bankName || bankName.length < 2) {
+ setNameErr("Bank name is required")
+ hasError = true
+ }
+ if (!bankBranch || bankBranch.length < 2) {
+ setBranchErr("Branch is required")
+ hasError = true
+ }
+ if (!bankAccountType) {
+ setAccountTypeErr("Account type is required")
+ hasError = true
+ }
+ if (!currency) {
+ setCurrencyErr("Currency is required")
+ hasError = true
+ }
+ if (!accountNumber || accountNumber.length < 4) {
+ setAccountNumErr("Account number is required")
+ hasError = true
+ }
+ }
+
+ if (!idDocument) {
+ setIdDocumentErr("You must upload an ID document before proceeding")
+ hasError = true
+ }
+
+ if (!hasError) {
+ const res = await submitAccountUpgrade()
+ if (res.success) navigation.navigate("AccountUpgradeSuccess")
+ else alert(res.errors)
+ }
+ }
+ const isOptional = accountType === AccountLevel.Two
+ return (
+
+
+
+ {
+ setNameErr(undefined)
+ dispatch(setBankInfo({ bankName: val }))
+ }}
+ autoCapitalize="words"
+ />
+ {
+ setBranchErr(undefined)
+ dispatch(setBankInfo({ bankBranch: val }))
+ }}
+ autoCapitalize="words"
+ />
+ {
+ setAccountTypeErr(undefined)
+ dispatch(setBankInfo({ bankAccountType: val }))
+ }}
+ />
+ {
+ setCurrencyErr(undefined)
+ dispatch(setBankInfo({ currency: val }))
+ }}
+ />
+ {
+ setAccountNumErr(undefined)
+ dispatch(setBankInfo({ accountNumber: val }))
+ }}
+ autoCapitalize="words"
+ keyboardType="number-pad"
+ />
+ dispatch(setBankInfo({ idDocument: val }))}
+ setErrorMsg={setIdDocumentErr}
+ />
+
+
+
+ )
+}
+
+export default BankInformation
+
+const useStyles = makeStyles(({ colors }) => ({
+ container: {
+ flex: 1,
+ paddingVertical: 10,
+ paddingHorizontal: 20,
+ },
+ btn: {
+ marginVertical: 10,
+ marginHorizontal: 20,
+ },
+}))
diff --git a/app/screens/account-upgrade-flow/BusinessInformation.tsx b/app/screens/account-upgrade-flow/BusinessInformation.tsx
new file mode 100644
index 000000000..6a5f336f1
--- /dev/null
+++ b/app/screens/account-upgrade-flow/BusinessInformation.tsx
@@ -0,0 +1,116 @@
+import React, { useState } from "react"
+import { View } from "react-native"
+import { makeStyles } from "@rneui/themed"
+import { StackScreenProps } from "@react-navigation/stack"
+import { RootStackParamList } from "@app/navigation/stack-param-lists"
+
+// components
+import { Screen } from "@app/components/screen"
+import { PrimaryBtn } from "@app/components/buttons"
+import {
+ AddressField,
+ CheckBoxField,
+ InputField,
+ ProgressSteps,
+} from "@app/components/account-upgrade-flow"
+
+// hooks
+import { useI18nContext } from "@app/i18n/i18n-react"
+
+// store
+import { useAppDispatch, useAppSelector } from "@app/store/redux"
+import { setBusinessInfo } from "@app/store/redux/slices/accountUpgradeSlice"
+
+type Props = StackScreenProps
+
+const BusinessInformation: React.FC = ({ navigation }) => {
+ const dispatch = useAppDispatch()
+ const styles = useStyles()
+ const { LL } = useI18nContext()
+
+ const [businessNameErr, setBusinessNameErr] = useState()
+ const [businessAddressErr, setBusinessAddressErr] = useState()
+ const {
+ numOfSteps,
+ businessInfo: { businessName, businessAddress, terminalRequested },
+ } = useAppSelector((state) => state.accountUpgrade)
+
+ const onPressNext = async () => {
+ let hasError = false
+ if (businessName && businessName.length < 2) {
+ setBusinessNameErr("Business name must be at least 2 characters")
+ hasError = true
+ }
+ if (businessAddress && businessAddress.length < 2) {
+ setBusinessAddressErr("Please enter a valid address")
+ hasError = true
+ }
+ if (!hasError) {
+ navigation.navigate("BankInformation")
+ }
+ }
+
+ return (
+
+
+
+ {
+ setBusinessNameErr(undefined)
+ dispatch(setBusinessInfo({ businessName: val }))
+ }}
+ autoCapitalize="words"
+ />
+
+ dispatch(setBusinessInfo({ businessAddress: val, lat, lng }))
+ }
+ />
+
+ dispatch(setBusinessInfo({ terminalRequested: !terminalRequested }))
+ }
+ />
+
+
+
+ )
+}
+
+export default BusinessInformation
+
+const useStyles = makeStyles(({ colors }) => ({
+ container: {
+ flex: 1,
+ paddingVertical: 10,
+ paddingHorizontal: 20,
+ },
+ btn: {
+ marginBottom: 10,
+ marginHorizontal: 20,
+ },
+ terminalRequest: {
+ flexDirection: "row",
+ alignItems: "center",
+ marginTop: 15,
+ },
+}))
diff --git a/app/screens/account-upgrade-flow/PersonalInformation.tsx b/app/screens/account-upgrade-flow/PersonalInformation.tsx
new file mode 100644
index 000000000..605fb07c0
--- /dev/null
+++ b/app/screens/account-upgrade-flow/PersonalInformation.tsx
@@ -0,0 +1,234 @@
+import React, { useEffect, useState } from "react"
+import { View } from "react-native"
+import { makeStyles } from "@rneui/themed"
+import { StackScreenProps } from "@react-navigation/stack"
+import { RootStackParamList } from "@app/navigation/stack-param-lists"
+import { AccountLevel, PhoneCodeChannelType, useAuthQuery } from "@app/graphql/generated"
+import { CountryCode } from "react-native-country-picker-modal"
+import { parsePhoneNumber } from "libphonenumber-js/mobile"
+
+// components
+import { Screen } from "@app/components/screen"
+import { PrimaryBtn } from "@app/components/buttons"
+import {
+ InputField,
+ PhoneNumber,
+ ProgressSteps,
+} from "@app/components/account-upgrade-flow"
+
+// store
+import { useAppDispatch, useAppSelector } from "@app/store/redux"
+import { setPersonalInfo } from "@app/store/redux/slices/accountUpgradeSlice"
+
+// hooks
+import {
+ RequestPhoneCodeStatus,
+ useRequestPhoneCodeLogin,
+} from "../phone-auth-screen/request-phone-code-login"
+import { useLevel } from "@app/graphql/level-context"
+import { useI18nContext } from "@app/i18n/i18n-react"
+import { useActivityIndicator } from "@app/hooks"
+import { useUserEmailRegistrationInitiateMutation } from "@app/graphql/generated"
+
+type Props = StackScreenProps
+
+const PersonalInformation: React.FC = ({ navigation }) => {
+ const dispatch = useAppDispatch()
+ const styles = useStyles()
+ const { currentLevel } = useLevel()
+ const { LL } = useI18nContext()
+ const { toggleActivityIndicator } = useActivityIndicator()
+
+ const [fullNameErr, setFullNameErr] = useState()
+ const [phoneNumberErr, setPhoneNumberErr] = useState()
+ const [emailErr, setEmailErr] = useState()
+
+ const {
+ accountType,
+ numOfSteps,
+ personalInfo: { fullName, countryCode, phoneNumber, email },
+ } = useAppSelector((state) => state.accountUpgrade)
+
+ const {
+ submitPhoneNumber,
+ captchaLoading,
+ status,
+ setPhoneNumber,
+ isSmsSupported,
+ isWhatsAppSupported,
+ phoneCodeChannel,
+ error,
+ validatedPhoneNumber,
+ supportedCountries,
+ setCountryCode,
+ } = useRequestPhoneCodeLogin()
+
+ const { data } = useAuthQuery()
+
+ const [userEmailRegistrationInitiateMutation] =
+ useUserEmailRegistrationInitiateMutation()
+
+ useEffect(() => {
+ if (phoneNumber && countryCode) {
+ setPhoneNumber(phoneNumber)
+ setCountryCode(countryCode)
+ }
+ }, [])
+
+ useEffect(() => {
+ if (
+ status === RequestPhoneCodeStatus.CompletingCaptcha ||
+ status === RequestPhoneCodeStatus.RequestingCode
+ ) {
+ toggleActivityIndicator(true)
+ } else {
+ toggleActivityIndicator(false)
+ }
+ }, [status])
+
+ useEffect(() => {
+ if (status === RequestPhoneCodeStatus.SuccessRequestingCode) {
+ navigation.navigate("Validation", {
+ phone: validatedPhoneNumber || "",
+ channel: phoneCodeChannel,
+ })
+ }
+ }, [status, phoneCodeChannel, validatedPhoneNumber, navigation])
+
+ const onPressNext = async (channel?: PhoneCodeChannelType) => {
+ try {
+ let hasError = false
+ const parsedPhoneNumber = parsePhoneNumber(phoneNumber || "", countryCode)
+ if (fullName && fullName?.length < 2) {
+ setFullNameErr("Name must be at least 2 characters")
+ hasError = true
+ }
+ if (!parsedPhoneNumber?.isValid()) {
+ setPhoneNumberErr("Please enter a valid phone number")
+ hasError = true
+ }
+ if (accountType !== AccountLevel.One && !email) {
+ setEmailErr("Please enter a valid email address")
+ hasError = true
+ }
+ if (!hasError) {
+ if (currentLevel === AccountLevel.Zero && channel) {
+ submitPhoneNumber(channel)
+ } else {
+ // For Level 1+ users upgrading to business, save email if provided
+ if (email && email.length > 0) {
+ try {
+ await userEmailRegistrationInitiateMutation({
+ variables: { input: { email } },
+ })
+ } catch (err) {
+ console.log("Email registration error:", err)
+ // Continue to next screen even if email fails
+ }
+ }
+ navigation.navigate("BusinessInformation")
+ }
+ }
+ } catch (err) {
+ console.log("Personal information error: ", err)
+ setFullNameErr("Name must be at least 2 characters")
+ setPhoneNumberErr("Please enter a valid phone number")
+ }
+ }
+
+ return (
+
+
+
+ {
+ setFullNameErr(undefined)
+ dispatch(setPersonalInfo({ fullName: val }))
+ }}
+ />
+ {
+ setPhoneNumberErr(undefined)
+ setCountryCode(val)
+ dispatch(setPersonalInfo({ countryCode: val }))
+ }}
+ setPhoneNumber={(val) => {
+ setPhoneNumberErr(undefined)
+ setPhoneNumber(val)
+ dispatch(setPersonalInfo({ phoneNumber: val }))
+ }}
+ />
+ dispatch(setPersonalInfo({ email: val }))}
+ autoCapitalize={"none"}
+ />
+
+
+ {currentLevel === AccountLevel.Zero ? (
+ <>
+ {isSmsSupported && (
+ onPressNext(PhoneCodeChannelType.Sms)}
+ btnStyle={isWhatsAppSupported ? { marginBottom: 10 } : {}}
+ />
+ )}
+ {isWhatsAppSupported && (
+ onPressNext(PhoneCodeChannelType.Whatsapp)}
+ />
+ )}
+ >
+ ) : (
+
+ )}
+
+
+ )
+}
+
+export default PersonalInformation
+
+const useStyles = makeStyles(({ colors }) => ({
+ container: {
+ flex: 1,
+ paddingVertical: 10,
+ paddingHorizontal: 20,
+ },
+ btn: {
+ marginBottom: 10,
+ marginHorizontal: 20,
+ },
+}))
diff --git a/app/screens/account-upgrade-flow/Success.tsx b/app/screens/account-upgrade-flow/Success.tsx
new file mode 100644
index 000000000..adfa35657
--- /dev/null
+++ b/app/screens/account-upgrade-flow/Success.tsx
@@ -0,0 +1,73 @@
+import React from "react"
+import { View } from "react-native"
+import { makeStyles, Text, useTheme } from "@rneui/themed"
+import { StackScreenProps } from "@react-navigation/stack"
+import { RootStackParamList } from "@app/navigation/stack-param-lists"
+
+// components
+import { Screen } from "@app/components/screen"
+import { PrimaryBtn } from "@app/components/buttons"
+
+// assets
+import Account from "@app/assets/illustrations/account.svg"
+
+// hooks
+import { useI18nContext } from "@app/i18n/i18n-react"
+import { useAppSelector } from "@app/store/redux"
+
+type Props = StackScreenProps
+
+const accountTypeLabel = { ONE: "PERSONAL", TWO: "PRO", THREE: "MERCHANT" }
+
+const Success: React.FC = ({ navigation }) => {
+ const styles = useStyles()
+ const { colors } = useTheme().theme
+ const { LL } = useI18nContext()
+
+ const { accountType } = useAppSelector((state) => state.accountUpgrade)
+
+ const onComplete = () => {
+ navigation.reset({
+ index: 0,
+ routes: [{ name: "Primary" }],
+ })
+ }
+
+ return (
+
+
+
+ {LL.AccountUpgrade.successTitle({
+ accountType: accountTypeLabel[accountType as keyof typeof accountTypeLabel],
+ })}
+
+
+
+
+
+ )
+}
+
+export default Success
+
+const useStyles = makeStyles(() => ({
+ wrapper: {
+ flex: 1,
+ alignItems: "center",
+ justifyContent: "center",
+ },
+ header: {
+ textAlign: "center",
+ color: "#fff",
+ },
+ btn: {
+ backgroundColor: "#fff",
+ marginHorizontal: 20,
+ marginBottom: 10,
+ },
+}))
diff --git a/app/screens/account-upgrade-flow/Validation.tsx b/app/screens/account-upgrade-flow/Validation.tsx
new file mode 100644
index 000000000..19b65d65b
--- /dev/null
+++ b/app/screens/account-upgrade-flow/Validation.tsx
@@ -0,0 +1,122 @@
+import React, { useCallback, useState } from "react"
+import { RootStackParamList } from "@app/navigation/stack-param-lists"
+import { StackScreenProps } from "@react-navigation/stack"
+import { makeStyles, Text } from "@rneui/themed"
+import { View } from "react-native"
+
+// components
+import { Screen } from "@app/components/screen"
+import { InputField, ProgressSteps } from "@app/components/account-upgrade-flow"
+
+// hooks
+import { useActivityIndicator, useAppConfig } from "@app/hooks"
+import { useI18nContext } from "@app/i18n/i18n-react"
+import { useAppSelector } from "@app/store/redux"
+import {
+ AccountLevel,
+ HomeAuthedDocument,
+ useUserLoginUpgradeMutation,
+} from "@app/graphql/generated"
+
+// utils
+import { PhoneCodeChannelToFriendlyName } from "../phone-auth-screen/request-phone-code-login"
+
+type Props = StackScreenProps
+
+const Validation: React.FC = ({ navigation, route }) => {
+ const { phone, channel } = route.params
+ const styles = useStyles()
+ const { accountType, numOfSteps } = useAppSelector((state) => state.accountUpgrade)
+ const { LL } = useI18nContext()
+ const { saveToken } = useAppConfig()
+ const { toggleActivityIndicator } = useActivityIndicator()
+
+ const [code, setCode] = useState()
+ const [errorMsg, setErrorMsg] = useState()
+
+ const [userLoginUpgradeMutation] = useUserLoginUpgradeMutation({
+ fetchPolicy: "no-cache",
+ refetchQueries: [HomeAuthedDocument],
+ })
+
+ const send = useCallback(
+ async (code: string) => {
+ try {
+ toggleActivityIndicator(true)
+ const { data } = await userLoginUpgradeMutation({
+ variables: { input: { phone, code } },
+ })
+ toggleActivityIndicator(false)
+
+ const success = data?.userLoginUpgrade?.success
+ const authToken = data?.userLoginUpgrade?.authToken
+ if (success) {
+ if (authToken) {
+ saveToken(authToken)
+ }
+ if (accountType === AccountLevel.One) {
+ navigation.replace("AccountUpgradeSuccess")
+ } else {
+ navigation.replace("BusinessInformation")
+ }
+ } else {
+ setErrorMsg(data?.userLoginUpgrade.errors[0].message)
+ }
+ setCode("")
+ } catch (err) {
+ setCode("")
+ }
+ },
+ [userLoginUpgradeMutation, saveToken, phone],
+ )
+
+ const onChangeText = (code: string) => {
+ if (code.length > 6) {
+ return
+ }
+
+ setCode(code)
+ if (code.length === 6) {
+ send(code)
+ }
+ }
+
+ return (
+
+
+
+
+ {LL.PhoneLoginValidationScreen.header({
+ channel: PhoneCodeChannelToFriendlyName[channel],
+ phoneNumber: phone,
+ })}
+
+
+
+
+ )
+}
+
+export default Validation
+
+const useStyles = makeStyles(() => ({
+ wrapper: {
+ paddingVertical: 10,
+ paddingHorizontal: 20,
+ },
+ header: {
+ marginBottom: 30,
+ },
+}))
diff --git a/app/screens/account-upgrade-flow/index.ts b/app/screens/account-upgrade-flow/index.ts
new file mode 100644
index 000000000..372d50471
--- /dev/null
+++ b/app/screens/account-upgrade-flow/index.ts
@@ -0,0 +1,15 @@
+import AccountType from "./AccountType"
+import PersonalInformation from "./PersonalInformation"
+import BusinessInformation from "./BusinessInformation"
+import BankInformation from "./BankInformation"
+import Validation from "./Validation"
+import Success from "./Success"
+
+export {
+ AccountType,
+ BusinessInformation,
+ PersonalInformation,
+ BankInformation,
+ Validation,
+ Success,
+}
diff --git a/app/screens/home-screen/home-screen.tsx b/app/screens/home-screen/home-screen.tsx
index ce414e30f..fd0643da3 100644
--- a/app/screens/home-screen/home-screen.tsx
+++ b/app/screens/home-screen/home-screen.tsx
@@ -68,7 +68,7 @@ export const HomeScreen: React.FC = () => {
dispatch(setUserData(dataAuthed.me))
saveDefaultWallet()
}
- }, [dataAuthed])
+ }, [dataAuthed?.me])
const saveDefaultWallet = () => {
const defaultWallet = getDefaultWallet(
diff --git a/app/screens/phone-auth-screen/request-phone-code-login.ts b/app/screens/phone-auth-screen/request-phone-code-login.ts
index 8d229779b..40cdb0df9 100644
--- a/app/screens/phone-auth-screen/request-phone-code-login.ts
+++ b/app/screens/phone-auth-screen/request-phone-code-login.ts
@@ -161,7 +161,7 @@ export const useRequestPhoneCodeLogin = (): UseRequestPhoneCodeReturn => {
setStatus(RequestPhoneCodeStatus.InputtingPhoneNumber)
}
- getCountryCodeFromIP()
+ if (!countryCode) getCountryCodeFromIP()
}, [])
const setPhoneNumber = (number: string) => {
diff --git a/app/screens/settings-screen/account/settings/delete.tsx b/app/screens/settings-screen/account/settings/delete.tsx
index 005600f8d..1a05f3e6c 100644
--- a/app/screens/settings-screen/account/settings/delete.tsx
+++ b/app/screens/settings-screen/account/settings/delete.tsx
@@ -104,6 +104,7 @@ export const Delete = () => {
if (res.data?.accountDelete?.success) {
await deleteNostrData()
+ if (data?.me?.phone) await deleteUser(data?.me?.phone)
await cleanUp(true)
setAccountIsBeingDeleted(false)
navigation.reset({
diff --git a/app/screens/settings-screen/account/settings/upgrade-trial-account.tsx b/app/screens/settings-screen/account/settings/upgrade-trial-account.tsx
index 9d096c7d1..8c585d4ab 100644
--- a/app/screens/settings-screen/account/settings/upgrade-trial-account.tsx
+++ b/app/screens/settings-screen/account/settings/upgrade-trial-account.tsx
@@ -1,11 +1,10 @@
import { useState } from "react"
import { View } from "react-native"
import { makeStyles, Text } from "@rneui/themed"
+import { StackNavigationProp } from "@react-navigation/stack"
+import { RootStackParamList } from "@app/navigation/stack-param-lists"
// components
-import ContactModal, {
- SupportChannels,
-} from "@app/components/contact-modal/contact-modal"
import { PrimaryBtn } from "@app/components/buttons"
import { GaloyIcon } from "@app/components/atomic/galoy-icon"
import { UpgradeAccountModal } from "@app/components/upgrade-account-modal"
@@ -15,24 +14,20 @@ import { GaloySecondaryButton } from "@app/components/atomic/galoy-secondary-but
import { useShowWarningSecureAccount } from "../show-warning-secure-account-hook"
import { AccountLevel, useLevel } from "@app/graphql/level-context"
import { useI18nContext } from "@app/i18n/i18n-react"
-import { useAppConfig } from "@app/hooks"
+import { useNavigation } from "@react-navigation/native"
export const UpgradeTrialAccount: React.FC = () => {
const styles = useStyles()
const { LL } = useI18nContext()
const { currentLevel } = useLevel()
- const { appConfig } = useAppConfig()
+ const navigation = useNavigation>()
const hasBalance = useShowWarningSecureAccount()
const [upgradeAccountModalVisible, setUpgradeAccountModalVisible] = useState(false)
- const [isContactModalVisible, setIsContactModalVisible] = useState(false)
-
- const { name: bankName } = appConfig.galoyInstance
const closeUpgradeAccountModal = () => setUpgradeAccountModalVisible(false)
const openUpgradeAccountModal = () => setUpgradeAccountModalVisible(true)
- const toggleContactModal = () => setIsContactModalVisible(!isContactModalVisible)
if (currentLevel === AccountLevel.Zero) {
return (
@@ -63,30 +58,12 @@ export const UpgradeTrialAccount: React.FC = () => {
>
)
} else if (currentLevel === AccountLevel.One) {
- const messageBody = LL.TransactionLimitsScreen.contactUsMessageBody({
- bankName,
- })
- const messageSubject = LL.TransactionLimitsScreen.contactUsMessageSubject()
-
return (
- <>
-
-
- >
+ navigation.navigate("AccountType")}
+ />
)
} else {
return null
diff --git a/app/store/redux/index.ts b/app/store/redux/index.ts
index 5fdf7d953..f80d1239f 100644
--- a/app/store/redux/index.ts
+++ b/app/store/redux/index.ts
@@ -2,11 +2,38 @@ import { configureStore, ThunkAction, Action } from "@reduxjs/toolkit"
import { useDispatch, useSelector } from "react-redux"
import type { TypedUseSelectorHook } from "react-redux"
import rootReducer from "./reducers"
+import {
+ persistStore,
+ persistReducer,
+ FLUSH,
+ REHYDRATE,
+ PAUSE,
+ PERSIST,
+ PURGE,
+ REGISTER,
+} from "redux-persist"
+import AsyncStorage from "@react-native-async-storage/async-storage"
+
+const persistConfig = {
+ key: "root",
+ storage: AsyncStorage,
+ whitelist: ["accountUpgrade"],
+}
+
+const persistedReducer = persistReducer(persistConfig, rootReducer)
export const store = configureStore({
- reducer: rootReducer,
+ reducer: persistedReducer,
+ middleware: (getDefaultMiddleware) =>
+ getDefaultMiddleware({
+ serializableCheck: {
+ ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
+ },
+ }),
})
+export const persistor = persistStore(store)
+
export type AppDispatch = typeof store.dispatch
export type RootState = ReturnType
diff --git a/app/store/redux/reducers.ts b/app/store/redux/reducers.ts
index 48668b47e..ec018442d 100644
--- a/app/store/redux/reducers.ts
+++ b/app/store/redux/reducers.ts
@@ -2,7 +2,9 @@ import { combineReducers } from "@reduxjs/toolkit"
// slices
import userSlice from "./slices/userSlice"
+import accountUpgradeSlice from "./slices/accountUpgradeSlice"
export default combineReducers({
user: userSlice,
+ accountUpgrade: accountUpgradeSlice,
})
diff --git a/app/store/redux/slices/accountUpgradeSlice.ts b/app/store/redux/slices/accountUpgradeSlice.ts
new file mode 100644
index 000000000..f377c9d98
--- /dev/null
+++ b/app/store/redux/slices/accountUpgradeSlice.ts
@@ -0,0 +1,109 @@
+import { AccountLevel } from "@app/graphql/generated"
+import { createSlice } from "@reduxjs/toolkit"
+import { CountryCode } from "libphonenumber-js"
+import { Asset } from "react-native-image-picker"
+
+interface AccountUpgradeSlice {
+ id?: string
+ accountType: AccountLevel
+ upgradeCompleted?: boolean
+ personalInfo: {
+ fullName?: string
+ countryCode?: CountryCode
+ phoneNumber?: string
+ email?: string
+ }
+ businessInfo: {
+ businessName?: string
+ businessAddress?: string
+ lat?: number
+ lng?: number
+ terminalRequested?: boolean
+ }
+ bankInfo: {
+ bankName?: string
+ bankBranch?: string
+ bankAccountType?: string
+ currency?: string
+ accountNumber?: string
+ idDocument?: Asset
+ }
+ numOfSteps: number
+ loading: boolean
+ error?: string
+}
+
+const initialState: AccountUpgradeSlice = {
+ id: undefined,
+ accountType: "ONE",
+ upgradeCompleted: undefined,
+ personalInfo: {
+ fullName: undefined,
+ countryCode: "JM",
+ phoneNumber: undefined,
+ email: undefined,
+ },
+ businessInfo: {
+ businessName: undefined,
+ businessAddress: undefined,
+ lat: undefined,
+ lng: undefined,
+ terminalRequested: undefined,
+ },
+ bankInfo: {
+ bankName: undefined,
+ bankBranch: undefined,
+ bankAccountType: undefined,
+ currency: undefined,
+ accountNumber: undefined,
+ idDocument: undefined,
+ },
+ numOfSteps: 3,
+ loading: false,
+ error: undefined,
+}
+
+export const accountUpgradeSlice = createSlice({
+ name: "accountUpgrade",
+ initialState,
+ reducers: {
+ setAccountUpgrade: (state, action) => ({
+ ...state,
+ ...action.payload,
+ }),
+ setPersonalInfo: (state, action) => ({
+ ...state,
+ personalInfo: { ...state.personalInfo, ...action.payload },
+ }),
+ setBusinessInfo: (state, action) => ({
+ ...state,
+ businessInfo: { ...state.businessInfo, ...action.payload },
+ }),
+ setBankInfo: (state, action) => ({
+ ...state,
+ bankInfo: { ...state.bankInfo, ...action.payload },
+ }),
+ setLoading: (state, action) => ({
+ ...state,
+ loading: action.payload,
+ }),
+ setError: (state, action) => ({
+ ...state,
+ error: action.payload,
+ }),
+ resetAccountUpgrade: () => ({
+ ...initialState,
+ }),
+ },
+})
+
+export const {
+ setAccountUpgrade,
+ setPersonalInfo,
+ setBusinessInfo,
+ setBankInfo,
+ setLoading,
+ setError,
+ resetAccountUpgrade,
+} = accountUpgradeSlice.actions
+export default accountUpgradeSlice.reducer
diff --git a/app/types/declaration.d.ts b/app/types/declaration.d.ts
index ab0a2eafe..ac58c9c79 100644
--- a/app/types/declaration.d.ts
+++ b/app/types/declaration.d.ts
@@ -30,4 +30,5 @@ declare module "@env" {
export const API_KEY: string
export const GREENLIGHT_PARTNER_CERT: string
export const GREENLIGHT_PARTNER_KEY: string
+ export const GOOGLE_PLACE_API_KEY: string
}
diff --git a/codegen.yml b/codegen.yml
index cb6f47e40..4117322e6 100644
--- a/codegen.yml
+++ b/codegen.yml
@@ -1,5 +1,6 @@
overwrite: true
-schema: "https://api.flashapp.me/graphql"
+# schema: "https://api.flashapp.me/graphql"
+schema: "http://localhost:4002/graphql"
# schema: "https://raw.githubusercontent.com/lnflash/flash/feature/merchant-map-suggest/src/graphql/public/schema.graphql"
documents:
- "app/**/*.ts"
diff --git a/ios/LNFlash.xcodeproj/project.pbxproj b/ios/LNFlash.xcodeproj/project.pbxproj
index 3f28dc150..81599fedc 100644
--- a/ios/LNFlash.xcodeproj/project.pbxproj
+++ b/ios/LNFlash.xcodeproj/project.pbxproj
@@ -381,7 +381,6 @@
"${PODS_CONFIGURATION_BUILD_DIR}/PromisesSwift/Promises_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage/RNCAsyncStorage_resources.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo/RNDeviceInfoPrivacyInfo.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf",
@@ -402,7 +401,6 @@
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/react-native-image-picker/RNImagePickerPrivacyInfo.bundle",
);
@@ -423,7 +421,6 @@
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Promises_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNCAsyncStorage_resources.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNDeviceInfoPrivacyInfo.bundle",
- "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AntDesign.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Entypo.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EvilIcons.ttf",
@@ -444,7 +441,6 @@
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SimpleLineIcons.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Zocial.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
- "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/nanopb_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImagePickerPrivacyInfo.bundle",
);
@@ -564,7 +560,6 @@
"${PODS_CONFIGURATION_BUILD_DIR}/PromisesSwift/Promises_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage/RNCAsyncStorage_resources.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNDeviceInfo/RNDeviceInfoPrivacyInfo.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf",
@@ -585,7 +580,6 @@
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf",
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
- "${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/react-native-image-picker/RNImagePickerPrivacyInfo.bundle",
);
@@ -606,7 +600,6 @@
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Promises_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNCAsyncStorage_resources.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNDeviceInfoPrivacyInfo.bundle",
- "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AntDesign.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Entypo.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EvilIcons.ttf",
@@ -627,7 +620,6 @@
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SimpleLineIcons.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Zocial.ttf",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
- "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/nanopb_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImagePickerPrivacyInfo.bundle",
);
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 9f3208bb3..3696345e3 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -681,15 +681,6 @@ PODS:
- React-Core
- RNGestureHandler (2.12.1):
- React-Core
- - RNImageCropPicker (0.39.0):
- - React-Core
- - React-RCTImage
- - RNImageCropPicker/QBImagePickerController (= 0.39.0)
- - TOCropViewController
- - RNImageCropPicker/QBImagePickerController (0.39.0):
- - React-Core
- - React-RCTImage
- - TOCropViewController
- RNInAppBrowser (3.7.0):
- React-Core
- RNKeychain (8.2.0):
@@ -754,7 +745,6 @@ PODS:
- RCT-Folly (= 2021.07.22.00)
- React-Core
- SocketRocket (0.6.1)
- - TOCropViewController (3.1.1)
- VisionCamera (3.6.4):
- React
- React-callinvoker
@@ -845,7 +835,6 @@ DEPENDENCIES:
- RNFileViewer (from `../node_modules/react-native-file-viewer`)
- RNFS (from `../node_modules/react-native-fs`)
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- - RNImageCropPicker (from `../node_modules/react-native-image-crop-picker`)
- RNInAppBrowser (from `../node_modules/react-native-inappbrowser-reborn`)
- RNKeychain (from `../node_modules/react-native-keychain`)
- RNLocalize (from `../node_modules/react-native-localize`)
@@ -895,7 +884,6 @@ SPEC REPOS:
- PromisesObjC
- PromisesSwift
- SocketRocket
- - TOCropViewController
- ZXingObjC
EXTERNAL SOURCES:
@@ -1053,8 +1041,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-fs"
RNGestureHandler:
:path: "../node_modules/react-native-gesture-handler"
- RNImageCropPicker:
- :path: "../node_modules/react-native-image-crop-picker"
RNInAppBrowser:
:path: "../node_modules/react-native-inappbrowser-reborn"
RNKeychain:
@@ -1195,7 +1181,6 @@ SPEC CHECKSUMS:
RNFileViewer: ce7ca3ac370e18554d35d6355cffd7c30437c592
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
RNGestureHandler: c0d04458598fcb26052494ae23dda8f8f5162b13
- RNImageCropPicker: 14fe1c29298fb4018f3186f455c475ab107da332
RNInAppBrowser: e36d6935517101ccba0e875bac8ad7b0cb655364
RNKeychain: bfe3d12bf4620fe488771c414530bf16e88f3678
RNLocalize: d4b8af4e442d4bcca54e68fc687a2129b4d71a81
@@ -1211,7 +1196,6 @@ SPEC CHECKSUMS:
RNSVG: 963a95f1f5d512a13d11ffd50d351c87fb5c6890
RNVectorIcons: 5fc79a64e2ec2468ef4d1f9d40c132e52ef37241
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
- TOCropViewController: 9002a9b12d8104d7478cdc306d80f0efea7fe2c5
VisionCamera: 1910a51e4c6f6b049650086d343090f267b4c260
Yoga: eddf2bbe4a896454c248a8f23b4355891eb720a6
ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5
diff --git a/package.json b/package.json
index eade69e6e..c21c15361 100644
--- a/package.json
+++ b/package.json
@@ -137,16 +137,17 @@
"react-native-device-info": "^10.11.0",
"react-native-document-picker": "^9.0.1",
"react-native-dotenv": "^3.4.9",
+ "react-native-element-dropdown": "^2.12.4",
"react-native-error-boundary": "^1.2.3",
"react-native-file-viewer": "^2.1.5",
"react-native-fingerprint-scanner": "git+https://github.com/hieuvp/react-native-fingerprint-scanner.git#9cecc0db326471c571553ea85f7c016fee2f803d",
"react-native-fs": "^2.20.0",
"react-native-gesture-handler": "2.12.1",
"react-native-get-random-values": "^1.9.0",
+ "react-native-google-places-autocomplete": "^2.5.7",
"react-native-gradle-plugin": "^0.71.19",
"react-native-haptic-feedback": "^2.0.3",
"react-native-html-to-pdf": "^0.12.0",
- "react-native-image-crop-picker": "^0.39.0",
"react-native-image-picker": "^7.0.0",
"react-native-in-app-review": "^4.3.3",
"react-native-inappbrowser-reborn": "^3.7.0",
@@ -182,11 +183,12 @@
"react-native-video": "^5.2.1",
"react-native-view-shot": "^3.7.0",
"react-native-vision-camera": "3.6.4",
- "react-native-walkthrough-tooltip": "^1.4.0",
+ "react-native-walkthrough-tooltip": "^1.6.0",
"react-native-webln": "^0.1.11",
"react-native-webview": "^13.8.1",
"react-native-webview-crypto": "^0.0.25",
"react-redux": "^9.1.0",
+ "redux-persist": "^6.0.0",
"rn-qr-generator": "^1.2.1",
"styled-components": "^6.1.8",
"subscriptions-transport-ws": "^0.11.0",
@@ -285,7 +287,7 @@
"jetifier": "^2.0.0",
"jimp": "^0.22.8",
"jsqr": "^1.4.0",
- "metro-config": "0.76.1",
+ "metro-config": "0.76.8",
"metro-react-native-babel-preset": "0.76.8",
"mocha": "^10.2.0",
"npm-run-all": "4.1.5",
@@ -321,6 +323,7 @@
}
},
"resolutions": {
+ "metro": "0.76.8",
"types-ramda": "0.29.4",
"pbkdf2": "^3.1.3",
"elliptic": "^6.6.1",
diff --git a/yarn.lock b/yarn.lock
index e9f3afdd7..8d6306cd0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -102,7 +102,7 @@
"@smithy/types" "^4.9.0"
tslib "^2.6.2"
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.21.4", "@babel/code-frame@^7.24.7", "@babel/code-frame@^7.27.1", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3":
+"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.21.4", "@babel/code-frame@^7.27.1", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be"
integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==
@@ -189,7 +189,7 @@
eslint-visitor-keys "^2.1.0"
semver "^6.3.1"
-"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.14.0", "@babel/generator@^7.18.13", "@babel/generator@^7.20.0", "@babel/generator@^7.21.5", "@babel/generator@^7.25.0", "@babel/generator@^7.26.10", "@babel/generator@^7.28.5", "@babel/generator@^7.7.2":
+"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.14.0", "@babel/generator@^7.18.13", "@babel/generator@^7.20.0", "@babel/generator@^7.21.5", "@babel/generator@^7.26.10", "@babel/generator@^7.28.5", "@babel/generator@^7.7.2":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.5.tgz#712722d5e50f44d07bc7ac9fe84438742dd61298"
integrity sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==
@@ -457,7 +457,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8", "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.0":
+"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8", "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.0":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1"
integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==
@@ -501,7 +501,7 @@
"@babel/helper-plugin-utils" "^7.18.6"
"@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
-"@babel/plugin-proposal-optional-chaining@^7.0.0", "@babel/plugin-proposal-optional-chaining@^7.12.7", "@babel/plugin-proposal-optional-chaining@^7.13.12", "@babel/plugin-proposal-optional-chaining@^7.20.0":
+"@babel/plugin-proposal-optional-chaining@^7.12.7", "@babel/plugin-proposal-optional-chaining@^7.13.12", "@babel/plugin-proposal-optional-chaining@^7.20.0":
version "7.21.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea"
integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==
@@ -568,7 +568,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-syntax-dynamic-import@^7.0.0", "@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3":
+"@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3"
integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==
@@ -718,7 +718,7 @@
"@babel/helper-remap-async-to-generator" "^7.27.1"
"@babel/traverse" "^7.28.0"
-"@babel/plugin-transform-async-to-generator@^7.0.0", "@babel/plugin-transform-async-to-generator@^7.20.0", "@babel/plugin-transform-async-to-generator@^7.27.1":
+"@babel/plugin-transform-async-to-generator@^7.20.0", "@babel/plugin-transform-async-to-generator@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz#9a93893b9379b39466c74474f55af03de78c66e7"
integrity sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==
@@ -1317,7 +1317,7 @@
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.4.tgz#a70226016fabe25c5783b2f22d3e1c9bc5ca3326"
integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==
-"@babel/template@^7.0.0", "@babel/template@^7.12.7", "@babel/template@^7.14.5", "@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.25.0", "@babel/template@^7.27.1", "@babel/template@^7.27.2", "@babel/template@^7.3.3":
+"@babel/template@^7.0.0", "@babel/template@^7.12.7", "@babel/template@^7.14.5", "@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.27.1", "@babel/template@^7.27.2", "@babel/template@^7.3.3":
version "7.27.2"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d"
integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==
@@ -14251,11 +14251,6 @@ hermes-estree@0.32.0:
resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.32.0.tgz#bb7da6613ab8e67e334a1854ea1e209f487d307b"
integrity sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ==
-hermes-estree@0.8.0:
- version "0.8.0"
- resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.8.0.tgz#530be27243ca49f008381c1f3e8b18fb26bf9ec0"
- integrity sha512-W6JDAOLZ5pMPMjEiQGLCXSSV7pIBEgRR5zGkxgmzGSXHOxqV5dC/M1Zevqpbm9TZDE5tu358qZf8Vkzmsc+u7Q==
-
hermes-parser@0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.12.0.tgz#114dc26697cfb41a6302c215b859b74224383773"
@@ -14270,13 +14265,6 @@ hermes-parser@0.32.0:
dependencies:
hermes-estree "0.32.0"
-hermes-parser@0.8.0:
- version "0.8.0"
- resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.8.0.tgz#116dceaba32e45b16d6aefb5c4c830eaeba2d257"
- integrity sha512-yZKalg1fTYG5eOiToLUaw69rQfZq/fi+/NtEXRU7N87K/XobNRhRWorh80oSge2lWUiZfTgUvRJH+XgZWrhoqA==
- dependencies:
- hermes-estree "0.8.0"
-
hermes-profile-transformer@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/hermes-profile-transformer/-/hermes-profile-transformer-0.0.6.tgz#bd0f5ecceda80dd0ddaae443469ab26fb38fc27b"
@@ -14568,7 +14556,7 @@ image-q@^4.0.0:
dependencies:
"@types/node" "16.9.1"
-image-size@^0.6.0, image-size@^1.0.2, image-size@^1.2.1:
+image-size@^1.0.2, image-size@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.2.1.tgz#ee118aedfe666db1a6ee12bed5821cde3740276d"
integrity sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==
@@ -15782,11 +15770,6 @@ jest-environment-node@^29.2.1, jest-environment-node@^29.7.0:
jest-mock "^29.7.0"
jest-util "^29.7.0"
-jest-get-type@^26.3.0:
- version "26.3.0"
- resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0"
- integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==
-
jest-get-type@^28.0.2:
version "28.0.2"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203"
@@ -16286,18 +16269,6 @@ jest-util@^29.7.0:
graceful-fs "^4.2.9"
picomatch "^2.2.3"
-jest-validate@^26.5.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec"
- integrity sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==
- dependencies:
- "@jest/types" "^26.6.2"
- camelcase "^6.0.0"
- chalk "^4.0.0"
- jest-get-type "^26.3.0"
- leven "^3.1.0"
- pretty-format "^26.6.2"
-
jest-validate@^28.1.3:
version "28.1.3"
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-28.1.3.tgz#e322267fd5e7c64cea4629612c357bbda96229df"
@@ -17687,16 +17658,6 @@ methods@~1.1.2:
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
-metro-babel-transformer@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.76.1.tgz#feb14d58b71b1767e9c9af2c294768a30ededd4e"
- integrity sha512-dhLo5tS+PxhkOLkHH5Cxw1FF+zQuUTXl2a5K/DD73ggj+bNXMm61bpmjKldIk6j1QkzwvuHvs7NugC6bzoi7tA==
- dependencies:
- "@babel/core" "^7.20.0"
- hermes-parser "0.8.0"
- metro-source-map "0.76.1"
- nullthrows "^1.1.1"
-
metro-babel-transformer@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.76.8.tgz#5efd1027353b36b73706164ef09c290dceac096a"
@@ -17706,55 +17667,11 @@ metro-babel-transformer@0.76.8:
hermes-parser "0.12.0"
nullthrows "^1.1.1"
-metro-babel-transformer@0.76.9:
- version "0.76.9"
- resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.76.9.tgz#659ba481d471b5f748c31a8f9397094b629f50ec"
- integrity sha512-dAnAmBqRdTwTPVn4W4JrowPolxD1MDbuU97u3MqtWZgVRvDpmr+Cqnn5oSxLQk3Uc+Zy3wkqVrB/zXNRlLDSAQ==
- dependencies:
- "@babel/core" "^7.20.0"
- hermes-parser "0.12.0"
- nullthrows "^1.1.1"
-
-metro-babel-transformer@0.83.3:
- version "0.83.3"
- resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.83.3.tgz#d8c134615530c9ee61364526d44ca4bb0c5343ea"
- integrity sha512-1vxlvj2yY24ES1O5RsSIvg4a4WeL7PFXgKOHvXTXiW0deLvQr28ExXj6LjwCCDZ4YZLhq6HddLpZnX4dEdSq5g==
- dependencies:
- "@babel/core" "^7.25.2"
- flow-enums-runtime "^0.0.6"
- hermes-parser "0.32.0"
- nullthrows "^1.1.1"
-
-metro-cache-key@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.76.1.tgz#c98c55c422ddea5519b01fe872519dc696b1c1ed"
- integrity sha512-edykkNFb3yt+uESZynTm+vVBlJFKf3tGOpZdvScovvlfRAInWuoErpZ72q2oFeswIEsE0D6J8kJgILtikhIHeA==
-
metro-cache-key@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.76.8.tgz#8a0a5e991c06f56fcc584acadacb313c312bdc16"
integrity sha512-buKQ5xentPig9G6T37Ww/R/bC+/V1MA5xU/D8zjnhlelsrPG6w6LtHUS61ID3zZcMZqYaELWk5UIadIdDsaaLw==
-metro-cache-key@0.76.9:
- version "0.76.9"
- resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.76.9.tgz#6f17f821d6f306fa9028b7e79445eb18387d03d9"
- integrity sha512-ugJuYBLngHVh1t2Jj+uP9pSCQl7enzVXkuh6+N3l0FETfqjgOaSHlcnIhMPn6yueGsjmkiIfxQU4fyFVXRtSTw==
-
-metro-cache-key@0.83.3:
- version "0.83.3"
- resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.83.3.tgz#ae6c5d4eb1ad8d06a92bf7294ca730a8d880b573"
- integrity sha512-59ZO049jKzSmvBmG/B5bZ6/dztP0ilp0o988nc6dpaDsU05Cl1c/lRf+yx8m9WW/JVgbmfO5MziBU559XjI5Zw==
- dependencies:
- flow-enums-runtime "^0.0.6"
-
-metro-cache@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.76.1.tgz#d71827d99c2f6c6b5b8a69232c0ba13325a79eb4"
- integrity sha512-2vpLWxG0fxZMYlSADPdoyrljra/8eAWaIOuSVZDQDcUowOjKmm8DGYZ7TJ8g4XJe0+RqU2s9MBazh/tMbeQIkQ==
- dependencies:
- metro-core "0.76.1"
- rimraf "^3.0.2"
-
metro-cache@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.76.8.tgz#296c1c189db2053b89735a8f33dbe82575f53661"
@@ -17781,18 +17698,6 @@ metro-cache@0.83.3:
https-proxy-agent "^7.0.5"
metro-core "0.83.3"
-metro-config@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.76.1.tgz#335fa403a0d68337bbcefad4de69af48e808fb52"
- integrity sha512-HCJOymif3LQsK2YsB/5Br15r9gOOBBP/6aikxy48aLoYj5uzQGVBqHAjaJMnYNN2AKRj49cHGESryKrlhRg7LQ==
- dependencies:
- cosmiconfig "^5.0.5"
- jest-validate "^26.5.2"
- metro "0.76.1"
- metro-cache "0.76.1"
- metro-core "0.76.1"
- metro-runtime "0.76.1"
-
metro-config@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.76.8.tgz#20bd5397fcc6096f98d2a813a7cecb38b8af062d"
@@ -17806,7 +17711,7 @@ metro-config@0.76.8:
metro-core "0.76.8"
metro-runtime "0.76.8"
-metro-config@0.76.9, metro-config@^0.76.9:
+metro-config@^0.76.9:
version "0.76.9"
resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.76.9.tgz#5e60aff9d8894c1ee6bbc5de23b7c8515a0b84a3"
integrity sha512-oYyJ16PY3rprsfoi80L+gDJhFJqsKI3Pob5LKQbJpvL+gGr8qfZe1eQzYp5Xxxk9DOHKBV1xD94NB8GdT/DA8Q==
@@ -17819,7 +17724,7 @@ metro-config@0.76.9, metro-config@^0.76.9:
metro-core "0.76.9"
metro-runtime "0.76.9"
-metro-config@0.83.3, metro-config@^0.83.1:
+metro-config@^0.83.1:
version "0.83.3"
resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.83.3.tgz#a30e7a69b5cf8c4ac4c4b68b1b4c33649ae129a2"
integrity sha512-mTel7ipT0yNjKILIan04bkJkuCzUUkm2SeEaTads8VfEecCh+ltXchdq6DovXJqzQAXuR2P9cxZB47Lg4klriA==
@@ -17833,14 +17738,6 @@ metro-config@0.83.3, metro-config@^0.83.1:
metro-runtime "0.83.3"
yaml "^2.6.1"
-metro-core@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.76.1.tgz#5dea1c4365ad63f7dc4b987ef0fefdf5e82f85a2"
- integrity sha512-RAqanj94vOFrwRjOdF3ByhiHJO87kXLW01LLvH+VmJzlyKJ5P7BN4/VnLKYyHS+uBiGnf78tN7ip/uz8jiQMhA==
- dependencies:
- lodash.throttle "^4.1.1"
- metro-resolver "0.76.1"
-
metro-core@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.76.8.tgz#917c8157c63406cb223522835abb8e7c6291dcad"
@@ -17866,26 +17763,6 @@ metro-core@0.83.3, metro-core@^0.83.1:
lodash.throttle "^4.1.1"
metro-resolver "0.83.3"
-metro-file-map@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.76.1.tgz#5a93c4e6ff3c68aaee199ef7d6807c7527621768"
- integrity sha512-I/9RUxWQvty7JXG18t4HJTG8QN7Mg+ZBC1/6s70e1w7fincNfuiwwMltpthZ26e9QlN672Eu6Q0ZX4W2iQwkCg==
- dependencies:
- anymatch "^3.0.3"
- debug "^2.2.0"
- fb-watchman "^2.0.0"
- graceful-fs "^4.2.4"
- invariant "^2.2.4"
- jest-regex-util "^27.0.6"
- jest-util "^27.2.0"
- jest-worker "^27.2.0"
- micromatch "^4.0.4"
- node-abort-controller "^3.1.1"
- nullthrows "^1.1.1"
- walker "^1.0.7"
- optionalDependencies:
- fsevents "^2.3.2"
-
metro-file-map@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.76.8.tgz#a1db1185b6c316904ba6b53d628e5d1323991d79"
@@ -17906,52 +17783,6 @@ metro-file-map@0.76.8:
optionalDependencies:
fsevents "^2.3.2"
-metro-file-map@0.76.9:
- version "0.76.9"
- resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.76.9.tgz#dd3d76ec23fc0ba8cb7b3a3b8075bb09e0b5d378"
- integrity sha512-7vJd8kksMDTO/0fbf3081bTrlw8SLiploeDf+vkkf0OwlrtDUWPOikfebp+MpZB2S61kamKjCNRfRkgrbPfSwg==
- dependencies:
- anymatch "^3.0.3"
- debug "^2.2.0"
- fb-watchman "^2.0.0"
- graceful-fs "^4.2.4"
- invariant "^2.2.4"
- jest-regex-util "^27.0.6"
- jest-util "^27.2.0"
- jest-worker "^27.2.0"
- micromatch "^4.0.4"
- node-abort-controller "^3.1.1"
- nullthrows "^1.1.1"
- walker "^1.0.7"
- optionalDependencies:
- fsevents "^2.3.2"
-
-metro-file-map@0.83.3:
- version "0.83.3"
- resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.83.3.tgz#3d79fbb1d379ab178dd895ce54cb5ecb183d74a2"
- integrity sha512-jg5AcyE0Q9Xbbu/4NAwwZkmQn7doJCKGW0SLeSJmzNB9Z24jBe0AL2PHNMy4eu0JiKtNWHz9IiONGZWq7hjVTA==
- dependencies:
- debug "^4.4.0"
- fb-watchman "^2.0.0"
- flow-enums-runtime "^0.0.6"
- graceful-fs "^4.2.4"
- invariant "^2.2.4"
- jest-worker "^29.7.0"
- micromatch "^4.0.4"
- nullthrows "^1.1.1"
- walker "^1.0.7"
-
-metro-inspector-proxy@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.76.1.tgz#43a4de729884fab8a8125a968f9bff13d6e4e040"
- integrity sha512-SCyXw4SOO7Y8f3eD5ecwXlRLxo+hczeOvUi1cNnh5q02EjAnHwqhmGMulxB0KtEpAgTvkUJMlz5NCwUo5t6ugw==
- dependencies:
- connect "^3.6.5"
- debug "^2.2.0"
- node-fetch "^2.2.0"
- ws "^7.5.1"
- yargs "^17.6.2"
-
metro-inspector-proxy@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.76.8.tgz#6b8678a7461b0b42f913a7881cc9319b4d3cddff"
@@ -17963,24 +17794,6 @@ metro-inspector-proxy@0.76.8:
ws "^7.5.1"
yargs "^17.6.2"
-metro-inspector-proxy@0.76.9:
- version "0.76.9"
- resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.76.9.tgz#0d333e64a7bc9d156d712265faa7b7ae88c775e8"
- integrity sha512-idIiPkb8CYshc0WZmbzwmr4B1QwsQUbpDwBzHwxE1ni27FWKWhV9CD5p+qlXZHgfwJuMRfPN+tIaLSR8+vttYg==
- dependencies:
- connect "^3.6.5"
- debug "^2.2.0"
- node-fetch "^2.2.0"
- ws "^7.5.1"
- yargs "^17.6.2"
-
-metro-minify-terser@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.76.1.tgz#be860d4d00b18309a171a96692feab2011792d90"
- integrity sha512-M0Dvu4IdePW63Hlbj0D2/HmV90195aWYGb/B9ZBelLrI2vhlD1t606EidhQb1HFq6EaD56LimgGHtvzy83MqKQ==
- dependencies:
- terser "^5.15.0"
-
metro-minify-terser@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.76.8.tgz#915ab4d1419257fc6a0b9fa15827b83fe69814bf"
@@ -17988,28 +17801,6 @@ metro-minify-terser@0.76.8:
dependencies:
terser "^5.15.0"
-metro-minify-terser@0.76.9:
- version "0.76.9"
- resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.76.9.tgz#3f6271da74dd57179852118443b62cc8dc578aab"
- integrity sha512-ju2nUXTKvh96vHPoGZH/INhSvRRKM14CbGAJXQ98+g8K5z1v3luYJ/7+dFQB202eVzJdTB2QMtBjI1jUUpooCg==
- dependencies:
- terser "^5.15.0"
-
-metro-minify-terser@0.83.3:
- version "0.83.3"
- resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.83.3.tgz#c1c70929c86b14c8bf03e6321b4f9310bc8dbe87"
- integrity sha512-O2BmfWj6FSfzBLrNCXt/rr2VYZdX5i6444QJU0fFoc7Ljg+Q+iqebwE3K0eTvkI6TRjELsXk1cjU+fXwAR4OjQ==
- dependencies:
- flow-enums-runtime "^0.0.6"
- terser "^5.15.0"
-
-metro-minify-uglify@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.76.1.tgz#47875dfc17b7fc68ecab6b1388b2ed1a659fe248"
- integrity sha512-36wOrfb+bn2d8n3Is0RYUMl7S85jBk/QB7vqsW7inYqgVadosRz/uTItGghutB2GN0ElOEVPpOezr64I9+bqng==
- dependencies:
- uglify-es "^3.1.9"
-
metro-minify-uglify@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.76.8.tgz#74745045ea2dd29f8783db483b2fce58385ba695"
@@ -18017,58 +17808,6 @@ metro-minify-uglify@0.76.8:
dependencies:
uglify-es "^3.1.9"
-metro-minify-uglify@0.76.9:
- version "0.76.9"
- resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.76.9.tgz#e88c30c27911c053e1ee20e12077f0f4cbb154f8"
- integrity sha512-MXRrM3lFo62FPISlPfTqC6n9HTEI3RJjDU5SvpE7sJFfJKLx02xXQEltsL/wzvEqK+DhRQ5DEYACTwf5W4Z3yA==
- dependencies:
- uglify-es "^3.1.9"
-
-metro-react-native-babel-preset@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.76.1.tgz#c6cc85556091d2064fe9c9e339c227cdce773b1b"
- integrity sha512-1336W8B84eew4J3bfTbL2I40S3M03v5Rus6nTjAsXMkJZWpeVFvJLRG3NO04kp+7CyFJCR1JBOJPzpLLv75fNQ==
- dependencies:
- "@babel/core" "^7.20.0"
- "@babel/plugin-proposal-async-generator-functions" "^7.0.0"
- "@babel/plugin-proposal-class-properties" "^7.0.0"
- "@babel/plugin-proposal-export-default-from" "^7.0.0"
- "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0"
- "@babel/plugin-proposal-numeric-separator" "^7.0.0"
- "@babel/plugin-proposal-object-rest-spread" "^7.0.0"
- "@babel/plugin-proposal-optional-catch-binding" "^7.0.0"
- "@babel/plugin-proposal-optional-chaining" "^7.0.0"
- "@babel/plugin-syntax-dynamic-import" "^7.0.0"
- "@babel/plugin-syntax-export-default-from" "^7.0.0"
- "@babel/plugin-syntax-flow" "^7.18.0"
- "@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0"
- "@babel/plugin-syntax-optional-chaining" "^7.0.0"
- "@babel/plugin-transform-arrow-functions" "^7.0.0"
- "@babel/plugin-transform-async-to-generator" "^7.0.0"
- "@babel/plugin-transform-block-scoping" "^7.0.0"
- "@babel/plugin-transform-classes" "^7.0.0"
- "@babel/plugin-transform-computed-properties" "^7.0.0"
- "@babel/plugin-transform-destructuring" "^7.0.0"
- "@babel/plugin-transform-flow-strip-types" "^7.0.0"
- "@babel/plugin-transform-function-name" "^7.0.0"
- "@babel/plugin-transform-literals" "^7.0.0"
- "@babel/plugin-transform-modules-commonjs" "^7.0.0"
- "@babel/plugin-transform-named-capturing-groups-regex" "^7.0.0"
- "@babel/plugin-transform-parameters" "^7.0.0"
- "@babel/plugin-transform-react-display-name" "^7.0.0"
- "@babel/plugin-transform-react-jsx" "^7.0.0"
- "@babel/plugin-transform-react-jsx-self" "^7.0.0"
- "@babel/plugin-transform-react-jsx-source" "^7.0.0"
- "@babel/plugin-transform-runtime" "^7.0.0"
- "@babel/plugin-transform-shorthand-properties" "^7.0.0"
- "@babel/plugin-transform-spread" "^7.0.0"
- "@babel/plugin-transform-sticky-regex" "^7.0.0"
- "@babel/plugin-transform-typescript" "^7.5.0"
- "@babel/plugin-transform-unicode-regex" "^7.0.0"
- "@babel/template" "^7.0.0"
- babel-plugin-transform-flow-enums "^0.0.2"
- react-refresh "^0.4.0"
-
metro-react-native-babel-preset@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.76.8.tgz#7476efae14363cbdfeeec403b4f01d7348e6c048"
@@ -18181,11 +17920,6 @@ metro-react-native-babel-transformer@^0.76.9:
metro-react-native-babel-preset "0.76.9"
nullthrows "^1.1.1"
-metro-resolver@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.76.1.tgz#b24ab6489834952290346830eca1ec1ca7822e48"
- integrity sha512-a0tRFz1dwQX/trNIpi3PR6rE4fjvHeZgZFFhNbCYsLV9xrdkxbdUTo66eegnPji0DZRdxsUgo1YkVPHY6FNQiA==
-
metro-resolver@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.76.8.tgz#0862755b9b84e26853978322464fb37c6fdad76d"
@@ -18203,14 +17937,6 @@ metro-resolver@0.83.3:
dependencies:
flow-enums-runtime "^0.0.6"
-metro-runtime@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.76.1.tgz#f3b50b5a777d94222196459f48215dca7a98853c"
- integrity sha512-J9yMTpbsao0YOo8PrzgYKbC+ZpRrPu+T3HNme7MrWNr9DgIG+8ufkyvQl9u8ieTN2uWi0habIg5VXW35TJZtSw==
- dependencies:
- "@babel/runtime" "^7.0.0"
- react-refresh "^0.4.0"
-
metro-runtime@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.76.8.tgz#74b2d301a2be5f3bbde91b8f1312106f8ffe50c3"
@@ -18235,20 +17961,6 @@ metro-runtime@0.83.3, metro-runtime@^0.83.1:
"@babel/runtime" "^7.25.0"
flow-enums-runtime "^0.0.6"
-metro-source-map@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.76.1.tgz#1e0487bf807b9b52c5a71580d588ee02f6b059d4"
- integrity sha512-lfMhXX7JokW4pkDlqYYtzLaqC3OKF4/AJPjgMtR44NSFWvJJO/pHrBebVnth8zDG+hO7R+SXgtnXcGMYbrwyyQ==
- dependencies:
- "@babel/traverse" "^7.20.0"
- "@babel/types" "^7.20.0"
- invariant "^2.2.4"
- metro-symbolicate "0.76.1"
- nullthrows "^1.1.1"
- ob1 "0.76.1"
- source-map "^0.5.6"
- vlq "^1.0.0"
-
metro-source-map@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.76.8.tgz#f085800152a6ba0b41ca26833874d31ec36c5a53"
@@ -18263,20 +17975,6 @@ metro-source-map@0.76.8:
source-map "^0.5.6"
vlq "^1.0.0"
-metro-source-map@0.76.9:
- version "0.76.9"
- resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.76.9.tgz#0f976ada836717f307427d3830aea52a2ca7ed5f"
- integrity sha512-q5qsMlu8EFvsT46wUUh+ao+efDsicT30zmaPATNhq+PcTawDbDgnMuUD+FT0bvxxnisU2PWl91RdzKfNc2qPQA==
- dependencies:
- "@babel/traverse" "^7.20.0"
- "@babel/types" "^7.20.0"
- invariant "^2.2.4"
- metro-symbolicate "0.76.9"
- nullthrows "^1.1.1"
- ob1 "0.76.9"
- source-map "^0.5.6"
- vlq "^1.0.0"
-
metro-source-map@0.83.3, metro-source-map@^0.83.1:
version "0.83.3"
resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.83.3.tgz#04bb464f7928ea48bcdfd18912c8607cf317c898"
@@ -18293,18 +17991,6 @@ metro-source-map@0.83.3, metro-source-map@^0.83.1:
source-map "^0.5.6"
vlq "^1.0.0"
-metro-symbolicate@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.76.1.tgz#6beb39f1e31050eac228642073af5c0a8caeb6ac"
- integrity sha512-t7D7WXOE9d5eAGUiv7N61ZhDyQ0KbRegqB/AMzBJB3rPmuQPDO0nvadY1/m7BeJKu+va6KIF1gI6JolnxmCzjQ==
- dependencies:
- invariant "^2.2.4"
- metro-source-map "0.76.1"
- nullthrows "^1.1.1"
- source-map "^0.5.6"
- through2 "^2.0.1"
- vlq "^1.0.0"
-
metro-symbolicate@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.76.8.tgz#f102ac1a306d51597ecc8fdf961c0a88bddbca03"
@@ -18317,18 +18003,6 @@ metro-symbolicate@0.76.8:
through2 "^2.0.1"
vlq "^1.0.0"
-metro-symbolicate@0.76.9:
- version "0.76.9"
- resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.76.9.tgz#f1627ef6f73bb0c4d48c55684d3c87866a0b0920"
- integrity sha512-Yyq6Ukj/IeWnGST09kRt0sBK8TwzGZWoU7YAcQlh14+AREH454Olx4wbFTpkkhUkV05CzNCvUuXQ0efFxhA1bw==
- dependencies:
- invariant "^2.2.4"
- metro-source-map "0.76.9"
- nullthrows "^1.1.1"
- source-map "^0.5.6"
- through2 "^2.0.1"
- vlq "^1.0.0"
-
metro-symbolicate@0.83.3:
version "0.83.3"
resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.83.3.tgz#67af03950f0dfe19a7c059e3983e39a31e95d03a"
@@ -18341,17 +18015,6 @@ metro-symbolicate@0.83.3:
source-map "^0.5.6"
vlq "^1.0.0"
-metro-transform-plugins@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.76.1.tgz#22ef3373c9272303bf25a2b24fb3cdce2e07bdca"
- integrity sha512-3nhguyDVS0zi9rELCiB6jWW+vBLbnRxYVqNJqDEtX7Gf0DZnhl8oP8gU4k3R80wlADjahuhXV2xzzA0qVqfPog==
- dependencies:
- "@babel/core" "^7.20.0"
- "@babel/generator" "^7.20.0"
- "@babel/template" "^7.0.0"
- "@babel/traverse" "^7.20.0"
- nullthrows "^1.1.1"
-
metro-transform-plugins@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.76.8.tgz#d77c28a6547a8e3b72250f740fcfbd7f5408f8ba"
@@ -18363,47 +18026,6 @@ metro-transform-plugins@0.76.8:
"@babel/traverse" "^7.20.0"
nullthrows "^1.1.1"
-metro-transform-plugins@0.76.9:
- version "0.76.9"
- resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.76.9.tgz#73e34f2014d3df3c336a882b13e541bceb826d37"
- integrity sha512-YEQeNlOCt92I7S9A3xbrfaDfwfgcxz9PpD/1eeop3c4cO3z3Q3otYuxw0WJ/rUIW8pZfOm5XCehd+1NRbWlAaw==
- dependencies:
- "@babel/core" "^7.20.0"
- "@babel/generator" "^7.20.0"
- "@babel/template" "^7.0.0"
- "@babel/traverse" "^7.20.0"
- nullthrows "^1.1.1"
-
-metro-transform-plugins@0.83.3:
- version "0.83.3"
- resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.83.3.tgz#2c59ba841e269363cf3acb13138cb992f0c75013"
- integrity sha512-eRGoKJU6jmqOakBMH5kUB7VitEWiNrDzBHpYbkBXW7C5fUGeOd2CyqrosEzbMK5VMiZYyOcNFEphvxk3OXey2A==
- dependencies:
- "@babel/core" "^7.25.2"
- "@babel/generator" "^7.25.0"
- "@babel/template" "^7.25.0"
- "@babel/traverse" "^7.25.3"
- flow-enums-runtime "^0.0.6"
- nullthrows "^1.1.1"
-
-metro-transform-worker@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.76.1.tgz#b736bb4df90752d339b33c1caa7a10733cdfbc10"
- integrity sha512-TiFxZIxLrARd9OEr2l0yRK/eCGEZ7Euv1x8x45mZeo0YZ6SwJLiCuL/Z4TQDyvn7tT+PzgCQonmjtok1i2MhJQ==
- dependencies:
- "@babel/core" "^7.20.0"
- "@babel/generator" "^7.20.0"
- "@babel/parser" "^7.20.0"
- "@babel/types" "^7.20.0"
- babel-preset-fbjs "^3.4.0"
- metro "0.76.1"
- metro-babel-transformer "0.76.1"
- metro-cache "0.76.1"
- metro-cache-key "0.76.1"
- metro-source-map "0.76.1"
- metro-transform-plugins "0.76.1"
- nullthrows "^1.1.1"
-
metro-transform-worker@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.76.8.tgz#b9012a196cee205170d0c899b8b175b9305acdea"
@@ -18422,98 +18044,7 @@ metro-transform-worker@0.76.8:
metro-transform-plugins "0.76.8"
nullthrows "^1.1.1"
-metro-transform-worker@0.76.9:
- version "0.76.9"
- resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.76.9.tgz#281fad223f0447e1ff9cc44d6f7e33dfab9ab120"
- integrity sha512-F69A0q0qFdJmP2Clqr6TpTSn4WTV9p5A28h5t9o+mB22ryXBZfUQ6BFBBW/6Wp2k/UtPH+oOsBfV9guiqm3d2Q==
- dependencies:
- "@babel/core" "^7.20.0"
- "@babel/generator" "^7.20.0"
- "@babel/parser" "^7.20.0"
- "@babel/types" "^7.20.0"
- babel-preset-fbjs "^3.4.0"
- metro "0.76.9"
- metro-babel-transformer "0.76.9"
- metro-cache "0.76.9"
- metro-cache-key "0.76.9"
- metro-minify-terser "0.76.9"
- metro-source-map "0.76.9"
- metro-transform-plugins "0.76.9"
- nullthrows "^1.1.1"
-
-metro-transform-worker@0.83.3:
- version "0.83.3"
- resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.83.3.tgz#ca6ae4a02b0f61b33299e6e56bacaba32dcd607f"
- integrity sha512-Ztekew9t/gOIMZX1tvJOgX7KlSLL5kWykl0Iwu2cL2vKMKVALRl1hysyhUw0vjpAvLFx+Kfq9VLjnHIkW32fPA==
- dependencies:
- "@babel/core" "^7.25.2"
- "@babel/generator" "^7.25.0"
- "@babel/parser" "^7.25.3"
- "@babel/types" "^7.25.2"
- flow-enums-runtime "^0.0.6"
- metro "0.83.3"
- metro-babel-transformer "0.83.3"
- metro-cache "0.83.3"
- metro-cache-key "0.83.3"
- metro-minify-terser "0.83.3"
- metro-source-map "0.83.3"
- metro-transform-plugins "0.83.3"
- nullthrows "^1.1.1"
-
-metro@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/metro/-/metro-0.76.1.tgz#935556c1bfaebd9bda36f0eaca041d3c343a8fdd"
- integrity sha512-zuO8wKvF/kgVMjcKkxM/o68J4Kqc1/ZtQ3mRQdNe1+/hHjIfoxfO3Btr98jFMUL4VHq7Dg5p/mJZdzOabU7Sbg==
- dependencies:
- "@babel/code-frame" "^7.0.0"
- "@babel/core" "^7.20.0"
- "@babel/generator" "^7.20.0"
- "@babel/parser" "^7.20.0"
- "@babel/template" "^7.0.0"
- "@babel/traverse" "^7.20.0"
- "@babel/types" "^7.20.0"
- accepts "^1.3.7"
- async "^3.2.2"
- chalk "^4.0.0"
- ci-info "^2.0.0"
- connect "^3.6.5"
- debug "^2.2.0"
- denodeify "^1.2.1"
- error-stack-parser "^2.0.6"
- graceful-fs "^4.2.4"
- hermes-parser "0.8.0"
- image-size "^0.6.0"
- invariant "^2.2.4"
- jest-worker "^27.2.0"
- lodash.throttle "^4.1.1"
- metro-babel-transformer "0.76.1"
- metro-cache "0.76.1"
- metro-cache-key "0.76.1"
- metro-config "0.76.1"
- metro-core "0.76.1"
- metro-file-map "0.76.1"
- metro-inspector-proxy "0.76.1"
- metro-minify-terser "0.76.1"
- metro-minify-uglify "0.76.1"
- metro-react-native-babel-preset "0.76.1"
- metro-resolver "0.76.1"
- metro-runtime "0.76.1"
- metro-source-map "0.76.1"
- metro-symbolicate "0.76.1"
- metro-transform-plugins "0.76.1"
- metro-transform-worker "0.76.1"
- mime-types "^2.1.27"
- node-fetch "^2.2.0"
- nullthrows "^1.1.1"
- rimraf "^3.0.2"
- serialize-error "^2.1.0"
- source-map "^0.5.6"
- strip-ansi "^6.0.0"
- throat "^5.0.0"
- ws "^7.5.1"
- yargs "^17.6.2"
-
-metro@0.76.8:
+metro@0.76.8, metro@0.76.9, metro@0.83.3, metro@^0.83.1:
version "0.76.8"
resolved "https://registry.yarnpkg.com/metro/-/metro-0.76.8.tgz#ba526808b99977ca3f9ac5a7432fd02a340d13a6"
integrity sha512-oQA3gLzrrYv3qKtuWArMgHPbHu8odZOD9AoavrqSFllkPgOtmkBvNNDLCELqv5SjBfqjISNffypg+5UGG3y0pg==
@@ -18567,105 +18098,6 @@ metro@0.76.8:
ws "^7.5.1"
yargs "^17.6.2"
-metro@0.76.9:
- version "0.76.9"
- resolved "https://registry.yarnpkg.com/metro/-/metro-0.76.9.tgz#605fddf1a54d27762ddba2f636420ae2408862df"
- integrity sha512-gcjcfs0l5qIPg0lc5P7pj0x7vPJ97tan+OnEjiYLbKjR1D7Oa78CE93YUPyymUPH6q7VzlzMm1UjT35waEkZUw==
- dependencies:
- "@babel/code-frame" "^7.0.0"
- "@babel/core" "^7.20.0"
- "@babel/generator" "^7.20.0"
- "@babel/parser" "^7.20.0"
- "@babel/template" "^7.0.0"
- "@babel/traverse" "^7.20.0"
- "@babel/types" "^7.20.0"
- accepts "^1.3.7"
- async "^3.2.2"
- chalk "^4.0.0"
- ci-info "^2.0.0"
- connect "^3.6.5"
- debug "^2.2.0"
- denodeify "^1.2.1"
- error-stack-parser "^2.0.6"
- graceful-fs "^4.2.4"
- hermes-parser "0.12.0"
- image-size "^1.0.2"
- invariant "^2.2.4"
- jest-worker "^27.2.0"
- jsc-safe-url "^0.2.2"
- lodash.throttle "^4.1.1"
- metro-babel-transformer "0.76.9"
- metro-cache "0.76.9"
- metro-cache-key "0.76.9"
- metro-config "0.76.9"
- metro-core "0.76.9"
- metro-file-map "0.76.9"
- metro-inspector-proxy "0.76.9"
- metro-minify-uglify "0.76.9"
- metro-react-native-babel-preset "0.76.9"
- metro-resolver "0.76.9"
- metro-runtime "0.76.9"
- metro-source-map "0.76.9"
- metro-symbolicate "0.76.9"
- metro-transform-plugins "0.76.9"
- metro-transform-worker "0.76.9"
- mime-types "^2.1.27"
- node-fetch "^2.2.0"
- nullthrows "^1.1.1"
- rimraf "^3.0.2"
- serialize-error "^2.1.0"
- source-map "^0.5.6"
- strip-ansi "^6.0.0"
- throat "^5.0.0"
- ws "^7.5.1"
- yargs "^17.6.2"
-
-metro@0.83.3, metro@^0.83.1:
- version "0.83.3"
- resolved "https://registry.yarnpkg.com/metro/-/metro-0.83.3.tgz#1e7e04c15519af746f8932c7f9c553d92c39e922"
- integrity sha512-+rP+/GieOzkt97hSJ0MrPOuAH/jpaS21ZDvL9DJ35QYRDlQcwzcvUlGUf79AnQxq/2NPiS/AULhhM4TKutIt8Q==
- dependencies:
- "@babel/code-frame" "^7.24.7"
- "@babel/core" "^7.25.2"
- "@babel/generator" "^7.25.0"
- "@babel/parser" "^7.25.3"
- "@babel/template" "^7.25.0"
- "@babel/traverse" "^7.25.3"
- "@babel/types" "^7.25.2"
- accepts "^1.3.7"
- chalk "^4.0.0"
- ci-info "^2.0.0"
- connect "^3.6.5"
- debug "^4.4.0"
- error-stack-parser "^2.0.6"
- flow-enums-runtime "^0.0.6"
- graceful-fs "^4.2.4"
- hermes-parser "0.32.0"
- image-size "^1.0.2"
- invariant "^2.2.4"
- jest-worker "^29.7.0"
- jsc-safe-url "^0.2.2"
- lodash.throttle "^4.1.1"
- metro-babel-transformer "0.83.3"
- metro-cache "0.83.3"
- metro-cache-key "0.83.3"
- metro-config "0.83.3"
- metro-core "0.83.3"
- metro-file-map "0.83.3"
- metro-resolver "0.83.3"
- metro-runtime "0.83.3"
- metro-source-map "0.83.3"
- metro-symbolicate "0.83.3"
- metro-transform-plugins "0.83.3"
- metro-transform-worker "0.83.3"
- mime-types "^2.1.27"
- nullthrows "^1.1.1"
- serialize-error "^2.1.0"
- source-map "^0.5.6"
- throat "^5.0.0"
- ws "^7.5.10"
- yargs "^17.6.2"
-
microevent.ts@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0"
@@ -19461,21 +18893,11 @@ nyc@^15.1.0:
test-exclude "^6.0.0"
yargs "^15.0.2"
-ob1@0.76.1:
- version "0.76.1"
- resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.76.1.tgz#83bc8ba5ca7856be43a17491d0cb0f81643cb58e"
- integrity sha512-1i5IJGQGGU9c3WZ/vk718F34cEuTGYqBPBDrQD8KHdbfZuM4B84OBXTkTPGNbVEC+VyzA8uo7O2PRVlMCAiCnQ==
-
ob1@0.76.8:
version "0.76.8"
resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.76.8.tgz#ac4c459465b1c0e2c29aaa527e09fc463d3ffec8"
integrity sha512-dlBkJJV5M/msj9KYA9upc+nUWVwuOFFTbu28X6kZeGwcuW+JxaHSBZ70SYQnk5M+j5JbNLR6yKHmgW4M5E7X5g==
-ob1@0.76.9:
- version "0.76.9"
- resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.76.9.tgz#a493e4b83a0fb39200de639804b5d06eed5599dc"
- integrity sha512-g0I/OLnSxf6OrN3QjSew3bTDJCdbZoWxnh8adh1z36alwCuGF1dgDeRA25bTYSakrG5WULSaWJPOdgnf1O/oQw==
-
ob1@0.83.3:
version "0.83.3"
resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.83.3.tgz#2208e20c9070e9beff3ad067f2db458fa6b07014"
@@ -20844,6 +20266,11 @@ qs@^6.10.0, qs@^6.12.3, qs@~6.14.0:
dependencies:
side-channel "^1.1.0"
+qs@~6.9.1:
+ version "6.9.7"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe"
+ integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==
+
query-selector-shadow-dom@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz#1c7b0058eff4881ac44f45d8f84ede32e9a2f349"
@@ -21214,6 +20641,13 @@ react-native-dotenv@^3.4.9:
dependencies:
dotenv "^16.4.5"
+react-native-element-dropdown@^2.12.4:
+ version "2.12.4"
+ resolved "https://registry.yarnpkg.com/react-native-element-dropdown/-/react-native-element-dropdown-2.12.4.tgz#259db84e673b9f4fc03090a54760efd4f4a1456c"
+ integrity sha512-abZc5SVji9FIt7fjojRYrbuvp03CoeZJrgvezQoDoSOrpiTqkX69ix5m+j06W2AVncA0VWvbT+vCMam8SoVadw==
+ dependencies:
+ lodash "^4.17.21"
+
react-native-error-boundary@^1.2.3:
version "1.2.9"
resolved "https://registry.yarnpkg.com/react-native-error-boundary/-/react-native-error-boundary-1.2.9.tgz#ac504db7c0eeb95ec06a22d50de3674059a651bd"
@@ -21254,6 +20688,16 @@ react-native-get-random-values@^1.9.0:
dependencies:
fast-base64-decode "^1.0.0"
+react-native-google-places-autocomplete@^2.5.7:
+ version "2.5.7"
+ resolved "https://registry.yarnpkg.com/react-native-google-places-autocomplete/-/react-native-google-places-autocomplete-2.5.7.tgz#92a7ded4466a46fff70fa428f9f8dd60c19f9edb"
+ integrity sha512-yWEJ31gsRptStEZDele9no0J6Z+MxtNpQKKwjvGmFrWmpYDEAzpRtxy1Xq0u+ckMepJfrg/EU+OL5LgtMbnCDA==
+ dependencies:
+ lodash.debounce "^4.0.8"
+ prop-types "^15.7.2"
+ qs "~6.9.1"
+ uuid "^10.0.0"
+
react-native-gradle-plugin@^0.71.19:
version "0.71.19"
resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.19.tgz#3379e28341fcd189bc1f4691cefc84c1a4d7d232"
@@ -21269,11 +20713,6 @@ react-native-html-to-pdf@^0.12.0:
resolved "https://registry.yarnpkg.com/react-native-html-to-pdf/-/react-native-html-to-pdf-0.12.0.tgz#2b467296f85c9c9783a7288b19722a7028dcbcb8"
integrity sha512-Yb5WO9SfF86s5Yv9PqXQ7fZDr9zZOJ+6jtweT9zFLraPNHWX7pSxe2dSkeg3cGiNrib65ZXGN6ksHymfYLFSSg==
-react-native-image-crop-picker@^0.39.0:
- version "0.39.0"
- resolved "https://registry.yarnpkg.com/react-native-image-crop-picker/-/react-native-image-crop-picker-0.39.0.tgz#9cb8e8ffb0e8ab06f7b3227cadf077169e225eba"
- integrity sha512-4aANbQMrmU6zN/4b0rVBA7SbaZ3aa5JESm3Xk751sINybZMt1yz/9h95LkO7U0pbslHDo3ofXjG75PmQRP6a/w==
-
react-native-image-picker@^7.0.0:
version "7.2.3"
resolved "https://registry.yarnpkg.com/react-native-image-picker/-/react-native-image-picker-7.2.3.tgz#9c402591462af256cdd9aed796c28083a48f90cd"
@@ -21569,7 +21008,7 @@ react-native-vision-camera@3.6.4:
resolved "https://registry.yarnpkg.com/react-native-vision-camera/-/react-native-vision-camera-3.6.4.tgz#ac77238f31779f647d03bce3cd4b5eba61f3df85"
integrity sha512-DDWb8aB5tE7sM7YuU5f31AuhJVDJS3amZoZMQgHWa8S9h0acp3hY3uyriKzXshj/asYu2UAo5QUUglwl7Mcd1Q==
-react-native-walkthrough-tooltip@^1.4.0:
+react-native-walkthrough-tooltip@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/react-native-walkthrough-tooltip/-/react-native-walkthrough-tooltip-1.6.0.tgz#a9b9196973d2fdef8f36bbcae57c93069cd9fb3e"
integrity sha512-8DHpcqsF+2VULYnKJCSZtllhlFUFiZcWCwOlw5RLkS451ElxPWJn9ShOFVZtkPMcwQAirq3SovumVM7Y/li0Fw==
@@ -21938,6 +21377,11 @@ redis-parser@^3.0.0:
dependencies:
redis-errors "^1.0.0"
+redux-persist@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8"
+ integrity sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==
+
redux-thunk@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-3.1.0.tgz#94aa6e04977c30e14e892eae84978c1af6058ff3"
@@ -25296,6 +24740,11 @@ uuid@3.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
+uuid@^10.0.0:
+ version "10.0.0"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294"
+ integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==
+
uuid@^3.3.2:
version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
@@ -26299,10 +25748,10 @@ write-file-atomic@^4.0.1, write-file-atomic@^4.0.2:
imurmurhash "^0.1.4"
signal-exit "^3.0.7"
-ws@8.13.0, ws@8.16.0, "ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^6.2.2, ws@^6.2.3, ws@^7, ws@^7.0.0, ws@^7.1.2, ws@^7.5.1, ws@^7.5.10, ws@^8.12.0, ws@^8.14.0, ws@^8.17.1, ws@^8.18.0, ws@^8.18.3, ws@^8.2.3, ws@^8.8.0:
- version "8.18.3"
- resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472"
- integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==
+ws@8.13.0, ws@8.16.0, "ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^6.2.2, ws@^6.2.3, ws@^7, ws@^7.0.0, ws@^7.1.2, ws@^7.5.1, ws@^8.12.0, ws@^8.14.0, ws@^8.17.1, ws@^8.18.0, ws@^8.18.3, ws@^8.2.3, ws@^8.8.0:
+ version "8.18.1"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb"
+ integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==
x-default-browser@^0.4.0:
version "0.4.0"