Skip to content

Commit

Permalink
methods/swap/swapTx
Browse files Browse the repository at this point in the history
  • Loading branch information
Velenir committed Sep 10, 2024
1 parent 6a58963 commit c9572e4
Showing 1 changed file with 341 additions and 0 deletions.
341 changes: 341 additions & 0 deletions src/methods/swap/swapTx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,341 @@
import {
SwapSide,
ContractMethod,
API_URL,
DEFAULT_VERSION,
} from '../../constants';
import { constructSearchString } from '../../helpers/misc';
import type {
ConstructFetchInput,
Address,
AddressOrSymbol,
PriceString,
OptimalRate,
SwapApiResponse,
} from '../../types';
import { noramalizeRateOptions } from './helpers/normalizeRateOptions';

// TODO: This is legacy and can be removed
export enum PricingMethod {
megapath = 'megapath',
multipath = 'multipath',
simplepath = 'simplepath',
}

// more details in the docs https://developers.paraswap.network/api/get-rate-for-a-token-pair#query-parameters
export type RateOptions = {
excludeDEXS?: string[];
includeDEXS?: string[];
excludePools?: string[];
excludePricingMethods?: PricingMethod[];
excludeContractMethods?: ContractMethod[];
includeContractMethods?: ContractMethod[];
excludeContractMethodsWithoutFeeModel?: boolean;
partner?: string;
maxImpact?: number;
maxUSDImpact?: number;
otherExchangePrices?: boolean;
/** @description proceed with priceRoute building even when tokens don't have USD price. Default: false */
ignoreBadUsdPrice?: boolean;
/** @description Specify that methods without fee support should be excluded from the price route. Default: false */
exlcudeContractMethodsWithoutFeeModel?: boolean;
/** @description If the source token is a tax token, you should specify the tax amount in BPS. */
srcTokenTransferFee?: string;
/** @description If the destination token is a tax token, you should specify the tax amount in BPS. */
destTokenTransferFee?: string;
/** @description Some tokens only charge tax when swapped in/out DEXs and not on ordinary transfers. */
srcTokenDexTransferFee?: string;
/** @description Some tokens only charge tax when swapped in/out DEXs and not on ordinary transfers. */
destTokenDexTransferFee?: string;
};

