Skip to content

Commit

Permalink
chore(portfolio): added clear function to balance manager
Browse files Browse the repository at this point in the history
  • Loading branch information
stackchain committed Apr 27, 2024
1 parent 43a1b99 commit e7c0c5e
Show file tree
Hide file tree
Showing 13 changed files with 265 additions and 43 deletions.
58 changes: 58 additions & 0 deletions apps/wallet-mobile/ios/Podfile.lock
Expand Up @@ -29,6 +29,12 @@ PODS:
- ExpoModulesCore
- ExpoDevice (5.4.0):
- ExpoModulesCore
- ExpoImage (1.3.0):
- ExpoModulesCore
- SDWebImage (~> 5.15.8)
- SDWebImageAVIFCoder (~> 0.10.0)
- SDWebImageSVGCoder (~> 1.7.0)
- SDWebImageWebPCoder (~> 0.11.0)
- ExpoKeepAwake (12.0.1):
- ExpoModulesCore
- ExpoModulesCore (1.2.7):
Expand All @@ -48,7 +54,28 @@ PODS:
- hermes-engine (0.71.14):
- hermes-engine/Pre-built (= 0.71.14)
- hermes-engine/Pre-built (0.71.14)
- libaom (3.0.0):
- libvmaf (>= 2.2.0)
- libavif (0.11.1):
- libavif/libaom (= 0.11.1)
- libavif/core (0.11.1)
- libavif/libaom (0.11.1):
- libaom (>= 2.0.0)
- libavif/core
- libevent (2.1.12)
- libvmaf (2.3.1)
- libwebp (1.3.2):
- libwebp/demux (= 1.3.2)
- libwebp/mux (= 1.3.2)
- libwebp/sharpyuv (= 1.3.2)
- libwebp/webp (= 1.3.2)
- libwebp/demux (1.3.2):
- libwebp/webp
- libwebp/mux (1.3.2):
- libwebp/demux
- libwebp/sharpyuv (1.3.2)
- libwebp/webp (1.3.2):
- libwebp/sharpyuv
- MMKV (1.3.3):
- MMKVCore (~> 1.3.3)
- MMKVCore (1.3.3)
Expand Down Expand Up @@ -492,6 +519,17 @@ PODS:
- React-Core
- RNSVG (13.8.0):
- React-Core
- SDWebImage (5.15.8):
- SDWebImage/Core (= 5.15.8)
- SDWebImage/Core (5.15.8)
- SDWebImageAVIFCoder (0.10.1):
- libavif (>= 0.11.0)
- SDWebImage (~> 5.10)
- SDWebImageSVGCoder (1.7.0):
- SDWebImage/Core (~> 5.6)
- SDWebImageWebPCoder (0.11.0):
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.15)
- Sentry/HybridSDK (8.9.3):
- SentryPrivate (= 8.9.3)
- SentryPrivate (8.9.3)
Expand All @@ -517,6 +555,7 @@ DEPENDENCIES:
- Expo (from `../../../node_modules/expo`)
- ExpoBlur (from `../../../node_modules/expo-blur/ios`)
- ExpoDevice (from `../../../node_modules/expo-device/ios`)
- ExpoImage (from `../../../node_modules/expo-image/ios`)
- ExpoKeepAwake (from `../../../node_modules/expo-keep-awake/ios`)
- ExpoModulesCore (from `../../../node_modules/expo-modules-core`)
- FBLazyVector (from `../../../node_modules/react-native/Libraries/FBLazyVector`)
Expand Down Expand Up @@ -592,10 +631,18 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
- fmt
- libaom
- libavif
- libevent
- libvmaf
- libwebp
- MMKV
- MMKVCore
- MultiplatformBleAdapter
- SDWebImage
- SDWebImageAVIFCoder
- SDWebImageSVGCoder
- SDWebImageWebPCoder
- Sentry
- SentryPrivate
- ZXingObjC
Expand Down Expand Up @@ -629,6 +676,8 @@ EXTERNAL SOURCES:
:path: "../../../node_modules/expo-blur/ios"
ExpoDevice:
:path: "../../../node_modules/expo-device/ios"
ExpoImage:
:path: "../../../node_modules/expo-image/ios"
ExpoKeepAwake:
:path: "../../../node_modules/expo-keep-awake/ios"
ExpoModulesCore:
Expand Down Expand Up @@ -783,14 +832,19 @@ SPEC CHECKSUMS:
Expo: b7d2843b0a0027d0ce76121a63085764355a16ed
ExpoBlur: e832d874bd94afc0645daddbd3162ec1ce172080
ExpoDevice: 1c1b0c9cad96c292c1de73948649cfd654b2b3c0
ExpoImage: bf714e0101812ccbbd1a4fdbfd34905feeefd9f5
ExpoKeepAwake: 69f5f627670d62318410392d03e0b5db0f85759a
ExpoModulesCore: 653958063a301098b541ae4dfed1ac0b98db607b
FBLazyVector: 12ea01e587c9594e7b144e1bfc86ac4d9ac28fde
FBReactNativeSpec: faca7d16c37626ca5780a87adef703817722fe61
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
hermes-engine: d7cc127932c89c53374452d6f93473f1970d8e88
libaom: 144606b1da4b5915a1054383c3a4459ccdb3c661
libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
libvmaf: 27f523f1e63c694d14d534cd0fddd2fab0ae8711
libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009
MMKV: f902fb6719da13c2ab0965233d8963a59416f911
MMKVCore: d26e4d3edd5cb8588c2569222cbd8be4231374e9
MultiplatformBleAdapter: 5a6a897b006764392f9cef785e4360f54fb9477d
Expand Down Expand Up @@ -856,6 +910,10 @@ SPEC CHECKSUMS:
RNSentry: f9e637773502a61c7b455c4ce65bc7008ce22a6e
RNShare: 859ff710211285676b0bcedd156c12437ea1d564
RNSVG: c1e76b81c76cdcd34b4e1188852892dc280eb902
SDWebImage: cb032eba469c54e0000e78bcb0a13cdde0a52798
SDWebImageAVIFCoder: 8348fef6d0ec69e129c66c9fe4d74fbfbf366112
SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c
SDWebImageWebPCoder: 295a6573c512f54ad2dd58098e64e17dcf008499
Sentry: 97161cac725da1ecbe77d1445bf8a61c1e5667f1
SentryPrivate: 9a76def09fb08f9501997b8df946e8097947b94f
Yoga: e71803b4c1fff832ccf9b92541e00f9b873119b9
Expand Down
2 changes: 1 addition & 1 deletion apps/wallet-mobile/package.json
Expand Up @@ -151,7 +151,7 @@
"expo-blur": "12.9.2",
"expo-camera": "^13.2.1",
"expo-device": "^5.4.0",
"expo-image": "^1.10.6",
"expo-image": "1.3.0",
"expo-status-bar": "~1.4.4",
"immer": "^10.0.2",
"jsc-android": "241213.1.0",
Expand Down
Expand Up @@ -21,7 +21,7 @@ export const FilterBalancesByType = <T,>({chips, selectedValue}: Props<T>) => {
return (
<View style={styles.root}>
{chips.map(({label, disabled, onPress, value}, index) => (
<>
<View key={label}>
<ChipButton
key={index}
label={label}
Expand All @@ -31,7 +31,7 @@ export const FilterBalancesByType = <T,>({chips, selectedValue}: Props<T>) => {
/>

{index != chips.length - 1 && <Spacer width={12} />}
</>
</View>
))}
</View>
)
Expand Down
15 changes: 13 additions & 2 deletions apps/wallet-mobile/src/TxHistory/AssetList/ListBalances.tsx
Expand Up @@ -44,9 +44,19 @@ export const ListBalances = (props: Props) => {
const handleOnPressFTs = React.useCallback(() => startTransition(() => setFilteringBy('fts')), [])
const handleOnPressAll = React.useCallback(() => startTransition(() => setFilteringBy('all')), [])
const chips = [
{label: strings.tokens(balances.fts.length), onPress: handleOnPressFTs, value: 'fts', disabled: isPending},
{label: strings.nfts(balances.nfts.length), onPress: handleOnPressNFTs, value: 'nfts', disabled: isPending},
{label: strings.all, onPress: handleOnPressAll, value: 'all', disabled: isPending},
{
label: strings.nfts(balances.nfts.length),
onPress: handleOnPressNFTs,
value: 'nfts',
disabled: isPending || balances.nfts.length === 0,
},
{
label: strings.tokens(balances.fts.length),
onPress: handleOnPressFTs,
value: 'fts',
disabled: isPending || balances.fts.length === 0,
},
]

return (
Expand All @@ -55,6 +65,7 @@ export const ListBalances = (props: Props) => {

<FlashList
{...props}
bounces={false}
data={balances[filteringBy]}
renderItem={({item: amount}) => (
<ExplorableAssetItem
Expand Down
Expand Up @@ -6,18 +6,23 @@ import {SafeAreaView} from 'react-native-safe-area-context'
import {Button, Spacer} from '../../../components'
import {useWalletManager} from '../../../wallet-manager/WalletManagerContext'
import {YoroiWallet} from '../../../yoroi-wallets/cardano/types'
import {NetworkId} from '../../../yoroi-wallets/types'
import {toChainSupportedNetwork} from '../common/transformers/toChainSupportedNetwork'
import { Chain } from '@yoroi/types'

export const PortfolioScreen = () => {
const navigation = useNavigation()
const manager = useWalletManager()
const [openedWalletsByNetwork] = React.useState<Map<NetworkId, Set<YoroiWallet['id']>>>(
const [openedWalletsByNetwork] = React.useState<Map<Chain.SupportedNetworks, Set<YoroiWallet['id']>>>(
manager.getOpenedWalletsByNetwork(),
)

const handleOnReset = () => {
navigation.goBack()
openedWalletsByNetwork.forEach((walletIds, network) => {
const tm = manager.getTokenManager(network)
walletIds.forEach((walletId) => {
const wallet = manager.getOpenedWalletById(walletId)
}
}
}

return (
Expand All @@ -35,12 +40,12 @@ export const PortfolioScreen = () => {

<Spacer height={16} />

{Array.from(openedWalletsByNetwork).map(([networkId, walletIds]) => {
{Array.from(openedWalletsByNetwork).map(([network, walletIds]) => {
return Array.from(walletIds).map((walletId, index) => {
const wallet = manager.getOpenedWalletById(walletId)
return (
<View key={walletId}>
{index === 0 && <Text>{toChainSupportedNetwork(networkId)}</Text>}
{index === 0 && <Text>{network}</Text>}

{wallet && (
<FlatList
Expand Down
8 changes: 4 additions & 4 deletions apps/wallet-mobile/src/wallet-manager/walletManager.ts
Expand Up @@ -101,12 +101,12 @@ export class WalletManager {
}

getOpenedWalletsByNetwork = () => {
const openedWalletsByNetwork = new Map<NetworkId, Set<YoroiWallet['id']>>()
const openedWalletsByNetwork = new Map<Chain.SupportedNetworks, Set<YoroiWallet['id']>>()

this.#openedWallets.forEach(({id, networkId}) => {
if (!openedWalletsByNetwork.has(networkId)) openedWalletsByNetwork.set(networkId, new Set())
this.#openedWallets.forEach(({id, network}) => {
if (!openedWalletsByNetwork.has(network)) openedWalletsByNetwork.set(network, new Set())

openedWalletsByNetwork.get(networkId)?.add(id)
openedWalletsByNetwork.get(network)?.add(id)
})

return openedWalletsByNetwork
Expand Down
Expand Up @@ -434,6 +434,7 @@ export const makeShelleyWallet = (constants: typeof MAINNET | typeof TESTNET | t
}

async clear() {
this.balanceManager.
await this.transactionManager.clear()
this.transactionManager.resetState()
await this.utxoManager.clear()
Expand Down
92 changes: 92 additions & 0 deletions packages/portfolio/src/balance-manager.test.ts
Expand Up @@ -44,6 +44,7 @@ describe('portfolioBalanceManagerMaker', () => {
unsubscribe: jest.fn(),
observable$: new BehaviorSubject({} as any).asObservable(),
sync: jest.fn().mockResolvedValue(new Map()),
clear: jest.fn(),
}

it('should be instantiated', () => {
Expand Down Expand Up @@ -83,6 +84,7 @@ describe('hydrate', () => {
unsubscribe: jest.fn(),
observable$: new BehaviorSubject({} as any).asObservable(),
sync: jest.fn().mockResolvedValue(new Map()),
clear: jest.fn(),
}

afterEach(() => {
Expand Down Expand Up @@ -161,6 +163,7 @@ describe('destroy', () => {
unsubscribe: jest.fn(),
observable$: tokenManagerObservable,
sync: jest.fn().mockResolvedValue(new Map()),
clear: jest.fn(),
}
const queueDestroy = jest.fn()
const observerDestroy = jest.fn()
Expand Down Expand Up @@ -236,6 +239,7 @@ describe('primary updates', () => {
unsubscribe: jest.fn(),
observable$: tokenManagerObservable.asObservable(),
sync: jest.fn().mockResolvedValue(new Map()),
clear: jest.fn(),
}

afterEach(() => {
Expand Down Expand Up @@ -386,6 +390,7 @@ describe('sync & refresh', () => {
unsubscribe: jest.fn(),
observable$: tokenManagerObservable.asObservable(),
sync: jest.fn().mockResolvedValue(new Map()),
clear: jest.fn(),
}

afterEach(() => {
Expand Down Expand Up @@ -643,3 +648,90 @@ describe('sync & refresh', () => {
}
})
})

describe('clear', () => {
const balanceStorage = observableStorageMaker(
mountMMKVStorage<Portfolio.Token.Id>({
path: '/tmp/balance/',
id: 'balance',
}),
)
const primaryBreakdownStorage = observableStorageMaker(
mountMMKVStorage<Portfolio.Token.Id>({
path: '/tmp/primary-balance-breakdown/',
id: 'primary-breakdown',
}),
)
const storage: Portfolio.Storage.Balance = portfolioBalanceStorageMaker({
balanceStorage,
primaryBreakdownStorage,
primaryTokenId,
})
const tokenManager: Portfolio.Manager.Token = {
destroy: jest.fn(),
hydrate: jest.fn(),
subscribe: jest.fn(),
unsubscribe: jest.fn(),
observable$: new BehaviorSubject({} as any).asObservable(),
sync: jest.fn().mockResolvedValue(new Map()),
clear: jest.fn(),
}

afterEach(() => {
storage.clear()
tokenInfoStorage.clear()
})

it('should clear all data after syncing operations are complete', async () => {
const tasks: any = []
const enqueueMock = jest.fn((task) => tasks.push(task))
const mockedNotify = jest.fn()

const manager = portfolioBalanceManagerMaker(
{
tokenManager,
storage,
primaryTokenInfo: tokenMocks.primaryETH.info,
sourceId,
},
{
queue: {
enqueue: enqueueMock,
destroy: jest.fn(),
observable: new BehaviorSubject({} as any).asObservable(),
} as any,
observer: {
notify: mockedNotify,
subscribe: jest.fn(),
unsubscribe: jest.fn(),
destroy: jest.fn(),
observable: new BehaviorSubject({} as any).asObservable(),
},
},
)

manager.syncBalances({
primaryStated: {
totalFromTxs: 500n,
lockedAsStorageCost: 100n,
},
secondaryBalances: new Map(),
})

manager.clear()

expect(enqueueMock).toHaveBeenCalledTimes(2)

for (const task of tasks) {
await task()
}

expect(storage.balances.all()).toEqual([])
expect(storage.primaryBreakdown.read()).toBeNull()

expect(mockedNotify).toHaveBeenCalledWith({
on: Portfolio.Event.ManagerOn.Clear,
sourceId,
})
})
})

0 comments on commit e7c0c5e

Please sign in to comment.