@dimes-dot-fi/sdk 2.0.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{aliases-BJyM8ydu.d.cts → aliases-RwEPSZoO.d.cts} +91 -1
- package/dist/{aliases-BJyM8ydu.d.ts → aliases-RwEPSZoO.d.ts} +91 -1
- package/dist/contract/index.cjs +8 -1
- package/dist/contract/index.cjs.map +1 -1
- package/dist/contract/index.d.cts +3 -3
- package/dist/contract/index.d.ts +3 -3
- package/dist/contract/index.mjs +8 -1
- package/dist/contract/index.mjs.map +1 -1
- package/dist/{dimes-client-DYFvnZUx.d.ts → dimes-client-BLTd5GkU.d.ts} +9 -1
- package/dist/{dimes-client-DZPhU1CG.d.cts → dimes-client-CK7WmY0g.d.cts} +9 -1
- package/dist/{dimes-error-BlQWPqhQ.d.cts → dimes-error-CU1Ob_ed.d.cts} +1 -1
- package/dist/{dimes-error-DBKV5bfr.d.ts → dimes-error-DBT1WPVq.d.ts} +1 -1
- package/dist/index.cjs +11 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.mjs +11 -2
- package/dist/index.mjs.map +1 -1
- package/dist/{quote-CanwfT9m.d.cts → quote-CPl9ceZ3.d.cts} +2 -2
- package/dist/{quote-BFNgVsY-.d.ts → quote-D34eTxx3.d.ts} +2 -2
- package/dist/react/index.cjs +20 -2
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +11 -5
- package/dist/react/index.d.ts +11 -5
- package/dist/react/index.mjs +22 -4
- package/dist/react/index.mjs.map +1 -1
- package/dist/{types-ClHQbIcY.d.ts → types-Bf10ReSH.d.ts} +1 -1
- package/dist/{types-Co-2bQSi.d.cts → types-CL4jY3Gp.d.cts} +1 -1
- package/dist/ws/index.d.cts +3 -3
- package/dist/ws/index.d.ts +3 -3
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/dimes-client.ts","../src/client/http.ts","../src/client/auth.ts","../src/types/aliases.ts","../src/utils/eligibility.ts","../src/utils/leverage.ts","../src/utils/fees.ts","../src/utils/max-gain.ts","../src/utils/partial-close.ts"],"sourcesContent":["import { decamelizeKeys } from \"humps\";\nimport type {\n ContractInfo,\n CreateQuoteParams,\n CustomerLimit,\n FeeRates,\n FeeReport,\n FeeReportParams,\n Market,\n Paginated,\n Position,\n PositionTransactions,\n Quote,\n} from \"../types\";\nimport type { AuthProvider } from \"./auth\";\nimport { HttpClient } from \"./http\";\n\nexport interface DimesClientOptions {\n baseUrl?: string;\n auth: AuthProvider;\n fetch?: typeof globalThis.fetch;\n maxRetries?: number;\n maxRetryDelayMs?: number;\n}\n\nexport type MarketSort = \"ticker_asc\" | \"depth_desc\" | \"discovered_at_desc\";\n\nexport type MarketExpand = \"total_count\" | \"prices\";\n\nexport type PositionStatus = \"open\" | \"unwinding\" | \"pending\" | \"closing\" | \"closed\" | \"settled\" | \"liquidated\";\n\nexport interface GetMarketsParams {\n limit?: number;\n startingAfter?: string;\n endingBefore?: string;\n expand?: MarketExpand[];\n sort?: MarketSort;\n acceptingNewPositions?: boolean;\n category?: string;\n status?: string;\n provider?: \"polymarket\" | \"kalshi\";\n}\n\nexport interface SearchMarketsParams extends GetMarketsParams {\n query: string;\n}\n\nexport interface GetPositionsParams {\n limit?: number;\n startingAfter?: string;\n endingBefore?: string;\n expand?: string[];\n sortBy?: \"created_at\" | \"closed_at\";\n sortDirection?: \"asc\" | \"desc\";\n status?: PositionStatus;\n state?: \"active\" | \"inactive\";\n}\n\nexport interface GetFeeRatesParams {\n ticker?: string;\n}\n\nfunction buildQueryFromEntries(entries: [string, unknown][]): string {\n const filtered = entries.filter(([, v]) => v !== undefined && v !== null);\n if (filtered.length === 0) {\n return \"\";\n }\n\n const search = new URLSearchParams();\n for (const [key, value] of filtered) {\n search.set(\n key.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`),\n String(value),\n );\n }\n\n return `?${search.toString()}`;\n}\n\nexport class DimesClient {\n /** The resolved API base URL. Useful for constructing WebSocket clients against the same host. */\n public readonly baseUrl: string;\n\n private readonly http: HttpClient;\n\n private readonly auth: AuthProvider;\n\n constructor(options: DimesClientOptions) {\n this.baseUrl = options.baseUrl ?? \"https://api.dimes.fi\";\n this.auth = options.auth;\n this.http = new HttpClient({\n baseUrl: this.baseUrl,\n auth: options.auth,\n fetch: options.fetch,\n maxRetries: options.maxRetries,\n maxRetryDelayMs: options.maxRetryDelayMs,\n });\n }\n\n /** Synchronously return the current cached JWT, or null. Returns null if the auth provider does not expose one. */\n public getToken(): string | null {\n return this.auth.getToken?.() ?? null;\n }\n\n public async getMarkets(params?: GetMarketsParams): Promise<Paginated<Market>> {\n const query = params ? buildQueryFromEntries(Object.entries(params)) : \"\";\n return this.http.request<Paginated<Market>>(`/v1/prediction-markets/markets${query}`);\n }\n\n public async getMarket(ticker: string): Promise<Market> {\n return this.http.request<Market>(`/v1/prediction-markets/markets/${encodeURIComponent(ticker)}`);\n }\n\n public async searchMarkets(params: SearchMarketsParams): Promise<Paginated<Market>> {\n const query = buildQueryFromEntries(Object.entries(params));\n return this.http.request<Paginated<Market>>(`/v1/prediction-markets/markets/search${query}`);\n }\n\n public async createDraftQuote(params: CreateQuoteParams): Promise<Quote> {\n return this.http.request<Quote>(\"/v1/prediction-markets/draft-quotes\", {\n method: \"POST\",\n body: JSON.stringify(decamelizeKeys(params)),\n });\n }\n\n public async promoteDraftQuote(draftId: string): Promise<Quote> {\n return this.http.request<Quote>(`/v1/prediction-markets/promoted-quotes/${encodeURIComponent(draftId)}`, {\n method: \"POST\",\n });\n }\n\n public async createQuote(params: CreateQuoteParams): Promise<Quote> {\n return this.http.request<Quote>(\"/v1/prediction-markets/quotes\", {\n method: \"POST\",\n body: JSON.stringify(decamelizeKeys(params)),\n });\n }\n\n public async getPositions(params?: GetPositionsParams): Promise<Position[]> {\n const query = params ? buildQueryFromEntries(Object.entries(params)) : \"\";\n return this.http.requestList<Position>(`/v1/prediction-markets/positions${query}`);\n }\n\n public async getPositionTransactions(positionId: string): Promise<PositionTransactions> {\n return this.http.request<PositionTransactions>(\n `/v1/prediction-markets/positions/${encodeURIComponent(positionId)}/transactions`,\n );\n }\n\n public async cancelPosition(positionId: string): Promise<void> {\n await this.http.request<unknown>(`/v1/prediction-markets/positions/${encodeURIComponent(positionId)}`, {\n method: \"DELETE\",\n });\n }\n\n public async getContractInfo(): Promise<ContractInfo> {\n return this.http.request<ContractInfo>(\"/v1/prediction-markets/contract-info\");\n }\n\n public async getUserLimits(): Promise<CustomerLimit> {\n return this.http.request<CustomerLimit>(\"/v1/prediction-markets/user-limits\");\n }\n\n public async getPartnerLimits(): Promise<CustomerLimit> {\n return this.http.request<CustomerLimit>(\"/v1/prediction-markets/partner-limits\");\n }\n\n /**\n * @deprecated The `/limits` path was never served by the API. Use {@link getUserLimits}\n * (JWT/user context) or {@link getPartnerLimits} (API-key/partner context). This alias\n * forwards to `getUserLimits` and will be removed in a future major.\n */\n public async getLimits(): Promise<CustomerLimit> {\n return this.getUserLimits();\n }\n\n public async getFeeRates(params?: GetFeeRatesParams): Promise<FeeRates> {\n const query = params ? buildQueryFromEntries(Object.entries(params)) : \"\";\n return this.http.request<FeeRates>(`/v1/prediction-markets/fee-rates${query}`);\n }\n\n public async getFeeReport(params: FeeReportParams): Promise<FeeReport> {\n return this.http.request<FeeReport>(\"/v1/prediction-markets/fee-reports\", {\n method: \"POST\",\n body: JSON.stringify(decamelizeKeys(params)),\n });\n }\n}\n","import { camelizeKeys, type Camelized } from \"humps\";\nimport { DimesApiError } from \"../errors/dimes-error\";\nimport type { AuthProvider } from \"./auth\";\n\nexport type { Camelized };\n\ninterface ApiErrorBody {\n error?: {\n type?: string;\n code?: string;\n message: string;\n params?: Record<string, unknown>;\n };\n}\n\nconst HTTP_UNAUTHORIZED = 401;\nconst HTTP_TOO_MANY_REQUESTS = 429;\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_MAX_RETRY_DELAY_MS = 60_000;\nconst DEFAULT_RETRY_DELAY_MS = 1000;\nconst BACKOFF_FACTOR = 2;\nconst MS_PER_SECOND = 1000;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction parseRetryAfterMs(header: string | null, attempt: number): number {\n const fallbackMs = DEFAULT_RETRY_DELAY_MS * BACKOFF_FACTOR ** attempt;\n if (!header) {\n return fallbackMs;\n }\n\n const seconds = Number(header);\n if (!Number.isNaN(seconds) && seconds >= 0) {\n return seconds * MS_PER_SECOND;\n }\n\n const dateMs = Date.parse(header);\n if (!Number.isNaN(dateMs)) {\n return Math.max(0, dateMs - Date.now());\n }\n\n return fallbackMs;\n}\n\n// eslint-disable-next-line complexity\nasync function throwFromResponse(response: Response): Promise<never> {\n const rawBody = await response.text();\n let parsed: ApiErrorBody | null;\n try {\n parsed = rawBody ? (JSON.parse(rawBody) as ApiErrorBody) : null;\n } catch {\n parsed = null;\n }\n\n const code = parsed?.error?.code ?? \"unknown_error\";\n const type = parsed?.error?.type ?? null;\n const message = parsed?.error?.message ?? `API error ${response.status}`;\n const rawParams = parsed?.error?.params;\n const params = rawParams ? (camelizeKeys(rawParams) as Record<string, unknown>) : null;\n\n throw new DimesApiError({ status: response.status, code, type, message, params });\n}\n\nexport interface HttpClientOptions {\n baseUrl: string;\n auth: AuthProvider;\n fetch?: typeof globalThis.fetch;\n maxRetries?: number;\n maxRetryDelayMs?: number;\n}\n\nexport class HttpClient {\n private readonly baseUrl: string;\n\n private readonly auth: AuthProvider;\n\n private readonly fetchFn: typeof globalThis.fetch;\n\n private readonly maxRetries: number;\n\n private readonly maxRetryDelayMs: number;\n\n constructor(options: HttpClientOptions) {\n this.baseUrl = options.baseUrl;\n this.auth = options.auth;\n this.fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);\n this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;\n this.maxRetryDelayMs = options.maxRetryDelayMs ?? DEFAULT_MAX_RETRY_DELAY_MS;\n }\n\n public async request<T>(path: string, options?: RequestInit): Promise<T> {\n const authHeaders = await this.auth.getHeaders();\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...authHeaders,\n ...(options?.headers as Record<string, string> | undefined),\n };\n\n let response = await this.fetchFn(`${this.baseUrl}${path}`, {\n ...options,\n headers,\n });\n\n if (response.status === HTTP_UNAUTHORIZED && this.auth.refresh) {\n await this.auth.refresh();\n const retryHeaders = await this.auth.getHeaders();\n response = await this.fetchFn(`${this.baseUrl}${path}`, {\n ...options,\n headers: { ...headers, ...retryHeaders },\n });\n }\n\n for (let attempt = 0; response.status === HTTP_TOO_MANY_REQUESTS && attempt < this.maxRetries; attempt++) {\n const delayMs = parseRetryAfterMs(response.headers.get(\"retry-after\"), attempt);\n if (delayMs > this.maxRetryDelayMs) {\n break;\n }\n await sleep(delayMs);\n const freshAuth = await this.auth.getHeaders();\n response = await this.fetchFn(`${this.baseUrl}${path}`, {\n ...options,\n headers: { ...headers, ...freshAuth },\n });\n }\n\n if (!response.ok) {\n await throwFromResponse(response);\n }\n\n return camelizeKeys(await response.json()) as T;\n }\n\n public async requestList<T>(path: string, options?: RequestInit): Promise<T[]> {\n const result = await this.request<{ data: T[] }>(path, options);\n return result.data;\n }\n}\n","import { DimesError } from \"../errors/dimes-error\";\n\nexport interface AuthProvider {\n getHeaders(): Promise<Record<string, string>>;\n refresh?(): Promise<void>;\n /** Synchronously return the current cached JWT, or null if not yet obtained. Used by the WebSocket clients. */\n getToken?(): string | null;\n}\n\ninterface TokenResponse {\n token: string;\n expires_at: string;\n}\n\nexport interface ApiKeyAuthOptions {\n apiKey: string;\n walletAddress: string;\n baseUrl?: string;\n fetch?: typeof globalThis.fetch;\n}\n\nexport class ApiKeyAuth implements AuthProvider {\n private jwt: string | null = null;\n\n private expiresAt = 0;\n\n private refreshPromise: Promise<void> | null = null;\n\n private readonly apiKey: string;\n\n private readonly walletAddress: string;\n\n private readonly baseUrl: string;\n\n private readonly fetchFn: typeof globalThis.fetch;\n\n constructor(options: ApiKeyAuthOptions) {\n this.apiKey = options.apiKey;\n this.walletAddress = options.walletAddress;\n this.baseUrl = options.baseUrl ?? \"https://api.dimes.fi\";\n this.fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n public async getHeaders(): Promise<Record<string, string>> {\n const TOKEN_EXPIRY_BUFFER_MS = 30_000;\n if (!this.jwt || Date.now() >= this.expiresAt - TOKEN_EXPIRY_BUFFER_MS) {\n await this.refresh();\n }\n return { Authorization: `Bearer ${this.jwt}` };\n }\n\n public getToken(): string | null {\n return this.jwt;\n }\n\n public async refresh(): Promise<void> {\n if (this.refreshPromise) {\n await this.refreshPromise;\n return;\n }\n\n this.refreshPromise = this.fetchToken();\n try {\n await this.refreshPromise;\n } finally {\n this.refreshPromise = null;\n }\n }\n\n private async fetchToken(): Promise<void> {\n const response = await this.fetchFn(`${this.baseUrl}/v1/prediction-markets/tokens`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Api-Key ${this.apiKey}`,\n },\n body: JSON.stringify({ wallet_address: this.walletAddress }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new DimesError(\"auth_token_failed\", `Failed to obtain auth token (${response.status}): ${text}`);\n }\n\n const data = (await response.json()) as TokenResponse;\n this.jwt = data.token;\n this.expiresAt = new Date(data.expires_at).getTime();\n }\n}\n\nexport interface JwtAuthOptions {\n tokenUrl: string;\n fetch?: typeof globalThis.fetch;\n}\n\nexport class JwtAuth implements AuthProvider {\n private readonly fetchFn: typeof globalThis.fetch;\n\n private readonly tokenUrl: string;\n\n private jwt: string | null = null;\n\n private expiresAt = 0;\n\n private refreshPromise: Promise<void> | null = null;\n\n constructor(options: JwtAuthOptions) {\n this.tokenUrl = options.tokenUrl;\n this.fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n public async getHeaders(): Promise<Record<string, string>> {\n const TOKEN_EXPIRY_BUFFER_MS = 30_000;\n if (!this.jwt || Date.now() >= this.expiresAt - TOKEN_EXPIRY_BUFFER_MS) {\n await this.refresh();\n }\n return { Authorization: `Bearer ${this.jwt}` };\n }\n\n public getToken(): string | null {\n return this.jwt;\n }\n\n public async refresh(): Promise<void> {\n if (this.refreshPromise) {\n await this.refreshPromise;\n return;\n }\n\n this.refreshPromise = this.fetchToken();\n try {\n await this.refreshPromise;\n } finally {\n this.refreshPromise = null;\n }\n }\n\n private async fetchToken(): Promise<void> {\n const response = await this.fetchFn(this.tokenUrl);\n\n if (!response.ok) {\n const text = await response.text();\n throw new DimesError(\n \"auth_token_failed\",\n `Failed to fetch token from ${this.tokenUrl} (${response.status}): ${text}`,\n );\n }\n\n const data = (await response.json()) as TokenResponse;\n this.jwt = data.token;\n this.expiresAt = new Date(data.expires_at).getTime();\n }\n}\n","import type { CamelizeKeys } from \"./camelize\";\nimport type { components } from \"./generated\";\n\ntype Raw = components[\"schemas\"];\n\nexport type Market = CamelizeKeys<Raw[\"CustomerMarket\"]>;\n\nexport type MarketLeverage = CamelizeKeys<Raw[\"CustomerLeverage\"]>;\n\nexport type MarketMaxLeveragePerNotional = CamelizeKeys<Raw[\"CustomerMaxMarketLeveragePerNotional\"]>;\n\nexport type MarketSidedMaxLeveragePerNotional = CamelizeKeys<Raw[\"CustomerSidedMaxMarketLeveragePerNotional\"]>;\n\nexport type MarketSidedEligibility = CamelizeKeys<Raw[\"CustomerSidedEligibility\"]>;\n\nexport type MarketFees = CamelizeKeys<Raw[\"CustomerFees\"]>;\n\nexport type MarketPrices = CamelizeKeys<Raw[\"CustomerMarketPrices\"]>;\n\nexport interface MarketPolymarket {\n conditionId: string | null;\n noTokenId: string;\n slug: string;\n yesTokenId: string;\n}\n\nexport type OriginationTier = CamelizeKeys<Raw[\"CustomerOriginationTier\"]>;\n\nexport type Quote = CamelizeKeys<Raw[\"CustomerOffer\"]>;\n\n/** @deprecated Use {@link Quote}. Back-compat alias; removed in a future major. */\n// eslint-disable-next-line no-restricted-syntax -- intentional deprecated alias\nexport type Offer = Quote;\n\nexport type OpenPosition = CamelizeKeys<Raw[\"CustomerOpenPosition\"]>;\n\nexport type ClosedPosition = CamelizeKeys<Raw[\"CustomerClosedPosition\"]>;\n\nexport type Position = OpenPosition | ClosedPosition;\n\nexport type PositionEntry = CamelizeKeys<Raw[\"CustomerPositionEntry\"]>;\n\nexport type PositionCurrent = CamelizeKeys<Raw[\"CustomerPositionCurrent\"]>;\n\nexport type PositionRisk = CamelizeKeys<Raw[\"CustomerPositionRisk\"]>;\n\nexport type PositionOpenFees = CamelizeKeys<Raw[\"CustomerPositionOpenFees\"]>;\n\nexport type PositionClosedFees = CamelizeKeys<Raw[\"CustomerPositionClosedFees\"]>;\n\nexport type PositionResult = CamelizeKeys<Raw[\"CustomerPositionResult\"]>;\n\nexport type PositionTiming = CamelizeKeys<Raw[\"CustomerPositionTiming\"]>;\n\nexport type PositionFailure = CamelizeKeys<Raw[\"CustomerPositionFailure\"]>;\n\nexport type CloseAttempt = CamelizeKeys<Raw[\"CustomerCloseAttempt\"]>;\n\nexport type PendingOperation = CamelizeKeys<Raw[\"CustomerPendingOperation\"]>;\n\nexport type PositionUnwind = CamelizeKeys<Raw[\"CustomerPositionUnwind\"]>;\n\nexport type PositionUnwindList = CamelizeKeys<Raw[\"CustomerPositionUnwindList\"]>;\n\nexport type PositionTransactionEntry = CamelizeKeys<Raw[\"PositionTransactionEntry\"]>;\n\nexport type PositionTransactionGroup = CamelizeKeys<Raw[\"PositionTransactionGroup\"]>;\n\nexport type PositionTransactions = CamelizeKeys<Raw[\"PositionTransactions\"]>;\n\nexport type ContractInfo = CamelizeKeys<Raw[\"CustomerContractInfo\"]>;\n\nexport type CustomerLimit = CamelizeKeys<Raw[\"CustomerLimit\"]>;\n\nexport type CreateTokenResult = CamelizeKeys<Raw[\"CreateTokenResult\"]>;\n\nexport type FeeRatesOriginationTier = CamelizeKeys<Raw[\"CustomerOriginationFeeTier\"]>;\n\nexport type FeeRatesMarket = CamelizeKeys<Raw[\"CustomerFeeRatesMarket\"]>;\n\nexport type FeeRates = CamelizeKeys<Raw[\"CustomerFeeRates\"]>;\n\nexport type FeeReport = CamelizeKeys<Raw[\"CustomerFeeReport\"]>;\n\nexport interface CreateQuoteParams {\n marketTicker: string;\n effectiveSide: \"yes\" | \"no\";\n leverageBps: number;\n notionalAmountUsdPips: string;\n slippageBps: number;\n pmProvider?: \"polymarket\" | \"kalshi\";\n allowPartialFill?: boolean;\n minFillBps?: number;\n}\n\n/** @deprecated Renamed to {@link CreateQuoteParams}. Kept as an alias for backward compatibility. */\n// eslint-disable-next-line no-restricted-syntax -- intentional deprecated alias\nexport type CreateOfferParams = CreateQuoteParams;\n\nexport interface FeeReportParams {\n marketTicker: string;\n effectiveSide: \"yes\" | \"no\";\n leverageBps: number;\n notionalAmountUsdPips: string;\n entryPriceUsdPips?: string;\n}\n\nexport function isOpenPosition(p: Position): p is OpenPosition {\n return \"current\" in p;\n}\n\nexport function isClosedPosition(p: Position): p is ClosedPosition {\n return \"result\" in p;\n}\n\nexport function leverageMaxBps(lev: MarketLeverage, side: \"yes\" | \"no\"): number {\n const perSide = side === \"yes\" ? lev.maxYesBps : lev.maxNoBps;\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return perSide ?? lev.maxBps ?? lev.minBps;\n}\n","import type { Market } from \"../types/aliases\";\n\nexport type Side = \"yes\" | \"no\";\n\nexport interface SideEligibility {\n open: boolean;\n reasonCode: string | null;\n}\n\nexport interface SidedEligibility {\n yes: SideEligibility;\n no: SideEligibility;\n}\n\nexport function getSidedEligibility(market: Market): SidedEligibility {\n const sided = market.sidedEligibility;\n return {\n yes: {\n open: sided.yes.acceptingNewPositions,\n reasonCode: sided.yes.rejectionReasonCode ?? null,\n },\n no: {\n open: sided.no.acceptingNewPositions,\n reasonCode: sided.no.rejectionReasonCode ?? null,\n },\n };\n}\n\nexport function defaultSide(eligibility: SidedEligibility): Side | null {\n if (eligibility.yes.open && eligibility.no.open) {\n return \"yes\";\n }\n if (eligibility.yes.open) {\n return \"yes\";\n }\n if (eligibility.no.open) {\n return \"no\";\n }\n return null;\n}\n\nexport function isFullyOpen(eligibility: SidedEligibility): boolean {\n return eligibility.yes.open && eligibility.no.open;\n}\n\nexport function isFullyClosed(eligibility: SidedEligibility): boolean {\n return !eligibility.yes.open && !eligibility.no.open;\n}\n\nexport function rejectionReasonText(code: string | null | undefined): string {\n if (!code) {\n return \"Not eligible for new positions\";\n }\n const stripped = code\n .replace(/^quote_/i, \"\")\n .replaceAll(\"_\", \" \")\n .toLowerCase();\n return stripped.charAt(0).toUpperCase() + stripped.slice(1);\n}\n\nexport function rejectionReasonShort(code: string | null | undefined): string {\n if (!code) {\n return \"unavailable\";\n }\n const stripped = code\n .replace(/^quote_/i, \"\")\n .replace(/_exceeded$/i, \"\")\n .replace(/_too_(low|high)$/i, \"\")\n .replaceAll(\"_\", \" \")\n .toLowerCase();\n return stripped;\n}\n","import { type Market, type MarketMaxLeveragePerNotional, leverageMaxBps } from \"../types/aliases\";\nimport type { Side } from \"./eligibility\";\n\nconst USD_100 = 100;\nconst USD_500 = 500;\nconst USD_1K = 1_000;\nconst USD_10K = 10_000;\nconst BPS_PER_UNIT = 10_000;\n\nconst ANCHORS_USD = [USD_100, USD_500, USD_1K, USD_10K] as const;\n\ntype Anchor = readonly [usd: number, bps: number];\n\nfunction anchorsForSide(market: Market, side: Side): readonly Anchor[] {\n const sided = market.leverage.maxMarketLeveragePerNotional;\n const per: MarketMaxLeveragePerNotional = side === \"yes\" ? sided.yes : sided.no;\n return [\n [ANCHORS_USD[0], per.at100UsdBps],\n [ANCHORS_USD[1], per.at500UsdBps],\n [ANCHORS_USD[2], per.at1000UsdBps],\n [ANCHORS_USD[3], per.at10000UsdBps],\n ];\n}\n\nfunction snapDownToStep(bps: number, stepBps: number, minBps: number): number {\n if (stepBps <= 0) {\n return Math.max(minBps, bps);\n }\n const k = Math.floor((bps - minBps) / stepBps);\n return Math.max(minBps, minBps + Math.max(0, k) * stepBps);\n}\n\nfunction interpolateRawBps(anchors: readonly Anchor[], notionalUsd: number): number {\n const first = anchors[0];\n const last = anchors[anchors.length - 1];\n if (!first || !last) {\n return 0;\n }\n if (notionalUsd <= first[0]) {\n return first[1];\n }\n if (notionalUsd >= last[0]) {\n return last[1];\n }\n for (let i = 1; i < anchors.length; i++) {\n const hi = anchors[i];\n const lo = anchors[i - 1];\n if (!hi || !lo) {\n continue;\n }\n if (notionalUsd <= hi[0]) {\n const t = (notionalUsd - lo[0]) / (hi[0] - lo[0]);\n return lo[1] + (hi[1] - lo[1]) * t;\n }\n }\n return last[1];\n}\n\n/**\n * Maximum leverage in basis points the API will allow at a given notional, per side.\n * Piecewise-linear interpolation across the four anchor points ($100/$500/$1k/$10k).\n * Below $100 uses the $100 cap; above $10k uses the $10k cap. Result is clamped to\n * the absolute side max and rounded down to `stepBps`.\n */\nexport function maxLeverageBpsAtNotional(market: Market, side: Side, notionalUsd: number): number {\n const sideAbsMax = leverageMaxBps(market.leverage, side);\n if (!Number.isFinite(notionalUsd) || notionalUsd <= 0) {\n return sideAbsMax;\n }\n const anchors = anchorsForSide(market, side);\n const raw = interpolateRawBps(anchors, notionalUsd);\n const clamped = Math.min(sideAbsMax, raw);\n return snapDownToStep(clamped, market.leverage.stepBps, market.leverage.minBps);\n}\n\n/**\n * Largest leverage (bps) the user can pick for a given collateral such that the\n * resulting notional still satisfies the per-notional cap.\n *\n * Walks down from the absolute side max in `stepBps` increments and returns the\n * first leverage `lev` where `lev <= maxLeverageBpsAtNotional(collateral * lev / 1)`.\n */\nexport function maxViableLeverageBpsForCollateral(market: Market, side: Side, collateralUsd: number): number {\n const sideAbsMax = leverageMaxBps(market.leverage, side);\n if (!Number.isFinite(collateralUsd) || collateralUsd <= 0) {\n return sideAbsMax;\n }\n\n const step = Math.max(market.leverage.stepBps, 1);\n const minBps = market.leverage.minBps;\n const maxSteps = Math.max(0, Math.floor((sideAbsMax - minBps) / step));\n\n for (let i = maxSteps; i >= 0; i--) {\n const lev = minBps + i * step;\n const notionalUsd = collateralUsd * (lev / BPS_PER_UNIT);\n if (lev <= maxLeverageBpsAtNotional(market, side, notionalUsd)) {\n return lev;\n }\n }\n return minBps;\n}\n","import type { Position, PositionEntry } from \"../types/aliases\";\n\nconst BPS_DIVISOR = 10_000;\n\n/**\n * One leverage-tiered origination-fee rate. `maxLeverageBps` is the inclusive\n * upper bound (in basis points) of leverage covered by this tier; `feeBps` is\n * the protocol origination fee charged for any leverage at or below that bound.\n * Tiers must be supplied in ascending `maxLeverageBps` order; the final tier\n * acts as the catch-all for the highest leverages.\n */\nexport interface OriginationFeeTier {\n maxLeverageBps: number;\n feeBps: number;\n}\n\n/**\n * Resolve the protocol origination fee rate (bps) for a given leverage from an\n * ordered list of leverage tiers. Returns the `feeBps` of the first tier whose\n * `maxLeverageBps >= leverageBps`. If no tier matches (leverage exceeds every\n * bound) the last tier is used as the catch-all. The caller fetches the tiers\n * from the `fee-rates` API; the math is pure.\n *\n * Note: this returns the PROTOCOL rate only — add `partnerOriginationFeeBps`\n * separately (see {@link resolveOriginationFeeBps}).\n */\nexport function resolveProtocolOriginationFeeBps(tiers: readonly OriginationFeeTier[], leverageBps: number): number {\n const lastTier = tiers[tiers.length - 1];\n if (!lastTier) {\n return 0;\n }\n for (const tier of tiers) {\n if (leverageBps <= tier.maxLeverageBps) {\n return tier.feeBps;\n }\n }\n return lastTier.feeBps;\n}\n\n/**\n * Combined origination fee rate (bps) = protocol tier rate + partner add-on.\n * Mirrors the server: the protocol rate is leverage-tiered, the partner rate is\n * a flat add-on supplied by the partner's `fee-rates` config.\n */\nexport function resolveOriginationFeeBps(\n tiers: readonly OriginationFeeTier[],\n leverageBps: number,\n partnerOriginationFeeBps: number,\n): number {\n return resolveProtocolOriginationFeeBps(tiers, leverageBps) + partnerOriginationFeeBps;\n}\n\n/**\n * Origination fee in USDC units (1_000_000 = $1), floored, matching the server:\n * `floor(notionalUsdcUnits * combinedOriginationFeeBps / 10_000)`.\n */\nexport function computeOriginationFeeUsdcUnits(notionalUsdcUnits: number, combinedOriginationFeeBps: number): number {\n return Math.floor((notionalUsdcUnits * combinedOriginationFeeBps) / BPS_DIVISOR);\n}\n\nexport interface OriginationFeeBreakdown {\n totalBps: number;\n totalUsd: number;\n protocolBps: number;\n protocolUsd: number;\n partnerBps: number;\n partnerUsd: number;\n}\n\nfunction getEntry(position: Position): PositionEntry {\n return position.entry;\n}\n\nexport function getOriginationFeeBreakdown(position: Position): OriginationFeeBreakdown {\n const entry = getEntry(position);\n const totalBps = entry.originationFeeBps;\n const totalUsd = Number(entry.originationFeeUsd) || 0;\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const protocolBps = entry.protocolOriginationFeeBps ?? totalBps;\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const partnerBps = entry.partnerOriginationFeeBps ?? 0;\n\n const share = totalBps > 0 ? protocolBps / totalBps : 1;\n const protocolUsd = totalUsd * share;\n const partnerUsd = totalUsd - protocolUsd;\n\n return {\n totalBps,\n totalUsd,\n protocolBps,\n protocolUsd,\n partnerBps,\n partnerUsd,\n };\n}\n","const BPS_DIVISOR = 10_000;\nconst USDC_UNITS_PER_USD = 1_000_000;\nconst TOKEN_UNITS_PER_TOKEN = 1_000_000;\n\n/**\n * Inputs to the Polymarket trading-fee curve. All rates are basis points; the\n * caller fetches `feeRateBps`, `feeExponent`, and `builderTakerFeeRateBps` from\n * the `fee-rates` API (snapshotted server-side as `Quote.polymarketFeeRateBps`\n * / `polymarketFeeExponent` / `polymarketBuilderFeeRateBps`).\n */\nexport interface PolymarketTradingFeeInput {\n notionalUsdcUnits: number;\n priceUsd: number;\n feeRateBps: number;\n feeExponent?: number;\n builderTakerFeeRateBps?: number;\n}\n\n/**\n * Polymarket open/close trading fee in USDC units (1_000_000 = $1).\n *\n * Matches the canonical formula (docs: position-math/09-exchange-trading-fees):\n *\n * ```\n * protocol = feeRateBps / 10_000 * C * (p * (1 - p)) ^ feeExponent * 1e6\n * builder = builderTakerFeeRateBps / 10_000 * notionalUsdc\n * fee = ceil(protocol + builder)\n * ```\n *\n * where `C` = contracts = notionalUsd / p, `p` = price in dollars (0..1). The\n * curvature term peaks at p = 0.5 and is symmetric; the flat builder term does\n * not shrink at price extremes. `feeExponent` defaults to 1 (standard quadratic\n * curvature); some markets use 0 (flat `feeRate * C`). `builderTakerFeeRateBps`\n * defaults to 0 (Bloom's own operator builder code is always 0-fee).\n */\nexport function computePolymarketTradingFee(input: PolymarketTradingFeeInput): number {\n const { notionalUsdcUnits, priceUsd, feeRateBps } = input;\n const feeExponent = input.feeExponent ?? 1;\n const builderTakerFeeRateBps = input.builderTakerFeeRateBps ?? 0;\n\n if (priceUsd <= 0) {\n return 0;\n }\n\n const notionalUsd = notionalUsdcUnits / USDC_UNITS_PER_USD;\n const contracts = notionalUsd / priceUsd;\n const curvature = (priceUsd * (1 - priceUsd)) ** feeExponent;\n\n const protocolFeeUsdcUnits = (feeRateBps / BPS_DIVISOR) * contracts * curvature * USDC_UNITS_PER_USD;\n const builderFeeUsdcUnits = (builderTakerFeeRateBps / BPS_DIVISOR) * notionalUsdcUnits;\n\n return Math.ceil(protocolFeeUsdcUnits + builderFeeUsdcUnits);\n}\n\n/**\n * Expected position size in token units (1_000_000 = 1 whole token) for a given\n * notional and entry price, optionally discounted by slippage. A token redeems\n * at $1 on a win, so token units are numerically equal to USDC units.\n *\n * `tokens = notionalUsd / entryPrice`, then scaled down by `slippageBps`.\n * Floored to whole token units. This is an at-quote estimate of the quote's\n * `minExpectedPositionTokenUnits`; the server is authoritative.\n */\nexport function expectedPositionTokenUnits(notionalUsdcUnits: number, entryPriceUsd: number, slippageBps = 0): number {\n if (entryPriceUsd <= 0) {\n return 0;\n }\n const notionalUsd = notionalUsdcUnits / USDC_UNITS_PER_USD;\n const tokens = notionalUsd / entryPriceUsd;\n const slippageFactor = (BPS_DIVISOR - slippageBps) / BPS_DIVISOR;\n return Math.floor(tokens * slippageFactor * TOKEN_UNITS_PER_TOKEN);\n}\n\n/**\n * Estimated base liquidation price (deterministic, at-entry closed form).\n *\n * **This is an estimate, not the server's TWAP solver result.** It computes the\n * at-entry base liquidation price (F = 0, no safety margin) per the docs\n * (position-math/04-liquidation):\n *\n * ```\n * P_liq_base = entryPrice * (L - 1) / L * (1 + liquidationFeeBps / 10_000)\n * ```\n *\n * where `L = leverageBps / 10_000`. At 1x leverage the borrowed capital is zero\n * so the liquidation price is zero. `entryPriceUsd` is in dollars; the result is\n * in the same units. The live server liquidation price drifts above this as the\n * lifetime fee `F` accrues and includes a safety margin.\n */\nexport function estimateLiquidationPrice(\n entryPriceUsd: number,\n leverageBps: number,\n liquidationFeeBps: number,\n): number {\n const leverage = leverageBps / BPS_DIVISOR;\n if (leverage <= 1) {\n return 0;\n }\n const loanPerToken = entryPriceUsd * ((leverage - 1) / leverage);\n return loanPerToken * (1 + liquidationFeeBps / BPS_DIVISOR);\n}\n\n/**\n * Inputs for {@link computeMaxGain}. All amounts are in USDC units\n * (1_000_000 = $1) except `positionTokenUnits` (token units, 1_000_000 = 1\n * token) which is numerically equal to its settlement USDC value.\n */\nexport interface MaxGainInput {\n positionTokenUnits: number;\n notionalUsdcUnits: number;\n expectedOpenTradingFeeUsdcUnits: number;\n originationFeeUsdcUnits: number;\n}\n\n/**\n * Result of {@link computeMaxGain}. All amounts in USDC units (1_000_000 = $1).\n * Gains are profit OVER principal (notional = loan + collateral) and may be\n * negative — they are signed and never clamped.\n */\nexport interface MaxGainResult {\n fullValueOnWinUsdcUnits: number;\n grossMaxGainUsdcUnits: number;\n netMaxGainUsdcUnits: number;\n}\n\n/**\n * Maximum gain (gross and net) for a winning settlement exit — profit over\n * principal. On a win each position token redeems at $1 (CTF settlement), so\n * the full value equals `positionTokenUnits` and there is NO exit trading fee.\n *\n * ```\n * fullValueOnWin = positionTokenUnits\n * grossMaxGain = fullValueOnWin - notionalUsdcUnits\n * netMaxGain = grossMaxGain - expectedOpenTradingFee - originationFee\n * ```\n *\n * Lifetime fees are excluded, so net max gain is an upper bound (a position held\n * to settlement accrues lifetime fees that reduce realized profit). Gains are\n * signed — a position whose principal exceeds its winning redemption value\n * yields a negative max gain.\n */\nexport function computeMaxGain(input: MaxGainInput): MaxGainResult {\n const fullValueOnWinUsdcUnits = input.positionTokenUnits;\n const grossMaxGainUsdcUnits = fullValueOnWinUsdcUnits - input.notionalUsdcUnits;\n const netMaxGainUsdcUnits =\n grossMaxGainUsdcUnits - input.expectedOpenTradingFeeUsdcUnits - input.originationFeeUsdcUnits;\n\n return {\n fullValueOnWinUsdcUnits,\n grossMaxGainUsdcUnits,\n netMaxGainUsdcUnits,\n };\n}\n","const BPS_DIVISOR = 10_000;\nconst BPS_DIVISOR_BIG = 10_000n;\n\nexport const tokenUnitsPerToken = 1_000_000n;\n\nexport const partialCloseMinTokens = 5n;\n\nexport const partialCloseMinFractionBps = 2_000n;\n\nexport function closeTokenUnitsForPct(currentTokenUnits: bigint, pctBps: number): bigint {\n const clampedBps = BigInt(Math.max(0, Math.min(BPS_DIVISOR, Math.round(pctBps))));\n\n return (currentTokenUnits * clampedBps) / BPS_DIVISOR_BIG;\n}\n\nexport function pctBpsForCloseTokenUnits(currentTokenUnits: bigint, closeTokenUnits: bigint): number {\n if (currentTokenUnits <= 0n) {\n return 0;\n }\n\n return Number((closeTokenUnits * BPS_DIVISOR_BIG) / currentTokenUnits);\n}\n\nexport function fallbackMinPartialCloseTokenUnits(originalTokenUnits: bigint): bigint {\n const floorTokens = partialCloseMinTokens * tokenUnitsPerToken;\n const floorFraction = (originalTokenUnits * partialCloseMinFractionBps) / BPS_DIVISOR_BIG;\n\n return floorFraction > floorTokens ? floorFraction : floorTokens;\n}\n\nexport function clampCloseTokenUnits(value: bigint, min: bigint, max: bigint): bigint {\n if (value < min) {\n return min;\n }\n\n if (value > max) {\n return max;\n }\n\n return value;\n}\n"],"mappings":"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","names":["BPS_DIVISOR","BPS_DIVISOR"]}
|
|
1
|
+
{"version":3,"sources":["../src/client/dimes-client.ts","../src/client/http.ts","../src/client/auth.ts","../src/types/aliases.ts","../src/utils/eligibility.ts","../src/utils/leverage.ts","../src/utils/fees.ts","../src/utils/max-gain.ts","../src/utils/partial-close.ts"],"sourcesContent":["import { decamelizeKeys } from \"humps\";\nimport type {\n ContractInfo,\n CreateQuoteParams,\n CustomerLimit,\n FeeRates,\n FeeReport,\n FeeReportParams,\n Market,\n Paginated,\n Position,\n PositionPartialCloseList,\n PositionTransactions,\n Quote,\n} from \"../types\";\nimport type { AuthProvider } from \"./auth\";\nimport { HttpClient } from \"./http\";\n\nexport interface DimesClientOptions {\n baseUrl?: string;\n auth: AuthProvider;\n fetch?: typeof globalThis.fetch;\n maxRetries?: number;\n maxRetryDelayMs?: number;\n}\n\nexport type MarketSort = \"ticker_asc\" | \"depth_desc\" | \"discovered_at_desc\";\n\nexport type MarketExpand = \"total_count\" | \"prices\";\n\nexport type PositionStatus = \"open\" | \"unwinding\" | \"pending\" | \"closing\" | \"closed\" | \"settled\" | \"liquidated\";\n\nexport interface GetMarketsParams {\n limit?: number;\n startingAfter?: string;\n endingBefore?: string;\n expand?: MarketExpand[];\n sort?: MarketSort;\n acceptingNewPositions?: boolean;\n category?: string;\n status?: string;\n provider?: \"polymarket\" | \"kalshi\";\n /** Free-text search across market tickers and titles. */\n query?: string;\n}\n\n/** @deprecated Use {@link GetMarketsParams} with `query` and {@link DimesClient.getMarkets}. */\nexport interface SearchMarketsParams extends GetMarketsParams {\n query: string;\n}\n\nexport interface GetPositionsParams {\n limit?: number;\n startingAfter?: string;\n endingBefore?: string;\n expand?: string[];\n sortBy?: \"created_at\" | \"closed_at\";\n sortDirection?: \"asc\" | \"desc\";\n status?: PositionStatus;\n state?: \"active\" | \"inactive\";\n}\n\nexport interface GetFeeRatesParams {\n ticker?: string;\n}\n\nfunction buildQueryFromEntries(entries: [string, unknown][]): string {\n const filtered = entries.filter(([, v]) => v !== undefined && v !== null);\n if (filtered.length === 0) {\n return \"\";\n }\n\n const search = new URLSearchParams();\n for (const [key, value] of filtered) {\n search.set(\n key.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`),\n String(value),\n );\n }\n\n return `?${search.toString()}`;\n}\n\nexport class DimesClient {\n /** The resolved API base URL. Useful for constructing WebSocket clients against the same host. */\n public readonly baseUrl: string;\n\n private readonly http: HttpClient;\n\n private readonly auth: AuthProvider;\n\n constructor(options: DimesClientOptions) {\n this.baseUrl = options.baseUrl ?? \"https://api.dimes.fi\";\n this.auth = options.auth;\n this.http = new HttpClient({\n baseUrl: this.baseUrl,\n auth: options.auth,\n fetch: options.fetch,\n maxRetries: options.maxRetries,\n maxRetryDelayMs: options.maxRetryDelayMs,\n });\n }\n\n /** Synchronously return the current cached JWT, or null. Returns null if the auth provider does not expose one. */\n public getToken(): string | null {\n return this.auth.getToken?.() ?? null;\n }\n\n public async getMarkets(params?: GetMarketsParams): Promise<Paginated<Market>> {\n const query = params ? buildQueryFromEntries(Object.entries(params)) : \"\";\n return this.http.request<Paginated<Market>>(`/v1/prediction-markets/markets${query}`);\n }\n\n public async getMarket(ticker: string): Promise<Market> {\n return this.http.request<Market>(`/v1/prediction-markets/markets/${encodeURIComponent(ticker)}`);\n }\n\n /**\n * @deprecated The `/markets/search` path is deprecated. Use {@link getMarkets} with a `query` param:\n * `getMarkets({ query: \"bitcoin\" })`.\n */\n // eslint-disable-next-line @typescript-eslint/no-deprecated -- this IS the deprecated method\n public async searchMarkets(params: SearchMarketsParams): Promise<Paginated<Market>> {\n return this.getMarkets(params);\n }\n\n public async createDraftQuote(params: CreateQuoteParams): Promise<Quote> {\n return this.http.request<Quote>(\"/v1/prediction-markets/draft-quotes\", {\n method: \"POST\",\n body: JSON.stringify(decamelizeKeys(params)),\n });\n }\n\n public async promoteDraftQuote(draftId: string): Promise<Quote> {\n return this.http.request<Quote>(`/v1/prediction-markets/promoted-quotes/${encodeURIComponent(draftId)}`, {\n method: \"POST\",\n });\n }\n\n public async createQuote(params: CreateQuoteParams): Promise<Quote> {\n return this.http.request<Quote>(\"/v1/prediction-markets/quotes\", {\n method: \"POST\",\n body: JSON.stringify(decamelizeKeys(params)),\n });\n }\n\n public async getPositions(params?: GetPositionsParams): Promise<Position[]> {\n const query = params ? buildQueryFromEntries(Object.entries(params)) : \"\";\n return this.http.requestList<Position>(`/v1/prediction-markets/positions${query}`);\n }\n\n public async getPositionTransactions(positionId: string): Promise<PositionTransactions> {\n return this.http.request<PositionTransactions>(\n `/v1/prediction-markets/positions/${encodeURIComponent(positionId)}/transactions`,\n );\n }\n\n public async getPositionPartialCloses(positionId: string): Promise<PositionPartialCloseList> {\n return this.http.request<PositionPartialCloseList>(\n `/v1/prediction-markets/positions/${encodeURIComponent(positionId)}/partial-closes`,\n );\n }\n\n public async cancelPosition(positionId: string): Promise<void> {\n await this.http.request<unknown>(`/v1/prediction-markets/positions/${encodeURIComponent(positionId)}`, {\n method: \"DELETE\",\n });\n }\n\n public async getContractInfo(): Promise<ContractInfo> {\n return this.http.request<ContractInfo>(\"/v1/prediction-markets/contract-info\");\n }\n\n public async getUserLimits(): Promise<CustomerLimit> {\n return this.http.request<CustomerLimit>(\"/v1/prediction-markets/user-limits\");\n }\n\n public async getPartnerLimits(): Promise<CustomerLimit> {\n return this.http.request<CustomerLimit>(\"/v1/prediction-markets/partner-limits\");\n }\n\n /**\n * @deprecated The `/limits` path was never served by the API. Use {@link getUserLimits}\n * (JWT/user context) or {@link getPartnerLimits} (API-key/partner context). This alias\n * forwards to `getUserLimits` and will be removed in a future major.\n */\n public async getLimits(): Promise<CustomerLimit> {\n return this.getUserLimits();\n }\n\n public async getFeeRates(params?: GetFeeRatesParams): Promise<FeeRates> {\n const query = params ? buildQueryFromEntries(Object.entries(params)) : \"\";\n return this.http.request<FeeRates>(`/v1/prediction-markets/fee-rates${query}`);\n }\n\n public async getFeeReport(params: FeeReportParams): Promise<FeeReport> {\n return this.http.request<FeeReport>(\"/v1/prediction-markets/fee-reports\", {\n method: \"POST\",\n body: JSON.stringify(decamelizeKeys(params)),\n });\n }\n}\n","import { camelizeKeys, type Camelized } from \"humps\";\nimport { DimesApiError } from \"../errors/dimes-error\";\nimport type { AuthProvider } from \"./auth\";\n\nexport type { Camelized };\n\ninterface ApiErrorBody {\n error?: {\n type?: string;\n code?: string;\n message: string;\n params?: Record<string, unknown>;\n };\n}\n\nconst HTTP_UNAUTHORIZED = 401;\nconst HTTP_TOO_MANY_REQUESTS = 429;\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_MAX_RETRY_DELAY_MS = 60_000;\nconst DEFAULT_RETRY_DELAY_MS = 1000;\nconst BACKOFF_FACTOR = 2;\nconst MS_PER_SECOND = 1000;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction parseRetryAfterMs(header: string | null, attempt: number): number {\n const fallbackMs = DEFAULT_RETRY_DELAY_MS * BACKOFF_FACTOR ** attempt;\n if (!header) {\n return fallbackMs;\n }\n\n const seconds = Number(header);\n if (!Number.isNaN(seconds) && seconds >= 0) {\n return seconds * MS_PER_SECOND;\n }\n\n const dateMs = Date.parse(header);\n if (!Number.isNaN(dateMs)) {\n return Math.max(0, dateMs - Date.now());\n }\n\n return fallbackMs;\n}\n\n// eslint-disable-next-line complexity\nasync function throwFromResponse(response: Response): Promise<never> {\n const rawBody = await response.text();\n let parsed: ApiErrorBody | null;\n try {\n parsed = rawBody ? (JSON.parse(rawBody) as ApiErrorBody) : null;\n } catch {\n parsed = null;\n }\n\n const code = parsed?.error?.code ?? \"unknown_error\";\n const type = parsed?.error?.type ?? null;\n const message = parsed?.error?.message ?? `API error ${response.status}`;\n const rawParams = parsed?.error?.params;\n const params = rawParams ? (camelizeKeys(rawParams) as Record<string, unknown>) : null;\n\n throw new DimesApiError({ status: response.status, code, type, message, params });\n}\n\nexport interface HttpClientOptions {\n baseUrl: string;\n auth: AuthProvider;\n fetch?: typeof globalThis.fetch;\n maxRetries?: number;\n maxRetryDelayMs?: number;\n}\n\nexport class HttpClient {\n private readonly baseUrl: string;\n\n private readonly auth: AuthProvider;\n\n private readonly fetchFn: typeof globalThis.fetch;\n\n private readonly maxRetries: number;\n\n private readonly maxRetryDelayMs: number;\n\n constructor(options: HttpClientOptions) {\n this.baseUrl = options.baseUrl;\n this.auth = options.auth;\n this.fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);\n this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;\n this.maxRetryDelayMs = options.maxRetryDelayMs ?? DEFAULT_MAX_RETRY_DELAY_MS;\n }\n\n public async request<T>(path: string, options?: RequestInit): Promise<T> {\n const authHeaders = await this.auth.getHeaders();\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...authHeaders,\n ...(options?.headers as Record<string, string> | undefined),\n };\n\n let response = await this.fetchFn(`${this.baseUrl}${path}`, {\n ...options,\n headers,\n });\n\n if (response.status === HTTP_UNAUTHORIZED && this.auth.refresh) {\n await this.auth.refresh();\n const retryHeaders = await this.auth.getHeaders();\n response = await this.fetchFn(`${this.baseUrl}${path}`, {\n ...options,\n headers: { ...headers, ...retryHeaders },\n });\n }\n\n for (let attempt = 0; response.status === HTTP_TOO_MANY_REQUESTS && attempt < this.maxRetries; attempt++) {\n const delayMs = parseRetryAfterMs(response.headers.get(\"retry-after\"), attempt);\n if (delayMs > this.maxRetryDelayMs) {\n break;\n }\n await sleep(delayMs);\n const freshAuth = await this.auth.getHeaders();\n response = await this.fetchFn(`${this.baseUrl}${path}`, {\n ...options,\n headers: { ...headers, ...freshAuth },\n });\n }\n\n if (!response.ok) {\n await throwFromResponse(response);\n }\n\n return camelizeKeys(await response.json()) as T;\n }\n\n public async requestList<T>(path: string, options?: RequestInit): Promise<T[]> {\n const result = await this.request<{ data: T[] }>(path, options);\n return result.data;\n }\n}\n","import { DimesError } from \"../errors/dimes-error\";\n\nexport interface AuthProvider {\n getHeaders(): Promise<Record<string, string>>;\n refresh?(): Promise<void>;\n /** Synchronously return the current cached JWT, or null if not yet obtained. Used by the WebSocket clients. */\n getToken?(): string | null;\n}\n\ninterface TokenResponse {\n token: string;\n expires_at: string;\n}\n\nexport interface ApiKeyAuthOptions {\n apiKey: string;\n walletAddress: string;\n baseUrl?: string;\n fetch?: typeof globalThis.fetch;\n}\n\nexport class ApiKeyAuth implements AuthProvider {\n private jwt: string | null = null;\n\n private expiresAt = 0;\n\n private refreshPromise: Promise<void> | null = null;\n\n private readonly apiKey: string;\n\n private readonly walletAddress: string;\n\n private readonly baseUrl: string;\n\n private readonly fetchFn: typeof globalThis.fetch;\n\n constructor(options: ApiKeyAuthOptions) {\n this.apiKey = options.apiKey;\n this.walletAddress = options.walletAddress;\n this.baseUrl = options.baseUrl ?? \"https://api.dimes.fi\";\n this.fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n public async getHeaders(): Promise<Record<string, string>> {\n const TOKEN_EXPIRY_BUFFER_MS = 30_000;\n if (!this.jwt || Date.now() >= this.expiresAt - TOKEN_EXPIRY_BUFFER_MS) {\n await this.refresh();\n }\n return { Authorization: `Bearer ${this.jwt}` };\n }\n\n public getToken(): string | null {\n return this.jwt;\n }\n\n public async refresh(): Promise<void> {\n if (this.refreshPromise) {\n await this.refreshPromise;\n return;\n }\n\n this.refreshPromise = this.fetchToken();\n try {\n await this.refreshPromise;\n } finally {\n this.refreshPromise = null;\n }\n }\n\n private async fetchToken(): Promise<void> {\n const response = await this.fetchFn(`${this.baseUrl}/v1/prediction-markets/tokens`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Api-Key ${this.apiKey}`,\n },\n body: JSON.stringify({ wallet_address: this.walletAddress }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new DimesError(\"auth_token_failed\", `Failed to obtain auth token (${response.status}): ${text}`);\n }\n\n const data = (await response.json()) as TokenResponse;\n this.jwt = data.token;\n this.expiresAt = new Date(data.expires_at).getTime();\n }\n}\n\nexport interface JwtAuthOptions {\n tokenUrl: string;\n fetch?: typeof globalThis.fetch;\n}\n\nexport class JwtAuth implements AuthProvider {\n private readonly fetchFn: typeof globalThis.fetch;\n\n private readonly tokenUrl: string;\n\n private jwt: string | null = null;\n\n private expiresAt = 0;\n\n private refreshPromise: Promise<void> | null = null;\n\n constructor(options: JwtAuthOptions) {\n this.tokenUrl = options.tokenUrl;\n this.fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n public async getHeaders(): Promise<Record<string, string>> {\n const TOKEN_EXPIRY_BUFFER_MS = 30_000;\n if (!this.jwt || Date.now() >= this.expiresAt - TOKEN_EXPIRY_BUFFER_MS) {\n await this.refresh();\n }\n return { Authorization: `Bearer ${this.jwt}` };\n }\n\n public getToken(): string | null {\n return this.jwt;\n }\n\n public async refresh(): Promise<void> {\n if (this.refreshPromise) {\n await this.refreshPromise;\n return;\n }\n\n this.refreshPromise = this.fetchToken();\n try {\n await this.refreshPromise;\n } finally {\n this.refreshPromise = null;\n }\n }\n\n private async fetchToken(): Promise<void> {\n const response = await this.fetchFn(this.tokenUrl);\n\n if (!response.ok) {\n const text = await response.text();\n throw new DimesError(\n \"auth_token_failed\",\n `Failed to fetch token from ${this.tokenUrl} (${response.status}): ${text}`,\n );\n }\n\n const data = (await response.json()) as TokenResponse;\n this.jwt = data.token;\n this.expiresAt = new Date(data.expires_at).getTime();\n }\n}\n","import type { CamelizeKeys } from \"./camelize\";\nimport type { components } from \"./generated\";\n\ntype Raw = components[\"schemas\"];\n\nexport type Market = CamelizeKeys<Raw[\"CustomerMarket\"]>;\n\nexport type MarketLeverage = CamelizeKeys<Raw[\"CustomerLeverage\"]>;\n\nexport type MarketMaxLeveragePerNotional = CamelizeKeys<Raw[\"CustomerMaxMarketLeveragePerNotional\"]>;\n\nexport type MarketSidedMaxLeveragePerNotional = CamelizeKeys<Raw[\"CustomerSidedMaxMarketLeveragePerNotional\"]>;\n\nexport type MarketSidedEligibility = CamelizeKeys<Raw[\"CustomerSidedEligibility\"]>;\n\nexport type MarketFees = CamelizeKeys<Raw[\"CustomerFees\"]>;\n\nexport type MarketPrices = CamelizeKeys<Raw[\"CustomerMarketPrices\"]>;\n\nexport interface MarketPolymarket {\n conditionId: string | null;\n noTokenId: string;\n slug: string;\n yesTokenId: string;\n}\n\nexport type OriginationTier = CamelizeKeys<Raw[\"CustomerOriginationTier\"]>;\n\nexport type Quote = CamelizeKeys<Raw[\"CustomerOffer\"]>;\n\n/** @deprecated Use {@link Quote}. Back-compat alias; removed in a future major. */\n// eslint-disable-next-line no-restricted-syntax -- intentional deprecated alias\nexport type Offer = Quote;\n\nexport type OpenPosition = CamelizeKeys<Raw[\"CustomerOpenPosition\"]>;\n\nexport type ClosedPosition = CamelizeKeys<Raw[\"CustomerClosedPosition\"]>;\n\nexport type Position = OpenPosition | ClosedPosition;\n\nexport type PositionEntry = CamelizeKeys<Raw[\"CustomerPositionEntry\"]>;\n\nexport type PositionCurrent = CamelizeKeys<Raw[\"CustomerPositionCurrent\"]>;\n\nexport type PositionRisk = CamelizeKeys<Raw[\"CustomerPositionRisk\"]>;\n\nexport type PositionOpenFees = CamelizeKeys<Raw[\"CustomerPositionOpenFees\"]>;\n\nexport type PositionClosedFees = CamelizeKeys<Raw[\"CustomerPositionClosedFees\"]>;\n\nexport type PositionResult = CamelizeKeys<Raw[\"CustomerPositionResult\"]>;\n\nexport type PositionTiming = CamelizeKeys<Raw[\"CustomerPositionTiming\"]>;\n\nexport type PositionFailure = CamelizeKeys<Raw[\"CustomerPositionFailure\"]>;\n\nexport type CloseAttempt = CamelizeKeys<Raw[\"CustomerCloseAttempt\"]>;\n\nexport type PendingOperation = CamelizeKeys<Raw[\"CustomerPendingOperation\"]>;\n\nexport type PositionUnwind = CamelizeKeys<Raw[\"CustomerPositionUnwind\"]>;\n\nexport type PositionUnwindList = CamelizeKeys<Raw[\"CustomerPositionUnwindList\"]>;\n\nexport type PositionPartialClose = CamelizeKeys<Raw[\"CustomerPartialClose\"]>;\n\nexport type PositionPartialCloseList = CamelizeKeys<Raw[\"CustomerPartialCloseList\"]>;\n\nexport type PositionTransactionEntry = CamelizeKeys<Raw[\"PositionTransactionEntry\"]>;\n\nexport type PositionTransactionGroup = CamelizeKeys<Raw[\"PositionTransactionGroup\"]>;\n\nexport type PositionTransactions = CamelizeKeys<Raw[\"PositionTransactions\"]>;\n\nexport type ContractInfo = CamelizeKeys<Raw[\"CustomerContractInfo\"]>;\n\nexport type CustomerLimit = CamelizeKeys<Raw[\"CustomerLimit\"]>;\n\nexport type CreateTokenResult = CamelizeKeys<Raw[\"CreateTokenResult\"]>;\n\nexport type FeeRatesOriginationTier = CamelizeKeys<Raw[\"CustomerOriginationFeeTier\"]>;\n\nexport type FeeRatesMarket = CamelizeKeys<Raw[\"CustomerFeeRatesMarket\"]>;\n\nexport type FeeRates = CamelizeKeys<Raw[\"CustomerFeeRates\"]>;\n\nexport type FeeReport = CamelizeKeys<Raw[\"CustomerFeeReport\"]>;\n\nexport interface CreateQuoteParams {\n marketTicker: string;\n effectiveSide: \"yes\" | \"no\";\n leverageBps: number;\n notionalAmountUsdPips: string;\n slippageBps: number;\n pmProvider?: \"polymarket\" | \"kalshi\";\n allowPartialFill?: boolean;\n minFillBps?: number;\n}\n\n/** @deprecated Renamed to {@link CreateQuoteParams}. Kept as an alias for backward compatibility. */\n// eslint-disable-next-line no-restricted-syntax -- intentional deprecated alias\nexport type CreateOfferParams = CreateQuoteParams;\n\nexport interface FeeReportParams {\n marketTicker: string;\n effectiveSide: \"yes\" | \"no\";\n leverageBps: number;\n notionalAmountUsdPips: string;\n entryPriceUsdPips?: string;\n}\n\nexport function isOpenPosition(p: Position): p is OpenPosition {\n return \"current\" in p;\n}\n\nexport function isClosedPosition(p: Position): p is ClosedPosition {\n return \"result\" in p;\n}\n\nexport function leverageMaxBps(lev: MarketLeverage, side: \"yes\" | \"no\"): number {\n const perSide = side === \"yes\" ? lev.maxYesBps : lev.maxNoBps;\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return perSide ?? lev.maxBps ?? lev.minBps;\n}\n","import type { Market } from \"../types/aliases\";\n\nexport type Side = \"yes\" | \"no\";\n\nexport interface SideEligibility {\n open: boolean;\n reasonCode: string | null;\n}\n\nexport interface SidedEligibility {\n yes: SideEligibility;\n no: SideEligibility;\n}\n\nexport function getSidedEligibility(market: Market): SidedEligibility {\n const sided = market.sidedEligibility;\n return {\n yes: {\n open: sided.yes.acceptingNewPositions,\n reasonCode: sided.yes.rejectionReasonCode ?? null,\n },\n no: {\n open: sided.no.acceptingNewPositions,\n reasonCode: sided.no.rejectionReasonCode ?? null,\n },\n };\n}\n\nexport function defaultSide(eligibility: SidedEligibility): Side | null {\n if (eligibility.yes.open && eligibility.no.open) {\n return \"yes\";\n }\n if (eligibility.yes.open) {\n return \"yes\";\n }\n if (eligibility.no.open) {\n return \"no\";\n }\n return null;\n}\n\nexport function isFullyOpen(eligibility: SidedEligibility): boolean {\n return eligibility.yes.open && eligibility.no.open;\n}\n\nexport function isFullyClosed(eligibility: SidedEligibility): boolean {\n return !eligibility.yes.open && !eligibility.no.open;\n}\n\nexport function rejectionReasonText(code: string | null | undefined): string {\n if (!code) {\n return \"Not eligible for new positions\";\n }\n const stripped = code\n .replace(/^quote_/i, \"\")\n .replaceAll(\"_\", \" \")\n .toLowerCase();\n return stripped.charAt(0).toUpperCase() + stripped.slice(1);\n}\n\nexport function rejectionReasonShort(code: string | null | undefined): string {\n if (!code) {\n return \"unavailable\";\n }\n const stripped = code\n .replace(/^quote_/i, \"\")\n .replace(/_exceeded$/i, \"\")\n .replace(/_too_(low|high)$/i, \"\")\n .replaceAll(\"_\", \" \")\n .toLowerCase();\n return stripped;\n}\n","import { type Market, type MarketMaxLeveragePerNotional, leverageMaxBps } from \"../types/aliases\";\nimport type { Side } from \"./eligibility\";\n\nconst USD_100 = 100;\nconst USD_500 = 500;\nconst USD_1K = 1_000;\nconst USD_10K = 10_000;\nconst BPS_PER_UNIT = 10_000;\n\nconst ANCHORS_USD = [USD_100, USD_500, USD_1K, USD_10K] as const;\n\ntype Anchor = readonly [usd: number, bps: number];\n\nfunction anchorsForSide(market: Market, side: Side): readonly Anchor[] {\n const sided = market.leverage.maxMarketLeveragePerNotional;\n const per: MarketMaxLeveragePerNotional = side === \"yes\" ? sided.yes : sided.no;\n return [\n [ANCHORS_USD[0], per.at100UsdBps],\n [ANCHORS_USD[1], per.at500UsdBps],\n [ANCHORS_USD[2], per.at1000UsdBps],\n [ANCHORS_USD[3], per.at10000UsdBps],\n ];\n}\n\nfunction snapDownToStep(bps: number, stepBps: number, minBps: number): number {\n if (stepBps <= 0) {\n return Math.max(minBps, bps);\n }\n const k = Math.floor((bps - minBps) / stepBps);\n return Math.max(minBps, minBps + Math.max(0, k) * stepBps);\n}\n\nfunction interpolateRawBps(anchors: readonly Anchor[], notionalUsd: number): number {\n const first = anchors[0];\n const last = anchors[anchors.length - 1];\n if (!first || !last) {\n return 0;\n }\n if (notionalUsd <= first[0]) {\n return first[1];\n }\n if (notionalUsd >= last[0]) {\n return last[1];\n }\n for (let i = 1; i < anchors.length; i++) {\n const hi = anchors[i];\n const lo = anchors[i - 1];\n if (!hi || !lo) {\n continue;\n }\n if (notionalUsd <= hi[0]) {\n const t = (notionalUsd - lo[0]) / (hi[0] - lo[0]);\n return lo[1] + (hi[1] - lo[1]) * t;\n }\n }\n return last[1];\n}\n\n/**\n * Maximum leverage in basis points the API will allow at a given notional, per side.\n * Piecewise-linear interpolation across the four anchor points ($100/$500/$1k/$10k).\n * Below $100 uses the $100 cap; above $10k uses the $10k cap. Result is clamped to\n * the absolute side max and rounded down to `stepBps`.\n */\nexport function maxLeverageBpsAtNotional(market: Market, side: Side, notionalUsd: number): number {\n const sideAbsMax = leverageMaxBps(market.leverage, side);\n if (!Number.isFinite(notionalUsd) || notionalUsd <= 0) {\n return sideAbsMax;\n }\n const anchors = anchorsForSide(market, side);\n const raw = interpolateRawBps(anchors, notionalUsd);\n const clamped = Math.min(sideAbsMax, raw);\n return snapDownToStep(clamped, market.leverage.stepBps, market.leverage.minBps);\n}\n\n/**\n * Largest leverage (bps) the user can pick for a given collateral such that the\n * resulting notional still satisfies the per-notional cap.\n *\n * Walks down from the absolute side max in `stepBps` increments and returns the\n * first leverage `lev` where `lev <= maxLeverageBpsAtNotional(collateral * lev / 1)`.\n */\nexport function maxViableLeverageBpsForCollateral(market: Market, side: Side, collateralUsd: number): number {\n const sideAbsMax = leverageMaxBps(market.leverage, side);\n if (!Number.isFinite(collateralUsd) || collateralUsd <= 0) {\n return sideAbsMax;\n }\n\n const step = Math.max(market.leverage.stepBps, 1);\n const minBps = market.leverage.minBps;\n const maxSteps = Math.max(0, Math.floor((sideAbsMax - minBps) / step));\n\n for (let i = maxSteps; i >= 0; i--) {\n const lev = minBps + i * step;\n const notionalUsd = collateralUsd * (lev / BPS_PER_UNIT);\n if (lev <= maxLeverageBpsAtNotional(market, side, notionalUsd)) {\n return lev;\n }\n }\n return minBps;\n}\n","import type { Position, PositionEntry } from \"../types/aliases\";\n\nconst BPS_DIVISOR = 10_000;\n\n/**\n * One leverage-tiered origination-fee rate. `maxLeverageBps` is the inclusive\n * upper bound (in basis points) of leverage covered by this tier; `feeBps` is\n * the protocol origination fee charged for any leverage at or below that bound.\n * Tiers must be supplied in ascending `maxLeverageBps` order; the final tier\n * acts as the catch-all for the highest leverages.\n */\nexport interface OriginationFeeTier {\n maxLeverageBps: number;\n feeBps: number;\n}\n\n/**\n * Resolve the protocol origination fee rate (bps) for a given leverage from an\n * ordered list of leverage tiers. Returns the `feeBps` of the first tier whose\n * `maxLeverageBps >= leverageBps`. If no tier matches (leverage exceeds every\n * bound) the last tier is used as the catch-all. The caller fetches the tiers\n * from the `fee-rates` API; the math is pure.\n *\n * Note: this returns the PROTOCOL rate only — add `partnerOriginationFeeBps`\n * separately (see {@link resolveOriginationFeeBps}).\n */\nexport function resolveProtocolOriginationFeeBps(tiers: readonly OriginationFeeTier[], leverageBps: number): number {\n const lastTier = tiers[tiers.length - 1];\n if (!lastTier) {\n return 0;\n }\n for (const tier of tiers) {\n if (leverageBps <= tier.maxLeverageBps) {\n return tier.feeBps;\n }\n }\n return lastTier.feeBps;\n}\n\n/**\n * Combined origination fee rate (bps) = protocol tier rate + partner add-on.\n * Mirrors the server: the protocol rate is leverage-tiered, the partner rate is\n * a flat add-on supplied by the partner's `fee-rates` config.\n */\nexport function resolveOriginationFeeBps(\n tiers: readonly OriginationFeeTier[],\n leverageBps: number,\n partnerOriginationFeeBps: number,\n): number {\n return resolveProtocolOriginationFeeBps(tiers, leverageBps) + partnerOriginationFeeBps;\n}\n\n/**\n * Origination fee in USDC units (1_000_000 = $1), floored, matching the server:\n * `floor(notionalUsdcUnits * combinedOriginationFeeBps / 10_000)`.\n */\nexport function computeOriginationFeeUsdcUnits(notionalUsdcUnits: number, combinedOriginationFeeBps: number): number {\n return Math.floor((notionalUsdcUnits * combinedOriginationFeeBps) / BPS_DIVISOR);\n}\n\nexport interface OriginationFeeBreakdown {\n totalBps: number;\n totalUsd: number;\n protocolBps: number;\n protocolUsd: number;\n partnerBps: number;\n partnerUsd: number;\n}\n\nfunction getEntry(position: Position): PositionEntry {\n return position.entry;\n}\n\nexport function getOriginationFeeBreakdown(position: Position): OriginationFeeBreakdown {\n const entry = getEntry(position);\n const totalBps = entry.originationFeeBps;\n const totalUsd = Number(entry.originationFeeUsd) || 0;\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const protocolBps = entry.protocolOriginationFeeBps ?? totalBps;\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const partnerBps = entry.partnerOriginationFeeBps ?? 0;\n\n const share = totalBps > 0 ? protocolBps / totalBps : 1;\n const protocolUsd = totalUsd * share;\n const partnerUsd = totalUsd - protocolUsd;\n\n return {\n totalBps,\n totalUsd,\n protocolBps,\n protocolUsd,\n partnerBps,\n partnerUsd,\n };\n}\n","const BPS_DIVISOR = 10_000;\nconst USDC_UNITS_PER_USD = 1_000_000;\nconst TOKEN_UNITS_PER_TOKEN = 1_000_000;\n\n/**\n * Inputs to the Polymarket trading-fee curve. All rates are basis points; the\n * caller fetches `feeRateBps`, `feeExponent`, and `builderTakerFeeRateBps` from\n * the `fee-rates` API (snapshotted server-side as `Quote.polymarketFeeRateBps`\n * / `polymarketFeeExponent` / `polymarketBuilderFeeRateBps`).\n */\nexport interface PolymarketTradingFeeInput {\n notionalUsdcUnits: number;\n priceUsd: number;\n feeRateBps: number;\n feeExponent?: number;\n builderTakerFeeRateBps?: number;\n}\n\n/**\n * Polymarket open/close trading fee in USDC units (1_000_000 = $1).\n *\n * Matches the canonical formula (docs: position-math/09-exchange-trading-fees):\n *\n * ```\n * protocol = feeRateBps / 10_000 * C * (p * (1 - p)) ^ feeExponent * 1e6\n * builder = builderTakerFeeRateBps / 10_000 * notionalUsdc\n * fee = ceil(protocol + builder)\n * ```\n *\n * where `C` = contracts = notionalUsd / p, `p` = price in dollars (0..1). The\n * curvature term peaks at p = 0.5 and is symmetric; the flat builder term does\n * not shrink at price extremes. `feeExponent` defaults to 1 (standard quadratic\n * curvature); some markets use 0 (flat `feeRate * C`). `builderTakerFeeRateBps`\n * defaults to 0 (Bloom's own operator builder code is always 0-fee).\n */\nexport function computePolymarketTradingFee(input: PolymarketTradingFeeInput): number {\n const { notionalUsdcUnits, priceUsd, feeRateBps } = input;\n const feeExponent = input.feeExponent ?? 1;\n const builderTakerFeeRateBps = input.builderTakerFeeRateBps ?? 0;\n\n if (priceUsd <= 0) {\n return 0;\n }\n\n const notionalUsd = notionalUsdcUnits / USDC_UNITS_PER_USD;\n const contracts = notionalUsd / priceUsd;\n const curvature = (priceUsd * (1 - priceUsd)) ** feeExponent;\n\n const protocolFeeUsdcUnits = (feeRateBps / BPS_DIVISOR) * contracts * curvature * USDC_UNITS_PER_USD;\n const builderFeeUsdcUnits = (builderTakerFeeRateBps / BPS_DIVISOR) * notionalUsdcUnits;\n\n return Math.ceil(protocolFeeUsdcUnits + builderFeeUsdcUnits);\n}\n\n/**\n * Expected position size in token units (1_000_000 = 1 whole token) for a given\n * notional and entry price, optionally discounted by slippage. A token redeems\n * at $1 on a win, so token units are numerically equal to USDC units.\n *\n * `tokens = notionalUsd / entryPrice`, then scaled down by `slippageBps`.\n * Floored to whole token units. This is an at-quote estimate of the quote's\n * `minExpectedPositionTokenUnits`; the server is authoritative.\n */\nexport function expectedPositionTokenUnits(notionalUsdcUnits: number, entryPriceUsd: number, slippageBps = 0): number {\n if (entryPriceUsd <= 0) {\n return 0;\n }\n const notionalUsd = notionalUsdcUnits / USDC_UNITS_PER_USD;\n const tokens = notionalUsd / entryPriceUsd;\n const slippageFactor = (BPS_DIVISOR - slippageBps) / BPS_DIVISOR;\n return Math.floor(tokens * slippageFactor * TOKEN_UNITS_PER_TOKEN);\n}\n\n/**\n * Estimated base liquidation price (deterministic, at-entry closed form).\n *\n * **This is an estimate, not the server's TWAP solver result.** It computes the\n * at-entry base liquidation price (F = 0, no safety margin) per the docs\n * (position-math/04-liquidation):\n *\n * ```\n * P_liq_base = entryPrice * (L - 1) / L * (1 + liquidationFeeBps / 10_000)\n * ```\n *\n * where `L = leverageBps / 10_000`. At 1x leverage the borrowed capital is zero\n * so the liquidation price is zero. `entryPriceUsd` is in dollars; the result is\n * in the same units. The live server liquidation price drifts above this as the\n * lifetime fee `F` accrues and includes a safety margin.\n */\nexport function estimateLiquidationPrice(\n entryPriceUsd: number,\n leverageBps: number,\n liquidationFeeBps: number,\n): number {\n const leverage = leverageBps / BPS_DIVISOR;\n if (leverage <= 1) {\n return 0;\n }\n const loanPerToken = entryPriceUsd * ((leverage - 1) / leverage);\n return loanPerToken * (1 + liquidationFeeBps / BPS_DIVISOR);\n}\n\n/**\n * Inputs for {@link computeMaxGain}. All amounts are in USDC units\n * (1_000_000 = $1) except `positionTokenUnits` (token units, 1_000_000 = 1\n * token) which is numerically equal to its settlement USDC value.\n */\nexport interface MaxGainInput {\n positionTokenUnits: number;\n notionalUsdcUnits: number;\n expectedOpenTradingFeeUsdcUnits: number;\n originationFeeUsdcUnits: number;\n}\n\n/**\n * Result of {@link computeMaxGain}. All amounts in USDC units (1_000_000 = $1).\n * Gains are profit OVER principal (notional = loan + collateral) and may be\n * negative — they are signed and never clamped.\n */\nexport interface MaxGainResult {\n fullValueOnWinUsdcUnits: number;\n grossMaxGainUsdcUnits: number;\n netMaxGainUsdcUnits: number;\n}\n\n/**\n * Maximum gain (gross and net) for a winning settlement exit — profit over\n * principal. On a win each position token redeems at $1 (CTF settlement), so\n * the full value equals `positionTokenUnits` and there is NO exit trading fee.\n *\n * ```\n * fullValueOnWin = positionTokenUnits\n * grossMaxGain = fullValueOnWin - notionalUsdcUnits\n * netMaxGain = grossMaxGain - expectedOpenTradingFee - originationFee\n * ```\n *\n * Lifetime fees are excluded, so net max gain is an upper bound (a position held\n * to settlement accrues lifetime fees that reduce realized profit). Gains are\n * signed — a position whose principal exceeds its winning redemption value\n * yields a negative max gain.\n */\nexport function computeMaxGain(input: MaxGainInput): MaxGainResult {\n const fullValueOnWinUsdcUnits = input.positionTokenUnits;\n const grossMaxGainUsdcUnits = fullValueOnWinUsdcUnits - input.notionalUsdcUnits;\n const netMaxGainUsdcUnits =\n grossMaxGainUsdcUnits - input.expectedOpenTradingFeeUsdcUnits - input.originationFeeUsdcUnits;\n\n return {\n fullValueOnWinUsdcUnits,\n grossMaxGainUsdcUnits,\n netMaxGainUsdcUnits,\n };\n}\n","const BPS_DIVISOR = 10_000;\nconst BPS_DIVISOR_BIG = 10_000n;\n\nexport const tokenUnitsPerToken = 1_000_000n;\n\nexport const partialCloseMinTokens = 5n;\n\nexport const partialCloseMinFractionBps = 2_000n;\n\nexport function closeTokenUnitsForPct(currentTokenUnits: bigint, pctBps: number): bigint {\n const clampedBps = BigInt(Math.max(0, Math.min(BPS_DIVISOR, Math.round(pctBps))));\n\n return (currentTokenUnits * clampedBps) / BPS_DIVISOR_BIG;\n}\n\nexport function pctBpsForCloseTokenUnits(currentTokenUnits: bigint, closeTokenUnits: bigint): number {\n if (currentTokenUnits <= 0n) {\n return 0;\n }\n\n return Number((closeTokenUnits * BPS_DIVISOR_BIG) / currentTokenUnits);\n}\n\nexport function fallbackMinPartialCloseTokenUnits(originalTokenUnits: bigint): bigint {\n const floorTokens = partialCloseMinTokens * tokenUnitsPerToken;\n const floorFraction = (originalTokenUnits * partialCloseMinFractionBps) / BPS_DIVISOR_BIG;\n\n return floorFraction > floorTokens ? floorFraction : floorTokens;\n}\n\nexport function clampCloseTokenUnits(value: bigint, min: bigint, max: bigint): bigint {\n if (value < min) {\n return min;\n }\n\n if (value > max) {\n return max;\n }\n\n return value;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,SAAS,sBAAsB;;;ACA/B,SAAS,oBAAoC;AAe7C,IAAM,oBAAoB;AAC1B,IAAM,yBAAyB;AAC/B,IAAM,sBAAsB;AAC5B,IAAM,6BAA6B;AACnC,IAAM,yBAAyB;AAC/B,IAAM,iBAAiB;AACvB,IAAM,gBAAgB;AAEtB,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAEA,SAAS,kBAAkB,QAAuB,SAAyB;AACzE,QAAM,aAAa,yBAAyB,kBAAkB;AAC9D,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,OAAO,MAAM;AAC7B,MAAI,CAAC,OAAO,MAAM,OAAO,KAAK,WAAW,GAAG;AAC1C,WAAO,UAAU;AAAA,EACnB;AAEA,QAAM,SAAS,KAAK,MAAM,MAAM;AAChC,MAAI,CAAC,OAAO,MAAM,MAAM,GAAG;AACzB,WAAO,KAAK,IAAI,GAAG,SAAS,KAAK,IAAI,CAAC;AAAA,EACxC;AAEA,SAAO;AACT;AAGA,eAAe,kBAAkB,UAAoC;AACnE,QAAM,UAAU,MAAM,SAAS,KAAK;AACpC,MAAI;AACJ,MAAI;AACF,aAAS,UAAW,KAAK,MAAM,OAAO,IAAqB;AAAA,EAC7D,QAAQ;AACN,aAAS;AAAA,EACX;AAEA,QAAM,OAAO,QAAQ,OAAO,QAAQ;AACpC,QAAM,OAAO,QAAQ,OAAO,QAAQ;AACpC,QAAM,UAAU,QAAQ,OAAO,WAAW,aAAa,SAAS,MAAM;AACtE,QAAM,YAAY,QAAQ,OAAO;AACjC,QAAM,SAAS,YAAa,aAAa,SAAS,IAAgC;AAElF,QAAM,IAAI,cAAc,EAAE,QAAQ,SAAS,QAAQ,MAAM,MAAM,SAAS,OAAO,CAAC;AAClF;AAUO,IAAM,aAAN,MAAiB;AAAA,EACL;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEjB,YAAY,SAA4B;AACtC,SAAK,UAAU,QAAQ;AACvB,SAAK,OAAO,QAAQ;AACpB,SAAK,UAAU,QAAQ,SAAS,WAAW,MAAM,KAAK,UAAU;AAChE,SAAK,aAAa,QAAQ,cAAc;AACxC,SAAK,kBAAkB,QAAQ,mBAAmB;AAAA,EACpD;AAAA,EAEA,MAAa,QAAW,MAAc,SAAmC;AACvE,UAAM,cAAc,MAAM,KAAK,KAAK,WAAW;AAC/C,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,MAChB,GAAG;AAAA,MACH,GAAI,SAAS;AAAA,IACf;AAEA,QAAI,WAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAC1D,GAAG;AAAA,MACH;AAAA,IACF,CAAC;AAED,QAAI,SAAS,WAAW,qBAAqB,KAAK,KAAK,SAAS;AAC9D,YAAM,KAAK,KAAK,QAAQ;AACxB,YAAM,eAAe,MAAM,KAAK,KAAK,WAAW;AAChD,iBAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,QACtD,GAAG;AAAA,QACH,SAAS,EAAE,GAAG,SAAS,GAAG,aAAa;AAAA,MACzC,CAAC;AAAA,IACH;AAEA,aAAS,UAAU,GAAG,SAAS,WAAW,0BAA0B,UAAU,KAAK,YAAY,WAAW;AACxG,YAAM,UAAU,kBAAkB,SAAS,QAAQ,IAAI,aAAa,GAAG,OAAO;AAC9E,UAAI,UAAU,KAAK,iBAAiB;AAClC;AAAA,MACF;AACA,YAAM,MAAM,OAAO;AACnB,YAAM,YAAY,MAAM,KAAK,KAAK,WAAW;AAC7C,iBAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,QACtD,GAAG;AAAA,QACH,SAAS,EAAE,GAAG,SAAS,GAAG,UAAU;AAAA,MACtC,CAAC;AAAA,IACH;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,kBAAkB,QAAQ;AAAA,IAClC;AAEA,WAAO,aAAa,MAAM,SAAS,KAAK,CAAC;AAAA,EAC3C;AAAA,EAEA,MAAa,YAAe,MAAc,SAAqC;AAC7E,UAAM,SAAS,MAAM,KAAK,QAAuB,MAAM,OAAO;AAC9D,WAAO,OAAO;AAAA,EAChB;AACF;;;ADxEA,SAAS,sBAAsB,SAAsC;AACnE,QAAM,WAAW,QAAQ,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,UAAa,MAAM,IAAI;AACxE,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,IAAI,gBAAgB;AACnC,aAAW,CAAC,KAAK,KAAK,KAAK,UAAU;AACnC,WAAO;AAAA,MACL,IAAI,QAAQ,UAAU,CAAC,MAAM,IAAI,EAAE,YAAY,CAAC,EAAE;AAAA,MAClD,OAAO,KAAK;AAAA,IACd;AAAA,EACF;AAEA,SAAO,IAAI,OAAO,SAAS,CAAC;AAC9B;AAEO,IAAM,cAAN,MAAkB;AAAA;AAAA,EAEP;AAAA,EAEC;AAAA,EAEA;AAAA,EAEjB,YAAY,SAA6B;AACvC,SAAK,UAAU,QAAQ,WAAW;AAClC,SAAK,OAAO,QAAQ;AACpB,SAAK,OAAO,IAAI,WAAW;AAAA,MACzB,SAAS,KAAK;AAAA,MACd,MAAM,QAAQ;AAAA,MACd,OAAO,QAAQ;AAAA,MACf,YAAY,QAAQ;AAAA,MACpB,iBAAiB,QAAQ;AAAA,IAC3B,CAAC;AAAA,EACH;AAAA;AAAA,EAGO,WAA0B;AAC/B,WAAO,KAAK,KAAK,WAAW,KAAK;AAAA,EACnC;AAAA,EAEA,MAAa,WAAW,QAAuD;AAC7E,UAAM,QAAQ,SAAS,sBAAsB,OAAO,QAAQ,MAAM,CAAC,IAAI;AACvE,WAAO,KAAK,KAAK,QAA2B,iCAAiC,KAAK,EAAE;AAAA,EACtF;AAAA,EAEA,MAAa,UAAU,QAAiC;AACtD,WAAO,KAAK,KAAK,QAAgB,kCAAkC,mBAAmB,MAAM,CAAC,EAAE;AAAA,EACjG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAa,cAAc,QAAyD;AAClF,WAAO,KAAK,WAAW,MAAM;AAAA,EAC/B;AAAA,EAEA,MAAa,iBAAiB,QAA2C;AACvE,WAAO,KAAK,KAAK,QAAe,uCAAuC;AAAA,MACrE,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,eAAe,MAAM,CAAC;AAAA,IAC7C,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,kBAAkB,SAAiC;AAC9D,WAAO,KAAK,KAAK,QAAe,0CAA0C,mBAAmB,OAAO,CAAC,IAAI;AAAA,MACvG,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,YAAY,QAA2C;AAClE,WAAO,KAAK,KAAK,QAAe,iCAAiC;AAAA,MAC/D,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,eAAe,MAAM,CAAC;AAAA,IAC7C,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,aAAa,QAAkD;AAC1E,UAAM,QAAQ,SAAS,sBAAsB,OAAO,QAAQ,MAAM,CAAC,IAAI;AACvE,WAAO,KAAK,KAAK,YAAsB,mCAAmC,KAAK,EAAE;AAAA,EACnF;AAAA,EAEA,MAAa,wBAAwB,YAAmD;AACtF,WAAO,KAAK,KAAK;AAAA,MACf,oCAAoC,mBAAmB,UAAU,CAAC;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,MAAa,yBAAyB,YAAuD;AAC3F,WAAO,KAAK,KAAK;AAAA,MACf,oCAAoC,mBAAmB,UAAU,CAAC;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,MAAa,eAAe,YAAmC;AAC7D,UAAM,KAAK,KAAK,QAAiB,oCAAoC,mBAAmB,UAAU,CAAC,IAAI;AAAA,MACrG,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,kBAAyC;AACpD,WAAO,KAAK,KAAK,QAAsB,sCAAsC;AAAA,EAC/E;AAAA,EAEA,MAAa,gBAAwC;AACnD,WAAO,KAAK,KAAK,QAAuB,oCAAoC;AAAA,EAC9E;AAAA,EAEA,MAAa,mBAA2C;AACtD,WAAO,KAAK,KAAK,QAAuB,uCAAuC;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAa,YAAoC;AAC/C,WAAO,KAAK,cAAc;AAAA,EAC5B;AAAA,EAEA,MAAa,YAAY,QAA+C;AACtE,UAAM,QAAQ,SAAS,sBAAsB,OAAO,QAAQ,MAAM,CAAC,IAAI;AACvE,WAAO,KAAK,KAAK,QAAkB,mCAAmC,KAAK,EAAE;AAAA,EAC/E;AAAA,EAEA,MAAa,aAAa,QAA6C;AACrE,WAAO,KAAK,KAAK,QAAmB,sCAAsC;AAAA,MACxE,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,eAAe,MAAM,CAAC;AAAA,IAC7C,CAAC;AAAA,EACH;AACF;;;AEpLO,IAAM,aAAN,MAAyC;AAAA,EACtC,MAAqB;AAAA,EAErB,YAAY;AAAA,EAEZ,iBAAuC;AAAA,EAE9B;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEjB,YAAY,SAA4B;AACtC,SAAK,SAAS,QAAQ;AACtB,SAAK,gBAAgB,QAAQ;AAC7B,SAAK,UAAU,QAAQ,WAAW;AAClC,SAAK,UAAU,QAAQ,SAAS,WAAW,MAAM,KAAK,UAAU;AAAA,EAClE;AAAA,EAEA,MAAa,aAA8C;AACzD,UAAM,yBAAyB;AAC/B,QAAI,CAAC,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK,YAAY,wBAAwB;AACtE,YAAM,KAAK,QAAQ;AAAA,IACrB;AACA,WAAO,EAAE,eAAe,UAAU,KAAK,GAAG,GAAG;AAAA,EAC/C;AAAA,EAEO,WAA0B;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAa,UAAyB;AACpC,QAAI,KAAK,gBAAgB;AACvB,YAAM,KAAK;AACX;AAAA,IACF;AAEA,SAAK,iBAAiB,KAAK,WAAW;AACtC,QAAI;AACF,YAAM,KAAK;AAAA,IACb,UAAE;AACA,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAc,aAA4B;AACxC,UAAM,WAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,OAAO,iCAAiC;AAAA,MAClF,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,WAAW,KAAK,MAAM;AAAA,MACvC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,gBAAgB,KAAK,cAAc,CAAC;AAAA,IAC7D,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,WAAW,qBAAqB,gCAAgC,SAAS,MAAM,MAAM,IAAI,EAAE;AAAA,IACvG;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,SAAK,MAAM,KAAK;AAChB,SAAK,YAAY,IAAI,KAAK,KAAK,UAAU,EAAE,QAAQ;AAAA,EACrD;AACF;AAOO,IAAM,UAAN,MAAsC;AAAA,EAC1B;AAAA,EAEA;AAAA,EAET,MAAqB;AAAA,EAErB,YAAY;AAAA,EAEZ,iBAAuC;AAAA,EAE/C,YAAY,SAAyB;AACnC,SAAK,WAAW,QAAQ;AACxB,SAAK,UAAU,QAAQ,SAAS,WAAW,MAAM,KAAK,UAAU;AAAA,EAClE;AAAA,EAEA,MAAa,aAA8C;AACzD,UAAM,yBAAyB;AAC/B,QAAI,CAAC,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK,YAAY,wBAAwB;AACtE,YAAM,KAAK,QAAQ;AAAA,IACrB;AACA,WAAO,EAAE,eAAe,UAAU,KAAK,GAAG,GAAG;AAAA,EAC/C;AAAA,EAEO,WAA0B;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAa,UAAyB;AACpC,QAAI,KAAK,gBAAgB;AACvB,YAAM,KAAK;AACX;AAAA,IACF;AAEA,SAAK,iBAAiB,KAAK,WAAW;AACtC,QAAI;AACF,YAAM,KAAK;AAAA,IACb,UAAE;AACA,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAc,aAA4B;AACxC,UAAM,WAAW,MAAM,KAAK,QAAQ,KAAK,QAAQ;AAEjD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI;AAAA,QACR;AAAA,QACA,8BAA8B,KAAK,QAAQ,KAAK,SAAS,MAAM,MAAM,IAAI;AAAA,MAC3E;AAAA,IACF;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,SAAK,MAAM,KAAK;AAChB,SAAK,YAAY,IAAI,KAAK,KAAK,UAAU,EAAE,QAAQ;AAAA,EACrD;AACF;;;ACzCO,SAAS,eAAe,GAAgC;AAC7D,SAAO,aAAa;AACtB;AAEO,SAAS,iBAAiB,GAAkC;AACjE,SAAO,YAAY;AACrB;AAEO,SAAS,eAAe,KAAqB,MAA4B;AAC9E,QAAM,UAAU,SAAS,QAAQ,IAAI,YAAY,IAAI;AAErD,SAAO,WAAW,IAAI,UAAU,IAAI;AACtC;;;AC7GO,SAAS,oBAAoB,QAAkC;AACpE,QAAM,QAAQ,OAAO;AACrB,SAAO;AAAA,IACL,KAAK;AAAA,MACH,MAAM,MAAM,IAAI;AAAA,MAChB,YAAY,MAAM,IAAI,uBAAuB;AAAA,IAC/C;AAAA,IACA,IAAI;AAAA,MACF,MAAM,MAAM,GAAG;AAAA,MACf,YAAY,MAAM,GAAG,uBAAuB;AAAA,IAC9C;AAAA,EACF;AACF;AAEO,SAAS,YAAY,aAA4C;AACtE,MAAI,YAAY,IAAI,QAAQ,YAAY,GAAG,MAAM;AAC/C,WAAO;AAAA,EACT;AACA,MAAI,YAAY,IAAI,MAAM;AACxB,WAAO;AAAA,EACT;AACA,MAAI,YAAY,GAAG,MAAM;AACvB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,YAAY,aAAwC;AAClE,SAAO,YAAY,IAAI,QAAQ,YAAY,GAAG;AAChD;AAEO,SAAS,cAAc,aAAwC;AACpE,SAAO,CAAC,YAAY,IAAI,QAAQ,CAAC,YAAY,GAAG;AAClD;AAEO,SAAS,oBAAoB,MAAyC;AAC3E,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AACA,QAAM,WAAW,KACd,QAAQ,YAAY,EAAE,EACtB,WAAW,KAAK,GAAG,EACnB,YAAY;AACf,SAAO,SAAS,OAAO,CAAC,EAAE,YAAY,IAAI,SAAS,MAAM,CAAC;AAC5D;AAEO,SAAS,qBAAqB,MAAyC;AAC5E,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AACA,QAAM,WAAW,KACd,QAAQ,YAAY,EAAE,EACtB,QAAQ,eAAe,EAAE,EACzB,QAAQ,qBAAqB,EAAE,EAC/B,WAAW,KAAK,GAAG,EACnB,YAAY;AACf,SAAO;AACT;;;ACpEA,IAAM,UAAU;AAChB,IAAM,UAAU;AAChB,IAAM,SAAS;AACf,IAAM,UAAU;AAChB,IAAM,eAAe;AAErB,IAAM,cAAc,CAAC,SAAS,SAAS,QAAQ,OAAO;AAItD,SAAS,eAAe,QAAgB,MAA+B;AACrE,QAAM,QAAQ,OAAO,SAAS;AAC9B,QAAM,MAAoC,SAAS,QAAQ,MAAM,MAAM,MAAM;AAC7E,SAAO;AAAA,IACL,CAAC,YAAY,CAAC,GAAG,IAAI,WAAW;AAAA,IAChC,CAAC,YAAY,CAAC,GAAG,IAAI,WAAW;AAAA,IAChC,CAAC,YAAY,CAAC,GAAG,IAAI,YAAY;AAAA,IACjC,CAAC,YAAY,CAAC,GAAG,IAAI,aAAa;AAAA,EACpC;AACF;AAEA,SAAS,eAAe,KAAa,SAAiB,QAAwB;AAC5E,MAAI,WAAW,GAAG;AAChB,WAAO,KAAK,IAAI,QAAQ,GAAG;AAAA,EAC7B;AACA,QAAM,IAAI,KAAK,OAAO,MAAM,UAAU,OAAO;AAC7C,SAAO,KAAK,IAAI,QAAQ,SAAS,KAAK,IAAI,GAAG,CAAC,IAAI,OAAO;AAC3D;AAEA,SAAS,kBAAkB,SAA4B,aAA6B;AAClF,QAAM,QAAQ,QAAQ,CAAC;AACvB,QAAM,OAAO,QAAQ,QAAQ,SAAS,CAAC;AACvC,MAAI,CAAC,SAAS,CAAC,MAAM;AACnB,WAAO;AAAA,EACT;AACA,MAAI,eAAe,MAAM,CAAC,GAAG;AAC3B,WAAO,MAAM,CAAC;AAAA,EAChB;AACA,MAAI,eAAe,KAAK,CAAC,GAAG;AAC1B,WAAO,KAAK,CAAC;AAAA,EACf;AACA,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,KAAK,QAAQ,CAAC;AACpB,UAAM,KAAK,QAAQ,IAAI,CAAC;AACxB,QAAI,CAAC,MAAM,CAAC,IAAI;AACd;AAAA,IACF;AACA,QAAI,eAAe,GAAG,CAAC,GAAG;AACxB,YAAM,KAAK,cAAc,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC;AAC/C,aAAO,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK;AAAA,IACnC;AAAA,EACF;AACA,SAAO,KAAK,CAAC;AACf;AAQO,SAAS,yBAAyB,QAAgB,MAAY,aAA6B;AAChG,QAAM,aAAa,eAAe,OAAO,UAAU,IAAI;AACvD,MAAI,CAAC,OAAO,SAAS,WAAW,KAAK,eAAe,GAAG;AACrD,WAAO;AAAA,EACT;AACA,QAAM,UAAU,eAAe,QAAQ,IAAI;AAC3C,QAAM,MAAM,kBAAkB,SAAS,WAAW;AAClD,QAAM,UAAU,KAAK,IAAI,YAAY,GAAG;AACxC,SAAO,eAAe,SAAS,OAAO,SAAS,SAAS,OAAO,SAAS,MAAM;AAChF;AASO,SAAS,kCAAkC,QAAgB,MAAY,eAA+B;AAC3G,QAAM,aAAa,eAAe,OAAO,UAAU,IAAI;AACvD,MAAI,CAAC,OAAO,SAAS,aAAa,KAAK,iBAAiB,GAAG;AACzD,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,KAAK,IAAI,OAAO,SAAS,SAAS,CAAC;AAChD,QAAM,SAAS,OAAO,SAAS;AAC/B,QAAM,WAAW,KAAK,IAAI,GAAG,KAAK,OAAO,aAAa,UAAU,IAAI,CAAC;AAErE,WAAS,IAAI,UAAU,KAAK,GAAG,KAAK;AAClC,UAAM,MAAM,SAAS,IAAI;AACzB,UAAM,cAAc,iBAAiB,MAAM;AAC3C,QAAI,OAAO,yBAAyB,QAAQ,MAAM,WAAW,GAAG;AAC9D,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;;;AClGA,IAAM,cAAc;AAwBb,SAAS,iCAAiC,OAAsC,aAA6B;AAClH,QAAM,WAAW,MAAM,MAAM,SAAS,CAAC;AACvC,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AACA,aAAW,QAAQ,OAAO;AACxB,QAAI,eAAe,KAAK,gBAAgB;AACtC,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AACA,SAAO,SAAS;AAClB;AAOO,SAAS,yBACd,OACA,aACA,0BACQ;AACR,SAAO,iCAAiC,OAAO,WAAW,IAAI;AAChE;AAMO,SAAS,+BAA+B,mBAA2B,2BAA2C;AACnH,SAAO,KAAK,MAAO,oBAAoB,4BAA6B,WAAW;AACjF;AAWA,SAAS,SAAS,UAAmC;AACnD,SAAO,SAAS;AAClB;AAEO,SAAS,2BAA2B,UAA6C;AACtF,QAAM,QAAQ,SAAS,QAAQ;AAC/B,QAAM,WAAW,MAAM;AACvB,QAAM,WAAW,OAAO,MAAM,iBAAiB,KAAK;AAGpD,QAAM,cAAc,MAAM,6BAA6B;AAEvD,QAAM,aAAa,MAAM,4BAA4B;AAErD,QAAM,QAAQ,WAAW,IAAI,cAAc,WAAW;AACtD,QAAM,cAAc,WAAW;AAC/B,QAAM,aAAa,WAAW;AAE9B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC/FA,IAAMA,eAAc;AACpB,IAAM,qBAAqB;AAC3B,IAAM,wBAAwB;AAiCvB,SAAS,4BAA4B,OAA0C;AACpF,QAAM,EAAE,mBAAmB,UAAU,WAAW,IAAI;AACpD,QAAM,cAAc,MAAM,eAAe;AACzC,QAAM,yBAAyB,MAAM,0BAA0B;AAE/D,MAAI,YAAY,GAAG;AACjB,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,oBAAoB;AACxC,QAAM,YAAY,cAAc;AAChC,QAAM,aAAa,YAAY,IAAI,cAAc;AAEjD,QAAM,uBAAwB,aAAaA,eAAe,YAAY,YAAY;AAClF,QAAM,sBAAuB,yBAAyBA,eAAe;AAErE,SAAO,KAAK,KAAK,uBAAuB,mBAAmB;AAC7D;AAWO,SAAS,2BAA2B,mBAA2B,eAAuB,cAAc,GAAW;AACpH,MAAI,iBAAiB,GAAG;AACtB,WAAO;AAAA,EACT;AACA,QAAM,cAAc,oBAAoB;AACxC,QAAM,SAAS,cAAc;AAC7B,QAAM,kBAAkBA,eAAc,eAAeA;AACrD,SAAO,KAAK,MAAM,SAAS,iBAAiB,qBAAqB;AACnE;AAkBO,SAAS,yBACd,eACA,aACA,mBACQ;AACR,QAAM,WAAW,cAAcA;AAC/B,MAAI,YAAY,GAAG;AACjB,WAAO;AAAA,EACT;AACA,QAAM,eAAe,kBAAkB,WAAW,KAAK;AACvD,SAAO,gBAAgB,IAAI,oBAAoBA;AACjD;AAyCO,SAAS,eAAe,OAAoC;AACjE,QAAM,0BAA0B,MAAM;AACtC,QAAM,wBAAwB,0BAA0B,MAAM;AAC9D,QAAM,sBACJ,wBAAwB,MAAM,kCAAkC,MAAM;AAExE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACxJA,IAAMC,eAAc;AACpB,IAAM,kBAAkB;AAEjB,IAAM,qBAAqB;AAE3B,IAAM,wBAAwB;AAE9B,IAAM,6BAA6B;AAEnC,SAAS,sBAAsB,mBAA2B,QAAwB;AACvF,QAAM,aAAa,OAAO,KAAK,IAAI,GAAG,KAAK,IAAIA,cAAa,KAAK,MAAM,MAAM,CAAC,CAAC,CAAC;AAEhF,SAAQ,oBAAoB,aAAc;AAC5C;AAEO,SAAS,yBAAyB,mBAA2B,iBAAiC;AACnG,MAAI,qBAAqB,IAAI;AAC3B,WAAO;AAAA,EACT;AAEA,SAAO,OAAQ,kBAAkB,kBAAmB,iBAAiB;AACvE;AAEO,SAAS,kCAAkC,oBAAoC;AACpF,QAAM,cAAc,wBAAwB;AAC5C,QAAM,gBAAiB,qBAAqB,6BAA8B;AAE1E,SAAO,gBAAgB,cAAc,gBAAgB;AACvD;AAEO,SAAS,qBAAqB,OAAe,KAAa,KAAqB;AACpF,MAAI,QAAQ,KAAK;AACf,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,KAAK;AACf,WAAO;AAAA,EACT;AAEA,SAAO;AACT;","names":["BPS_DIVISOR","BPS_DIVISOR"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { H as HintAdjustment } from './dimes-client-
|
|
2
|
-
import { Q as Quote } from './aliases-
|
|
1
|
+
import { H as HintAdjustment } from './dimes-client-CK7WmY0g.cjs';
|
|
2
|
+
import { Q as Quote } from './aliases-RwEPSZoO.cjs';
|
|
3
3
|
|
|
4
4
|
type Side = "yes" | "no";
|
|
5
5
|
interface QuoteParams {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { H as HintAdjustment } from './dimes-client-
|
|
2
|
-
import { Q as Quote } from './aliases-
|
|
1
|
+
import { H as HintAdjustment } from './dimes-client-BLTd5GkU.js';
|
|
2
|
+
import { Q as Quote } from './aliases-RwEPSZoO.js';
|
|
3
3
|
|
|
4
4
|
type Side = "yes" | "no";
|
|
5
5
|
interface QuoteParams {
|
package/dist/react/index.cjs
CHANGED
|
@@ -231,7 +231,7 @@ function useSearchMarkets(params, queryOptions) {
|
|
|
231
231
|
const client = useDimesClient();
|
|
232
232
|
return _reactquery.useQuery.call(void 0, {
|
|
233
233
|
queryKey: ["dimes", "markets", "search", params],
|
|
234
|
-
queryFn: () => client.
|
|
234
|
+
queryFn: () => client.getMarkets(params),
|
|
235
235
|
enabled: !!params.query,
|
|
236
236
|
...queryOptions
|
|
237
237
|
});
|
|
@@ -351,6 +351,23 @@ function useContractInfo(queryOptions) {
|
|
|
351
351
|
});
|
|
352
352
|
}
|
|
353
353
|
|
|
354
|
+
// src/react/use-partial-closes.ts
|
|
355
|
+
|
|
356
|
+
function usePositionPartialCloses(positionId, queryOptions) {
|
|
357
|
+
const client = useDimesClient();
|
|
358
|
+
return _reactquery.useQuery.call(void 0, {
|
|
359
|
+
queryKey: ["dimes", "positionPartialCloses", positionId],
|
|
360
|
+
queryFn: () => {
|
|
361
|
+
if (positionId == null) {
|
|
362
|
+
return Promise.reject(new Error("positionId is required"));
|
|
363
|
+
}
|
|
364
|
+
return client.getPositionPartialCloses(positionId);
|
|
365
|
+
},
|
|
366
|
+
enabled: Boolean(positionId),
|
|
367
|
+
...queryOptions
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
|
|
354
371
|
// src/react/use-limits.ts
|
|
355
372
|
|
|
356
373
|
function useUserLimits(queryOptions) {
|
|
@@ -560,5 +577,6 @@ function useMarketStream(options) {
|
|
|
560
577
|
|
|
561
578
|
|
|
562
579
|
|
|
563
|
-
|
|
580
|
+
|
|
581
|
+
exports.DimesProvider = DimesProvider; exports.useCancelPosition = useCancelPosition; exports.useContractInfo = useContractInfo; exports.useDimesClient = useDimesClient; exports.useLimits = useLimits; exports.useMarket = useMarket; exports.useMarketStream = useMarketStream; exports.useMarkets = useMarkets; exports.usePartnerLimits = usePartnerLimits; exports.usePositionPartialCloses = usePositionPartialCloses; exports.usePositionStream = usePositionStream; exports.usePositions = usePositions; exports.useQuote = useQuote; exports.useQuoteMachine = useQuoteMachine; exports.useSearchMarkets = useSearchMarkets; exports.useUserLimits = useUserLimits;
|
|
564
582
|
//# sourceMappingURL=index.cjs.map
|
package/dist/react/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/alexemery/bl/dimes-sdk/dist/react/index.cjs","../../src/react/provider.tsx","../../src/react/use-quote.ts","../../src/react/use-quote-machine.ts","../../src/react/use-markets.ts","../../src/react/use-positions.ts","../../src/react/ws-reconcile.ts","../../src/react/use-contract-info.ts","../../src/react/use-limits.ts","../../src/react/use-cancel-position.ts","../../src/react/use-position-stream.ts","../../src/react/use-market-stream.ts"],"names":["reducer","useReducer","useCallback","useQuery","useRef","useQueryClient","useState","useEffect"],"mappings":"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","file":"/Users/alexemery/bl/dimes-sdk/dist/react/index.cjs","sourcesContent":[null,"import { createContext, useContext, type ReactNode } from \"react\";\nimport type { DimesClient } from \"../client/dimes-client\";\nimport { DimesError } from \"../errors/dimes-error\";\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst DimesContext = createContext<DimesClient | null>(null);\n\nexport interface DimesProviderProps {\n client: DimesClient;\n children: ReactNode;\n}\n\n// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/explicit-function-return-type\nexport function DimesProvider({ client, children }: DimesProviderProps) {\n return <DimesContext.Provider value={client}>{children}</DimesContext.Provider>;\n}\n\nexport function useDimesClient(): DimesClient {\n const client = useContext(DimesContext);\n if (!client) {\n throw new DimesError(\"missing_provider\", \"useDimesClient must be used within a <DimesProvider>\");\n }\n return client;\n}\n","import { useCallback, useReducer } from \"react\";\nimport { executeQuote } from \"../quote/quote\";\nimport type { HintAdjustment } from \"../quote/quote-error-hints\";\nimport type { Quote } from \"../types\";\nimport type { QuoteOptions, QuoteParams, QuoteResult } from \"../types/quote\";\nimport { useDimesClient } from \"./provider\";\n\nexport type QuotePhase = \"idle\" | \"loading-draft\" | \"draft-ready\" | \"promoting\" | \"promoted\" | \"market-moved\" | \"error\";\n\nexport interface QuoteState {\n phase: QuotePhase;\n draft?: Quote;\n quote?: Quote;\n /** @deprecated Renamed to {@link QuoteState.quote}. Still populated for backward compatibility. */\n // eslint-disable-next-line no-restricted-syntax -- intentional deprecated alias field\n offer?: Quote;\n corrections: HintAdjustment[];\n retries: number;\n error?: unknown;\n}\n\ntype Action =\n | { type: \"loading\" }\n | { type: \"draftReady\"; draft: Quote }\n | { type: \"promoting\" }\n | { type: \"marketMoved\" }\n | { type: \"done\"; result: QuoteResult }\n | { type: \"error\"; error: unknown }\n | { type: \"reset\" };\n\nfunction reducer(state: QuoteState, action: Action): QuoteState {\n switch (action.type) {\n case \"loading\":\n return { phase: \"loading-draft\", corrections: [], retries: 0 };\n case \"draftReady\":\n return { ...state, phase: \"draft-ready\", draft: action.draft };\n case \"promoting\":\n return { ...state, phase: \"promoting\" };\n case \"marketMoved\":\n return { ...state, phase: \"market-moved\" };\n case \"done\":\n return {\n phase: \"promoted\",\n quote: action.result.quote,\n offer: action.result.quote,\n corrections: action.result.corrections,\n retries: action.result.retries,\n draft: state.draft,\n };\n case \"error\":\n return { ...state, phase: \"error\", error: action.error };\n case \"reset\":\n return { phase: \"idle\", corrections: [], retries: 0 };\n default:\n return state;\n }\n}\n\nexport interface UseQuoteReturn {\n state: QuoteState;\n execute: (params: QuoteParams, options?: QuoteOptions) => Promise<QuoteResult>;\n reset: () => void;\n}\n\nexport function useQuote(): UseQuoteReturn {\n const client = useDimesClient();\n const [state, dispatch] = useReducer(reducer, {\n phase: \"idle\",\n corrections: [],\n retries: 0,\n });\n\n const execute = useCallback(\n async (params: QuoteParams, options?: QuoteOptions): Promise<QuoteResult> => {\n dispatch({ type: \"loading\" });\n\n try {\n const result = await executeQuote(client, params, {\n ...options,\n onDraftReady: (draft) => {\n dispatch({ type: \"draftReady\", draft });\n dispatch({ type: \"promoting\" });\n options?.onDraftReady?.(draft);\n },\n onMarketMoved: (event) => {\n dispatch({ type: \"marketMoved\" });\n return options?.onMarketMoved?.(event);\n },\n onCorrection: (adj) => {\n return options?.onCorrection?.(adj);\n },\n });\n\n dispatch({ type: \"done\", result });\n return result;\n } catch (err) {\n dispatch({ type: \"error\", error: err });\n throw err;\n }\n },\n [client],\n );\n\n const reset = useCallback(() => {\n dispatch({ type: \"reset\" });\n }, []);\n\n return { state, execute, reset };\n}\n","import { useCallback, useReducer, useRef } from \"react\";\nimport { buildQuoteParams } from \"../quote/build-quote-params\";\nimport { isMarketMovedError } from \"../quote/quote\";\nimport type { CreateQuoteParams, Quote } from \"../types\";\nimport type { QuoteParams } from \"../types/quote\";\nimport { useDimesClient } from \"./provider\";\n\nconst DEFAULT_MAX_RETRIES = 3;\n\n/**\n * Interactive, user-in-the-loop quote flow: draft → review → promote, pausing\n * across renders so the UI can show each step. This is the granular companion\n * to `useQuote`/`executeQuote` (which run draft→promote in one call). The steps\n * map directly onto the SDK client (`createDraftQuote`/`promoteDraftQuote`/\n * `createQuote`); on a market-moved promote failure it re-drafts and surfaces a\n * `market-moved` state so the user can review and accept the new draft.\n */\nexport type QuoteMachineState =\n | { phase: \"idle\" }\n | { phase: \"loading-draft\" }\n | { phase: \"draft-ready\"; draft: Quote; quotedAt: number }\n | { phase: \"promoting\"; draft: Quote; quotedAt: number }\n | { phase: \"promoted\"; draft: Quote; promotedQuote: Quote; correctedFrom?: Quote; quotedAt: number }\n | { phase: \"market-moved\"; originalDraft: Quote; newDraft: Quote; retryCount: number; quotedAt: number }\n | { phase: \"error\"; error: unknown; draft?: Quote };\n\ntype Action =\n | { type: \"loading\" }\n | { type: \"draftReady\"; draft: Quote; quotedAt: number }\n | { type: \"promoting\"; draft: Quote; quotedAt: number }\n | { type: \"promoted\"; draft: Quote; promotedQuote: Quote; correctedFrom?: Quote; quotedAt: number }\n | { type: \"marketMoved\"; originalDraft: Quote; newDraft: Quote; retryCount: number; quotedAt: number }\n | { type: \"error\"; error: unknown; draft?: Quote }\n | { type: \"reset\" };\n\nfunction reducer(_state: QuoteMachineState, action: Action): QuoteMachineState {\n switch (action.type) {\n case \"loading\":\n return { phase: \"loading-draft\" };\n case \"draftReady\":\n return { phase: \"draft-ready\", draft: action.draft, quotedAt: action.quotedAt };\n case \"promoting\":\n return { phase: \"promoting\", draft: action.draft, quotedAt: action.quotedAt };\n case \"promoted\":\n return {\n phase: \"promoted\",\n draft: action.draft,\n promotedQuote: action.promotedQuote,\n correctedFrom: action.correctedFrom,\n quotedAt: action.quotedAt,\n };\n case \"marketMoved\":\n return {\n phase: \"market-moved\",\n originalDraft: action.originalDraft,\n newDraft: action.newDraft,\n retryCount: action.retryCount,\n quotedAt: action.quotedAt,\n };\n case \"error\":\n return { phase: \"error\", error: action.error, draft: action.draft };\n case \"reset\":\n return { phase: \"idle\" };\n default:\n return _state;\n }\n}\n\nexport interface UseQuoteMachineOptions {\n /** Maximum number of re-draft attempts on a market-moved promote failure. Default 3. */\n maxRetries?: number;\n}\n\nexport interface UseQuoteMachineReturn {\n state: QuoteMachineState;\n /** Build params from a `QuoteParams` and fetch a draft quote. Moves to `draft-ready`. */\n getDraft: (params: QuoteParams) => Promise<void>;\n /** Promote a reviewed draft into a signed quote. On market-moved, re-drafts and surfaces `market-moved`. */\n promote: (draft: Quote, retryCount?: number) => Promise<void>;\n /** Accept a re-drafted quote after a `market-moved` and promote it. */\n acceptChanges: (newDraft: Quote, retryCount: number) => Promise<void>;\n /** Promote pre-adjusted params directly via `createQuote` (e.g. after applying a correction hint). */\n correctAndPromote: (originalDraft: Quote, adjustedParams: CreateQuoteParams) => Promise<void>;\n reset: () => void;\n}\n\nexport function useQuoteMachine(options?: UseQuoteMachineOptions): UseQuoteMachineReturn {\n const client = useDimesClient();\n const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;\n const [state, dispatch] = useReducer(reducer, { phase: \"idle\" } as QuoteMachineState);\n const lastParamsRef = useRef<CreateQuoteParams | null>(null);\n const quotedAtRef = useRef(0);\n\n const getDraft = useCallback(\n async (params: QuoteParams): Promise<void> => {\n dispatch({ type: \"loading\" });\n const quoteParams = buildQuoteParams(params);\n lastParamsRef.current = quoteParams;\n try {\n const draft = await client.createDraftQuote(quoteParams);\n\n quotedAtRef.current = Date.now();\n dispatch({ type: \"draftReady\", draft, quotedAt: quotedAtRef.current });\n } catch (err) {\n dispatch({ type: \"error\", error: err });\n }\n },\n [client],\n );\n\n const promote = useCallback(\n async (draft: Quote, retryCount = 0): Promise<void> => {\n const quotedAt = quotedAtRef.current;\n dispatch({ type: \"promoting\", draft, quotedAt });\n try {\n const promotedQuote = await client.promoteDraftQuote(draft.id);\n dispatch({ type: \"promoted\", draft, promotedQuote, quotedAt });\n } catch (err) {\n if (isMarketMovedError(err) && retryCount < maxRetries && lastParamsRef.current) {\n try {\n const newDraft = await client.createDraftQuote(lastParamsRef.current);\n // eslint-disable-next-line require-atomic-updates -- timestamp ref, no contended state\n quotedAtRef.current = Date.now();\n dispatch({\n type: \"marketMoved\",\n originalDraft: draft,\n newDraft,\n retryCount: retryCount + 1,\n quotedAt: quotedAtRef.current,\n });\n } catch (draftErr) {\n dispatch({ type: \"error\", error: draftErr, draft });\n }\n } else {\n dispatch({ type: \"error\", error: err, draft });\n }\n }\n },\n [client, maxRetries],\n );\n\n const acceptChanges = useCallback(\n async (newDraft: Quote, retryCount: number): Promise<void> => {\n await promote(newDraft, retryCount);\n },\n [promote],\n );\n\n const correctAndPromote = useCallback(\n async (originalDraft: Quote, adjustedParams: CreateQuoteParams): Promise<void> => {\n dispatch({ type: \"promoting\", draft: originalDraft, quotedAt: quotedAtRef.current });\n lastParamsRef.current = adjustedParams;\n try {\n const promotedQuote = await client.createQuote(adjustedParams);\n // eslint-disable-next-line require-atomic-updates -- timestamp ref, no contended state\n quotedAtRef.current = Date.now();\n dispatch({\n type: \"promoted\",\n draft: promotedQuote,\n promotedQuote,\n correctedFrom: originalDraft,\n quotedAt: quotedAtRef.current,\n });\n } catch (err) {\n dispatch({ type: \"error\", error: err });\n }\n },\n [client],\n );\n\n const reset = useCallback((): void => {\n dispatch({ type: \"reset\" });\n lastParamsRef.current = null;\n quotedAtRef.current = 0;\n }, []);\n\n return { state, getDraft, promote, acceptChanges, correctAndPromote, reset };\n}\n","import { useQuery, type UseQueryOptions, type UseQueryResult } from \"@tanstack/react-query\";\nimport type { GetMarketsParams, SearchMarketsParams } from \"../client/dimes-client\";\nimport type { Market, Paginated } from \"../types\";\nimport { useDimesClient } from \"./provider\";\n\nexport function useMarkets(\n params?: GetMarketsParams,\n queryOptions?: Partial<UseQueryOptions<Paginated<Market>>>,\n): UseQueryResult<Paginated<Market>> {\n const client = useDimesClient();\n\n return useQuery({\n queryKey: [\"dimes\", \"markets\", params],\n queryFn: () => client.getMarkets(params),\n ...queryOptions,\n });\n}\n\nexport function useSearchMarkets(\n params: SearchMarketsParams,\n queryOptions?: Partial<UseQueryOptions<Paginated<Market>>>,\n): UseQueryResult<Paginated<Market>> {\n const client = useDimesClient();\n\n return useQuery({\n queryKey: [\"dimes\", \"markets\", \"search\", params],\n queryFn: () => client.searchMarkets(params),\n enabled: !!params.query,\n ...queryOptions,\n });\n}\n\nexport function useMarket(ticker: string, queryOptions?: Partial<UseQueryOptions<Market>>): UseQueryResult<Market> {\n const client = useDimesClient();\n\n return useQuery({\n queryKey: [\"dimes\", \"market\", ticker],\n queryFn: () => client.getMarket(ticker),\n enabled: !!ticker,\n ...queryOptions,\n });\n}\n","import { useQuery, type Query, type UseQueryOptions, type UseQueryResult } from \"@tanstack/react-query\";\nimport type { GetPositionsParams } from \"../client/dimes-client\";\nimport type { Position } from \"../types\";\nimport { useDimesClient } from \"./provider\";\nimport { defaultReconciliationWindowMs, reconcilePolledPositions, transientPositionStatuses } from \"./ws-reconcile\";\n\nconst DEFAULT_FAST_POLL_MS = 5_000;\nconst DEFAULT_SLOW_POLL_MS = 15_000;\n\nexport interface UsePositionsOptions {\n /**\n * Appended to the query key so changing scope (e.g. switching wallet) does not serve the previous\n * scope's cached positions until a refetch. Omit to keep the default, scope-less cache key.\n */\n scope?: string | null;\n /**\n * Poll faster while any position is in a transient state (pending/closing/settling/unwinding) and\n * slower otherwise. Pass `true` for the defaults (5s / 15s) or an object to tune them.\n */\n adaptivePolling?: boolean | { fastMs?: number; slowMs?: number };\n /**\n * Defer to fresher WebSocket data: when a position was updated over the socket within the\n * reconciliation window, a slower REST poll won't overwrite it. Use with `usePositionStream` in\n * reconcile mode. Pass `true` for the default window or a number of milliseconds.\n */\n reconcile?: boolean | number;\n}\n\nfunction adaptiveRefetchInterval(\n adaptive: NonNullable<UsePositionsOptions[\"adaptivePolling\"]>,\n): (query: Query<Position[]>) => number {\n const fastMs = typeof adaptive === \"object\" ? (adaptive.fastMs ?? DEFAULT_FAST_POLL_MS) : DEFAULT_FAST_POLL_MS;\n const slowMs = typeof adaptive === \"object\" ? (adaptive.slowMs ?? DEFAULT_SLOW_POLL_MS) : DEFAULT_SLOW_POLL_MS;\n return (query) => (query.state.data?.some((p) => transientPositionStatuses.has(p.status)) ? fastMs : slowMs);\n}\n\nfunction reconcileStructuralSharing(reconcile: number | true): (oldData: unknown, newData: unknown) => Position[] {\n const windowMs = typeof reconcile === \"number\" ? reconcile : defaultReconciliationWindowMs;\n return (oldData, newData) =>\n reconcilePolledPositions(oldData as Position[] | undefined, newData as Position[], windowMs, Date.now());\n}\n\nexport function usePositions(\n params?: GetPositionsParams,\n queryOptions?: Partial<UseQueryOptions<Position[]>>,\n options?: UsePositionsOptions,\n): UseQueryResult<Position[]> {\n const client = useDimesClient();\n\n const queryKey =\n options?.scope !== undefined ? [\"dimes\", \"positions\", params, options.scope] : [\"dimes\", \"positions\", params];\n\n const config: UseQueryOptions<Position[]> = {\n queryKey,\n queryFn: () => client.getPositions(params),\n };\n\n if (options?.adaptivePolling) {\n config.refetchInterval = adaptiveRefetchInterval(options.adaptivePolling);\n }\n\n if (options?.reconcile) {\n config.structuralSharing = reconcileStructuralSharing(options.reconcile);\n }\n\n return useQuery({ ...config, ...queryOptions });\n}\n","import type { QueryClient } from \"@tanstack/react-query\";\nimport type { Market, Paginated, Position } from \"../types\";\nimport type { MarketDelta, PositionEvent } from \"../ws\";\n\n/**\n * Shared plumbing for merging WebSocket events into the React Query cache. Used by the optional\n * reconcile mode of `usePositionStream` / `useMarketStream` and the `reconcile` option on\n * `usePositions`. Kept internal so the query keys and the WS-timestamp registry stay in sync.\n */\n\nexport const positionsQueryKey = [\"dimes\", \"positions\"] as const;\n\nexport const marketsQueryKey = [\"dimes\", \"markets\"] as const;\n\nexport const defaultReconciliationWindowMs = 12_000;\n\n/** Position statuses that indicate an in-flight transition — polled faster by `adaptivePolling`. */\nexport const transientPositionStatuses: ReadonlySet<string> = new Set([\"pending\", \"closing\", \"settling\", \"unwinding\"]);\n\n/**\n * Records the last time each position id was written from a WebSocket event. Polling reconciliation\n * uses this so a slower REST poll never clobbers fresher WS data inside the reconciliation window.\n */\nexport const wsPositionTimestamps = new Map<string, number>();\n\n/** Merge a single position event into every cached positions query. */\nexport function mergePositionEvent(queryClient: QueryClient, event: PositionEvent, now: number): void {\n const position = event.data;\n queryClient.setQueriesData<Position[]>({ queryKey: positionsQueryKey }, (old) => {\n if (!old) {\n return old;\n }\n const idx = old.findIndex((p) => p.id === position.id);\n if (idx >= 0) {\n const next = [...old];\n next[idx] = position;\n return next;\n }\n if (event.type === \"position.created\") {\n return [position, ...old];\n }\n return old;\n });\n wsPositionTimestamps.set(position.id, now);\n}\n\n/**\n * `structuralSharing` for a polled positions list: keep the cached (WS-fresher) copy of any position\n * updated over the socket within `windowMs`, otherwise accept the polled copy.\n */\nexport function reconcilePolledPositions(\n oldData: Position[] | undefined,\n newData: Position[],\n windowMs: number,\n now: number,\n): Position[] {\n if (!oldData) {\n return newData;\n }\n return newData.map((polled) => {\n const wsTime = wsPositionTimestamps.get(polled.id);\n if (wsTime !== undefined && now - wsTime < windowMs) {\n const fresher = oldData.find((p) => p.id === polled.id);\n return fresher ?? polled;\n }\n if (wsTime !== undefined) {\n wsPositionTimestamps.delete(polled.id);\n }\n return polled;\n });\n}\n\n/**\n * Deep-merge a market delta onto a cached market. The nested `leverage` block must be merged rather\n * than replaced — a max-leverage delta carries only the changed leverage fields, so a shallow spread\n * would drop the constant `minBps`/`stepBps` until the next full refetch.\n */\nfunction mergeMarket(prev: Market, delta: MarketDelta): Market {\n return {\n ...prev,\n ...delta,\n leverage: delta.leverage ? { ...prev.leverage, ...delta.leverage } : prev.leverage,\n };\n}\n\n/** Merge market deltas into every cached paginated markets query (no-op for ids not present). */\nexport function mergeMarketDeltas(queryClient: QueryClient, deltas: MarketDelta[]): void {\n queryClient.setQueriesData<Paginated<Market>>({ queryKey: marketsQueryKey }, (old) => {\n if (!old) {\n return old;\n }\n const data = old.data.map((market) => {\n const delta = deltas.find((d) => d.id === market.id);\n return delta ? mergeMarket(market, delta) : market;\n });\n const changed = data.some((market, i) => market !== old.data[i]);\n return changed ? { ...old, data } : old;\n });\n}\n","import { useQuery, type UseQueryOptions, type UseQueryResult } from \"@tanstack/react-query\";\nimport type { ContractInfo } from \"../types\";\nimport { useDimesClient } from \"./provider\";\n\nexport function useContractInfo(queryOptions?: Partial<UseQueryOptions<ContractInfo>>): UseQueryResult<ContractInfo> {\n const client = useDimesClient();\n\n return useQuery({\n queryKey: [\"dimes\", \"contractInfo\"],\n queryFn: () => client.getContractInfo(),\n staleTime: Infinity,\n ...queryOptions,\n });\n}\n","import { useQuery, type UseQueryOptions, type UseQueryResult } from \"@tanstack/react-query\";\nimport type { CustomerLimit } from \"../types\";\nimport { useDimesClient } from \"./provider\";\n\n/** User trading limits (JWT auth) — `GET /user-limits`. */\nexport function useUserLimits(queryOptions?: Partial<UseQueryOptions<CustomerLimit>>): UseQueryResult<CustomerLimit> {\n const client = useDimesClient();\n\n return useQuery({\n queryKey: [\"dimes\", \"user-limits\"],\n queryFn: () => client.getUserLimits(),\n ...queryOptions,\n });\n}\n\n/** Partner-wide limits (API-key auth) — `GET /partner-limits`. */\nexport function usePartnerLimits(\n queryOptions?: Partial<UseQueryOptions<CustomerLimit>>,\n): UseQueryResult<CustomerLimit> {\n const client = useDimesClient();\n\n return useQuery({\n queryKey: [\"dimes\", \"partner-limits\"],\n queryFn: () => client.getPartnerLimits(),\n ...queryOptions,\n });\n}\n\n/** @deprecated Use {@link useUserLimits}. Alias kept for back-compat; resolves to user limits. */\nexport function useLimits(queryOptions?: Partial<UseQueryOptions<CustomerLimit>>): UseQueryResult<CustomerLimit> {\n return useUserLimits(queryOptions);\n}\n","import { useMutation, type UseMutationOptions, type UseMutationResult } from \"@tanstack/react-query\";\nimport { DimesApiError } from \"../errors/dimes-error\";\nimport { useDimesClient } from \"./provider\";\n\nconst HTTP_CONFLICT = 409;\n\nexport type CancelPositionResult = \"cancelled\" | \"already_cancelling\";\n\nexport interface UseCancelPositionOptions {\n /**\n * Treat a 409 Conflict (the position is already being cancelled) as success, resolving to\n * `\"already_cancelling\"` instead of throwing. Default false — a 409 rejects like any other error.\n */\n treatConflictAsAlreadyCancelling?: boolean;\n}\n\nexport function useCancelPosition(\n mutationOptions?: Partial<UseMutationOptions<CancelPositionResult, Error, string>>,\n options?: UseCancelPositionOptions,\n): UseMutationResult<CancelPositionResult, Error, string> {\n const client = useDimesClient();\n const treatConflictAsAlreadyCancelling = options?.treatConflictAsAlreadyCancelling ?? false;\n\n return useMutation({\n mutationFn: async (positionId: string): Promise<CancelPositionResult> => {\n try {\n await client.cancelPosition(positionId);\n return \"cancelled\";\n } catch (err) {\n if (treatConflictAsAlreadyCancelling && err instanceof DimesApiError && err.status === HTTP_CONFLICT) {\n return \"already_cancelling\";\n }\n throw err;\n }\n },\n ...mutationOptions,\n });\n}\n","import { useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { PositionSocket, type NotificationEvent, type PositionEvent } from \"../ws\";\nimport { useDimesClient } from \"./provider\";\nimport { mergePositionEvent, positionsQueryKey } from \"./ws-reconcile\";\n\nexport type StreamMode = \"raw\" | \"reconcile\";\n\nexport interface UsePositionStreamOptions {\n /** Connect the socket. Default true. Set false to gate on auth being ready. */\n enabled?: boolean;\n /**\n * `\"reconcile\"` (default) merges every event into the `usePositions` query cache so the UI updates\n * instantly; `\"raw\"` does not touch the cache and only forwards events to your callbacks.\n */\n mode?: StreamMode;\n /** Disconnect while the tab is hidden and reconnect when it becomes visible again. Default true. */\n pauseOnHidden?: boolean;\n /** Invalidate the positions query on reconnect (skipping the first connect) to catch missed events. Default true. */\n invalidateOnReconnect?: boolean;\n /** Always called with the raw (camelCased) event, in both modes. */\n onEvent?: (event: PositionEvent) => void;\n /** Called with user-gateway notification events (toasts, fill progress…). Never touches the cache. */\n onNotification?: (event: NotificationEvent) => void;\n onConnect?: () => void;\n onDisconnect?: () => void;\n onError?: (error: unknown) => void;\n}\n\nexport interface UsePositionStreamResult {\n socket: PositionSocket | null;\n connected: boolean;\n}\n\n/**\n * Subscribe to the user position WebSocket gateway. In `reconcile` mode (default) events are merged\n * into the React Query cache used by `usePositions`; in `raw` mode you handle events yourself via\n * `onEvent`. App-specific side effects (toasts, stores) belong in the callbacks, not the SDK.\n */\nexport function usePositionStream(options?: UsePositionStreamOptions): UsePositionStreamResult {\n const client = useDimesClient();\n const queryClient = useQueryClient();\n const socketRef = useRef<PositionSocket | null>(null);\n const [connected, setConnected] = useState(false);\n\n const enabled = options?.enabled ?? true;\n const mode = options?.mode ?? \"reconcile\";\n const pauseOnHidden = options?.pauseOnHidden ?? true;\n const invalidateOnReconnect = options?.invalidateOnReconnect ?? true;\n\n // Keep the latest callbacks/flags in a ref so the socket effect does not reconnect on every render.\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n useEffect(() => {\n if (!enabled) {\n return undefined;\n }\n\n const socket = new PositionSocket({\n baseUrl: client.baseUrl,\n getToken: (): string | null => client.getToken(),\n });\n socketRef.current = socket;\n\n const unsubEvent = socket.on(\"*\", (event) => {\n if (mode === \"reconcile\") {\n mergePositionEvent(queryClient, event, Date.now());\n }\n optionsRef.current?.onEvent?.(event);\n });\n\n const unsubNotification = socket.onNotification((event) => {\n optionsRef.current?.onNotification?.(event);\n });\n\n let firstConnect = true;\n const unsubConnect = socket.onConnect(() => {\n setConnected(true);\n if (firstConnect) {\n firstConnect = false;\n } else if (mode === \"reconcile\" && invalidateOnReconnect) {\n void queryClient.invalidateQueries({ queryKey: positionsQueryKey });\n }\n optionsRef.current?.onConnect?.();\n });\n\n const unsubDisconnect = socket.onDisconnect(() => {\n setConnected(false);\n optionsRef.current?.onDisconnect?.();\n });\n\n const unsubError = socket.onError((error) => {\n optionsRef.current?.onError?.(error);\n });\n\n const handleVisibility =\n pauseOnHidden && typeof document !== \"undefined\"\n ? (): void => {\n if (document.hidden) {\n socket.disconnect();\n } else {\n socket.connect();\n }\n }\n : null;\n if (handleVisibility) {\n document.addEventListener(\"visibilitychange\", handleVisibility);\n }\n\n socket.connect();\n\n return (): void => {\n if (handleVisibility) {\n document.removeEventListener(\"visibilitychange\", handleVisibility);\n }\n unsubEvent();\n unsubNotification();\n unsubConnect();\n unsubDisconnect();\n unsubError();\n socket.disconnect();\n socketRef.current = null;\n setConnected(false);\n };\n }, [client, queryClient, enabled, mode, pauseOnHidden, invalidateOnReconnect]);\n\n return { socket: socketRef.current, connected };\n}\n","import { useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { MarketSocket, type MarketDelta, type MarketEvent } from \"../ws\";\nimport { useDimesClient } from \"./provider\";\nimport type { StreamMode } from \"./use-position-stream\";\nimport { marketsQueryKey, mergeMarketDeltas } from \"./ws-reconcile\";\n\nexport interface UseMarketStreamOptions {\n /** Connect the socket. Default true. */\n enabled?: boolean;\n /**\n * `\"reconcile\"` (default) merges `eligibility_changed` / `max_leverage_changed` deltas into the\n * `useMarkets` query cache; `\"raw\"` only forwards events. `market.discovered` events are never\n * injected into the paginated cache (that would pollute server-filtered views) — handle them via\n * `onEvent` in either mode.\n */\n mode?: StreamMode;\n /** Disconnect while the tab is hidden and reconnect when visible again. Default true. */\n pauseOnHidden?: boolean;\n /** Invalidate the markets query on reconnect (skipping the first connect). Default true. */\n invalidateOnReconnect?: boolean;\n /** Always called with the raw (camelCased) event, in both modes. */\n onEvent?: (event: MarketEvent) => void;\n onConnect?: () => void;\n onDisconnect?: () => void;\n onError?: (error: unknown) => void;\n}\n\nexport interface UseMarketStreamResult {\n socket: MarketSocket | null;\n connected: boolean;\n}\n\n/**\n * Subscribe to the user market WebSocket gateway. In `reconcile` mode (default) eligibility and\n * max-leverage deltas are deep-merged into the `useMarkets` cache; discovered markets are forwarded\n * to `onEvent` for the app to route (e.g. a \"new markets\" strip).\n */\nexport function useMarketStream(options?: UseMarketStreamOptions): UseMarketStreamResult {\n const client = useDimesClient();\n const queryClient = useQueryClient();\n const socketRef = useRef<MarketSocket | null>(null);\n const [connected, setConnected] = useState(false);\n\n const enabled = options?.enabled ?? true;\n const mode = options?.mode ?? \"reconcile\";\n const pauseOnHidden = options?.pauseOnHidden ?? true;\n const invalidateOnReconnect = options?.invalidateOnReconnect ?? true;\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n useEffect(() => {\n if (!enabled) {\n return undefined;\n }\n\n const socket = new MarketSocket({\n baseUrl: client.baseUrl,\n getToken: (): string | null => client.getToken(),\n });\n socketRef.current = socket;\n\n const unsubEvent = socket.on(\"*\", (event) => {\n if (mode === \"reconcile\" && event.type !== \"market.discovered\") {\n mergeMarketDeltas(queryClient, event.data as MarketDelta[]);\n }\n optionsRef.current?.onEvent?.(event);\n });\n\n let firstConnect = true;\n const unsubConnect = socket.onConnect(() => {\n setConnected(true);\n if (firstConnect) {\n firstConnect = false;\n } else if (mode === \"reconcile\" && invalidateOnReconnect) {\n void queryClient.invalidateQueries({ queryKey: marketsQueryKey });\n }\n optionsRef.current?.onConnect?.();\n });\n\n const unsubDisconnect = socket.onDisconnect(() => {\n setConnected(false);\n optionsRef.current?.onDisconnect?.();\n });\n\n const unsubError = socket.onError((error) => {\n optionsRef.current?.onError?.(error);\n });\n\n const handleVisibility =\n pauseOnHidden && typeof document !== \"undefined\"\n ? (): void => {\n if (document.hidden) {\n socket.disconnect();\n } else {\n socket.connect();\n }\n }\n : null;\n if (handleVisibility) {\n document.addEventListener(\"visibilitychange\", handleVisibility);\n }\n\n socket.connect();\n\n return (): void => {\n if (handleVisibility) {\n document.removeEventListener(\"visibilitychange\", handleVisibility);\n }\n unsubEvent();\n unsubConnect();\n unsubDisconnect();\n unsubError();\n socket.disconnect();\n socketRef.current = null;\n setConnected(false);\n };\n }, [client, queryClient, enabled, mode, pauseOnHidden, invalidateOnReconnect]);\n\n return { socket: socketRef.current, connected };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/Users/alexemery/bl/dimes-sdk/dist/react/index.cjs","../../src/react/provider.tsx","../../src/react/use-quote.ts","../../src/react/use-quote-machine.ts","../../src/react/use-markets.ts","../../src/react/use-positions.ts","../../src/react/ws-reconcile.ts","../../src/react/use-contract-info.ts","../../src/react/use-partial-closes.ts","../../src/react/use-limits.ts","../../src/react/use-cancel-position.ts","../../src/react/use-position-stream.ts","../../src/react/use-market-stream.ts"],"names":["reducer","useReducer","useCallback","useQuery","useRef","useQueryClient","useState","useEffect"],"mappings":"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","file":"/Users/alexemery/bl/dimes-sdk/dist/react/index.cjs","sourcesContent":[null,"import { createContext, useContext, type ReactNode } from \"react\";\nimport type { DimesClient } from \"../client/dimes-client\";\nimport { DimesError } from \"../errors/dimes-error\";\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst DimesContext = createContext<DimesClient | null>(null);\n\nexport interface DimesProviderProps {\n client: DimesClient;\n children: ReactNode;\n}\n\n// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/explicit-function-return-type\nexport function DimesProvider({ client, children }: DimesProviderProps) {\n return <DimesContext.Provider value={client}>{children}</DimesContext.Provider>;\n}\n\nexport function useDimesClient(): DimesClient {\n const client = useContext(DimesContext);\n if (!client) {\n throw new DimesError(\"missing_provider\", \"useDimesClient must be used within a <DimesProvider>\");\n }\n return client;\n}\n","import { useCallback, useReducer } from \"react\";\nimport { executeQuote } from \"../quote/quote\";\nimport type { HintAdjustment } from \"../quote/quote-error-hints\";\nimport type { Quote } from \"../types\";\nimport type { QuoteOptions, QuoteParams, QuoteResult } from \"../types/quote\";\nimport { useDimesClient } from \"./provider\";\n\nexport type QuotePhase = \"idle\" | \"loading-draft\" | \"draft-ready\" | \"promoting\" | \"promoted\" | \"market-moved\" | \"error\";\n\nexport interface QuoteState {\n phase: QuotePhase;\n draft?: Quote;\n quote?: Quote;\n /** @deprecated Renamed to {@link QuoteState.quote}. Still populated for backward compatibility. */\n // eslint-disable-next-line no-restricted-syntax -- intentional deprecated alias field\n offer?: Quote;\n corrections: HintAdjustment[];\n retries: number;\n error?: unknown;\n}\n\ntype Action =\n | { type: \"loading\" }\n | { type: \"draftReady\"; draft: Quote }\n | { type: \"promoting\" }\n | { type: \"marketMoved\" }\n | { type: \"done\"; result: QuoteResult }\n | { type: \"error\"; error: unknown }\n | { type: \"reset\" };\n\nfunction reducer(state: QuoteState, action: Action): QuoteState {\n switch (action.type) {\n case \"loading\":\n return { phase: \"loading-draft\", corrections: [], retries: 0 };\n case \"draftReady\":\n return { ...state, phase: \"draft-ready\", draft: action.draft };\n case \"promoting\":\n return { ...state, phase: \"promoting\" };\n case \"marketMoved\":\n return { ...state, phase: \"market-moved\" };\n case \"done\":\n return {\n phase: \"promoted\",\n quote: action.result.quote,\n offer: action.result.quote,\n corrections: action.result.corrections,\n retries: action.result.retries,\n draft: state.draft,\n };\n case \"error\":\n return { ...state, phase: \"error\", error: action.error };\n case \"reset\":\n return { phase: \"idle\", corrections: [], retries: 0 };\n default:\n return state;\n }\n}\n\nexport interface UseQuoteReturn {\n state: QuoteState;\n execute: (params: QuoteParams, options?: QuoteOptions) => Promise<QuoteResult>;\n reset: () => void;\n}\n\nexport function useQuote(): UseQuoteReturn {\n const client = useDimesClient();\n const [state, dispatch] = useReducer(reducer, {\n phase: \"idle\",\n corrections: [],\n retries: 0,\n });\n\n const execute = useCallback(\n async (params: QuoteParams, options?: QuoteOptions): Promise<QuoteResult> => {\n dispatch({ type: \"loading\" });\n\n try {\n const result = await executeQuote(client, params, {\n ...options,\n onDraftReady: (draft) => {\n dispatch({ type: \"draftReady\", draft });\n dispatch({ type: \"promoting\" });\n options?.onDraftReady?.(draft);\n },\n onMarketMoved: (event) => {\n dispatch({ type: \"marketMoved\" });\n return options?.onMarketMoved?.(event);\n },\n onCorrection: (adj) => {\n return options?.onCorrection?.(adj);\n },\n });\n\n dispatch({ type: \"done\", result });\n return result;\n } catch (err) {\n dispatch({ type: \"error\", error: err });\n throw err;\n }\n },\n [client],\n );\n\n const reset = useCallback(() => {\n dispatch({ type: \"reset\" });\n }, []);\n\n return { state, execute, reset };\n}\n","import { useCallback, useReducer, useRef } from \"react\";\nimport { buildQuoteParams } from \"../quote/build-quote-params\";\nimport { isMarketMovedError } from \"../quote/quote\";\nimport type { CreateQuoteParams, Quote } from \"../types\";\nimport type { QuoteParams } from \"../types/quote\";\nimport { useDimesClient } from \"./provider\";\n\nconst DEFAULT_MAX_RETRIES = 3;\n\n/**\n * Interactive, user-in-the-loop quote flow: draft → review → promote, pausing\n * across renders so the UI can show each step. This is the granular companion\n * to `useQuote`/`executeQuote` (which run draft→promote in one call). The steps\n * map directly onto the SDK client (`createDraftQuote`/`promoteDraftQuote`/\n * `createQuote`); on a market-moved promote failure it re-drafts and surfaces a\n * `market-moved` state so the user can review and accept the new draft.\n */\nexport type QuoteMachineState =\n | { phase: \"idle\" }\n | { phase: \"loading-draft\" }\n | { phase: \"draft-ready\"; draft: Quote; quotedAt: number }\n | { phase: \"promoting\"; draft: Quote; quotedAt: number }\n | { phase: \"promoted\"; draft: Quote; promotedQuote: Quote; correctedFrom?: Quote; quotedAt: number }\n | { phase: \"market-moved\"; originalDraft: Quote; newDraft: Quote; retryCount: number; quotedAt: number }\n | { phase: \"error\"; error: unknown; draft?: Quote };\n\ntype Action =\n | { type: \"loading\" }\n | { type: \"draftReady\"; draft: Quote; quotedAt: number }\n | { type: \"promoting\"; draft: Quote; quotedAt: number }\n | { type: \"promoted\"; draft: Quote; promotedQuote: Quote; correctedFrom?: Quote; quotedAt: number }\n | { type: \"marketMoved\"; originalDraft: Quote; newDraft: Quote; retryCount: number; quotedAt: number }\n | { type: \"error\"; error: unknown; draft?: Quote }\n | { type: \"reset\" };\n\nfunction reducer(_state: QuoteMachineState, action: Action): QuoteMachineState {\n switch (action.type) {\n case \"loading\":\n return { phase: \"loading-draft\" };\n case \"draftReady\":\n return { phase: \"draft-ready\", draft: action.draft, quotedAt: action.quotedAt };\n case \"promoting\":\n return { phase: \"promoting\", draft: action.draft, quotedAt: action.quotedAt };\n case \"promoted\":\n return {\n phase: \"promoted\",\n draft: action.draft,\n promotedQuote: action.promotedQuote,\n correctedFrom: action.correctedFrom,\n quotedAt: action.quotedAt,\n };\n case \"marketMoved\":\n return {\n phase: \"market-moved\",\n originalDraft: action.originalDraft,\n newDraft: action.newDraft,\n retryCount: action.retryCount,\n quotedAt: action.quotedAt,\n };\n case \"error\":\n return { phase: \"error\", error: action.error, draft: action.draft };\n case \"reset\":\n return { phase: \"idle\" };\n default:\n return _state;\n }\n}\n\nexport interface UseQuoteMachineOptions {\n /** Maximum number of re-draft attempts on a market-moved promote failure. Default 3. */\n maxRetries?: number;\n}\n\nexport interface UseQuoteMachineReturn {\n state: QuoteMachineState;\n /** Build params from a `QuoteParams` and fetch a draft quote. Moves to `draft-ready`. */\n getDraft: (params: QuoteParams) => Promise<void>;\n /** Promote a reviewed draft into a signed quote. On market-moved, re-drafts and surfaces `market-moved`. */\n promote: (draft: Quote, retryCount?: number) => Promise<void>;\n /** Accept a re-drafted quote after a `market-moved` and promote it. */\n acceptChanges: (newDraft: Quote, retryCount: number) => Promise<void>;\n /** Promote pre-adjusted params directly via `createQuote` (e.g. after applying a correction hint). */\n correctAndPromote: (originalDraft: Quote, adjustedParams: CreateQuoteParams) => Promise<void>;\n reset: () => void;\n}\n\nexport function useQuoteMachine(options?: UseQuoteMachineOptions): UseQuoteMachineReturn {\n const client = useDimesClient();\n const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;\n const [state, dispatch] = useReducer(reducer, { phase: \"idle\" } as QuoteMachineState);\n const lastParamsRef = useRef<CreateQuoteParams | null>(null);\n const quotedAtRef = useRef(0);\n\n const getDraft = useCallback(\n async (params: QuoteParams): Promise<void> => {\n dispatch({ type: \"loading\" });\n const quoteParams = buildQuoteParams(params);\n lastParamsRef.current = quoteParams;\n try {\n const draft = await client.createDraftQuote(quoteParams);\n\n quotedAtRef.current = Date.now();\n dispatch({ type: \"draftReady\", draft, quotedAt: quotedAtRef.current });\n } catch (err) {\n dispatch({ type: \"error\", error: err });\n }\n },\n [client],\n );\n\n const promote = useCallback(\n async (draft: Quote, retryCount = 0): Promise<void> => {\n const quotedAt = quotedAtRef.current;\n dispatch({ type: \"promoting\", draft, quotedAt });\n try {\n const promotedQuote = await client.promoteDraftQuote(draft.id);\n dispatch({ type: \"promoted\", draft, promotedQuote, quotedAt });\n } catch (err) {\n if (isMarketMovedError(err) && retryCount < maxRetries && lastParamsRef.current) {\n try {\n const newDraft = await client.createDraftQuote(lastParamsRef.current);\n // eslint-disable-next-line require-atomic-updates -- timestamp ref, no contended state\n quotedAtRef.current = Date.now();\n dispatch({\n type: \"marketMoved\",\n originalDraft: draft,\n newDraft,\n retryCount: retryCount + 1,\n quotedAt: quotedAtRef.current,\n });\n } catch (draftErr) {\n dispatch({ type: \"error\", error: draftErr, draft });\n }\n } else {\n dispatch({ type: \"error\", error: err, draft });\n }\n }\n },\n [client, maxRetries],\n );\n\n const acceptChanges = useCallback(\n async (newDraft: Quote, retryCount: number): Promise<void> => {\n await promote(newDraft, retryCount);\n },\n [promote],\n );\n\n const correctAndPromote = useCallback(\n async (originalDraft: Quote, adjustedParams: CreateQuoteParams): Promise<void> => {\n dispatch({ type: \"promoting\", draft: originalDraft, quotedAt: quotedAtRef.current });\n lastParamsRef.current = adjustedParams;\n try {\n const promotedQuote = await client.createQuote(adjustedParams);\n // eslint-disable-next-line require-atomic-updates -- timestamp ref, no contended state\n quotedAtRef.current = Date.now();\n dispatch({\n type: \"promoted\",\n draft: promotedQuote,\n promotedQuote,\n correctedFrom: originalDraft,\n quotedAt: quotedAtRef.current,\n });\n } catch (err) {\n dispatch({ type: \"error\", error: err });\n }\n },\n [client],\n );\n\n const reset = useCallback((): void => {\n dispatch({ type: \"reset\" });\n lastParamsRef.current = null;\n quotedAtRef.current = 0;\n }, []);\n\n return { state, getDraft, promote, acceptChanges, correctAndPromote, reset };\n}\n","import { useQuery, type UseQueryOptions, type UseQueryResult } from \"@tanstack/react-query\";\n// eslint-disable-next-line import-x/no-deprecated -- SearchMarketsParams imported for the deprecated shim below\nimport type { GetMarketsParams, SearchMarketsParams } from \"../client/dimes-client\";\nimport type { Market, Paginated } from \"../types\";\nimport { useDimesClient } from \"./provider\";\n\nexport function useMarkets(\n params?: GetMarketsParams,\n queryOptions?: Partial<UseQueryOptions<Paginated<Market>>>,\n): UseQueryResult<Paginated<Market>> {\n const client = useDimesClient();\n\n return useQuery({\n queryKey: [\"dimes\", \"markets\", params],\n queryFn: () => client.getMarkets(params),\n ...queryOptions,\n });\n}\n\n/**\n * @deprecated Use {@link useMarkets} with a `query` param: `useMarkets({ query })`.\n * Search is now served by `GET /markets?query=` instead of the deprecated `/markets/search` path.\n */\nexport function useSearchMarkets(\n // eslint-disable-next-line @typescript-eslint/no-deprecated, import-x/no-deprecated -- this IS the deprecated hook\n params: SearchMarketsParams,\n queryOptions?: Partial<UseQueryOptions<Paginated<Market>>>,\n): UseQueryResult<Paginated<Market>> {\n const client = useDimesClient();\n\n return useQuery({\n queryKey: [\"dimes\", \"markets\", \"search\", params],\n queryFn: () => client.getMarkets(params),\n enabled: !!params.query,\n ...queryOptions,\n });\n}\n\nexport function useMarket(ticker: string, queryOptions?: Partial<UseQueryOptions<Market>>): UseQueryResult<Market> {\n const client = useDimesClient();\n\n return useQuery({\n queryKey: [\"dimes\", \"market\", ticker],\n queryFn: () => client.getMarket(ticker),\n enabled: !!ticker,\n ...queryOptions,\n });\n}\n","import { useQuery, type Query, type UseQueryOptions, type UseQueryResult } from \"@tanstack/react-query\";\nimport type { GetPositionsParams } from \"../client/dimes-client\";\nimport type { Position } from \"../types\";\nimport { useDimesClient } from \"./provider\";\nimport { defaultReconciliationWindowMs, reconcilePolledPositions, transientPositionStatuses } from \"./ws-reconcile\";\n\nconst DEFAULT_FAST_POLL_MS = 5_000;\nconst DEFAULT_SLOW_POLL_MS = 15_000;\n\nexport interface UsePositionsOptions {\n /**\n * Appended to the query key so changing scope (e.g. switching wallet) does not serve the previous\n * scope's cached positions until a refetch. Omit to keep the default, scope-less cache key.\n */\n scope?: string | null;\n /**\n * Poll faster while any position is in a transient state (pending/closing/settling/unwinding) and\n * slower otherwise. Pass `true` for the defaults (5s / 15s) or an object to tune them.\n */\n adaptivePolling?: boolean | { fastMs?: number; slowMs?: number };\n /**\n * Defer to fresher WebSocket data: when a position was updated over the socket within the\n * reconciliation window, a slower REST poll won't overwrite it. Use with `usePositionStream` in\n * reconcile mode. Pass `true` for the default window or a number of milliseconds.\n */\n reconcile?: boolean | number;\n}\n\nfunction adaptiveRefetchInterval(\n adaptive: NonNullable<UsePositionsOptions[\"adaptivePolling\"]>,\n): (query: Query<Position[]>) => number {\n const fastMs = typeof adaptive === \"object\" ? (adaptive.fastMs ?? DEFAULT_FAST_POLL_MS) : DEFAULT_FAST_POLL_MS;\n const slowMs = typeof adaptive === \"object\" ? (adaptive.slowMs ?? DEFAULT_SLOW_POLL_MS) : DEFAULT_SLOW_POLL_MS;\n return (query) => (query.state.data?.some((p) => transientPositionStatuses.has(p.status)) ? fastMs : slowMs);\n}\n\nfunction reconcileStructuralSharing(reconcile: number | true): (oldData: unknown, newData: unknown) => Position[] {\n const windowMs = typeof reconcile === \"number\" ? reconcile : defaultReconciliationWindowMs;\n return (oldData, newData) =>\n reconcilePolledPositions(oldData as Position[] | undefined, newData as Position[], windowMs, Date.now());\n}\n\nexport function usePositions(\n params?: GetPositionsParams,\n queryOptions?: Partial<UseQueryOptions<Position[]>>,\n options?: UsePositionsOptions,\n): UseQueryResult<Position[]> {\n const client = useDimesClient();\n\n const queryKey =\n options?.scope !== undefined ? [\"dimes\", \"positions\", params, options.scope] : [\"dimes\", \"positions\", params];\n\n const config: UseQueryOptions<Position[]> = {\n queryKey,\n queryFn: () => client.getPositions(params),\n };\n\n if (options?.adaptivePolling) {\n config.refetchInterval = adaptiveRefetchInterval(options.adaptivePolling);\n }\n\n if (options?.reconcile) {\n config.structuralSharing = reconcileStructuralSharing(options.reconcile);\n }\n\n return useQuery({ ...config, ...queryOptions });\n}\n","import type { QueryClient } from \"@tanstack/react-query\";\nimport type { Market, Paginated, Position } from \"../types\";\nimport type { MarketDelta, PositionEvent } from \"../ws\";\n\n/**\n * Shared plumbing for merging WebSocket events into the React Query cache. Used by the optional\n * reconcile mode of `usePositionStream` / `useMarketStream` and the `reconcile` option on\n * `usePositions`. Kept internal so the query keys and the WS-timestamp registry stay in sync.\n */\n\nexport const positionsQueryKey = [\"dimes\", \"positions\"] as const;\n\nexport const marketsQueryKey = [\"dimes\", \"markets\"] as const;\n\nexport const defaultReconciliationWindowMs = 12_000;\n\n/** Position statuses that indicate an in-flight transition — polled faster by `adaptivePolling`. */\nexport const transientPositionStatuses: ReadonlySet<string> = new Set([\"pending\", \"closing\", \"settling\", \"unwinding\"]);\n\n/**\n * Records the last time each position id was written from a WebSocket event. Polling reconciliation\n * uses this so a slower REST poll never clobbers fresher WS data inside the reconciliation window.\n */\nexport const wsPositionTimestamps = new Map<string, number>();\n\n/** Merge a single position event into every cached positions query. */\nexport function mergePositionEvent(queryClient: QueryClient, event: PositionEvent, now: number): void {\n const position = event.data;\n queryClient.setQueriesData<Position[]>({ queryKey: positionsQueryKey }, (old) => {\n if (!old) {\n return old;\n }\n const idx = old.findIndex((p) => p.id === position.id);\n if (idx >= 0) {\n const next = [...old];\n next[idx] = position;\n return next;\n }\n if (event.type === \"position.created\") {\n return [position, ...old];\n }\n return old;\n });\n wsPositionTimestamps.set(position.id, now);\n}\n\n/**\n * `structuralSharing` for a polled positions list: keep the cached (WS-fresher) copy of any position\n * updated over the socket within `windowMs`, otherwise accept the polled copy.\n */\nexport function reconcilePolledPositions(\n oldData: Position[] | undefined,\n newData: Position[],\n windowMs: number,\n now: number,\n): Position[] {\n if (!oldData) {\n return newData;\n }\n return newData.map((polled) => {\n const wsTime = wsPositionTimestamps.get(polled.id);\n if (wsTime !== undefined && now - wsTime < windowMs) {\n const fresher = oldData.find((p) => p.id === polled.id);\n return fresher ?? polled;\n }\n if (wsTime !== undefined) {\n wsPositionTimestamps.delete(polled.id);\n }\n return polled;\n });\n}\n\n/**\n * Deep-merge a market delta onto a cached market. The nested `leverage` block must be merged rather\n * than replaced — a max-leverage delta carries only the changed leverage fields, so a shallow spread\n * would drop the constant `minBps`/`stepBps` until the next full refetch.\n */\nfunction mergeMarket(prev: Market, delta: MarketDelta): Market {\n return {\n ...prev,\n ...delta,\n leverage: delta.leverage ? { ...prev.leverage, ...delta.leverage } : prev.leverage,\n };\n}\n\n/** Merge market deltas into every cached paginated markets query (no-op for ids not present). */\nexport function mergeMarketDeltas(queryClient: QueryClient, deltas: MarketDelta[]): void {\n queryClient.setQueriesData<Paginated<Market>>({ queryKey: marketsQueryKey }, (old) => {\n if (!old) {\n return old;\n }\n const data = old.data.map((market) => {\n const delta = deltas.find((d) => d.id === market.id);\n return delta ? mergeMarket(market, delta) : market;\n });\n const changed = data.some((market, i) => market !== old.data[i]);\n return changed ? { ...old, data } : old;\n });\n}\n","import { useQuery, type UseQueryOptions, type UseQueryResult } from \"@tanstack/react-query\";\nimport type { ContractInfo } from \"../types\";\nimport { useDimesClient } from \"./provider\";\n\nexport function useContractInfo(queryOptions?: Partial<UseQueryOptions<ContractInfo>>): UseQueryResult<ContractInfo> {\n const client = useDimesClient();\n\n return useQuery({\n queryKey: [\"dimes\", \"contractInfo\"],\n queryFn: () => client.getContractInfo(),\n staleTime: Infinity,\n ...queryOptions,\n });\n}\n","import { useQuery, type UseQueryOptions, type UseQueryResult } from \"@tanstack/react-query\";\nimport type { PositionPartialCloseList } from \"../types\";\nimport { useDimesClient } from \"./provider\";\n\nexport function usePositionPartialCloses(\n positionId: string | null | undefined,\n queryOptions?: Partial<UseQueryOptions<PositionPartialCloseList>>,\n): UseQueryResult<PositionPartialCloseList> {\n const client = useDimesClient();\n\n return useQuery({\n queryKey: [\"dimes\", \"positionPartialCloses\", positionId],\n queryFn: () => {\n if (positionId == null) {\n return Promise.reject(new Error(\"positionId is required\"));\n }\n return client.getPositionPartialCloses(positionId);\n },\n enabled: Boolean(positionId),\n ...queryOptions,\n });\n}\n","import { useQuery, type UseQueryOptions, type UseQueryResult } from \"@tanstack/react-query\";\nimport type { CustomerLimit } from \"../types\";\nimport { useDimesClient } from \"./provider\";\n\n/** User trading limits (JWT auth) — `GET /user-limits`. */\nexport function useUserLimits(queryOptions?: Partial<UseQueryOptions<CustomerLimit>>): UseQueryResult<CustomerLimit> {\n const client = useDimesClient();\n\n return useQuery({\n queryKey: [\"dimes\", \"user-limits\"],\n queryFn: () => client.getUserLimits(),\n ...queryOptions,\n });\n}\n\n/** Partner-wide limits (API-key auth) — `GET /partner-limits`. */\nexport function usePartnerLimits(\n queryOptions?: Partial<UseQueryOptions<CustomerLimit>>,\n): UseQueryResult<CustomerLimit> {\n const client = useDimesClient();\n\n return useQuery({\n queryKey: [\"dimes\", \"partner-limits\"],\n queryFn: () => client.getPartnerLimits(),\n ...queryOptions,\n });\n}\n\n/** @deprecated Use {@link useUserLimits}. Alias kept for back-compat; resolves to user limits. */\nexport function useLimits(queryOptions?: Partial<UseQueryOptions<CustomerLimit>>): UseQueryResult<CustomerLimit> {\n return useUserLimits(queryOptions);\n}\n","import { useMutation, type UseMutationOptions, type UseMutationResult } from \"@tanstack/react-query\";\nimport { DimesApiError } from \"../errors/dimes-error\";\nimport { useDimesClient } from \"./provider\";\n\nconst HTTP_CONFLICT = 409;\n\nexport type CancelPositionResult = \"cancelled\" | \"already_cancelling\";\n\nexport interface UseCancelPositionOptions {\n /**\n * Treat a 409 Conflict (the position is already being cancelled) as success, resolving to\n * `\"already_cancelling\"` instead of throwing. Default false — a 409 rejects like any other error.\n */\n treatConflictAsAlreadyCancelling?: boolean;\n}\n\nexport function useCancelPosition(\n mutationOptions?: Partial<UseMutationOptions<CancelPositionResult, Error, string>>,\n options?: UseCancelPositionOptions,\n): UseMutationResult<CancelPositionResult, Error, string> {\n const client = useDimesClient();\n const treatConflictAsAlreadyCancelling = options?.treatConflictAsAlreadyCancelling ?? false;\n\n return useMutation({\n mutationFn: async (positionId: string): Promise<CancelPositionResult> => {\n try {\n await client.cancelPosition(positionId);\n return \"cancelled\";\n } catch (err) {\n if (treatConflictAsAlreadyCancelling && err instanceof DimesApiError && err.status === HTTP_CONFLICT) {\n return \"already_cancelling\";\n }\n throw err;\n }\n },\n ...mutationOptions,\n });\n}\n","import { useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { PositionSocket, type NotificationEvent, type PositionEvent } from \"../ws\";\nimport { useDimesClient } from \"./provider\";\nimport { mergePositionEvent, positionsQueryKey } from \"./ws-reconcile\";\n\nexport type StreamMode = \"raw\" | \"reconcile\";\n\nexport interface UsePositionStreamOptions {\n /** Connect the socket. Default true. Set false to gate on auth being ready. */\n enabled?: boolean;\n /**\n * `\"reconcile\"` (default) merges every event into the `usePositions` query cache so the UI updates\n * instantly; `\"raw\"` does not touch the cache and only forwards events to your callbacks.\n */\n mode?: StreamMode;\n /** Disconnect while the tab is hidden and reconnect when it becomes visible again. Default true. */\n pauseOnHidden?: boolean;\n /** Invalidate the positions query on reconnect (skipping the first connect) to catch missed events. Default true. */\n invalidateOnReconnect?: boolean;\n /** Always called with the raw (camelCased) event, in both modes. */\n onEvent?: (event: PositionEvent) => void;\n /** Called with user-gateway notification events (toasts, fill progress…). Never touches the cache. */\n onNotification?: (event: NotificationEvent) => void;\n onConnect?: () => void;\n onDisconnect?: () => void;\n onError?: (error: unknown) => void;\n}\n\nexport interface UsePositionStreamResult {\n socket: PositionSocket | null;\n connected: boolean;\n}\n\n/**\n * Subscribe to the user position WebSocket gateway. In `reconcile` mode (default) events are merged\n * into the React Query cache used by `usePositions`; in `raw` mode you handle events yourself via\n * `onEvent`. App-specific side effects (toasts, stores) belong in the callbacks, not the SDK.\n */\nexport function usePositionStream(options?: UsePositionStreamOptions): UsePositionStreamResult {\n const client = useDimesClient();\n const queryClient = useQueryClient();\n const socketRef = useRef<PositionSocket | null>(null);\n const [connected, setConnected] = useState(false);\n\n const enabled = options?.enabled ?? true;\n const mode = options?.mode ?? \"reconcile\";\n const pauseOnHidden = options?.pauseOnHidden ?? true;\n const invalidateOnReconnect = options?.invalidateOnReconnect ?? true;\n\n // Keep the latest callbacks/flags in a ref so the socket effect does not reconnect on every render.\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n useEffect(() => {\n if (!enabled) {\n return undefined;\n }\n\n const socket = new PositionSocket({\n baseUrl: client.baseUrl,\n getToken: (): string | null => client.getToken(),\n });\n socketRef.current = socket;\n\n const unsubEvent = socket.on(\"*\", (event) => {\n if (mode === \"reconcile\") {\n mergePositionEvent(queryClient, event, Date.now());\n }\n optionsRef.current?.onEvent?.(event);\n });\n\n const unsubNotification = socket.onNotification((event) => {\n optionsRef.current?.onNotification?.(event);\n });\n\n let firstConnect = true;\n const unsubConnect = socket.onConnect(() => {\n setConnected(true);\n if (firstConnect) {\n firstConnect = false;\n } else if (mode === \"reconcile\" && invalidateOnReconnect) {\n void queryClient.invalidateQueries({ queryKey: positionsQueryKey });\n }\n optionsRef.current?.onConnect?.();\n });\n\n const unsubDisconnect = socket.onDisconnect(() => {\n setConnected(false);\n optionsRef.current?.onDisconnect?.();\n });\n\n const unsubError = socket.onError((error) => {\n optionsRef.current?.onError?.(error);\n });\n\n const handleVisibility =\n pauseOnHidden && typeof document !== \"undefined\"\n ? (): void => {\n if (document.hidden) {\n socket.disconnect();\n } else {\n socket.connect();\n }\n }\n : null;\n if (handleVisibility) {\n document.addEventListener(\"visibilitychange\", handleVisibility);\n }\n\n socket.connect();\n\n return (): void => {\n if (handleVisibility) {\n document.removeEventListener(\"visibilitychange\", handleVisibility);\n }\n unsubEvent();\n unsubNotification();\n unsubConnect();\n unsubDisconnect();\n unsubError();\n socket.disconnect();\n socketRef.current = null;\n setConnected(false);\n };\n }, [client, queryClient, enabled, mode, pauseOnHidden, invalidateOnReconnect]);\n\n return { socket: socketRef.current, connected };\n}\n","import { useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { MarketSocket, type MarketDelta, type MarketEvent } from \"../ws\";\nimport { useDimesClient } from \"./provider\";\nimport type { StreamMode } from \"./use-position-stream\";\nimport { marketsQueryKey, mergeMarketDeltas } from \"./ws-reconcile\";\n\nexport interface UseMarketStreamOptions {\n /** Connect the socket. Default true. */\n enabled?: boolean;\n /**\n * `\"reconcile\"` (default) merges `eligibility_changed` / `max_leverage_changed` deltas into the\n * `useMarkets` query cache; `\"raw\"` only forwards events. `market.discovered` events are never\n * injected into the paginated cache (that would pollute server-filtered views) — handle them via\n * `onEvent` in either mode.\n */\n mode?: StreamMode;\n /** Disconnect while the tab is hidden and reconnect when visible again. Default true. */\n pauseOnHidden?: boolean;\n /** Invalidate the markets query on reconnect (skipping the first connect). Default true. */\n invalidateOnReconnect?: boolean;\n /** Always called with the raw (camelCased) event, in both modes. */\n onEvent?: (event: MarketEvent) => void;\n onConnect?: () => void;\n onDisconnect?: () => void;\n onError?: (error: unknown) => void;\n}\n\nexport interface UseMarketStreamResult {\n socket: MarketSocket | null;\n connected: boolean;\n}\n\n/**\n * Subscribe to the user market WebSocket gateway. In `reconcile` mode (default) eligibility and\n * max-leverage deltas are deep-merged into the `useMarkets` cache; discovered markets are forwarded\n * to `onEvent` for the app to route (e.g. a \"new markets\" strip).\n */\nexport function useMarketStream(options?: UseMarketStreamOptions): UseMarketStreamResult {\n const client = useDimesClient();\n const queryClient = useQueryClient();\n const socketRef = useRef<MarketSocket | null>(null);\n const [connected, setConnected] = useState(false);\n\n const enabled = options?.enabled ?? true;\n const mode = options?.mode ?? \"reconcile\";\n const pauseOnHidden = options?.pauseOnHidden ?? true;\n const invalidateOnReconnect = options?.invalidateOnReconnect ?? true;\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n useEffect(() => {\n if (!enabled) {\n return undefined;\n }\n\n const socket = new MarketSocket({\n baseUrl: client.baseUrl,\n getToken: (): string | null => client.getToken(),\n });\n socketRef.current = socket;\n\n const unsubEvent = socket.on(\"*\", (event) => {\n if (mode === \"reconcile\" && event.type !== \"market.discovered\") {\n mergeMarketDeltas(queryClient, event.data as MarketDelta[]);\n }\n optionsRef.current?.onEvent?.(event);\n });\n\n let firstConnect = true;\n const unsubConnect = socket.onConnect(() => {\n setConnected(true);\n if (firstConnect) {\n firstConnect = false;\n } else if (mode === \"reconcile\" && invalidateOnReconnect) {\n void queryClient.invalidateQueries({ queryKey: marketsQueryKey });\n }\n optionsRef.current?.onConnect?.();\n });\n\n const unsubDisconnect = socket.onDisconnect(() => {\n setConnected(false);\n optionsRef.current?.onDisconnect?.();\n });\n\n const unsubError = socket.onError((error) => {\n optionsRef.current?.onError?.(error);\n });\n\n const handleVisibility =\n pauseOnHidden && typeof document !== \"undefined\"\n ? (): void => {\n if (document.hidden) {\n socket.disconnect();\n } else {\n socket.connect();\n }\n }\n : null;\n if (handleVisibility) {\n document.addEventListener(\"visibilitychange\", handleVisibility);\n }\n\n socket.connect();\n\n return (): void => {\n if (handleVisibility) {\n document.removeEventListener(\"visibilitychange\", handleVisibility);\n }\n unsubEvent();\n unsubConnect();\n unsubDisconnect();\n unsubError();\n socket.disconnect();\n socketRef.current = null;\n setConnected(false);\n };\n }, [client, queryClient, enabled, mode, pauseOnHidden, invalidateOnReconnect]);\n\n return { socket: socketRef.current, connected };\n}\n"]}
|