diff --git a/apps/wallet-mobile/.storybook/storybook.requires.js b/apps/wallet-mobile/.storybook/storybook.requires.js
index a41e78585f..21011eaba6 100644
--- a/apps/wallet-mobile/.storybook/storybook.requires.js
+++ b/apps/wallet-mobile/.storybook/storybook.requires.js
@@ -88,6 +88,7 @@ const getStories = () => {
"./src/components/PairedBalance/PairedBalance.stories.tsx": require("../src/components/PairedBalance/PairedBalance.stories.tsx"),
"./src/components/PressableIcon/PressableIcon.stories.tsx": require("../src/components/PressableIcon/PressableIcon.stories.tsx"),
"./src/components/ShareQRCodeCard/ShareQRCodeCard.stories.tsx": require("../src/components/ShareQRCodeCard/ShareQRCodeCard.stories.tsx"),
+ "./src/components/SimpleTab/SimpleTab.stories.tsx": require("../src/components/SimpleTab/SimpleTab.stories.tsx"),
"./src/components/SomethingWentWrong/SomethingWentWrong.stories.tsx": require("../src/components/SomethingWentWrong/SomethingWentWrong.stories.tsx"),
"./src/components/StepperProgress/StepperProgress.stories.tsx": require("../src/components/StepperProgress/StepperProgress.stories.tsx"),
"./src/components/TextInput/TextInput.stories.tsx": require("../src/components/TextInput/TextInput.stories.tsx"),
@@ -121,7 +122,6 @@ const getStories = () => {
"./src/features/Discover/useCases/SearchDappInBrowser/SearchDappInBrowserScreen.stories.tsx": require("../src/features/Discover/useCases/SearchDappInBrowser/SearchDappInBrowserScreen.stories.tsx"),
"./src/features/Discover/useCases/SelectDappFromList/CountDAppsAvailable/CountDAppsAvailable.stories.tsx": require("../src/features/Discover/useCases/SelectDappFromList/CountDAppsAvailable/CountDAppsAvailable.stories.tsx"),
"./src/features/Discover/useCases/SelectDappFromList/CountDAppsConnected/CountDAppsConnected.stories.tsx": require("../src/features/Discover/useCases/SelectDappFromList/CountDAppsConnected/CountDAppsConnected.stories.tsx"),
- "./src/features/Discover/useCases/SelectDappFromList/DAppExplorerTabItem/DAppExplorerTabItem.stories.tsx": require("../src/features/Discover/useCases/SelectDappFromList/DAppExplorerTabItem/DAppExplorerTabItem.stories.tsx"),
"./src/features/Discover/useCases/SelectDappFromList/DAppListItem/DAppItemSkeleton.stories.tsx": require("../src/features/Discover/useCases/SelectDappFromList/DAppListItem/DAppItemSkeleton.stories.tsx"),
"./src/features/Discover/useCases/SelectDappFromList/DAppListItem/DAppListItem.stories.tsx": require("../src/features/Discover/useCases/SelectDappFromList/DAppListItem/DAppListItem.stories.tsx"),
"./src/features/Discover/useCases/SelectDappFromList/DAppTypes/DAppTypes.stories.tsx": require("../src/features/Discover/useCases/SelectDappFromList/DAppTypes/DAppTypes.stories.tsx"),
@@ -194,7 +194,6 @@ const getStories = () => {
"./src/features/Settings/Currency/ChangeCurrencyScreen.stories.tsx": require("../src/features/Settings/Currency/ChangeCurrencyScreen.stories.tsx"),
"./src/features/Settings/EasyConfirmation/EasyConfirmationScreen.stories.tsx": require("../src/features/Settings/EasyConfirmation/EasyConfirmationScreen.stories.tsx"),
"./src/features/Settings/EnableLoginWithOs/EnableLoginWithOsScreen.stories.tsx": require("../src/features/Settings/EnableLoginWithOs/EnableLoginWithOsScreen.stories.tsx"),
- "./src/features/Settings/ManageCollateral/ConfirmTx/ConfirmTxScreen.stories.tsx": require("../src/features/Settings/ManageCollateral/ConfirmTx/ConfirmTxScreen.stories.tsx"),
"./src/features/Settings/ManageCollateral/ConfirmTx/FailedTx/FailedTxScreen.stories.tsx": require("../src/features/Settings/ManageCollateral/ConfirmTx/FailedTx/FailedTxScreen.stories.tsx"),
"./src/features/Settings/ManageCollateral/ConfirmTx/SubmittedTx/SubmittedTxScreen.stories.tsx": require("../src/features/Settings/ManageCollateral/ConfirmTx/SubmittedTx/SubmittedTxScreen.stories.tsx"),
"./src/features/Settings/ManageCollateral/ManageCollateralScreen.stories.tsx": require("../src/features/Settings/ManageCollateral/ManageCollateralScreen.stories.tsx"),
diff --git a/apps/wallet-mobile/src/YoroiApp.tsx b/apps/wallet-mobile/src/YoroiApp.tsx
index 99a3c8c92c..7b35f285ea 100644
--- a/apps/wallet-mobile/src/YoroiApp.tsx
+++ b/apps/wallet-mobile/src/YoroiApp.tsx
@@ -17,6 +17,7 @@ import {AuthProvider} from './features/Auth/AuthProvider'
import {BrowserProvider} from './features/Discover/common/BrowserProvider'
import {notificationManager} from './features/Notifications/useCases/common/notification-manager'
import {PortfolioTokenActivityProvider} from './features/Portfolio/common/PortfolioTokenActivityProvider'
+import {ReviewTxProvider} from './features/ReviewTx/common/ReviewTxProvider'
import {CurrencyProvider} from './features/Settings/Currency/CurrencyContext'
import {AutomaticWalletOpenerProvider} from './features/WalletManager/context/AutomaticWalletOpeningProvider'
import {WalletManagerProvider} from './features/WalletManager/context/WalletManagerProvider'
@@ -67,9 +68,11 @@ const Yoroi = () => {
-
-
-
+
+
+
+
+
diff --git a/apps/wallet-mobile/src/features/Portfolio/common/MediaPreview/MediaPreview.tsx b/apps/wallet-mobile/src/components/MediaPreview/MediaPreview.tsx
similarity index 90%
rename from apps/wallet-mobile/src/features/Portfolio/common/MediaPreview/MediaPreview.tsx
rename to apps/wallet-mobile/src/components/MediaPreview/MediaPreview.tsx
index 8dacd28a7c..36f43371e1 100644
--- a/apps/wallet-mobile/src/features/Portfolio/common/MediaPreview/MediaPreview.tsx
+++ b/apps/wallet-mobile/src/components/MediaPreview/MediaPreview.tsx
@@ -5,9 +5,9 @@ import React from 'react'
import {ImageStyle, StyleSheet, View} from 'react-native'
import SkeletonPlaceholder from 'react-native-skeleton-placeholder'
-import placeholderLight from '../../../../assets/img/nft-placeholder.png'
-import placeholderDark from '../../../../assets/img/nft-placeholder-dark.png'
-import {useSelectedWallet} from '../../../WalletManager/common/hooks/useSelectedWallet'
+import placeholderLight from '../../assets/img/nft-placeholder.png'
+import placeholderDark from '../../assets/img/nft-placeholder-dark.png'
+import {useSelectedWallet} from '../../features/WalletManager/common/hooks/useSelectedWallet'
type MediaPreviewProps = {
info: Portfolio.Token.Info
diff --git a/apps/wallet-mobile/src/components/SimpleTab/SimpleTab.stories.tsx b/apps/wallet-mobile/src/components/SimpleTab/SimpleTab.stories.tsx
new file mode 100644
index 0000000000..549ead2f95
--- /dev/null
+++ b/apps/wallet-mobile/src/components/SimpleTab/SimpleTab.stories.tsx
@@ -0,0 +1,26 @@
+import {action} from '@storybook/addon-actions'
+import {storiesOf} from '@storybook/react-native'
+import * as React from 'react'
+import {View} from 'react-native'
+
+import {SimpleTab} from './SimpleTab'
+
+storiesOf('SimpleTab', module)
+ .add('Active', () => )
+ .add('Inactive', () => )
+
+const Active = () => {
+ return (
+
+
+
+ )
+}
+
+const Inactive = () => {
+ return (
+
+
+
+ )
+}
diff --git a/apps/wallet-mobile/src/features/Discover/useCases/SelectDappFromList/DAppExplorerTabItem/DAppExplorerTabItem.tsx b/apps/wallet-mobile/src/components/SimpleTab/SimpleTab.tsx
similarity index 89%
rename from apps/wallet-mobile/src/features/Discover/useCases/SelectDappFromList/DAppExplorerTabItem/DAppExplorerTabItem.tsx
rename to apps/wallet-mobile/src/components/SimpleTab/SimpleTab.tsx
index e140c97e43..e72787c55d 100644
--- a/apps/wallet-mobile/src/features/Discover/useCases/SelectDappFromList/DAppExplorerTabItem/DAppExplorerTabItem.tsx
+++ b/apps/wallet-mobile/src/components/SimpleTab/SimpleTab.tsx
@@ -8,7 +8,7 @@ type Props = {
onPress: () => void
}
-export const DAppExplorerTabItem = ({name, onPress, isActive}: Props) => {
+export const SimpleTab = ({name, onPress, isActive}: Props) => {
const {styles} = useStyles()
return (
@@ -34,5 +34,5 @@ const useStyles = () => {
},
})
- return {styles}
+ return {styles} as const
}
diff --git a/apps/wallet-mobile/src/features/Discover/useCases/SelectDappFromList/DAppExplorerTabItem/DAppExplorerTabItem.stories.tsx b/apps/wallet-mobile/src/features/Discover/useCases/SelectDappFromList/DAppExplorerTabItem/DAppExplorerTabItem.stories.tsx
deleted file mode 100644
index 626ac02ba0..0000000000
--- a/apps/wallet-mobile/src/features/Discover/useCases/SelectDappFromList/DAppExplorerTabItem/DAppExplorerTabItem.stories.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import {action} from '@storybook/addon-actions'
-import {storiesOf} from '@storybook/react-native'
-import * as React from 'react'
-import {View} from 'react-native'
-
-import {DAppExplorerTabItem} from './DAppExplorerTabItem'
-
-storiesOf('Discover DAppExplorerTabItem', module)
- .add('connected', () => )
- .add('recommended', () => )
-
-const Connected = () => {
- return (
-
-
-
- )
-}
-
-const Recommended = () => {
- return (
-
-
-
- )
-}
diff --git a/apps/wallet-mobile/src/features/Discover/useCases/SelectDappFromList/SelectDappFromListScreen.tsx b/apps/wallet-mobile/src/features/Discover/useCases/SelectDappFromList/SelectDappFromListScreen.tsx
index a21de2ae63..39a2ee4b6c 100644
--- a/apps/wallet-mobile/src/features/Discover/useCases/SelectDappFromList/SelectDappFromListScreen.tsx
+++ b/apps/wallet-mobile/src/features/Discover/useCases/SelectDappFromList/SelectDappFromListScreen.tsx
@@ -3,6 +3,7 @@ import {useTheme} from '@yoroi/theme'
import * as React from 'react'
import {FlatList, StyleSheet, View} from 'react-native'
+import {SimpleTab} from '../../../../components/SimpleTab/SimpleTab'
import {Spacer} from '../../../../components/Spacer/Spacer'
import {useMetrics} from '../../../../kernel/metrics/metricsManager'
import {useSearch, useSearchOnNavBar} from '../../../Search/SearchContext'
@@ -13,7 +14,6 @@ import {useDAppsConnected} from '../../common/useDAppsConnected'
import {useStrings} from '../../common/useStrings'
import {CountDAppsAvailable} from './CountDAppsAvailable/CountDAppsAvailable'
import {CountDAppsConnected} from './CountDAppsConnected/CountDAppsConnected'
-import {DAppExplorerTabItem} from './DAppExplorerTabItem/DAppExplorerTabItem'
import {DAppListItem} from './DAppListItem/DAppListItem'
import {DAppTypes} from './DAppTypes/DAppTypes'
import {WelcomeDAppModal} from './WelcomeDAppModal'
@@ -153,13 +153,13 @@ const HeaderControl = ({
<>
{hasConnectedDapps && (
- onTabChange(DAppTabs.connected)}
/>
- onTabChange(DAppTabs.recommended)}
diff --git a/apps/wallet-mobile/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx b/apps/wallet-mobile/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx
index bcd4e24f25..f2cff3c32c 100644
--- a/apps/wallet-mobile/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx
+++ b/apps/wallet-mobile/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx
@@ -20,6 +20,7 @@ import {Boundary} from '../../../../components/Boundary/Boundary'
import {CopyButton} from '../../../../components/CopyButton'
import {FadeIn} from '../../../../components/FadeIn'
import {Hr} from '../../../../components/Hr/Hr'
+import {MediaPreview} from '../../../../components/MediaPreview/MediaPreview'
import {Spacer} from '../../../../components/Spacer/Spacer'
import {Tab, TabPanel, TabPanels, Tabs} from '../../../../components/Tabs/Tabs'
import {Text} from '../../../../components/Text'
@@ -28,7 +29,6 @@ import {useMetrics} from '../../../../kernel/metrics/metricsManager'
import {NftRoutes} from '../../../../kernel/navigation'
import {useSelectedWallet} from '../../../WalletManager/common/hooks/useSelectedWallet'
import {usePortfolioImageInvalidate} from '../hooks/usePortfolioImage'
-import {MediaPreview} from '../MediaPreview/MediaPreview'
import {useNavigateTo} from '../navigation'
export const MediaDetailsScreen = () => {
diff --git a/apps/wallet-mobile/src/features/Portfolio/common/MediaGallery/MediaGallery.tsx b/apps/wallet-mobile/src/features/Portfolio/common/MediaGallery/MediaGallery.tsx
index 149d062a5f..273b193caf 100644
--- a/apps/wallet-mobile/src/features/Portfolio/common/MediaGallery/MediaGallery.tsx
+++ b/apps/wallet-mobile/src/features/Portfolio/common/MediaGallery/MediaGallery.tsx
@@ -4,8 +4,8 @@ import {Balance, Portfolio} from '@yoroi/types'
import * as React from 'react'
import {StyleSheet, Text, TouchableOpacity, useWindowDimensions, View} from 'react-native'
+import {MediaPreview} from '../../../../components/MediaPreview/MediaPreview'
import {Spacer} from '../../../../components/Spacer/Spacer'
-import {MediaPreview} from '../MediaPreview/MediaPreview'
type Props = {
amounts: ReadonlyArray
diff --git a/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioDashboard/DashboardNFTsList/DashboardNFTsList.tsx b/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioDashboard/DashboardNFTsList/DashboardNFTsList.tsx
index d60950805a..a3e6402aa3 100644
--- a/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioDashboard/DashboardNFTsList/DashboardNFTsList.tsx
+++ b/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioDashboard/DashboardNFTsList/DashboardNFTsList.tsx
@@ -5,12 +5,12 @@ import {FlatList, Image, StyleSheet, Text, TouchableOpacity, useWindowDimensions
import placeholderLight from '../../../../../assets/img/nft-placeholder.png'
import placeholderDark from '../../../../../assets/img/nft-placeholder-dark.png'
import {Icon} from '../../../../../components/Icon'
+import {MediaPreview} from '../../../../../components/MediaPreview/MediaPreview'
import {Spacer} from '../../../../../components/Spacer/Spacer'
import {useSelectedWallet} from '../../../../WalletManager/common/hooks/useSelectedWallet'
import {useNavigateTo} from '../../../common/hooks/useNavigateTo'
import {usePortfolioBalances} from '../../../common/hooks/usePortfolioBalances'
import {useStrings} from '../../../common/hooks/useStrings'
-import {MediaPreview} from '../../../common/MediaPreview/MediaPreview'
export const DashboardNFTsList = () => {
const {styles, cardItemWidth} = useStyles()
diff --git a/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/PortfolioWalletTokenList/ListMediaGalleryScreen/ZoomMediaImageScreen.tsx b/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/PortfolioWalletTokenList/ListMediaGalleryScreen/ZoomMediaImageScreen.tsx
index fc4fdb9071..b655b30e32 100644
--- a/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/PortfolioWalletTokenList/ListMediaGalleryScreen/ZoomMediaImageScreen.tsx
+++ b/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/PortfolioWalletTokenList/ListMediaGalleryScreen/ZoomMediaImageScreen.tsx
@@ -6,11 +6,11 @@ import {StyleSheet, useWindowDimensions, View} from 'react-native'
import ViewTransformer from 'react-native-easy-view-transformer'
import {FadeIn} from '../../../../../../components/FadeIn'
+import {MediaPreview} from '../../../../../../components/MediaPreview/MediaPreview'
import {useMetrics} from '../../../../../../kernel/metrics/metricsManager'
import {NftRoutes, useParams} from '../../../../../../kernel/navigation'
import {isEmptyString} from '../../../../../../kernel/utils'
import {useSelectedWallet} from '../../../../../WalletManager/common/hooks/useSelectedWallet'
-import {MediaPreview} from '../../../../common/MediaPreview/MediaPreview'
type Params = NftRoutes['nft-details']
diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/CollapsibleSection.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/Accordion.tsx
similarity index 80%
rename from apps/wallet-mobile/src/features/ReviewTx/common/CollapsibleSection.tsx
rename to apps/wallet-mobile/src/features/ReviewTx/common/Accordion.tsx
index 048ac41d0e..92e7bfb3ac 100644
--- a/apps/wallet-mobile/src/features/ReviewTx/common/CollapsibleSection.tsx
+++ b/apps/wallet-mobile/src/features/ReviewTx/common/Accordion.tsx
@@ -4,7 +4,7 @@ import {Animated, LayoutAnimation, StyleSheet, Text, TouchableOpacity, View} fro
import {Icon} from '../../../components/Icon'
-export const CollapsibleSection = ({label, children}: {label: string; children: React.ReactNode}) => {
+export const Accordion = ({label, children}: {label: string; children: React.ReactNode}) => {
const {styles, colors} = useStyles()
const [isOpen, setIsOpen] = React.useState(false)
const animatedHeight = React.useRef(new Animated.Value(0)).current
@@ -20,14 +20,12 @@ export const CollapsibleSection = ({label, children}: {label: string; children:
}
return (
- <>
-
+
+
{label}
-
-
-
-
+
+
{children}
- >
+
)
}
diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/Address.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/Address.tsx
deleted file mode 100644
index 5279b07df9..0000000000
--- a/apps/wallet-mobile/src/features/ReviewTx/common/Address.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import {useTheme} from '@yoroi/theme'
-import * as React from 'react'
-import {StyleSheet, Text, TextStyle, TouchableOpacity, View} from 'react-native'
-
-import {Icon} from '../../../components/Icon'
-import {Space} from '../../../components/Space/Space'
-import {useCopy} from '../../../hooks/useCopy'
-
-export const Address = ({
- address,
- index,
- textStyle,
- multiline = false,
-}: {
- address: string
- index?: number
- textStyle?: TextStyle
- multiline?: boolean
-}) => {
- const {styles, colors} = useStyles()
- const [, copy] = useCopy()
-
- return (
-
-
- {address}
-
-
- {index !== undefined && (
- <>
-
-
- {`#${index}`}
-
-
- >
- )}
-
- copy(address)} activeOpacity={0.5}>
-
-
-
- )
-}
-
-const useStyles = () => {
- const {atoms, color} = useTheme()
- const styles = StyleSheet.create({
- address: {
- ...atoms.flex_row,
- ...atoms.justify_between,
- },
- addressText: {
- ...atoms.flex_1,
- ...atoms.body_2_md_regular,
- color: color.text_gray_medium,
- },
- index: {
- ...atoms.body_2_md_medium,
- color: color.text_gray_medium,
- },
- })
-
- const colors = {
- copy: color.gray_900,
- }
-
- return {styles, colors} as const
-}
diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/CopiableText.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/CopiableText.tsx
new file mode 100644
index 0000000000..b09812b5a6
--- /dev/null
+++ b/apps/wallet-mobile/src/features/ReviewTx/common/CopiableText.tsx
@@ -0,0 +1,37 @@
+import {useTheme} from '@yoroi/theme'
+import * as React from 'react'
+import {StyleSheet, TouchableOpacity, View} from 'react-native'
+
+import {Icon} from '../../../components/Icon'
+import {useCopy} from '../../../hooks/useCopy'
+
+export const CopiableText = ({children, textToCopy}: {children: React.ReactNode; textToCopy: string}) => {
+ const {styles, colors} = useStyles()
+ const [, copy] = useCopy()
+
+ return (
+
+ {children}
+
+ copy(textToCopy)} activeOpacity={0.5}>
+
+
+
+ )
+}
+
+const useStyles = () => {
+ const {atoms, color} = useTheme()
+ const styles = StyleSheet.create({
+ text: {
+ ...atoms.flex_row,
+ ...atoms.justify_between,
+ },
+ })
+
+ const colors = {
+ copy: color.gray_900,
+ }
+
+ return {styles, colors} as const
+}
diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/ReviewTxProvider.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/ReviewTxProvider.tsx
new file mode 100644
index 0000000000..05dd6ec924
--- /dev/null
+++ b/apps/wallet-mobile/src/features/ReviewTx/common/ReviewTxProvider.tsx
@@ -0,0 +1,141 @@
+import {castDraft, produce} from 'immer'
+import _ from 'lodash'
+import React from 'react'
+
+import {YoroiSignedTx, YoroiUnsignedTx} from '../../../yoroi-wallets/types/yoroi'
+
+export const useReviewTx = () => React.useContext(ReviewTxContext)
+
+export const ReviewTxProvider = ({
+ children,
+ initialState,
+}: {
+ children: React.ReactNode
+ initialState?: Partial
+}) => {
+ const [state, dispatch] = React.useReducer(reviewTxReducer, {
+ ...defaultState,
+ ...initialState,
+ })
+
+ const actions = React.useRef({
+ unsignedTxChanged: (unsignedTx: ReviewTxState['unsignedTx']) =>
+ dispatch({type: ReviewTxActionType.UnsignedTxChanged, unsignedTx}),
+ cborChanged: (cbor: ReviewTxState['cbor']) => dispatch({type: ReviewTxActionType.CborChanged, cbor}),
+ operationsChanged: (operations: ReviewTxState['operations']) =>
+ dispatch({type: ReviewTxActionType.OperationsChanged, operations}),
+ onSuccessChanged: (onSuccess: ReviewTxState['onSuccess']) =>
+ dispatch({type: ReviewTxActionType.OnSuccessChanged, onSuccess}),
+ onErrorChanged: (onError: ReviewTxState['onError']) => dispatch({type: ReviewTxActionType.OnErrorChanged, onError}),
+ }).current
+
+ const context = React.useMemo(
+ () => ({
+ ...state,
+ ...actions,
+ }),
+ [state, actions],
+ )
+
+ return {children}
+}
+
+const reviewTxReducer = (state: ReviewTxState, action: ReviewTxAction) => {
+ return produce(state, (draft) => {
+ switch (action.type) {
+ case ReviewTxActionType.UnsignedTxChanged:
+ draft.unsignedTx = castDraft(action.unsignedTx)
+ break
+
+ case ReviewTxActionType.CborChanged:
+ draft.cbor = action.cbor
+ break
+
+ case ReviewTxActionType.OperationsChanged:
+ draft.operations = action.operations
+ break
+
+ case ReviewTxActionType.OnSuccessChanged:
+ draft.onSuccess = action.onSuccess
+ break
+
+ case ReviewTxActionType.OnErrorChanged:
+ draft.onError = action.onError
+ break
+
+ default:
+ throw new Error('[ReviewTxContext] invalid action')
+ }
+ })
+}
+
+type ReviewTxAction =
+ | {
+ type: ReviewTxActionType.UnsignedTxChanged
+ unsignedTx: ReviewTxState['unsignedTx']
+ }
+ | {
+ type: ReviewTxActionType.CborChanged
+ cbor: ReviewTxState['cbor']
+ }
+ | {
+ type: ReviewTxActionType.OperationsChanged
+ operations: ReviewTxState['operations']
+ }
+ | {
+ type: ReviewTxActionType.OnSuccessChanged
+ onSuccess: ReviewTxState['onSuccess']
+ }
+ | {
+ type: ReviewTxActionType.OnErrorChanged
+ onError: ReviewTxState['onError']
+ }
+
+export type ReviewTxState = {
+ unsignedTx: YoroiUnsignedTx | null
+ cbor: string | null
+ operations: Array | null
+ onSuccess: ((signedTx: YoroiSignedTx) => void) | null
+ onError: (() => void) | null
+}
+
+type ReviewTxActions = {
+ unsignedTxChanged: (unsignedTx: ReviewTxState['unsignedTx']) => void
+ cborChanged: (cbor: ReviewTxState['cbor']) => void
+ operationsChanged: (operations: ReviewTxState['operations']) => void
+ onSuccessChanged: (onSuccess: ReviewTxState['onSuccess']) => void
+ onErrorChanged: (onError: ReviewTxState['onError']) => void
+}
+
+const defaultState: ReviewTxState = Object.freeze({
+ unsignedTx: null,
+ cbor: null,
+ operations: null,
+ onSuccess: null,
+ onError: null,
+})
+
+function missingInit() {
+ console.error('[ReviewTxContext] missing initialization')
+}
+
+const initialReviewTxContext: ReviewTxContext = {
+ ...defaultState,
+ unsignedTxChanged: missingInit,
+ cborChanged: missingInit,
+ operationsChanged: missingInit,
+ onSuccessChanged: missingInit,
+ onErrorChanged: missingInit,
+}
+
+enum ReviewTxActionType {
+ UnsignedTxChanged = 'unsignedTxChanged',
+ CborChanged = 'cborChanged',
+ OperationsChanged = 'operationsChanged',
+ OnSuccessChanged = 'onSuccessChanged',
+ OnErrorChanged = 'onErrorChanged',
+}
+
+type ReviewTxContext = ReviewTxState & ReviewTxActions
+
+const ReviewTxContext = React.createContext(initialReviewTxContext)
diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/TokenDetails.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/TokenDetails.tsx
new file mode 100644
index 0000000000..6f590decfa
--- /dev/null
+++ b/apps/wallet-mobile/src/features/ReviewTx/common/TokenDetails.tsx
@@ -0,0 +1,396 @@
+import {usePortfolioTokenDiscovery} from '@yoroi/portfolio'
+import {useTheme} from '@yoroi/theme'
+import {Portfolio} from '@yoroi/types'
+import * as React from 'react'
+import {Linking, ScrollView, StyleSheet, Text, TouchableOpacity, View} from 'react-native'
+
+import {Icon} from '../../../components/Icon'
+import {MediaPreview} from '../../../components/MediaPreview/MediaPreview'
+import {SimpleTab} from '../../../components/SimpleTab/SimpleTab'
+import {Space} from '../../../components/Space/Space'
+import {useCopy} from '../../../hooks/useCopy'
+import {time} from '../../../kernel/constants'
+import {isEmptyString} from '../../../kernel/utils'
+import {useSelectedWallet} from '../../WalletManager/common/hooks/useSelectedWallet'
+import {CopiableText} from './CopiableText'
+import {useStrings} from './hooks/useStrings'
+
+export const TokenDetails = ({tokenInfo}: {tokenInfo: Portfolio.Token.Info}) => {
+ const {styles} = useStyles()
+
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+const Header = ({info}: {info: Portfolio.Token.Info}) => {
+ const {styles} = useStyles()
+ const [policyId, assetName] = info.id.split('.')
+
+ const title = !isEmptyString(info.ticker) ? info.ticker : !isEmptyString(info.name) ? info.name : ''
+
+ return (
+
+
+
+
+
+ {!isEmptyString(title) && {title}}
+
+ {`(${assetName})`}
+
+
+
+
+
+
+
+
+
+ )
+}
+
+const Info = ({info}: {info: Portfolio.Token.Info}) => {
+ const {styles} = useStyles()
+ const strings = useStrings()
+ const {wallet} = useSelectedWallet()
+ const [activeTab, setActiveTab] = React.useState<'overview' | 'json'>('overview')
+
+ const {tokenDiscovery} = usePortfolioTokenDiscovery(
+ {
+ id: info.id,
+ network: wallet.networkManager.network,
+ getTokenDiscovery: wallet.networkManager.tokenManager.api.tokenDiscovery,
+ },
+ {
+ staleTime: time.session,
+ },
+ )
+
+ return (
+
+
+ setActiveTab('overview')}
+ isActive={activeTab === 'overview'}
+ />
+
+ setActiveTab('json')} isActive={activeTab === 'json'} />
+
+
+
+
+ {/* ↓↓↓ TABS CONTENT ↓↓↓ */}
+
+
+
+
+
+ )
+}
+
+const Json = ({discovery, isActive}: {discovery?: Portfolio.Token.Discovery; isActive: boolean}) => {
+ const {styles, colors} = useStyles()
+ const strings = useStrings()
+ const [, copy] = useCopy()
+
+ if (!isActive || !discovery) return null
+
+ const stringifiedMetadata = JSON.stringify(discovery.originalMetadata, null, 2)
+
+ return (
+
+
+ {strings.metadata}
+
+ copy(stringifiedMetadata)} activeOpacity={0.5}>
+
+
+
+
+
+
+
+ {stringifiedMetadata}
+
+
+ )
+}
+
+const Overview = ({
+ info,
+ discovery,
+ isActive,
+}: {
+ info: Portfolio.Token.Info
+ discovery?: Portfolio.Token.Discovery
+ isActive: boolean
+}) => {
+ if (!isActive) return null
+
+ if (info.type === 'ft') {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ )
+ }
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+const PolicyId = ({policyId}: {policyId: string}) => {
+ const {styles} = useStyles()
+ const strings = useStrings()
+
+ if (isEmptyString(policyId)) return null
+
+ return (
+
+ {strings.policyId}
+
+
+
+
+
+ {policyId}
+
+
+
+ )
+}
+
+const Fingerprint = ({info}: {info: Portfolio.Token.Info}) => {
+ const {styles} = useStyles()
+ const strings = useStrings()
+
+ if (isEmptyString(info.fingerprint)) return null
+
+ return (
+
+ {strings.fingerprint}
+
+
+
+
+
+ {info.fingerprint}
+
+
+
+ )
+}
+
+const Name = ({info}: {info: Portfolio.Token.Info}) => {
+ const {styles} = useStyles()
+ const strings = useStrings()
+
+ if (isEmptyString(info.name)) return null
+
+ return (
+
+ {strings.name}
+
+ {info.name}
+
+ )
+}
+
+const TokenSupply = ({discovery}: {discovery?: Portfolio.Token.Discovery}) => {
+ const {styles} = useStyles()
+ const strings = useStrings()
+
+ if (!discovery || isEmptyString(discovery.supply)) return null
+
+ return (
+
+
+
+
+ {strings.tokenSupply}
+
+ {discovery.supply}
+
+
+ )
+}
+
+const Symbol = ({info}: {info: Portfolio.Token.Info}) => {
+ const {styles} = useStyles()
+ const strings = useStrings()
+
+ if (isEmptyString(info.ticker)) return null
+
+ return (
+
+
+
+
+ {strings.symbol}
+
+ {info.ticker}
+
+
+ )
+}
+
+const Description = ({info}: {info: Portfolio.Token.Info}) => {
+ const {styles} = useStyles()
+ const strings = useStrings()
+
+ if (isEmptyString(info.description)) return null
+
+ return (
+
+
+
+ {strings.description}
+
+ {info.description}
+
+ )
+}
+
+const Links = ({info}: {info: Portfolio.Token.Info}) => {
+ const {styles} = useStyles()
+ const {wallet} = useSelectedWallet()
+ const strings = useStrings()
+
+ const handleOpenLink = async (direction: 'cardanoscan' | 'adaex') => {
+ if (info == null) return
+ if (direction === 'cardanoscan') {
+ await Linking.openURL(wallet.networkManager.explorers.cardanoscan.token(info.id))
+ } else {
+ await Linking.openURL(wallet.networkManager.explorers.cexplorer.token(info.id))
+ }
+ }
+
+ return (
+
+
+
+ {strings.details}
+
+
+ handleOpenLink('cardanoscan')}>
+ Cardanoscan
+
+
+ handleOpenLink('adaex')}>
+ Adaex
+
+
+
+ )
+}
+
+const Row = ({children}: {children: React.ReactNode}) => {
+ const {styles} = useStyles()
+ return {children}
+}
+
+const useStyles = () => {
+ const {atoms, color} = useTheme()
+
+ const styles = StyleSheet.create({
+ root: {
+ ...atoms.flex_1,
+ ...atoms.px_lg,
+ },
+ header: {
+ ...atoms.align_center,
+ },
+ headerText: {
+ ...atoms.body_1_lg_medium,
+ ...atoms.text_center,
+ color: color.text_gray_medium,
+ maxWidth: 300,
+ },
+ row: {
+ ...atoms.flex_row,
+ ...atoms.justify_between,
+ },
+ label: {
+ ...atoms.body_2_md_regular,
+ color: color.text_gray_low,
+ },
+ value: {
+ ...atoms.flex_1,
+ ...atoms.text_right,
+ ...atoms.body_2_md_regular,
+ color: color.text_gray_max,
+ },
+ description: {
+ ...atoms.body_2_md_regular,
+ color: color.text_gray_max,
+ },
+ tabs: {
+ ...atoms.flex_row,
+ },
+ link: {
+ ...atoms.link_1_lg_underline,
+ color: color.text_primary_medium,
+ },
+ linkGroup: {
+ ...atoms.flex_row,
+ ...atoms.gap_lg,
+ },
+ copiableText: {
+ ...atoms.flex_1,
+ ...atoms.align_center,
+ },
+ json: {
+ ...atoms.flex_1,
+ ...atoms.pt_lg,
+ borderRadius: 8,
+ backgroundColor: color.bg_color_min,
+ },
+ jsonHeader: {
+ ...atoms.px_lg,
+ ...atoms.flex_row,
+ ...atoms.justify_between,
+ },
+ jsonLabel: {
+ ...atoms.body_1_lg_medium,
+ color: color.text_gray_medium,
+ },
+ jsonContent: {
+ ...atoms.px_lg,
+ },
+ info: {
+ ...atoms.flex_1,
+ },
+ metadata: {
+ ...atoms.body_2_md_regular,
+ color: color.text_gray_medium,
+ },
+ })
+
+ const colors = {
+ copy: color.gray_900,
+ }
+
+ return {styles, colors} as const
+}
diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/TokenItem.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/TokenItem.tsx
index 751a3bbd56..fabea93b81 100644
--- a/apps/wallet-mobile/src/features/ReviewTx/common/TokenItem.tsx
+++ b/apps/wallet-mobile/src/features/ReviewTx/common/TokenItem.tsx
@@ -1,31 +1,55 @@
import {useTheme} from '@yoroi/theme'
+import {Portfolio} from '@yoroi/types'
import * as React from 'react'
-import {StyleSheet, Text, View} from 'react-native'
+import {StyleSheet, Text, TouchableOpacity, useWindowDimensions} from 'react-native'
+
+import {useModal} from '../../../components/Modal/ModalContext'
+import {useStrings} from './hooks/useStrings'
+import {TokenDetails} from './TokenDetails'
export const TokenItem = ({
+ tokenInfo,
isPrimaryToken = true,
isSent = true,
label,
}: {
+ tokenInfo: Portfolio.Token.Info
isPrimaryToken?: boolean
isSent?: boolean
label: string
}) => {
const {styles} = useStyles()
+ const strings = useStrings()
+ const {openModal} = useModal()
+ const {height: windowHeight} = useWindowDimensions()
+
+ const handleShowTokenDetails = () => {
+ openModal(strings.tokenDetailsTitle, , windowHeight * 0.8)
+ }
if (!isSent)
return (
-
+
{label}
-
+
)
return (
-
+
{label}
-
+
)
}
diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useFormattedTx.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useFormattedTx.tsx
index 08a8d1ebfe..7949d9541d 100644
--- a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useFormattedTx.tsx
+++ b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useFormattedTx.tsx
@@ -1,7 +1,7 @@
import {invalid, isNonNullable} from '@yoroi/common'
import {infoExtractName} from '@yoroi/portfolio'
import {Portfolio} from '@yoroi/types'
-import * as _ from 'lodash'
+import _ from 'lodash'
import {useQuery} from 'react-query'
import {YoroiWallet} from '../../../../yoroi-wallets/cardano/types'
@@ -19,7 +19,6 @@ import {
TransactionOutputs,
} from '../types'
-export type FormattedTx = ReturnType
export const useFormattedTx = (data: TransactionBody) => {
const {wallet} = useSelectedWallet()
@@ -102,6 +101,7 @@ const formatInputs = async (
coin != null
? [
{
+ tokenInfo: wallet.portfolioPrimaryTokenInfo,
name: wallet.portfolioPrimaryTokenInfo.name,
label: formatTokenWithText(coin, wallet.portfolioPrimaryTokenInfo),
quantity: coin,
@@ -118,6 +118,7 @@ const formatInputs = async (
const quantity = asQuantity(a.amount)
return {
+ tokenInfo,
name: infoExtractName(tokenInfo),
label: formatTokenWithText(quantity, tokenInfo),
quantity: quantity,
@@ -151,6 +152,7 @@ const formatOutputs = async (
const primaryAssets = [
{
+ tokenInfo: wallet.portfolioPrimaryTokenInfo,
name: wallet.portfolioPrimaryTokenInfo.name,
label: formatTokenWithText(coin, wallet.portfolioPrimaryTokenInfo),
quantity: coin,
@@ -166,6 +168,7 @@ const formatOutputs = async (
const quantity = asQuantity(amount)
return {
+ tokenInfo,
name: infoExtractName(tokenInfo),
label: formatTokenWithText(quantity, tokenInfo),
quantity,
@@ -191,6 +194,7 @@ export const formatFee = (wallet: YoroiWallet, data: TransactionBody): Formatted
const fee = asQuantity(data?.fee ?? '0')
return {
+ tokenInfo: wallet.portfolioPrimaryTokenInfo,
name: wallet.portfolioPrimaryTokenInfo.name,
label: formatTokenWithText(fee, wallet.portfolioPrimaryTokenInfo),
quantity: fee,
diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useOnConfirm.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useOnConfirm.tsx
index dfb076eab5..38188b6e93 100644
--- a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useOnConfirm.tsx
+++ b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useOnConfirm.tsx
@@ -15,8 +15,8 @@ export const useOnConfirm = ({
onError,
onNotSupportedCIP1694,
}: {
- onSuccess: (txId: YoroiSignedTx) => void
- onError: () => void
+ onSuccess?: ((txId: YoroiSignedTx) => void) | null
+ onError?: (() => void) | null
cbor?: string
unsignedTx?: YoroiUnsignedTx
onNotSupportedCIP1694?: () => void
@@ -34,7 +34,7 @@ export const useOnConfirm = ({
onSuccess(signedTx)}
+ onSuccess={(signedTx) => onSuccess?.(signedTx)}
onNotSupportedCIP1694={onNotSupportedCIP1694}
/>,
400,
@@ -47,8 +47,8 @@ export const useOnConfirm = ({
strings.signTransaction,
onSuccess(signedTx)}
- onError={onError}
+ onSuccess={(signedTx) => onSuccess?.(signedTx)}
+ onError={onError ?? undefined}
/>,
)
return
@@ -59,13 +59,13 @@ export const useOnConfirm = ({
strings.signTransaction,
onSuccess(signedTx)}
- onError={onError}
+ onSuccess={(signedTx) => onSuccess?.(signedTx)}
+ onError={onError ?? undefined}
/>,
)
return
}
}
- return {onConfirm}
+ return {onConfirm} as const
}
diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useStrings.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useStrings.tsx
index 54d8581849..9914016ec2 100644
--- a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useStrings.tsx
+++ b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useStrings.tsx
@@ -21,6 +21,17 @@ export const useStrings = () => {
utxosOutputsLabel: intl.formatMessage(messages.utxosOutputsLabel),
utxosYourAddressLabel: intl.formatMessage(messages.utxosYourAddressLabel),
utxosForeignAddressLabel: intl.formatMessage(messages.utxosForeignAddressLabel),
+ overview: intl.formatMessage(messages.overview),
+ json: intl.formatMessage(messages.json),
+ metadata: intl.formatMessage(messages.metadata),
+ policyId: intl.formatMessage(messages.policyId),
+ fingerprint: intl.formatMessage(messages.fingerprint),
+ name: intl.formatMessage(messages.name),
+ tokenSupply: intl.formatMessage(messages.tokenSupply),
+ symbol: intl.formatMessage(messages.symbol),
+ description: intl.formatMessage(messages.description),
+ details: intl.formatMessage(messages.details),
+ tokenDetailsTitle: intl.formatMessage(messages.tokenDetailsTitle),
}
}
@@ -59,7 +70,7 @@ const messages = defineMessages({
},
receiveToLabel: {
id: 'txReview.overview.receiveToLabel',
- defaultMessage: '!!!receiveToLabel',
+ defaultMessage: '!!!To',
},
receiveToScriptLabel: {
id: 'txReview.overview.receiveToScriptLabel',
@@ -81,4 +92,48 @@ const messages = defineMessages({
id: 'txReview.utxos.utxosForeignAddressLabel',
defaultMessage: '!!!Foreign address',
},
+ overview: {
+ id: 'txReview.tokenDetails.overViewTab.title',
+ defaultMessage: '!!!Overview',
+ },
+ json: {
+ id: 'txReview.tokenDetails.jsonTab.title',
+ defaultMessage: '!!!JSON',
+ },
+ metadata: {
+ id: 'txReview.tokenDetails.jsonTab.metadata',
+ defaultMessage: '!!!Metadata',
+ },
+ policyId: {
+ id: 'txReview.tokenDetails.policyId.label',
+ defaultMessage: '!!!Policy ID',
+ },
+ fingerprint: {
+ id: 'txReview.tokenDetails.fingerprint.label',
+ defaultMessage: '!!!Fingerprint',
+ },
+ name: {
+ id: 'txReview.tokenDetails.overViewTab.name.label',
+ defaultMessage: '!!!Name',
+ },
+ tokenSupply: {
+ id: 'txReview.tokenDetails.overViewTab.tokenSupply.label',
+ defaultMessage: '!!!Token Supply',
+ },
+ symbol: {
+ id: 'txReview.tokenDetails.overViewTab.symbol.label',
+ defaultMessage: '!!!Symbol',
+ },
+ description: {
+ id: 'txReview.tokenDetails.overViewTab.description.label',
+ defaultMessage: '!!!Description',
+ },
+ details: {
+ id: 'txReview.tokenDetails.overViewTab.details.label',
+ defaultMessage: '!!!Details on',
+ },
+ tokenDetailsTitle: {
+ id: 'txReview.tokenDetails.title',
+ defaultMessage: '!!!Asset Details',
+ },
})
diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/types.ts b/apps/wallet-mobile/src/features/ReviewTx/common/types.ts
index 935f333b56..45744a4cf6 100644
--- a/apps/wallet-mobile/src/features/ReviewTx/common/types.ts
+++ b/apps/wallet-mobile/src/features/ReviewTx/common/types.ts
@@ -1,863 +1,17 @@
-import {Balance} from '@yoroi/types'
+import {
+ TransactionBodyJSON,
+ TransactionInputsJSON,
+ TransactionOutputsJSON,
+} from '@emurgo/cardano-serialization-lib-nodejs'
+import {Balance, Portfolio} from '@yoroi/types'
-export type TransactionDetails = {
- id: string
- walletPlate: React.ReactNode
- walletName: string
- createdBy: string | null
- fee: string
- txBody: TransactionBody
-}
-
-export type Address = string
-export type URL = string
-
-export interface Anchor {
- anchor_data_hash: string
- anchor_url: URL
-}
-export type AnchorDataHash = string
-export type AssetName = string
-export type AssetNames = string[]
-export interface Assets {
- [k: string]: string
-}
-export type NativeScript =
- | {
- ScriptPubkey: ScriptPubkey
- }
- | {
- ScriptAll: ScriptAll
- }
- | {
- ScriptAny: ScriptAny
- }
- | {
- ScriptNOfK: ScriptNOfK
- }
- | {
- TimelockStart: TimelockStart
- }
- | {
- TimelockExpiry: TimelockExpiry
- }
-export type NativeScripts = NativeScript[]
-export type PlutusScripts = string[]
-
-export interface AuxiliaryData {
- metadata?: {
- [k: string]: string
- } | null
- native_scripts?: NativeScripts | null
- plutus_scripts?: PlutusScripts | null
- prefer_alonzo_format: boolean
-}
-export interface ScriptPubkey {
- addr_keyhash: string
-}
-export interface ScriptAll {
- native_scripts: NativeScripts
-}
-export interface ScriptAny {
- native_scripts: NativeScripts
-}
-export interface ScriptNOfK {
- n: number
- native_scripts: NativeScripts
-}
-export interface TimelockStart {
- slot: string
-}
-export interface TimelockExpiry {
- slot: string
-}
-export type AuxiliaryDataHash = string
-export interface AuxiliaryDataSet {
- [k: string]: AuxiliaryData
-}
-export type BigInt = string
-export type BigNum = string
-export type Vkey = string
-export type HeaderLeaderCertEnum =
- | {
- /**
- * @minItems 2
- * @maxItems 2
- */
- NonceAndLeader: [VRFCert, VRFCert]
- }
- | {
- VrfResult: VRFCert
- }
-export type Certificate =
- | {
- StakeRegistration: StakeRegistration
- }
- | {
- StakeDeregistration: StakeDeregistration
- }
- | {
- StakeDelegation: StakeDelegation
- }
- | {
- PoolRegistration: PoolRegistration
- }
- | {
- PoolRetirement: PoolRetirement
- }
- | {
- GenesisKeyDelegation: GenesisKeyDelegation
- }
- | {
- MoveInstantaneousRewardsCert: MoveInstantaneousRewardsCert
- }
- | {
- CommitteeHotAuth: CommitteeHotAuth
- }
- | {
- CommitteeColdResign: CommitteeColdResign
- }
- | {
- DRepDeregistration: DRepDeregistration
- }
- | {
- DRepRegistration: DRepRegistration
- }
- | {
- DRepUpdate: DRepUpdate
- }
- | {
- StakeAndVoteDelegation: StakeAndVoteDelegation
- }
- | {
- StakeRegistrationAndDelegation: StakeRegistrationAndDelegation
- }
- | {
- StakeVoteRegistrationAndDelegation: StakeVoteRegistrationAndDelegation
- }
- | {
- VoteDelegation: VoteDelegation
- }
- | {
- VoteRegistrationAndDelegation: VoteRegistrationAndDelegation
- }
-export type CredType =
- | {
- Key: string
- }
- | {
- Script: string
- }
-export type Relay =
- | {
- SingleHostAddr: SingleHostAddr
- }
- | {
- SingleHostName: SingleHostName
- }
- | {
- MultiHostName: MultiHostName
- }
-/**
- * @minItems 4
- * @maxItems 4
- */
-export type Ipv4 = [number, number, number, number]
-/**
- * @minItems 16
- * @maxItems 16
- */
-export type Ipv6 = [
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
-]
-export type DNSRecordAorAAAA = string
-export type DNSRecordSRV = string
-export type Relays = Relay[]
-export type MIRPot = 'Reserves' | 'Treasury'
-export type MIREnum =
- | {
- ToOtherPot: string
- }
- | {
- ToStakeCredentials: StakeToCoin[]
- }
-export type DRep =
- | ('AlwaysAbstain' | 'AlwaysNoConfidence')
- | {
- KeyHash: string
- }
- | {
- ScriptHash: string
- }
-export type DataOption =
- | {
- DataHash: string
- }
- | {
- Data: string
- }
-export type ScriptRef =
- | {
- NativeScript: NativeScript
- }
- | {
- PlutusScript: string
- }
-export type Mint = [string, MintAssets][]
-export type NetworkId = 'Testnet' | 'Mainnet'
-export type TransactionOutputs = TransactionOutput[]
-export type CostModel = string[]
-export type Voter =
- | {
- ConstitutionalCommitteeHotCred: CredType
- }
- | {
- DRep: CredType
- }
- | {
- StakingPool: string
- }
-export type VoteKind = 'No' | 'Yes' | 'Abstain'
-export type GovernanceAction =
- | {
- ParameterChangeAction: ParameterChangeAction
- }
- | {
- HardForkInitiationAction: HardForkInitiationAction
- }
- | {
- TreasuryWithdrawalsAction: TreasuryWithdrawalsAction
- }
- | {
- NoConfidenceAction: NoConfidenceAction
- }
- | {
- UpdateCommitteeAction: UpdateCommitteeAction
- }
- | {
- NewConstitutionAction: NewConstitutionAction
- }
- | {
- InfoAction: InfoAction
- }
-/**
- * @minItems 0
- * @maxItems 0
- */
-export type InfoAction = []
-export type TransactionBodies = TransactionBody[]
-export type RedeemerTag = 'Spend' | 'Mint' | 'Cert' | 'Reward' | 'Vote' | 'VotingProposal'
-export type TransactionWitnessSets = TransactionWitnessSet[]
-
-export interface Block {
- auxiliary_data_set: {
- [k: string]: AuxiliaryData
- }
- header: Header
- invalid_transactions: number[]
- transaction_bodies: TransactionBodies
- transaction_witness_sets: TransactionWitnessSets
-}
-export interface Header {
- body_signature: string
- header_body: HeaderBody
-}
-export interface HeaderBody {
- block_body_hash: string
- block_body_size: number
- block_number: number
- issuer_vkey: Vkey
- leader_cert: HeaderLeaderCertEnum
- operational_cert: OperationalCert
- prev_hash?: string | null
- protocol_version: ProtocolVersion
- slot: string
- vrf_vkey: string
-}
-export interface VRFCert {
- output: number[]
- proof: number[]
-}
-export interface OperationalCert {
- hot_vkey: string
- kes_period: number
- sequence_number: number
- sigma: string
-}
-export interface ProtocolVersion {
- major: number
- minor: number
-}
-export interface TransactionBody {
- auxiliary_data_hash?: string | null
- certs?: Certificate[] | null
- collateral?: TransactionInput[] | null
- collateral_return?: TransactionOutput | null
- current_treasury_value?: string | null
- donation?: string | null
- fee: string
- inputs: TransactionInput[]
- mint?: Mint | null
- network_id?: NetworkId | null
- outputs: TransactionOutputs
- reference_inputs?: TransactionInput[] | null
- required_signers?: string[] | null
- script_data_hash?: string | null
- total_collateral?: string | null
- ttl?: string | null
- update?: Update | null
- validity_start_interval?: string | null
- voting_procedures?: VoterVotes[] | null
- voting_proposals?: VotingProposal[] | null
- withdrawals?: {
- [k: string]: string
- } | null
-}
-export interface StakeRegistration {
- coin?: string | null
- stake_credential: CredType
-}
-export interface StakeDeregistration {
- coin?: string | null
- stake_credential: CredType
-}
-export interface StakeDelegation {
- pool_keyhash: string
- stake_credential: CredType
-}
-export interface PoolRegistration {
- pool_params: PoolParams
-}
-export interface PoolParams {
- cost: string
- margin: UnitInterval
- operator: string
- pledge: string
- pool_metadata?: PoolMetadata | null
- pool_owners: string[]
- relays: Relays
- reward_account: string
- vrf_keyhash: string
-}
-export interface UnitInterval {
- denominator: string
- numerator: string
-}
-export interface PoolMetadata {
- pool_metadata_hash: string
- url: URL
-}
-export interface SingleHostAddr {
- ipv4?: Ipv4 | null
- ipv6?: Ipv6 | null
- port?: number | null
-}
-export interface SingleHostName {
- dns_name: DNSRecordAorAAAA
- port?: number | null
-}
-export interface MultiHostName {
- dns_name: DNSRecordSRV
-}
-export interface PoolRetirement {
- epoch: number
- pool_keyhash: string
-}
-export interface GenesisKeyDelegation {
- genesis_delegate_hash: string
- genesishash: string
- vrf_keyhash: string
-}
-export interface MoveInstantaneousRewardsCert {
- move_instantaneous_reward: MoveInstantaneousReward
-}
-export interface MoveInstantaneousReward {
- pot: MIRPot
- variant: MIREnum
-}
-export interface StakeToCoin {
- amount: string
- stake_cred: CredType
-}
-export interface CommitteeHotAuth {
- committee_cold_credential: CredType
- committee_hot_credential: CredType
-}
-export interface CommitteeColdResign {
- anchor?: Anchor | null
- committee_cold_credential: CredType
-}
-export interface DRepDeregistration {
- coin: string
- voting_credential: CredType
-}
-export interface DRepRegistration {
- anchor?: Anchor | null
- coin: string
- voting_credential: CredType
-}
-export interface DRepUpdate {
- anchor?: Anchor | null
- voting_credential: CredType
-}
-export interface StakeAndVoteDelegation {
- drep: DRep
- pool_keyhash: string
- stake_credential: CredType
-}
-export interface StakeRegistrationAndDelegation {
- coin: string
- pool_keyhash: string
- stake_credential: CredType
-}
-export interface StakeVoteRegistrationAndDelegation {
- coin: string
- drep: DRep
- pool_keyhash: string
- stake_credential: CredType
-}
-export interface VoteDelegation {
- drep: DRep
- stake_credential: CredType
-}
-export interface VoteRegistrationAndDelegation {
- coin: string
- drep: DRep
- stake_credential: CredType
-}
-export interface TransactionInput {
- index: number
- transaction_id: string
-}
-export interface TransactionOutput {
- address: string
- amount: Value
- plutus_data?: DataOption | null
- script_ref?: ScriptRef | null
-}
-export interface Value {
- coin: string
- multiasset?: MultiAsset | null
-}
-export interface MultiAsset {
- [k: string]: Assets
-}
-export interface MintAssets {
- [k: string]: string
-}
-export interface Update {
- epoch: number
- proposed_protocol_parameter_updates: {
- [k: string]: ProtocolParamUpdate
- }
-}
-export interface ProtocolParamUpdate {
- ada_per_utxo_byte?: string | null
- collateral_percentage?: number | null
- committee_term_limit?: number | null
- cost_models?: Costmdls | null
- d?: UnitInterval | null
- drep_deposit?: string | null
- drep_inactivity_period?: number | null
- drep_voting_thresholds?: DRepVotingThresholds | null
- execution_costs?: ExUnitPrices | null
- expansion_rate?: UnitInterval | null
- extra_entropy?: Nonce | null
- governance_action_deposit?: string | null
- governance_action_validity_period?: number | null
- key_deposit?: string | null
- max_block_body_size?: number | null
- max_block_ex_units?: ExUnits | null
- max_block_header_size?: number | null
- max_collateral_inputs?: number | null
- max_epoch?: number | null
- max_tx_ex_units?: ExUnits | null
- max_tx_size?: number | null
- max_value_size?: number | null
- min_committee_size?: number | null
- min_pool_cost?: string | null
- minfee_a?: string | null
- minfee_b?: string | null
- n_opt?: number | null
- pool_deposit?: string | null
- pool_pledge_influence?: UnitInterval | null
- pool_voting_thresholds?: PoolVotingThresholds | null
- protocol_version?: ProtocolVersion | null
- ref_script_coins_per_byte?: UnitInterval | null
- treasury_growth_rate?: UnitInterval | null
-}
-export interface Costmdls {
- [k: string]: CostModel
-}
-export interface DRepVotingThresholds {
- committee_no_confidence: UnitInterval
- committee_normal: UnitInterval
- hard_fork_initiation: UnitInterval
- motion_no_confidence: UnitInterval
- pp_economic_group: UnitInterval
- pp_governance_group: UnitInterval
- pp_network_group: UnitInterval
- pp_technical_group: UnitInterval
- treasury_withdrawal: UnitInterval
- update_constitution: UnitInterval
-}
-export interface ExUnitPrices {
- mem_price: UnitInterval
- step_price: UnitInterval
-}
-export interface Nonce {
- /**
- * @minItems 32
- * @maxItems 32
- */
- hash?:
- | [
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- number,
- ]
- | null
-}
-export interface ExUnits {
- mem: string
- steps: string
-}
-export interface PoolVotingThresholds {
- committee_no_confidence: UnitInterval
- committee_normal: UnitInterval
- hard_fork_initiation: UnitInterval
- motion_no_confidence: UnitInterval
- security_relevant_threshold: UnitInterval
-}
-export interface VoterVotes {
- voter: Voter
- votes: Vote[]
-}
-export interface Vote {
- action_id: GovernanceActionId
- voting_procedure: VotingProcedure
-}
-export interface GovernanceActionId {
- index: number
- transaction_id: string
-}
-export interface VotingProcedure {
- anchor?: Anchor | null
- vote: VoteKind
-}
-export interface VotingProposal {
- anchor: Anchor
- deposit: string
- governance_action: GovernanceAction
- reward_account: string
-}
-export interface ParameterChangeAction {
- gov_action_id?: GovernanceActionId | null
- policy_hash?: string | null
- protocol_param_updates: ProtocolParamUpdate
-}
-export interface HardForkInitiationAction {
- gov_action_id?: GovernanceActionId | null
- protocol_version: ProtocolVersion
-}
-export interface TreasuryWithdrawalsAction {
- policy_hash?: string | null
- withdrawals: TreasuryWithdrawals
-}
-export interface TreasuryWithdrawals {
- [k: string]: string
-}
-export interface NoConfidenceAction {
- gov_action_id?: GovernanceActionId | null
-}
-export interface UpdateCommitteeAction {
- committee: Committee
- gov_action_id?: GovernanceActionId | null
- members_to_remove: CredType[]
-}
-export interface Committee {
- members: CommitteeMember[]
- quorum_threshold: UnitInterval
-}
-export interface CommitteeMember {
- stake_credential: CredType
- term_limit: number
-}
-export interface NewConstitutionAction {
- constitution: Constitution
- gov_action_id?: GovernanceActionId | null
-}
-export interface Constitution {
- anchor: Anchor
- script_hash?: string | null
-}
-export interface TransactionWitnessSet {
- bootstraps?: BootstrapWitness[] | null
- native_scripts?: NativeScripts | null
- plutus_data?: PlutusList | null
- plutus_scripts?: PlutusScripts | null
- redeemers?: Redeemer[] | null
- vkeys?: Vkeywitness[] | null
-}
-export interface BootstrapWitness {
- attributes: number[]
- chain_code: number[]
- signature: string
- vkey: Vkey
-}
-export interface PlutusList {
- definite_encoding?: boolean | null
- elems: string[]
-}
-export interface Redeemer {
- data: string
- ex_units: ExUnits
- index: string
- tag: RedeemerTag
-}
-export interface Vkeywitness {
- signature: string
- vkey: Vkey
-}
-export type BlockHash = string
-export type BootstrapWitnesses = BootstrapWitness[]
-
-export type CertificateEnum =
- | {
- StakeRegistration: StakeRegistration
- }
- | {
- StakeDeregistration: StakeDeregistration
- }
- | {
- StakeDelegation: StakeDelegation
- }
- | {
- PoolRegistration: PoolRegistration
- }
- | {
- PoolRetirement: PoolRetirement
- }
- | {
- GenesisKeyDelegation: GenesisKeyDelegation
- }
- | {
- MoveInstantaneousRewardsCert: MoveInstantaneousRewardsCert
- }
- | {
- CommitteeHotAuth: CommitteeHotAuth
- }
- | {
- CommitteeColdResign: CommitteeColdResign
- }
- | {
- DRepDeregistration: DRepDeregistration
- }
- | {
- DRepRegistration: DRepRegistration
- }
- | {
- DRepUpdate: DRepUpdate
- }
- | {
- StakeAndVoteDelegation: StakeAndVoteDelegation
- }
- | {
- StakeRegistrationAndDelegation: StakeRegistrationAndDelegation
- }
- | {
- StakeVoteRegistrationAndDelegation: StakeVoteRegistrationAndDelegation
- }
- | {
- VoteDelegation: VoteDelegation
- }
- | {
- VoteRegistrationAndDelegation: VoteRegistrationAndDelegation
- }
-export type Certificates = Certificate[]
-
-export type Credential = CredType
-export type Credentials = CredType[]
-export type DRepEnum =
- | ('AlwaysAbstain' | 'AlwaysNoConfidence')
- | {
- KeyHash: string
- }
- | {
- ScriptHash: string
- }
-export type DataHash = string
-export type Ed25519KeyHash = string
-export type Ed25519KeyHashes = string[]
-export type Ed25519Signature = string
-export interface GeneralTransactionMetadata {
- [k: string]: string
-}
-export type GenesisDelegateHash = string
-export type GenesisHash = string
-export type GenesisHashes = string[]
-export type GovernanceActionEnum =
- | {
- ParameterChangeAction: ParameterChangeAction
- }
- | {
- HardForkInitiationAction: HardForkInitiationAction
- }
- | {
- TreasuryWithdrawalsAction: TreasuryWithdrawalsAction
- }
- | {
- NoConfidenceAction: NoConfidenceAction
- }
- | {
- UpdateCommitteeAction: UpdateCommitteeAction
- }
- | {
- NewConstitutionAction: NewConstitutionAction
- }
- | {
- InfoAction: InfoAction
- }
-export type GovernanceActionIds = GovernanceActionId[]
-
-export type Int = string
-/**
- * @minItems 4
- * @maxItems 4
- */
-export type KESVKey = string
-export type Language = LanguageKind
-export type LanguageKind = 'PlutusV1' | 'PlutusV2' | 'PlutusV3'
-export type Languages = Language[]
-export type MIRToStakeCredentials = StakeToCoin[]
-
-export type MintsAssets = MintAssets[]
-
-export type NetworkIdKind = 'Testnet' | 'Mainnet'
-export type PlutusScript = string
-export type PoolMetadataHash = string
-export interface ProposedProtocolParameterUpdates {
- [k: string]: ProtocolParamUpdate
-}
-export type PublicKey = string
-export type RedeemerTagKind = 'Spend' | 'Mint' | 'Cert' | 'Reward' | 'Vote' | 'VotingProposal'
-export type Redeemers = Redeemer[]
-
-export type RelayEnum =
- | {
- SingleHostAddr: SingleHostAddr
- }
- | {
- SingleHostName: SingleHostName
- }
- | {
- MultiHostName: MultiHostName
- }
-/**
- * @minItems 4
- * @maxItems 4
- */
-export type RewardAddress = string
-export type RewardAddresses = string[]
-export type ScriptDataHash = string
-export type ScriptHash = string
-export type ScriptHashes = string[]
-export type ScriptRefEnum =
- | {
- NativeScript: NativeScript
- }
- | {
- PlutusScript: string
- }
-export interface Transaction {
- auxiliary_data?: AuxiliaryData | null
- body: TransactionBody
- is_valid: boolean
- witness_set: TransactionWitnessSet
-}
-export type TransactionHash = string
-export type TransactionInputs = TransactionInput[]
-
-export type TransactionMetadatum = string
-export interface TransactionUnspentOutput {
- input: TransactionInput
- output: TransactionOutput
-}
-export type TransactionUnspentOutputs = TransactionUnspentOutput[]
-
-export type VRFKeyHash = string
-export type VRFVKey = string
-export interface VersionedBlock {
- block: Block
- era_code: number
-}
-export type Vkeywitnesses = Vkeywitness[]
-
-export type VoterEnum =
- | {
- ConstitutionalCommitteeHotCred: CredType
- }
- | {
- DRep: CredType
- }
- | {
- StakingPool: string
- }
-export type Voters = Voter[]
-export type VotingProcedures = VoterVotes[]
-
-export type VotingProposals = VotingProposal[]
-
-export interface Withdrawals {
- [k: string]: string
-}
+export type TransactionBody = TransactionBodyJSON
+export type TransactionInputs = TransactionInputsJSON
+export type TransactionOutputs = TransactionOutputsJSON
export type FormattedInput = {
assets: Array<{
+ tokenInfo: Portfolio.Token.Info
name: string
label: string
quantity: Balance.Quantity
@@ -871,8 +25,10 @@ export type FormattedInput = {
}
export type FormattedInputs = Array
+
export type FormattedOutput = {
assets: Array<{
+ tokenInfo: Portfolio.Token.Info
name: string
label: string
quantity: Balance.Quantity
@@ -882,10 +38,19 @@ export type FormattedOutput = {
rewardAddress: string | null
ownAddress: boolean
}
+
export type FormattedOutputs = Array
+
export type FormattedFee = {
+ tokenInfo: Portfolio.Token.Info
name: string
label: string
quantity: Balance.Quantity
isPrimary: boolean
}
+
+export type FormattedTx = {
+ inputs: FormattedInputs
+ outputs: FormattedOutputs
+ fee: FormattedFee
+}
diff --git a/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/Overview/OverviewTab.tsx b/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/Overview/OverviewTab.tsx
index eed42fd24a..92278d03ba 100644
--- a/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/Overview/OverviewTab.tsx
+++ b/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/Overview/OverviewTab.tsx
@@ -6,22 +6,21 @@ import * as React from 'react'
import {Linking, StyleSheet, Text, TouchableOpacity, View} from 'react-native'
import {Icon} from '../../../../../components/Icon'
-import {Info} from '../../../../../components/Info/Info'
import {Space} from '../../../../../components/Space/Space'
import {formatTokenWithText} from '../../../../../yoroi-wallets/utils/format'
import {Quantities} from '../../../../../yoroi-wallets/utils/utils'
import {useSelectedWallet} from '../../../../WalletManager/common/hooks/useSelectedWallet'
import {useWalletManager} from '../../../../WalletManager/context/WalletManagerProvider'
-import {Address} from '../../../common/Address'
-import {CollapsibleSection} from '../../../common/CollapsibleSection'
+import {Accordion} from '../../../common/Accordion'
+import {CopiableText} from '../../../common/CopiableText'
import {Divider} from '../../../common/Divider'
import {useAddressType} from '../../../common/hooks/useAddressType'
-import {FormattedTx} from '../../../common/hooks/useFormattedTx'
import {useStrings} from '../../../common/hooks/useStrings'
+import {ReviewTxState} from '../../../common/ReviewTxProvider'
import {TokenItem} from '../../../common/TokenItem'
-import {FormattedOutputs} from '../../../common/types'
+import {FormattedOutputs, FormattedTx} from '../../../common/types'
-export const OverviewTab = ({tx}: {tx: FormattedTx}) => {
+export const OverviewTab = ({tx, operations}: {tx: FormattedTx; operations: ReviewTxState['operations']}) => {
const {styles} = useStyles()
const notOwnedOutputs = React.useMemo(() => tx.outputs.filter((output) => !output.ownAddress), [tx.outputs])
@@ -36,6 +35,8 @@ export const OverviewTab = ({tx}: {tx: FormattedTx}) => {
+
+
)
}
@@ -77,7 +78,7 @@ const FeeInfoItem = ({fee}: {fee: string}) => {
{strings.feeLabel}
- {fee}
+ {`-${fee}`}
)
}
@@ -92,20 +93,25 @@ const SenderSection = ({
ownedOutputs: FormattedOutputs
}) => {
const strings = useStrings()
+ const {styles} = useStyles()
const address = ownedOutputs[0]?.rewardAddress ?? ownedOutputs[0]?.address
return (
-
+
-
+
+
+ {address}
+
+
{notOwnedOutputs.length === 1 && }
-
+
)
}
@@ -140,10 +146,10 @@ const SenderTokens = ({tx, notOwnedOutputs}: {tx: FormattedTx; notOwnedOutputs:
-
+
- {notPrimaryTokenSent.map((token) => (
-
+ {notPrimaryTokenSent.map((token, index) => (
+
))}
@@ -179,12 +185,42 @@ const ReceiverSection = ({notOwnedOutputs}: {notOwnedOutputs: FormattedOutputs})
{isScriptAddress ? strings.receiveToScriptLabel : strings.receiveToLabel}:
-
+
+
+ {address}
+
+
>
)
}
+const OperationsSection = ({operations}: {operations: ReviewTxState['operations']}) => {
+ if (operations === null || (Array.isArray(operations) && operations.length === 0)) return null
+
+ return (
+
+
+
+
+
+
+ {operations.map((operation, index) => {
+ if (index === 0) return operation
+
+ return (
+ <>
+
+
+ {operation}
+ >
+ )
+ })}
+
+
+ )
+}
+
const useStyles = () => {
const {atoms, color} = useTheme()
const styles = StyleSheet.create({
@@ -249,6 +285,11 @@ const useStyles = () => {
receiverSectionAddress: {
maxWidth: 260,
},
+ addressText: {
+ ...atoms.flex_1,
+ ...atoms.body_2_md_regular,
+ color: color.text_gray_medium,
+ },
})
const colors = {
@@ -285,7 +326,7 @@ const CreatedByInfoItem = () => {
// 🚧 TODO: WIP 🚧
// eslint-disable-next-line @typescript-eslint/no-unused-vars
-const ReceiverTokensSectionMultiReceiver = () => {
+/* const ReceiverTokensSectionMultiReceiver = () => {
const {styles} = useStyles()
return (
@@ -294,7 +335,7 @@ const ReceiverTokensSectionMultiReceiver = () => {
-
+
@@ -311,36 +352,36 @@ const ReceiverTokensSectionMultiReceiver = () => {
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
>
)
-}
+} */
// 🚧 TODO: WIP 🚧
-const ReceiverSectionLabel = () => {
+/* const ReceiverSectionLabel = () => {
const {styles, colors} = useStyles()
return (
@@ -352,4 +393,4 @@ const ReceiverSectionLabel = () => {
Receive
)
-}
+} */
diff --git a/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/ReviewTxScreen.tsx b/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/ReviewTxScreen.tsx
index 6216f4c12f..c1d728dbe5 100644
--- a/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/ReviewTxScreen.tsx
+++ b/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/ReviewTxScreen.tsx
@@ -1,15 +1,15 @@
import {createMaterialTopTabNavigator, MaterialTopTabBarProps} from '@react-navigation/material-top-tabs'
import {useTheme} from '@yoroi/theme'
import * as React from 'react'
-import {FlatList, StyleSheet, Text, TouchableOpacity, TouchableOpacityProps, View} from 'react-native'
+import {FlatList, ScrollView, StyleSheet, Text, TouchableOpacity, TouchableOpacityProps, View} from 'react-native'
import {Button} from '../../../../components/Button/Button'
import {SafeArea} from '../../../../components/SafeArea'
-import {ReviewTxRoutes, useUnsafeParams} from '../../../../kernel/navigation'
import {useFormattedTx} from '../../common/hooks/useFormattedTx'
import {useOnConfirm} from '../../common/hooks/useOnConfirm'
import {useStrings} from '../../common/hooks/useStrings'
import {useTxBody} from '../../common/hooks/useTxBody'
+import {useReviewTx} from '../../common/ReviewTxProvider'
import {OverviewTab} from './Overview/OverviewTab'
import {UTxOsTab} from './UTxOs/UTxOsTab'
@@ -18,28 +18,43 @@ const MaterialTab = createMaterialTopTabNavigator()
export const ReviewTxScreen = () => {
const {styles} = useStyles()
const strings = useStrings()
+ const {unsignedTx, operations, onSuccess, onError} = useReviewTx()
+
+ if (unsignedTx === null) throw new Error('ReviewTxScreen: missing unsignedTx')
- // TODO: move this to a context
- const params = useUnsafeParams()
const {onConfirm} = useOnConfirm({
- unsignedTx: params.unsignedTx,
- onSuccess: params.onSuccess,
- onError: params.onError,
+ unsignedTx,
+ onSuccess,
+ onError,
})
// TODO: add cbor arguments
- const txBody = useTxBody({unsignedTx: params.unsignedTx})
+ const txBody = useTxBody({unsignedTx})
const formatedTx = useFormattedTx(txBody)
- const OverViewTabMemo = React.memo(() => )
+ const OverViewTabMemo = React.memo(() => )
const UTxOsTabMemo = React.memo(() => )
return (
-
-
-
+
+ {() => (
+ /* TODO: make scrollview general to use button border */
+
+
+
+ )}
+
+
+
+ {() => (
+ /* TODO: make scrollview general to use button border */
+
+
+
+ )}
+
@@ -59,11 +74,11 @@ const TabBar = ({navigation, state}: MaterialTopTabBarProps) => {
[strings.overviewTab, 'overview'],
[strings.utxosTab, 'utxos'],
]}
- style={styles.tabBar}
- showsHorizontalScrollIndicator={false}
renderItem={({item: [label, key], index}) => (
navigation.navigate(key)} />
)}
+ style={styles.tabBar}
+ showsHorizontalScrollIndicator={false}
bounces={false}
horizontal
/>
diff --git a/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/UTxOs/UTxOsTab.tsx b/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/UTxOs/UTxOsTab.tsx
index bbf23f8cec..83861af94f 100644
--- a/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/UTxOs/UTxOsTab.tsx
+++ b/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/UTxOs/UTxOsTab.tsx
@@ -3,13 +3,12 @@ import * as React from 'react'
import {StyleSheet, Text, View} from 'react-native'
import {Space} from '../../../../../components/Space/Space'
-import {Address} from '../../../common/Address'
-import {CollapsibleSection} from '../../../common/CollapsibleSection'
+import {Accordion} from '../../../common/Accordion'
+import {CopiableText} from '../../../common/CopiableText'
import {Divider} from '../../../common/Divider'
-import {FormattedTx} from '../../../common/hooks/useFormattedTx'
import {useStrings} from '../../../common/hooks/useStrings'
import {TokenItem} from '../../../common/TokenItem'
-import {FormattedInput, FormattedInputs, FormattedOutput, FormattedOutputs} from '../../../common/types'
+import {FormattedInput, FormattedInputs, FormattedOutput, FormattedOutputs, FormattedTx} from '../../../common/types'
export const UTxOsTab = ({tx}: {tx: FormattedTx}) => {
const {styles} = useStyles()
@@ -19,21 +18,21 @@ export const UTxOsTab = ({tx}: {tx: FormattedTx}) => {
-
+
-
+
-
+
-
+
)
}
const Inputs = ({inputs}: {inputs: FormattedInputs}) => {
- return inputs.map((input) => )
+ return inputs.map((input, index) => )
}
const Input = ({input}: {input: FormattedInput}) => {
@@ -49,25 +48,35 @@ const Input = ({input}: {input: FormattedInput}) => {
-
+
+ {input.address}
+
-
+
+ {input.txHash}
+
+
+
+ {`#${input.txIndex}`}
+
+
+
- {input.assets.map((asset) => (
-
+ {input.assets.map((asset, index) => (
+
))}
)
}
const Outputs = ({outputs}: {outputs: FormattedOutputs}) => {
- return outputs.map((output) => )
+ return outputs.map((output, index) => )
}
const Output = ({output}: {output: FormattedOutput}) => {
@@ -83,14 +92,22 @@ const Output = ({output}: {output: FormattedOutput}) => {
-
+
+ {output.address}
+
- {output.assets.map((asset) => (
-
+ {output.assets.map((asset, index) => (
+
))}
@@ -179,6 +196,15 @@ const useStyles = () => {
...atoms.body_2_md_regular,
color: color.text_gray_medium,
},
+ addressText: {
+ ...atoms.flex_1,
+ ...atoms.body_2_md_regular,
+ color: color.text_gray_medium,
+ },
+ index: {
+ ...atoms.body_2_md_medium,
+ color: color.text_gray_medium,
+ },
})
return {styles} as const
diff --git a/apps/wallet-mobile/src/features/Send/useCases/ListAmountsToSend/ListAmountsToSendScreen.tsx b/apps/wallet-mobile/src/features/Send/useCases/ListAmountsToSend/ListAmountsToSendScreen.tsx
index ee534acc81..aa4bfac370 100644
--- a/apps/wallet-mobile/src/features/Send/useCases/ListAmountsToSend/ListAmountsToSendScreen.tsx
+++ b/apps/wallet-mobile/src/features/Send/useCases/ListAmountsToSend/ListAmountsToSendScreen.tsx
@@ -22,6 +22,7 @@ import {useWalletNavigation} from '../../../../kernel/navigation'
import {useSaveMemo} from '../../../../yoroi-wallets/hooks'
import {YoroiEntry, YoroiSignedTx} from '../../../../yoroi-wallets/types/yoroi'
import {TokenAmountItem} from '../../../Portfolio/common/TokenAmountItem/TokenAmountItem'
+import {useReviewTx} from '../../../ReviewTx/common/ReviewTxProvider'
import {useSearch} from '../../../Search/SearchContext'
import {useSelectedWallet} from '../../../WalletManager/common/hooks/useSelectedWallet'
import {useNavigateTo, useOverridePreviousSendTxRoute} from '../../common/navigation'
@@ -38,6 +39,7 @@ export const ListAmountsToSendScreen = () => {
const navigation = useNavigation()
const {track} = useMetrics()
const {wallet} = useSelectedWallet()
+ const {unsignedTxChanged, onSuccessChanged, onErrorChanged} = useReviewTx()
useOverridePreviousSendTxRoute('send-start-tx')
@@ -45,14 +47,7 @@ export const ListAmountsToSendScreen = () => {
navigation.setOptions({headerLeft: () => })
}, [navigation])
- const {
- memo,
- targets,
- selectedTargetIndex,
- tokenSelectedChanged,
- amountRemoved,
- unsignedTxChanged: yoroiUnsignedTxChanged,
- } = useTransfer()
+ const {memo, targets, selectedTargetIndex, tokenSelectedChanged, amountRemoved} = useTransfer()
const {saveMemo} = useSaveMemo({wallet})
const {amounts} = targets[selectedTargetIndex].entry
const selectedTokensCounter = Object.keys(amounts).length
@@ -108,8 +103,10 @@ export const ListAmountsToSendScreen = () => {
// NOTE: update on multi target support
createUnsignedTx([toYoroiEntry(targets[selectedTargetIndex].entry)], {
onSuccess: (yoroiUnsignedTx) => {
- yoroiUnsignedTxChanged(yoroiUnsignedTx)
- navigateToTxReview({unsignedTx: yoroiUnsignedTx, onSuccess, onError})
+ unsignedTxChanged(yoroiUnsignedTx)
+ onSuccessChanged(onSuccess)
+ onErrorChanged(onError)
+ navigateToTxReview()
},
})
}
diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/CollateralInfoModal.tsx b/apps/wallet-mobile/src/features/Settings/ManageCollateral/CollateralInfoModal.tsx
new file mode 100644
index 0000000000..98a14c7025
--- /dev/null
+++ b/apps/wallet-mobile/src/features/Settings/ManageCollateral/CollateralInfoModal.tsx
@@ -0,0 +1,41 @@
+import {useTheme} from '@yoroi/theme'
+import * as React from 'react'
+import {StyleSheet, Text, View} from 'react-native'
+
+import {InfoModalIllustration} from './illustrations/InfoModalIllustration'
+import {useStrings} from './strings'
+
+export const CollateralInfoModal = () => {
+ const {styles} = useStyles()
+ const strings = useStrings()
+
+ return (
+
+
+
+ {strings.collateralInfoModalText}
+
+ )
+}
+
+const useStyles = () => {
+ const {color, atoms} = useTheme()
+ const styles = StyleSheet.create({
+ modal: {
+ ...atoms.flex_1,
+ ...atoms.px_lg,
+ ...atoms.align_center,
+ },
+ modalText: {
+ ...atoms.text_center,
+ ...atoms.body_1_lg_regular,
+ color: color.text_gray_medium,
+ },
+ })
+
+ const colors = {
+ iconColor: color.gray_900,
+ }
+
+ return {styles, colors} as const
+}
diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/ConfirmTxScreen.stories.tsx b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/ConfirmTxScreen.stories.tsx
deleted file mode 100644
index a62d55cffe..0000000000
--- a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/ConfirmTxScreen.stories.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import {storiesOf} from '@storybook/react-native'
-import {TransferProvider} from '@yoroi/transfer'
-import React from 'react'
-
-import {mocks as walletMocks} from '../../../../yoroi-wallets/mocks/wallet'
-import {WalletManagerProviderMock} from '../../../../yoroi-wallets/mocks/WalletManagerProviderMock'
-import {mocks as sendMocks} from '../../../Send/common/mocks'
-import {ConfirmTxScreen} from './ConfirmTxScreen'
-
-storiesOf('Confirm Tx', module).add('initial', () => {
- return (
-
-
-
-
-
- )
-})
diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/ConfirmTxScreen.tsx b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/ConfirmTxScreen.tsx
deleted file mode 100644
index a81b7b750c..0000000000
--- a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/ConfirmTxScreen.tsx
+++ /dev/null
@@ -1,150 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import {useTheme} from '@yoroi/theme'
-import {useTransfer} from '@yoroi/transfer'
-import React, {useEffect} from 'react'
-import {useIntl} from 'react-intl'
-import {ScrollView, StyleSheet, View, ViewProps} from 'react-native'
-import {SafeAreaView} from 'react-native-safe-area-context'
-
-import {ConfirmTx} from '../../../../components/ConfirmTx/ConfirmTx'
-import {KeyboardAvoidingView} from '../../../../components/KeyboardAvoidingView/KeyboardAvoidingView'
-import {Spacer} from '../../../../components/Spacer/Spacer'
-import {ValidatedTextInput} from '../../../../components/ValidatedTextInput'
-import {debugWalletInfo, features} from '../../../../kernel/features'
-import globalMessages, {confirmationMessages, errorMessages, txLabels} from '../../../../kernel/i18n/global-messages'
-import {useSetCollateralId} from '../../../../yoroi-wallets/cardano/utxoManager/useSetCollateralId'
-import {useSaveMemo} from '../../../../yoroi-wallets/hooks'
-import {YoroiSignedTx} from '../../../../yoroi-wallets/types/yoroi'
-import {CurrentBalance} from '../../../Send/useCases/ConfirmTx/Summary/CurrentBalance'
-import {useSelectedWallet} from '../../../WalletManager/common/hooks/useSelectedWallet'
-import {useNavigateTo} from '../navigation'
-import {BalanceAfter} from './Summary/BalanceAfter'
-import {Fees} from './Summary/Fees'
-import {PrimaryTotal} from './Summary/PrimaryTotal'
-import {SecondaryTotals} from './Summary/SecondaryTotals'
-
-export const ConfirmTxScreen = () => {
- const strings = useStrings()
- const styles = useStyles()
- const {wallet, meta} = useSelectedWallet()
- const navigateTo = useNavigateTo()
- const [password, setPassword] = React.useState('')
- const [useUSB, setUseUSB] = React.useState(false)
- const {setCollateralId} = useSetCollateralId(wallet)
-
- const {memo, unsignedTx: yoroiUnsignedTx} = useTransfer()
-
- const {saveMemo} = useSaveMemo({wallet})
-
- useEffect(() => {
- if (features.prefillWalletInfo && __DEV__) {
- setPassword(debugWalletInfo.PASSWORD)
- }
- }, [])
-
- const onSuccess = (signedTx: YoroiSignedTx) => {
- navigateTo.submittedTx()
- const collateralId = `${signedTx.signedTx.id}:0`
- setCollateralId(collateralId)
- if (memo.length > 0) {
- saveMemo({txId: signedTx.signedTx.id, memo: memo.trim()})
- }
- }
-
- const onError = () => {
- navigateTo.failedTx()
- }
-
- if (yoroiUnsignedTx === undefined) throw new Error('Missing yoroiUnsignedTx')
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {!meta.isEasyConfirmationEnabled && !meta.isHW && (
-
- )}
-
-
-
-
-
-
-
- )
-}
-
-const Actions = (props: ViewProps) => {
- const styles = useStyles()
- return
-}
-
-const useStyles = () => {
- const {color} = useTheme()
- const styles = StyleSheet.create({
- root: {
- backgroundColor: color.bg_color_max,
- flex: 1,
- },
- container: {
- flex: 1,
- paddingHorizontal: 16,
- },
- actions: {
- paddingTop: 16,
- paddingHorizontal: 16,
- },
- })
- return styles
-}
-
-const useStrings = () => {
- const intl = useIntl()
-
- return {
- availableFunds: intl.formatMessage(globalMessages.availableFunds),
- balanceAfterTx: intl.formatMessage(txLabels.balanceAfterTx),
- total: intl.formatMessage(globalMessages.total),
- password: intl.formatMessage(txLabels.password),
- confirmButton: intl.formatMessage(confirmationMessages.commonButtons.confirmButton),
- submittingTx: intl.formatMessage(txLabels.submittingTx),
- pleaseWait: intl.formatMessage(globalMessages.pleaseWait),
- generalTxError: {
- title: intl.formatMessage(errorMessages.generalTxError.title),
- message: intl.formatMessage(errorMessages.generalTxError.message),
- },
- }
-}
diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/BalanceAfter.tsx b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/BalanceAfter.tsx
deleted file mode 100644
index 44a25cc607..0000000000
--- a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/BalanceAfter.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import * as React from 'react'
-import {useIntl} from 'react-intl'
-
-import {Text} from '../../../../../components/Text'
-import {txLabels} from '../../../../../kernel/i18n/global-messages'
-import {useBalances} from '../../../../../yoroi-wallets/hooks'
-import {YoroiUnsignedTx} from '../../../../../yoroi-wallets/types/yoroi'
-import {formatTokenWithSymbol} from '../../../../../yoroi-wallets/utils/format'
-import {Amounts} from '../../../../../yoroi-wallets/utils/utils'
-import {useSelectedWallet} from '../../../../WalletManager/common/hooks/useSelectedWallet'
-
-export const BalanceAfter = ({yoroiUnsignedTx}: {yoroiUnsignedTx: YoroiUnsignedTx}) => {
- const strings = useStrings()
- const {wallet} = useSelectedWallet()
- const balances = useBalances(wallet)
-
- const balancesAfter = Amounts.diff(balances, yoroiUnsignedTx.fee)
- const primaryAmountAfter = Amounts.getAmount(balancesAfter, wallet.portfolioPrimaryTokenInfo.id)
-
- return (
-
- {`${strings.balanceAfterTx}: ${formatTokenWithSymbol(
- primaryAmountAfter.quantity,
- wallet.portfolioPrimaryTokenInfo,
- )}`}
-
- )
-}
-
-const useStrings = () => {
- const intl = useIntl()
-
- return {
- balanceAfterTx: intl.formatMessage(txLabels.balanceAfterTx),
- }
-}
diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/Fees.tsx b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/Fees.tsx
deleted file mode 100644
index 05ad1a135f..0000000000
--- a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/Fees.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import * as React from 'react'
-import {useIntl} from 'react-intl'
-
-import {Text} from '../../../../../components/Text'
-import {txLabels} from '../../../../../kernel/i18n/global-messages'
-import {YoroiUnsignedTx} from '../../../../../yoroi-wallets/types/yoroi'
-import {formatTokenWithSymbol} from '../../../../../yoroi-wallets/utils/format'
-import {Amounts} from '../../../../../yoroi-wallets/utils/utils'
-import {useSelectedWallet} from '../../../../WalletManager/common/hooks/useSelectedWallet'
-
-export const Fees = ({yoroiUnsignedTx}: {yoroiUnsignedTx: YoroiUnsignedTx}) => {
- const strings = useStrings()
- const {wallet} = useSelectedWallet()
- const feeAmount = Amounts.getAmount(yoroiUnsignedTx.fee, wallet.portfolioPrimaryTokenInfo.id)
-
- return (
-
- {`${strings.fees}: ${formatTokenWithSymbol(feeAmount.quantity, wallet.portfolioPrimaryTokenInfo)}`}
-
- )
-}
-
-const useStrings = () => {
- const intl = useIntl()
-
- return {
- fees: intl.formatMessage(txLabels.fees),
- }
-}
diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/PrimaryTotal.tsx b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/PrimaryTotal.tsx
deleted file mode 100644
index a34bfdebf5..0000000000
--- a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/PrimaryTotal.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import {useTheme} from '@yoroi/theme'
-import * as React from 'react'
-import {useIntl} from 'react-intl'
-import {StyleSheet, View} from 'react-native'
-
-import {Text} from '../../../../../components/Text'
-import globalMessages from '../../../../../kernel/i18n/global-messages'
-import {YoroiUnsignedTx} from '../../../../../yoroi-wallets/types/yoroi'
-import {formatTokenWithSymbol} from '../../../../../yoroi-wallets/utils/format'
-import {Amounts} from '../../../../../yoroi-wallets/utils/utils'
-import {useSelectedWallet} from '../../../../WalletManager/common/hooks/useSelectedWallet'
-
-export const PrimaryTotal = ({yoroiUnsignedTx}: {yoroiUnsignedTx: YoroiUnsignedTx}) => {
- const strings = useStrings()
- const styles = useStyles()
- const {wallet} = useSelectedWallet()
- const primaryAmount = Amounts.getAmount(
- Amounts.getAmountsFromEntries(yoroiUnsignedTx.entries),
- wallet.portfolioPrimaryTokenInfo.id,
- )
-
- return (
-
- {strings.total}
-
-
- {formatTokenWithSymbol(primaryAmount.quantity, wallet.portfolioPrimaryTokenInfo)}
-
-
- )
-}
-
-const useStrings = () => {
- const intl = useIntl()
-
- return {
- total: intl.formatMessage(globalMessages.total),
- }
-}
-const useStyles = () => {
- const {color} = useTheme()
- const styles = StyleSheet.create({
- amount: {
- color: color.secondary_600,
- },
- })
- return styles
-}
diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/SecondaryTotals.tsx b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/SecondaryTotals.tsx
deleted file mode 100644
index 318160016a..0000000000
--- a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/SecondaryTotals.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-import {createUnknownTokenInfo, usePortfolioTokenInfo} from '@yoroi/portfolio'
-import {useTheme} from '@yoroi/theme'
-import {Balance, Portfolio} from '@yoroi/types'
-import * as React from 'react'
-import {StyleSheet, View} from 'react-native'
-
-import {Boundary} from '../../../../../components/Boundary/Boundary'
-import {Text} from '../../../../../components/Text'
-import {YoroiWallet} from '../../../../../yoroi-wallets/cardano/types'
-import {YoroiUnsignedTx} from '../../../../../yoroi-wallets/types/yoroi'
-import {formatTokenWithText} from '../../../../../yoroi-wallets/utils/format'
-import {Amounts, Quantities} from '../../../../../yoroi-wallets/utils/utils'
-import {useSelectedWallet} from '../../../../WalletManager/common/hooks/useSelectedWallet'
-
-export const SecondaryTotals = ({yoroiUnsignedTx}: {yoroiUnsignedTx: YoroiUnsignedTx}) => {
- const {wallet} = useSelectedWallet()
- const secondaryAmounts = Amounts.remove(Amounts.getAmountsFromEntries(yoroiUnsignedTx.entries), [
- wallet.portfolioPrimaryTokenInfo.id,
- ])
- const sortedAmounts = Amounts.toArray(secondaryAmounts).sort((a, b) =>
- Quantities.isGreaterThan(a.quantity, b.quantity) ? -1 : 1,
- )
-
- return (
-
- {sortedAmounts.map((amount) => (
-
-
-
- ))}
-
- )
-}
-
-const Amount = ({amount, wallet}: {amount: Balance.Amount; wallet: YoroiWallet}) => {
- const styles = useStyles()
- const {tokenInfo} = usePortfolioTokenInfo({
- network: wallet.networkManager.network,
- id: amount.tokenId as Portfolio.Token.Id,
- getTokenInfo: wallet.networkManager.tokenManager.api.tokenInfo,
- primaryTokenInfo: wallet.portfolioPrimaryTokenInfo,
- })
-
- const info =
- tokenInfo ??
- createUnknownTokenInfo({id: amount.tokenId as Portfolio.Token.Id, name: `Unknown token ${amount.tokenId}`})
-
- return {formatTokenWithText(amount.quantity, info)}
-}
-
-const useStyles = () => {
- const {color} = useTheme()
- const styles = StyleSheet.create({
- amount: {
- color: color.secondary_600,
- },
- })
- return styles
-}
diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/index.ts b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/index.ts
deleted file mode 100644
index 8e77dd2083..0000000000
--- a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './ConfirmTxScreen'
diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/InitialCollateralInfoModal.tsx b/apps/wallet-mobile/src/features/Settings/ManageCollateral/InitialCollateralInfoModal.tsx
new file mode 100644
index 0000000000..589cd07a1f
--- /dev/null
+++ b/apps/wallet-mobile/src/features/Settings/ManageCollateral/InitialCollateralInfoModal.tsx
@@ -0,0 +1,52 @@
+import {useTheme} from '@yoroi/theme'
+import * as React from 'react'
+import {StyleSheet, Text, View} from 'react-native'
+
+import {Button} from '../../../components/Button/Button'
+import {Space} from '../../../components/Space/Space'
+import {InfoModalIllustration} from './illustrations/InfoModalIllustration'
+import {useStrings} from './strings'
+
+export const InitialCollateralInfoModal = ({onConfirm}: {onConfirm: () => void}) => {
+ const {styles} = useStyles()
+ const strings = useStrings()
+
+ return (
+
+
+
+ {strings.collateralInfoModalText}
+
+
+
+
+
+
+
+ )
+}
+
+const useStyles = () => {
+ const {color, atoms} = useTheme()
+ const styles = StyleSheet.create({
+ modal: {
+ ...atoms.flex_1,
+ ...atoms.px_lg,
+ ...atoms.align_center,
+ },
+ modalText: {
+ ...atoms.text_center,
+ ...atoms.body_1_lg_regular,
+ color: color.text_gray_medium,
+ },
+ actions: {
+ alignSelf: 'stretch',
+ },
+ })
+
+ const colors = {
+ iconColor: color.gray_900,
+ }
+
+ return {styles, colors} as const
+}
diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ManageCollateralScreen.tsx b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ManageCollateralScreen.tsx
index 7f8d2d6c53..2662984730 100644
--- a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ManageCollateralScreen.tsx
+++ b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ManageCollateralScreen.tsx
@@ -1,6 +1,4 @@
-import {toBigInt} from '@yoroi/common'
import {useTheme} from '@yoroi/theme'
-import {useTransfer} from '@yoroi/transfer'
import {Portfolio} from '@yoroi/types'
import BigNumber from 'bignumber.js'
import * as React from 'react'
@@ -11,6 +9,7 @@ import {
StyleSheet,
TouchableOpacity,
TouchableOpacityProps,
+ useWindowDimensions,
View,
ViewProps,
} from 'react-native'
@@ -21,20 +20,25 @@ import {Button} from '../../../components/Button/Button'
import {CopyButton} from '../../../components/CopyButton'
import {ErrorPanel} from '../../../components/ErrorPanel/ErrorPanel'
import {Icon} from '../../../components/Icon'
+import {Info} from '../../../components/Icon/Info'
+import {useModal} from '../../../components/Modal/ModalContext'
import {Space} from '../../../components/Space/Space'
import {Spacer} from '../../../components/Spacer/Spacer'
import {Text} from '../../../components/Text'
-import {SettingsStackRoutes, useUnsafeParams} from '../../../kernel/navigation'
+import {SettingsStackRoutes, useUnsafeParams, useWalletNavigation} from '../../../kernel/navigation'
import {useCollateralInfo} from '../../../yoroi-wallets/cardano/utxoManager/useCollateralInfo'
import {useSetCollateralId} from '../../../yoroi-wallets/cardano/utxoManager/useSetCollateralId'
import {collateralConfig, utxosMaker} from '../../../yoroi-wallets/cardano/utxoManager/utxos'
import {useBalances} from '../../../yoroi-wallets/hooks'
import {RawUtxo} from '../../../yoroi-wallets/types/other'
-import {YoroiEntry} from '../../../yoroi-wallets/types/yoroi'
+import {YoroiEntry, YoroiSignedTx} from '../../../yoroi-wallets/types/yoroi'
import {Amounts, asQuantity, Quantities} from '../../../yoroi-wallets/utils/utils'
import {TokenAmountItem} from '../../Portfolio/common/TokenAmountItem/TokenAmountItem'
+import {useReviewTx} from '../../ReviewTx/common/ReviewTxProvider'
import {useSelectedWallet} from '../../WalletManager/common/hooks/useSelectedWallet'
+import {CollateralInfoModal} from './CollateralInfoModal'
import {createCollateralEntry} from './helpers'
+import {InitialCollateralInfoModal} from './InitialCollateralInfoModal'
import {useNavigateTo} from './navigation'
import {useStrings} from './strings'
@@ -44,23 +48,20 @@ export const ManageCollateralScreen = () => {
wallet,
meta: {addressMode},
} = useSelectedWallet()
+ const screenHeight = useWindowDimensions().height
const {amount, collateralId, utxo} = useCollateralInfo(wallet)
const hasCollateral = collateralId !== '' && utxo !== undefined
const didSpend = collateralId !== '' && utxo === undefined
const navigateTo = useNavigateTo()
+ const {openModal} = useModal()
const strings = useStrings()
const balances = useBalances(wallet)
+ const {navigateToTxReview} = useWalletNavigation()
+ const {unsignedTxChanged, onSuccessChanged, onErrorChanged, operationsChanged} = useReviewTx()
const lockedAmount = asQuantity(wallet.primaryBreakdown.lockedAsStorageCost.toString())
const params = useUnsafeParams()
- const {
- reset: resetSendState,
- receiverResolveChanged,
- amountChanged,
- tokenSelectedChanged,
- unsignedTxChanged: yoroiUnsignedTxChanged,
- } = useTransfer()
const {mutate: createUnsignedTx, isLoading: isLoadingTx} = useMutation({
mutationFn: (entries: YoroiEntry[]) => wallet.createUnsignedTx({entries, addressMode}),
retry: false,
@@ -76,25 +77,27 @@ export const ManageCollateralScreen = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)
setCollateralId(collateralId)
}
- const createCollateralTransaction = () => {
- const address = wallet.externalAddresses[0]
- const amount: Portfolio.Token.Amount = {
- quantity: toBigInt(collateralConfig.minLovelace, wallet.portfolioPrimaryTokenInfo.decimals),
- info: wallet.portfolioPrimaryTokenInfo,
- }
- // populate for confirmation screen
- resetSendState()
- receiverResolveChanged(address)
- tokenSelectedChanged(amount.info.id)
- amountChanged(amount)
+ const onSuccess = (signedTx: YoroiSignedTx) => {
+ navigateTo.submittedTx()
+ const collateralId = `${signedTx.signedTx.id}:0`
+ setCollateralId(collateralId)
+ }
+
+ const onError = () => {
+ navigateTo.failedTx()
+ }
+ const createCollateralTransaction = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)
createUnsignedTx([createCollateralEntry(wallet)], {
onSuccess: (yoroiUnsignedTx) => {
- yoroiUnsignedTxChanged(yoroiUnsignedTx)
- navigateTo.confirmTx()
+ unsignedTxChanged(yoroiUnsignedTx)
+ operationsChanged([])
+ onSuccessChanged(onSuccess)
+ onErrorChanged(onError)
+ navigateToTxReview()
},
})
}
@@ -126,6 +129,14 @@ export const ManageCollateralScreen = () => {
createCollateralTransaction()
}
+ const handleCollateralInfoModal = () => {
+ openModal(
+ strings.initialCollateralInfoModalTitle,
+ ,
+ Math.min(screenHeight * 0.9, 650),
+ )
+ }
+
const shouldShowPrimaryButton = !hasCollateral || didSpend
const shouldShowBackButton = !shouldShowPrimaryButton && !!params?.backButton
@@ -171,7 +182,7 @@ export const ManageCollateralScreen = () => {
{shouldShowPrimaryButton && (
@@ -228,27 +239,58 @@ const RemoveAmountButton = ({disabled, ...props}: TouchableOpacityProps) => {
)
}
+const Operation = () => {
+ const {styles, colors} = useStyles()
+ const strings = useStrings()
+ const {openModal} = useModal()
+
+ const handleOnPressInfo = () => {
+ openModal(strings.collateralInfoModalTitle, , 500)
+ }
+
+ return (
+
+ {strings.collateralInfoModalLabel}
+
+
+
+
+
+
+
+ )
+}
+
const useStyles = () => {
- const {color} = useTheme()
+ const {color, atoms} = useTheme()
const styles = StyleSheet.create({
safeAreaView: {
backgroundColor: color.bg_color_max,
- flex: 1,
- paddingHorizontal: 16,
+ ...atoms.flex_1,
+ ...atoms.px_lg,
},
amountItem: {
- flexDirection: 'row',
- justifyContent: 'space-between',
- alignItems: 'center',
+ ...atoms.flex_row,
+ ...atoms.justify_between,
+ ...atoms.align_center,
},
heading: {
- flex: 1,
+ ...atoms.flex_1,
alignSelf: 'center',
},
+ operation: {
+ ...atoms.flex_row,
+ ...atoms.align_center,
+ },
+ operationText: {
+ ...atoms.body_2_md_regular,
+ color: color.text_gray_medium,
+ },
})
+
const colors = {
- iconColor: color.gray_max,
+ iconColor: color.gray_900,
}
- return {styles, colors}
+ return {styles, colors} as const
}
diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/illustrations/InfoModalIllustration.tsx b/apps/wallet-mobile/src/features/Settings/ManageCollateral/illustrations/InfoModalIllustration.tsx
new file mode 100644
index 0000000000..57462d9ee8
--- /dev/null
+++ b/apps/wallet-mobile/src/features/Settings/ManageCollateral/illustrations/InfoModalIllustration.tsx
@@ -0,0 +1,430 @@
+import * as React from 'react'
+import Svg, {Defs, LinearGradient, Path, Stop} from 'react-native-svg'
+
+export const InfoModalIllustration = () => {
+ return (
+
+ )
+}
diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/strings.ts b/apps/wallet-mobile/src/features/Settings/ManageCollateral/strings.ts
index 5a973c8fdf..0b5fc162c0 100644
--- a/apps/wallet-mobile/src/features/Settings/ManageCollateral/strings.ts
+++ b/apps/wallet-mobile/src/features/Settings/ManageCollateral/strings.ts
@@ -10,6 +10,12 @@ export const useStrings = () => {
notEnoughFundsAlertTitle: intl.formatMessage(messages.notEnoughFundsAlertTitle),
notEnoughFundsAlertMessage: intl.formatMessage(messages.notEnoughFundsAlertMessage),
notEnoughFundsAlertOK: intl.formatMessage(messages.notEnoughFundsAlertOK),
+ collateralInfoModalLabel: intl.formatMessage(messages.collateralInfoModalLabel),
+ collateralInfoModalTitle: intl.formatMessage(messages.collateralInfoModalTitle),
+ collateralInfoModalText: intl.formatMessage(messages.collateralInfoModalText),
+ initialCollateralInfoModalTitle: intl.formatMessage(messages.initialCollateralInfoModalTitle),
+ initialCollateralInfoModalText: intl.formatMessage(messages.initialCollateralInfoModalText),
+ initialCollateralInfoModalButton: intl.formatMessage(messages.initialCollateralInfoModalButton),
}
}
@@ -42,4 +48,30 @@ const messages = defineMessages({
id: 'components.settings.collateral.notEnoughFundsAlertOK',
defaultMessage: '!!!OK',
},
+ collateralInfoModalLabel: {
+ id: 'components.settings.collateral.collateralInfoModalLabel',
+ defaultMessage: '!!!Collateral creation',
+ },
+ collateralInfoModalTitle: {
+ id: 'components.settings.collateral.collateralInfoModalTitle',
+ defaultMessage: '!!!What is collateral?',
+ },
+ collateralInfoModalText: {
+ id: 'components.settings.collateral.collateralInfoModalText',
+ defaultMessage:
+ '!!!The collateral mechanism is an important feature that has been designed to ensure successful smart contract execution. It is used to guarantee that Cardano nodes are compensated for their work in case phase-2 validation fails.',
+ },
+ initialCollateralInfoModalTitle: {
+ id: 'components.settings.collateral.initialCollateralInfoModalTitle',
+ defaultMessage: '!!!Collateral creation',
+ },
+ initialCollateralInfoModalText: {
+ id: 'components.settings.collateral.initialCollateralInfoModalText',
+ defaultMessage:
+ '!!!The collateral mechanism is designed to ensure smart contracts on Cardano execute successfully. It guarantees that nodes are compensated for their work if a contract fails during validation.',
+ },
+ initialCollateralInfoModalButton: {
+ id: 'components.settings.collateral.initialCollateralInfoModalButton',
+ defaultMessage: '!!!Add collateral',
+ },
})
diff --git a/apps/wallet-mobile/src/features/Settings/SettingsScreenNavigator.tsx b/apps/wallet-mobile/src/features/Settings/SettingsScreenNavigator.tsx
index 6054fdd899..c624d71cda 100644
--- a/apps/wallet-mobile/src/features/Settings/SettingsScreenNavigator.tsx
+++ b/apps/wallet-mobile/src/features/Settings/SettingsScreenNavigator.tsx
@@ -30,7 +30,6 @@ import {ChangeCurrencyScreen} from './Currency/ChangeCurrencyScreen'
import {DisableEasyConfirmationScreen, EnableEasyConfirmationScreen} from './EasyConfirmation'
import {EnableLoginWithOsScreen} from './EnableLoginWithOs'
import {ManageCollateralScreen} from './ManageCollateral'
-import {ConfirmTxScreen} from './ManageCollateral/ConfirmTx'
import {FailedTxScreen} from './ManageCollateral/ConfirmTx/FailedTx/FailedTxScreen'
import {SubmittedTxScreen} from './ManageCollateral/ConfirmTx/SubmittedTx/SubmittedTxScreen'
import {PrivacyPolicyScreen} from './PrivacyPolicy'
@@ -187,14 +186,6 @@ export const SettingsScreenNavigator = () => {
component={ManageCollateralScreen}
/>
-
-
void
- onError: () => void
- }
+ 'review-tx': undefined
}
export type PortfolioTokenListTabRoutes = {
@@ -464,12 +459,11 @@ export const useWalletNavigation = () => {
})
},
- navigateToTxReview: (params: ReviewTxRoutes['review-tx']) => {
+ navigateToTxReview: () => {
navigation.navigate('manage-wallets', {
screen: 'review-tx-routes',
params: {
screen: 'review-tx',
- params,
},
})
},
diff --git a/apps/wallet-mobile/translations/messages/src/WalletNavigator.json b/apps/wallet-mobile/translations/messages/src/WalletNavigator.json
index f8e4bc086c..ce9df7a0e8 100644
--- a/apps/wallet-mobile/translations/messages/src/WalletNavigator.json
+++ b/apps/wallet-mobile/translations/messages/src/WalletNavigator.json
@@ -4,14 +4,14 @@
"defaultMessage": "!!!Transactions",
"file": "src/WalletNavigator.tsx",
"start": {
- "line": 309,
+ "line": 306,
"column": 22,
- "index": 10838
+ "index": 10668
},
"end": {
- "line": 312,
+ "line": 309,
"column": 3,
- "index": 10941
+ "index": 10771
}
},
{
@@ -19,14 +19,14 @@
"defaultMessage": "!!!Send",
"file": "src/WalletNavigator.tsx",
"start": {
- "line": 313,
+ "line": 310,
"column": 14,
- "index": 10957
+ "index": 10787
},
"end": {
- "line": 316,
+ "line": 313,
"column": 3,
- "index": 11056
+ "index": 10886
}
},
{
@@ -34,14 +34,14 @@
"defaultMessage": "!!!Receive",
"file": "src/WalletNavigator.tsx",
"start": {
- "line": 317,
+ "line": 314,
"column": 17,
- "index": 11075
+ "index": 10905
},
"end": {
- "line": 320,
+ "line": 317,
"column": 3,
- "index": 11180
+ "index": 11010
}
},
{
@@ -49,14 +49,14 @@
"defaultMessage": "!!!Dashboard",
"file": "src/WalletNavigator.tsx",
"start": {
- "line": 321,
+ "line": 318,
"column": 19,
- "index": 11201
+ "index": 11031
},
"end": {
- "line": 324,
+ "line": 321,
"column": 3,
- "index": 11298
+ "index": 11128
}
},
{
@@ -64,14 +64,14 @@
"defaultMessage": "!!!Delegate",
"file": "src/WalletNavigator.tsx",
"start": {
- "line": 325,
+ "line": 322,
"column": 18,
- "index": 11318
+ "index": 11148
},
"end": {
- "line": 328,
+ "line": 325,
"column": 3,
- "index": 11413
+ "index": 11243
}
},
{
@@ -79,14 +79,14 @@
"defaultMessage": "!!!Wallet",
"file": "src/WalletNavigator.tsx",
"start": {
- "line": 329,
+ "line": 326,
"column": 16,
- "index": 11431
+ "index": 11261
},
"end": {
- "line": 332,
+ "line": 329,
"column": 3,
- "index": 11529
+ "index": 11359
}
},
{
@@ -94,14 +94,14 @@
"defaultMessage": "!!!Staking",
"file": "src/WalletNavigator.tsx",
"start": {
- "line": 333,
+ "line": 330,
"column": 17,
- "index": 11548
+ "index": 11378
},
"end": {
- "line": 336,
+ "line": 333,
"column": 3,
- "index": 11613
+ "index": 11443
}
},
{
@@ -109,14 +109,14 @@
"defaultMessage": "!!!NFT Gallery",
"file": "src/WalletNavigator.tsx",
"start": {
- "line": 337,
+ "line": 334,
"column": 14,
- "index": 11629
+ "index": 11459
},
"end": {
- "line": 340,
+ "line": 337,
"column": 3,
- "index": 11723
+ "index": 11553
}
},
{
@@ -124,14 +124,14 @@
"defaultMessage": "!!!Menu",
"file": "src/WalletNavigator.tsx",
"start": {
- "line": 341,
+ "line": 338,
"column": 14,
- "index": 11739
+ "index": 11569
},
"end": {
- "line": 344,
+ "line": 341,
"column": 3,
- "index": 11791
+ "index": 11621
}
},
{
@@ -139,14 +139,14 @@
"defaultMessage": "!!!Discover",
"file": "src/WalletNavigator.tsx",
"start": {
- "line": 345,
+ "line": 342,
"column": 18,
- "index": 11811
+ "index": 11641
},
"end": {
- "line": 348,
+ "line": 345,
"column": 3,
- "index": 11900
+ "index": 11730
}
},
{
@@ -154,14 +154,14 @@
"defaultMessage": "!!!My wallets",
"file": "src/WalletNavigator.tsx",
"start": {
- "line": 349,
+ "line": 346,
"column": 31,
- "index": 11933
+ "index": 11763
},
"end": {
- "line": 352,
+ "line": 349,
"column": 3,
- "index": 12042
+ "index": 11872
}
},
{
@@ -169,14 +169,14 @@
"defaultMessage": "!!!Portfolio",
"file": "src/WalletNavigator.tsx",
"start": {
- "line": 353,
+ "line": 350,
"column": 19,
- "index": 12063
+ "index": 11893
},
"end": {
- "line": 356,
+ "line": 353,
"column": 3,
- "index": 12132
+ "index": 11962
}
}
]
\ No newline at end of file
diff --git a/apps/wallet-mobile/translations/messages/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.json b/apps/wallet-mobile/translations/messages/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.json
index 3938849601..38ab260df5 100644
--- a/apps/wallet-mobile/translations/messages/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.json
+++ b/apps/wallet-mobile/translations/messages/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.json
@@ -6,12 +6,12 @@
"start": {
"line": 378,
"column": 9,
- "index": 10888
+ "index": 10908
},
"end": {
"line": 381,
"column": 3,
- "index": 10959
+ "index": 10979
}
},
{
@@ -21,12 +21,12 @@
"start": {
"line": 382,
"column": 12,
- "index": 10973
+ "index": 10993
},
"end": {
"line": 385,
"column": 3,
- "index": 11044
+ "index": 11064
}
},
{
@@ -36,12 +36,12 @@
"start": {
"line": 386,
"column": 12,
- "index": 11058
+ "index": 11078
},
"end": {
"line": 389,
"column": 3,
- "index": 11129
+ "index": 11149
}
},
{
@@ -51,12 +51,12 @@
"start": {
"line": 390,
"column": 11,
- "index": 11142
+ "index": 11162
},
"end": {
"line": 393,
"column": 3,
- "index": 11212
+ "index": 11232
}
},
{
@@ -66,12 +66,12 @@
"start": {
"line": 394,
"column": 13,
- "index": 11227
+ "index": 11247
},
"end": {
"line": 397,
"column": 3,
- "index": 11298
+ "index": 11318
}
},
{
@@ -81,12 +81,12 @@
"start": {
"line": 398,
"column": 15,
- "index": 11315
+ "index": 11335
},
"end": {
"line": 401,
"column": 3,
- "index": 11392
+ "index": 11412
}
},
{
@@ -96,12 +96,12 @@
"start": {
"line": 402,
"column": 10,
- "index": 11404
+ "index": 11424
},
"end": {
"line": 405,
"column": 3,
- "index": 11471
+ "index": 11491
}
},
{
@@ -111,12 +111,12 @@
"start": {
"line": 406,
"column": 15,
- "index": 11488
+ "index": 11508
},
"end": {
"line": 409,
"column": 3,
- "index": 11565
+ "index": 11585
}
},
{
@@ -126,12 +126,12 @@
"start": {
"line": 410,
"column": 12,
- "index": 11579
+ "index": 11599
},
"end": {
"line": 413,
"column": 3,
- "index": 11651
+ "index": 11671
}
},
{
@@ -141,12 +141,12 @@
"start": {
"line": 414,
"column": 16,
- "index": 11669
+ "index": 11689
},
"end": {
"line": 417,
"column": 3,
- "index": 11746
+ "index": 11766
}
},
{
@@ -156,12 +156,12 @@
"start": {
"line": 418,
"column": 16,
- "index": 11764
+ "index": 11784
},
"end": {
"line": 421,
"column": 3,
- "index": 11844
+ "index": 11864
}
}
]
\ No newline at end of file
diff --git a/apps/wallet-mobile/translations/messages/src/features/ReviewTx/common/hooks/useStrings.json b/apps/wallet-mobile/translations/messages/src/features/ReviewTx/common/hooks/useStrings.json
index 77bbb70459..f7ec21070a 100644
--- a/apps/wallet-mobile/translations/messages/src/features/ReviewTx/common/hooks/useStrings.json
+++ b/apps/wallet-mobile/translations/messages/src/features/ReviewTx/common/hooks/useStrings.json
@@ -4,14 +4,14 @@
"defaultMessage": "!!!Confirm",
"file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
"start": {
- "line": 28,
+ "line": 39,
"column": 11,
- "index": 1188
+ "index": 1785
},
"end": {
- "line": 31,
+ "line": 42,
"column": 3,
- "index": 1255
+ "index": 1852
}
},
{
@@ -19,14 +19,14 @@
"defaultMessage": "!!!UTxOs",
"file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
"start": {
- "line": 32,
+ "line": 43,
"column": 9,
- "index": 1266
+ "index": 1863
},
"end": {
- "line": 35,
+ "line": 46,
"column": 3,
- "index": 1329
+ "index": 1926
}
},
{
@@ -34,14 +34,14 @@
"defaultMessage": "!!!UTxOs",
"file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
"start": {
- "line": 36,
+ "line": 47,
"column": 12,
- "index": 1343
+ "index": 1940
},
"end": {
- "line": 39,
+ "line": 50,
"column": 3,
- "index": 1415
+ "index": 2012
}
},
{
@@ -49,14 +49,14 @@
"defaultMessage": "!!!Overview",
"file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
"start": {
- "line": 40,
+ "line": 51,
"column": 15,
- "index": 1432
+ "index": 2029
},
"end": {
- "line": 43,
+ "line": 54,
"column": 3,
- "index": 1510
+ "index": 2107
}
},
{
@@ -64,14 +64,14 @@
"defaultMessage": "!!!Wallet",
"file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
"start": {
- "line": 44,
+ "line": 55,
"column": 15,
- "index": 1527
+ "index": 2124
},
"end": {
- "line": 47,
+ "line": 58,
"column": 3,
- "index": 1601
+ "index": 2198
}
},
{
@@ -79,14 +79,14 @@
"defaultMessage": "!!!Fee",
"file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
"start": {
- "line": 48,
+ "line": 59,
"column": 12,
- "index": 1615
+ "index": 2212
},
"end": {
- "line": 51,
+ "line": 62,
"column": 3,
- "index": 1674
+ "index": 2271
}
},
{
@@ -94,14 +94,14 @@
"defaultMessage": "!!!Your Wallet",
"file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
"start": {
- "line": 52,
+ "line": 63,
"column": 17,
- "index": 1693
+ "index": 2290
},
"end": {
- "line": 55,
+ "line": 66,
"column": 3,
- "index": 1779
+ "index": 2376
}
},
{
@@ -109,29 +109,29 @@
"defaultMessage": "!!!Send",
"file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
"start": {
- "line": 56,
+ "line": 67,
"column": 13,
- "index": 1794
+ "index": 2391
},
"end": {
- "line": 59,
+ "line": 70,
"column": 3,
- "index": 1869
+ "index": 2466
}
},
{
"id": "txReview.overview.receiveToLabel",
- "defaultMessage": "!!!receiveToLabel",
+ "defaultMessage": "!!!To",
"file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
"start": {
- "line": 60,
+ "line": 71,
"column": 18,
- "index": 1889
+ "index": 2486
},
"end": {
- "line": 63,
+ "line": 74,
"column": 3,
- "index": 1979
+ "index": 2564
}
},
{
@@ -139,14 +139,14 @@
"defaultMessage": "!!!To script",
"file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
"start": {
- "line": 64,
+ "line": 75,
"column": 24,
- "index": 2005
+ "index": 2590
},
"end": {
- "line": 67,
+ "line": 78,
"column": 3,
- "index": 2096
+ "index": 2681
}
},
{
@@ -154,14 +154,14 @@
"defaultMessage": "!!!Inputs",
"file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
"start": {
- "line": 68,
+ "line": 79,
"column": 20,
- "index": 2118
+ "index": 2703
},
"end": {
- "line": 71,
+ "line": 82,
"column": 3,
- "index": 2199
+ "index": 2784
}
},
{
@@ -169,14 +169,14 @@
"defaultMessage": "!!!Outputs",
"file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
"start": {
- "line": 72,
+ "line": 83,
"column": 21,
- "index": 2222
+ "index": 2807
},
"end": {
- "line": 75,
+ "line": 86,
"column": 3,
- "index": 2305
+ "index": 2890
}
},
{
@@ -184,14 +184,14 @@
"defaultMessage": "!!!Your address",
"file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
"start": {
- "line": 76,
+ "line": 87,
"column": 25,
- "index": 2332
+ "index": 2917
},
"end": {
- "line": 79,
+ "line": 90,
"column": 3,
- "index": 2424
+ "index": 3009
}
},
{
@@ -199,14 +199,179 @@
"defaultMessage": "!!!Foreign address",
"file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
"start": {
- "line": 80,
+ "line": 91,
"column": 28,
- "index": 2454
+ "index": 3039
},
"end": {
- "line": 83,
+ "line": 94,
+ "column": 3,
+ "index": 3137
+ }
+ },
+ {
+ "id": "txReview.tokenDetails.overViewTab.title",
+ "defaultMessage": "!!!Overview",
+ "file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
+ "start": {
+ "line": 95,
+ "column": 12,
+ "index": 3151
+ },
+ "end": {
+ "line": 98,
+ "column": 3,
+ "index": 3242
+ }
+ },
+ {
+ "id": "txReview.tokenDetails.jsonTab.title",
+ "defaultMessage": "!!!JSON",
+ "file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
+ "start": {
+ "line": 99,
+ "column": 8,
+ "index": 3252
+ },
+ "end": {
+ "line": 102,
+ "column": 3,
+ "index": 3335
+ }
+ },
+ {
+ "id": "txReview.tokenDetails.jsonTab.metadata",
+ "defaultMessage": "!!!Metadata",
+ "file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
+ "start": {
+ "line": 103,
+ "column": 12,
+ "index": 3349
+ },
+ "end": {
+ "line": 106,
+ "column": 3,
+ "index": 3439
+ }
+ },
+ {
+ "id": "txReview.tokenDetails.policyId.label",
+ "defaultMessage": "!!!Policy ID",
+ "file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
+ "start": {
+ "line": 107,
+ "column": 12,
+ "index": 3453
+ },
+ "end": {
+ "line": 110,
+ "column": 3,
+ "index": 3542
+ }
+ },
+ {
+ "id": "txReview.tokenDetails.fingerprint.label",
+ "defaultMessage": "!!!Fingerprint",
+ "file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
+ "start": {
+ "line": 111,
+ "column": 15,
+ "index": 3559
+ },
+ "end": {
+ "line": 114,
+ "column": 3,
+ "index": 3653
+ }
+ },
+ {
+ "id": "txReview.tokenDetails.overViewTab.name.label",
+ "defaultMessage": "!!!Name",
+ "file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
+ "start": {
+ "line": 115,
+ "column": 8,
+ "index": 3663
+ },
+ "end": {
+ "line": 118,
+ "column": 3,
+ "index": 3755
+ }
+ },
+ {
+ "id": "txReview.tokenDetails.overViewTab.tokenSupply.label",
+ "defaultMessage": "!!!Token Supply",
+ "file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
+ "start": {
+ "line": 119,
+ "column": 15,
+ "index": 3772
+ },
+ "end": {
+ "line": 122,
+ "column": 3,
+ "index": 3879
+ }
+ },
+ {
+ "id": "txReview.tokenDetails.overViewTab.symbol.label",
+ "defaultMessage": "!!!Symbol",
+ "file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
+ "start": {
+ "line": 123,
+ "column": 10,
+ "index": 3891
+ },
+ "end": {
+ "line": 126,
+ "column": 3,
+ "index": 3987
+ }
+ },
+ {
+ "id": "txReview.tokenDetails.overViewTab.description.label",
+ "defaultMessage": "!!!Description",
+ "file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
+ "start": {
+ "line": 127,
+ "column": 15,
+ "index": 4004
+ },
+ "end": {
+ "line": 130,
+ "column": 3,
+ "index": 4110
+ }
+ },
+ {
+ "id": "txReview.tokenDetails.overViewTab.details.label",
+ "defaultMessage": "!!!Details on",
+ "file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
+ "start": {
+ "line": 131,
+ "column": 11,
+ "index": 4123
+ },
+ "end": {
+ "line": 134,
+ "column": 3,
+ "index": 4224
+ }
+ },
+ {
+ "id": "txReview.tokenDetails.title",
+ "defaultMessage": "!!!Asset Details",
+ "file": "src/features/ReviewTx/common/hooks/useStrings.tsx",
+ "start": {
+ "line": 135,
+ "column": 21,
+ "index": 4247
+ },
+ "end": {
+ "line": 138,
"column": 3,
- "index": 2552
+ "index": 4331
}
}
]
\ No newline at end of file
diff --git a/apps/wallet-mobile/translations/messages/src/features/Send/useCases/ListAmountsToSend/ListAmountsToSendScreen.json b/apps/wallet-mobile/translations/messages/src/features/Send/useCases/ListAmountsToSend/ListAmountsToSendScreen.json
index 0c575d3101..f08697a91d 100644
--- a/apps/wallet-mobile/translations/messages/src/features/Send/useCases/ListAmountsToSend/ListAmountsToSendScreen.json
+++ b/apps/wallet-mobile/translations/messages/src/features/Send/useCases/ListAmountsToSend/ListAmountsToSendScreen.json
@@ -4,14 +4,14 @@
"defaultMessage": "!!!Add token",
"file": "src/features/Send/useCases/ListAmountsToSend/ListAmountsToSendScreen.tsx",
"start": {
- "line": 229,
+ "line": 226,
"column": 12,
- "index": 7330
+ "index": 7420
},
"end": {
- "line": 232,
+ "line": 229,
"column": 3,
- "index": 7407
+ "index": 7497
}
}
]
\ No newline at end of file
diff --git a/apps/wallet-mobile/translations/messages/src/features/Settings/ManageCollateral/strings.json b/apps/wallet-mobile/translations/messages/src/features/Settings/ManageCollateral/strings.json
index 91042d5e7a..c1bf1a5728 100644
--- a/apps/wallet-mobile/translations/messages/src/features/Settings/ManageCollateral/strings.json
+++ b/apps/wallet-mobile/translations/messages/src/features/Settings/ManageCollateral/strings.json
@@ -4,14 +4,14 @@
"defaultMessage": "!!!Locked as collateral",
"file": "src/features/Settings/ManageCollateral/strings.ts",
"start": {
- "line": 17,
+ "line": 23,
"column": 22,
- "index": 720
+ "index": 1270
},
"end": {
- "line": 20,
+ "line": 26,
"column": 3,
- "index": 833
+ "index": 1383
}
},
{
@@ -19,14 +19,14 @@
"defaultMessage": "!!!If you want to return the amount locked as collateral to your balance press the remove icon",
"file": "src/features/Settings/ManageCollateral/strings.ts",
"start": {
- "line": 21,
+ "line": 27,
"column": 20,
- "index": 855
+ "index": 1405
},
"end": {
- "line": 24,
+ "line": 30,
"column": 3,
- "index": 1037
+ "index": 1587
}
},
{
@@ -34,14 +34,14 @@
"defaultMessage": "!!!Your collateral is gone, please generate new collateral",
"file": "src/features/Settings/ManageCollateral/strings.ts",
"start": {
- "line": 25,
+ "line": 31,
"column": 19,
- "index": 1058
+ "index": 1608
},
"end": {
- "line": 28,
+ "line": 34,
"column": 3,
- "index": 1203
+ "index": 1753
}
},
{
@@ -49,14 +49,14 @@
"defaultMessage": "!!!Generate collateral",
"file": "src/features/Settings/ManageCollateral/strings.ts",
"start": {
- "line": 29,
+ "line": 35,
"column": 22,
- "index": 1227
+ "index": 1777
},
"end": {
- "line": 32,
+ "line": 38,
"column": 3,
- "index": 1339
+ "index": 1889
}
},
{
@@ -64,14 +64,14 @@
"defaultMessage": "!!!Not enough funds",
"file": "src/features/Settings/ManageCollateral/strings.ts",
"start": {
- "line": 33,
+ "line": 39,
"column": 28,
- "index": 1369
+ "index": 1919
},
"end": {
- "line": 36,
+ "line": 42,
"column": 3,
- "index": 1484
+ "index": 2034
}
},
{
@@ -79,14 +79,14 @@
"defaultMessage": "!!!We could not find enough funds in this wallet to create collateral.",
"file": "src/features/Settings/ManageCollateral/strings.ts",
"start": {
- "line": 37,
+ "line": 43,
"column": 30,
- "index": 1516
+ "index": 2066
},
"end": {
- "line": 40,
+ "line": 46,
"column": 3,
- "index": 1684
+ "index": 2234
}
},
{
@@ -94,14 +94,104 @@
"defaultMessage": "!!!OK",
"file": "src/features/Settings/ManageCollateral/strings.ts",
"start": {
- "line": 41,
+ "line": 47,
"column": 25,
- "index": 1711
+ "index": 2261
},
"end": {
- "line": 44,
+ "line": 50,
"column": 3,
- "index": 1809
+ "index": 2359
+ }
+ },
+ {
+ "id": "components.settings.collateral.collateralInfoModalLabel",
+ "defaultMessage": "!!!Collateral creation",
+ "file": "src/features/Settings/ManageCollateral/strings.ts",
+ "start": {
+ "line": 51,
+ "column": 28,
+ "index": 2389
+ },
+ "end": {
+ "line": 54,
+ "column": 3,
+ "index": 2507
+ }
+ },
+ {
+ "id": "components.settings.collateral.collateralInfoModalTitle",
+ "defaultMessage": "!!!What is collateral?",
+ "file": "src/features/Settings/ManageCollateral/strings.ts",
+ "start": {
+ "line": 55,
+ "column": 28,
+ "index": 2537
+ },
+ "end": {
+ "line": 58,
+ "column": 3,
+ "index": 2655
+ }
+ },
+ {
+ "id": "components.settings.collateral.collateralInfoModalText",
+ "defaultMessage": "!!!The collateral mechanism is an important feature that has been designed to ensure successful smart contract execution. It is used to guarantee that Cardano nodes are compensated for their work in case phase-2 validation fails.",
+ "file": "src/features/Settings/ManageCollateral/strings.ts",
+ "start": {
+ "line": 59,
+ "column": 27,
+ "index": 2684
+ },
+ "end": {
+ "line": 63,
+ "column": 3,
+ "index": 3014
+ }
+ },
+ {
+ "id": "components.settings.collateral.initialCollateralInfoModalTitle",
+ "defaultMessage": "!!!Collateral creation",
+ "file": "src/features/Settings/ManageCollateral/strings.ts",
+ "start": {
+ "line": 64,
+ "column": 35,
+ "index": 3051
+ },
+ "end": {
+ "line": 67,
+ "column": 3,
+ "index": 3176
+ }
+ },
+ {
+ "id": "components.settings.collateral.initialCollateralInfoModalText",
+ "defaultMessage": "!!!The collateral mechanism is designed to ensure smart contracts on Cardano execute successfully. It guarantees that nodes are compensated for their work if a contract fails during validation.",
+ "file": "src/features/Settings/ManageCollateral/strings.ts",
+ "start": {
+ "line": 68,
+ "column": 34,
+ "index": 3212
+ },
+ "end": {
+ "line": 72,
+ "column": 3,
+ "index": 3513
+ }
+ },
+ {
+ "id": "components.settings.collateral.initialCollateralInfoModalButton",
+ "defaultMessage": "!!!Add collateral",
+ "file": "src/features/Settings/ManageCollateral/strings.ts",
+ "start": {
+ "line": 73,
+ "column": 36,
+ "index": 3551
+ },
+ "end": {
+ "line": 76,
+ "column": 3,
+ "index": 3672
}
}
]
\ No newline at end of file
diff --git a/apps/wallet-mobile/translations/messages/src/features/Settings/WalletSettings/WalletSettingsScreen.json b/apps/wallet-mobile/translations/messages/src/features/Settings/WalletSettings/WalletSettingsScreen.json
index 91a15ad429..0c242a6bf8 100644
--- a/apps/wallet-mobile/translations/messages/src/features/Settings/WalletSettings/WalletSettingsScreen.json
+++ b/apps/wallet-mobile/translations/messages/src/features/Settings/WalletSettings/WalletSettingsScreen.json
@@ -4,14 +4,14 @@
"defaultMessage": "!!!General",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 214,
+ "line": 227,
"column": 11,
- "index": 6741
+ "index": 7420
},
"end": {
- "line": 217,
+ "line": 230,
"column": 3,
- "index": 6839
+ "index": 7518
}
},
{
@@ -19,14 +19,14 @@
"defaultMessage": "!!!Actions",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 218,
+ "line": 231,
"column": 11,
- "index": 6852
+ "index": 7531
},
"end": {
- "line": 221,
+ "line": 234,
"column": 3,
- "index": 6950
+ "index": 7629
}
},
{
@@ -34,14 +34,14 @@
"defaultMessage": "!!!Switch wallet",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 222,
+ "line": 235,
"column": 16,
- "index": 6968
+ "index": 7647
},
"end": {
- "line": 225,
+ "line": 238,
"column": 3,
- "index": 7077
+ "index": 7756
}
},
{
@@ -49,14 +49,14 @@
"defaultMessage": "!!!Logout",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 226,
+ "line": 239,
"column": 10,
- "index": 7089
+ "index": 7768
},
"end": {
- "line": 229,
+ "line": 242,
"column": 3,
- "index": 7185
+ "index": 7864
}
},
{
@@ -64,14 +64,14 @@
"defaultMessage": "!!!Wallet name",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 230,
+ "line": 243,
"column": 14,
- "index": 7201
+ "index": 7880
},
"end": {
- "line": 233,
+ "line": 246,
"column": 3,
- "index": 7306
+ "index": 7985
}
},
{
@@ -79,14 +79,14 @@
"defaultMessage": "!!!Security",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 234,
+ "line": 247,
"column": 12,
- "index": 7320
+ "index": 7999
},
"end": {
- "line": 237,
+ "line": 250,
"column": 3,
- "index": 7420
+ "index": 8099
}
},
{
@@ -94,14 +94,14 @@
"defaultMessage": "!!!Change spending password",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 238,
+ "line": 251,
"column": 18,
- "index": 7440
+ "index": 8119
},
"end": {
- "line": 241,
+ "line": 254,
"column": 3,
- "index": 7562
+ "index": 8241
}
},
{
@@ -109,14 +109,14 @@
"defaultMessage": "!!!Easy transaction confirmation",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 242,
+ "line": 255,
"column": 20,
- "index": 7584
+ "index": 8263
},
"end": {
- "line": 245,
+ "line": 258,
"column": 3,
- "index": 7713
+ "index": 8392
}
},
{
@@ -124,14 +124,14 @@
"defaultMessage": "!!!Skip the password and approve transactions with biometrics",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 246,
+ "line": 259,
"column": 24,
- "index": 7739
+ "index": 8418
},
"end": {
- "line": 249,
+ "line": 262,
"column": 3,
- "index": 7901
+ "index": 8580
}
},
{
@@ -139,14 +139,14 @@
"defaultMessage": "!!!Remove wallet",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 250,
+ "line": 263,
"column": 16,
- "index": 7919
+ "index": 8598
},
"end": {
- "line": 253,
+ "line": 266,
"column": 3,
- "index": 8028
+ "index": 8707
}
},
{
@@ -154,14 +154,14 @@
"defaultMessage": "!!!Collateral",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 254,
+ "line": 267,
"column": 14,
- "index": 8044
+ "index": 8723
},
"end": {
- "line": 257,
+ "line": 270,
"column": 3,
- "index": 8115
+ "index": 8794
}
},
{
@@ -169,14 +169,14 @@
"defaultMessage": "!!!Multiple addresses",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 258,
+ "line": 271,
"column": 21,
- "index": 8138
+ "index": 8817
},
"end": {
- "line": 261,
+ "line": 274,
"column": 3,
- "index": 8224
+ "index": 8903
}
},
{
@@ -184,14 +184,14 @@
"defaultMessage": "!!!Single address",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 262,
+ "line": 275,
"column": 17,
- "index": 8243
+ "index": 8922
},
"end": {
- "line": 265,
+ "line": 278,
"column": 3,
- "index": 8321
+ "index": 9000
}
},
{
@@ -199,14 +199,14 @@
"defaultMessage": "!!!By enabling this you can operate with more wallet addresses",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 266,
+ "line": 279,
"column": 25,
- "index": 8348
+ "index": 9027
},
"end": {
- "line": 269,
+ "line": 282,
"column": 3,
- "index": 8479
+ "index": 9158
}
},
{
@@ -214,14 +214,14 @@
"defaultMessage": "!!!Network:",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 271,
+ "line": 284,
"column": 11,
- "index": 8540
+ "index": 9219
},
"end": {
- "line": 274,
+ "line": 287,
"column": 3,
- "index": 8606
+ "index": 9285
}
},
{
@@ -229,14 +229,14 @@
"defaultMessage": "!!!Wallet type:",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 275,
+ "line": 288,
"column": 14,
- "index": 8622
+ "index": 9301
},
"end": {
- "line": 278,
+ "line": 291,
"column": 3,
- "index": 8728
+ "index": 9407
}
},
{
@@ -244,14 +244,14 @@
"defaultMessage": "!!!Byron-era wallet",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 279,
+ "line": 292,
"column": 15,
- "index": 8745
+ "index": 9424
},
"end": {
- "line": 282,
+ "line": 295,
"column": 3,
- "index": 8856
+ "index": 9535
}
},
{
@@ -259,14 +259,14 @@
"defaultMessage": "!!!Shelley-era wallet",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 283,
+ "line": 296,
"column": 17,
- "index": 8875
+ "index": 9554
},
"end": {
- "line": 286,
+ "line": 299,
"column": 3,
- "index": 8990
+ "index": 9669
}
},
{
@@ -274,14 +274,14 @@
"defaultMessage": "!!!Unknown Wallet Type",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 287,
+ "line": 300,
"column": 21,
- "index": 9013
+ "index": 9692
},
"end": {
- "line": 290,
+ "line": 303,
"column": 3,
- "index": 9133
+ "index": 9812
}
},
{
@@ -289,14 +289,14 @@
"defaultMessage": "!!!About",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 291,
+ "line": 304,
"column": 9,
- "index": 9144
+ "index": 9823
},
"end": {
- "line": 294,
+ "line": 307,
"column": 3,
- "index": 9238
+ "index": 9917
}
},
{
@@ -304,14 +304,14 @@
"defaultMessage": "!!!Resync",
"file": "src/features/Settings/WalletSettings/WalletSettingsScreen.tsx",
"start": {
- "line": 295,
+ "line": 308,
"column": 10,
- "index": 9250
+ "index": 9929
},
"end": {
- "line": 298,
+ "line": 311,
"column": 3,
- "index": 9352
+ "index": 10031
}
}
]
\ No newline at end of file