@reservoir0x/relay-kit-ui
Version:
Relay is the Fastest and Cheapest Way to Bridge and Transact Across Chains.
262 lines • 10.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateUsdValue = exports.getSwapEventData = exports.getCurrentStep = exports.appendMetadataToRequest = exports.calculatePriceTimeEstimate = exports.extractDepositAddress = exports.extractQuoteId = exports.isHighRelayerServiceFeeUsd = exports.calculateRelayerFeeProportion = exports.calculateRelayerFeeProportionUsd = exports.parseFees = void 0;
const tslib_1 = require("tslib");
const numbers_js_1 = require("./numbers.js");
const time_js_1 = require("./time.js");
const bitcoin_js_1 = require("../utils/bitcoin.js");
const axios_1 = tslib_1.__importDefault(require("axios"));
const hashing_js_1 = require("./hashing.js");
const formatUsdFee = (amountUsd, shouldFlipSign = false) => {
const value = Number(amountUsd ?? 0);
const finalValue = shouldFlipSign ? -value : value;
return {
value: finalValue,
formatted: (0, numbers_js_1.formatDollar)(finalValue)
};
};
const parseFees = (selectedTo, selectedFrom, quote) => {
const fees = quote?.fees;
const gasFee = BigInt(fees?.gas?.amount ?? 0);
const formattedGasFee = (0, numbers_js_1.formatBN)(gasFee, 5, Number(fees?.gas?.currency?.decimals ?? 18));
const relayerGasFee = BigInt(fees?.relayerGas?.amount ?? 0);
const formattedRelayerGas = (0, numbers_js_1.formatBN)(relayerGasFee, 5, Number(fees?.relayerGas?.currency?.decimals ?? 18));
const relayerFee = BigInt(fees?.relayerService?.amount ?? 0);
const relayerFeeIsReward = relayerFee < 0;
const formattedRelayer = relayerFeeIsReward
? (0, numbers_js_1.formatBN)(BigInt(fees?.relayerService?.amount?.replace('-', '') ?? 0), 5, Number(fees?.relayerService?.currency?.decimals ?? 18))
: (0, numbers_js_1.formatBN)(relayerFee, 5, Number(fees?.relayerService?.currency?.decimals ?? 18));
const appFee = BigInt(fees?.app?.amount ?? 0);
const totalFeesUsd = Number(fees?.relayer?.amountUsd ?? 0) + Number(fees?.app?.amountUsd ?? 0);
const breakdown = [
{
raw: gasFee,
formatted: `${formattedGasFee}`,
usd: formatUsdFee(fees?.gas?.amountUsd, true),
name: `Deposit Gas (${selectedFrom.displayName})`,
tooltip: null,
type: 'gas',
id: 'origin-gas',
currency: fees?.gas?.currency
},
{
raw: relayerGasFee,
formatted: `${formattedRelayerGas}`,
usd: formatUsdFee(fees?.relayerGas?.amountUsd, true),
name: `Fill Gas (${selectedTo.displayName})`,
tooltip: null,
type: 'gas',
id: 'destination-gas',
currency: fees?.relayerGas?.currency
},
{
raw: relayerFee,
formatted: `${relayerFeeIsReward ? '+' : '-'}${formattedRelayer}`,
usd: formatUsdFee(fees?.relayerService?.amountUsd, true),
name: relayerFeeIsReward ? 'Reward' : 'Relay Fee',
tooltip: null,
type: 'relayer',
id: 'relayer-fee',
currency: fees?.relayerService?.currency
}
];
if (appFee) {
const formattedAppFee = (0, numbers_js_1.formatBN)(appFee, 5, Number(fees?.app?.currency?.decimals ?? 18));
breakdown.push({
raw: appFee,
formatted: `${formattedAppFee}`,
usd: formatUsdFee(fees?.app?.amountUsd, true),
name: 'App Fee',
tooltip: null,
type: 'relayer',
id: 'app-fee',
currency: fees?.app?.currency
});
}
let priceImpactColor = 'subtleSecondary';
if (quote?.details?.totalImpact?.percent === '-0.00') {
quote.details.totalImpact.percent = '-0.01';
}
if (quote?.details?.totalImpact?.percent) {
let percent = Number(quote.details.totalImpact.percent);
if (percent <= -3) {
priceImpactColor = 'red';
}
else if (percent > 0) {
priceImpactColor = 'success';
}
}
return {
breakdown,
totalFees: {
usd: (0, numbers_js_1.formatDollar)(totalFeesUsd),
priceImpactPercentage: quote?.details?.totalImpact?.percent
? `${quote?.details?.totalImpact?.percent}%`
: undefined,
priceImpact: quote?.details?.totalImpact?.usd
? (0, numbers_js_1.formatDollar)(parseFloat(quote?.details?.totalImpact?.usd ?? 0))
: undefined,
priceImpactColor,
swapImpact: formatUsdFee(quote?.details?.swapImpact?.usd, false)
}
};
};
exports.parseFees = parseFees;
const calculateRelayerFeeProportionUsd = (quote) => {
const usdIn = quote?.details?.currencyIn?.amountUsd
? Number(quote.details.currencyIn.amountUsd)
: null;
const relayerServiceFeeUsd = quote?.fees?.relayerService?.amountUsd
? Number(quote.fees.relayerService.amountUsd)
: null;
if (!usdIn || !relayerServiceFeeUsd) {
return 0n;
}
return BigInt(Math.floor((relayerServiceFeeUsd * 100) / usdIn));
};
exports.calculateRelayerFeeProportionUsd = calculateRelayerFeeProportionUsd;
const calculateRelayerFeeProportion = (totalAmount, feeBreakdown) => {
if (totalAmount.rawExcludingOriginGas > 0n) {
const relayerFeeRaw = feeBreakdown.find((fee) => fee.id === 'relayer-fee')?.raw ?? 0n;
return (relayerFeeRaw * 100n) / totalAmount.rawExcludingOriginGas;
}
return 0n;
};
exports.calculateRelayerFeeProportion = calculateRelayerFeeProportion;
const isHighRelayerServiceFeeUsd = (quote) => {
const usdIn = quote?.details?.currencyIn?.amountUsd
? Number(quote.details.currencyIn.amountUsd)
: null;
const relayerServiceFeeUsd = quote?.fees?.relayerService?.amountUsd
? Number(quote.fees.relayerService.amountUsd)
: null;
if (!usdIn || !relayerServiceFeeUsd) {
return false;
}
const feeThresholdPercentage = (usdIn * 1.5) / 100;
const feeThresholdUsd = 25;
return (relayerServiceFeeUsd > feeThresholdPercentage &&
relayerServiceFeeUsd > feeThresholdUsd);
};
exports.isHighRelayerServiceFeeUsd = isHighRelayerServiceFeeUsd;
const extractQuoteId = (steps) => {
return steps && steps[0] ? steps[0].requestId : undefined;
};
exports.extractQuoteId = extractQuoteId;
const extractDepositAddress = (steps) => {
const depositStep = steps?.find((step) => step.id === 'deposit');
return depositStep?.depositAddress;
};
exports.extractDepositAddress = extractDepositAddress;
const calculatePriceTimeEstimate = (details) => {
const isBitcoin = details?.currencyIn?.currency?.chainId === bitcoin_js_1.bitcoin.id ||
details?.currencyOut?.currency?.chainId === bitcoin_js_1.bitcoin.id;
const time = isBitcoin ? 1200 : (details?.timeEstimate ?? 0);
const formattedTime = (0, time_js_1.formatSeconds)(time);
return {
time,
formattedTime
};
};
exports.calculatePriceTimeEstimate = calculatePriceTimeEstimate;
const appendMetadataToRequest = (baseUrl, requestId, additionalMetadata, referrer) => {
if (requestId && additionalMetadata) {
const triggerData = {
requestId,
additionalMetadata,
referrer
};
return axios_1.default.request({
url: `${baseUrl}/requests/metadata`,
method: 'POST',
data: triggerData
});
}
};
exports.appendMetadataToRequest = appendMetadataToRequest;
const getCurrentStep = (steps) => {
if (!steps) {
return { step: null, stepItem: null };
}
const executableSteps = steps.filter((step) => step.items && step.items.length > 0);
const step = executableSteps.find((step) => step.items.some((item) => item.status === 'incomplete'));
const stepItem = step?.items.find((item) => item.status === 'incomplete');
return { step, stepItem };
};
exports.getCurrentStep = getCurrentStep;
const getSwapEventData = (details, steps, connector, quoteParameters) => {
let operation = details?.operation;
if (operation === 'swap') {
const isSameChain = details?.currencyIn?.currency?.chainId ===
details?.currencyOut?.currency?.chainId;
if (isSameChain) {
operation = 'same_chain_swap';
}
else if (details?.currencyIn?.currency?.symbol ===
details?.currencyOut?.currency?.symbol) {
operation = 'bridge';
}
else {
operation = 'cross_chain_swap';
}
}
const interval = (0, time_js_1.get15MinuteInterval)();
const quoteRequestId = (0, hashing_js_1.sha256)({ ...quoteParameters, interval });
return {
wallet_connector: connector,
quote_request_id: quoteRequestId,
quote_id: steps ? (0, exports.extractQuoteId)(steps) : undefined,
amount_in: details?.currencyIn?.amount,
currency_in: details?.currencyIn?.currency?.symbol,
chain_id_in: details?.currencyIn?.currency?.chainId,
amount_out: details?.currencyOut?.amount,
currency_out: details?.currencyOut?.currency?.symbol,
chain_id_out: details?.currencyOut?.currency?.chainId,
currency_in_usd: details?.currencyIn?.amountUsd,
currency_out_usd: details?.currencyOut?.amountUsd,
deposit_address: steps?.find((step) => step.depositAddress)?.depositAddress,
txHashes: steps
?.map((step) => {
let txHashes = [];
step.items?.forEach((item) => {
if (item.txHashes) {
txHashes = txHashes.concat([
...(item.txHashes ?? []),
...(item.internalTxHashes ?? [])
]);
}
});
return txHashes;
})
.flat(),
operation,
checkStatuses: steps
?.map((step) => {
let checkStatuses = [];
step.items?.forEach((item) => {
if (item.checkStatus) {
checkStatuses.push({
stepId: step.id,
checkStatus: item.checkStatus
});
}
});
return checkStatuses;
})
.flat()
};
};
exports.getSwapEventData = getSwapEventData;
const calculateUsdValue = (price, amountString) => {
if (price && price > 0 && amountString && Number(amountString) > 0) {
try {
return parseFloat(amountString) * price;
}
catch (e) {
console.error('Failed to parse amount string for USD calculation', amountString, e);
}
}
return undefined;
};
exports.calculateUsdValue = calculateUsdValue;
//# sourceMappingURL=quote.js.map