UNPKG

@openocean.finance/widget-sdk

Version:

OpenOcean Any-to-Any Cross-Chain-Swap SDK

437 lines 16.4 kB
import { isContractCallsRequestWithFromAmount, isContractCallsRequestWithToAmount, } from '@openocean.finance/widget-types'; import { config } from '../config.js'; import { SDKError } from '../errors/SDKError.js'; import { BaseError } from '../errors/baseError.js'; import { ErrorName } from '../errors/constants.js'; import { ValidationError } from '../errors/errors.js'; import { request } from '../request.js'; import { isRoutesRequest, isStep } from '../typeguards.js'; import { withDedupe } from '../utils/withDedupe.js'; /** * Get a quote for a token transfer * @param params - The configuration of the requested quote * @param options - Request options * @throws {OpenOceanError} - Throws a OpenOceanError if request fails * @returns Quote for a token transfer */ export const getQuote = async (params, options) => { const requiredParameters = [ 'fromChain', 'fromToken', 'fromAddress', 'fromAmount', 'toChain', 'toToken', ]; for (const requiredParameter of requiredParameters) { if (!params[requiredParameter]) { throw new SDKError(new ValidationError(`Required parameter "${requiredParameter}" is missing.`)); } } const _config = 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 request(`${_config.apiUrl}/quote?${new URLSearchParams(params)}`, { signal: options?.signal, }); }; /** * 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 {OpenOceanError} Throws a OpenOceanError if request fails. */ export const getRoutes = async (params, options) => { if (!isRoutesRequest(params)) { throw new SDKError(new ValidationError('Invalid routes request.')); } const _config = config.get(); // apply defaults params.options = { integrator: _config.integrator, ..._config.routeOptions, ...params.options, }; return await request(`${_config.apiUrl}/advanced/routes`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(params), signal: options?.signal, }); }; /** * Get a quote for a destination contract call * @param params - The configuration of the requested destination call * @param options - Request options * @throws {OpenOceanError} - Throws a OpenOceanError if request fails * @returns - Returns step. */ export 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(new ValidationError(`Required parameter "${requiredParameter}" is missing.`)); } } if (!isContractCallsRequestWithFromAmount(params) && !isContractCallsRequestWithToAmount(params)) { throw new SDKError(new ValidationError(`Required parameter "fromAmount" or "toAmount" is missing.`)); } const _config = 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 request(`${_config.apiUrl}/quote/contractCalls`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(params), signal: options?.signal, }); }; /** * 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 {OpenOceanError} Throws a OpenOceanError if request fails. */ export const getStepTransaction = async (step, options) => { if (!isStep(step)) { // While the validation fails for some users we should not enforce it console.warn('SDK Validation: Invalid Step', step); } return await request(`${config.get().apiUrl}/advanced/stepTransaction`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(step), signal: options?.signal, }); }; /** * 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 {OpenOceanError} - Throws a OpenOceanError if request fails * @returns Returns status response. */ export const getStatus = async (params, options) => { if (!params.txHash) { throw new SDKError(new ValidationError('Required parameter "txHash" is missing.')); } const queryParams = new URLSearchParams(params); return await request(`${config.get().apiUrl}/status?${queryParams}`, { signal: options?.signal, }); }; /** * Get a relayer quote for a token transfer * @param params - The configuration of the requested quote * @param options - Request options * @throws {OpenOceanError} - Throws a OpenOceanError if request fails * @returns Relayer quote for a token transfer */ export const getRelayerQuote = async (params, options) => { const requiredParameters = [ 'fromChain', 'fromToken', 'fromAddress', 'fromAmount', 'toChain', 'toToken', ]; for (const requiredParameter of requiredParameters) { if (!params[requiredParameter]) { throw new SDKError(new ValidationError(`Required parameter "${requiredParameter}" is missing.`)); } } const _config = 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 request(`${config.get().apiUrl}/relayer/quote?${new URLSearchParams(params)}`, { signal: options?.signal, }); if (result.status === 'error') { throw new BaseError(ErrorName.ServerError, result.data.code, result.data.message); } return result.data; }; /** * Relay a transaction through the relayer service * @param params - The configuration for the relay request * @param options - Request options * @throws {OpenOceanError} - Throws a OpenOceanError if request fails * @returns Task ID for the relayed transaction */ export const relayTransaction = async (params, options) => { const requiredParameters = [ 'typedData', 'transactionRequest', ]; for (const requiredParameter of requiredParameters) { if (!params[requiredParameter]) { throw new SDKError(new ValidationError(`Required parameter "${requiredParameter}" is missing.`)); } } const result = await request(`${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(ErrorName.ServerError, result.data.code, result.data.message); } return result.data; }; /** * Get the status of a relayed transaction * @param params - Parameters for the relay status request * @param options - Request options * @throws {OpenOceanError} - Throws a OpenOceanError if request fails * @returns Status of the relayed transaction */ export const getRelayedTransactionStatus = async (params, options) => { if (!params.taskId) { throw new SDKError(new ValidationError('Required parameter "taskId" is missing.')); } const { taskId, ...otherParams } = params; const queryParams = new URLSearchParams(otherParams); const result = await request(`${config.get().apiUrl}/relayer/status/${taskId}?${queryParams}`, { signal: options?.signal, }); if (result.status === 'error') { throw new BaseError(ErrorName.ServerError, result.data.code, result.data.message); } return result.data; }; /** * Get all available chains * @returns A list of all available chains * @throws {OpenOceanError} Throws a OpenOceanError if request fails. */ export const getChains = async () => { const response = await withDedupe(() => request(`https://openapi-test.openocean.finance/v3/widgetv2/chains`), { id: `${getChains.name}` }); return convertChainData(response.data); }; function convertChainData(data) { return data.map(chain => ({ key: chain.code, chainType: 'EVM', name: chain.name, coin: chain.symbol, id: Number(chain.chainId), mainnet: true, logoURI: chain.icon, tokenlistUrl: chain.tokenlistUrl, multicallAddress: chain.multicallAddress, relayerSupported: false, metamask: chain.metamask, nativeToken: chain.nativeToken, diamondAddress: chain.exchangeAddress, permit2: chain.permit2, permit2Proxy: chain.permit2Proxy, })); } /** * 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 */ export 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 withDedupe(() => request(`${config.get().apiUrl}/tokens?${urlSearchParams}`, { signal: options?.signal, }), { id: `${getTokens.name}.${urlSearchParams}` }); return response; }; /** * 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 {OpenOceanError} - Throws a OpenOceanError if request fails * @returns Token information */ export const getToken = async (chain, token, options) => { if (!chain) { throw new SDKError(new ValidationError('Required parameter "chain" is missing.')); } if (!token) { throw new SDKError(new ValidationError('Required parameter "token" is missing.')); } return await request(`${config.get().apiUrl}/token?${new URLSearchParams({ chain, token, })}`, { signal: options?.signal, }); }; /** * 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 */ export const getTools = async (params, options) => { if (params) { for (const key of Object.keys(params)) { if (!params[key]) { delete params[key]; } } } return await request(`${config.get().apiUrl}/tools?${new URLSearchParams(params)}`, { signal: options?.signal, }); }; /** * Get gas recommendation for a certain chain * @param params - Configuration of the requested gas recommendation. * @param options - Request options * @throws {OpenOceanError} Throws a OpenOceanError if request fails. * @returns Gas recommendation response. */ export const getGasRecommendation = async (params, options) => { if (!params.chainId) { throw new SDKError(new ValidationError('Required parameter "chainId" is missing.')); } const url = new URL(`${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 request(url.toString(), { signal: options?.signal, }); }; /** * Get all the available connections for swap/bridging tokens * @param connectionRequest ConnectionsRequest * @param options - Request options * @returns ConnectionsResponse */ export const getConnections = async (connectionRequest, options) => { const url = new URL(`${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 request(url, options); }; export const getTransactionHistory = async ({ wallet, status, fromTimestamp, toTimestamp }, options) => { if (!wallet) { throw new SDKError(new ValidationError('Required parameter "wallet" is missing.')); } const _config = 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 request(url, options); }; //# sourceMappingURL=api.js.map