Skip to content

Commit 90f0008

Browse files
committed
swap: infer swap direction based on balance mode
1 parent 772b99a commit 90f0008

File tree

2 files changed

+57
-12
lines changed

2 files changed

+57
-12
lines changed

app/src/__tests__/store/buildSwapStore.spec.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { BuildSwapSteps, SwapDirection } from 'types/state';
33
import { grpc } from '@improbable-eng/grpc-web';
44
import { waitFor } from '@testing-library/react';
55
import Big from 'big.js';
6+
import { BalanceMode } from 'util/constants';
67
import { injectIntoGrpcUnary } from 'util/tests';
78
import { lndChannel, loopTerms } from 'util/tests/sampleData';
89
import { BuildSwapStore, createStore, Store } from 'store';
@@ -38,12 +39,43 @@ describe('BuildSwapStore', () => {
3839
expect(store.selectedChanIds).toHaveLength(0);
3940
});
4041

41-
it('should infer the swap direction based on the selected channels', () => {
42+
it('should infer the swap direction based on the selected channels (receiving mode)', () => {
43+
rootStore.settingsStore.setBalanceMode(BalanceMode.receive);
4244
const channels = rootStore.channelStore.sortedChannels;
4345
store.toggleSelectedChannel(channels[0].chanId);
4446
expect(store.inferredDirection).toEqual(SwapDirection.OUT);
4547
store.toggleSelectedChannel(channels[channels.length - 1].chanId);
48+
expect(store.inferredDirection).toEqual(SwapDirection.OUT);
49+
});
50+
51+
it('should infer the swap direction based on the selected channels (sending mode)', () => {
52+
rootStore.settingsStore.setBalanceMode(BalanceMode.send);
53+
const channels = rootStore.channelStore.sortedChannels;
54+
store.toggleSelectedChannel(channels[0].chanId);
55+
expect(store.inferredDirection).toEqual(SwapDirection.IN);
56+
store.toggleSelectedChannel(channels[channels.length - 1].chanId);
57+
expect(store.inferredDirection).toEqual(SwapDirection.IN);
58+
});
59+
60+
it('should infer the swap direction based on the selected channels (routing mode)', () => {
61+
rootStore.settingsStore.setBalanceMode(BalanceMode.routing);
62+
const channels = rootStore.channelStore.sortedChannels;
63+
let c = channels[0];
64+
c.localBalance = c.capacity.mul(0.2);
65+
c.remoteBalance = c.capacity.sub(c.localBalance);
66+
store.toggleSelectedChannel(c.chanId);
4667
expect(store.inferredDirection).toEqual(SwapDirection.IN);
68+
69+
c = channels[channels.length - 1];
70+
c.localBalance = c.capacity.mul(0.85);
71+
c.remoteBalance = c.capacity.sub(c.localBalance);
72+
store.toggleSelectedChannel(channels[channels.length - 1].chanId);
73+
expect(store.inferredDirection).toEqual(SwapDirection.OUT);
74+
});
75+
76+
it('should not infer the swap direction with no selected channels (routing mode)', () => {
77+
rootStore.settingsStore.setBalanceMode(BalanceMode.routing);
78+
expect(store.inferredDirection).toBeUndefined();
4779
});
4880

4981
it('should fetch loop terms', async () => {

app/src/store/stores/buildSwapStore.ts

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { SwapResponse } from 'types/generated/loop_pb';
33
import { BuildSwapSteps, Quote, SwapDirection, SwapTerms } from 'types/state';
44
import Big from 'big.js';
55
import { percentage } from 'util/bigmath';
6+
import { BalanceMode } from 'util/constants';
67
import { formatSats } from 'util/formatters';
78
import { prefixTranslation } from 'util/translate';
89
import { Store } from 'store';
@@ -134,17 +135,29 @@ class BuildSwapStore {
134135
/** infer a swap direction based on the selected channels */
135136
@computed
136137
get inferredDirection(): SwapDirection | undefined {
137-
if (this.selectedChanIds.length === 0) return undefined;
138-
139-
// calculate the average local balance percent
140-
const percents = values(this._store.channelStore.channels)
141-
.filter(c => this.selectedChanIds.includes(c.chanId))
142-
.map(c => c.localPercent);
143-
const sum = percents.reduce((s, p) => s + p, 0);
144-
const avgPct = sum / percents.length;
145-
146-
// if the average is low, suggest Loop In. Otherwise, suggest Loop Out
147-
return avgPct < 50 ? SwapDirection.IN : SwapDirection.OUT;
138+
const mode = this._store.settingsStore.balanceMode;
139+
switch (mode) {
140+
case BalanceMode.routing:
141+
// unable to infer a direction with no selection
142+
if (this.selectedChanIds.length === 0) return undefined;
143+
144+
// calculate the average local balance percent
145+
const percents = values(this._store.channelStore.channels)
146+
.filter(c => this.selectedChanIds.includes(c.chanId))
147+
.map(c => c.localPercent);
148+
const sum = percents.reduce((s, p) => s + p, 0);
149+
const avgPct = sum / percents.length;
150+
151+
// if the average is low, suggest Loop In. Otherwise, suggest Loop Out
152+
return avgPct < 50 ? SwapDirection.IN : SwapDirection.OUT;
153+
case BalanceMode.send:
154+
// always infer Loop In when using Sending mode
155+
return SwapDirection.IN;
156+
case BalanceMode.receive:
157+
default:
158+
// always suggest Loop Out when using Receiving mode
159+
return SwapDirection.OUT;
160+
}
148161
}
149162

150163
/**

0 commit comments

Comments
 (0)