UNPKG

@shogun-sdk/money-legos

Version:

Shogun Money Legos: clients and types for quotes, memes, prices, balances, fees, validations, etc.

179 lines (145 loc) 7.84 kB
import { BaseError } from 'viem'; import { CHAIN_MAP } from '../config/chains.js'; import type { QuoteTypes } from '../types/index.js'; import { formatEthDecimal } from './format-eth-decimals.js'; import { lowercase } from './formatter.js'; import { getSuggestedSlippage } from './slippage.js'; const UNPOSSIBLE_SLIPPAGE = 100; export const DEFAULT_ERROR_MESSAGE = 'Action Failed: Please try again or contact support'; export const ERROR_FETCHING_DEST_TX = 'Transaction is still processing.'; export const INSUFFICIENT_BALANCE_MSG = 'Insufficient balance'; const LOW_AMOUNT_ERROR_MSG = 'error_low_give_amount error message:'; export const SLIPPAGE_CODE = '0xff5f293c'; export const SLIPPAGE_ERROR_MSG = 'Slippage tolerance exceeded'; const SLIPPAGE_ERROR_OUTPUT_MSG = 'Slippage error. Please retry, or increase slippage if the issue persists.'; export const ERROR_MISSING_REQUIRED_DATA = 'Missing required data, aborting swap'; const MINIMUM_TX_FEE_PART = 'Minimum transaction fee for cross-chain swap'; export const makeNotEnoughFundsUsdCrosschainErrorMsg = ( amountInUsd: number | string, inTokenSymbol: string, network: number, ): string => { return `${MINIMUM_TX_FEE_PART} is $${formatEthDecimal(amountInUsd, 2, 0)} worth of ${inTokenSymbol} on ${CHAIN_MAP[network]?.name ?? ''}`; }; export const makeEstimatedSlippageError = (suggestedSlippage: number): string => { if (suggestedSlippage === UNPOSSIBLE_SLIPPAGE) { return `Transaction can't be executed with the slippage ${suggestedSlippage}%`; } return `Slippage error. Please increase slippage up to ${suggestedSlippage}%`; }; export const ERROR_INSUFFICIENT_FUNDS_DETAILED = 'Please ensure your account has sufficient funds to cover the transaction cost.'; const UNAUTHORIZED_ERROR_MSG = 'Please log out and log back in.'; const DELEGATED_TRANSACTION_APPROVALS_EXPIRED_ERROR_MSG = 'Delegated transaction approvals have expired or been disabled. Please log in to the dashboard to re-enable access for delegated transactions.'; const ERROR_MISSING_ASSET = 'Please select an asset'; export const ERROR_INVALID_RECIPIENT = 'Please enter a valid recipient address'; const ERROR_INVALID_TRANSFER_DATA = 'The specified amount is invalid or the recipient address is incorrect.'; const ERROR_INVALID_SWAP_PAYLOAD = 'Invalid swap payload'; const ERROR_INVALID_AMOUNT = 'Please enter a valid amount'; export const INSUFFICIENT_FUNDS_ERROR_MSG = 'Insufficient balance'; export const INSUFFICIENT_FUNDS_FOR_GAS_ERROR_MSG = 'Insufficient funds for gas'; export const getInsufficientFundsWebAppError = (estimatedFees: bigint, network: number) => { if (!estimatedFees && !network) { return buildInsufficientFundsWebAppError(); } return INSUFFICIENT_FUNDS_ERROR_MSG; }; export const getInsufficientGasWebAppError = () => { return INSUFFICIENT_FUNDS_FOR_GAS_ERROR_MSG; }; export const BELOW_MIN_TRADE = 'Below minimum trade'; export const buildInsufficientFundsWebAppError = () => { return INSUFFICIENT_FUNDS_ERROR_MSG; }; const renderFundsWebAppError = () => { return INSUFFICIENT_FUNDS_ERROR_MSG; }; const sameErrorReturn = ({ errorMessage }: { errorMessage: string }) => { return errorMessage || DEFAULT_ERROR_MESSAGE; }; const ERROR_MESSAGES = { InsufficientFundsForRent: renderFundsWebAppError, 'Simulation failed': renderFundsWebAppError, gasRefuel: renderFundsWebAppError, ['TransactionExecutionError'.toLowerCase()]: renderFundsWebAppError, ['execution reverted']: renderFundsWebAppError, [LOW_AMOUNT_ERROR_MSG]: renderFundsWebAppError, 'insufficient funds for transfer': renderFundsWebAppError, 'Insufficient balance to cover gas cost': renderFundsWebAppError, 'Insufficient balance to cover transaction fees': renderFundsWebAppError, 'intrinsic gas too low': renderFundsWebAppError, 'insufficient funds for gas * price + value': renderFundsWebAppError, 'intrinsic gas too low: gas 0, minimum needed': renderFundsWebAppError, duplicateinstruction: 'Unable to process transaction', 'is too small to cover operational costs': 'The input amount is too small. Please increase the amount to execute the order', 'Request failed with status code 400': DEFAULT_ERROR_MESSAGE, 'gas required exceeds allowance': 'Swap Failed: Insufficient gas fee', 'turnkey error 16': DELEGATED_TRANSACTION_APPROVALS_EXPIRED_ERROR_MSG, 'transaction failed:{"instructionerror":[5,{"custom":6001}]}': SLIPPAGE_ERROR_OUTPUT_MSG, 'non-base58 character': 'The provided address is not a valid Solana address', [UNAUTHORIZED_ERROR_MSG.toLowerCase()]: UNAUTHORIZED_ERROR_MSG, SLIPPAGE_CODE: SLIPPAGE_ERROR_OUTPUT_MSG, '0x5c0dee5d': DEFAULT_ERROR_MESSAGE, [ERROR_INVALID_TRANSFER_DATA.toLowerCase()]: ERROR_INVALID_TRANSFER_DATA, 'self-transfers within the same chain are not allowed': 'Self-transfers within the same chain are not allowed.', [ERROR_INVALID_SWAP_PAYLOAD]: ERROR_INVALID_SWAP_PAYLOAD, [ERROR_INVALID_AMOUNT]: ERROR_INVALID_AMOUNT, [ERROR_MISSING_ASSET]: ERROR_MISSING_ASSET, [ERROR_INVALID_RECIPIENT]: ERROR_INVALID_RECIPIENT, [ERROR_INVALID_TRANSFER_DATA]: ERROR_INVALID_TRANSFER_DATA, 'Internal server error': DEFAULT_ERROR_MESSAGE, 'Invalid value affiliateFee': INSUFFICIENT_FUNDS_ERROR_MSG, 'insufficient balance to cover gas cost': 'Insufficient funds', 'the total cost (gas * gas fee + value) of executing this transaction exceeds': ERROR_INSUFFICIENT_FUNDS_DETAILED, 'please increase the amount in to execute the order': 'Amount too low! Please increase the input to execute the swap.', [ERROR_MISSING_REQUIRED_DATA]: ERROR_MISSING_REQUIRED_DATA, 'No account found': "No account found. Let's create one and get started!", 'Token IN and Token OUT are the same': 'Please select different tokens', 'denied permission': 'Please enable passkey permissions in your device settings', [BELOW_MIN_TRADE]: sameErrorReturn, slippage: sameErrorReturn, "couldn't find a valid swap route": 'No valid swap route found. Please try again with different tokens.', 'relay error: amount is higher than the available liquidity.': 'The amount you are trying to swap is higher than the available liquidity. Please try again with a smaller amount.', 'transaction confirmation timeout after': 'Swap failed: try again or increase slippage', 'bundle transaction failed to confirm': 'Swap failed: try again or increase slippage', [INSUFFICIENT_FUNDS_ERROR_MSG]: sameErrorReturn, [INSUFFICIENT_FUNDS_FOR_GAS_ERROR_MSG]: sameErrorReturn, }; export function decodeErrorMessage(errorMessage: string): string { if (!errorMessage) { return ''; } const lowerCaseError = errorMessage?.toLowerCase(); for (const [key, value] of Object.entries(ERROR_MESSAGES)) { const lowercaseKey = key.toLowerCase(); if (lowerCaseError.includes(lowercaseKey)) { return typeof value === 'function' ? value({ errorMessage } as any) : value; } } return DEFAULT_ERROR_MESSAGE; } export const returnErrorDuringEstimationGas = (quote: QuoteTypes, error: unknown) => { const err = (error as BaseError).walk?.() || error; const errorData = (err as any)?.['data']; if (errorData) { // Convert error data to lowercase for case-insensitive matching const lowercasedData = lowercase(errorData); if (lowercasedData.includes(lowercase(SLIPPAGE_CODE))) { const suggestedSlippageValue = getSuggestedSlippage(quote, errorData); throw Object.assign(new Error(makeEstimatedSlippageError(suggestedSlippageValue)), { suggestedSlippageValue, }); } else { // Iterate over the ERROR_MESSAGES object for (const [key, value] of Object.entries(ERROR_MESSAGES)) { if (lowercasedData.includes(lowercase(key)) && typeof value !== 'function') { throw new Error(value); } } } } };