@getclave/lifi-sdk
Version:
LI.FI Any-to-Any Cross-Chain-Swap SDK
448 lines (447 loc) • 17.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTransactionHistory = exports.getConnections = exports.getGasRecommendation = exports.getTools = exports.getToken = exports.getTokens = exports.getChains = exports.getRelayedTransactionStatus = exports.relayTransaction = exports.getRelayerQuote = exports.getStatus = exports.getStepTransaction = exports.getContractCallsQuote = exports.getRoutes = exports.getQuote = void 0;
const types_1 = require("@lifi/types");
const config_1 = require("../config");
const SDKError_1 = require("../errors/SDKError");
const baseError_1 = require("../errors/baseError");
const constants_1 = require("../errors/constants");
const errors_1 = require("../errors/errors");
const request_1 = require("../request");
const typeguards_1 = require("../typeguards");
const withDedupe_1 = require("../utils/withDedupe");
/**
* Get a quote for a token transfer
* @param params - The configuration of the requested quote
* @param options - Request options
* @throws {LiFiError} - Throws a LiFiError if request fails
* @returns Quote for a token transfer
*/
const getQuote = async (params, options) => {
const requiredParameters = [
'fromChain',
'fromToken',
'fromAddress',
'fromAmount',
'toChain',
'toToken',
];
for (const requiredParameter of requiredParameters) {
if (!params[requiredParameter]) {
throw new SDKError_1.SDKError(new errors_1.ValidationError(`Required parameter "${requiredParameter}" is missing.`));
}
}
const _config = config_1.config.get();
// apply defaults
params.integrator ??= _config.integrator;
params.order ??= _config.routeOptions?.order;
params.slippage ??= _config.routeOptions?.slippage;
params.referrer ??= _config.routeOptions?.referrer;
params.fee ??= _config.routeOptions?.fee;
params.allowBridges ??= _config.routeOptions?.bridges?.allow;
params.denyBridges ??= _config.routeOptions?.bridges?.deny;
params.preferBridges ??= _config.routeOptions?.bridges?.prefer;
params.allowExchanges ??= _config.routeOptions?.exchanges?.allow;
params.denyExchanges ??= _config.routeOptions?.exchanges?.deny;
params.preferExchanges ??= _config.routeOptions?.exchanges?.prefer;
for (const key of Object.keys(params)) {
if (!params[key]) {
delete params[key];
}
}
return await (0, request_1.request)(`${_config.apiUrl}/quote?${new URLSearchParams(params)}`, {
signal: options?.signal,
});
};
exports.getQuote = getQuote;
/**
* Get a set of routes for a request that describes a transfer of tokens.
* @param params - A description of the transfer.
* @param options - Request options
* @returns The resulting routes that can be used to realize the described transfer of tokens.
* @throws {LiFiError} Throws a LiFiError if request fails.
*/
const getRoutes = async (params, options) => {
if (!(0, typeguards_1.isRoutesRequest)(params)) {
throw new SDKError_1.SDKError(new errors_1.ValidationError('Invalid routes request.'));
}
const _config = config_1.config.get();
// apply defaults
params.options = {
integrator: _config.integrator,
..._config.routeOptions,
...params.options,
};
return await (0, request_1.request)(`${_config.apiUrl}/advanced/routes`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(params),
signal: options?.signal,
});
};
exports.getRoutes = getRoutes;
/**
* Get a quote for a destination contract call
* @param params - The configuration of the requested destination call
* @param options - Request options
* @throws {LiFiError} - Throws a LiFiError if request fails
* @returns - Returns step.
*/
const getContractCallsQuote = async (params, options) => {
// validation
const requiredParameters = [
'fromChain',
'fromToken',
'fromAddress',
'toChain',
'toToken',
'contractCalls',
];
for (const requiredParameter of requiredParameters) {
if (!params[requiredParameter]) {
throw new SDKError_1.SDKError(new errors_1.ValidationError(`Required parameter "${requiredParameter}" is missing.`));
}
}
if (!(0, types_1.isContractCallsRequestWithFromAmount)(params) &&
!(0, types_1.isContractCallsRequestWithToAmount)(params)) {
throw new SDKError_1.SDKError(new errors_1.ValidationError(`Required parameter "fromAmount" or "toAmount" is missing.`));
}
const _config = config_1.config.get();
// apply defaults
// option.order is not used in this endpoint
params.integrator ??= _config.integrator;
params.slippage ??= _config.routeOptions?.slippage;
params.referrer ??= _config.routeOptions?.referrer;
params.fee ??= _config.routeOptions?.fee;
params.allowBridges ??= _config.routeOptions?.bridges?.allow;
params.denyBridges ??= _config.routeOptions?.bridges?.deny;
params.preferBridges ??= _config.routeOptions?.bridges?.prefer;
params.allowExchanges ??= _config.routeOptions?.exchanges?.allow;
params.denyExchanges ??= _config.routeOptions?.exchanges?.deny;
params.preferExchanges ??= _config.routeOptions?.exchanges?.prefer;
// send request
return await (0, request_1.request)(`${_config.apiUrl}/quote/contractCalls`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(params),
signal: options?.signal,
});
};
exports.getContractCallsQuote = getContractCallsQuote;
/**
* Get the transaction data for a single step of a route
* @param step - The step object.
* @param options - Request options
* @returns The step populated with the transaction data.
* @throws {LiFiError} Throws a LiFiError if request fails.
*/
const getStepTransaction = async (step, options) => {
if (!(0, typeguards_1.isStep)(step)) {
// While the validation fails for some users we should not enforce it
console.warn('SDK Validation: Invalid Step', step);
}
return await (0, request_1.request)(`${config_1.config.get().apiUrl}/advanced/stepTransaction`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(step),
signal: options?.signal,
});
};
exports.getStepTransaction = getStepTransaction;
/**
* Check the status of a transfer. For cross chain transfers, the "bridge" parameter is required.
* @param params - Configuration of the requested status
* @param options - Request options.
* @throws {LiFiError} - Throws a LiFiError if request fails
* @returns Returns status response.
*/
const getStatus = async (params, options) => {
if (!params.txHash) {
throw new SDKError_1.SDKError(new errors_1.ValidationError('Required parameter "txHash" is missing.'));
}
const queryParams = new URLSearchParams(params);
return await (0, request_1.request)(`${config_1.config.get().apiUrl}/status?${queryParams}`, {
signal: options?.signal,
});
};
exports.getStatus = getStatus;
/**
* Get a relayer quote for a token transfer
* @param params - The configuration of the requested quote
* @param options - Request options
* @throws {LiFiError} - Throws a LiFiError if request fails
* @returns Relayer quote for a token transfer
*/
const getRelayerQuote = async (params, options) => {
const requiredParameters = [
'fromChain',
'fromToken',
'fromAddress',
'fromAmount',
'toChain',
'toToken',
];
for (const requiredParameter of requiredParameters) {
if (!params[requiredParameter]) {
throw new SDKError_1.SDKError(new errors_1.ValidationError(`Required parameter "${requiredParameter}" is missing.`));
}
}
const _config = config_1.config.get();
// apply defaults
params.integrator ??= _config.integrator;
params.order ??= _config.routeOptions?.order;
params.slippage ??= _config.routeOptions?.slippage;
params.referrer ??= _config.routeOptions?.referrer;
params.fee ??= _config.routeOptions?.fee;
params.allowBridges ??= _config.routeOptions?.bridges?.allow;
params.denyBridges ??= _config.routeOptions?.bridges?.deny;
params.preferBridges ??= _config.routeOptions?.bridges?.prefer;
params.allowExchanges ??= _config.routeOptions?.exchanges?.allow;
params.denyExchanges ??= _config.routeOptions?.exchanges?.deny;
params.preferExchanges ??= _config.routeOptions?.exchanges?.prefer;
for (const key of Object.keys(params)) {
if (!params[key]) {
delete params[key];
}
}
const result = await (0, request_1.request)(`${config_1.config.get().apiUrl}/relayer/quote?${new URLSearchParams(params)}`, {
signal: options?.signal,
});
if (result.status === 'error') {
throw new baseError_1.BaseError(constants_1.ErrorName.ServerError, result.data.code, result.data.message);
}
return result.data;
};
exports.getRelayerQuote = getRelayerQuote;
/**
* Relay a transaction through the relayer service
* @param params - The configuration for the relay request
* @param options - Request options
* @throws {LiFiError} - Throws a LiFiError if request fails
* @returns Task ID for the relayed transaction
*/
const relayTransaction = async (params, options) => {
const requiredParameters = [
'typedData',
'transactionRequest',
];
for (const requiredParameter of requiredParameters) {
if (!params[requiredParameter]) {
throw new SDKError_1.SDKError(new errors_1.ValidationError(`Required parameter "${requiredParameter}" is missing.`));
}
}
const result = await (0, request_1.request)(`${config_1.config.get().apiUrl}/relayer/relay`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(params, (_, value) => {
if (typeof value === 'bigint') {
return value.toString();
}
return value;
}),
signal: options?.signal,
});
if (result.status === 'error') {
throw new baseError_1.BaseError(constants_1.ErrorName.ServerError, result.data.code, result.data.message);
}
return result.data;
};
exports.relayTransaction = relayTransaction;
/**
* Get the status of a relayed transaction
* @param params - Parameters for the relay status request
* @param options - Request options
* @throws {LiFiError} - Throws a LiFiError if request fails
* @returns Status of the relayed transaction
*/
const getRelayedTransactionStatus = async (params, options) => {
if (!params.taskId) {
throw new SDKError_1.SDKError(new errors_1.ValidationError('Required parameter "taskId" is missing.'));
}
const { taskId, ...otherParams } = params;
const queryParams = new URLSearchParams(otherParams);
const result = await (0, request_1.request)(`${config_1.config.get().apiUrl}/relayer/status/${taskId}?${queryParams}`, {
signal: options?.signal,
});
if (result.status === 'error') {
throw new baseError_1.BaseError(constants_1.ErrorName.ServerError, result.data.code, result.data.message);
}
return result.data;
};
exports.getRelayedTransactionStatus = getRelayedTransactionStatus;
/**
* Get all available chains
* @param params - The configuration of the requested chains
* @param options - Request options
* @returns A list of all available chains
* @throws {LiFiError} Throws a LiFiError if request fails.
*/
const getChains = async (params, options) => {
if (params) {
for (const key of Object.keys(params)) {
if (!params[key]) {
delete params[key];
}
}
}
const urlSearchParams = new URLSearchParams(params).toString();
const response = await (0, withDedupe_1.withDedupe)(() => (0, request_1.request)(`${config_1.config.get().apiUrl}/chains?${urlSearchParams}`, {
signal: options?.signal,
}), { id: `${exports.getChains.name}.${urlSearchParams}` });
return response.chains;
};
exports.getChains = getChains;
/**
* Get all known tokens.
* @param params - The configuration of the requested tokens
* @param options - Request options
* @returns The tokens that are available on the requested chains
*/
const getTokens = async (params, options) => {
if (params) {
for (const key of Object.keys(params)) {
if (!params[key]) {
delete params[key];
}
}
}
const urlSearchParams = new URLSearchParams(params).toString();
const response = await (0, withDedupe_1.withDedupe)(() => (0, request_1.request)(`${config_1.config.get().apiUrl}/tokens?${urlSearchParams}`, {
signal: options?.signal,
}), { id: `${exports.getTokens.name}.${urlSearchParams}` });
return response;
};
exports.getTokens = getTokens;
/**
* Fetch information about a Token
* @param chain - Id or key of the chain that contains the token
* @param token - Address or symbol of the token on the requested chain
* @param options - Request options
* @throws {LiFiError} - Throws a LiFiError if request fails
* @returns Token information
*/
const getToken = async (chain, token, options) => {
if (!chain) {
throw new SDKError_1.SDKError(new errors_1.ValidationError('Required parameter "chain" is missing.'));
}
if (!token) {
throw new SDKError_1.SDKError(new errors_1.ValidationError('Required parameter "token" is missing.'));
}
return await (0, request_1.request)(`${config_1.config.get().apiUrl}/token?${new URLSearchParams({
chain,
token,
})}`, {
signal: options?.signal,
});
};
exports.getToken = getToken;
/**
* Get the available tools to bridge and swap tokens.
* @param params - The configuration of the requested tools
* @param options - Request options
* @returns The tools that are available on the requested chains
*/
const getTools = async (params, options) => {
if (params) {
for (const key of Object.keys(params)) {
if (!params[key]) {
delete params[key];
}
}
}
return await (0, request_1.request)(`${config_1.config.get().apiUrl}/tools?${new URLSearchParams(params)}`, {
signal: options?.signal,
});
};
exports.getTools = getTools;
/**
* Get gas recommendation for a certain chain
* @param params - Configuration of the requested gas recommendation.
* @param options - Request options
* @throws {LiFiError} Throws a LiFiError if request fails.
* @returns Gas recommendation response.
*/
const getGasRecommendation = async (params, options) => {
if (!params.chainId) {
throw new SDKError_1.SDKError(new errors_1.ValidationError('Required parameter "chainId" is missing.'));
}
const url = new URL(`${config_1.config.get().apiUrl}/gas/suggestion/${params.chainId}`);
if (params.fromChain) {
url.searchParams.append('fromChain', params.fromChain);
}
if (params.fromToken) {
url.searchParams.append('fromToken', params.fromToken);
}
return await (0, request_1.request)(url.toString(), {
signal: options?.signal,
});
};
exports.getGasRecommendation = getGasRecommendation;
/**
* Get all the available connections for swap/bridging tokens
* @param connectionRequest ConnectionsRequest
* @param options - Request options
* @returns ConnectionsResponse
*/
const getConnections = async (connectionRequest, options) => {
const url = new URL(`${config_1.config.get().apiUrl}/connections`);
const { fromChain, fromToken, toChain, toToken } = connectionRequest;
if (fromChain) {
url.searchParams.append('fromChain', fromChain);
}
if (fromToken) {
url.searchParams.append('fromToken', fromToken);
}
if (toChain) {
url.searchParams.append('toChain', toChain);
}
if (toToken) {
url.searchParams.append('toToken', toToken);
}
const connectionRequestArrayParams = [
'allowBridges',
'denyBridges',
'preferBridges',
'allowExchanges',
'denyExchanges',
'preferExchanges',
];
for (const parameter of connectionRequestArrayParams) {
const connectionRequestArrayParam = connectionRequest[parameter];
if (connectionRequestArrayParam?.length) {
for (const value of connectionRequestArrayParam) {
url.searchParams.append(parameter, value);
}
}
}
return await (0, request_1.request)(url, options);
};
exports.getConnections = getConnections;
const getTransactionHistory = async ({ wallet, status, fromTimestamp, toTimestamp }, options) => {
if (!wallet) {
throw new SDKError_1.SDKError(new errors_1.ValidationError('Required parameter "wallet" is missing.'));
}
const _config = config_1.config.get();
const url = new URL(`${_config.apiUrl}/analytics/transfers`);
url.searchParams.append('integrator', _config.integrator);
url.searchParams.append('wallet', wallet);
if (status) {
url.searchParams.append('status', status);
}
if (fromTimestamp) {
url.searchParams.append('fromTimestamp', fromTimestamp.toString());
}
if (toTimestamp) {
url.searchParams.append('toTimestamp', toTimestamp.toString());
}
return await (0, request_1.request)(url, options);
};
exports.getTransactionHistory = getTransactionHistory;