wido
Version:
JavaScript library for interacting with the Wido protocol which allows you to seamlessly move liquidity across vaults and chains.
148 lines (134 loc) • 3.25 kB
text/typescript
import { CONFIG } from "./config"
import {
QuoteResult,
QuoteApiParams,
QuoteApiResponse,
QuoteRequest,
} from "./types"
import { WidoError } from "./WidoError"
/**
* Get an easy-to-consume quote and a unsigned transaction for zapping any ERC20 token,
* on behalf of `user`, spending `fromToken` and receiving `toToken` in exchange.
*
* Note: `user` and `amount` are required to receive a valid unsigned tx.
*/
export async function quote(request: QuoteRequest): Promise<QuoteResult> {
const {
user,
fromChainId,
fromToken,
toChainId,
toToken,
amount,
slippagePercentage = 0.01,
varsOverride = {},
partner,
lowerTick,
upperTick,
tokenId,
recipient,
gaslessType,
providers,
} = request
const endpoint = "quote_v2"
const paramsObj: QuoteApiParams = {
from_chain_id: String(fromChainId),
from_token: fromToken,
to_chain_id: String(toChainId),
to_token: toToken,
...varsOverride,
}
if (slippagePercentage) {
paramsObj.slippage_percentage = String(slippagePercentage)
}
if (amount) {
paramsObj.amount = amount
}
if (user) {
paramsObj.user = user
}
if (partner) {
paramsObj.partner = partner
}
if (lowerTick) {
paramsObj.lower_tick = lowerTick
}
if (upperTick) {
paramsObj.upper_tick = upperTick
}
if (tokenId) {
paramsObj.token_id = tokenId
}
if (recipient) {
paramsObj.recipient = recipient
}
if (gaslessType) {
paramsObj.gasless_type = gaslessType
}
const params = new URLSearchParams(paramsObj)
if (providers) {
for (const provider of providers) {
params.append("providers", provider)
}
}
const url = `${CONFIG.WIDO_API_URL}/${endpoint}?${params}`
const res = await fetch(url)
if (!res.ok) {
throw WidoError.from_api_response(await res.json())
}
const body: QuoteApiResponse = await res.json()
const { is_supported, steps, steps_count, messages } = body
const baseQuoteResult: QuoteResult = {
isSupported: is_supported,
steps,
stepsCount: steps_count,
messages: messages || [],
}
if (!amount && !user) {
return baseQuoteResult
}
const {
price,
min_price,
from_token_usd_price,
from_token_amount,
from_token_amount_usd_value,
to_token_usd_price,
to_token_amount,
to_token_amount_usd_value,
expected_slippage,
min_to_token_amount,
from,
to,
data,
value,
gas_fee,
gas_fee_usd,
fee_in_from_token,
bridge_fee_usd_value,
fee_usd_value,
} = body
return {
...baseQuoteResult,
price,
minPrice: min_price,
fromTokenUsdPrice: from_token_usd_price,
fromTokenAmount: from_token_amount,
fromTokenAmountUsdValue: from_token_amount_usd_value,
toTokenUsdPrice: to_token_usd_price,
toTokenAmount: to_token_amount,
toTokenAmountUsdValue: to_token_amount_usd_value,
expectedSlippage: expected_slippage,
minToTokenAmount: min_to_token_amount,
from,
to,
data,
value,
gasFee: gas_fee,
gasFeeUsdValue: gas_fee_usd,
feeBps: body.fee_bps,
feeInFromToken: fee_in_from_token,
bridgeFeeUsdValue: bridge_fee_usd_value,
feeUsdValue: fee_usd_value,
} as QuoteResult
}