@dimes-dot-fi/sdk 1.5.0 → 2.0.1

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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +88 -19
  3. package/dist/{aliases-ByZ2DcA5.d.cts → aliases-BJyM8ydu.d.cts} +54 -4
  4. package/dist/{aliases-ByZ2DcA5.d.ts → aliases-BJyM8ydu.d.ts} +54 -4
  5. package/dist/{chunk-UHQZSMUD.cjs → chunk-53U53KZ2.cjs} +5 -1
  6. package/dist/chunk-53U53KZ2.cjs.map +1 -0
  7. package/dist/chunk-5VHDXPRV.mjs +240 -0
  8. package/dist/chunk-5VHDXPRV.mjs.map +1 -0
  9. package/dist/{chunk-Y5WQ3UWF.cjs → chunk-7SAMK7CS.cjs} +18 -12
  10. package/dist/chunk-7SAMK7CS.cjs.map +1 -0
  11. package/dist/chunk-FAW2C5AM.cjs +240 -0
  12. package/dist/chunk-FAW2C5AM.cjs.map +1 -0
  13. package/dist/{chunk-4MO3HKMS.mjs → chunk-PK2PRTQW.mjs} +5 -1
  14. package/dist/chunk-PK2PRTQW.mjs.map +1 -0
  15. package/dist/{chunk-3OPRSKCY.mjs → chunk-T67Z74J3.mjs} +17 -11
  16. package/dist/chunk-T67Z74J3.mjs.map +1 -0
  17. package/dist/contract/index.cjs +5522 -293
  18. package/dist/contract/index.cjs.map +1 -1
  19. package/dist/contract/index.d.cts +68 -10
  20. package/dist/contract/index.d.ts +68 -10
  21. package/dist/contract/index.mjs +5523 -294
  22. package/dist/contract/index.mjs.map +1 -1
  23. package/dist/{dimes-client-B-thu7VQ.d.cts → dimes-client-DYFvnZUx.d.ts} +41 -9
  24. package/dist/{dimes-client-CerC9mTr.d.ts → dimes-client-DZPhU1CG.d.cts} +41 -9
  25. package/dist/{dimes-error-BY5qVGZC.d.cts → dimes-error-BlQWPqhQ.d.cts} +2 -2
  26. package/dist/{dimes-error-CrvPuFzB.d.ts → dimes-error-DBKV5bfr.d.ts} +2 -2
  27. package/dist/index.cjs +78 -8
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +23 -14
  30. package/dist/index.d.ts +23 -14
  31. package/dist/index.mjs +78 -8
  32. package/dist/index.mjs.map +1 -1
  33. package/dist/quote-BFNgVsY-.d.ts +39 -0
  34. package/dist/quote-CanwfT9m.d.cts +39 -0
  35. package/dist/react/index.cjs +414 -16
  36. package/dist/react/index.cjs.map +1 -1
  37. package/dist/react/index.d.cts +165 -8
  38. package/dist/react/index.d.ts +165 -8
  39. package/dist/react/index.mjs +413 -15
  40. package/dist/react/index.mjs.map +1 -1
  41. package/dist/{types-2bGyrtqd.d.cts → types-ClHQbIcY.d.ts} +3 -3
  42. package/dist/{types-CAuPxEwO.d.ts → types-Co-2bQSi.d.cts} +3 -3
  43. package/dist/ws/index.cjs +4 -230
  44. package/dist/ws/index.cjs.map +1 -1
  45. package/dist/ws/index.d.cts +3 -3
  46. package/dist/ws/index.d.ts +3 -3
  47. package/dist/ws/index.mjs +5 -231
  48. package/dist/ws/index.mjs.map +1 -1
  49. package/package.json +43 -4
  50. package/dist/chunk-3OPRSKCY.mjs.map +0 -1
  51. package/dist/chunk-4MO3HKMS.mjs.map +0 -1
  52. package/dist/chunk-UHQZSMUD.cjs.map +0 -1
  53. package/dist/chunk-Y5WQ3UWF.cjs.map +0 -1
  54. package/dist/quote-Czq3Selh.d.ts +0 -30
  55. package/dist/quote-quIOosIv.d.cts +0 -30
