Skip to content

Commit 1884da8

Browse files
authored
Merge pull request #3 from diamondhands-dev/develop
Develop
2 parents 9bcf0dc + ae50190 commit 1884da8

File tree

9 files changed

+70
-5
lines changed

9 files changed

+70
-5
lines changed

docs/deployment.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ otpsecretpath = "/home/boltz/.boltz/otpSecret.dat"
9292
# - Kraken
9393
# - Poloniex
9494
# - "fee": percentage of the swapped amount that should be charged as fee
95+
# - "swapInFee" (optional): percentage of the swapped in amount that should be charged as fee
96+
# "fee" is applied if this is not configured
9597

9698
[[pairs]]
9799
base = "LTC"
@@ -109,6 +111,7 @@ base = "LTC"
109111
quote = "LTC"
110112
rate = 1
111113
fee = 0.5
114+
swapInFee = 1.0
112115
timeoutDelta = 300
113116

114117
# The array "currencies" configures the chain and LND clients for the "pairs"

docs/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
jinja2<3.1.0
2+
Markdown<3.2

lib/consts/Types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export type PairConfig = {
3131

3232
// Percentage of the amount that will be charged as fee
3333
fee?: number;
34+
swapInFee?: number;
3435

3536
// If there is a hardcoded rate the APIs of the exchanges will not be queried
3637
rate?: number;

lib/rates/FeeProvider.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type MinerFees = {
1919
class FeeProvider {
2020
// A map between the symbols of the pairs and their percentage fees
2121
public percentageFees = new Map<string, number>();
22+
public percentageSwapInFees = new Map<string, number>();
2223

2324
public minerFees = new Map<string, MinerFees>();
2425

@@ -65,6 +66,9 @@ class FeeProvider {
6566
}
6667

6768
this.percentageFees.set(getPairId(pair), percentage / 100);
69+
70+
const percentageSwapIn = pair.swapInFee !== undefined ? pair.swapInFee : 0;
71+
this.percentageSwapInFees.set(getPairId(pair), percentageSwapIn / 100);
6872
});
6973

7074
this.logger.debug(`Prepared data for fee estimations: ${stringify(mapToObject(this.percentageFees))}`);
@@ -74,6 +78,10 @@ class FeeProvider {
7478
return this.percentageFees.get(pair) || 0;
7579
};
7680

81+
public getPercentageSwapInFee = (pair: string): number => {
82+
return this.percentageSwapInFees.get(pair) || 0;
83+
};
84+
7785
public getFees = (
7886
pair: string,
7987
rate: number,
@@ -83,18 +91,25 @@ class FeeProvider {
8391
): {
8492
baseFee: number,
8593
percentageFee: number,
94+
percentageSwapInFee: number,
8695
} => {
8796
let percentageFee = this.getPercentageFee(pair);
97+
let percentageSwapInFee = this.getPercentageSwapInFee(pair);
8898

8999
if (percentageFee !== 0) {
90100
percentageFee = percentageFee * amount * rate;
91101
}
92102

103+
if (percentageSwapInFee !== 0) {
104+
percentageSwapInFee = percentageSwapInFee * amount * rate;
105+
}
106+
93107
const { base, quote } = splitPairId(pair);
94108
const chainCurrency = getChainCurrency(base, quote, orderSide, type !== BaseFeeType.NormalClaim);
95109

96110
return {
97111
percentageFee: Math.ceil(percentageFee),
112+
percentageSwapInFee: Math.ceil(percentageSwapInFee),
98113
baseFee: this.getBaseFee(chainCurrency, type),
99114
};
100115
};

lib/rates/RateProvider.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ type PairType = {
3737
};
3838
fees: {
3939
percentage: number;
40+
swapInFee: number;
4041
minerFees: {
4142
baseAsset: MinerFees,
4243
quoteAsset: MinerFees,
@@ -64,6 +65,7 @@ class RateProvider {
6465

6566
// A copy of the "percentageFees" Map in the FeeProvider but all values are multiplied with 100
6667
private percentageFees = new Map<string, number>();
68+
private percentageSwapInFees = new Map<string, number>();
6769

6870
private timer!: any;
6971

@@ -83,6 +85,11 @@ class RateProvider {
8385
this.percentageFees.set(pair, percentage * 100);
8486
});
8587

88+
this.feeProvider.percentageSwapInFees.forEach((swapInFee, pair) => {
89+
// Multiply with 100 to get the percentage
90+
this.percentageSwapInFees.set(pair, swapInFee * 100);
91+
});
92+
8693
await this.updateMinerFees();
8794

8895
pairs.forEach((pair) => {
@@ -99,6 +106,7 @@ class RateProvider {
99106
limits: this.getLimits(id, pair.base, pair.quote, pair.rate),
100107
fees: {
101108
percentage: this.percentageFees.get(id)!,
109+
swapInFee: this.percentageSwapInFees.get(id)!,
102110
minerFees: {
103111
baseAsset: emptyMinerFees,
104112
quoteAsset: emptyMinerFees,
@@ -189,6 +197,7 @@ class RateProvider {
189197
hash: '',
190198
fees: {
191199
percentage: this.percentageFees.get(pairId)!,
200+
swapInFee: this.percentageSwapInFees.get(pairId)!,
192201
minerFees: {
193202
baseAsset: this.feeProvider.minerFees.get(base)!,
194203
quoteAsset: this.feeProvider.minerFees.get(quote)!,

lib/service/Service.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -674,9 +674,13 @@ class Service {
674674

675675
const rate = getRate(swap.rate!, swap.orderSide, false);
676676

677-
const percentageFee = this.rateProvider.feeProvider.getPercentageFee(swap.pair);
677+
let percentageFee = this.rateProvider.feeProvider.getPercentageFee(swap.pair);
678+
const percentageSwapInFee = this.rateProvider.feeProvider.getPercentageSwapInFee(swap.pair);
678679
const baseFee = this.rateProvider.feeProvider.getBaseFee(onchainCurrency, BaseFeeType.NormalClaim);
679680

681+
if (percentageSwapInFee !== 0) {
682+
percentageFee = percentageSwapInFee;
683+
}
680684
const invoiceAmount = this.calculateInvoiceAmount(swap.orderSide, rate, swap.onchainAmount, baseFee, percentageFee);
681685

682686
this.verifyAmount(swap.pair, rate, invoiceAmount, swap.orderSide, false);
@@ -730,22 +734,27 @@ class Service {
730734

731735
this.verifyAmount(swap.pair, rate, invoiceAmount, swap.orderSide, false);
732736

733-
const { baseFee, percentageFee } = this.rateProvider.feeProvider.getFees(
737+
const { baseFee, percentageFee, percentageSwapInFee } = this.rateProvider.feeProvider.getFees(
734738
swap.pair,
735739
rate,
736740
swap.orderSide,
737741
invoiceAmount,
738742
BaseFeeType.NormalClaim,
739743
);
740-
const expectedAmount = Math.floor(invoiceAmount * rate) + baseFee + percentageFee;
744+
745+
let serviceFee = percentageFee;
746+
if (percentageSwapInFee !== 0) {
747+
serviceFee = percentageSwapInFee;
748+
}
749+
const expectedAmount = Math.floor(invoiceAmount * rate) + baseFee + serviceFee;
741750

742751
if (swap.onchainAmount && expectedAmount > swap.onchainAmount) {
743752
const maxInvoiceAmount = this.calculateInvoiceAmount(
744753
swap.orderSide,
745754
rate,
746755
swap.onchainAmount,
747756
baseFee,
748-
this.rateProvider.feeProvider.getPercentageFee(swap.pair),
757+
Math.max(this.rateProvider.feeProvider.getPercentageFee(swap.pair),this.rateProvider.feeProvider.getPercentageSwapInFee(swap.pair)),
749758
);
750759

751760
throw Errors.INVALID_INVOICE_AMOUNT(maxInvoiceAmount);
@@ -757,7 +766,7 @@ class Service {
757766
swap,
758767
invoice,
759768
expectedAmount,
760-
percentageFee,
769+
serviceFee,
761770
acceptZeroConf,
762771
this.eventHandler.emitSwapInvoiceSet,
763772
);

test/unit/rates/FeeProvider.spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,21 @@ describe('FeeProvider', () => {
3434
base: 'LTC',
3535
quote: 'BTC',
3636
fee: 2,
37+
swapInFee: -1,
3738
},
3839
{
3940
base: 'BTC',
4041
quote: 'BTC',
4142
fee: 0,
43+
swapInFee: -1,
4244
},
4345
{
4446
base: 'LTC',
4547
quote: 'LTC',
4648

4749
// The FeeProvider should set this to 1
4850
fee: undefined,
51+
swapInFee: undefined,
4952
},
5053
]);
5154

@@ -112,11 +115,13 @@ describe('FeeProvider', () => {
112115
expect(feeProvider.getFees('LTC/BTC', 2, OrderSide.BUY, amount, BaseFeeType.NormalClaim)).toEqual({
113116
baseFee: 6120,
114117
percentageFee: 4000000,
118+
percentageSwapInFee: -2000000,
115119
});
116120

117121
expect(feeProvider.getFees('LTC/BTC', 2, OrderSide.BUY, amount, BaseFeeType.ReverseLockup)).toEqual({
118122
baseFee: 459,
119123
percentageFee: 4000000,
124+
percentageSwapInFee: -2000000,
120125
});
121126
});
122127

test/unit/rates/RateProvider.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ const percentageFees = new Map<string, number>([
2525
['BTC/BTC', 0.005],
2626
]);
2727

28+
const percentageSwapInFees = new Map<string, number>([
29+
['LTC/BTC', 0.01],
30+
['BTC/BTC', -0.01],
31+
]);
32+
2833
const minerFees = new Map<string, MinerFees>([
2934
[
3035
'BTC',
@@ -70,6 +75,7 @@ jest.mock('../../../lib/rates/FeeProvider', () => {
7075
return {
7176
minerFees,
7277
percentageFees,
78+
percentageSwapInFees,
7379
getBaseFee: mockGetBaseFee,
7480
updateMinerFees: mockUpdateMinerFees,
7581
};
@@ -196,6 +202,14 @@ describe('RateProvider', () => {
196202
});
197203
});
198204

205+
test('should get percentage fees for swapin', () => {
206+
const { pairs } = rateProvider;
207+
208+
percentageSwapInFees.forEach((_, pairId) => {
209+
expect(pairs.get(pairId)!.fees.swapInFee).toEqual(percentageSwapInFees.get(pairId)! * 100);
210+
});
211+
});
212+
199213
test('should get miner fees', () => {
200214
const { pairs } = rateProvider;
201215

test/unit/service/Service.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ const mockInitFeeProvider = jest.fn().mockReturnValue(undefined);
240240
const mockGetFees = jest.fn().mockReturnValue({
241241
baseFee: 1,
242242
percentageFee: 1,
243+
percentageSwapInFee: 0,
243244
});
244245

245246
const mockGetBaseFeeResult = 320;
@@ -248,12 +249,16 @@ const mockGetBaseFee = jest.fn().mockReturnValue(mockGetBaseFeeResult);
248249
const mockGetPercentageFeeResult = 0.02;
249250
const mockGetPercentageFee = jest.fn().mockReturnValue(mockGetPercentageFeeResult);
250251

252+
const mockGetPercentageSwapInFeeResult = 0.02;
253+
const mockGetPercentageSwapInFee = jest.fn().mockReturnValue(mockGetPercentageSwapInFeeResult);
254+
251255
jest.mock('../../../lib/rates/FeeProvider', () => {
252256
return jest.fn().mockImplementation(() => ({
253257
init: mockInitFeeProvider,
254258
getFees: mockGetFees,
255259
getBaseFee: mockGetBaseFee,
256260
getPercentageFee: mockGetPercentageFee,
261+
getPercentageSwapInFee: mockGetPercentageSwapInFee,
257262
}));
258263
});
259264

@@ -965,6 +970,7 @@ describe('Service', () => {
965970
})).rejects.toEqual(Errors.SWAP_WITH_PREIMAGE_EXISTS());
966971
});
967972

973+
// TODO: Add anohter test for swapInFee
968974
test('should get swap rates', async () => {
969975
const id = 'id';
970976

@@ -993,6 +999,7 @@ describe('Service', () => {
993999
await expect(service.getSwapRates(id)).rejects.toEqual(Errors.SWAP_NOT_FOUND(id));
9941000
});
9951001

1002+
// TODO: Add anohter test for swapInFee
9961003
test('should set invoices of swaps', async () => {
9971004
mockGetSwapResult = {
9981005
id: 'invoiceId',

0 commit comments

Comments
 (0)