Skip to content

Commit

Permalink
Utxo Manager (#2233)
Browse files Browse the repository at this point in the history
  • Loading branch information
stackchain committed Nov 25, 2022
1 parent 9e2978a commit 6d33ede
Show file tree
Hide file tree
Showing 13 changed files with 224 additions and 196 deletions.
8 changes: 4 additions & 4 deletions src/Dashboard/Dashboard.tsx
Expand Up @@ -6,7 +6,7 @@ import {defineMessages, useIntl} from 'react-intl'
import {ActivityIndicator, RefreshControl, ScrollView, StyleSheet, View, ViewProps} from 'react-native'

import {Banner, Button, Modal, StatusBar} from '../components'
import {useBalances, useIsOnline, useUtxos} from '../hooks'
import {useBalances, useIsOnline, useSync} from '../hooks'
import globalMessages from '../i18n/global-messages'
import {getCardanoBaseConfig} from '../legacy/config'
import {getCardanoNetworkConfigById} from '../legacy/networks'
Expand All @@ -31,7 +31,7 @@ export const Dashboard = () => {
const navigateTo = useNavigateTo()

const wallet = useSelectedWallet()
const {isLoading: isFetchingUtxos, refetch: refetchUtxos} = useUtxos(wallet)
const {isLoading: isSyncing, sync} = useSync(wallet)
const isOnline = useIsOnline(wallet)

const balances = useBalances(wallet)
Expand All @@ -47,15 +47,15 @@ export const Dashboard = () => {
<StatusBar type="dark" />

<View style={styles.container}>
{isOnline && error && <SyncErrorBanner showRefresh={!(isLoading || isFetchingUtxos)} />}
{isOnline && error && <SyncErrorBanner showRefresh={!(isLoading || isSyncing)} />}

<ScrollView
style={styles.scrollView}
contentContainerStyle={styles.contentContainer}
refreshControl={
<RefreshControl
onRefresh={() => {
refetchUtxos()
sync()
refetchStakingInfo()
}}
refreshing={false}
Expand Down
6 changes: 2 additions & 4 deletions src/Dashboard/StakePoolInfos.tsx
Expand Up @@ -54,11 +54,9 @@ export const useStakingInfo = (
})

React.useEffect(() => {
const unsubscribe = wallet.subscribeOnTxHistoryUpdate(() => {
setTimeout(() => query.refetch(), 1000)
}) // refetch on new transactions
const unsubscribe = wallet.subscribe(({type}) => type === 'utxos' && query.refetch())

return () => unsubscribe()
return () => unsubscribe?.()
}, [query, wallet])

return {
Expand Down
6 changes: 3 additions & 3 deletions src/Send/SendScreen/ErrorBanners.tsx
@@ -1,7 +1,7 @@
import React from 'react'

import {Banner, ClickableBanner} from '../../components'
import {useHasPendingTx, useUtxos} from '../../hooks'
import {useHasPendingTx, useSync} from '../../hooks'
import {useSelectedWallet} from '../../SelectedWallet'
import {useStrings} from './strings'

Expand All @@ -10,10 +10,10 @@ export const ErrorBanners = () => {

const wallet = useSelectedWallet()
const hasPendingTx = useHasPendingTx(wallet)
const {isLoading, refetch, error} = useUtxos(wallet)
const {isLoading, error, sync} = useSync(wallet)

if (error != null && !isLoading) {
return <ClickableBanner error onPress={() => refetch()} text={strings.errorBannerNetworkError} />
return <ClickableBanner error onPress={() => sync()} text={strings.errorBannerNetworkError} />
} else if (hasPendingTx) {
return <Banner error text={strings.errorBannerPendingOutgoingTransaction} />
} else {
Expand Down
5 changes: 1 addition & 4 deletions src/Send/SendScreen/SendScreen.tsx
Expand Up @@ -37,7 +37,7 @@ export const SendScreen = () => {
const wallet = useSelectedWallet()
const balances = useBalances(wallet)

const {utxos, isLoading, error} = useUtxos(wallet)
const utxos = useUtxos(wallet)
const hasPendingTx = useHasPendingTx(wallet)
const isOnline = useIsOnline(wallet)

Expand Down Expand Up @@ -67,9 +67,6 @@ export const SendScreen = () => {
const isValid =
isOnline &&
!hasPendingTx &&
!isLoading &&
error == null &&
utxos &&
_.isEmpty(addressErrors) &&
_.isEmpty(amountErrors) &&
_.isEmpty(balanceErrors) &&
Expand Down
3 changes: 1 addition & 2 deletions src/TxHistory/LockedDeposit.tsx
Expand Up @@ -7,7 +7,6 @@ import {Boundary, Spacer, Text} from '../components'
import {useLockedAmount, useTokenInfo} from '../hooks'
import globalMessages from '../i18n/global-messages'
import {formatTokenWithText, formatTokenWithTextWhenHidden} from '../legacy/format'
import {isEmptyString} from '../legacy/utils'
import {useSelectedWallet} from '../SelectedWallet'
import {Token} from '../yoroi-wallets/types'

Expand Down Expand Up @@ -38,7 +37,7 @@ export const LockedDeposit = ({privacyMode}: Props) => {
const LockedAmount = ({tokenInfo}: {tokenInfo: Token}) => {
const wallet = useSelectedWallet()
const lockedAmount = useLockedAmount({wallet})
const amount = formatTokenWithText(new BigNumber(!isEmptyString(lockedAmount) ? lockedAmount : 0), tokenInfo)
const amount = formatTokenWithText(new BigNumber(lockedAmount), tokenInfo)

return <FormattedAmount amount={amount} />
}
Expand Down
1 change: 0 additions & 1 deletion src/TxHistory/TxHistory.stories.tsx
Expand Up @@ -23,7 +23,6 @@ storiesOf('V2/TxHistory', module)
const wallet = {
...mocks.wallet,
fetchCurrentPrice: mocks.fetchCurrentPrice.error,
fetchUTXOs: () => Promise.reject(new Error('fetchUTXOs failed')),
}

return (
Expand Down
53 changes: 10 additions & 43 deletions src/hooks/index.ts
@@ -1,6 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import AsyncStorage, {AsyncStorageStatic} from '@react-native-async-storage/async-storage'
import {useFocusEffect} from '@react-navigation/native'
import BigNumber from 'bignumber.js'
import {delay} from 'bluebird'
import {mapValues} from 'lodash'
Expand Down Expand Up @@ -110,35 +109,10 @@ export const useReceiveAddresses = (wallet: YoroiWallet) => {
return wallet.receiveAddresses
}

export const useUtxos = (
wallet: YoroiWallet,
options?: UseQueryOptions<Array<RawUtxo>, Error, Array<RawUtxo>, [string, 'utxos']>,
) => {
const {refetch, ...query} = useQuery({
...options,
refetchInterval: 20000,
queryKey: [wallet.id, 'utxos'],
queryFn: () => wallet.fetchUTXOs(),
})
export const useUtxos = (wallet: YoroiWallet) => {
useWallet(wallet, 'utxos')

const isOnline = useIsOnline(wallet)
React.useEffect(() => {
isOnline && refetch()
}, [isOnline, refetch])

React.useEffect(() => wallet.subscribe(() => refetch()), [refetch, wallet])

useFocusEffect(
React.useCallback(() => {
refetch()
}, [refetch]),
)

return {
...query,
refetch,
utxos: query.data,
}
return wallet.utxos
}

/**
Expand All @@ -152,25 +126,18 @@ export const useLockedAmount = (
{wallet}: {wallet: YoroiWallet},
options?: UseQueryOptions<Quantity, Error, Quantity, [string, 'lockedAmount']>,
) => {
const queryClient = useQueryClient()
const query = useQuery({
...options,
suspense: true,
queryKey: [wallet.id, 'lockedAmount'],
queryFn: () =>
wallet
.fetchUTXOs()
.then((utxos) => calcLockedDeposit(utxos, wallet.networkId))
.then((amount) => amount.toString() as Quantity),
queryFn: () => calcLockedDeposit(wallet.utxos, wallet.networkId).then((amount) => amount.toString() as Quantity),
})

React.useEffect(() => {
const unsubscribe = wallet.subscribeOnTxHistoryUpdate(() =>
queryClient.invalidateQueries([wallet.id, 'lockedAmount']),
)
const unsubscribe = wallet.subscribe(({type}) => type === 'utxos' && query.refetch())

return () => unsubscribe()
}, [queryClient, wallet])
return () => unsubscribe?.()
}, [query, wallet])

if (query.data == null) throw new Error('invalid state')

Expand Down Expand Up @@ -561,11 +528,12 @@ const getTransactionInfos = (wallet: YoroiWallet) =>
export const useTransactionInfos = (wallet: YoroiWallet) => {
const [transactionInfos, setTransactionInfos] = React.useState(() => getTransactionInfos(wallet))
React.useEffect(() => {
wallet.subscribe((event) => {
const unsubscribe = wallet.subscribe((event) => {
if (event.type !== 'transactions') return

setTransactionInfos(getTransactionInfos(wallet))
})
return () => unsubscribe?.()
}, [wallet])

return transactionInfos
Expand Down Expand Up @@ -870,8 +838,7 @@ export const useExchangeRate = ({
}

export const useBalances = (wallet: YoroiWallet): YoroiAmounts => {
const {utxos} = useUtxos(wallet, {suspense: true})
if (utxos == null) throw new Error('invalid state')
const utxos = useUtxos(wallet)

const primaryTokenId = wallet.defaultAsset.identifier

Expand Down

0 comments on commit 6d33ede

Please sign in to comment.