package/dist/index.d.cts CHANGED
@@ -1,10 +1,10 @@
1
- export { A as ApiKeyAuth, a as ApiKeyAuthOptions, b as AuthProvider, C as CorrectedField, D as DimesClient, c as DimesClientOptions, G as GetFeeRatesParams, d as GetMarketsParams, e as GetPositionsParams, H as HintAdjustment, J as JwtAuth, f as JwtAuthOptions, M as MarketSort, P as Paginated, Q as QuoteHint, h as hintAdjustment, m as marketMovedCodes, q as quoteErrorHint } from './dimes-client-B-thu7VQ.cjs';
2
- export { D as DimesApiError, a as DimesContractError, b as DimesError } from './dimes-error-BY5qVGZC.cjs';
3
- import { C as CreateOfferParams, O as Offer, M as Market, P as Position } from './aliases-ByZ2DcA5.cjs';
4
- export { a as CamelizeKeys, b as CloseAttempt, c as ClosedPosition, d as ContractInfo, e as CreateTokenResult, f as CustomerLimit, F as FeeRates, g as FeeRatesMarket, h as FeeRatesOriginationTier, i as FeeReport, j as FeeReportParams, k as MarketFees, l as MarketLeverage, m as MarketMaxLeveragePerNotional, n as MarketPrices, o as MarketSidedEligibility, p as MarketSidedMaxLeveragePerNotional, q as OpenPosition, r as OriginationTier, s as PositionClosedFees, t as PositionCurrent, u as PositionEntry, v as PositionFailure, w as PositionOpenFees, x as PositionResult, y as PositionRisk, z as PositionTiming, A as PositionUnwind, B as PositionUnwindList, D as isClosedPosition, E as isOpenPosition, G as leverageMaxBps } from './aliases-ByZ2DcA5.cjs';
5
- import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from './quote-quIOosIv.cjs';
6
- export { M as MarketMovedEvent, S as Side } from './quote-quIOosIv.cjs';
7
- export { P as PositionEvent, a as PositionEventType, p as positionEventTypes } from './types-2bGyrtqd.cjs';
1
+ export { A as ApiKeyAuth, a as ApiKeyAuthOptions, b as AuthProvider, C as CorrectedField, D as DimesClient, c as DimesClientOptions, G as GetFeeRatesParams, d as GetMarketsParams, e as GetPositionsParams, H as HintAdjustment, J as JwtAuth, f as JwtAuthOptions, M as MarketExpand, g as MarketSort, P as Paginated, h as PositionStatus, Q as QuoteHint, S as SearchMarketsParams, i as hintAdjustment, m as marketMovedCodes, q as quoteErrorHint } from './dimes-client-DZPhU1CG.cjs';
2
+ export { a as DimesApiError, D as DimesContractError, b as DimesError } from './dimes-error-BlQWPqhQ.cjs';
3
+ import { C as CreateQuoteParams, Q as Quote, M as Market, P as Position } from './aliases-BJyM8ydu.cjs';
4
+ export { h as CamelizeKeys, i as CloseAttempt, j as ClosedPosition, d as ContractInfo, k as CreateOfferParams, l as CreateTokenResult, e as CustomerLimit, F as FeeRates, m as FeeRatesMarket, n as FeeRatesOriginationTier, g as FeeReport, f as FeeReportParams, o as MarketFees, b as MarketLeverage, p as MarketMaxLeveragePerNotional, q as MarketPrices, r as MarketSidedEligibility, s as MarketSidedMaxLeveragePerNotional, O as Offer, t as OpenPosition, u as OriginationTier, v as PendingOperation, w as PositionClosedFees, x as PositionCurrent, y as PositionEntry, z as PositionFailure, A as PositionOpenFees, B as PositionResult, D as PositionRisk, E as PositionTiming, G as PositionUnwind, H as PositionUnwindList, I as isClosedPosition, J as isOpenPosition, K as leverageMaxBps } from './aliases-BJyM8ydu.cjs';
5
+ import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from './quote-CanwfT9m.cjs';
6
+ export { M as MarketMovedEvent, S as Side } from './quote-CanwfT9m.cjs';
7
+ export { P as PositionEvent, a as PositionEventType, p as positionEventTypes } from './types-Co-2bQSi.cjs';
8
8
 
9
9
  type Params = Record<string, unknown> | null;
10
10
 
@@ -12,13 +12,14 @@ declare function resolveFriendlyMessage(code: string, params: Params): string |
12
12
  declare function formatErrorMessage(code: string, params: Params): string;
13
13
 
14
14
  interface QuoteClient {
15
- createDraftQuote(params: CreateOfferParams): Promise<Offer>;
16
- promoteDraftQuote(draftId: string): Promise<Offer>;
17
- createQuote(params: CreateOfferParams): Promise<Offer>;
15
+ createDraftQuote(params: CreateQuoteParams): Promise<Quote>;
16
+ promoteDraftQuote(draftId: string): Promise<Quote>;
17
+ createQuote(params: CreateQuoteParams): Promise<Quote>;
18
18
  }
