-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
341 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
}; | ||
}; |