UNPKG

@0xsplits/splits-sdk

Version:

SDK for the 0xSplits protocol

95 lines (83 loc) 2.66 kB
import { GetContractReturnType, getAddress, getContract } from 'viem' import { BaseTransactions } from './base' import { TransactionType, ORACLE_CHAIN_IDS } from '../constants' import { uniV3OracleAbi } from '../constants/abi/uniV3Oracle' import type { QuoteParams, SplitsClientConfig, SplitsPublicClient, TransactionConfig, } from '../types' import { validateAddress } from '../utils/validation' type UniV3OracleAbi = typeof uniV3OracleAbi class OracleTransactions extends BaseTransactions { constructor(transactionClientArgs: SplitsClientConfig & TransactionConfig) { super({ supportedChainIds: ORACLE_CHAIN_IDS, ...transactionClientArgs, }) } protected _getOracleContract( oracle: string, chainId: number, ): GetContractReturnType<UniV3OracleAbi, SplitsPublicClient> { const publicClient = this._getPublicClient(chainId) return getContract({ address: getAddress(oracle), abi: uniV3OracleAbi, client: publicClient, }) } } export class OracleClient extends OracleTransactions { constructor(clientArgs: SplitsClientConfig) { super({ transactionType: TransactionType.Transaction, ...clientArgs, }) } // Read actions async getQuoteAmounts({ oracleAddress, quoteParams, chainId, }: { oracleAddress: string quoteParams: QuoteParams[] chainId?: number }): Promise<{ quoteAmounts: bigint[] }> { validateAddress(oracleAddress) const functionChainId = this._getReadOnlyFunctionChainId(chainId) const publicClient = this._getPublicClient(functionChainId) // It's possible to fetch all quotes in a single request to the oracle, but if the // oracle hits an error for just one pair there is no way to separate that out. So // instead we are making a multicall combining each individual quote request. This // allows us to easily filter out the failed quotes. const multicallResponse = await publicClient.multicall({ contracts: quoteParams.map((quoteParam) => { return { address: getAddress(oracleAddress), abi: uniV3OracleAbi, functionName: 'getQuoteAmounts', args: [ [ [ [quoteParam.quotePair.base, quoteParam.quotePair.quote], quoteParam.baseAmount, quoteParam.data ?? '0x', ], ], ], } }), }) const quoteAmounts = multicallResponse.map((data) => { return data.status === 'success' ? (data.result as unknown as bigint[])[0] : BigInt(0) }) return { quoteAmounts } } }