UNPKG

@accret/bridge-sdk

Version:
314 lines 14.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getQuote = getQuote; exports.executeSwap = executeSwap; exports.getTokenList = getTokenList; const types_1 = require("../types"); const jupiter_1 = require("./jupiter"); const mayan_1 = require("./mayan"); const deBridge_1 = require("./deBridge"); const utils_1 = require("../utils"); /** * @description Formats a quote response into a standardized AccretQuote format * @param provider - The provider of the quote * @param quote - The quote response from the provider * @param inputParams - The original input parameters for the quote request * @returns The formatted quote in AccretQuote format */ function formatQuote(provider, quote, inputParams) { let quoteDetails; switch (provider) { case types_1.AccretSupportedProvider.DEBRIDGE: // Single Chain if (inputParams.fromChain === inputParams.toChain) { const singleChainQuote = quote; quoteDetails = { provider, details: { tokenIn: { address: singleChainQuote.estimation.tokenIn.address, amount: parseFloat(singleChainQuote.estimation.tokenIn.amount), decimals: singleChainQuote.estimation.tokenIn.decimals, name: singleChainQuote.estimation.tokenIn.name, symbol: singleChainQuote.estimation.tokenIn.symbol, }, tokenOut: { address: singleChainQuote.estimation.tokenOut.address, amount: parseFloat(singleChainQuote.estimation.tokenOut.amount), decimals: singleChainQuote.estimation.tokenOut.decimals, name: singleChainQuote.estimation.tokenOut.name, symbol: singleChainQuote.estimation.tokenOut.symbol, }, slippage: singleChainQuote.estimation.slippage, }, fee: parseFloat(singleChainQuote.estimation.tokenOut.amount || "0") * 0.01, rawQuote: singleChainQuote, }; } else { const crossChainQuote = quote; quoteDetails = { provider, details: { tokenIn: { address: crossChainQuote.estimation.srcChainTokenIn.address, amount: parseFloat(crossChainQuote.estimation.srcChainTokenIn.amount), decimals: crossChainQuote.estimation.srcChainTokenIn.decimals, name: crossChainQuote.estimation.srcChainTokenIn.name, symbol: crossChainQuote.estimation.srcChainTokenIn.symbol, amountUsd: crossChainQuote.estimation.srcChainTokenIn.approximateUsdValue, }, tokenOut: { address: crossChainQuote.estimation.dstChainTokenOut.address, amount: parseFloat(crossChainQuote.estimation.dstChainTokenOut.amount), decimals: crossChainQuote.estimation.dstChainTokenOut.decimals, name: crossChainQuote.estimation.dstChainTokenOut.name, symbol: crossChainQuote.estimation.dstChainTokenOut.symbol, amountUsd: crossChainQuote.estimation.dstChainTokenOut.approximateUsdValue, }, slippage: crossChainQuote.estimation.recommendedSlippage, }, fee: parseFloat(crossChainQuote.estimation.costsDetails[0]?.payload.feeAmount || "0") * 0.01, feeUsd: parseFloat(crossChainQuote.estimation.costsDetails[0]?.payload .feeApproximateUsdValue || "0"), estimatedTime: crossChainQuote.order?.approximateFulfillmentDelay || 0, rawQuote: crossChainQuote, }; } break; case types_1.AccretSupportedProvider.JUPITER: { const quoteResponse = quote; quoteDetails = { provider: types_1.AccretSupportedProvider.JUPITER, details: { tokenIn: { address: inputParams.fromToken, decimals: inputParams.srcTokenDecimals, amount: parseFloat(quoteResponse.inAmount), }, tokenOut: { address: quoteResponse.outputMint, amount: parseFloat(quoteResponse.outAmount), }, slippage: quoteResponse.slippageBps, }, fee: parseFloat(quoteResponse.platformFee?.amount || "0"), rawQuote: quoteResponse, }; break; } case types_1.AccretSupportedProvider.MAYAN: { const mayanQuote = quote; quoteDetails = { provider, details: { tokenIn: { address: mayanQuote.fromToken.contract, amount: parseFloat(mayanQuote.effectiveAmountIn64), decimals: mayanQuote.fromToken.decimals, name: mayanQuote.fromToken.name, symbol: mayanQuote.fromToken.symbol, }, tokenOut: { address: mayanQuote.toToken.mint, amount: mayanQuote.expectedAmountOut, decimals: mayanQuote.toToken.decimals, name: mayanQuote.toToken.name, symbol: mayanQuote.toToken.symbol, amountUsd: mayanQuote.price, }, slippage: mayanQuote.slippageBps, }, fee: mayanQuote.bridgeFee, estimatedTime: mayanQuote.etaSeconds, rawQuote: mayanQuote, }; break; } } return quoteDetails; } /** * @description Finds the best quote from an array of quotes based on the output amount * @param quotes - An array of AccretQuote objects * @returns The best quote object */ function findBestQuote(quotes) { if (quotes.length === 0) { throw new Error("No quotes available"); } const validQuotes = quotes.filter((quote) => quote.details.tokenOut.amount > 0); if (validQuotes.length === 0) { throw new Error("No valid quotes with positive output amount"); } validQuotes.sort((quote1, quote2) => quote2.details.tokenOut.amount - quote1.details.tokenOut.amount); const bestQuote = validQuotes[0]; if (!bestQuote) { throw new Error("No valid quote found after filtering"); } return bestQuote; } /** * @description Fetches quotes from multiple providers and returns the best and the other quotes * @param params - The parameters for fetching a quote * @param params.fromChain - The chain from which to swap * @param params.fromToken - The token to swap from * @param params.toChain - The chain to which to swap * @param params.toToken - The token to swap to * @param params.amount - The amount to swap * @param params.srcTokenDecimals - The decimals of the source token * @param params.slippage - The slippage in basis points (default is 50) * @param params.referrer - The referrer for the swap (optional) * @param params.referrerBps - The referrer basis points (optional) * @param params.referrerAddress - The referrer address (optional) * @returns An object containing the best quote and all quotes */ async function getQuote(params) { const quotes = []; const errors = []; // Set Referrer Address if (!params.referrerAddress || !params.referrerBps) { params.referrerAddress = params.fromChain === types_1.AccretSupportedChain.SOLANA_CHAIN ? utils_1.AccretReferrerAddresses.solana : utils_1.AccretReferrerAddresses.evm; params.referrerBps = 50; } // Get DeBridge Quote // Note: Used for both Cross Chain & Single Chain swaps only try { const deBridgeParams = { srcChain: params.fromChain, srcChainTokenIn: params.fromToken, srcChainTokenInAmount: params.amount.toString(), srcTokenDecimals: params.srcTokenDecimals, dstChain: params.toChain, dstChainTokenOut: params.toToken, slippage: params.slippage, affiliateFeeRecipient: params.referrerAddress, affiliateFeePercent: Number(params.referrerBps), }; const deBridgeQuote = await (0, deBridge_1.getDeBridgeQuote)(deBridgeParams); quotes.push(formatQuote(types_1.AccretSupportedProvider.DEBRIDGE, deBridgeQuote, params)); } catch (error) { errors.push(`deBridge: ${error instanceof Error ? error.message : "Unknown error"}`); } // Get Jupiter Quote // Note: Used for Single Chain Solana swaps only if (params.fromChain === types_1.AccretSupportedChain.SOLANA_CHAIN && params.toChain === types_1.AccretSupportedChain.SOLANA_CHAIN) { try { console.log("Fetching Jupiter quote..."); const jupiterQuote = await (0, jupiter_1.getJupiterQuote)(params.fromToken, params.toToken, params.amount); quotes.push(formatQuote(types_1.AccretSupportedProvider.JUPITER, jupiterQuote, params)); } catch (error) { errors.push(`Jupiter: ${error instanceof Error ? error.message : "Unknown error"}`); } } // Get Mayan Quote // Note: Used for cross-chain swaps only try { const mayanParams = { fromChain: params.fromChain, fromToken: params.fromToken, toChain: params.toChain, toToken: params.toToken, amount: params.amount, slippageBps: params.slippage || 50, referrer: params.referrer, referrerBps: params.referrerBps, referrerAddress: params.referrerAddress, }; const mayanQuote = await (0, mayan_1.getMayanQuote)(mayanParams); quotes.push(formatQuote(types_1.AccretSupportedProvider.MAYAN, mayanQuote, params)); } catch (error) { errors.push(`Mayan: ${error instanceof Error ? error.message : "Unknown error"}`); } if (quotes.length === 0) { throw new Error(`No quotes available from any bridge. Errors: ${errors.join(", ")}`); } const bestQuote = findBestQuote(quotes); return { bestQuote, allQuotes: quotes, }; } /** * @description Executes a swap on the specified provider * @param params - The parameters for executing a swap * @param params.provider - The provider to use for the swap * @param params.data - The data required for the swap, which can vary by provider * @returns A promise that resolves to the swap response */ async function executeSwap(params) { switch (params.provider) { case types_1.AccretSupportedProvider.JUPITER: return await (0, jupiter_1.executeJupiterTransaction)({ userPublicKey: params.data.privateKey, quoteResponse: params.data.quote, }); case types_1.AccretSupportedProvider.MAYAN: return await (0, mayan_1.executeMayanSwap)({ quote: params.data.quote, destAddr: params.data.destAddr, privateKey: params.data.privateKey, }); case types_1.AccretSupportedProvider.DEBRIDGE: return await (0, deBridge_1.executeDeBridgeSwap)({ privateKey: params.data.privateKey, srcNetwork: params.data.srcNetwork, srcTokenAddress: params.data .srcTokenAddress, srcTokenDecimals: params.data .srcTokenDecimals, amountToSwap: params.data.amountToSwap, dstTokenAddress: params.data .dstTokenAddress, dstNetwork: params.data.dstNetwork, recipientAddress: params.data .recipientAddress, srcChainRpcUrl: params.data .srcChainRpcUrl, // Optional deBridge parameters slippage: params.data.slippage || 10, referralCode: params.data.referralCode || "", srcChainOrderAuthorityAddress: params.data .srcChainOrderAuthorityAddress || "", dstChainOrderAuthorityAddress: params.data .dstChainOrderAuthorityAddress || "", dstChainTokenOutAmount: params.data.dstChainTokenOutAmount || "", // Optional logging enableLogging: params.data.enableLogging || false, // Optional parameters affiliateFeeRecipient: params.data.affiliateFeeRecipient || "", affiliateFeePercent: params.data.affiliateFeePercent || 0, }); default: throw new Error(`Unsupported provider: ${params.provider}`); } } /** * @description Fetches the token list from the specified provider * @param params - The parameters for fetching the token list * @returns A promise that resolves to the token list */ async function getTokenList(params) { switch (params.provider) { case types_1.AccretSupportedProvider.JUPITER: return await (0, jupiter_1.getJupiterTokenList)(); case types_1.AccretSupportedProvider.MAYAN: return await (0, mayan_1.getMayanTokenList)(params.chainId); case types_1.AccretSupportedProvider.DEBRIDGE: return await (0, deBridge_1.getDeBridgeTokenList)(params.chainId); default: throw new Error(`Unsupported provider: ${params.provider}`); } } //# sourceMappingURL=index.js.map