Skip to content

Commit

Permalink
feat: include max routing fee in submarine pairs when queried with ref (
Browse files Browse the repository at this point in the history
  • Loading branch information
michael1011 authored Jan 9, 2025
1 parent 50cb625 commit 9dd6d50
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 28 deletions.
11 changes: 11 additions & 0 deletions lib/db/models/Referral.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,17 @@ class Referral extends Model implements ReferralType {
);
};

public maxRoutingFeeRatioForPairs = (pairs: string[]): number | undefined => {
for (const pair of pairs) {
const ratio = this.config?.pairs?.[pair]?.maxRoutingFee;
if (ratio !== undefined) {
return ratio;
}
}

return this.config?.maxRoutingFee;
};

public limits = (pair: string, type: SwapType): Limits | undefined => {
return (
this.config?.pairs?.[pair]?.limits?.[type] || this.config?.limits?.[type]
Expand Down
2 changes: 2 additions & 0 deletions lib/lightning/LightningClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ interface LightningClient extends BalancerFetcher, BaseClient<EventTypes> {
symbol: string;
type: NodeType;

readonly maxPaymentFeeRatio: number;

isConnected(): boolean;

setClientStatus(status: ClientStatus): void;
Expand Down
3 changes: 2 additions & 1 deletion lib/lightning/LndClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ class LndClient extends BaseClient<EventTypes> implements LightningClient {
private static readonly paymentTimeout = 300;
private static readonly paymentTimePreference = 0.9;

public readonly maxPaymentFeeRatio!: number;

private readonly uri!: string;
private readonly maxPaymentFeeRatio!: number;
private readonly credentials!: ChannelCredentials;

private readonly meta!: Metadata;
Expand Down
2 changes: 1 addition & 1 deletion lib/lightning/cln/ClnClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class ClnClient
private static readonly paymentMinFee = 121;
private static readonly paymentTimeout = 300;

private readonly maxPaymentFeeRatio!: number;
public readonly maxPaymentFeeRatio!: number;

private readonly nodeUri: string;
private readonly holdUri: string;
Expand Down
67 changes: 42 additions & 25 deletions lib/rates/providers/RateProviderTaproot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type SubmarinePairTypeTaproot = PairTypeTaproot & {
fees: {
percentage: number;
minerFees: number;
maximalRoutingFee?: number;
};
};

Expand Down Expand Up @@ -512,32 +513,48 @@ class RateProviderTaproot extends RateProviderBase<SwapTypes> {
const premium = referral?.premiumForPairs(pairIds, type);
const limits = referral?.limitsForPairs(pairIds, type);

return [
to,
{
...value,
limits: {
...value.limits,
minimal: this.applyOverride(
Math.max,
value.limits.minimal,
limits?.minimal,
),
maximal: this.applyOverride(
Math.min,
value.limits.maximal,
limits?.maximal,
),
},
fees: {
...value.fees,
percentage: FeeProvider.addPremium(
value.fees.percentage,
premium,
),
},
const result = {
...value,
limits: {
...value.limits,
minimal: this.applyOverride(
Math.max,
value.limits.minimal,
limits?.minimal,
),
maximal: this.applyOverride(
Math.min,
value.limits.maximal,
limits?.maximal,
),
},
];
fees: {
...value.fees,
percentage: FeeProvider.addPremium(
value.fees.percentage,
premium,
),
},
};

if (type === SwapType.Submarine) {
const maxRoutingFeeOverride =
referral?.maxRoutingFeeRatioForPairs(pairIds);

if (maxRoutingFeeOverride !== undefined) {
(result as SubmarinePairTypeTaproot).fees.maximalRoutingFee =
maxRoutingFeeOverride * 100;
} else {
const currency = this.currencies.get(to);

(result as SubmarinePairTypeTaproot).fees.maximalRoutingFee =
(currency?.lndClient?.maxPaymentFeeRatio ||
currency?.clnClient?.maxPaymentFeeRatio ||
0) * 100;
}
}

return [to, result];
}),
),
]),
Expand Down
16 changes: 16 additions & 0 deletions test/integration/db/models/Referral.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,22 @@ describe('Referral', () => {
expect(ref!.maxRoutingFeeRatio(pair)).toEqual(expected);
});

test.each`
pairs | expected
${['BTC/BTC']} | ${referralValues.config!.maxRoutingFee}
${['L-BTC/BTC']} | ${referralValues.config!.maxRoutingFee}
${['RBTC/BTC']} | ${referralValues.config!.pairs!['RBTC/BTC']!.maxRoutingFee}
${['BTC/BTC', 'RBTC/BTC']} | ${referralValues.config!.pairs!['RBTC/BTC']!.maxRoutingFee}
`(
'should get maxRoutingFeeRatioForPairs for pairs $pairs',
async ({ pairs, expected }) => {
const ref = await ReferralRepository.getReferralById(referralValues.id);

expect(ref).not.toBeNull();
expect(ref!.maxRoutingFeeRatioForPairs(pairs)).toEqual(expected);
},
);

test.each`
pair | type | expected
${'BTC/BTC'} | ${SwapType.ReverseSubmarine} | ${referralValues.config!.limits![SwapType.ReverseSubmarine]}
Expand Down
38 changes: 37 additions & 1 deletion test/unit/rates/providers/RateProviderTaproot.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,15 @@ describe('RateProviderTaproot', () => {

const provider = new RateProviderTaproot(
new Map<string, any>([
['BTC', { chainClient: {}, lndClient: {} }],
[
'BTC',
{
chainClient: {},
lndClient: {
maxPaymentFeeRatio: 0.021,
},
},
],
[
'L-BTC',
{
Expand Down Expand Up @@ -125,6 +133,7 @@ describe('RateProviderTaproot', () => {
const referral = {
premiumForPairs: jest.fn().mockReturnValue(premium),
limitsForPairs: jest.fn().mockReturnValue(undefined),
maxRoutingFeeRatioForPairs: jest.fn().mockReturnValue(undefined),
} as any as Referral;

expect(
Expand Down Expand Up @@ -168,6 +177,7 @@ describe('RateProviderTaproot', () => {

const referral = {
premiumForPairs: jest.fn().mockReturnValue(undefined),
maxRoutingFeeRatioForPairs: jest.fn().mockReturnValue(undefined),
limitsForPairs: jest.fn().mockReturnValue({
minimal: limitMin,
maximal: limitMax,
Expand All @@ -191,6 +201,32 @@ describe('RateProviderTaproot', () => {
expect(originalPair.limits.maximal).toEqual(initialMax);
},
);

test('should use maxRoutingFeeRatioForPairs when provided', () => {
const referral = {
limitsForPairs: jest.fn().mockReturnValue(undefined),
premiumForPairs: jest.fn().mockReturnValue(undefined),
maxRoutingFeeRatioForPairs: jest.fn().mockReturnValue(0.01),
} as any as Referral;

const pairWithReferral = provider
.getSubmarinePairs(referral)
.get('L-BTC')!
.get('BTC')!;
expect(pairWithReferral.fees.maximalRoutingFee).toEqual(1);
});

test('should coalesce max routing fee from lightning clients when not provided in referral', () => {
const pairWithReferral = provider
.getSubmarinePairs({
limitsForPairs: jest.fn().mockReturnValue(undefined),
premiumForPairs: jest.fn().mockReturnValue(undefined),
maxRoutingFeeRatioForPairs: jest.fn().mockReturnValue(undefined),
} as any as Referral)
.get('L-BTC')!
.get('BTC')!;
expect(pairWithReferral.fees.maximalRoutingFee).toEqual(2.1);
});
});

test('should serialize pairs', () => {
Expand Down

0 comments on commit 9dd6d50

Please sign in to comment.