{"version":3,"sources":["../../src/utils/market.ts","../../src/constants/common.ts"],"sourcesContent":["import { encodeAbiParameters, Hex, parseUnits } from 'viem';\nimport { SynthetixSdk } from '..';\nimport { CUSTOM_DECIMALS, DISABLED_MARKETS } from '../constants';\nimport { MarketIdOrName } from '../interface/commonTypes';\nimport { MarketData, SpotMarketData } from '../perps/interface';\nimport { Call3Value } from '../interface/contractTypes';\n\nexport abstract class Market<T extends MarketData | SpotMarketData> {\n  sdk: SynthetixSdk;\n  marketsById: Map<number, T>;\n  marketsByName: Map<string, T>;\n\n  // Mapping of Market Symbol to T.\n  // @note Ideally prefer using market symbol over market name\n  marketsBySymbol: Map<string, T>;\n  disabledMarkets: number[] = [];\n\n  constructor(synthetixSdk: SynthetixSdk) {\n    this.sdk = synthetixSdk;\n    // Initialize empty market data\n    this.marketsById = new Map<number, T>();\n    this.marketsByName = new Map<string, T>();\n    this.marketsBySymbol = new Map<string, T>();\n\n    // Set disabled markets\n    if (synthetixSdk.rpcConfig.chainId in DISABLED_MARKETS) {\n      this.disabledMarkets = DISABLED_MARKETS[synthetixSdk.rpcConfig.chainId];\n    }\n  }\n  /**\n   * Look up the market_id and market_name for a market. If only one is provided,\n   * the other is resolved. If both are provided, they are checked for consistency.\n   * @param marketIdOrName Id or name of the market to resolve\n   */\n  public async resolveMarket(\n    marketIdOrName: MarketIdOrName,\n  ): Promise<{ resolvedMarketId: number; resolvedMarketName: string }> {\n    // Do not resolve markets if flag is not set or if market name is passed as\n    // an argument\n    if (!this.sdk.resolveMarketNames && typeof marketIdOrName === 'number') {\n      console.log('Resolve markets set to false. Returning market id without validating...');\n      return { resolvedMarketName: 'Unresolved Market', resolvedMarketId: Number(marketIdOrName) };\n    }\n\n    const market = await this.getMarket(marketIdOrName);\n    if (!market?.marketName || market?.marketId === undefined)\n      throw new Error(`Market not found for ${marketIdOrName}`);\n\n    return { resolvedMarketName: market.marketName, resolvedMarketId: market.marketId };\n  }\n\n  /**\n   * Format the size of a synth for an order. This is used for synths whose base asset\n   * does not use 18 decimals. For example, USDC uses 6 decimals, so we need to handle size\n   * differently from other assets.\n   * @param size The size as an ether value (e.g. 100).\n   * @param marketId The id of the market.\n   * @returns The formatted size in wei. (e.g. 100 = 100000000000000000000)\n   */\n  public async formatSize(size: number, marketId: MarketIdOrName) {\n    // TODO: think in a better solution maybe get the collateral and query the decimals from the contract\n\n    return parseUnits(size.toString(), CUSTOM_DECIMALS[this.sdk.rpcConfig.chainId][marketId] || 18);\n  }\n\n  async prepareOracleCallsWithPriceId(priceFeedIds: string[]): Promise<Call3Value[]> {\n    if (!priceFeedIds.length) {\n      return [];\n    }\n    const stalenessTolerance = 30n; // 30 seconds\n    const updateData = await this.sdk.pyth.getPriceFeedsUpdateData(priceFeedIds as Hex[]);\n\n    const signedRequiredData = encodeAbiParameters(\n      [\n        { type: 'uint8', name: 'updateType' },\n        { type: 'uint64', name: 'stalenessTolerance' },\n        { type: 'bytes32[]', name: 'priceIds' },\n        { type: 'bytes[]', name: 'updateData' },\n      ],\n      [1, stalenessTolerance, priceFeedIds as Hex[], updateData],\n    );\n\n    const pythWrapper = await this.sdk.contracts.getPythErc7412WrapperInstance();\n    const dataVerificationTx = this.sdk.utils.generateDataVerificationTx(pythWrapper.address, signedRequiredData);\n\n    // set `requireSuccess` to false in this case, since sometimes\n    // the wrapper will return an error if the price has already been updated\n\n    // @note A better approach would be to fetch the priceUpdateFee for tx dynamically\n    // from the Pyth contract instead of using arbitrary values for pyth price update fees\n    return [{ ...dataVerificationTx, value: 0n, requireSuccess: false }];\n  }\n\n  /**\n   *   Prepare a call to the external node with oracle updates for the specified market names.\n   * The result can be passed as the first argument to a multicall function to improve performance\n   * of ERC-7412 calls. If no market names are provided, all markets are fetched. This is useful for\n   * read functions since the user does not pay gas for those oracle calls, and reduces RPC calls and\n   * runtime.\n   * @param {number[]} marketIds An array of market ids to fetch prices for. If not provided, all markets are fetched\n   * @returns {Promise<Call3Value[]>} objects representing the target contract, call data, value, requireSuccess flag and other necessary details for executing the function in the blockchain.\n   */\n  public async prepareOracleCall(marketIds: number[] = []): Promise<Call3Value[]> {\n    let priceFeedIds: string[] = [];\n\n    if (marketIds.length != 0) {\n      const marketSymbols: string[] = [];\n      marketIds.forEach((marketId) => {\n        const marketSymbol = this.marketsById.get(marketId)?.symbol;\n        if (!marketSymbol) return;\n        marketSymbols.push(marketSymbol);\n      });\n\n      marketSymbols.forEach((marketSymbol) => {\n        const feedId = this.sdk.pyth.priceFeedIds.get(marketSymbol);\n        if (!feedId) return;\n        priceFeedIds.push(feedId);\n      });\n    } else {\n      priceFeedIds = Array.from(this.sdk.pyth.priceFeedIds.values());\n    }\n\n    return this.prepareOracleCallsWithPriceId(priceFeedIds);\n  }\n\n  public async getMarket(marketIdOrName: MarketIdOrName): Promise<T> {\n    throw new Error('Method not implemented. ' + marketIdOrName);\n  }\n}\n","import { Hex, zeroAddress } from 'viem';\nimport { MarketIdOrName } from '../interface/commonTypes';\nimport { SUPPORTED_CHAINS } from './chains';\n\nexport const ZERO_ADDRESS: Hex = zeroAddress;\n\nexport const SIG_ORACLE_DATA_REQUIRED = '0xcf2cabdf';\nexport const SIG_FEE_REQUIRED = '0x0e7186fb';\nexport const SIG_ERRORS = '0x0b42fd17';\n\n// for markets metadata it is requesting too much oracle updates\nexport const MAX_ERC7412_RETRIES = 80; // Limit the max failures to prevent infinite loops\n\n// List of market ids disabled by chainId\nexport const DISABLED_MARKETS: { [key: number]: number[] } = {\n  84532: [3, 6300],\n  8453: [6300],\n};\n\nexport const publicRpcEndpoints: { [key: number]: string } = {\n  8453: 'https://base.llamarpc.com',\n  84532: 'https://sepolia.base.org',\n  42161: 'https://arbitrum.llamarpc.com',\n  421614: 'https://sepolia-rollup.arbitrum.io/rpc',\n};\n\n// Logger constants\nexport type LOGGER_MESSAGE_TYPE = 'json' | 'pretty' | 'hidden';\n\n// 0: silly, 1: trace, 2: debug, 3: info, 4: warn, 5: error, 6: fatal\nexport const DEFAULT_LOGGER_LEVEL = 4; // https://tslog.js.org/#/?id=highlights to see more levels\nexport const CUSTOM_DECIMALS: Record<number, Record<MarketIdOrName, number>> = {\n  [SUPPORTED_CHAINS.ARBITUM_SEPOLIA]: {\n    2: 6,\n    USDC: 6,\n  },\n  [SUPPORTED_CHAINS.ARBITRUM]: {\n    2: 6,\n    USDC: 6,\n  },\n  [SUPPORTED_CHAINS.BASE_SEPOLIA]: {\n    1: 6,\n    USDC: 6,\n  },\n  [SUPPORTED_CHAINS.BASE]: {\n    1: 6,\n    USDC: 6,\n  },\n};\n"],"mappings":"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","names":[]}