UNPKG

@ledgerhq/live-common

Version:
127 lines 6.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const network_1 = __importDefault(require("@ledgerhq/live-network/network")); const bignumber_js_1 = require("bignumber.js"); const account_1 = require("../../account"); const currencies_1 = require("../../currencies"); const errors_1 = require("../../errors"); const _1 = require("./"); const mock_1 = require("./mock"); const isIntegrationTestEnv_1 = require("./utils/isIntegrationTestEnv"); const swap_1 = require("../providers/swap"); const getExchangeRates = async ({ exchange, transaction, currencyTo, providers = [], timeout, timeoutErrorMessage, }) => { if ((0, isIntegrationTestEnv_1.isIntegrationTestEnv)()) return (0, mock_1.mockGetExchangeRates)(exchange, transaction, currencyTo); const from = (0, account_1.getAccountCurrency)(exchange.fromAccount).id; const unitFrom = (0, account_1.getAccountCurrency)(exchange.fromAccount).units[0]; const to = (currencyTo ?? (0, account_1.getAccountCurrency)(exchange.toAccount)).id; const unitTo = (currencyTo && currencyTo.units[0]) ?? (0, account_1.getAccountCurrency)(exchange.toAccount).units[0]; const amountFrom = transaction.amount; const tenPowMagnitude = new bignumber_js_1.BigNumber(10).pow(unitFrom.magnitude); const apiAmount = new bignumber_js_1.BigNumber(amountFrom).div(tenPowMagnitude); const providerList = providers .filter(provider => provider.pairs.some(pair => pair.from === from && pair.to === to)) .map(item => item.provider); const request = { from, to, amountFrom: apiAmount.toString(), providers: providerList, }; const headers = (0, _1.getSwapUserIP)(); const res = await (0, network_1.default)({ method: "POST", url: `${(0, _1.getSwapAPIBaseURL)()}/rate`, ...(timeout ? { timeout } : {}), ...(timeoutErrorMessage ? { timeoutErrorMessage } : {}), data: request, ...(headers !== undefined ? headers : {}), }); const rates = res.data.map(async (responseData) => { const { rate: maybeRate, payoutNetworkFees: maybePayoutNetworkFees, rateId, provider, providerType, amountFrom, amountTo, tradeMethod, providerURL, expirationTime, } = responseData; const error = await inferError(apiAmount, unitFrom, responseData); if (error) { return { provider, tradeMethod, error, }; } const payoutNetworkFees = new bignumber_js_1.BigNumber(maybePayoutNetworkFees || 0); const magnitudeAwarePayoutNetworkFees = payoutNetworkFees.times(new bignumber_js_1.BigNumber(10).pow(unitTo.magnitude)); const rate = maybeRate ? new bignumber_js_1.BigNumber(maybeRate) : new bignumber_js_1.BigNumber(amountTo).minus(payoutNetworkFees).div(amountFrom); // NB Allows us to simply multiply satoshi values from/to const magnitudeAwareRate = rate.div(new bignumber_js_1.BigNumber(10).pow(unitFrom.magnitude - unitTo.magnitude)); const toAmount = new bignumber_js_1.BigNumber(amountTo).minus(payoutNetworkFees); const magnitudeAwareToAmount = toAmount.times(new bignumber_js_1.BigNumber(10).pow(unitTo.magnitude)); // Nb no longer need to break it down on UI const out = { magnitudeAwareRate, provider, providerType, rate, rateId, expirationTime, toAmount: magnitudeAwareToAmount, tradeMethod, providerURL, }; if (tradeMethod === "fixed") { return { ...out, payoutNetworkFees: magnitudeAwarePayoutNetworkFees, rateId, }; } else { return { ...out, payoutNetworkFees: magnitudeAwarePayoutNetworkFees, }; } }); return rates; }; const inferError = async (apiAmount, unitFrom, responseData) => { const tenPowMagnitude = new bignumber_js_1.BigNumber(10).pow(unitFrom.magnitude); const { amountTo, minAmountFrom, maxAmountFrom, errorCode, errorMessage, provider, status } = responseData; const isDex = (await (0, swap_1.getSwapProvider)(provider)).type === "DEX"; // DEX quotes are out of limits error. We do not know if it is a low or high limit, neither the amount. if ((!minAmountFrom || !maxAmountFrom) && status === "error" && errorCode !== 300 && isDex) { return new errors_1.SwapExchangeRateAmountTooLowOrTooHigh(undefined, { message: "", }); } if (!amountTo) { // We are in an error case regardless of api version. if (errorCode) { return (0, _1.getSwapAPIError)(errorCode, errorMessage); } // For out of range errors we will have a min/max pairing const hasAmountLimit = minAmountFrom || maxAmountFrom; if (hasAmountLimit) { const isTooSmall = minAmountFrom ? new bignumber_js_1.BigNumber(apiAmount).lte(minAmountFrom) : false; const MinOrMaxError = isTooSmall ? errors_1.SwapExchangeRateAmountTooLow : errors_1.SwapExchangeRateAmountTooHigh; const key = isTooSmall ? "minAmountFromFormatted" : "maxAmountFromFormatted"; const amount = isTooSmall ? minAmountFrom : maxAmountFrom; return new MinOrMaxError(undefined, { [key]: (0, currencies_1.formatCurrencyUnit)(unitFrom, new bignumber_js_1.BigNumber(amount).times(tenPowMagnitude), { alwaysShowSign: false, disableRounding: true, showCode: true, }), amount: new bignumber_js_1.BigNumber(amount), }); } } return; }; exports.default = getExchangeRates; //# sourceMappingURL=getExchangeRates.js.map