Skip to content

Commit e65f651

Browse files
committed
refactor: useBalance hook to use balanceSelector
1 parent 502cbc5 commit e65f651

File tree

3 files changed

+129
-115
lines changed

3 files changed

+129
-115
lines changed

__tests__/reselect.ts

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
import assert from 'node:assert';
21
import cloneDeep from 'lodash/cloneDeep';
2+
import assert from 'node:assert';
33

44
import '../src/utils/i18n';
55
import store, { RootState } from '../src/store';
6-
import { createNewWallet } from '../src/utils/startup';
76
import { updateWallet } from '../src/store/actions/wallet';
8-
import { EAvailableNetwork } from '../src/utils/networks';
97
import {
8+
TBalance,
109
balanceSelector,
1110
lnSetupSelector,
1211
} from '../src/store/reselect/aggregations';
13-
import { TChannel, EChannelStatus } from '../src/store/types/lightning';
12+
import { EChannelStatus, TChannel } from '../src/store/types/lightning';
13+
import { EAvailableNetwork } from '../src/utils/networks';
14+
import { createNewWallet } from '../src/utils/startup';
1415

1516
describe('Reselect', () => {
1617
let s: RootState;
@@ -27,29 +28,41 @@ describe('Reselect', () => {
2728
describe('balanceSelector', () => {
2829
it('should return zeros by default', () => {
2930
const state = cloneDeep(s);
30-
assert.deepEqual(balanceSelector(state), {
31+
32+
const balance: TBalance = {
33+
balanceInTransferToSavings: 0,
34+
balanceInTransferToSpending: 0,
35+
claimableBalance: 0,
3136
lightningBalance: 0,
32-
lightningClaimableBalance: 0,
33-
lightningReserveBalance: 0,
34-
lightningSpendingBalance: 0,
3537
onchainBalance: 0,
38+
pendingPaymentsBalance: 0,
39+
reserveBalance: 0,
40+
spendableBalance: 0,
41+
spendingBalance: 0,
3642
totalBalance: 0,
37-
totalSpendableBalance: 0,
38-
});
43+
};
44+
45+
assert.deepEqual(balanceSelector(state), balance);
3946
});
4047

4148
it('should return onchain balance for current wallet', () => {
4249
const state = cloneDeep(s);
4350
state.wallet.wallets.wallet0.balance.bitcoinRegtest = 1;
44-
assert.deepEqual(balanceSelector(state), {
51+
52+
const balance: TBalance = {
53+
balanceInTransferToSavings: 0,
54+
balanceInTransferToSpending: 0,
55+
claimableBalance: 0,
4556
lightningBalance: 0,
46-
lightningClaimableBalance: 0,
47-
lightningReserveBalance: 0,
48-
lightningSpendingBalance: 0,
4957
onchainBalance: 1,
58+
pendingPaymentsBalance: 0,
59+
reserveBalance: 0,
60+
spendableBalance: 1,
61+
spendingBalance: 0,
5062
totalBalance: 1,
51-
totalSpendableBalance: 1,
52-
});
63+
};
64+
65+
assert.deepEqual(balanceSelector(state), balance);
5366
});
5467

5568
it('should calculate balance for LN wallet', () => {
@@ -84,15 +97,20 @@ describe('Reselect', () => {
8497
const lnWallet = state.lightning.nodes.wallet0;
8598
lnWallet.channels.bitcoinRegtest = { channel1, channel2, channel3 };
8699

87-
assert.deepEqual(balanceSelector(state), {
100+
const balance: TBalance = {
101+
balanceInTransferToSavings: 3,
102+
balanceInTransferToSpending: 0,
103+
claimableBalance: 3,
88104
lightningBalance: 4,
89-
lightningClaimableBalance: 3,
90-
lightningReserveBalance: 2,
91-
lightningSpendingBalance: 2,
92105
onchainBalance: 1,
93-
totalBalance: 5,
94-
totalSpendableBalance: 3,
95-
});
106+
pendingPaymentsBalance: 0,
107+
reserveBalance: 2,
108+
spendableBalance: 3,
109+
spendingBalance: 2,
110+
totalBalance: 8,
111+
};
112+
113+
assert.deepEqual(balanceSelector(state), balance);
96114
});
97115
});
98116

src/hooks/wallet.ts

Lines changed: 8 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,21 @@
11
import { useTranslation } from 'react-i18next';
22

33
import { useAppDispatch, useAppSelector } from '../hooks/redux';
4-
import {
5-
claimableBalanceSelector,
6-
lightningBalanceSelector,
7-
pendingPaymentsSelector,
8-
} from '../store/reselect/lightning';
4+
import { TBalance, balanceSelector } from '../store/reselect/aggregations';
5+
import { nextUnitSelector, unitSelector } from '../store/reselect/settings';
6+
import { ignoresSwitchUnitToastSelector } from '../store/reselect/user';
97
import { updateSettings } from '../store/slices/settings';
10-
import { unitSelector, nextUnitSelector } from '../store/reselect/settings';
11-
import {
12-
currentWalletSelector,
13-
pendingTransfersSelector,
14-
selectedNetworkSelector,
15-
selectedWalletSelector,
16-
} from '../store/reselect/wallet';
17-
import { useCurrency } from './displayValues';
8+
import { ignoreSwitchUnitToast } from '../store/slices/user';
9+
import { EUnit } from '../store/types/wallet';
1810
import i18n from '../utils/i18n';
1911
import { showToast } from '../utils/notifications';
20-
import { ignoresSwitchUnitToastSelector } from '../store/reselect/user';
21-
import { ignoreSwitchUnitToast } from '../store/slices/user';
22-
import { ETransferType, EUnit } from '../store/types/wallet';
23-
import { newChannelsNotificationsSelector } from '../store/reselect/todos';
12+
import { useCurrency } from './displayValues';
2413

2514
/**
2615
* Retrieves wallet balances for the currently selected wallet and network.
2716
*/
28-
export const useBalance = (): {
29-
onchainBalance: number; // Total onchain funds
30-
lightningBalance: number; // Total lightning funds (spendable + reserved + claimable)
31-
spendingBalance: number; // Share of lightning funds that are spendable
32-
reserveBalance: number; // Share of lightning funds that are locked up in channels
33-
claimableBalance: number; // Funds that will be available after a channel opens/closes
34-
spendableBalance: number; // Total spendable funds (onchain + spendable lightning)
35-
pendingPaymentsBalance: number; // LN funds that have not been claimed by payee (hold invoices)
36-
balanceInTransferToSpending: number;
37-
balanceInTransferToSavings: number;
38-
totalBalance: number; // Total funds (all of the above)
39-
} => {
40-
const selectedWallet = useAppSelector(selectedWalletSelector);
41-
const selectedNetwork = useAppSelector(selectedNetworkSelector);
42-
const currentWallet = useAppSelector((state) => {
43-
return currentWalletSelector(state, selectedWallet);
44-
});
45-
const pendingTransfers = useAppSelector(pendingTransfersSelector);
46-
const pendingPayments = useAppSelector(pendingPaymentsSelector);
47-
const claimableBalance = useAppSelector(claimableBalanceSelector);
48-
const newChannels = useAppSelector(newChannelsNotificationsSelector);
49-
const { lightningBalance, spendingBalance, reserveBalance } = useAppSelector(
50-
lightningBalanceSelector,
51-
);
52-
53-
const onchainBalance = currentWallet.balance[selectedNetwork];
54-
const spendableBalance = onchainBalance + spendingBalance;
55-
const pendingPaymentsBalance = pendingPayments.reduce(
56-
(acc, payment) => acc + payment.amount,
57-
0,
58-
);
59-
60-
let inTransferToSpending = pendingTransfers.reduce((acc, transfer) => {
61-
if (transfer.type === ETransferType.open) {
62-
acc += transfer.amount;
63-
}
64-
return acc;
65-
}, 0);
66-
67-
if (newChannels.length > 0) {
68-
// avoid flashing wrong balance on channel open
69-
inTransferToSpending = 0;
70-
}
71-
72-
const totalBalance =
73-
onchainBalance + lightningBalance + claimableBalance + inTransferToSpending;
74-
75-
return {
76-
onchainBalance,
77-
lightningBalance,
78-
spendingBalance,
79-
reserveBalance,
80-
claimableBalance,
81-
spendableBalance,
82-
pendingPaymentsBalance,
83-
balanceInTransferToSpending: inTransferToSpending,
84-
balanceInTransferToSavings: claimableBalance,
85-
totalBalance,
86-
};
17+
export const useBalance = (): TBalance => {
18+
return useAppSelector(balanceSelector);
8719
};
8820

8921
export const useSwitchUnit = (): (() => void) => {

src/store/reselect/aggregations.ts

Lines changed: 80 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,94 @@
11
import { createSelector } from '@reduxjs/toolkit';
22

3-
import { blocktankInfoSelector } from './blocktank';
4-
import { channelsSizeSelector, lightningBalanceSelector } from './lightning';
5-
import { onChainBalanceSelector } from './wallet';
63
import {
74
DEFAULT_SPENDING_PERCENTAGE,
85
MAX_SPENDING_PERCENTAGE,
96
} from '../../utils/wallet/constants';
7+
import { ETransferType } from '../types/wallet';
8+
import { blocktankInfoSelector } from './blocktank';
9+
import {
10+
channelsSizeSelector,
11+
claimableBalanceSelector,
12+
lightningBalanceSelector,
13+
pendingPaymentsSelector,
14+
} from './lightning';
15+
import { newChannelsNotificationsSelector } from './todos';
16+
import { onChainBalanceSelector, pendingTransfersSelector } from './wallet';
17+
18+
export type TBalance = {
19+
/** Total onchain funds */
20+
onchainBalance: number;
21+
/** Total lightning funds (spendable + reserved + claimable) */
22+
lightningBalance: number;
23+
/** Share of lightning funds that are spendable */
24+
spendingBalance: number;
25+
/** Share of lightning funds that are locked up in channels */
26+
reserveBalance: number;
27+
/** Funds that will be available after a channel opens/closes */
28+
claimableBalance: number;
29+
/** Total spendable funds (onchain + spendable lightning) */
30+
spendableBalance: number;
31+
/** LN funds that have not been claimed by payee (hold invoices) */
32+
pendingPaymentsBalance: number;
33+
balanceInTransferToSpending: number;
34+
balanceInTransferToSavings: number;
35+
/** Total funds (all of the above) */
36+
totalBalance: number;
37+
};
1038

11-
/**
12-
* Returns all balances
13-
*/
1439
export const balanceSelector = createSelector(
15-
[lightningBalanceSelector, onChainBalanceSelector],
16-
(lightning, onchain) => {
17-
const totalSpendableBalance = onchain + lightning.spendingBalance;
18-
const totalBalance = onchain + lightning.lightningBalance;
40+
[
41+
onChainBalanceSelector,
42+
pendingTransfersSelector,
43+
pendingPaymentsSelector,
44+
claimableBalanceSelector,
45+
newChannelsNotificationsSelector,
46+
lightningBalanceSelector,
47+
],
48+
(
49+
onchainBalance,
50+
pendingTransfers,
51+
pendingPayments,
52+
claimableBalance,
53+
newChannels,
54+
lnBalance,
55+
): TBalance => {
56+
const { lightningBalance, spendingBalance, reserveBalance } = lnBalance;
57+
const spendableBalance = onchainBalance + spendingBalance;
58+
const pendingPaymentsBalance = pendingPayments.reduce(
59+
(acc, payment) => acc + payment.amount,
60+
0,
61+
);
62+
63+
let inTransferToSpending = pendingTransfers.reduce((acc, transfer) => {
64+
if (transfer.type === ETransferType.open) {
65+
acc += transfer.amount;
66+
}
67+
return acc;
68+
}, 0);
69+
70+
if (newChannels.length > 0) {
71+
// avoid flashing wrong balance on channel open
72+
inTransferToSpending = 0;
73+
}
74+
75+
const totalBalance =
76+
onchainBalance +
77+
lightningBalance +
78+
claimableBalance +
79+
inTransferToSpending;
1980

2081
return {
21-
onchainBalance: onchain,
22-
lightningBalance: lightning.lightningBalance,
23-
lightningSpendingBalance: lightning.spendingBalance,
24-
lightningReserveBalance: lightning.reserveBalance,
25-
lightningClaimableBalance: lightning.claimableBalance,
82+
onchainBalance,
83+
lightningBalance,
84+
spendingBalance,
85+
reserveBalance,
86+
claimableBalance,
87+
spendableBalance,
88+
pendingPaymentsBalance,
89+
balanceInTransferToSpending: inTransferToSpending,
90+
balanceInTransferToSavings: claimableBalance,
2691
totalBalance,
27-
totalSpendableBalance,
2892
};
2993
},
3094
);

0 commit comments

Comments
 (0)