From 94f6bfef65d890790c118fbb469cae700182116c Mon Sep 17 00:00:00 2001 From: Michal S Date: Wed, 30 Oct 2024 20:25:25 +0000 Subject: [PATCH 1/4] feat(wallet-mobile): Rewards updated notification (#3715) --- .../Notifications/useCases/common/hooks.ts | 2 + .../useCases/common/notification-manager.ts | 2 + .../useCases/common/notifications.ts | 8 ++ .../common/rewards-updated-notification.ts | 120 ++++++++++++++++++ .../Notifications/useCases/common/storage.ts | 11 ++ .../transaction-received-notification.ts | 4 +- packages/types/src/notifications/manager.ts | 1 + 7 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 apps/wallet-mobile/src/features/Notifications/useCases/common/rewards-updated-notification.ts diff --git a/apps/wallet-mobile/src/features/Notifications/useCases/common/hooks.ts b/apps/wallet-mobile/src/features/Notifications/useCases/common/hooks.ts index 21e427fe42..b47fc503a9 100644 --- a/apps/wallet-mobile/src/features/Notifications/useCases/common/hooks.ts +++ b/apps/wallet-mobile/src/features/Notifications/useCases/common/hooks.ts @@ -6,6 +6,7 @@ import {PermissionsAndroid} from 'react-native' import {notificationManager} from './notification-manager' import {parseNotificationId} from './notifications' import {usePrimaryTokenPriceChangedNotification} from './primary-token-price-changed-notification' +import {useRewardsUpdatedNotifications} from './rewards-updated-notification' import {useTransactionReceivedNotifications} from './transaction-received-notification' let initialized = false @@ -41,4 +42,5 @@ export const useInitNotifications = ({enabled}: {enabled: boolean}) => { React.useEffect(() => (enabled ? init() : undefined), [enabled]) useTransactionReceivedNotifications({enabled}) usePrimaryTokenPriceChangedNotification({enabled}) + useRewardsUpdatedNotifications({enabled}) } diff --git a/apps/wallet-mobile/src/features/Notifications/useCases/common/notification-manager.ts b/apps/wallet-mobile/src/features/Notifications/useCases/common/notification-manager.ts index c18f248e2c..2bcc1937d8 100644 --- a/apps/wallet-mobile/src/features/Notifications/useCases/common/notification-manager.ts +++ b/apps/wallet-mobile/src/features/Notifications/useCases/common/notification-manager.ts @@ -4,6 +4,7 @@ import {Notifications} from '@yoroi/types' import {displayNotificationEvent} from './notifications' import {primaryTokenPriceChangedSubject} from './primary-token-price-changed-notification' +import {rewardsUpdatedSubject} from './rewards-updated-notification' import {transactionReceivedSubject} from './transaction-received-notification' const appStorage = mountAsyncStorage({path: '/'}) @@ -16,5 +17,6 @@ export const notificationManager = notificationManagerMaker({ subscriptions: { [Notifications.Trigger.TransactionReceived]: transactionReceivedSubject, [Notifications.Trigger.PrimaryTokenPriceChanged]: primaryTokenPriceChangedSubject, + [Notifications.Trigger.RewardsUpdated]: rewardsUpdatedSubject, }, }) diff --git a/apps/wallet-mobile/src/features/Notifications/useCases/common/notifications.ts b/apps/wallet-mobile/src/features/Notifications/useCases/common/notifications.ts index 11356dba56..5ddca12e36 100644 --- a/apps/wallet-mobile/src/features/Notifications/useCases/common/notifications.ts +++ b/apps/wallet-mobile/src/features/Notifications/useCases/common/notifications.ts @@ -36,6 +36,14 @@ export const displayNotificationEvent = async (notificationEvent: NotificationTy id: notificationEvent.id, }) } + + if (notificationEvent.trigger === NotificationTypes.Trigger.RewardsUpdated) { + sendNotification({ + title: 'Rewards updated', + body: 'Your rewards have been updated', + id: notificationEvent.id, + }) + } } const sendNotification = (options: {title: string; body: string; id: number}) => { diff --git a/apps/wallet-mobile/src/features/Notifications/useCases/common/rewards-updated-notification.ts b/apps/wallet-mobile/src/features/Notifications/useCases/common/rewards-updated-notification.ts new file mode 100644 index 0000000000..b4d58eaa34 --- /dev/null +++ b/apps/wallet-mobile/src/features/Notifications/useCases/common/rewards-updated-notification.ts @@ -0,0 +1,120 @@ +import {mountAsyncStorage, useAsyncStorage} from '@yoroi/common' +import {App, Notifications as NotificationTypes} from '@yoroi/types' +import * as BackgroundFetch from 'expo-background-fetch' +import * as TaskManager from 'expo-task-manager' +import * as React from 'react' +import {Subject} from 'rxjs' + +import {useWalletManager} from '../../../WalletManager/context/WalletManagerProvider' +import {walletManager} from '../../../WalletManager/wallet-manager' +import {notificationManager} from './notification-manager' +import {generateNotificationId} from './notifications' +import {buildProcessedNotificationsStorage} from './storage' + +const backgroundTaskId = 'yoroi-rewards-updated-notifications-background-fetch' +const storageKey = 'rewards-updated-notification-history' +const backgroundSyncInMinutes = 60 * 10 + +// Check is needed for hot reloading, as task can not be defined twice +if (!TaskManager.isTaskDefined(backgroundTaskId)) { + const appStorage = mountAsyncStorage({path: '/'}) + TaskManager.defineTask(backgroundTaskId, async () => { + await syncAllWallets() + const notifications = await buildNotifications(appStorage) + notifications.forEach((notification) => notificationManager.events.push(notification)) + const hasNewData = notifications.length > 0 + return hasNewData ? BackgroundFetch.BackgroundFetchResult.NewData : BackgroundFetch.BackgroundFetchResult.NoData + }) +} + +export const rewardsUpdatedSubject = new Subject() + +const registerBackgroundFetchAsync = () => { + return BackgroundFetch.registerTaskAsync(backgroundTaskId, { + minimumInterval: backgroundSyncInMinutes, + stopOnTerminate: false, + startOnBoot: true, + }) +} + +const buildNotifications = async (appStorage: App.Storage) => { + const walletIds = [...walletManager.walletMetas.keys()] + const notifications: NotificationTypes.RewardsUpdatedEvent[] = [] + + for (const walletId of walletIds) { + const wallet = walletManager.getWalletById(walletId) + if (!wallet) continue + + const fullStorageKey = `wallet/${walletId}/${wallet.networkManager.network}/${storageKey}/` as const + const storage = buildProcessedNotificationsStorage(appStorage.join(fullStorageKey)) + const stakingInfo = await wallet.getStakingInfo() + if (stakingInfo.status !== 'staked') continue + + const {rewards} = stakingInfo + + if (await storage.isEmpty()) { + await storage.setValues([rewards]) + } + + const [latestReward] = await storage.getValues() + + if (latestReward === rewards) continue + + await storage.setValues([rewards]) + notifications.push(createRewardsUpdatedNotification()) + } + + return notifications +} + +const unregisterBackgroundFetchAsync = () => { + return BackgroundFetch.unregisterTaskAsync(backgroundTaskId) +} + +const syncAllWallets = async () => { + const ids = [...walletManager.walletMetas.keys()] + for (const id of ids) { + const wallet = walletManager.getWalletById(id) + if (!wallet) continue + await wallet.sync({}) + } +} + +const createRewardsUpdatedNotification = () => { + return { + id: generateNotificationId(), + date: new Date().toISOString(), + isRead: false, + trigger: NotificationTypes.Trigger.RewardsUpdated, + } as const +} + +export const useRewardsUpdatedNotifications = ({enabled}: {enabled: boolean}) => { + const {walletManager} = useWalletManager() + const asyncStorage = useAsyncStorage() + + React.useEffect(() => { + if (!enabled) return + registerBackgroundFetchAsync() + return () => { + unregisterBackgroundFetchAsync() + } + }, [enabled]) + + React.useEffect(() => { + if (!enabled) return + const subscription = walletManager.syncWalletInfos$.subscribe(async (status) => { + const walletInfos = Array.from(status.values()) + const walletsDoneSyncing = walletInfos.filter((info) => info.status === 'done') + const areAllDone = walletsDoneSyncing.length === walletInfos.length + if (!areAllDone) return + + const notifications = await buildNotifications(asyncStorage) + notifications.forEach((notification) => rewardsUpdatedSubject.next(notification)) + }) + + return () => { + subscription.unsubscribe() + } + }, [walletManager, asyncStorage, enabled]) +} diff --git a/apps/wallet-mobile/src/features/Notifications/useCases/common/storage.ts b/apps/wallet-mobile/src/features/Notifications/useCases/common/storage.ts index 3cfee7308a..c880a05400 100644 --- a/apps/wallet-mobile/src/features/Notifications/useCases/common/storage.ts +++ b/apps/wallet-mobile/src/features/Notifications/useCases/common/storage.ts @@ -11,6 +11,10 @@ export const buildProcessedNotificationsStorage = (storage: App.Storage) => { await storage.setItem('processed', newProcessed) } + const setValues = async (values: string[]) => { + await storage.setItem('processed', values) + } + const includes = async (value: string) => { const processed = await getValues() return processed.includes(value) @@ -20,10 +24,17 @@ export const buildProcessedNotificationsStorage = (storage: App.Storage) => { await storage.setItem('processed', []) } + const isEmpty = async () => { + const processed = await getValues() + return processed.length === 0 + } + return { getValues, addValues, includes, clear, + setValues, + isEmpty, } } diff --git a/apps/wallet-mobile/src/features/Notifications/useCases/common/transaction-received-notification.ts b/apps/wallet-mobile/src/features/Notifications/useCases/common/transaction-received-notification.ts index dcd4bab540..08bc87a206 100644 --- a/apps/wallet-mobile/src/features/Notifications/useCases/common/transaction-received-notification.ts +++ b/apps/wallet-mobile/src/features/Notifications/useCases/common/transaction-received-notification.ts @@ -57,7 +57,9 @@ const buildNotifications = async (appStorage: App.Storage) => { for (const walletId of walletIds) { const wallet = walletManager.getWalletById(walletId) if (!wallet) continue - const storage = buildProcessedNotificationsStorage(appStorage.join(`wallet/${walletId}/${storageKey}/`)) + + const fullStorageKey = `wallet/${walletId}/${wallet.networkManager.network}/${storageKey}/` as const + const storage = buildProcessedNotificationsStorage(appStorage.join(fullStorageKey)) const processed = await storage.getValues() const allTxIds = getTxIds(wallet) diff --git a/packages/types/src/notifications/manager.ts b/packages/types/src/notifications/manager.ts index 21766d7be0..2f5669a51b 100644 --- a/packages/types/src/notifications/manager.ts +++ b/packages/types/src/notifications/manager.ts @@ -48,6 +48,7 @@ export type NotificationGroup = 'transaction-history' | 'portfolio' export type NotificationEvent = | NotificationTransactionReceivedEvent | NotificationPrimaryTokenPriceChangedEvent + | NotificationRewardsUpdatedEvent type NotificationEventId = number From 705ba78f5fddc4557031d7f117c74c51da807811 Mon Sep 17 00:00:00 2001 From: banklesss <105349292+banklesss@users.noreply.github.com> Date: Thu, 31 Oct 2024 16:36:29 +0100 Subject: [PATCH 2/4] feature(wallet-mobile): new transaction for discovery (dapps) (#3717) --- .../features/Discover/DiscoverNavigator.tsx | 7 - .../Discover/common/useNavigateTo.tsx | 2 - .../ReviewTransaction.stories.tsx | 28 - .../ReviewTransaction/ReviewTransaction.tsx | 494 ------------------ .../Discover/useDappConnectorManager.ts | 118 ++++- .../common/hooks/useFormattedMetadata.tsx | 62 ++- .../ReviewTx/common/hooks/useOnConfirm.tsx | 10 +- .../ReviewTx/common/hooks/useSignTx.tsx | 69 --- .../ReviewTx/common/hooks/useTxBody.tsx | 12 +- .../ReviewTxScreen/ReviewTxScreen.tsx | 33 +- apps/wallet-mobile/src/kernel/navigation.tsx | 3 +- 11 files changed, 199 insertions(+), 639 deletions(-) delete mode 100644 apps/wallet-mobile/src/features/Discover/useCases/ReviewTransaction/ReviewTransaction.stories.tsx delete mode 100644 apps/wallet-mobile/src/features/Discover/useCases/ReviewTransaction/ReviewTransaction.tsx delete mode 100644 apps/wallet-mobile/src/features/ReviewTx/common/hooks/useSignTx.tsx diff --git a/apps/wallet-mobile/src/features/Discover/DiscoverNavigator.tsx b/apps/wallet-mobile/src/features/Discover/DiscoverNavigator.tsx index 1b16ebd52f..478fee15f2 100644 --- a/apps/wallet-mobile/src/features/Discover/DiscoverNavigator.tsx +++ b/apps/wallet-mobile/src/features/Discover/DiscoverNavigator.tsx @@ -10,7 +10,6 @@ import {defaultStackNavigationOptions, DiscoverRoutes} from '../../kernel/naviga import {NetworkTag} from '../Settings/useCases/changeAppSettings/ChangeNetwork/NetworkTag' import {BrowserNavigator} from './BrowserNavigator' import {useStrings} from './common/useStrings' -import {ReviewTransaction} from './useCases/ReviewTransaction/ReviewTransaction' import {ListSkeleton} from './useCases/SelectDappFromList/ListSkeleton' import {SelectDappFromListScreen} from './useCases/SelectDappFromList/SelectDappFromListScreen' import {useDappConnectorManager} from './useDappConnectorManager' @@ -45,12 +44,6 @@ export const DiscoverNavigator = () => { - - ) diff --git a/apps/wallet-mobile/src/features/Discover/common/useNavigateTo.tsx b/apps/wallet-mobile/src/features/Discover/common/useNavigateTo.tsx index 3542dbc6cd..7d978861fb 100644 --- a/apps/wallet-mobile/src/features/Discover/common/useNavigateTo.tsx +++ b/apps/wallet-mobile/src/features/Discover/common/useNavigateTo.tsx @@ -2,7 +2,6 @@ import {NavigationProp, useNavigation} from '@react-navigation/native' import * as React from 'react' import {DiscoverRoutes} from '../../../kernel/navigation' -import {ReviewTransactionParams} from '../useCases/ReviewTransaction/ReviewTransaction' export const useNavigateTo = () => { const navigation = useNavigation>() @@ -12,6 +11,5 @@ export const useNavigateTo = () => { searchDappInBrowser: () => navigation.navigate('discover-browser', {screen: 'discover-search-dapp-in-browser'}), selectDappFromList: () => navigation.navigate('discover-select-dapp-from-list'), browseDapp: () => navigation.navigate('discover-browser', {screen: 'discover-browse-dapp'}), - reviewTransaction: (params: ReviewTransactionParams) => navigation.navigate('discover-review-tx', params), } as const).current } diff --git a/apps/wallet-mobile/src/features/Discover/useCases/ReviewTransaction/ReviewTransaction.stories.tsx b/apps/wallet-mobile/src/features/Discover/useCases/ReviewTransaction/ReviewTransaction.stories.tsx deleted file mode 100644 index d4f79e39b9..0000000000 --- a/apps/wallet-mobile/src/features/Discover/useCases/ReviewTransaction/ReviewTransaction.stories.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import {action} from '@storybook/addon-actions' -import {storiesOf} from '@storybook/react-native' -import * as React from 'react' - -import {RouteProvider} from '../../../../../.storybook' -import {WalletManagerProviderMock} from '../../../../yoroi-wallets/mocks/WalletManagerProviderMock' -import {BrowserProvider} from '../../common/BrowserProvider' -import {ReviewTransaction, ReviewTransactionParams} from './ReviewTransaction' - -storiesOf('Discover ReviewTransaction', module) - .addDecorator((story) => ( - - - {story()} - - - )) - .add('initial', () => ) - -const getParams = (): ReviewTransactionParams => ({ - cbor, - isHW: false, - onCancel: action('onCancel'), - onConfirm: action('onConfirm'), -}) - -const cbor = - '84a60081825820cda06bbb18f65cf41b882bb5540a90c9b50b83ba6cbea0661b4845bb95bbb6f6020181825839017ef00ee3672330155382a2857573868af466b88aa8c4081f45583e1784d958399bcce03402fd853d43a4e7366f2018932e5aff4eea904693821a0026918ba1581ca0028f350aaabe0545fdcb56b039bfb08e4bb4d8c4d7c3c7d481c235a145484f534b591a01036640021a0007de900b5820d6ce04742d48d98691d07d67707c2d53a714d113dde67fdc259224a931f31e270d81825820caec92c836b10281c35a3a9b13f732686cf8ddccb4c75c9aef42a1324da21975010e81581c7ef00ee3672330155382a2857573868af466b88aa8c4081f45583e17a3038159152d59152a010000323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323223232323232322232323232323232323232533355333573460d000226464646424446600200a0086eb4d5d09aba2003355333573460d060da0022660a06eb4d5d098360009bad357426ae88c1b000458c1b88894ccd5cd18358008b0a999ab9a337100029000099801983500118350008991982a19b8400300133708004002660ce0040026ea8d5d080098350010a999ab9a306700113212223002004375a6ae84c1a800854ccd5cd18330008220b099180e1a9a805030911111111111299a999aa983583601892999ab9a3371e01c002260c80020c400840d20c2a020426038660946010002660946603a666aa60b40c06a0340c26a0340c4666aa60b40c044a66a6a0044444a66a6605060a4030008260ba0060b642660c200200420020ba60546a0140c2660366660486a01e0c26a01e0c460460246660486a01e0c26a01e0c466604c6a0120886a01e0c26a01e0c4660946008a0226020a00a4426464646464646046660a2601e00e660a2603e032660a2602ea018660a26016a030660a26a01044666ae68cdc499b8200248008cdc1240000020be0cc660a26a0104426ae68cdc419b8200248008cdc1011000998289982899814982980c98298029982899827981d00c981d0029982899827981700c98170029982899827980e00c980e0029982899827980e80c980e802a99a980f80c88020a99a80202e031998289a9980f1a804111919191982d99b8400300133708004002660dc00400266e0808c008cdc099b8202200133704004044660ac60540329001112999ab9a3370e00a0042660760440020bc66048660446a00c0d26660560040026a6a6603c010660ac66605a6a0200960040029001111982c19b84002001330583370a0040020020d0660446a0200966660566a02c0d06a02c0d26a6603c660ac6054032900100438435014068350130663027002301b00135001063533553353500b22350022222222222223333500d206620662066233355306f070035235001225335330470020041306a00306800d2135001223500122223501222350022222222222223335530700762235002222253353303e01800413307a006005100507300a16162215335001133052300a00235002204a2216306a00137540144666aa60b80ba604a04c400266aa60b00ba46a00244446a0084466a0044a666ae68cdc78048008a999a80282d102d90a99a9981a0009a80803390a99a9999999aba40012325333573460e060ea0022646666aae7c00481848cccd55cf9aba2002253353039357420064260c82460020040c240c40d60d460e80020bc6ea8008817881788178817819c84cc140d4004800522010f4d7565736c69537761705f76322e320005c05b061206230273500705e13306822533500105922132533553353035303735003062215335007213304a00200105615335006205605c15335333049034350030613500922200113305e30073500306200110011001300400130313500505c30513500304025333535001203f16216215335330290013500505c21533533333335748002464a666ae68c194c1a80044c8cccd55cf800902b11999aab9f35744004464a66a6666666ae900048c94ccd5cd183598380008991999aab9f001205c23233335573e00240bc4646666aae7c00481808c8cccd55cf80090311191999aab9f001206423233335573e00240cc4646666aae7c00481a08c8cccd55cf800903511999aab9f35744004464a66aa66aa66aa66aa66aa66aa66aa66a6666666ae900048c94ccd5cd183f9842008008991999aab9f001207023233335573e00240e446666aae7cd5d10011299a98241aba1005213253353333333574800246464a666ae68c224040044cccd55cf984680801103c91999aab9f35744611c02006464a66a6666666ae900048c8c94ccd5cd18480080089999aab9f309301002207f23233335573e0024102024646666aae7c004820c048cccd55cf9aba200225335305a3574261320201042a66a60b66ae84018854cd4c170d5d0802909844009998410080180100084280842008418090420084680846009aba200208a0135744612802006110022a666ae68c23c040044cccd55cf984980801103f91999aab9f357446128020064a66a60aa6ae84c2540401084c20804c208040041fc82000422404220041f4c24c04004dd5001103e103e103e103e0428090983e983e80083d1aba1308f01004207a083010820115333573461140200226666aae7cc234040088c1e81e481e4208041dcc23404004dd5001103b103b103b103b03f90983b9983780180083a1aba1004072207307c07b357440040f26106020020da6ea800881b481b481b481b41d884c1b8c1bc0041ac854cd4c110d5d0808909837980100083603590a99a98221aba100f21306f300200106c06b21533530443574201a4260de60040020d80d642a66a60886ae8402c84c1bcc0080041b01ac854cd4c10cd5d080490983798010008360359099299a9999999aba4001232325333573461060200226666aae7cc218040088c1cc1e481c81ec54ccd5cd18410080089999aab9f30860100223073072207207b070308601001375400440de40de40de40de0f04260e060060020da6ae8401c1ac854cd4c10cd5d080290983798010008360359aba1011206b074073357440040e26ae880081bcd5d10010369aba200206b357440040d26ae8800819cd5d1001032983780082c9baa002205920592059205906221305a305c0010573574200640ae0c00be60d20020a66ea8008814c814c814c814c17084d4004800458588c8d4d4d401016c888818888d40048c894ccd54ccd4018854ccd4010854ccd402084c0140c44c0100c054ccd401484c0140c44c0100c011810c54ccd401c84c0100c04c00c0bc54ccd401084c0100c04c00c0bc11454ccd400c810811010454ccd400c854ccd401c84c0100c04c00c0bc54ccd401084c0100c04c00c0bc11410854ccd401884c00c0bc4c0080b854ccd400c84c00c0bc4c0080b811054cd400415016c16c15094ccd4008854ccd4018854ccd401084ccc0d00c400800458585810854ccd4014854ccd400c84ccc0cc0c0008004585858104100c100ccc198888c94ccd5cd19b87003371a002200426600866e0000d20023370066e080092080043371c002006a66a660d244a66a0020a64426a00444a666ae68cdc78012451c5817c34e5702473304f3cf676299176d3824e55b8c0bfa94830429fd001305900113006003353533533069221225333573466e2000520001615335002162215333573460d20062004266a600c0c400266e0400d200205c30323500605d00405e204321533500116221350022253350031002221616480012000350012233335001262626232533530303032001213212333001003002005350022043163330672225335002162213500222533533035002005100113300700300530303500405b0015333573460ba60c400226464642466002006004606c6ae84d5d11831801a999ab9a305e3063001132323232323232323232323232323232323232323232321233333333333300101801601401201000e00c009007005003002304e357426ae88008ccc121d710009aba10013574400466608c09040026ae84004d5d100119822bae357420026ae8800d4ccd5cd1836983900089919191909198008020012999ab9a307030750011330583304175a6ae84c1d0004c158d5d09aba230740011637546ae84d5d11839801a999ab9a306e30730011323212330010030023055357426ae88c1cc008cc0fdd69aba130720011637546ae84c1c400458dd51aba10013574400466607e0a6eb4d5d08009aba20023303e040357420026ae88008ccc0edd701d1aba100135744004666072eb80e0d5d08009aba200233038035357420026ae88008cc0d80c8d5d08009aba23063002330340303574260c40022c6ea8d5d098308008b1baa00133041300700430080043304030240033018003305d22533500104e2213303e33303d03c303f3040002500530040011303a303b001355333573460aa60b40022646090a666ae68c158c16c0044c8c8c8c8c8c8cccccccc134c10cd5d098300039bae3574200c6eb8d5d08029bae357420086eb8d5d08019bad3574200460846ae84004dd69aba1357440026ae88004d5d10009aba2001357440026ae88004d5d1182d0008b1baa3574260b20022c40026ea80048d40041408d4004814488d400888d400c88c8c8c8cc104cdc200100099b84003001330540010023370400a00666e0800c0048d4004888880c9200233035001043223355304204723500122330390023355304504a235001223303c0023335001370090003802337000029000000998028010009299a8008890008b11199aa9822022980680711a80091199aa9823824180800891a80091199a80091980ea400000203846603a0029000000998018010009119aa981f82211a800911981b001199a800919aa982182411a800911981d001181900080091199804018801000919aa982182411a800911981d0011806000800999801816001000911199aa981f02202119aa981f82211a800911981b0011817000999aa981f022111a80111299a999aa98238241981b91199805025801000980402511a8009119805001002803080189982300200182080099aa981f82211a800911981b0011982a11299a800898050019109a80111299a9980600100408911198010050020980300180200111980091299a80101f880081b909111800802111a801111a801911919a802919a80212999ab9a3371e004002006078407a466a008407a4a666ae68cdc780100080181e0a99a80190a99a8011099a801119a801119a801119a8011198190010009020119a801102011981900100091102011119a80210201112999ab9a3370e00c0062a666ae68cdc380280109980f00200082082081d0a99a800901d02011a800911110149111981e998170019981e9981700100081e01e1981511299a801108018800818911198251119a800a4000446a00444a666ae68cdc78010040998281119a800a4000446a00444a666ae68cdc78010068800898030018008980300180191a8009111111100311981411199a80181e0010009a80081d891980081101a91a80091111111111100511999999aba40012323253335734608200226666aae7cc11000880c08cccd55cf9aba2304500325335300835742608c008426066605e00206040620740722a666ae68c1000044cccd55cf9822001101811999aab9f35744608a0064a66a60106ae84c11801084c0ccc0cc0040c080c40e80e40b8c110004dd5001101690169016901681b11999999aba4001202c202c202c2302d375a004405806a46666666ae9000480ac80ac80ac80ac8c0b0dd700101a111a8009111111111111982691299a80081b9109a801112999ab9a3371e0040282607a0022600c006004930919999999800801912999ab9a3370e0040020302a666ae68cdc480100080a80b1109ab9a337100040024426ae68cdc480100091199ab9a3371200400205206000444a666ae68cdc480100088008801112999ab9a337120040022004200244666ae68cdc40010008138171109ab9a3370e00400246a0024444444400e44a666ae68cdc79a8010179a800817889ab9a3370e6a0040606a00206004646a0024466a004404a04a46a00244444444444401846a0024444008446464a666ae68c0d400403854ccd5cd181a0008980998021aba13037002153335734606600201e2c606e0026ea80048c94ccd5cd1818181a80089919091980080180118021aba135744606a00460126ae84c0d000458dd50009192999ab9a302f3034001132323232323232321233330010090070030023302375c6ae84d5d10022999ab9a3037001132122230020043574260720042a666ae68c0d80044c84888c004010dd71aba13039002153335734606a0020262c60720026ea8d5d08009aba200233300675c00a6ae84004d5d1181a001180b1aba1303300116375400266002eb9d69111981a111999aab9f0012027232330293301a30073037001300630360013004357440066ae840080a4dd58009119819111999aab9f001202523302630053574200460066ae8800809cdd6000919192999ab9a302f00113212222300400530043574260600042a666ae68c0b80044c848888c008014c054d5d098180010a999ab9a302d00113212222300100530053574260600042a666ae68c0b00044c848888c00c014dd71aba13030002163030001375400246464a666ae68cdc3a401800222444401c2a666ae68cdc3a4014002220522a666ae68cdc3a40100022646424444444660020120106eb4d5d09aba23030003375c6ae84c0bc00854ccd5cd18170008991909111111198010048041bae357426ae88c0c000cdd71aba1302f002153335734605a00226464244444446600c0120106eb8d5d09aba23030003301435742605e0042a666ae68c0b00044c848888888c01c020c050d5d098178010a999ab9a302b001132122222223005008301435742605e0042c605e0026ea80048c94ccd5cd181498170008991909198008018011bad357426ae88c0b8008c00cd5d098168008b1baa001232533357346050605a00226eb8d5d098160008b1baa0011122200111001222002110012220032122230030042213573466e3c0080048894cd4cc00c00800403c058894cd400840040348d400488cd40088004988d4004888888880208c94ccd5cd180e8008088a999ab9a301c00100a1630203754002464a666ae68c06cc0800044cc00cc018d5d0980f800998040021aba135744603e0022c6ea80048848cc00400c0088c8c94ccd5cd180d8008991998029bad35742603e0066eb4d5d08009bad357426ae88004d5d1180f0010a999ab9a301a0011300a300535742603c0042c603c0026ea8004888488ccc00401401000c8c8c94ccd5cd180c800898021bae3574260380042a666ae68c0600044c020dd71aba1301c00216301c001375400242446002006446464a666ae68c05c0044c01cc010d5d0980d8010a999ab9a301800100516301b0013754002200220184244600400644444444246666666600201201000e00c00a008006004424600200460264422444a66a00220044426600a004666aa600e01a00a0080026024442244a66a00200a44266012600800466aa600c016008002200220084424466002008006601c4422444a66a00226a006010442666a00a0126008004666aa600e01000a0080022400244004440026014444a666ae68c01c00440084cc00c004cdc30010009111111100291111110021b8148000dc3a40006e1d2002370e90021b874801955cf2ab9d23230010012233003300200200101049fd8799fd8799fd8799fd8799f581c7ef00ee3672330155382a2857573868af466b88aa8c4081f45583e17ffd8799fd8799fd8799f581c84d958399bcce03402fd853d43a4e7366f2018932e5aff4eea904693ffffffff581ca0028f350aaabe0545fdcb56b039bfb08e4bb4d8c4d7c3c7d481c23545484f534b5940401a023e6a08d879801a002e701bffffff0581840000d87980821a000f42401a1dcd6500f5f6' diff --git a/apps/wallet-mobile/src/features/Discover/useCases/ReviewTransaction/ReviewTransaction.tsx b/apps/wallet-mobile/src/features/Discover/useCases/ReviewTransaction/ReviewTransaction.tsx deleted file mode 100644 index 4b189642db..0000000000 --- a/apps/wallet-mobile/src/features/Discover/useCases/ReviewTransaction/ReviewTransaction.tsx +++ /dev/null @@ -1,494 +0,0 @@ -import {Transaction} from '@emurgo/cross-csl-core' -import {createTypeGuardFromSchema, isNonNullable, truncateString} from '@yoroi/common' -import {useTheme} from '@yoroi/theme' -import {Portfolio} from '@yoroi/types' -import {uniq} from 'lodash' -import * as React from 'react' -import {useEffect} from 'react' -import {StyleSheet, View} from 'react-native' -import {TouchableOpacity} from 'react-native-gesture-handler' -import {SafeAreaView} from 'react-native-safe-area-context' -import {useMutation, useQuery} from 'react-query' -import {z} from 'zod' - -import {Button} from '../../../../components/Button/Button' -import {CopyButton} from '../../../../components/CopyButton' -import {Icon} from '../../../../components/Icon' -import {ScrollView} from '../../../../components/ScrollView/ScrollView' -import {Spacer} from '../../../../components/Spacer/Spacer' -import {Text} from '../../../../components/Text' -import {logger} from '../../../../kernel/logger/logger' -import {useParams} from '../../../../kernel/navigation' -import {cip30LedgerExtensionMaker} from '../../../../yoroi-wallets/cardano/cip30/cip30-ledger' -import {wrappedCsl} from '../../../../yoroi-wallets/cardano/wrappedCsl' -import {formatAdaWithText, formatTokenWithText} from '../../../../yoroi-wallets/utils/format' -import {asQuantity} from '../../../../yoroi-wallets/utils/utils' -import {usePortfolioTokenInfos} from '../../../Portfolio/common/hooks/usePortfolioTokenInfos' -import {useSelectedWallet} from '../../../WalletManager/common/hooks/useSelectedWallet' -import {useConfirmHWConnectionModal} from '../../common/ConfirmHWConnectionModal' -import {isUserRejectedError, userRejectedError} from '../../common/errors' -import {usePromptRootKey} from '../../common/hooks' -import {useStrings} from '../../common/useStrings' - -export type ReviewTransactionParams = - | { - isHW: false - cbor: string - onConfirm: (rootKey: string) => void - onCancel: () => void - } - | { - isHW: true - cbor: string - partial?: boolean - onConfirm: (transaction: Transaction) => void - onCancel: () => void - } - -export const ReviewTransaction = () => { - const params = useParams(isParams) - const promptRootKey = useConnectorPromptRootKey() - const [inputsOpen, setInputsOpen] = React.useState(true) - const [outputsOpen, setOutputsOpen] = React.useState(true) - const [scrollbarShown, setScrollbarShown] = React.useState(false) - const strings = useStrings() - const formattedTX = useFormattedTransaction(params.cbor) - - const {styles} = useStyles() - - const {sign: signTxWithHW} = useSignTxWithHW() - - const handleOnConfirm = async () => { - if (!params.isHW) { - const rootKey = await promptRootKey() - params.onConfirm(rootKey) - return - } - - signTxWithHW( - {cbor: params.cbor, partial: params.partial}, - { - onSuccess: (signature) => params.onConfirm(signature), - onError: (error) => logger.error('ReviewTransaction::handleOnConfirm', {error}), - }, - ) - } - - useEffect(() => { - return () => { - params.onCancel() - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) - - return ( - - - setInputsOpen((o) => !o)}> - {`${strings.inputs} (${formattedTX.inputs.length})`} - - - {inputsOpen && } - - {inputsOpen && - formattedTX.inputs.map((input, index) => { - return ( - - ) - })} - - - - - - - - - - - {formattedTX.fee} - - - - - setOutputsOpen((o) => !o)}> - {`${strings.outputs} (${formattedTX.outputs.length})`} - - - {outputsOpen && } - - {outputsOpen && - formattedTX.outputs.map((output, index) => { - return ( - - ) - })} - - - -