mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-23 07:15:35 +01:00
REF: WalletAddresses to TSX (#6670)
This commit is contained in:
parent
a88c95f9f3
commit
2cbfa9593f
5 changed files with 270 additions and 207 deletions
|
@ -1,44 +1,57 @@
|
|||
import React from 'react';
|
||||
import { StyleSheet, Text, View } from 'react-native';
|
||||
|
||||
import { StyleSheet, Text, View, Pressable, LayoutAnimation, Platform, UIManager, ViewStyle, TextStyle } from 'react-native';
|
||||
import loc from '../../loc';
|
||||
import { useTheme } from '../themes';
|
||||
|
||||
export const TABS = {
|
||||
EXTERNAL: 'receive',
|
||||
INTERNAL: 'change',
|
||||
};
|
||||
} as const;
|
||||
|
||||
const AddressTypeTabs = ({ currentTab, setCurrentTab }) => {
|
||||
type TabKey = keyof typeof TABS;
|
||||
type TABS_VALUES = (typeof TABS)[keyof typeof TABS];
|
||||
|
||||
if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental) {
|
||||
UIManager.setLayoutAnimationEnabledExperimental(true);
|
||||
}
|
||||
|
||||
interface AddressTypeTabsProps {
|
||||
currentTab: TABS_VALUES;
|
||||
setCurrentTab: (tab: TABS_VALUES) => void;
|
||||
customTabText?: { [key in TabKey]?: string };
|
||||
}
|
||||
|
||||
const AddressTypeTabs: React.FC<AddressTypeTabsProps> = ({ currentTab, setCurrentTab, customTabText }) => {
|
||||
const { colors } = useTheme();
|
||||
|
||||
const stylesHook = StyleSheet.create({
|
||||
activeTab: {
|
||||
backgroundColor: colors.modal,
|
||||
},
|
||||
} as ViewStyle,
|
||||
activeText: {
|
||||
fontWeight: 'bold',
|
||||
color: colors.foregroundColor,
|
||||
},
|
||||
} as TextStyle,
|
||||
inactiveTab: {
|
||||
fontWeight: 'normal',
|
||||
color: colors.foregroundColor,
|
||||
},
|
||||
} as TextStyle,
|
||||
backTabs: {
|
||||
backgroundColor: colors.buttonDisabledBackgroundColor,
|
||||
},
|
||||
} as ViewStyle,
|
||||
});
|
||||
|
||||
const tabs = Object.entries(TABS).map(([key, value]) => {
|
||||
return {
|
||||
key,
|
||||
key: key as TabKey,
|
||||
value,
|
||||
name: loc.addresses[`type_${value}`],
|
||||
name: customTabText?.[key as TabKey] || loc.addresses[`type_${value}`],
|
||||
};
|
||||
});
|
||||
|
||||
const changeToTab = tabKey => {
|
||||
const changeToTab = (tabKey: TabKey) => {
|
||||
if (tabKey in TABS) {
|
||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
||||
setCurrentTab(TABS[tabKey]);
|
||||
}
|
||||
};
|
||||
|
@ -47,15 +60,13 @@ const AddressTypeTabs = ({ currentTab, setCurrentTab }) => {
|
|||
const tabsButtons = tabs.map(tab => {
|
||||
const isActive = tab.value === currentTab;
|
||||
|
||||
const tabStyle = isActive ? stylesHook.activeTab : stylesHook.inactiveTab;
|
||||
const tabStyle = isActive ? stylesHook.activeTab : undefined;
|
||||
const textStyle = isActive ? stylesHook.activeText : stylesHook.inactiveTab;
|
||||
|
||||
return (
|
||||
<View key={tab.key} onPress={() => changeToTab(tab.key)} style={[styles.tab, tabStyle]}>
|
||||
<Text onPress={() => changeToTab(tab.key)} style={textStyle}>
|
||||
{tab.name}
|
||||
</Text>
|
||||
</View>
|
||||
<Pressable key={tab.key} onPress={() => changeToTab(tab.key)} style={[styles.tab, tabStyle]}>
|
||||
<Text style={textStyle}>{tab.name}</Text>
|
||||
</Pressable>
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -76,22 +87,23 @@ const styles = StyleSheet.create({
|
|||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
} as ViewStyle,
|
||||
backTabs: {
|
||||
padding: 4,
|
||||
marginVertical: 8,
|
||||
borderRadius: 8,
|
||||
},
|
||||
} as ViewStyle,
|
||||
tabs: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
} as ViewStyle,
|
||||
tab: {
|
||||
borderRadius: 6,
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
justifyContent: 'center',
|
||||
} as ViewStyle,
|
||||
});
|
||||
|
||||
export { AddressTypeTabs };
|
|
@ -24,7 +24,7 @@ import TransactionDetails from '../screen/transactions/TransactionDetails';
|
|||
import RBFBumpFee from '../screen/transactions/RBFBumpFee';
|
||||
import RBFCancel from '../screen/transactions/RBFCancel';
|
||||
import TransactionStatus from '../screen/transactions/TransactionStatus';
|
||||
import WalletAddresses from '../screen/wallets/addresses';
|
||||
import WalletAddresses from '../screen/wallets/WalletAddresses';
|
||||
import WalletDetails from '../screen/wallets/details';
|
||||
import GenerateWord from '../screen/wallets/generateWord';
|
||||
import LdkViewLogs from '../screen/wallets/ldkViewLogs';
|
||||
|
@ -241,7 +241,11 @@ const DetailViewStackScreensStack = () => {
|
|||
gestureEnabled: false,
|
||||
}}
|
||||
/>
|
||||
<DetailViewStack.Screen name="WalletAddresses" component={WalletAddresses} options={WalletAddresses.navigationOptions(theme)} />
|
||||
<DetailViewStack.Screen
|
||||
name="WalletAddresses"
|
||||
component={WalletAddresses}
|
||||
options={navigationStyle({ title: loc.addresses.addresses_title, statusBarStyle: 'auto' })(theme)}
|
||||
/>
|
||||
|
||||
<DetailViewStack.Screen name="AddWalletRoot" component={AddWalletStack} options={NavigationFormModalOptions} />
|
||||
<DetailViewStack.Screen
|
||||
|
|
224
screen/wallets/WalletAddresses.tsx
Normal file
224
screen/wallets/WalletAddresses.tsx
Normal file
|
@ -0,0 +1,224 @@
|
|||
import React, { useCallback, useEffect, useLayoutEffect, useRef, useReducer, useMemo } from 'react';
|
||||
import { useFocusEffect, useRoute, RouteProp } from '@react-navigation/native';
|
||||
import { ActivityIndicator, FlatList, StyleSheet, View } from 'react-native';
|
||||
import { WatchOnlyWallet } from '../../class';
|
||||
import { AddressItem } from '../../components/addresses/AddressItem';
|
||||
import { AddressTypeTabs, TABS } from '../../components/addresses/AddressTypeTabs';
|
||||
import { useTheme } from '../../components/themes';
|
||||
import usePrivacy from '../../hooks/usePrivacy';
|
||||
import { useStorage } from '../../hooks/context/useStorage';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import { DetailViewStackParamList } from '../../navigation/DetailViewStackParamList';
|
||||
import { useExtendedNavigation } from '../../hooks/useExtendedNavigation';
|
||||
|
||||
interface Address {
|
||||
key: string;
|
||||
index: number;
|
||||
address: string;
|
||||
isInternal: boolean;
|
||||
balance: number;
|
||||
transactions: number;
|
||||
}
|
||||
|
||||
interface WalletAddressesState {
|
||||
showAddresses: boolean;
|
||||
addresses: Address[];
|
||||
currentTab: (typeof TABS)[keyof typeof TABS];
|
||||
search: string;
|
||||
}
|
||||
|
||||
const SET_SHOW_ADDRESSES = 'SET_SHOW_ADDRESSES' as const;
|
||||
const SET_ADDRESSES = 'SET_ADDRESSES' as const;
|
||||
const SET_CURRENT_TAB = 'SET_CURRENT_TAB' as const;
|
||||
const SET_SEARCH = 'SET_SEARCH' as const;
|
||||
|
||||
type WalletAddressesAction =
|
||||
| { type: typeof SET_SHOW_ADDRESSES; payload: boolean }
|
||||
| { type: typeof SET_ADDRESSES; payload: Address[] }
|
||||
| { type: typeof SET_CURRENT_TAB; payload: (typeof TABS)[keyof typeof TABS] }
|
||||
| { type: typeof SET_SEARCH; payload: string };
|
||||
|
||||
const initialState: WalletAddressesState = {
|
||||
showAddresses: false,
|
||||
addresses: [],
|
||||
currentTab: TABS.EXTERNAL,
|
||||
search: '',
|
||||
};
|
||||
|
||||
const reducer = (state: WalletAddressesState, action: WalletAddressesAction): WalletAddressesState => {
|
||||
switch (action.type) {
|
||||
case SET_SHOW_ADDRESSES:
|
||||
return { ...state, showAddresses: action.payload };
|
||||
case SET_ADDRESSES:
|
||||
return { ...state, addresses: action.payload };
|
||||
case SET_CURRENT_TAB:
|
||||
return { ...state, currentTab: action.payload };
|
||||
case SET_SEARCH:
|
||||
return { ...state, search: action.payload };
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export const totalBalance = ({ c, u } = { c: 0, u: 0 }) => c + u;
|
||||
|
||||
export const getAddress = (wallet: any, index: number, isInternal: boolean): Address => {
|
||||
let address: string;
|
||||
let balance = 0;
|
||||
let transactions = 0;
|
||||
|
||||
if (isInternal) {
|
||||
address = wallet._getInternalAddressByIndex(index);
|
||||
balance = totalBalance(wallet._balances_by_internal_index[index]);
|
||||
transactions = wallet._txs_by_internal_index[index]?.length;
|
||||
} else {
|
||||
address = wallet._getExternalAddressByIndex(index);
|
||||
balance = totalBalance(wallet._balances_by_external_index[index]);
|
||||
transactions = wallet._txs_by_external_index[index]?.length;
|
||||
}
|
||||
|
||||
return {
|
||||
key: address,
|
||||
index,
|
||||
address,
|
||||
isInternal,
|
||||
balance,
|
||||
transactions,
|
||||
};
|
||||
};
|
||||
|
||||
export const sortByAddressIndex = (a: Address, b: Address) => {
|
||||
return a.index > b.index ? 1 : -1;
|
||||
};
|
||||
|
||||
export const filterByAddressType = (
|
||||
type: (typeof TABS)[keyof typeof TABS],
|
||||
isInternal: boolean,
|
||||
currentType: (typeof TABS)[keyof typeof TABS],
|
||||
) => {
|
||||
return currentType === type ? isInternal === true : isInternal === false;
|
||||
};
|
||||
|
||||
type NavigationProps = NativeStackNavigationProp<DetailViewStackParamList, 'WalletAddresses'>;
|
||||
type RouteProps = RouteProp<DetailViewStackParamList, 'WalletAddresses'>;
|
||||
|
||||
const WalletAddresses: React.FC = () => {
|
||||
const [{ showAddresses, addresses, currentTab, search }, dispatch] = useReducer(reducer, initialState);
|
||||
|
||||
const { wallets } = useStorage();
|
||||
const { walletID } = useRoute<RouteProps>().params;
|
||||
|
||||
const addressList = useRef<FlatList<Address>>(null);
|
||||
const wallet = wallets.find((w: any) => w.getID() === walletID);
|
||||
|
||||
const balanceUnit = wallet?.getPreferredBalanceUnit();
|
||||
const isWatchOnly = wallet?.type === WatchOnlyWallet.type;
|
||||
const walletInstance = isWatchOnly ? wallet._hdWalletInstance : wallet;
|
||||
const allowSignVerifyMessage = wallet && 'allowSignVerifyMessage' in wallet && wallet.allowSignVerifyMessage();
|
||||
|
||||
const { colors } = useTheme();
|
||||
const { setOptions } = useExtendedNavigation<NavigationProps>();
|
||||
const { enableBlur, disableBlur } = usePrivacy();
|
||||
|
||||
const stylesHook = StyleSheet.create({
|
||||
root: {
|
||||
backgroundColor: colors.elevated,
|
||||
},
|
||||
});
|
||||
|
||||
const filteredAddresses = useMemo(
|
||||
() => addresses.filter(address => filterByAddressType(TABS.INTERNAL, address.isInternal, currentTab)).sort(sortByAddressIndex),
|
||||
[addresses, currentTab],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (showAddresses && addressList.current) {
|
||||
addressList.current.scrollToIndex({ animated: false, index: 0 });
|
||||
}
|
||||
}, [showAddresses]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
setOptions({
|
||||
headerSearchBarOptions: {
|
||||
onChangeText: (event: { nativeEvent: { text: string } }) => dispatch({ type: SET_SEARCH, payload: event.nativeEvent.text }),
|
||||
},
|
||||
});
|
||||
}, [setOptions]);
|
||||
|
||||
const getAddresses = useCallback(() => {
|
||||
const newAddresses: Address[] = [];
|
||||
// @ts-ignore: idk what to do
|
||||
for (let index = 0; index <= (walletInstance?.next_free_change_address_index ?? 0); index++) {
|
||||
const address = getAddress(walletInstance, index, true);
|
||||
newAddresses.push(address);
|
||||
}
|
||||
|
||||
// @ts-ignore: idk what to do
|
||||
for (let index = 0; index < (walletInstance?.next_free_address_index ?? 0) + (walletInstance?.gap_limit ?? 0); index++) {
|
||||
const address = getAddress(walletInstance, index, false);
|
||||
newAddresses.push(address);
|
||||
}
|
||||
dispatch({ type: SET_ADDRESSES, payload: newAddresses });
|
||||
dispatch({ type: SET_SHOW_ADDRESSES, payload: true });
|
||||
}, [walletInstance]);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
enableBlur();
|
||||
getAddresses();
|
||||
return () => {
|
||||
disableBlur();
|
||||
};
|
||||
}, [enableBlur, disableBlur, getAddresses]),
|
||||
);
|
||||
|
||||
const data =
|
||||
search.length > 0 ? filteredAddresses.filter(item => item.address.toLowerCase().includes(search.toLowerCase())) : filteredAddresses;
|
||||
|
||||
const renderRow = useCallback(
|
||||
({ item }: { item: Address }) => {
|
||||
return balanceUnit && allowSignVerifyMessage ? (
|
||||
<AddressItem item={item} {...item} balanceUnit={balanceUnit} walletID={walletID} allowSignVerifyMessage={allowSignVerifyMessage} />
|
||||
) : null;
|
||||
},
|
||||
[balanceUnit, walletID, allowSignVerifyMessage],
|
||||
);
|
||||
|
||||
if (!wallet) {
|
||||
return (
|
||||
<View>
|
||||
<ActivityIndicator />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={[styles.root, stylesHook.root]}>
|
||||
<FlatList
|
||||
contentContainerStyle={stylesHook.root}
|
||||
ref={addressList}
|
||||
data={data}
|
||||
extraData={data}
|
||||
initialNumToRender={20}
|
||||
renderItem={renderRow}
|
||||
ListEmptyComponent={search.length > 0 ? null : <ActivityIndicator />}
|
||||
centerContent={!showAddresses}
|
||||
contentInsetAdjustmentBehavior="automatic"
|
||||
ListHeaderComponent={
|
||||
<AddressTypeTabs
|
||||
currentTab={currentTab}
|
||||
setCurrentTab={(tab: (typeof TABS)[keyof typeof TABS]) => dispatch({ type: SET_CURRENT_TAB, payload: tab })}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default WalletAddresses;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
root: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
|
@ -1,176 +0,0 @@
|
|||
import { useFocusEffect, useNavigation, useRoute } from '@react-navigation/native';
|
||||
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import { ActivityIndicator, FlatList, StyleSheet, View } from 'react-native';
|
||||
import { WatchOnlyWallet } from '../../class';
|
||||
import { AddressItem } from '../../components/addresses/AddressItem';
|
||||
import { AddressTypeTabs, TABS } from '../../components/addresses/AddressTypeTabs';
|
||||
import navigationStyle from '../../components/navigationStyle';
|
||||
import { useTheme } from '../../components/themes';
|
||||
import usePrivacy from '../../hooks/usePrivacy';
|
||||
import loc from '../../loc';
|
||||
import { useStorage } from '../../hooks/context/useStorage';
|
||||
|
||||
export const totalBalance = ({ c, u } = { c: 0, u: 0 }) => c + u;
|
||||
|
||||
export const getAddress = (wallet, index, isInternal) => {
|
||||
let address;
|
||||
let balance = 0;
|
||||
let transactions = 0;
|
||||
|
||||
if (isInternal) {
|
||||
address = wallet._getInternalAddressByIndex(index);
|
||||
balance = totalBalance(wallet._balances_by_internal_index[index]);
|
||||
transactions = wallet._txs_by_internal_index[index]?.length;
|
||||
} else {
|
||||
address = wallet._getExternalAddressByIndex(index);
|
||||
balance = totalBalance(wallet._balances_by_external_index[index]);
|
||||
transactions = wallet._txs_by_external_index[index]?.length;
|
||||
}
|
||||
|
||||
return {
|
||||
key: address,
|
||||
index,
|
||||
address,
|
||||
isInternal,
|
||||
balance,
|
||||
transactions,
|
||||
};
|
||||
};
|
||||
|
||||
export const sortByAddressIndex = (a, b) => {
|
||||
if (a.index > b.index) {
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
export const filterByAddressType = (type, isInternal, currentType) => {
|
||||
if (currentType === type) {
|
||||
return isInternal === true;
|
||||
}
|
||||
return isInternal === false;
|
||||
};
|
||||
|
||||
const WalletAddresses = () => {
|
||||
const [showAddresses, setShowAddresses] = useState(false);
|
||||
|
||||
const [addresses, setAddresses] = useState([]);
|
||||
|
||||
const [currentTab, setCurrentTab] = useState(TABS.EXTERNAL);
|
||||
|
||||
const { wallets } = useStorage();
|
||||
|
||||
const { walletID } = useRoute().params;
|
||||
|
||||
const addressList = useRef();
|
||||
|
||||
const wallet = wallets.find(w => w.getID() === walletID);
|
||||
|
||||
const balanceUnit = wallet.getPreferredBalanceUnit();
|
||||
|
||||
const isWatchOnly = wallet.type === WatchOnlyWallet.type;
|
||||
|
||||
const walletInstance = isWatchOnly ? wallet._hdWalletInstance : wallet;
|
||||
|
||||
const allowSignVerifyMessage = 'allowSignVerifyMessage' in wallet && wallet.allowSignVerifyMessage();
|
||||
|
||||
const { colors } = useTheme();
|
||||
|
||||
const { setOptions } = useNavigation();
|
||||
|
||||
const [search, setSearch] = React.useState('');
|
||||
|
||||
const { enableBlur, disableBlur } = usePrivacy();
|
||||
|
||||
const stylesHook = StyleSheet.create({
|
||||
root: {
|
||||
backgroundColor: colors.elevated,
|
||||
},
|
||||
});
|
||||
|
||||
// computed property
|
||||
const filteredAddresses = addresses
|
||||
.filter(address => filterByAddressType(TABS.INTERNAL, address.isInternal, currentTab))
|
||||
.sort(sortByAddressIndex);
|
||||
|
||||
useEffect(() => {
|
||||
if (showAddresses) {
|
||||
addressList.current.scrollToIndex({ animated: false, index: 0 });
|
||||
}
|
||||
}, [showAddresses]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
setOptions({
|
||||
headerSearchBarOptions: {
|
||||
onChangeText: event => setSearch(event.nativeEvent.text),
|
||||
},
|
||||
});
|
||||
}, [setOptions]);
|
||||
|
||||
const getAddresses = () => {
|
||||
const newAddresses = [];
|
||||
|
||||
for (let index = 0; index <= walletInstance.next_free_change_address_index; index++) {
|
||||
const address = getAddress(walletInstance, index, true);
|
||||
|
||||
newAddresses.push(address);
|
||||
}
|
||||
|
||||
for (let index = 0; index < walletInstance.next_free_address_index + walletInstance.gap_limit; index++) {
|
||||
const address = getAddress(walletInstance, index, false);
|
||||
|
||||
newAddresses.push(address);
|
||||
}
|
||||
|
||||
setAddresses(newAddresses);
|
||||
setShowAddresses(true);
|
||||
};
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
enableBlur();
|
||||
getAddresses();
|
||||
return () => {
|
||||
disableBlur();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []),
|
||||
);
|
||||
|
||||
const data =
|
||||
search.length > 0 ? filteredAddresses.filter(item => item.address.toLowerCase().includes(search.toLowerCase())) : filteredAddresses;
|
||||
|
||||
const renderRow = item => {
|
||||
return <AddressItem {...item} balanceUnit={balanceUnit} walletID={walletID} allowSignVerifyMessage={allowSignVerifyMessage} />;
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={[styles.root, stylesHook.root]}>
|
||||
<FlatList
|
||||
contentContainerStyle={stylesHook.root}
|
||||
ref={addressList}
|
||||
data={data}
|
||||
extraData={data}
|
||||
initialNumToRender={20}
|
||||
renderItem={renderRow}
|
||||
ListEmptyComponent={search.length > 0 ? null : <ActivityIndicator />}
|
||||
centerContent={!showAddresses}
|
||||
contentInsetAdjustmentBehavior="automatic"
|
||||
ListHeaderComponent={<AddressTypeTabs currentTab={currentTab} setCurrentTab={setCurrentTab} />}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
WalletAddresses.navigationOptions = navigationStyle({
|
||||
title: loc.addresses.addresses_title,
|
||||
statusBarStyle: 'auto',
|
||||
});
|
||||
|
||||
export default WalletAddresses;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
root: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
|
@ -1,7 +1,6 @@
|
|||
import assert from 'assert';
|
||||
|
||||
import { filterByAddressType, getAddress, sortByAddressIndex, totalBalance } from '../../screen/wallets/WalletAddresses';
|
||||
import { TABS } from '../../components/addresses/AddressTypeTabs';
|
||||
import { filterByAddressType, getAddress, sortByAddressIndex, totalBalance } from '../../screen/wallets/addresses';
|
||||
|
||||
jest.mock('../../blue_modules/currency', () => {
|
||||
return {
|
||||
|
@ -16,11 +15,11 @@ jest.mock('../../blue_modules/BlueElectrum', () => {
|
|||
});
|
||||
|
||||
const mockAddressesList = [
|
||||
{ index: 2, isInternal: false, key: 'third_external_address' },
|
||||
{ index: 0, isInternal: true, key: 'first_internal_address' },
|
||||
{ index: 1, isInternal: false, key: 'second_external_address' },
|
||||
{ index: 1, isInternal: true, key: 'second_internal_address' },
|
||||
{ index: 0, isInternal: false, key: 'first_external_address' },
|
||||
{ index: 2, isInternal: false, key: 'third_external_address', address: '', balance: 0, transactions: 0 },
|
||||
{ index: 0, isInternal: true, key: 'first_internal_address', address: '', balance: 0, transactions: 0 },
|
||||
{ index: 1, isInternal: false, key: 'second_external_address', address: '', balance: 0, transactions: 0 },
|
||||
{ index: 1, isInternal: true, key: 'second_internal_address', address: '', balance: 0, transactions: 0 },
|
||||
{ index: 0, isInternal: false, key: 'first_external_address', address: '', balance: 0, transactions: 0 },
|
||||
];
|
||||
|
||||
describe('Addresses', () => {
|
||||
|
@ -42,7 +41,7 @@ describe('Addresses', () => {
|
|||
});
|
||||
|
||||
it('Filter by type', () => {
|
||||
let currentTab = TABS.EXTERNAL;
|
||||
let currentTab: (typeof TABS)[keyof typeof TABS] = TABS.EXTERNAL;
|
||||
|
||||
const externalAddresses = mockAddressesList.filter(address => filterByAddressType(TABS.INTERNAL, address.isInternal, currentTab));
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue