Skip to content

Commit

Permalink
Refactor the calculation of fees
Browse files Browse the repository at this point in the history
  • Loading branch information
skubarenko committed Aug 24, 2022
1 parent 2564f57 commit 55cb1b3
Showing 1 changed file with 75 additions and 54 deletions.
129 changes: 75 additions & 54 deletions src/atomex/atomex.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import BigNumber from 'bignumber.js';

import type { AuthorizationManager } from '../authorization/index';
import type { AtomexProtocolV1, CurrencyInfo, WalletsManager } from '../blockchain/index';
import type { AtomexProtocolV1, CurrencyInfo, FeesInfo, WalletsManager } from '../blockchain/index';
import type { AtomexService, Currency } from '../common/index';
import { NewOrderRequest, ExchangeManager, symbolsHelper, OrderPreview } from '../exchange/index';
import type { Swap, SwapManager } from '../swaps/index';
Expand Down Expand Up @@ -286,66 +286,20 @@ export class Atomex implements AtomexService {
toAtomexProtocol.getInitiateFees({}),
fromAtomexProtocol.getRedeemFees({}),
]);
// TODO: use mixed rates providers
const [estimatedToInitiateFeesInFromCurrency, maxToInitiateFeesInFromCurrency] = await Promise.all([
this.exchangeManager.getOrderPreview({
type: 'SolidFillOrKill',
from: toNativeCurrencyInfo.currency.id,
to: fromCurrencyInfo.currency.id,
amount: toInitiateFees.estimated,
isFromAmount: true
}).then(orderPreview => orderPreview?.to.amount),

this.exchangeManager.getOrderPreview({
type: 'SolidFillOrKill',
from: toNativeCurrencyInfo.currency.id,
to: fromCurrencyInfo.currency.id,
amount: toInitiateFees.max,
isFromAmount: true
}).then(orderPreview => orderPreview?.to.amount)
]);
if (!estimatedToInitiateFeesInFromCurrency || !maxToInitiateFeesInFromCurrency)
throw new Error('It\'s no possible to calculate maker fee');

let estimatedFromRedeemFeesInFromNativeCurrency: BigNumber | undefined;
let maxFromRedeemFeesInFromNativeCurrency: BigNumber | undefined;
if (fromCurrencyInfo.currency.id !== fromNativeCurrencyInfo.currency.id) {
[estimatedFromRedeemFeesInFromNativeCurrency, maxFromRedeemFeesInFromNativeCurrency] = await Promise.all([
this.exchangeManager.getOrderPreview({
type: 'SolidFillOrKill',
from: fromNativeCurrencyInfo.currency.id,
to: fromCurrencyInfo.currency.id,
amount: fromRedeemFees.estimated,
isFromAmount: true
}).then(orderPreview => orderPreview?.to.amount),
this.exchangeManager.getOrderPreview({
type: 'SolidFillOrKill',
from: fromNativeCurrencyInfo.currency.id,
to: fromCurrencyInfo.currency.id,
amount: fromRedeemFees.max,
isFromAmount: true
}).then(orderPreview => orderPreview?.to.amount)
]);
}
else {
estimatedFromRedeemFeesInFromNativeCurrency = fromRedeemFees.estimated;
maxFromRedeemFeesInFromNativeCurrency = fromRedeemFees.max;
}
if (!estimatedFromRedeemFeesInFromNativeCurrency || !maxFromRedeemFeesInFromNativeCurrency)
throw new Error('It\'s no possible to calculate maker fee');

const paymentFee: SwapPreviewFee = {
name: 'payment-fee',
currencyId: fromNativeCurrencyInfo.currency.id,
estimated: fromInitiateFees.estimated,
max: fromInitiateFees.max,
};
const makerFee: SwapPreviewFee = {
name: 'maker-fee',
currencyId: fromCurrencyInfo.currency.id,
estimated: estimatedToInitiateFeesInFromCurrency.plus(estimatedFromRedeemFeesInFromNativeCurrency),
max: maxToInitiateFeesInFromCurrency.plus(maxFromRedeemFeesInFromNativeCurrency)
};
const makerFee = await this.calculateMakerFees(
fromCurrencyInfo.currency.id,
fromNativeCurrencyInfo.currency.id,
toNativeCurrencyInfo.currency.id,
toInitiateFees,
fromRedeemFees
);

return {
success: [
Expand All @@ -370,4 +324,71 @@ export class Atomex implements AtomexService {
]
};
}

private async calculateMakerFees(
fromCurrencyId: Currency['id'],
fromNativeCurrencyId: Currency['id'],
toNativeCurrencyId: Currency['id'],
toInitiateFees: FeesInfo,
fromRedeemFees: FeesInfo
): Promise<SwapPreviewFee> {
const toInitiateFeeConversationPromise = this.convertFeesToFromCurrency(toInitiateFees, toNativeCurrencyId, fromCurrencyId);
const fromRedeemFeeConversationPromise = fromCurrencyId !== fromNativeCurrencyId
? this.convertFeesToFromCurrency(fromRedeemFees, fromNativeCurrencyId, fromCurrencyId)
: undefined;

let estimatedToInitiateFeesInFromCurrency: BigNumber;
let maxToInitiateFeesInFromCurrency: BigNumber;
let estimatedFromRedeemFeesInFromCurrency: BigNumber;
let maxFromRedeemFeesInFromCurrency: BigNumber;
if (fromRedeemFeeConversationPromise) {
const conversationResult = await Promise.all([toInitiateFeeConversationPromise, fromRedeemFeeConversationPromise]);
estimatedToInitiateFeesInFromCurrency = conversationResult[0].estimated;
maxToInitiateFeesInFromCurrency = conversationResult[0].max;
estimatedFromRedeemFeesInFromCurrency = conversationResult[1].estimated;
maxFromRedeemFeesInFromCurrency = conversationResult[1].max;
}
else {
const conversationResult = await toInitiateFeeConversationPromise;
estimatedToInitiateFeesInFromCurrency = conversationResult.estimated;
maxToInitiateFeesInFromCurrency = conversationResult.max;
estimatedFromRedeemFeesInFromCurrency = fromRedeemFees.estimated;
maxFromRedeemFeesInFromCurrency = fromRedeemFees.max;
}

return {
name: 'maker-fee',
currencyId: fromCurrencyId,
estimated: estimatedToInitiateFeesInFromCurrency.plus(estimatedFromRedeemFeesInFromCurrency),
max: maxToInitiateFeesInFromCurrency.plus(maxFromRedeemFeesInFromCurrency)
};
}

private async convertFeesToFromCurrency(fees: FeesInfo, from: Currency['id'], to: Currency['id']): Promise<FeesInfo> {
const [estimatedInFromCurrency, maxInFromCurrency] = await Promise.all([
this.exchangeManager.getOrderPreview({
type: 'SolidFillOrKill',
from,
to,
amount: fees.estimated,
isFromAmount: true
}).then(orderPreview => orderPreview?.to.amount),

this.exchangeManager.getOrderPreview({
type: 'SolidFillOrKill',
from,
to,
amount: fees.max,
isFromAmount: true
}).then(orderPreview => orderPreview?.to.amount)
]);

if (!estimatedInFromCurrency || !maxInFromCurrency)
throw new Error(`It's no possible to convert fees from "${from}" to "${to}" currency`);

return {
estimated: estimatedInFromCurrency,
max: maxInFromCurrency
};
}
}

0 comments on commit 55cb1b3

Please sign in to comment.