19
+ declare function isMarketMovedError(err: unknown): boolean;
19
20
  declare function executeQuote(client: QuoteClient, params: QuoteParams, options?: QuoteOptions): Promise<QuoteResult>;
20
21
 
21
- declare function buildQuoteParams(params: QuoteParams, stepBps?: number): CreateOfferParams;
22
+ declare function buildQuoteParams(params: QuoteParams, stepBps?: number): CreateQuoteParams;
22
23
 
23
24
  type Side = "yes" | "no";
24
25
  interface SideEligibility {
@@ -98,7 +99,7 @@ declare function getOriginationFeeBreakdown(position: Position): OriginationFeeB
98
99
  /**
99
100
  * Inputs to the Polymarket trading-fee curve. All rates are basis points; the
100
101
  * caller fetches `feeRateBps`, `feeExponent`, and `builderTakerFeeRateBps` from
101
- * the `fee-rates` API (snapshotted server-side as `Offer.polymarketFeeRateBps`
102
+ * the `fee-rates` API (snapshotted server-side as `Quote.polymarketFeeRateBps`
102
103
  * / `polymarketFeeExponent` / `polymarketBuilderFeeRateBps`).
103
104
  */
104
105
  interface PolymarketTradingFeeInput {
@@ -132,7 +133,7 @@ declare function computePolymarketTradingFee(input: PolymarketTradingFeeInput):
132
133
  * at $1 on a win, so token units are numerically equal to USDC units.
133
134
  *
134
135
  * `tokens = notionalUsd / entryPrice`, then scaled down by `slippageBps`.
135
- * Floored to whole token units. This is an at-quote estimate of the offer's
136
+ * Floored to whole token units. This is an at-quote estimate of the quote's
136
137
  * `minExpectedPositionTokenUnits`; the server is authoritative.
137
138
  */
138
139
  declare function expectedPositionTokenUnits(notionalUsdcUnits: number, entryPriceUsd: number, slippageBps?: number): number;
@@ -192,4 +193,12 @@ interface MaxGainResult {
192
193
  */
193
194
  declare function computeMaxGain(input: MaxGainInput): MaxGainResult;
194
195
 
195
- export { CreateOfferParams, Market, type MaxGainInput, type MaxGainResult, Offer, type OriginationFeeBreakdown, type OriginationFeeTier, type PolymarketTradingFeeInput, Position, QuoteOptions, QuoteParams, QuoteResult, type SideEligibility, type SidedEligibility, buildQuoteParams, computeMaxGain, computeOriginationFeeUsdcUnits, computePolymarketTradingFee, defaultSide, estimateLiquidationPrice, executeQuote, expectedPositionTokenUnits, formatErrorMessage, getOriginationFeeBreakdown, getSidedEligibility, isFullyClosed, isFullyOpen, maxLeverageBpsAtNotional, maxViableLeverageBpsForCollateral, rejectionReasonShort, rejectionReasonText, resolveFriendlyMessage, resolveOriginationFeeBps, resolveProtocolOriginationFeeBps };
196
+ declare const tokenUnitsPerToken = 1000000n;
197
+ declare const partialCloseMinTokens = 5n;
198
+ declare const partialCloseMinFractionBps = 2000n;
199
+ declare function closeTokenUnitsForPct(currentTokenUnits: bigint, pctBps: number): bigint;
200
+ declare function pctBpsForCloseTokenUnits(currentTokenUnits: bigint, closeTokenUnits: bigint): number;
201
+ declare function fallbackMinPartialCloseTokenUnits(originalTokenUnits: bigint): bigint;
202
+ declare function clampCloseTokenUnits(value: bigint, min: bigint, max: bigint): bigint;
203
+
204
+ export { CreateQuoteParams, Market, type MaxGainInput, type MaxGainResult, type OriginationFeeBreakdown, type OriginationFeeTier, type PolymarketTradingFeeInput, Position, Quote, QuoteOptions, QuoteParams, QuoteResult, type SideEligibility, type SidedEligibility, buildQuoteParams, clampCloseTokenUnits, closeTokenUnitsForPct, computeMaxGain, computeOriginationFeeUsdcUnits, computePolymarketTradingFee, defaultSide, estimateLiquidationPrice, executeQuote, expectedPositionTokenUnits, fallbackMinPartialCloseTokenUnits, formatErrorMessage, getOriginationFeeBreakdown, getSidedEligibility, isFullyClosed, isFullyOpen, isMarketMovedError, maxLeverageBpsAtNotional, maxViableLeverageBpsForCollateral, partialCloseMinFractionBps, partialCloseMinTokens, pctBpsForCloseTokenUnits, rejectionReasonShort, rejectionReasonText, resolveFriendlyMessage, resolveOriginationFeeBps, resolveProtocolOriginationFeeBps, tokenUnitsPerToken };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- export { A as ApiKeyAuth, a as ApiKeyAuthOptions, b as AuthProvider, C as CorrectedField, D as DimesClient, c as DimesClientOptions, G as GetFeeRatesParams, d as GetMarketsParams, e as GetPositionsParams, H as HintAdjustment, J as JwtAuth, f as JwtAuthOptions, M as MarketSort, P as Paginated, Q as QuoteHint, h as hintAdjustment, m as marketMovedCodes, q as quoteErrorHint } from './dimes-client-CerC9mTr.js';
2
- export { D as DimesApiError, a as DimesContractError, b as DimesError } from './dimes-error-CrvPuFzB.js';
3
- import { C as CreateOfferParams, O as Offer, M as Market, P as Position } from './aliases-ByZ2DcA5.js';
4
- export { a as CamelizeKeys, b as CloseAttempt, c as ClosedPosition, d as ContractInfo, e as CreateTokenResult, f as CustomerLimit, F as FeeRates, g as FeeRatesMarket, h as FeeRatesOriginationTier, i as FeeReport, j as FeeReportParams, k as MarketFees, l as MarketLeverage, m as MarketMaxLeveragePerNotional, n as MarketPrices, o as MarketSidedEligibility, p as MarketSidedMaxLeveragePerNotional, q as OpenPosition, r as OriginationTier, s as PositionClosedFees, t as PositionCurrent, u as PositionEntry, v as PositionFailure, w as PositionOpenFees, x as PositionResult, y as PositionRisk, z as PositionTiming, A as PositionUnwind, B as PositionUnwindList, D as isClosedPosition, E as isOpenPosition, G as leverageMaxBps } from './aliases-ByZ2DcA5.js';
5
- import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from './quote-Czq3Selh.js';
6
- export { M as MarketMovedEvent, S as Side } from './quote-Czq3Selh.js';
7
- export { P as PositionEvent, a as PositionEventType, p as positionEventTypes } from './types-CAuPxEwO.js';
1
+ export { A as ApiKeyAuth, a as ApiKeyAuthOptions, b as AuthProvider, C as CorrectedField, D as DimesClient, c as DimesClientOptions, G as GetFeeRatesParams, d as GetMarketsParams, e as GetPositionsParams, H as HintAdjustment, J as JwtAuth, f as JwtAuthOptions, M as MarketExpand, g as MarketSort, P as Paginated, h as PositionStatus, Q as QuoteHint, S as SearchMarketsParams, i as hintAdjustment, m as marketMovedCodes, q as quoteErrorHint } from './dimes-client-DYFvnZUx.js';
2
+ export { a as DimesApiError, D as DimesContractError, b as DimesError } from './dimes-error-DBKV5bfr.js';
3
+ import { C as CreateQuoteParams, Q as Quote, M as Market, P as Position } from './aliases-BJyM8ydu.js';
4
+ export { h as CamelizeKeys, i as CloseAttempt, j as ClosedPosition, d as ContractInfo, k as CreateOfferParams, l as CreateTokenResult, e as CustomerLimit, F as FeeRates, m as FeeRatesMarket, n as FeeRatesOriginationTier, g as FeeReport, f as FeeReportParams, o as MarketFees, b as MarketLeverage, p as MarketMaxLeveragePerNotional, q as MarketPrices, r as MarketSidedEligibility, s as MarketSidedMaxLeveragePerNotional, O as Offer, t as OpenPosition, u as OriginationTier, v as PendingOperation, w as PositionClosedFees, x as PositionCurrent, y as PositionEntry, z as PositionFailure, A as PositionOpenFees, B as PositionResult, D as PositionRisk, E as PositionTiming, G as PositionUnwind, H as PositionUnwindList, I as isClosedPosition, J as isOpenPosition, K as leverageMaxBps } from './aliases-BJyM8ydu.js';
5
+ import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from './quote-BFNgVsY-.js';
6
+ export { M as MarketMovedEvent, S as Side } from './quote-BFNgVsY-.js';
7
+ export { P as PositionEvent, a as PositionEventType, p as positionEventTypes } from './types-ClHQbIcY.js';
8
8
 
9
9
  type Params = Record<string, unknown> | null;
10
10
 
@@ -12,13 +12,14 @@ declare function resolveFriendlyMessage(code: string, params: Params): string |
12
12
  declare function formatErrorMessage(code: string, params: Params): string;
13
13
 
14
14
  interface QuoteClient {
15
- createDraftQuote(params: CreateOfferParams): Promise<Offer>;
16
- promoteDraftQuote(draftId: string): Promise<Offer>;
17
- createQuote(params: CreateOfferParams): Promise<Offer>;
15
+ createDraftQuote(params: CreateQuoteParams): Promise<Quote>;
16
+ promoteDraftQuote(draftId: string): Promise<Quote>;
17
+ createQuote(params: CreateQuoteParams): Promise<Quote>;
18
18
  }
19
+ declare function isMarketMovedError(err: unknown): boolean;
19
20
  declare function executeQuote(client: QuoteClient, params: QuoteParams, options?: QuoteOptions): Promise<QuoteResult>;
20
21
 
21
- declare function buildQuoteParams(params: QuoteParams, stepBps?: number): CreateOfferParams;
22
+ declare function buildQuoteParams(params: QuoteParams, stepBps?: number): CreateQuoteParams;
22
23
 
23
24
  type Side = "yes" | "no";
24
25
  interface SideEligibility {
@@ -98,7 +99,7 @@ declare function getOriginationFeeBreakdown(position: Position): OriginationFeeB
98
99
  /**
99
100
  * Inputs to the Polymarket trading-fee curve. All rates are basis points; the
100
101
  * caller fetches `feeRateBps`, `feeExponent`, and `builderTakerFeeRateBps` from
101
- * the `fee-rates` API (snapshotted server-side as `Offer.polymarketFeeRateBps`
102
+ * the `fee-rates` API (snapshotted server-side as `Quote.polymarketFeeRateBps`
102
103
  * / `polymarketFeeExponent` / `polymarketBuilderFeeRateBps`).
103
104
  */
104
105
  interface PolymarketTradingFeeInput {
@@ -132,7 +133,7 @@ declare function computePolymarketTradingFee(input: PolymarketTradingFeeInput):
132
133
  * at $1 on a win, so token units are numerically equal to USDC units.
133
134
  *
134
135
  * `tokens = notionalUsd / entryPrice`, then scaled down by `slippageBps`.
135
- * Floored to whole token units. This is an at-quote estimate of the offer's
136
+ * Floored to whole token units. This is an at-quote estimate of the quote's
136
137
  * `minExpectedPositionTokenUnits`; the server is authoritative.
137
138
  */
138
139
  declare function expectedPositionTokenUnits(notionalUsdcUnits: number, entryPriceUsd: number, slippageBps?: number): number;
@@ -192,4 +193,12 @@ interface MaxGainResult {
192
193
  */
193
194
  declare function computeMaxGain(input: MaxGainInput): MaxGainResult;
194
195
 
195
- export { CreateOfferParams, Market, type MaxGainInput, type MaxGainResult, Offer, type OriginationFeeBreakdown, type OriginationFeeTier, type PolymarketTradingFeeInput, Position, QuoteOptions, QuoteParams, QuoteResult, type SideEligibility, type SidedEligibility, buildQuoteParams, computeMaxGain, computeOriginationFeeUsdcUnits, computePolymarketTradingFee, defaultSide, estimateLiquidationPrice, executeQuote, expectedPositionTokenUnits, formatErrorMessage, getOriginationFeeBreakdown, getSidedEligibility, isFullyClosed, isFullyOpen, maxLeverageBpsAtNotional, maxViableLeverageBpsForCollateral, rejectionReasonShort, rejectionReasonText, resolveFriendlyMessage, resolveOriginationFeeBps, resolveProtocolOriginationFeeBps };
196
+ declare const tokenUnitsPerToken = 1000000n;
197
+ declare const partialCloseMinTokens = 5n;
198
+ declare const partialCloseMinFractionBps = 2000n;
199
+ declare function closeTokenUnitsForPct(currentTokenUnits: bigint, pctBps: number): bigint;
200
+ declare function pctBpsForCloseTokenUnits(currentTokenUnits: bigint, closeTokenUnits: bigint): number;
201
+ declare function fallbackMinPartialCloseTokenUnits(originalTokenUnits: bigint): bigint;
202
+ declare function clampCloseTokenUnits(value: bigint, min: bigint, max: bigint): bigint;
203
+
204
+ export { CreateQuoteParams, Market, type MaxGainInput, type MaxGainResult, type OriginationFeeBreakdown, type OriginationFeeTier, type PolymarketTradingFeeInput, Position, Quote, QuoteOptions, QuoteParams, QuoteResult, type SideEligibility, type SidedEligibility, buildQuoteParams, clampCloseTokenUnits, closeTokenUnitsForPct, computeMaxGain, computeOriginationFeeUsdcUnits, computePolymarketTradingFee, defaultSide, estimateLiquidationPrice, executeQuote, expectedPositionTokenUnits, fallbackMinPartialCloseTokenUnits, formatErrorMessage, getOriginationFeeBreakdown, getSidedEligibility, isFullyClosed, isFullyOpen, isMarketMovedError, maxLeverageBpsAtNotional, maxViableLeverageBpsForCollateral, partialCloseMinFractionBps, partialCloseMinTokens, pctBpsForCloseTokenUnits, rejectionReasonShort, rejectionReasonText, resolveFriendlyMessage, resolveOriginationFeeBps, resolveProtocolOriginationFeeBps, tokenUnitsPerToken };
package/dist/index.mjs CHANGED
@@ -2,9 +2,10 @@ import {
2
2
  buildQuoteParams,
3
3
  executeQuote,
4
4
  hintAdjustment,
5
+ isMarketMovedError,
5
6
  marketMovedCodes,
6
7
  quoteErrorHint
7
- } from "./chunk-3OPRSKCY.mjs";
8
+ } from "./chunk-T67Z74J3.mjs";
8
9
  import {
9
10
  DimesApiError,
10
11
  DimesContractError,
@@ -14,7 +15,7 @@ import {
14
15
  } from "./chunk-PZCBUVPD.mjs";
15
16
  import {
16
17
  positionEventTypes
17
- } from "./chunk-4MO3HKMS.mjs";
18
+ } from "./chunk-PK2PRTQW.mjs";
18
19
 
19
20
  // src/client/dimes-client.ts
20
21
  import { decamelizeKeys } from "humps";
@@ -132,16 +133,25 @@ function buildQueryFromEntries(entries) {
132
133
  return `?${search.toString()}`;
133
134
  }
134
135
  var DimesClient = class {
136
+ /** The resolved API base URL. Useful for constructing WebSocket clients against the same host. */
137
+ baseUrl;
135
138
  http;
139
+ auth;
136
140
  constructor(options) {
141
+ this.baseUrl = options.baseUrl ?? "https://api.dimes.fi";
142
+ this.auth = options.auth;
137
143
  this.http = new HttpClient({
138
- baseUrl: options.baseUrl ?? "https://api.dimes.fi",
144
+ baseUrl: this.baseUrl,
139
145
  auth: options.auth,
140
146
  fetch: options.fetch,
141
147
  maxRetries: options.maxRetries,
142
148
  maxRetryDelayMs: options.maxRetryDelayMs
143
149
  });
144
150
  }
151
+ /** Synchronously return the current cached JWT, or null. Returns null if the auth provider does not expose one. */
152
+ getToken() {
153
+ return this.auth.getToken?.() ?? null;
154
+ }
145
155
  async getMarkets(params) {
146
156
  const query = params ? buildQueryFromEntries(Object.entries(params)) : "";
147
157
  return this.http.request(`/v1/prediction-markets/markets${query}`);
@@ -149,6 +159,10 @@ var DimesClient = class {
149
159
  async getMarket(ticker) {
150
160
  return this.http.request(`/v1/prediction-markets/markets/${encodeURIComponent(ticker)}`);
151
161
  }
162
+ async searchMarkets(params) {
163
+ const query = buildQueryFromEntries(Object.entries(params));
164
+ return this.http.request(`/v1/prediction-markets/markets/search${query}`);
165
+ }
152
166
  async createDraftQuote(params) {
153
167
  return this.http.request("/v1/prediction-markets/draft-quotes", {
154
168
  method: "POST",
@@ -176,15 +190,26 @@ var DimesClient = class {
176
190
  );
177
191
  }
178
192
  async cancelPosition(positionId) {
179
- await this.http.request(`/v1/prediction-markets/positions/${encodeURIComponent(positionId)}/cancel`, {
180
- method: "POST"
193
+ await this.http.request(`/v1/prediction-markets/positions/${encodeURIComponent(positionId)}`, {
194
+ method: "DELETE"
181
195
  });
182
196
  }
183
197
  async getContractInfo() {
184
198
  return this.http.request("/v1/prediction-markets/contract-info");
185
199
  }
200
+ async getUserLimits() {
201
+ return this.http.request("/v1/prediction-markets/user-limits");
202
+ }
203
+ async getPartnerLimits() {
204
+ return this.http.request("/v1/prediction-markets/partner-limits");
205
+ }
206
+ /**
207
+ * @deprecated The `/limits` path was never served by the API. Use {@link getUserLimits}
208
+ * (JWT/user context) or {@link getPartnerLimits} (API-key/partner context). This alias
209
+ * forwards to `getUserLimits` and will be removed in a future major.
210
+ */
186
211
  async getLimits() {
187
- return this.http.request("/v1/prediction-markets/limits");
212
+ return this.getUserLimits();
188
213
  }
189
214
  async getFeeRates(params) {
190
215
  const query = params ? buildQueryFromEntries(Object.entries(params)) : "";
@@ -220,6 +245,9 @@ var ApiKeyAuth = class {
220
245
  }
221
246
  return { Authorization: `Bearer ${this.jwt}` };
222
247
  }
248
+ getToken() {
249
+ return this.jwt;
250
+ }
223
251
  async refresh() {
224
252
  if (this.refreshPromise) {
225
253
  await this.refreshPromise;
@@ -237,7 +265,7 @@ var ApiKeyAuth = class {
237
265
  method: "POST",
238
266
  headers: {
239
267
  "Content-Type": "application/json",
240
- Authorization: `Bearer ${this.apiKey}`
268
+ Authorization: `Api-Key ${this.apiKey}`
241
269
  },
242
270
  body: JSON.stringify({ wallet_address: this.walletAddress })
243
271
  });
@@ -267,6 +295,9 @@ var JwtAuth = class {
267
295
  }
268
296
  return { Authorization: `Bearer ${this.jwt}` };
269
297
  }
298
+ getToken() {
299
+ return this.jwt;
300
+ }
270
301
  async refresh() {
271
302
  if (this.refreshPromise) {
272
303
  await this.refreshPromise;
@@ -517,6 +548,37 @@ function computeMaxGain(input) {
517
548
  netMaxGainUsdcUnits
518
549
  };
519
550
  }
551
+
552
+ // src/utils/partial-close.ts
553
+ var BPS_DIVISOR3 = 1e4;
554
+ var BPS_DIVISOR_BIG = 10000n;
555
+ var tokenUnitsPerToken = 1000000n;
556
+ var partialCloseMinTokens = 5n;
557
+ var partialCloseMinFractionBps = 2000n;
558
+ function closeTokenUnitsForPct(currentTokenUnits, pctBps) {
559
+ const clampedBps = BigInt(Math.max(0, Math.min(BPS_DIVISOR3, Math.round(pctBps))));
560
+ return currentTokenUnits * clampedBps / BPS_DIVISOR_BIG;
561
+ }
562
+ function pctBpsForCloseTokenUnits(currentTokenUnits, closeTokenUnits) {
563
+ if (currentTokenUnits <= 0n) {
564
+ return 0;
565
+ }
566
+ return Number(closeTokenUnits * BPS_DIVISOR_BIG / currentTokenUnits);
567
+ }
568
+ function fallbackMinPartialCloseTokenUnits(originalTokenUnits) {
569
+ const floorTokens = partialCloseMinTokens * tokenUnitsPerToken;
570
+ const floorFraction = originalTokenUnits * partialCloseMinFractionBps / BPS_DIVISOR_BIG;
571
+ return floorFraction > floorTokens ? floorFraction : floorTokens;
572
+ }
573
+ function clampCloseTokenUnits(value, min, max) {
574
+ if (value < min) {
575
+ return min;
576
+ }
577
+ if (value > max) {
578
+ return max;
579
+ }
580
+ return value;
581
+ }
520
582
  export {
521
583
  ApiKeyAuth,
522
584
  DimesApiError,
@@ -525,6 +587,8 @@ export {
525
587
  DimesError,
526
588
  JwtAuth,
527
589
  buildQuoteParams,
590
+ clampCloseTokenUnits,
591
+ closeTokenUnitsForPct,
528
592
  computeMaxGain,
529
593
  computeOriginationFeeUsdcUnits,
530
594
  computePolymarketTradingFee,
@@ -532,6 +596,7 @@ export {
532
596
  estimateLiquidationPrice,
533
597
  executeQuote,
534
598
  expectedPositionTokenUnits,
599
+ fallbackMinPartialCloseTokenUnits,
535
600
  formatErrorMessage,
536
601
  getOriginationFeeBreakdown,
537
602
  getSidedEligibility,
@@ -539,17 +604,22 @@ export {
539
604
  isClosedPosition,
540
605
  isFullyClosed,
541
606
  isFullyOpen,
607
+ isMarketMovedError,
542
608
  isOpenPosition,
543
609
  leverageMaxBps,
544
610
  marketMovedCodes,
545
611
  maxLeverageBpsAtNotional,
546
612
  maxViableLeverageBpsForCollateral,
613
+ partialCloseMinFractionBps,
614
+ partialCloseMinTokens,
615
+ pctBpsForCloseTokenUnits,
547
616
  positionEventTypes,
548
617
  quoteErrorHint,
549
618
  rejectionReasonShort,
550
619
  rejectionReasonText,
551
620
  resolveFriendlyMessage,
552
621
  resolveOriginationFeeBps,
553
- resolveProtocolOriginationFeeBps
622
+ resolveProtocolOriginationFeeBps,
623
+ tokenUnitsPerToken
554
624
  };
555
625
  //# sourceMappingURL=index.mjs.map
@@ -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"],"sourcesContent":["import { decamelizeKeys } from \"humps\";\nimport type {\n ContractInfo,\n CreateOfferParams,\n CustomerLimit,\n FeeRates,\n FeeReport,\n FeeReportParams,\n Market,\n Offer,\n Paginated,\n Position,\n PositionTransactions,\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 interface GetMarketsParams {\n cursor?: string;\n limit?: number;\n category?: string;\n status?: string;\n provider?: \"polymarket\" | \"kalshi\";\n sort?: MarketSort;\n}\n\nexport interface GetPositionsParams {\n cursor?: string;\n limit?: number;\n status?: \"open\" | \"closed\";\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 private readonly http: HttpClient;\n\n constructor(options: DimesClientOptions) {\n this.http = new HttpClient({\n baseUrl: options.baseUrl ?? \"https://api.dimes.fi\",\n auth: options.auth,\n fetch: options.fetch,\n maxRetries: options.maxRetries,\n maxRetryDelayMs: options.maxRetryDelayMs,\n });\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 createDraftQuote(params: CreateOfferParams): Promise<Offer> {\n return this.http.request<Offer>(\"/v1/prediction-markets/draft-quotes\", {\n method: \"POST\",\n body: JSON.stringify(decamelizeKeys(params)),\n });\n }\n\n public async promoteDraftQuote(draftId: string): Promise<Offer> {\n return this.http.request<Offer>(`/v1/prediction-markets/promoted-quotes/${encodeURIComponent(draftId)}`, {\n method: \"POST\",\n });\n }\n\n public async createQuote(params: CreateOfferParams): Promise<Offer> {\n return this.http.request<Offer>(\"/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)}/cancel`, {\n method: \"POST\",\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 getLimits(): Promise<CustomerLimit> {\n return this.http.request<CustomerLimit>(\"/v1/prediction-markets/limits\");\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}\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 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: `Bearer ${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 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 Offer = CamelizeKeys<Raw[\"CustomerOffer\"]>;\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 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 CreateOfferParams {\n marketTicker: string;\n effectiveSide: \"yes\" | \"no\";\n leverageBps: number;\n notionalAmountUsdPips: string;\n slippageBps: number;\n pmProvider?: \"polymarket\" | \"kalshi\";\n}\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 `Offer.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 offer'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"],"mappings":"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","names":["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 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"]}
@@ -0,0 +1,39 @@
1
+ import { H as HintAdjustment } from './dimes-client-DYFvnZUx.js';
2
+ import { Q as Quote } from './aliases-BJyM8ydu.js';
3
+
4
+ type Side = "yes" | "no";
5
+ interface QuoteParams {
6
+ marketTicker: string;
7
+ side: Side;
8
+ collateralUsd: number;
9
+ leverageBps: number;
10
+ slippageBps: number;
11
+ /**
12
+ * Allow the order to fill less than the requested notional (down to `minFillBps`),
13
+ * opening the position at the actual fill size. Defaults to atomic (fully filled or rejected).
14
+ */
15
+ allowPartialFill?: boolean;
16
+ /** Minimum acceptable fill in basis points. Only valid when `allowPartialFill` is true. */
17
+ minFillBps?: number;
18
+ }
19
+ interface MarketMovedEvent {
20
+ originalDraft: Quote;
21
+ newDraft: Quote;
22
+ retryCount: number;
23
+ }
24
+ interface QuoteOptions {
25
+ maxRetries?: number;
26
+ autoCorrect?: boolean;
27
+ onDraftReady?: (draft: Quote) => void;
28
+ onMarketMoved?: (event: MarketMovedEvent) => boolean | undefined;
29
+ onCorrection?: (adjustment: HintAdjustment) => boolean | undefined;
30
+ }
31
+ interface QuoteResult {
32
+ quote: Quote;
33
+ /** @deprecated Renamed to {@link QuoteResult.quote}. Still populated for backward compatibility. */
34
+ offer: Quote;
35
+ corrections: HintAdjustment[];
36
+ retries: number;
37
+ }
38
+
39
+ export type { MarketMovedEvent as M, QuoteParams as Q, Side as S, QuoteOptions as a, QuoteResult as b };