/**
* Types for transaction parameters.
*/
type SwapQueryParams = {
/**
* @description Source Token Address. Instead, **Token Symbol** could be used for tokens listed in the `/tokens` endpoint.
*/
srcToken: string;

/**
* @description Source Token Decimals. (Can be omitted if Token Symbol is used in `srcToken`).
*/
srcDecimals?: number;

/**
* @description Destination Token Address. Instead, **Token Symbol** could be used for tokens listed in the `/tokens` endpoint.
*/
destToken: string;

/**
* @description srcToken amount (in case of SELL) or destToken amount (in case of BUY). The amount should be in **WEI/Raw units** (eg. 1WBTC -> 100000000).
*/
amount: string;

/**
* @description **SELL** or **BUY**. Default: `SELL`.
*/
side?: 'SELL' | 'BUY';

/**
* @description Network ID. (Mainnet - 1, Optimism - 10, BSC - 56, Polygon - 137, Fantom - 250, zkEVM - 1101, Base - 8453, Arbitrum - 42161, Avalanche - 43114). Default: `1`.
*/
network?: number;

/**
* @description If provided, **others** object is filled in the response with price quotes from other exchanges _(if available for comparison)_. Default: `false`.
*/
otherExchangePrices?: boolean;

/**
* @description Comma Separated List of DEXs to include. **Supported DEXs:** Uniswap, Kyber, Bancor, AugustusRFQ, Oasis, Compound, Fulcrum, 0x, MakerDAO, Chai, Aave, Aave2, MultiPath, MegaPath, Curve, Curve3, Saddle, IronV2, BDai, idle, Weth, Beth, UniswapV2, Balancer, 0xRFQt, SushiSwap, LINKSWAP, Synthetix, DefiSwap, Swerve, CoFiX, Shell, DODOV1, DODOV2, OnChainPricing, PancakeSwap, PancakeSwapV2, ApeSwap, Wbnb, acryptos, streetswap, bakeryswap, julswap, vswap, vpegswap, beltfi, ellipsis, QuickSwap, COMETH, Wmatic, Nerve, Dfyn, UniswapV3, Smoothy, PantherSwap, OMM1, OneInchLP, CurveV2, mStable, WaultFinance, MDEX, ShibaSwap, CoinSwap, SakeSwap, JetSwap, Biswap, BProtocol eg: `UniswapV3,0x`.
*/
includeDEXS?: string;

/**
* @description Comma Separated List of DEXs to exclude. (from the list of DEXs mentioned above).
*/
excludeDEXS?: string;

/**
* @description Comma Separated List of Contract Methods to include without spaces. **Available values:** swapOnUniswap, buyOnUniswap, swapOnUniswapFork, buyOnUniswapFork, swapOnUniswapV2Fork, buyOnUniswapV2Fork, simpleBuy, simpleSwap, multiSwap, megaSwap, protectedMultiSwap, protectedMegaSwap, protectedSimpleSwap, protectedSimpleBuy, swapOnZeroXv2, swapOnZeroXv4, buy. eg: `simpleSwap,multiSwap`.
*/
includeContractMethods?: string;

/**
* @description Comma Separated List of Contract Methods to exclude without spaces. (from the list of contract methods mentioned above).
*/
excludeContractMethods?: string;

/**
* @description User's Wallet Address.
*/
userAddress?: string;

/**
* @description Dash (-) separated list of tokens (addresses or symbols from `/tokens`) to comprise the price route. _Max 4 tokens._ _**\*Note:**_ _If_ `_route_` _is specified, the response will only comprise of the route specified which might not be the optimal route._
*/
route?: string;

/**
* @description Partner string.
*/
partner?: string;

/**
* @description If provided it is used together with `partnerAddress`. Should be in basis points percentage. Look at `slippage` parameter description for understanding better. Eg: `200` (for 2% fee percent). Fees have to be claimed from the Fee Claimer contract unless `_isSurplusToUser_` or `_isDirectFeeTransfer_` are used.
*/
partnerFeeBps?: string;

/**
* @description Address that will be entitled to claim fees or surplus. Fees have to be claimed from the Fee Claimer contract unless `_isSurplusToUser_` or `_isDirectFeeTransfer_` are used.
*/
partnerAddress?: string;

/**
* @description Allowed slippage percentage represented in basis points. _Eg:_ for **2.5%** slippage, set the value to **2.5 \* 100 = 250**; for 10% = 1000. Slippage could be passed instead of `destAmount` when **side=SELL** or `srcAmount` when **side=BUY**. `Min: 0; Max: 10000`.
*/
slippage?: number;

/**
* @description Destination Token Decimals. (Can be omitted if Token Symbol is used in `destToken`).
*/
destDecimals?: number;

/**
* @description In %. It's a way to bypass the API price impact check (default = 15%).
*/
maxImpact?: number;

/**
* @description Receiver's Wallet address. (Can be omitted if swapping tokens from and to same account).
*/
receiver?: string;

/**
* @description If the source token is a tax token, you should specify the tax amount in BPS. For example: for a token with a 5% tax, you should set it to 500 as `[(500/10000)*100=5%]`. Note: not all DEXs and contract methods support trading tax tokens, so we will filter those that don't.
*/
srcTokenTransferFee?: string;

/**
* @description If the destination token is a tax token, you should specify the tax amount in BPS. For example: for a token with a 5% tax, you should set it to 500 as `[(500/10000)*100=5%]`. Note: not all DEXs and contract methods support trading tax tokens, so we will filter those that don't.
*/
destTokenTransferFee?: string;

/**
* @description If the source token is a tax token, you should specify the tax amount in BPS. Some tokens only charge tax when swapped in/out DEXs and not on ordinary transfers.
*/
srcTokenDexTransferFee?: string;

/**
* @description If the destination token is a tax token, you should specify the tax amount in BPS. Some tokens only charge tax when swapped in/out DEXs, not on ordinary transfers.
*/
destTokenDexTransferFee?: string;

/**
* @description To specify the protocol version. **Values:** 5 or 6.2 **Default**: 5.
*/
version?: number | string;

/**
* @description If tokens USD prices are not available, `Bad USD Price` error will be thrown. Use this param to skip this check. Default: `false`.
*/
ignoreBadUsdPrice?: boolean;

/**
* @description Specify if user should receive surplus instead of partner. Default: `false`.
*/
isSurplusToUser?: boolean;

/**
* @description Specify if fees should be sent directly to the partner instead of registering them on FeeClaimer. Default: `false`.
*/
isDirectFeeTransfer?: boolean;

/**
* @description Allows for capping the surplus at 1% maximum. Default: `true`.
*/
isCapSurplus?: boolean;

/**
* @description Allows to collect surplus. Works with `partnerAddress`. Default: `false`.
*/
takeSurplus?: boolean;
};

type SwapTxInputFields =
| 'srcToken'
| 'destToken'
| 'amount'
| 'side'
| 'srcDecimals'
| 'destDecimals'
| 'userAddress';
type SwapTxInputListFields =
| 'includeDEXS'
| 'excludeDEXS'
| 'includeContractMethods'
| 'excludeContractMethods'
| 'route';

