import { PairInfo } from '@premia/pair-lists/src/types' import { Provider, toBigInt } from 'ethers' import { BlackScholes } from '@uqee/black-scholes' import { TokenPair, TokenPairExtended, TokenPairMinimal } from '../entities' import { BaseAPI } from './baseAPI' // Newton-Raphoson method fails for low vega options (near dated or deep OTM-ITM) // So we use a slower, but more universal bisection export const blackScholes = new BlackScholes({ priceToSigmaMethod: 'bisection', priceToSigmaAccuracy: 1e-2, priceToSigmaBRight: 4, }) export const ONE_YEAR_MS = 1000 * 60 * 60 * 24 * 365 export type TokenPairOrInfo = PairInfo | TokenPair | TokenPairMinimal export type TokenPairOrId = TokenPairOrInfo | string /** * Represents a class for handling `TokenPair` operations related to the voidnode server. * * @class TokenPairAPI * @extends {BaseAPI} */ export class TokenPairAPI extends BaseAPI { /** * Fetches the current spot price of a token pair from the price oracle. * Uses caching with a one-minute time-to-live. * * @param {TokenPairOrId} pair - The token pair to fetch the spot price for. * @param {Provider} provider - The custom provider to use for this call. * @returns {Promise} The current spot price of the token pair. */ async getSpotPrice( pair: TokenPairOrId, provider?: Provider ): Promise { const _pair = this.premia.voidnode._parsePair(pair) const oracleAdapter = await this.premia.contracts.getOracleAdapterContract( _pair.priceOracleAddress, provider ?? this.premia.multicallProvider ) return toBigInt(await oracleAdapter.getPrice(_pair.base, _pair.quote)) } /** * Gets the strike interval for a token pair based on its spot price. * * @param {TokenPairOrId} pair - The token pair to fetch the strike increment for. * @param {Provider} provider - The custom provider to use for this call. * @returns {Promise} The strike increment for the token pair. */ async getStrikeInterval( pair: TokenPairOrId, provider?: Provider ): Promise { const spotPrice = await this.getSpotPrice(pair, provider) const interval = this.premia.options.getStrikeInterval(Number(spotPrice)) return toBigInt(interval) } /** * Fetches data for a token pair from the voidnode server. * Uses caching with a one-day time-to-live. * * @param {TokenPairOrId} pair - The token pair or id to fetch the data for. * * @returns {Promise} The data for the token pair. */ async getPair(pair: TokenPairOrId): Promise { return this.premia.voidnode.getPair(pair) } /** * Retrieves extended information for a token pair. * Uses caching with a one-minute time-to-live. * * @param {TokenPairOrId} pair - The token pair to fetch the extended information for. * * @returns {Promise} The extended information for the token pair. */ async getPairExtended(pair: TokenPairOrId): Promise { return this.premia.voidnode.getPairExtended(pair) } /** * Fetches data for multiple token pairs. * Uses caching with a one-day time-to-live. * * @param {TokenPairOrId[]} pairs - An array of token pairs to fetch the data for. * * @returns {Promise} The data for the specified token pairs. */ async getPairs(pairs: TokenPairOrId[]): Promise { return this.premia.voidnode.getPairs(pairs) } /** * Retrieves extended information for multiple token pairs. * Uses caching with a one-minute time-to-live. * * @param {TokenPairOrId[]} pairs - An array of token pairs to fetch the extended information for. * * @returns {Promise} The extended information for the specified token pairs. */ async getPairsExtended(pairs: TokenPairOrId[]): Promise { return this.premia.voidnode.getPairsExtended(pairs) } }