@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
102 lines • 4.49 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAmountFromUSD = getAmountFromUSD;
exports.getMinimumSwapAmount = getMinimumSwapAmount;
const index_1 = require("./index");
const axios_1 = __importDefault(require("axios"));
// Target a sensible USD amount that works for most pairs
const FALLBACK_TARGET_USD = 50;
const COUNTERVALUES_URL = "https://countervalues.live.ledger.com/v3/spot/simple";
const SWAP_QUOTE_URL = "https://swap-stg.ledger-test.com/v5/quote";
/** Smallest amount sent to the quote API to discover minimum thresholds. */
const PROBE_AMOUNT = 0.0001;
const PROBE_NETWORK_FEES = 0.001;
const PROVIDERS_WHITELIST = "changelly_v2,exodus,thorswap,uniswap,cic_v2,nearintents,swapsxyz";
function isQuoteErrorItem(item) {
return typeof item === "object" && item !== null && "parameter" in item;
}
/**
* Fetches the current USD price for a currency from the Ledger countervalues API
* and converts a target USD value into the equivalent crypto amount.
*/
async function getAmountFromUSD(currencyId, targetUSD) {
try {
const { data } = await axios_1.default.get(COUNTERVALUES_URL, {
params: {
froms: currencyId,
to: "USD",
},
});
const price = data?.[currencyId];
if (!price || price <= 0) {
console.warn(`No USD price found for ${currencyId}`);
return null;
}
return targetUSD / price;
}
catch (error) {
console.warn(`Failed to fetch countervalue for ${currencyId}:`, (0, index_1.sanitizeError)(error));
return null;
}
}
async function getMinimumSwapAmount(accountFrom, accountTo, providersWhitelist) {
try {
const addressFrom = accountFrom.address || accountFrom.parentAccount?.address;
if (!addressFrom) {
throw new Error("No address available from accounts when requesting minimum swap amount.");
}
const requestConfig = {
method: "GET",
url: SWAP_QUOTE_URL,
params: {
from: accountFrom.currency.id,
to: accountTo.currency.id,
amountFrom: PROBE_AMOUNT,
addressFrom,
fiatForCounterValue: "USD",
slippage: 1,
networkFees: PROBE_NETWORK_FEES,
networkFeesCurrency: accountTo.currency.speculosApp.name.toLowerCase(),
displayLanguage: "en",
theme: "light",
"providers-whitelist": providersWhitelist?.join(",") ?? PROVIDERS_WHITELIST,
tradeType: "INPUT",
uniswapOrderType: "uniswapxv1",
},
headers: { accept: "application/json" },
};
const { data } = await (0, axios_1.default)(requestConfig);
if (!Array.isArray(data)) {
console.warn("Unexpected quote API response, falling back to countervalues");
return await getAmountFromUSD(accountFrom.currency.id, FALLBACK_TARGET_USD);
}
// Try to extract minAmount from AMOUNT_OFF_LIMITS errors
const minimumAmounts = data
.filter(isQuoteErrorItem)
.filter(item => item.parameter?.minAmount !== undefined)
.map(item => Number.parseFloat(item.parameter.minAmount))
.filter((amount) => !Number.isNaN(amount) && amount > 0);
if (minimumAmounts.length > 0) {
return Math.max(...minimumAmounts);
}
// No minAmount returned — compute a sensible fallback from countervalues
console.warn(`No minAmount from quote API for ${accountFrom.currency.id} → ${accountTo.currency.id}, ` +
`computing fallback from countervalues (~$${FALLBACK_TARGET_USD} USD)`);
return await getAmountFromUSD(accountFrom.currency.id, FALLBACK_TARGET_USD);
}
catch (error) {
const sanitizedError = (0, index_1.sanitizeError)(error);
console.warn("Error fetching swap minimum amount:", sanitizedError);
// Last resort: try to compute a sensible amount even if the quote call failed entirely
try {
return await getAmountFromUSD(accountFrom.currency.id, FALLBACK_TARGET_USD);
}
catch {
return null;
}
}
}
//# sourceMappingURL=swap.js.map