type SwapRateOptions = Omit<
SwapQueryParams,
SwapTxInputFields | SwapTxInputListFields | 'network' | 'version'
>;

type SwapTxInput = Pick<SwapQueryParams, SwapTxInputFields> & {
/**
* @description List of DEXs to include. **Supported DEXs:** Uniswap, Kyber, Bancor, AugustusRFQ, Oasis, Compound, Fulcrum, 0x, MakerDAO, Chai, Aave, Aave2, MultiPath, MegaPath, Curve, Curve3, Saddle, IronV2, BDai, idle, Weth, Beth, UniswapV2, Balancer, 0xRFQt, SushiSwap, LINKSWAP, Synthetix, DefiSwap, Swerve, CoFiX, Shell, DODOV1, DODOV2, OnChainPricing, PancakeSwap, PancakeSwapV2, ApeSwap, Wbnb, acryptos, streetswap, bakeryswap, julswap, vswap, vpegswap, beltfi, ellipsis, QuickSwap, COMETH, Wmatic, Nerve, Dfyn, UniswapV3, Smoothy, PantherSwap, OMM1, OneInchLP, CurveV2, mStable, WaultFinance, MDEX, ShibaSwap, CoinSwap, SakeSwap, JetSwap, Biswap, BProtocol eg: `UniswapV3,0x`.
*/
includeDEXS?: string[];

/**
* @description List of DEXs to exclude. (from the list of DEXs mentioned above).
*/
excludeDEXS?: string[];

/**
* @description List of Contract Methods to include without spaces. **Available values:** swapOnUniswap, buyOnUniswap, swapOnUniswapFork, buyOnUniswapFork, swapOnUniswapV2Fork, buyOnUniswapV2Fork, simpleBuy, simpleSwap, multiSwap, megaSwap, protectedMultiSwap, protectedMegaSwap, protectedSimpleSwap, protectedSimpleBuy, swapOnZeroXv2, swapOnZeroXv4, buy. eg: `simpleSwap,multiSwap`.
*/
includeContractMethods?: string[];

/**
* @description List of Contract Methods to exclude without spaces. (from the list of contract methods mentioned above).
*/
excludeContractMethods?: string[];

/**
* @description List of tokens (addresses or symbols from `/tokens`) to comprise the price route. _Max 4 tokens._ _**\*Note:**_ _If_ `_route_` _is specified, the response will only comprise of the route specified which might not be the optimal route._
*/
route?: string[];

options?: SwapRateOptions;
};

export type SwapTxResult = SwapApiResponse;

export type GetSwapTxData = (
options: SwapTxInput,
signal?: AbortSignal
) => Promise<SwapTxResult>;

export type GetSwapTxFunctions = {
getSwapTxData: GetSwapTxData;
};

type CommonGetRateInput = {
amount: PriceString;
userAddress?: Address;
side?: SwapSide;
options?: RateOptions;
srcDecimals?: number;
destDecimals?: number;
};

export type GetRateInput = CommonGetRateInput & {
srcToken: AddressOrSymbol;
destToken: AddressOrSymbol;
};

export type GetRate = (
options: GetRateInput,
signal?: AbortSignal
) => Promise<OptimalRate>;

type GetRateByRouteInput = CommonGetRateInput & {
route: AddressOrSymbol[];
};

type GetRateByRoute = (
options: GetRateByRouteInput,
signal?: AbortSignal
) => Promise<OptimalRate>;

export type GetRateFunctions = {
getRate: GetRate;
getRateByRoute: GetRateByRoute;
};

export const constructSwapTx = ({
apiURL = API_URL,
version = DEFAULT_VERSION,
chainId,
fetcher,
}: ConstructFetchInput): GetSwapTxFunctions => {
const pricesUrl = `${apiURL}/swap` as const;

const getSwapTxData: GetSwapTxData = async (
{ srcToken, destToken, amount, route, ...rest },
signal
) => {
const parsedOptions = noramalizeRateOptions(rest);

const _route = route?.join('-');

// always pass explicit type to make sure UrlSearchParams are correct
const search = constructSearchString<SwapQueryParams>({
amount,
srcToken,
destToken,
route: _route,
network: chainId,
version,
...parsedOptions,
});

const fetchURL = `${pricesUrl}/${search}` as const;

const data = await fetcher<SwapApiResponse>({
url: fetchURL,
method: 'GET',
signal,
});

return data;
};

return {
getSwapTxData,
};
};

0 comments on commit c9572e4

Please sign in to comment.