@funkit/fun-relay
Version:
1,488 lines (1,468 loc) • 66.6 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// index.ts
var index_exports = {};
__export(index_exports, {
ASSET_LOGO_SRCS: () => ASSET_LOGO_SRCS,
DYNAMIC_ROUTES: () => DYNAMIC_ROUTES,
FALLBACK_ASSET: () => FALLBACK_ASSET,
FUN_RELAY_REFERRER: () => FUN_RELAY_REFERRER,
FUN_RELAY_REVENUE_WALLET: () => FUN_RELAY_REVENUE_WALLET,
LogLevel: () => import_relay_sdk.LogLevel,
RELAY_BITCOIN_CHAIN_ID: () => RELAY_BITCOIN_CHAIN_ID,
RELAY_BITCOIN_CHAIN_ID_NUMBER: () => RELAY_BITCOIN_CHAIN_ID_NUMBER,
RELAY_LIGHTER_CHAIN_ID: () => RELAY_LIGHTER_CHAIN_ID,
RELAY_NATIVE_TOKEN: () => RELAY_NATIVE_TOKEN,
RELAY_NATIVE_TOKEN_BITCOIN: () => RELAY_NATIVE_TOKEN_BITCOIN,
RELAY_NATIVE_TOKEN_HYPERCORE: () => RELAY_NATIVE_TOKEN_HYPERCORE,
RELAY_SOLANA_CHAIN_ID: () => RELAY_SOLANA_CHAIN_ID,
RELAY_SOLANA_CHAIN_ID_NUMBER: () => RELAY_SOLANA_CHAIN_ID_NUMBER,
RELAY_TERMINAL_STATUSES: () => RELAY_TERMINAL_STATUSES,
RELAY_VM_TYPES: () => RELAY_VM_TYPES,
RelayQuoteClientError: () => RelayQuoteClientError,
UNWRAP_AND_CALL_ABI: () => UNWRAP_AND_CALL_ABI,
VAULT_DEPOSITOR_ABI: () => VAULT_DEPOSITOR_ABI,
convertFunToRelayChainId: () => convertFunToRelayChainId,
convertFunToRelayTokenAddress: () => convertFunToRelayTokenAddress,
executeRelayQuote: () => executeRelayQuote,
getAssetLogoSrc: () => getAssetLogoSrc,
getBitcoinWallet: () => getBitcoinWallet,
getBitcoinWalletFromSigner: () => getBitcoinWalletFromSigner,
getReferrer: () => getReferrer,
getRelayAssetInfo: () => getRelayAssetInfo,
getRelayAssetPriceInfo: () => getRelayAssetPriceInfo,
getRelayClient: () => getRelayClient,
getRelayExecutionInfo: () => getRelayExecutionInfo,
getRelayExecutionRefundState: () => getRelayExecutionRefundState,
getRelayExecutionState: () => getRelayExecutionState,
getRelayQuote: () => getRelayQuote,
getSolanaWallet: () => getSolanaWallet,
getTronWallet: () => getTronWallet,
initDynamicRouting: () => initDynamicRouting,
initializeRelayClient: () => initializeRelayClient,
isRelayExecutionTerminalStatus: () => isRelayExecutionTerminalStatus,
parseRelayFees: () => parseRelayFees,
shouldResetApproval: () => shouldResetApproval
});
module.exports = __toCommonJS(index_exports);
// src/bitcoin.ts
var import_relay_bitcoin_wallet_adapter = require("@relayprotocol/relay-bitcoin-wallet-adapter");
function getBitcoinWallet(walletAddress, signPsbt) {
return (0, import_relay_bitcoin_wallet_adapter.adaptBitcoinWallet)(
walletAddress,
(address, psbt, dynamicParams) => signPsbt(address, psbt, dynamicParams)
);
}
function getBitcoinWalletFromSigner(walletAddress, signer) {
return getBitcoinWallet(
walletAddress,
async (_, psbt) => psbt.signAllInputs(signer).toBase64()
);
}
// src/client.ts
var relaySdk = __toESM(require("@relayprotocol/relay-sdk"));
// src/types.ts
var import_relay_sdk = require("@relayprotocol/relay-sdk");
// src/constants.ts
var RELAY_BITCOIN_CHAIN_ID_NUMBER = 8253038;
var RELAY_BITCOIN_CHAIN_ID = `${RELAY_BITCOIN_CHAIN_ID_NUMBER}`;
var RELAY_SOLANA_CHAIN_ID_NUMBER = 792703809;
var RELAY_SOLANA_CHAIN_ID = `${RELAY_SOLANA_CHAIN_ID_NUMBER}`;
var FUN_SOLANA_CHAIN_ID_NUMBER = 1151111081099710;
var FUN_HYPERCORE_CHAIN_ID_NUMBER = 1337;
var RELAY_LIGHTER_CHAIN_ID_NUMBER = 3586256;
var RELAY_LIGHTER_CHAIN_ID = `${RELAY_LIGHTER_CHAIN_ID_NUMBER}`;
var RELAY_TRON_CHAIN_ID_NUMBER = 728126428;
var RELAY_TRON_CHAIN_ID = `${RELAY_TRON_CHAIN_ID_NUMBER}`;
var FUNKIT_NATIVE_TOKEN = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
var RELAY_NATIVE_TOKEN = "0x0000000000000000000000000000000000000000";
var RELAY_NATIVE_TOKEN_HYPERCORE = "0x00000000000000000000000000000000";
var RELAY_NATIVE_TOKEN_SOLANA = "11111111111111111111111111111111";
var RELAY_NATIVE_TOKEN_BITCOIN = "bc1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqmql8k8";
var RELAY_LIGHTER_USDC_PERPS = "0";
var RELAY_LIGHTER_USDC_SPOT = "3";
var RELAY_LIGHTER_ETH_SPOT = "1";
var RELAY_LIGHTER_FUN_ADDRESS_MAP = {
"0x0000000000000000000000000000000000000000": RELAY_LIGHTER_USDC_PERPS,
"0x0000000000000000000000000000000000000001": RELAY_LIGHTER_ETH_SPOT,
"0x0000000000000000000000000000000000000003": RELAY_LIGHTER_USDC_SPOT
};
var FUN_RELAY_REVENUE_WALLET = "0xdfd877679e95c1276c85801805b2c2ab8f4f4cf6";
var FUN_RELAY_REFERRER = "funxyz";
var RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS = 25e3;
var RELAY_TERMINAL_STATUSES = [
"refund" /* REFUND */,
"failure" /* FAILURE */,
"success" /* SUCCESS */
];
// src/client.ts
function initializeRelayClient({
chains,
logger,
...options
}) {
const relayLogger = (message, level) => {
const logType = level === relaySdk.LogLevel.Error ? "error" : "info";
const logMessage = message[0] ?? "Unknown error";
const logData = message.length > 1 ? message.slice(1) : void 0;
logger[logType]("[RelayClient]", {
message: logMessage,
relayLogLevel: level,
...logData && { data: logData }
});
};
return relaySdk.createClient({
...options,
baseApiUrl: relaySdk.MAINNET_RELAY_API,
logLevel: options.logLevel ?? relaySdk.LogLevel.Verbose,
logger: relayLogger,
chains: [
...chains.map(relaySdk.convertViemChainToRelayChain),
{
id: RELAY_SOLANA_CHAIN_ID_NUMBER,
name: "Solana",
displayName: "Solana"
},
{
id: RELAY_LIGHTER_CHAIN_ID_NUMBER,
name: "Lighter",
displayName: "Lighter"
}
]
});
}
function getRelayClient() {
const client = relaySdk.getClient();
if (!client) {
throw new Error("Relay client is not defined");
}
return client;
}
// src/execution.ts
var import_relay_sdk2 = require("@relayprotocol/relay-sdk");
var RELAY_VM_TYPES = [
"bvm",
"evm",
"hypevm",
"svm",
"lvm",
"tvm"
];
function getTxHash({
logger,
transactionType,
txHashes,
steps
}) {
const logPrefix = "getTxHash";
const logProps = {
logger,
transactionType,
txHashes,
steps
};
logger.info(`${logPrefix}:started`, logProps);
const getTxHashFromTxHashes = () => {
const rawTxHashWithUnreliableTyping = txHashes[0]?.txHash;
const txHash = typeof rawTxHashWithUnreliableTyping === "object" ? rawTxHashWithUnreliableTyping.id : rawTxHashWithUnreliableTyping;
logger.info(`${logPrefix}:txHashesMode`, {
...logProps,
txHash
});
if (!txHash) {
logger.error(`${logPrefix}:txHashesMode:noTxHash`, {
...logProps,
txHash
});
}
return txHash;
};
const getTxHashFromReceipt = () => {
if (transactionType !== "erc4337") {
throw new Error(
`Transaction type ${transactionType} is not supported for receipt mode`
);
}
const receipt = steps?.[0]?.items?.[0]?.receipt;
const txHash = receipt && "transactionHash" in receipt ? receipt.transactionHash : void 0;
logger.info(`${logPrefix}:receiptMode`, {
...logProps,
txHash
});
return txHash;
};
switch (transactionType) {
// txHashes mode is the default mode
case "standard": {
const txHash = getTxHashFromTxHashes();
return txHash;
}
// receipt mode is used for ERC-4337 smart wallet transactions
// unsupported for Solana Virtual Machine (SVM) or Sui (sui) transactions
case "erc4337": {
const txHash = getTxHashFromReceipt();
if (!txHash) {
logger.info(`${logPrefix}:receiptMode:fallbackToTxHashes`, {
...logProps,
txHash
});
return getTxHashFromTxHashes();
}
return txHash;
}
default: {
throw new Error(`Unknown transactionType: ${transactionType}`);
}
}
}
async function executeRelayQuote({
logger,
onError,
onProgress,
onTransactionConfirmed,
onUserActionsCompleted,
relayQuote,
walletClient,
transactionType = "standard"
}) {
let isUserActionsCompleted = false;
let isTransactionConfirmed = false;
await getRelayClient().actions.execute({
quote: relayQuote,
wallet: walletClient,
onProgress: async ({
steps,
fees,
breakdown,
currentStep,
currentStepItem,
txHashes,
details,
error
}) => {
const logPrefix = "onRelayProgress";
logger.info(`${logPrefix}:params`, {
steps,
currentStep,
fees,
breakdown,
currentStepItem,
txHashes,
details,
error
});
onProgress?.(currentStep ?? null);
if (error) {
logger.info(`${logPrefix}:errorDetected`, error);
await onError(error).catch((e) => {
logger.error(`${logPrefix}:onErrorFailed`, e);
});
} else if (txHashes?.length) {
const txHash = getTxHash({
transactionType,
logger,
txHashes,
steps
});
if (
// Call onUserActionsCompleted only once
!isUserActionsCompleted && steps.every(
(step) => step.items.every(
// 'completed' - catch-all for items marked completed with no other info
// - e.g. Batched items will not have txHash but will have their item marked 'complete'
// 'pending' - for origin chain transactions that have been included on chain
// - may sometimes be skipped, hence the need for 'submitted' condition below
// 'submitted' - for destination chain transactions that have been submitted to the network
// receipt - is present when the transaction has been mined/confirmed
// Ensure onUserActionsCompleted is always called before onTransactionConfirmed
(item) => item.status === "complete" || item.checkStatus === "pending" || item.checkStatus === "submitted" || item.receipt !== void 0
)
)
) {
logger.info(`${logPrefix}:onUserActionsCompleted`, txHashes);
isUserActionsCompleted = true;
try {
await onUserActionsCompleted?.(txHash);
} catch (e) {
logger.error(
`${logPrefix}:onUserActionsCompletedFailed`,
e
);
}
}
if (
// Call onTransactionConfirmed only once
!isTransactionConfirmed && steps.every(
(step) => step.items.every((item) => item.status === "complete")
)
) {
logger.info(`${logPrefix}:onTransactionConfirmed`, txHashes);
isTransactionConfirmed = true;
try {
await onTransactionConfirmed?.(txHash);
} catch (e) {
logger.error(
`${logPrefix}:onTransactionConfirmedFailed`,
e
);
}
}
}
}
});
}
async function getRelayExecutionInfo(requestId, apiKey) {
const url = `${import_relay_sdk2.MAINNET_RELAY_API}/intents/status/v2?requestId=${requestId}`;
const response = await fetch(url, {
headers: { "x-api-key": apiKey }
});
if (!response.ok) {
throw Error(response.statusText);
}
const data = await response.json();
return data;
}
// src/fees.ts
async function getFunRelayFees({
clientId,
estUsdValue,
fromTokenAddress,
fromChainId,
recipientAddress,
senderAddress,
toTokenAddress,
toChainId,
usePermit
}) {
const params = new URLSearchParams({
clientId,
estUsdValue: estUsdValue.toString(),
fromTokenAddress,
fromChainId,
toTokenAddress,
toChainId,
...recipientAddress ? { recipientAddress } : {},
...senderAddress ? { senderAddress } : {},
...usePermit !== void 0 ? { usePermit: String(usePermit) } : {}
});
const url = `https://frog.fun.xyz/api/fee?${params.toString()}`;
const response = await fetch(url);
if (!response.ok) {
throw Error(response.statusText);
}
const data = await response.json();
return data;
}
function parseRelayFees({
fees,
fromChainIdRelay,
fromTokenAddressRelay,
logger,
sourceAssetDecimals,
sourceUnitPrice
}) {
const relayGasFeesUsd = Number.parseFloat(fees?.gas?.amountUsd || "0");
const areFunLpFeesInSourceChainToken = fees?.app?.currency?.chainId === fromChainIdRelay && fees?.app?.currency?.address?.toLowerCase() === fromTokenAddressRelay.toLowerCase();
const funLpFeesUsd = Number.parseFloat(fees?.app?.amountUsd || "0");
const funLpFeesFromAmount = areFunLpFeesInSourceChainToken ? Number.parseFloat(fees?.app?.amountFormatted || "0") : funLpFeesUsd / sourceUnitPrice || 0;
const funLpFeesFromAmountBaseUnit = areFunLpFeesInSourceChainToken ? BigInt(fees?.app?.amount || "0") : BigInt(Math.floor(funLpFeesFromAmount * 10 ** sourceAssetDecimals));
const areRelayLpFeesInSourceChainToken = fees?.relayer?.currency?.chainId === fromChainIdRelay && fees?.relayer?.currency?.address?.toLowerCase() === fromTokenAddressRelay.toLowerCase();
const relayLpFeesUsd = Number.parseFloat(fees?.relayer?.amountUsd || "0");
const relayLpFeesFromAmount = areRelayLpFeesInSourceChainToken ? Number.parseFloat(fees?.relayer?.amountFormatted || "0") : relayLpFeesUsd / sourceUnitPrice || 0;
const relayLpFeesFromAmountBaseUnit = areRelayLpFeesInSourceChainToken ? BigInt(fees?.relayer?.amount || "0") : BigInt(Math.floor(relayLpFeesFromAmount * 10 ** sourceAssetDecimals));
const totalLpFeesUsd = funLpFeesUsd + relayLpFeesUsd;
const totalLpFeesFromAmount = funLpFeesFromAmount + relayLpFeesFromAmount;
const totalLpFeesFromAmountBaseUnit = funLpFeesFromAmountBaseUnit + relayLpFeesFromAmountBaseUnit;
logger.info("parseRelayFees", {
relayGasFeesUsd,
funLpFeesUsd,
funLpFeesFromAmount,
funLpFeesFromAmountBaseUnit,
relayLpFeesUsd,
relayLpFeesFromAmount,
relayLpFeesFromAmountBaseUnit,
totalLpFeesUsd,
totalLpFeesFromAmount,
totalLpFeesFromAmountBaseUnit
});
return {
relayGasFeesUsd,
totalLpFeesUsd,
totalFeesUsd: relayGasFeesUsd + totalLpFeesUsd,
totalFeesFromAmount: totalLpFeesFromAmount,
totalFeesFromAmountBaseUnit: totalLpFeesFromAmountBaseUnit
};
}
// src/price.ts
var import_relay_sdk3 = require("@relayprotocol/relay-sdk");
// src/utils.ts
function convertFunToRelayTokenAddress(address, chainId) {
if (address.toLowerCase() === FUNKIT_NATIVE_TOKEN.toLowerCase()) {
switch (chainId) {
case FUN_HYPERCORE_CHAIN_ID_NUMBER:
return RELAY_NATIVE_TOKEN_HYPERCORE;
case RELAY_BITCOIN_CHAIN_ID_NUMBER:
return RELAY_NATIVE_TOKEN_BITCOIN;
// TODO: is it correct to assume chainId here is relay chain id?
case RELAY_SOLANA_CHAIN_ID_NUMBER:
case FUN_SOLANA_CHAIN_ID_NUMBER:
return RELAY_NATIVE_TOKEN_SOLANA;
case RELAY_LIGHTER_CHAIN_ID_NUMBER:
return RELAY_LIGHTER_USDC_PERPS;
default:
return RELAY_NATIVE_TOKEN;
}
}
if (RELAY_LIGHTER_CHAIN_ID_NUMBER === chainId) {
const relayAddress = RELAY_LIGHTER_FUN_ADDRESS_MAP[address.toLowerCase()];
if (relayAddress) {
return relayAddress;
}
}
return address;
}
function convertFunToRelayChainId(chainId) {
if (chainId === FUN_SOLANA_CHAIN_ID_NUMBER) {
return RELAY_SOLANA_CHAIN_ID_NUMBER;
}
return chainId;
}
function getRelayExecutionRefundState(info) {
switch (info.status) {
case "refund" /* REFUND */:
return "REFUNDED" /* REFUNDED */;
default:
return void 0;
}
}
function getRelayExecutionState(info) {
switch (info.status) {
case "success" /* SUCCESS */:
return "COMPLETED" /* COMPLETED */;
case "failure" /* FAILURE */:
case "refund" /* REFUND */:
return "CHECKOUT_ERROR" /* CHECKOUT_ERROR */;
default:
return "PENDING_RECEIVAL" /* PENDING_RECEIVAL */;
}
}
function isRelayExecutionTerminalStatus(info) {
return RELAY_TERMINAL_STATUSES.includes(info.status);
}
function indexBy(items, getKey) {
const indexedItems = {};
for (const item of items) {
const key = getKey(item);
if (!key) {
continue;
}
indexedItems[key] = item;
}
return indexedItems;
}
function filterNullishHeaders(params) {
const result = {};
for (const [key, value] of Object.entries(params)) {
if (value != null) {
result[key] = value;
}
}
return result;
}
// src/price.ts
async function getRelayAssetPriceInfo({
chainId,
address,
apiKey
}) {
const relayChainId = convertFunToRelayChainId(Number(chainId));
const relayTokenAddress = convertFunToRelayTokenAddress(
address,
relayChainId
);
const url = `${import_relay_sdk3.MAINNET_RELAY_API}/currencies/token/price?chainId=${relayChainId}&address=${relayTokenAddress}`;
const headers = filterNullishHeaders({ "x-api-key": apiKey });
const response = await fetch(url, { headers });
if (!response.ok) {
throw Error(response.statusText);
}
const data = await response.json();
return data;
}
// src/currency.ts
var import_relay_sdk4 = require("@relayprotocol/relay-sdk");
async function getRelayAssetInfo({
chainId,
address,
// https://fun-xyz.slack.com/archives/C08MQ85QB2N/p1770674350731879?thread_ts=1770670744.270889&cid=C08MQ85QB2N
useExternalSearch = true,
apiKey
}) {
const relayChainId = convertFunToRelayChainId(Number(chainId));
const relayTokenAddress = convertFunToRelayTokenAddress(
address,
relayChainId
);
const url = `${import_relay_sdk4.MAINNET_RELAY_API}/currencies/v2`;
const headers = filterNullishHeaders({
"Content-Type": "application/json",
"x-api-key": apiKey
});
const body = {
chainIds: [relayChainId],
address: relayTokenAddress,
useExternalSearch
};
const response = await fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body)
});
if (!response.ok) {
throw Error(response.statusText);
}
const data = await response.json();
return data?.[0];
}
// src/quote.ts
var import_relay_sdk5 = require("@relayprotocol/relay-sdk");
var import_viem = require("viem");
async function getQuoteEstUsdValue({
tokenChainId,
tokenAddress,
tokenAmountBaseUnit,
logger,
apiKey
}) {
try {
const normalizedChainId = convertFunToRelayChainId(
Number(tokenChainId)
).toString();
const normalizedTokenAddress = convertFunToRelayTokenAddress(
tokenAddress,
Number(tokenChainId)
);
const [tokenPriceRes, tokenInfoRes] = await Promise.all([
getRelayAssetPriceInfo({
chainId: normalizedChainId,
address: normalizedTokenAddress,
apiKey
}),
getRelayAssetInfo({
chainId: normalizedChainId,
address: normalizedTokenAddress,
apiKey
})
]);
const isWUsdeEthereal = normalizedChainId === "5064014" && normalizedTokenAddress.toLowerCase() === "0xB6fC4B1BFF391e5F6b4a3D2C7Bda1FeE3524692D".toLowerCase();
const price = tokenPriceRes.price;
const decimals = isWUsdeEthereal ? 18 : tokenInfoRes.decimals;
const absoluteAmount = BigInt(tokenAmountBaseUnit) / BigInt(10 ** decimals);
return Number(price) * Number(absoluteAmount);
} catch (err) {
logger.error("getQuoteEstUsdValueError", {
message: `Failed to get USD value for token ${tokenAddress} on chain ${tokenChainId}: ${getErrorMessage(
err
)}. Falling back to 0 USD.`
});
return 0;
}
}
function getReferrer(clientId) {
return clientId ? `${FUN_RELAY_REFERRER}|${clientId}` : FUN_RELAY_REFERRER;
}
var RelayQuoteClientError = class extends Error {
constructor(statusCode, relayErrorCode, message, requestId = "") {
super(
`An error occurred trying to generate a relay quote: ${relayErrorCode} - ReqId ${requestId || "NO_REQ_ID"} - ${message}`
);
this.statusCode = statusCode;
this.relayErrorCode = relayErrorCode;
this.name = new.target.name;
Object.setPrototypeOf(this, new.target.prototype);
}
};
var getHeaders = (funRelayConfig, apiKey) => {
const headers = {
"x-api-key": apiKey,
// Remote headers will override passed in headers
...funRelayConfig.headers ? { ...funRelayConfig.headers } : {}
};
return headers;
};
async function getRelayQuote({
logger,
walletClient,
...params
}) {
const {
actionParams,
clientId,
fromChainId,
fromTokenAddress,
options,
recipientAddress,
toChainId,
toTokenAddress,
tradeType,
userAddress,
apiKey,
usePermit
} = params;
const vmType = walletClient && "vmType" in walletClient ? walletClient.vmType : "evm";
try {
const relayClient = getRelayClient();
const isSameChainFlow = String(fromChainId) === String(toChainId);
const txs = actionParams?.map((action) => {
const data = action.rawCalldata ?? (0, import_viem.encodeFunctionData)({
abi: action.contractAbi,
args: action.functionArgs,
functionName: action.functionName
});
return {
data,
to: action.contractAddress,
// Relay supports msg.value via 2 fields: `value` and `originalTxValue`
// Both `value` and `originalTxValue` are required to be set for `erc20` + gas transfers
// Only `value` is required for native token transfers. // TODO: This flow needs verification.
// Internally for Relay,
// - `originalTxValue` is designed to "bubble up" the value to the original tx. This only works for user-executed same-chain operations with calls. This does not work / apply to cross chain operations
// - `value` is the internal multicall value
...isSameChainFlow ? { originalTxValue: String(action.value ?? 0n) } : {},
value: String(action.value ?? 0n)
};
});
const isExactIn = params.tradeType === "EXACT_INPUT";
const queryTokenAmountBaseUnit = isExactIn ? params.fromTokenAmountBaseUnit : params.toTokenAmountBaseUnit;
const queryTokenAddress = isExactIn ? fromTokenAddress : toTokenAddress;
const queryTokenChainId = isExactIn ? fromChainId : toChainId;
const estUsdValue = await getQuoteEstUsdValue({
tokenChainId: queryTokenChainId,
tokenAddress: queryTokenAddress,
tokenAmountBaseUnit: queryTokenAmountBaseUnit.toString(),
logger,
apiKey
});
const funRelayConfig = await getFunRelayFees({
clientId,
estUsdValue: Number(estUsdValue) || 0,
fromTokenAddress,
fromChainId,
recipientAddress,
senderAddress: userAddress,
toTokenAddress,
toChainId,
usePermit
});
const headers = getHeaders(funRelayConfig, apiKey);
const appFeeBp = funRelayConfig.b + funRelayConfig.v;
logger.info("getRelayQuoteParams", {
...params,
appFeeBp,
estUsdValue,
funRelayConfig,
queryTokenAmountBaseUnit,
txs
});
const relayQuote = await relayClient.actions.getQuote(
{
amount: queryTokenAmountBaseUnit.toString(),
chainId: convertFunToRelayChainId(Number(fromChainId)),
currency: convertFunToRelayTokenAddress(
fromTokenAddress,
Number(fromChainId)
),
recipient: recipientAddress,
toChainId: convertFunToRelayChainId(Number(toChainId)),
toCurrency: convertFunToRelayTokenAddress(
toTokenAddress,
Number(toChainId)
),
tradeType,
txs,
user: userAddress,
wallet: walletClient,
options: {
referrer: getReferrer(clientId),
appFees: [
{
fee: appFeeBp.toString(),
recipient: FUN_RELAY_REVENUE_WALLET
}
],
// Passed in options
...options,
// Remote options will always override passed in options
...funRelayConfig.config.options
}
},
void 0,
headers
);
logger.info("relayQuote", relayQuote);
const toAmountUsd = Number(relayQuote.details?.currencyOut?.amountUsd || 0);
const fromAmountUsd = Number(relayQuote.details?.currencyIn?.amountUsd || 0);
const fromAmountString = relayQuote.details?.currencyIn?.amountFormatted || "0";
const fromAmountBaseUnitString = relayQuote.details?.currencyIn?.amount || "0";
const fromAssetAmount = Number(fromAmountString || 0);
const relayRequestId = relayQuote.steps[0]?.requestId;
if (!relayRequestId) {
throw new Error("Relay quote does not contain a requestId");
}
if (!relayQuote.details?.currencyIn || !relayQuote.details?.currencyOut) {
throw new Error("Relay quote does not contain trade details");
}
const {
relayGasFeesUsd,
totalLpFeesUsd,
totalFeesUsd,
totalFeesFromAmount,
totalFeesFromAmountBaseUnit
} = parseRelayFees({
fees: relayQuote.fees,
fromChainIdRelay: convertFunToRelayChainId(Number(fromChainId)),
fromTokenAddressRelay: convertFunToRelayTokenAddress(
fromTokenAddress,
Number(fromChainId)
),
logger,
sourceAssetDecimals: relayQuote.details.currencyIn.currency?.decimals ?? 18,
sourceUnitPrice: fromAmountUsd / fromAssetAmount || 1
});
const estSubtotalFromAmount = (fromAssetAmount - totalFeesFromAmount).toString();
const estSubtotalFromAmountBaseUnit = (BigInt(fromAmountBaseUnitString) - totalFeesFromAmountBaseUnit).toString();
return {
quoteId: relayRequestId,
estCheckoutTimeMs: (relayQuote.details.timeEstimate || 0) * 1e3 + RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS,
estFeesFromAmount: totalFeesFromAmount.toString(),
estFeesFromAmountBaseUnit: totalFeesFromAmountBaseUnit.toString(),
estFeesUsd: totalFeesUsd,
estMarketMakerGasUsd: relayGasFeesUsd,
estSubtotalFromAmount,
estSubtotalFromAmountBaseUnit,
estSubtotalUsd: toAmountUsd,
estTotalFromAmount: fromAmountString,
estTotalFromAmountBaseUnit: fromAmountBaseUnitString,
estTotalUsd: fromAmountUsd,
finalToAmountBaseUnit: relayQuote.details.currencyOut.amount ?? "0",
// TODO: Or do we want 'minimumAmount'?
fromTokenAddress,
// TODO: fromTokenAddress is typed as `0x${string}` why does not accept SolanaAddress
lpFeePercentage: 0,
// TODO: ?
lpFeeUsd: totalLpFeesUsd,
metadata: {
fromAmountBaseUnit: isExactIn ? queryTokenAmountBaseUnit.toString() : relayQuote.details.currencyIn.amount ?? "0",
relayQuote: {
...relayQuote,
vmType
},
toAmountBaseUnit: isExactIn ? relayQuote.details.currencyOut.amount ?? "0" : queryTokenAmountBaseUnit.toString()
}
};
} catch (err) {
if (err instanceof Error && (0, import_relay_sdk5.isAPIError)(err)) {
const apiError = err;
const rawError = apiError.rawError;
if (rawError?.errorCode) {
throw new RelayQuoteClientError(
apiError.statusCode,
rawError.errorCode,
rawError.message ?? apiError.message,
rawError.requestId
);
}
}
const message = getErrorMessage(err);
throw new Error(
`An error occurred trying to generate a relay quote: ${message}`
);
}
}
function getErrorMessage(err) {
return err instanceof Error ? err.message : typeof err === "string" ? err : JSON.stringify(err);
}
// src/solana.ts
var import_relay_svm_wallet_adapter = require("@relayprotocol/relay-svm-wallet-adapter");
var import_web3 = require("@solana/web3.js");
function getSolanaWallet(walletAddress, connection, signTransaction, payerKey) {
return (0, import_relay_svm_wallet_adapter.adaptSolanaWallet)(
walletAddress,
RELAY_SOLANA_CHAIN_ID_NUMBER,
connection,
async (transaction, options) => {
const signed = await signTransaction(transaction);
try {
const signature = await connection.sendTransaction(signed, {
...options,
maxRetries: 5
});
return { signature };
} catch (error) {
if (error instanceof import_web3.SendTransactionError) {
console.error(
"Failed transaction logs:",
error,
await error.getLogs(connection)
);
}
throw error;
}
},
payerKey
);
}
// src/tron.ts
var import_relay_tron_wallet_adapter = require("@relayprotocol/relay-tron-wallet-adapter");
function getTronWallet(walletAddress, tronWeb) {
return (0, import_relay_tron_wallet_adapter.adaptTronWallet)(walletAddress, tronWeb);
}
// src/assets.ts
var ASSET_LOGO_SRCS = {
$MFER: "https://sdk-cdn.fun.xyz/images/mfer.png",
AARBUSDCN: "https://sdk-cdn.fun.xyz/images/aarbusdcn.png",
AAVE: "https://sdk-cdn.fun.xyz/images/aave.svg",
AERO: "https://sdk-cdn.fun.xyz/images/aero.svg",
APE: "https://sdk-cdn.fun.xyz/images/ape.svg",
APOLWMATIC: "https://sdk-cdn.fun.xyz/images/apolwmatic.png",
ARB: "https://sdk-cdn.fun.xyz/images/arb.svg",
BEHYPE: "https://sdk-cdn.fun.xyz/images/behype.svg",
BENTO: "https://sdk-cdn.fun.xyz/images/bento.png",
BLERF: "https://sdk-cdn.fun.xyz/images/blerf.png",
BRETT: "https://sdk-cdn.fun.xyz/images/brett.svg",
BSHIB: "https://sdk-cdn.fun.xyz/images/bshib.png",
BTC: "https://sdk-cdn.fun.xyz/images/btc.svg",
CASH: "https://sdk-cdn.fun.xyz/images/cash.svg",
CBBTC: "https://sdk-cdn.fun.xyz/images/cbbtc.svg",
CBETH: "https://sdk-cdn.fun.xyz/images/cbeth.png",
CRO: "https://sdk-cdn.fun.xyz/images/cro.svg",
CRV: "https://sdk-cdn.fun.xyz/images/crv.svg",
DAI: "https://sdk-cdn.fun.xyz/images/dai.svg",
DEGEN: "https://sdk-cdn.fun.xyz/images/degen.svg",
ETH: "https://sdk-cdn.fun.xyz/images/eth.svg",
GMX: "https://sdk-cdn.fun.xyz/images/gmx.svg",
GRT: "https://sdk-cdn.fun.xyz/images/grt.svg",
HYPE: "https://sdk-cdn.fun.xyz/images/hype.svg",
IMX: "https://sdk-cdn.fun.xyz/images/imx.svg",
INJ: "https://sdk-cdn.fun.xyz/images/inj.svg",
LDO: "https://sdk-cdn.fun.xyz/images/ldo.svg",
LINK: "https://sdk-cdn.fun.xyz/images/link.png",
LUCK: "https://sdk-cdn.fun.xyz/images/luck.png",
MATIC: "https://sdk-cdn.fun.xyz/images/matic.svg",
MFER: "https://sdk-cdn.fun.xyz/images/mfer.png",
MKR: "https://sdk-cdn.fun.xyz/images/mkr.svg",
MNT: "https://sdk-cdn.fun.xyz/images/mnt.svg",
OP: "https://sdk-cdn.fun.xyz/images/optimism.svg",
PENDLE: "https://sdk-cdn.fun.xyz/images/pendle.svg",
POL: "https://sdk-cdn.fun.xyz/images/matic.svg",
PYUSD: "https://sdk-cdn.fun.xyz/images/pyusd.svg",
QNT: "https://sdk-cdn.fun.xyz/images/qnt.svg",
RNDR: "https://sdk-cdn.fun.xyz/images/rndr.svg",
ROOST: "https://sdk-cdn.fun.xyz/images/roost.png",
SAND: "https://sdk-cdn.fun.xyz/images/sand.svg",
SHIB: "https://sdk-cdn.fun.xyz/images/shib.svg",
SNX: "https://sdk-cdn.fun.xyz/images/snx.svg",
SOL: "https://sdk-cdn.fun.xyz/images/sol.svg",
SUSDS: "https://sdk-cdn.fun.xyz/images/susds.svg",
TYBG: "https://sdk-cdn.fun.xyz/images/tybg.png",
UNI: "https://sdk-cdn.fun.xyz/images/uni.png",
USDC: "https://sdk-cdn.fun.xyz/images/usdc.svg",
"USDC.E": "https://sdk-cdn.fun.xyz/images/usdc.svg",
USDBC: "https://sdk-cdn.fun.xyz/images/usdc.svg",
USDE: "https://sdk-cdn.fun.xyz/images/usde.svg",
WUSDE: "https://sdk-cdn.fun.xyz/images/usde.svg",
EUSDE: "https://sdk-cdn.fun.xyz/images/eusde.svg",
USDT: "https://sdk-cdn.fun.xyz/images/usdt.svg",
"USD\u20AE0": "https://sdk-cdn.fun.xyz/images/usdt0.svg",
USDT0: "https://sdk-cdn.fun.xyz/images/usdt0.svg",
USDS: "https://sdk-cdn.fun.xyz/images/usds.svg",
USDH: "https://sdk-cdn.fun.xyz/images/usdh.svg",
USDG: "https://sdk-cdn.fun.xyz/images/usdg.svg",
VRTX: "https://sdk-cdn.fun.xyz/images/vrtx.svg",
WBTC: "https://sdk-cdn.fun.xyz/images/wbtc.svg",
WEETH: "https://sdk-cdn.fun.xyz/images/weeth.png",
WETH: "https://sdk-cdn.fun.xyz/images/weth.svg",
WHYPE: "https://sdk-cdn.fun.xyz/images/whype.png",
WSTETH: "https://sdk-cdn.fun.xyz/images/wsteth.png",
TRUMP: "https://sdk-cdn.fun.xyz/images/trump.png",
BNB: "https://sdk-cdn.fun.xyz/images/bsc.svg",
WBNB: "https://sdk-cdn.fun.xyz/images/bsc.svg",
BTCB: "https://sdk-cdn.fun.xyz/images/btc.svg",
UBTC: "https://sdk-cdn.fun.xyz/images/btc.svg",
BUSD: "https://sdk-cdn.fun.xyz/images/busd.svg",
XAUT: "https://sdk-cdn.fun.xyz/images/xaut.png",
ADA: "https://sdk-cdn.fun.xyz/images/ada.svg",
XRP: "https://sdk-cdn.fun.xyz/images/xrp.svg",
UDOGE: "https://sdk-cdn.fun.xyz/images/doge.svg",
DOGE: "https://sdk-cdn.fun.xyz/images/doge.svg",
LTC: "https://sdk-cdn.fun.xyz/images/ltc.svg",
HNT: "https://sdk-cdn.fun.xyz/images/hnt.svg",
COMP: "https://sdk-cdn.fun.xyz/images/comp.svg",
PEPE: "https://sdk-cdn.fun.xyz/images/pepe.svg",
LSTHYPE: "https://sdk-cdn.fun.xyz/images/lsthype.svg",
HBUSDT: "https://sdk-cdn.fun.xyz/images/hbusdt.svg",
WVLP: "https://sdk-cdn.fun.xyz/images/wvlp.svg",
LIQUIDHYPE: "https://sdk-cdn.fun.xyz/images/liquidhype.svg",
VHYPE: "https://sdk-cdn.fun.xyz/images/vhype.png",
HBHYPE: "https://sdk-cdn.fun.xyz/images/hbhype.svg",
MON: "https://sdk-cdn.fun.xyz/images/monad.svg",
WMON: "https://sdk-cdn.fun.xyz/images/wmon.svg",
AUSD: "https://sdk-cdn.fun.xyz/images/ausd.svg",
SUSHI: "https://sdk-cdn.fun.xyz/images/sushi.svg",
SKY: "https://sdk-cdn.fun.xyz/images/sky.svg",
LIT: "https://sdk-cdn.fun.xyz/images/lit.svg",
AZTEC: "https://sdk-cdn.fun.xyz/images/aztec.svg",
U: "https://sdk-cdn.fun.xyz/images/u.png",
PUSD: "https://sdk-cdn.fun.xyz/images/pusd.svg",
KBTC: "https://sdk-cdn.fun.xyz/images/kbtc.svg",
QQQX: "https://sdk-cdn.fun.xyz/images/qqqx.svg",
SPYX: "https://sdk-cdn.fun.xyz/images/spyx.svg",
WSPYX: "https://sdk-cdn.fun.xyz/images/spyx.svg",
WQQQX: "https://sdk-cdn.fun.xyz/images/qqqx.svg",
AAPLX: "https://sdk-cdn.fun.xyz/images/applx.svg",
WAAPLX: "https://sdk-cdn.fun.xyz/images/applx.svg",
GOOGLX: "https://sdk-cdn.fun.xyz/images/googlx.svg",
WGOOGLX: "https://sdk-cdn.fun.xyz/images/googlx.svg",
METAX: "https://sdk-cdn.fun.xyz/images/metax.svg",
WMETAX: "https://sdk-cdn.fun.xyz/images/metax.svg",
NVDAX: "https://sdk-cdn.fun.xyz/images/nvdax.svg",
WNVDAX: "https://sdk-cdn.fun.xyz/images/nvdax.svg",
TSLAX: "https://sdk-cdn.fun.xyz/images/tslax.svg",
WTSLAX: "https://sdk-cdn.fun.xyz/images/tslax.svg",
MSFTX: "https://sdk-cdn.fun.xyz/images/msftx.svg",
WMSFTX: "https://sdk-cdn.fun.xyz/images/msftx.svg",
AMZNX: "https://sdk-cdn.fun.xyz/images/amznx.svg",
WAMZNX: "https://sdk-cdn.fun.xyz/images/amznx.svg"
};
var FALLBACK_ASSET = "https://sdk-cdn.fun.xyz/images/dollar_circle.png";
function getAssetLogoSrc(symbol) {
return ASSET_LOGO_SRCS[symbol.toUpperCase()] || FALLBACK_ASSET;
}
// src/dynamicRoutes/lighter.ts
var import_viem5 = require("viem");
var import_chains3 = require("viem/chains");
// src/dynamicRoutes/abi.ts
var UNWRAP_AND_CALL_ABI = [
{
name: "unwrapAndCall",
type: "function",
stateMutability: "nonpayable",
inputs: [
{ name: "target", type: "address" },
{ name: "callData", type: "bytes" }
],
outputs: [{ name: "returnData", type: "bytes" }]
}
];
var VAULT_DEPOSITOR_ABI = [
{
inputs: [
{ internalType: "address", name: "initialOwner", type: "address" }
],
stateMutability: "nonpayable",
type: "constructor"
},
{
inputs: [
{ internalType: "uint256", name: "amount", type: "uint256" },
{ internalType: "uint256", name: "tickSize", type: "uint256" }
],
name: "AmountBelowMinimumTick",
type: "error"
},
{
inputs: [{ internalType: "bytes", name: "returnData", type: "bytes" }],
name: "DepositFailed",
type: "error"
},
{ inputs: [], name: "DustRefundFailed", type: "error" },
{ inputs: [], name: "EmptyMethodSignature", type: "error" },
{ inputs: [], name: "InsufficientETHAmount", type: "error" },
{ inputs: [], name: "InsufficientTokenAmount", type: "error" },
{
inputs: [{ internalType: "string", name: "reason", type: "string" }],
name: "InvalidCalldata",
type: "error"
},
{ inputs: [], name: "InvalidDustRecipient", type: "error" },
{ inputs: [], name: "InvalidFunctionSelector", type: "error" },
{ inputs: [], name: "InvalidTickSize", type: "error" },
{ inputs: [], name: "InvalidVault", type: "error" },
{ inputs: [], name: "NoETHInContract", type: "error" },
{
inputs: [{ internalType: "address", name: "owner", type: "address" }],
name: "OwnableInvalidOwner",
type: "error"
},
{
inputs: [{ internalType: "address", name: "account", type: "address" }],
name: "OwnableUnauthorizedAccount",
type: "error"
},
{ inputs: [], name: "ReentrancyGuardReentrantCall", type: "error" },
{
inputs: [{ internalType: "address", name: "token", type: "address" }],
name: "SafeERC20FailedOperation",
type: "error"
},
{
inputs: [
{ internalType: "address", name: "vault", type: "address" },
{ internalType: "bytes4", name: "selector", type: "bytes4" }
],
name: "SelectorNotAllowed",
type: "error"
},
{ inputs: [], name: "VaultAlreadyRegistered", type: "error" },
{ inputs: [], name: "VaultDoesNotSupportNative", type: "error" },
{ inputs: [], name: "VaultNotRegistered", type: "error" },
{ inputs: [], name: "VaultNotRegisteredForDeposit", type: "error" },
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "recipient",
type: "address"
},
{
indexed: true,
internalType: "address",
name: "token",
type: "address"
},
{
indexed: false,
internalType: "uint256",
name: "dust",
type: "uint256"
},
{
indexed: false,
internalType: "uint256",
name: "originalAmount",
type: "uint256"
},
{
indexed: false,
internalType: "uint256",
name: "depositedAmount",
type: "uint256"
}
],
name: "DustRefunded",
type: "event"
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "vault",
type: "address"
},
{
indexed: true,
internalType: "address",
name: "token",
type: "address"
},
{
indexed: false,
internalType: "uint256",
name: "amount",
type: "uint256"
},
{
indexed: false,
internalType: "bytes",
name: "returnData",
type: "bytes"
}
],
name: "FunMediatedDeposit",
type: "event"
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "previousOwner",
type: "address"
},
{
indexed: true,
internalType: "address",
name: "newOwner",
type: "address"
}
],
name: "OwnershipTransferred",
type: "event"
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "vault",
type: "address"
},
{
indexed: true,
internalType: "bytes4",
name: "newSelector",
type: "bytes4"
}
],
name: "SelectorUpdated",
type: "event"
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "vault",
type: "address"
},
{
indexed: false,
internalType: "string",
name: "methodSignature",
type: "string"
},
{
indexed: false,
internalType: "bool",
name: "convertTo18Decimals",
type: "bool"
}
],
name: "VaultRegistered",
type: "event"
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "vault",
type: "address"
}
],
name: "VaultRemoved",
type: "event"
},
{
inputs: [],
name: "AMOUNT_PLACEHOLDER",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "AMOUNT_PLACEHOLDER_BYTES32",
outputs: [{ internalType: "bytes32", name: "", type: "bytes32" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "NATIVE_TOKEN",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function"
},
{
inputs: [
{ internalType: "uint256", name: "amount", type: "uint256" },
{ internalType: "uint256", name: "tickSize", type: "uint256" }
],
name: "calculateTickRounding",
outputs: [
{ internalType: "uint256", name: "roundedAmount", type: "uint256" },
{ internalType: "uint256", name: "dust", type: "uint256" }
],
stateMutability: "pure",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "address", name: "vault", type: "address" },
{ internalType: "bytes", name: "callData", type: "bytes" },
{ internalType: "uint256", name: "minAmountOut", type: "uint256" }
],
name: "deposit",
outputs: [{ internalType: "bytes", name: "returnData", type: "bytes" }],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "address", name: "vault", type: "address" },
{ internalType: "bytes", name: "callData", type: "bytes" },
{ internalType: "uint256", name: "minAmountOut", type: "uint256" },
{ internalType: "uint256", name: "tickSize", type: "uint256" },
{ internalType: "address", name: "dustRecipient", type: "address" }
],
name: "depositWithTick",
outputs: [{ internalType: "bytes", name: "returnData", type: "bytes" }],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [{ internalType: "address", name: "vault", type: "address" }],
name: "getAllowedSelector",
outputs: [{ internalType: "bytes4", name: "", type: "bytes4" }],
stateMutability: "view",
type: "function"
},
{
inputs: [{ internalType: "uint256", name: "tickSize", type: "uint256" }],
name: "getMinimumDepositForTick",
outputs: [{ internalType: "uint256", name: "minAmount", type: "uint256" }],
stateMutability: "pure",
type: "function"
},
{
inputs: [{ internalType: "address", name: "vault", type: "address" }],
name: "getVaultConfig",
outputs: [
{
components: [
{ internalType: "bool", name: "isRegistered", type: "bool" },
{ internalType: "bool", name: "convertTo18Decimals", type: "bool" },
{ internalType: "bool", name: "allowsNative", type: "bool" },
{ internalType: "bytes4", name: "allowedSelector", type: "bytes4" }
],
internalType: "struct VaultConfigLib.VaultConfig",
name: "config",
type: "tuple"
}
],
stateMutability: "view",
type: "function"
},
{
inputs: [{ internalType: "address", name: "vault", type: "address" }],
name: "isVaultRegistered",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "owner",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "vault", type: "address" },
{ internalType: "string", name: "vaultABI", type: "string" },
{
internalType: "bytes4",
name: "allowedFunctionSelector",
type: "bytes4"
},
{ internalType: "bool", name: "convertTo18Decimals", type: "bool" },
{ internalType: "bool", name: "allowsNative", type: "bool" }
],
name: "registerVault",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [{ internalType: "address", name: "vault", type: "address" }],
name: "removeVault",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [],
name: "renounceOwnership",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [{ internalType: "address", name: "newOwner", type: "address" }],
name: "transferOwnership",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "vault", type: "address" },
{ internalType: "bytes4", name: "newSelector", type: "bytes4" }
],
name: "updateAllowedSelector",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "uint256", name: "amount", type: "uint256" },
{ internalType: "uint256", name: "tickSize", type: "uint256" }
],
name: "validateAmountForTick",
outputs: [
{ internalType: "bool", name: "isValid", type: "bool" },
{ internalType: "uint256", name: "roundedAmount", type: "uint256" },
{ internalType: "uint256", name: "dust", type: "uint256" }
],
stateMutability: "pure",
type: "function"
},
{
inputs: [{ internalType: "address", name: "vault", type: "address" }],
name: "vaultAllowsNative",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "view",
type: "function"
},
{
inputs: [{ internalType: "address", name: "", type: "address" }],
name: "vaultConfigs",
outputs: [{ internalType: "uint40", name: "", type: "uint40" }],
stateMutability: "view",
type: "function"
},
{
inputs: [{ internalType: "address", name: "vault", type: "address" }],
name: "vaultRequires18Decimals",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "view",
type: "function"
},
{ stateMutability: "payable", type: "receive" }
];
// src/dynamicRoutes/consts.ts
var import_viem2 = require("viem");
var import_chains = require("viem/chains");
var import_viem3 = require("viem");
var AMOUNT_PLACEHOLDER = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffdeadbeefn;
var tokenAddresses = {
WETH: {
[import_chains.mainnet.id]: (0, import_viem2.getAddress)("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2")
},
USDC: {
[import_chains.mainnet.id]: (0, import_viem2.getAddress)("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48")
},
LIT: {
[import_chains.mainnet.id]: (0, import_viem2.getAddress)("0x232CE3bd40fCd6f80f3d55A522d03f25Df784Ee2")
},
LINK: {
[import_chains.mainnet.id]: (0, import_viem2.getAddress)("0x514910771AF9Ca656af840dff83E8264EcF986CA")
},
UNI: {
[import_chains.mainnet.id]: (0, import_viem2.getAddress)("0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984")
},
AAVE: {
[import_chains.mainnet.id]: (0, import_viem2.getAddress)("0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9")
},
SKY: {
[import_chains.mainnet.id]: (0, import_viem2.getAddress)("0x56072C95FAA701256059aa122697B133aDEd9279")
},
LDO: {
[import_chains.mainnet.id]: (0, import_viem2.getAddress)("0x5A98FcBEA516Cf06857215779Fd812CA3beF1B32")
},
AZTEC: {
[import_chains.mainnet.id]: (0, import_viem2.getAddress)("0xA27EC0006e59f245217Ff08CD52A7E8b169E62D2")
}
};
var UNWRAP_AND_CALL_ADDRESS = {
[import_chains.mainnet.id]: (0, import_viem2.getAddress)("0x177591f2F4DcC3a47F768f6533eC6Edf564d6927")
};
var VAULT_DEPOSITOR_ADDRESS = {
[import_chains.mainnet.id]: (0, import_viem2.getAddress)("0x40b72bB73B1E9380629B205e7880Fa409ae7fcc9")
};
var LIGHTER_DEPOSIT_ADDRESS = (0, import_viem2.getAddress)(
"0x3b4d794a66304f130a4db8f2551b0070dfcf5ca7"
);
var MATCH_ALL_CONDITION = "*";
// src/dynamicRoutes/utils.ts
var import_viem4 = require("viem");
var import_chains2 = require("viem/chains");
var createPath = (config) => {
return config;
};
var createRoute = (config) => {
const getPathById = (pathId) => {
const path = config.paths[pathId];
if (!path) {
return null;
}
return path;
};
return {
id: config.id,
config,
getPathById
};
};
var resolveBadge = (rule) => {
if ("badge" in rule.use) {
return rule.use.badge;
}
return void 0;
};
var resolveForceBridge = (rule) => {
if ("bridgeOverride" in rule.use) {
return rule.use.bridgeOverride;
}
return void 0;
};
var initDynamicRouting = (dynamicRoutes, dynamicRoutingConfig) => {
const indexedRoutes = indexBy(dynamicRoutes, (route) => route.id);
const indexedDynamicRoutingConfig = dynamicRoutingConfig.reduce(
(acc, routeConfig) => {
const route = indexedRoutes[routeConfig.routeId];
if (!route) {
return acc;
}
const { rules } = routeConfig;
const indexedRules = indexBy([...rules], (rule) => {
if (rule.when === MATCH_ALL_CONDITION)