@dimes-dot-fi/sdk 1.3.0 → 1.3.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 (49) hide show
  1. package/dist/{aliases-DzVxkXtK.d.cts → aliases-BGqwpyE-.d.cts} +39 -1
  2. package/dist/{aliases-DzVxkXtK.d.ts → aliases-BGqwpyE-.d.ts} +39 -1
  3. package/dist/{chunk-YUCGNELT.mjs → chunk-4MO3HKMS.mjs} +7 -1
  4. package/dist/chunk-4MO3HKMS.mjs.map +1 -0
  5. package/dist/{chunk-S65RABUT.mjs → chunk-BVILILIV.mjs} +13 -1
  6. package/dist/chunk-BVILILIV.mjs.map +1 -0
  7. package/dist/{chunk-JWAPH4GD.cjs → chunk-COSLZ5TM.cjs} +36 -11
  8. package/dist/chunk-COSLZ5TM.cjs.map +1 -0
  9. package/dist/{chunk-UUE4HG2H.cjs → chunk-DYPABUKC.cjs} +13 -1
  10. package/dist/chunk-DYPABUKC.cjs.map +1 -0
  11. package/dist/{chunk-EI5V5Z6G.mjs → chunk-SGA6OZEU.mjs} +33 -8
  12. package/dist/chunk-SGA6OZEU.mjs.map +1 -0
  13. package/dist/{chunk-ZK56XS4X.cjs → chunk-UHQZSMUD.cjs} +8 -2
  14. package/dist/chunk-UHQZSMUD.cjs.map +1 -0
  15. package/dist/contract/index.cjs +13 -13
  16. package/dist/contract/index.d.cts +3 -3
  17. package/dist/contract/index.d.ts +3 -3
  18. package/dist/contract/index.mjs +1 -1
  19. package/dist/{dimes-client-D88pW-Lm.d.ts → dimes-client-C2hT6mZ8.d.cts} +10 -2
  20. package/dist/{dimes-client-Bs6eTIvn.d.cts → dimes-client-DFAKtIeI.d.ts} +10 -2
  21. package/dist/{dimes-error-DxIoHQzj.d.cts → dimes-error-BW0wd1ib.d.cts} +1 -1
  22. package/dist/{dimes-error-BHVY6vDv.d.ts → dimes-error-IBJ5eff6.d.ts} +1 -1
  23. package/dist/index.cjs +12 -7
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +7 -7
  26. package/dist/index.d.ts +7 -7
  27. package/dist/index.mjs +8 -3
  28. package/dist/index.mjs.map +1 -1
  29. package/dist/{quote-Cy7ie8yT.d.ts → quote-BVMZb0T8.d.ts} +2 -2
  30. package/dist/{quote-CZqCqt8R.d.cts → quote-BcVJ0U0l.d.cts} +2 -2
  31. package/dist/react/index.cjs +4 -4
  32. package/dist/react/index.d.cts +3 -3
  33. package/dist/react/index.d.ts +3 -3
  34. package/dist/react/index.mjs +2 -2
  35. package/dist/{types-BcUKsoEs.d.ts → types-BwPF-kCK.d.cts} +20 -2
  36. package/dist/{types--ysRe5Os.d.cts → types-C7nWOxO-.d.ts} +20 -2
  37. package/dist/ws/index.cjs +114 -4
  38. package/dist/ws/index.cjs.map +1 -1
  39. package/dist/ws/index.d.cts +36 -9
  40. package/dist/ws/index.d.ts +36 -9
  41. package/dist/ws/index.mjs +111 -1
  42. package/dist/ws/index.mjs.map +1 -1
  43. package/package.json +1 -1
  44. package/dist/chunk-EI5V5Z6G.mjs.map +0 -1
  45. package/dist/chunk-JWAPH4GD.cjs.map +0 -1
  46. package/dist/chunk-S65RABUT.mjs.map +0 -1
  47. package/dist/chunk-UUE4HG2H.cjs.map +0 -1
  48. package/dist/chunk-YUCGNELT.mjs.map +0 -1
  49. package/dist/chunk-ZK56XS4X.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/quote/build-quote-params.ts","../src/quote/quote-error-hints.ts","../src/quote/quote.ts"],"sourcesContent":["import type { CreateOfferParams } from \"../types\";\nimport type { QuoteParams } from \"../types/quote\";\n\nconst DEFAULT_LEVERAGE_STEP_BPS = 2500;\n\nexport function buildQuoteParams(params: QuoteParams, stepBps: number = DEFAULT_LEVERAGE_STEP_BPS): CreateOfferParams {\n const leverageBps = Math.round(params.leverageBps / stepBps) * stepBps;\n const notionalUsdPips = Math.round(params.collateralUsd * leverageBps);\n\n return {\n marketTicker: params.marketTicker,\n effectiveSide: params.side,\n leverageBps,\n notionalAmountUsdPips: notionalUsdPips.toString(),\n slippageBps: params.slippageBps,\n };\n}\n","const pipsPerUsd = 10_000;\nconst bpsPerUnit = 10_000;\nconst bpsPerPct = 100;\nconst centsFactor = 100;\nconst decimalPlaces = 2;\n\nexport const marketMovedCodes = new Set([\n \"quote_slippage_too_high\",\n \"quote_insufficient_liquidity\",\n \"quote_entry_price_out_of_range\",\n \"quote_entry_bid_depth_too_low\",\n \"quote_entry_depth_too_low\",\n \"quote_entry_spread_too_wide\",\n]);\n\nexport type QuoteHint =\n | { kind: \"use-max-collateral\"; maxCollateralUsd: number; minCollateralUsd: number }\n | { kind: \"raise-collateral\"; minCollateralUsd: number }\n | { kind: \"clamp-leverage\"; maxLeverageBps?: number }\n | { kind: \"raise-leverage\"; minLeverageBps: number }\n | { kind: \"raise-slippage\"; currentSlippageBps: number; maxSlippageBps: number }\n | { kind: \"market-full\" }\n | { kind: \"insufficient-liquidity\"; maxCollateralUsd: number; minCollateralUsd: number }\n | null;\n\ntype Params = Record<string, unknown> | null | undefined;\n\nfunction num(params: Params, key: string): number | null {\n if (!params) {\n return null;\n }\n const raw = params[key];\n if (raw === null || raw === undefined) {\n return null;\n }\n // eslint-disable-next-line no-restricted-syntax\n const n = typeof raw === \"string\" ? Number(raw) : typeof raw === \"number\" ? raw : NaN;\n return Number.isFinite(n) ? n : null;\n}\n\nfunction pipsToUsd(pips: number): number {\n return pips / pipsPerUsd;\n}\n\nfunction notionalPipsToCollateralUsd(notionalPips: number, leverageBps: number): number | null {\n if (!Number.isFinite(leverageBps) || leverageBps <= 0) {\n return null;\n }\n return (notionalPips * bpsPerUnit) / leverageBps / pipsPerUsd;\n}\n\nfunction buildExhaustedHint(\n exhaustedKind: \"market-full\" | \"insufficient-liquidity\",\n maxCollateralUsd: number,\n minCollateralUsd: number,\n): QuoteHint {\n if (exhaustedKind === \"insufficient-liquidity\") {\n return { kind: \"insufficient-liquidity\", maxCollateralUsd, minCollateralUsd };\n }\n return { kind: \"market-full\" };\n}\n\nfunction resolveMaxCollateralHint(\n params: Params,\n context: { leverageBps: number },\n capacityKey: string,\n exhaustedKind: \"market-full\" | \"insufficient-liquidity\",\n): QuoteHint {\n const serverMaxCollateralPips = num(params, \"maxSupportedCollateralUsdPips\");\n const capacityPips = num(params, capacityKey);\n const minNotionalPips = num(params, \"minNotionalUsdPips\");\n\n const fromServer = serverMaxCollateralPips !== null ? pipsToUsd(serverMaxCollateralPips) : null;\n const fromCapacity = capacityPips !== null ? notionalPipsToCollateralUsd(capacityPips, context.leverageBps) : null;\n const maxCollateralUsd =\n fromServer !== null && fromCapacity !== null ? Math.min(fromServer, fromCapacity) : (fromServer ?? fromCapacity);\n\n const minCollateralUsd =\n minNotionalPips !== null ? notionalPipsToCollateralUsd(minNotionalPips, context.leverageBps) : null;\n\n if (maxCollateralUsd === null || minCollateralUsd === null) {\n return null;\n }\n if (maxCollateralUsd < minCollateralUsd) {\n return buildExhaustedHint(exhaustedKind, maxCollateralUsd, minCollateralUsd);\n }\n return { kind: \"use-max-collateral\", maxCollateralUsd, minCollateralUsd };\n}\n\n// eslint-disable-next-line complexity\nexport function quoteErrorHint(code: string | null, params: Params, context: { leverageBps: number }): QuoteHint {\n if (!code) {\n return null;\n }\n\n switch (code) {\n case \"quote_side_capacity_exceeded\":\n case \"quote_user_position_limit_exceeded\":\n case \"quote_market_position_limit_exceeded\":\n case \"quote_side_position_limit_exceeded\":\n case \"quote_global_position_limit_exceeded\":\n case \"quote_partner_position_limit_exceeded\":\n return resolveMaxCollateralHint(params, context, \"availableCapacityUsdPips\", \"market-full\");\n\n case \"quote_insufficient_liquidity\":\n return resolveMaxCollateralHint(params, context, \"slippageMaxUsdPips\", \"market-full\");\n\n case \"notional_selector_insufficient_liquidity\":\n return resolveMaxCollateralHint(params, context, \"slippageMaxUsdPips\", \"insufficient-liquidity\");\n\n case \"quote_leverage_exceeds_collateral_floor\": {\n const minCollateralPips = num(params, \"minCollateralUsdPips\");\n if (minCollateralPips === null) {\n return null;\n }\n return { kind: \"raise-collateral\", minCollateralUsd: pipsToUsd(minCollateralPips) };\n }\n\n case \"quote_leverage_exceeds_maximum\":\n case \"quote_leverage_exceeds_model_max\": {\n const maxLeverageBps = num(params, \"maxLeverageBps\");\n if (maxLeverageBps === null) {\n return null;\n }\n return { kind: \"clamp-leverage\", maxLeverageBps };\n }\n\n case \"quote_leverage_too_high_for_price\": {\n const maxLeverageBps = num(params, \"maxAcceptableLeverageBps\");\n if (maxLeverageBps === null) {\n return null;\n }\n return { kind: \"clamp-leverage\", maxLeverageBps };\n }\n\n case \"quote_leverage_below_minimum\": {\n const minLeverageBps = num(params, \"minLeverageBps\");\n if (minLeverageBps === null) {\n return null;\n }\n return { kind: \"raise-leverage\", minLeverageBps };\n }\n\n case \"quote_slippage_too_high\": {\n const currentSlippageBps = num(params, \"currentSlippageBps\");\n const maxSlippageBps = num(params, \"maxSlippageBps\");\n if (currentSlippageBps === null || maxSlippageBps === null) {\n return null;\n }\n return { kind: \"raise-slippage\", currentSlippageBps, maxSlippageBps };\n }\n\n default:\n return null;\n }\n}\n\nexport type CorrectedField = \"collateral\" | \"leverage\" | \"slippage\";\n\nexport type HintAdjustment =\n | {\n field: \"collateral\";\n fromValue: number;\n toValue: number;\n toLabel: string;\n reason: \"max-collateral\" | \"min-collateral\";\n }\n | {\n field: \"leverage\";\n fromValue: number;\n toValue: number;\n toLabel: string;\n reason: \"clamp-max\" | \"raise-min\";\n }\n | {\n field: \"slippage\";\n fromValue: number;\n toValue: number;\n toLabel: string;\n reason: \"raise-slippage\";\n }\n | null;\n\nfunction formatUsd(value: number): string {\n return new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: \"USD\",\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }).format(value);\n}\n\nfunction bpsToMultiplier(bps: number): string {\n return `${(bps / bpsPerUnit).toFixed(1).replace(/\\.0$/, \"\")}x`;\n}\n\nexport function hintAdjustment(\n hint: QuoteHint,\n current: { collateralUsd: number; leverageBps: number; slippageBps: number },\n): HintAdjustment {\n if (!hint) {\n return null;\n }\n\n switch (hint.kind) {\n case \"use-max-collateral\": {\n const to = Math.max(0, Math.floor(hint.maxCollateralUsd * centsFactor) / centsFactor);\n if (to <= 0) {\n return null;\n }\n return {\n field: \"collateral\",\n fromValue: current.collateralUsd,\n toValue: to,\n toLabel: formatUsd(to),\n reason: \"max-collateral\",\n };\n }\n case \"raise-collateral\": {\n const to = Math.ceil(hint.minCollateralUsd * centsFactor) / centsFactor;\n if (to <= 0) {\n return null;\n }\n return {\n field: \"collateral\",\n fromValue: current.collateralUsd,\n toValue: to,\n toLabel: formatUsd(to),\n reason: \"min-collateral\",\n };\n }\n case \"clamp-leverage\": {\n if (hint.maxLeverageBps === undefined) {\n return null;\n }\n return {\n field: \"leverage\",\n fromValue: current.leverageBps,\n toValue: hint.maxLeverageBps,\n toLabel: bpsToMultiplier(hint.maxLeverageBps),\n reason: \"clamp-max\",\n };\n }\n case \"raise-leverage\":\n return {\n field: \"leverage\",\n fromValue: current.leverageBps,\n toValue: hint.minLeverageBps,\n toLabel: bpsToMultiplier(hint.minLeverageBps),\n reason: \"raise-min\",\n };\n case \"raise-slippage\":\n return {\n field: \"slippage\",\n fromValue: hint.currentSlippageBps,\n toValue: hint.maxSlippageBps,\n toLabel: `${(hint.maxSlippageBps / bpsPerPct).toFixed(decimalPlaces).replace(/\\.?0+$/, \"\")}%`,\n reason: \"raise-slippage\",\n };\n default:\n return null;\n }\n}\n","import { DimesApiError, DimesError } from \"../errors/dimes-error\";\nimport type { CreateOfferParams, Offer } from \"../types\";\nimport type { QuoteOptions, QuoteParams, QuoteResult } from \"../types/quote\";\nimport { buildQuoteParams } from \"./build-quote-params\";\nimport { type HintAdjustment, hintAdjustment, marketMovedCodes, quoteErrorHint } from \"./quote-error-hints\";\n\nexport interface QuoteClient {\n createDraftQuote(params: CreateOfferParams): Promise<Offer>;\n promoteDraftQuote(draftId: string): Promise<Offer>;\n createQuote(params: CreateOfferParams): Promise<Offer>;\n}\n\nconst DEFAULT_MAX_RETRIES = 3;\n\nfunction isMarketMovedError(err: unknown): boolean {\n return err instanceof DimesApiError && marketMovedCodes.has(err.code);\n}\n\nfunction applyAdjustment(\n params: CreateOfferParams,\n adj: NonNullable<HintAdjustment>,\n currentParams: QuoteParams,\n): CreateOfferParams {\n switch (adj.field) {\n case \"collateral\": {\n const notionalUsdPips = Math.round(adj.toValue * params.leverageBps);\n return { ...params, notionalAmountUsdPips: notionalUsdPips.toString() };\n }\n case \"leverage\": {\n const notionalUsdPips = Math.round(currentParams.collateralUsd * adj.toValue);\n return {\n ...params,\n leverageBps: adj.toValue,\n notionalAmountUsdPips: notionalUsdPips.toString(),\n };\n }\n case \"slippage\":\n return { ...params, slippageBps: adj.toValue };\n default:\n return params;\n }\n}\n\nfunction handleMarketMoved(err: unknown, attempt: number, maxRetries: number): boolean {\n return isMarketMovedError(err) && attempt < maxRetries;\n}\n\nfunction handleCorrection(err: unknown, currentParams: QuoteParams): { adj: NonNullable<HintAdjustment> } | null {\n if (!(err instanceof DimesApiError)) {\n return null;\n }\n\n const hint = quoteErrorHint(err.code, err.params, {\n leverageBps: currentParams.leverageBps,\n });\n\n const adj = hintAdjustment(hint, {\n collateralUsd: currentParams.collateralUsd,\n leverageBps: currentParams.leverageBps,\n slippageBps: currentParams.slippageBps,\n });\n\n if (!adj) {\n return null;\n }\n\n return { adj };\n}\n\n// eslint-disable-next-line complexity\nexport async function executeQuote(\n client: QuoteClient,\n params: QuoteParams,\n options?: QuoteOptions,\n): Promise<QuoteResult> {\n const maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;\n const autoCorrect = options?.autoCorrect ?? true;\n const corrections: NonNullable<HintAdjustment>[] = [];\n let retries = 0;\n\n let offerParams = buildQuoteParams(params);\n const currentParams = { ...params };\n\n const draft = await client.createDraftQuote(offerParams);\n options?.onDraftReady?.(draft);\n\n let currentDraft: Offer = draft;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const promotedOffer = await client.promoteDraftQuote(currentDraft.id);\n return { offer: promotedOffer, corrections, retries };\n } catch (err) {\n if (handleMarketMoved(err, attempt, maxRetries)) {\n const newDraft = await client.createDraftQuote(offerParams);\n retries++;\n\n const callbackResult = options?.onMarketMoved?.({\n originalDraft: currentDraft,\n newDraft,\n retryCount: retries,\n });\n\n if (callbackResult === false) {\n throw err;\n }\n\n currentDraft = newDraft;\n continue;\n }\n\n if (autoCorrect) {\n const correction = handleCorrection(err, currentParams);\n\n if (correction) {\n const callbackResult = options?.onCorrection?.(correction.adj);\n if (callbackResult === false) {\n throw err;\n }\n\n offerParams = applyAdjustment(offerParams, correction.adj, currentParams);\n corrections.push(correction.adj);\n\n const correctedOffer = await client.createQuote(offerParams);\n return { offer: correctedOffer, corrections, retries };\n }\n }\n\n throw err;\n }\n }\n\n throw new DimesError(\"market_moved_retries_exhausted\", \"Exhausted market-moved retries\");\n}\n"],"mappings":";;;;;;AAGA,IAAM,4BAA4B;AAE3B,SAAS,iBAAiB,QAAqB,UAAkB,2BAA8C;AACpH,QAAM,cAAc,KAAK,MAAM,OAAO,cAAc,OAAO,IAAI;AAC/D,QAAM,kBAAkB,KAAK,MAAM,OAAO,gBAAgB,WAAW;AAErE,SAAO;AAAA,IACL,cAAc,OAAO;AAAA,IACrB,eAAe,OAAO;AAAA,IACtB;AAAA,IACA,uBAAuB,gBAAgB,SAAS;AAAA,IAChD,aAAa,OAAO;AAAA,EACtB;AACF;;;AChBA,IAAM,aAAa;AACnB,IAAM,aAAa;AACnB,IAAM,YAAY;AAClB,IAAM,cAAc;AACpB,IAAM,gBAAgB;AAEf,IAAM,mBAAmB,oBAAI,IAAI;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAcD,SAAS,IAAI,QAAgB,KAA4B;AACvD,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,QAAM,MAAM,OAAO,GAAG;AACtB,MAAI,QAAQ,QAAQ,QAAQ,QAAW;AACrC,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,OAAO,QAAQ,WAAW,OAAO,GAAG,IAAI,OAAO,QAAQ,WAAW,MAAM;AAClF,SAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAClC;AAEA,SAAS,UAAU,MAAsB;AACvC,SAAO,OAAO;AAChB;AAEA,SAAS,4BAA4B,cAAsB,aAAoC;AAC7F,MAAI,CAAC,OAAO,SAAS,WAAW,KAAK,eAAe,GAAG;AACrD,WAAO;AAAA,EACT;AACA,SAAQ,eAAe,aAAc,cAAc;AACrD;AAEA,SAAS,mBACP,eACA,kBACA,kBACW;AACX,MAAI,kBAAkB,0BAA0B;AAC9C,WAAO,EAAE,MAAM,0BAA0B,kBAAkB,iBAAiB;AAAA,EAC9E;AACA,SAAO,EAAE,MAAM,cAAc;AAC/B;AAEA,SAAS,yBACP,QACA,SACA,aACA,eACW;AACX,QAAM,0BAA0B,IAAI,QAAQ,+BAA+B;AAC3E,QAAM,eAAe,IAAI,QAAQ,WAAW;AAC5C,QAAM,kBAAkB,IAAI,QAAQ,oBAAoB;AAExD,QAAM,aAAa,4BAA4B,OAAO,UAAU,uBAAuB,IAAI;AAC3F,QAAM,eAAe,iBAAiB,OAAO,4BAA4B,cAAc,QAAQ,WAAW,IAAI;AAC9G,QAAM,mBACJ,eAAe,QAAQ,iBAAiB,OAAO,KAAK,IAAI,YAAY,YAAY,IAAK,cAAc;AAErG,QAAM,mBACJ,oBAAoB,OAAO,4BAA4B,iBAAiB,QAAQ,WAAW,IAAI;AAEjG,MAAI,qBAAqB,QAAQ,qBAAqB,MAAM;AAC1D,WAAO;AAAA,EACT;AACA,MAAI,mBAAmB,kBAAkB;AACvC,WAAO,mBAAmB,eAAe,kBAAkB,gBAAgB;AAAA,EAC7E;AACA,SAAO,EAAE,MAAM,sBAAsB,kBAAkB,iBAAiB;AAC1E;AAGO,SAAS,eAAe,MAAqB,QAAgB,SAA6C;AAC/G,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AAEA,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO,yBAAyB,QAAQ,SAAS,4BAA4B,aAAa;AAAA,IAE5F,KAAK;AACH,aAAO,yBAAyB,QAAQ,SAAS,sBAAsB,aAAa;AAAA,IAEtF,KAAK;AACH,aAAO,yBAAyB,QAAQ,SAAS,sBAAsB,wBAAwB;AAAA,IAEjG,KAAK,2CAA2C;AAC9C,YAAM,oBAAoB,IAAI,QAAQ,sBAAsB;AAC5D,UAAI,sBAAsB,MAAM;AAC9B,eAAO;AAAA,MACT;AACA,aAAO,EAAE,MAAM,oBAAoB,kBAAkB,UAAU,iBAAiB,EAAE;AAAA,IACpF;AAAA,IAEA,KAAK;AAAA,IACL,KAAK,oCAAoC;AACvC,YAAM,iBAAiB,IAAI,QAAQ,gBAAgB;AACnD,UAAI,mBAAmB,MAAM;AAC3B,eAAO;AAAA,MACT;AACA,aAAO,EAAE,MAAM,kBAAkB,eAAe;AAAA,IAClD;AAAA,IAEA,KAAK,qCAAqC;AACxC,YAAM,iBAAiB,IAAI,QAAQ,0BAA0B;AAC7D,UAAI,mBAAmB,MAAM;AAC3B,eAAO;AAAA,MACT;AACA,aAAO,EAAE,MAAM,kBAAkB,eAAe;AAAA,IAClD;AAAA,IAEA,KAAK,gCAAgC;AACnC,YAAM,iBAAiB,IAAI,QAAQ,gBAAgB;AACnD,UAAI,mBAAmB,MAAM;AAC3B,eAAO;AAAA,MACT;AACA,aAAO,EAAE,MAAM,kBAAkB,eAAe;AAAA,IAClD;AAAA,IAEA,KAAK,2BAA2B;AAC9B,YAAM,qBAAqB,IAAI,QAAQ,oBAAoB;AAC3D,YAAM,iBAAiB,IAAI,QAAQ,gBAAgB;AACnD,UAAI,uBAAuB,QAAQ,mBAAmB,MAAM;AAC1D,eAAO;AAAA,MACT;AACA,aAAO,EAAE,MAAM,kBAAkB,oBAAoB,eAAe;AAAA,IACtE;AAAA,IAEA;AACE,aAAO;AAAA,EACX;AACF;AA4BA,SAAS,UAAU,OAAuB;AACxC,SAAO,IAAI,KAAK,aAAa,SAAS;AAAA,IACpC,OAAO;AAAA,IACP,UAAU;AAAA,IACV,uBAAuB;AAAA,IACvB,uBAAuB;AAAA,EACzB,CAAC,EAAE,OAAO,KAAK;AACjB;AAEA,SAAS,gBAAgB,KAAqB;AAC5C,SAAO,IAAI,MAAM,YAAY,QAAQ,CAAC,EAAE,QAAQ,QAAQ,EAAE,CAAC;AAC7D;AAEO,SAAS,eACd,MACA,SACgB;AAChB,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AAEA,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK,sBAAsB;AACzB,YAAM,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,mBAAmB,WAAW,IAAI,WAAW;AACpF,UAAI,MAAM,GAAG;AACX,eAAO;AAAA,MACT;AACA,aAAO;AAAA,QACL,OAAO;AAAA,QACP,WAAW,QAAQ;AAAA,QACnB,SAAS;AAAA,QACT,SAAS,UAAU,EAAE;AAAA,QACrB,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,KAAK,oBAAoB;AACvB,YAAM,KAAK,KAAK,KAAK,KAAK,mBAAmB,WAAW,IAAI;AAC5D,UAAI,MAAM,GAAG;AACX,eAAO;AAAA,MACT;AACA,aAAO;AAAA,QACL,OAAO;AAAA,QACP,WAAW,QAAQ;AAAA,QACnB,SAAS;AAAA,QACT,SAAS,UAAU,EAAE;AAAA,QACrB,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,KAAK,kBAAkB;AACrB,UAAI,KAAK,mBAAmB,QAAW;AACrC,eAAO;AAAA,MACT;AACA,aAAO;AAAA,QACL,OAAO;AAAA,QACP,WAAW,QAAQ;AAAA,QACnB,SAAS,KAAK;AAAA,QACd,SAAS,gBAAgB,KAAK,cAAc;AAAA,QAC5C,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,KAAK;AACH,aAAO;AAAA,QACL,OAAO;AAAA,QACP,WAAW,QAAQ;AAAA,QACnB,SAAS,KAAK;AAAA,QACd,SAAS,gBAAgB,KAAK,cAAc;AAAA,QAC5C,QAAQ;AAAA,MACV;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,OAAO;AAAA,QACP,WAAW,KAAK;AAAA,QAChB,SAAS,KAAK;AAAA,QACd,SAAS,IAAI,KAAK,iBAAiB,WAAW,QAAQ,aAAa,EAAE,QAAQ,UAAU,EAAE,CAAC;AAAA,QAC1F,QAAQ;AAAA,MACV;AAAA,IACF;AACE,aAAO;AAAA,EACX;AACF;;;AC1PA,IAAM,sBAAsB;AAE5B,SAAS,mBAAmB,KAAuB;AACjD,SAAO,eAAe,iBAAiB,iBAAiB,IAAI,IAAI,IAAI;AACtE;AAEA,SAAS,gBACP,QACA,KACA,eACmB;AACnB,UAAQ,IAAI,OAAO;AAAA,IACjB,KAAK,cAAc;AACjB,YAAM,kBAAkB,KAAK,MAAM,IAAI,UAAU,OAAO,WAAW;AACnE,aAAO,EAAE,GAAG,QAAQ,uBAAuB,gBAAgB,SAAS,EAAE;AAAA,IACxE;AAAA,IACA,KAAK,YAAY;AACf,YAAM,kBAAkB,KAAK,MAAM,cAAc,gBAAgB,IAAI,OAAO;AAC5E,aAAO;AAAA,QACL,GAAG;AAAA,QACH,aAAa,IAAI;AAAA,QACjB,uBAAuB,gBAAgB,SAAS;AAAA,MAClD;AAAA,IACF;AAAA,IACA,KAAK;AACH,aAAO,EAAE,GAAG,QAAQ,aAAa,IAAI,QAAQ;AAAA,IAC/C;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,kBAAkB,KAAc,SAAiB,YAA6B;AACrF,SAAO,mBAAmB,GAAG,KAAK,UAAU;AAC9C;AAEA,SAAS,iBAAiB,KAAc,eAAyE;AAC/G,MAAI,EAAE,eAAe,gBAAgB;AACnC,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,eAAe,IAAI,MAAM,IAAI,QAAQ;AAAA,IAChD,aAAa,cAAc;AAAA,EAC7B,CAAC;AAED,QAAM,MAAM,eAAe,MAAM;AAAA,IAC/B,eAAe,cAAc;AAAA,IAC7B,aAAa,cAAc;AAAA,IAC3B,aAAa,cAAc;AAAA,EAC7B,CAAC;AAED,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,EACT;AAEA,SAAO,EAAE,IAAI;AACf;AAGA,eAAsB,aACpB,QACA,QACA,SACsB;AACtB,QAAM,aAAa,SAAS,cAAc;AAC1C,QAAM,cAAc,SAAS,eAAe;AAC5C,QAAM,cAA6C,CAAC;AACpD,MAAI,UAAU;AAEd,MAAI,cAAc,iBAAiB,MAAM;AACzC,QAAM,gBAAgB,EAAE,GAAG,OAAO;AAElC,QAAM,QAAQ,MAAM,OAAO,iBAAiB,WAAW;AACvD,WAAS,eAAe,KAAK;AAE7B,MAAI,eAAsB;AAE1B,WAAS,UAAU,GAAG,WAAW,YAAY,WAAW;AACtD,QAAI;AACF,YAAM,gBAAgB,MAAM,OAAO,kBAAkB,aAAa,EAAE;AACpE,aAAO,EAAE,OAAO,eAAe,aAAa,QAAQ;AAAA,IACtD,SAAS,KAAK;AACZ,UAAI,kBAAkB,KAAK,SAAS,UAAU,GAAG;AAC/C,cAAM,WAAW,MAAM,OAAO,iBAAiB,WAAW;AAC1D;AAEA,cAAM,iBAAiB,SAAS,gBAAgB;AAAA,UAC9C,eAAe;AAAA,UACf;AAAA,UACA,YAAY;AAAA,QACd,CAAC;AAED,YAAI,mBAAmB,OAAO;AAC5B,gBAAM;AAAA,QACR;AAEA,uBAAe;AACf;AAAA,MACF;AAEA,UAAI,aAAa;AACf,cAAM,aAAa,iBAAiB,KAAK,aAAa;AAEtD,YAAI,YAAY;AACd,gBAAM,iBAAiB,SAAS,eAAe,WAAW,GAAG;AAC7D,cAAI,mBAAmB,OAAO;AAC5B,kBAAM;AAAA,UACR;AAEA,wBAAc,gBAAgB,aAAa,WAAW,KAAK,aAAa;AACxE,sBAAY,KAAK,WAAW,GAAG;AAE/B,gBAAM,iBAAiB,MAAM,OAAO,YAAY,WAAW;AAC3D,iBAAO,EAAE,OAAO,gBAAgB,aAAa,QAAQ;AAAA,QACvD;AAAA,MACF;AAEA,YAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,IAAI,WAAW,kCAAkC,gCAAgC;AACzF;","names":[]}
@@ -11,6 +11,11 @@ var positionEventTypes = [
11
11
  "position.reverted",
12
12
  "position.settled"
13
13
  ];
14
+ var marketEventTypes = [
15
+ "market.discovered",
16
+ "market.eligibility_changed",
17
+ "market.max_leverage_changed"
18
+ ];
14
19
  var notificationCodes = {
15
20
  orderFulfillmentRetrying: "ORDER_FULFILLMENT_RETRYING"
16
21
  };
@@ -18,5 +23,6 @@ var notificationCodes = {
18
23
 
19
24
 
20
25
 
21
- exports.positionEventTypes = positionEventTypes; exports.notificationCodes = notificationCodes;
22
- //# sourceMappingURL=chunk-ZK56XS4X.cjs.map
26
+
27
+ exports.positionEventTypes = positionEventTypes; exports.marketEventTypes = marketEventTypes; exports.notificationCodes = notificationCodes;
28
+ //# sourceMappingURL=chunk-UHQZSMUD.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/alexemery/bl/dimes-sdk/dist/chunk-UHQZSMUD.cjs","../src/ws/types.ts"],"names":[],"mappings":"AAAA;ACEO,IAAM,mBAAA,EAAqB;AAAA,EAChC,oBAAA;AAAA,EACA,0BAAA;AAAA,EACA,iBAAA;AAAA,EACA,kBAAA;AAAA,EACA,wBAAA;AAAA,EACA,qBAAA;AAAA,EACA,iBAAA;AAAA,EACA,kBAAA;AAAA,EACA,mBAAA;AAAA,EACA;AACF,CAAA;AAkBO,IAAM,iBAAA,EAAmB;AAAA,EAC9B,mBAAA;AAAA,EACA,4BAAA;AAAA,EACA;AACF,CAAA;AA6CO,IAAM,kBAAA,EAAoB;AAAA,EAC/B,wBAAA,EAA0B;AAC5B,CAAA;AD7DA;AACA;AACE;AACA;AACA;AACF,4IAAC","file":"/Users/alexemery/bl/dimes-sdk/dist/chunk-UHQZSMUD.cjs","sourcesContent":[null,"import type { Market, MarketLeverage, MarketPolymarket, Position } from \"../types\";\n\nexport const positionEventTypes = [\n \"position.cancelled\",\n \"position.close_requested\",\n \"position.closed\",\n \"position.created\",\n \"position.force_unwound\",\n \"position.liquidated\",\n \"position.opened\",\n \"position.opening\",\n \"position.reverted\",\n \"position.settled\",\n] as const;\n\nexport type PositionEventType = (typeof positionEventTypes)[number];\n\nexport interface PositionEventEnvelope {\n id: string;\n type: PositionEventType;\n created_at: string;\n data: Record<string, unknown>;\n}\n\nexport interface PositionEvent {\n id: string;\n type: PositionEventType;\n createdAt: string;\n data: Position;\n}\n\nexport const marketEventTypes = [\n \"market.discovered\",\n \"market.eligibility_changed\",\n \"market.max_leverage_changed\",\n] as const;\n\nexport type MarketEventType = (typeof marketEventTypes)[number];\n\nexport type MarketDelta = Pick<Market, \"id\"> & {\n polymarket: MarketPolymarket;\n leverage?: MarketLeverage;\n} & Partial<Omit<Market, \"id\" | \"leverage\">>;\n\nexport interface MarketEventEnvelope {\n id: string;\n type: MarketEventType;\n created_at: string;\n data: Record<string, unknown>[];\n}\n\nexport interface MarketEvent {\n id: string;\n type: MarketEventType;\n createdAt: string;\n data: Market[] | MarketDelta[];\n}\n\nexport interface NotificationEventEnvelope {\n id: string;\n type: \"notification\";\n created_at: string;\n data: {\n code: string;\n message: string;\n params?: Record<string, unknown>;\n };\n}\n\nexport interface NotificationEvent {\n id: string;\n type: \"notification\";\n createdAt: string;\n data: {\n code: string;\n message: string;\n params?: Record<string, unknown>;\n };\n}\n\nexport const notificationCodes = {\n orderFulfillmentRetrying: \"ORDER_FULFILLMENT_RETRYING\",\n} as const;\n\nexport type NotificationCode = (typeof notificationCodes)[keyof typeof notificationCodes];\n"]}
@@ -1,7 +1,7 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
3
 
4
- var _chunkUUE4HG2Hcjs = require('../chunk-UUE4HG2H.cjs');
4
+ var _chunkDYPABUKCcjs = require('../chunk-DYPABUKC.cjs');
5
5
 
6
6
  // src/contract/vault-abi.json
7
7
  var vault_abi_default = {
@@ -411,7 +411,7 @@ var _viem = require('viem');
411
411
  function toHex(value) {
412
412
  if (!_viem.isHex.call(void 0, value)) {
413
413
  const HEX_PREVIEW_LENGTH = 10;
414
- throw new (0, _chunkUUE4HG2Hcjs.DimesError)(
414
+ throw new (0, _chunkDYPABUKCcjs.DimesError)(
415
415
  "invalid_hex",
416
416
  `Expected hex string starting with 0x, got: ${value.slice(0, HEX_PREVIEW_LENGTH)}`
417
417
  );
@@ -420,7 +420,7 @@ function toHex(value) {
420
420
  }
421
421
  function toAddress(value) {
422
422
  if (!_viem.isAddress.call(void 0, value)) {
423
- throw new (0, _chunkUUE4HG2Hcjs.DimesError)("invalid_address", `Invalid EVM address: ${value}`);
423
+ throw new (0, _chunkDYPABUKCcjs.DimesError)("invalid_address", `Invalid EVM address: ${value}`);
424
424
  }
425
425
  return _viem.getAddress.call(void 0, value);
426
426
  }
@@ -705,7 +705,7 @@ async function verifyOfferSignature(client, offer, userAddress) {
705
705
  const recoveredSigner = await recoverCreatePositionSigner(offer, userAddress);
706
706
  const expectedSigner = _viem.getAddress.call(void 0, info.polygonSignerAddress);
707
707
  if (recoveredSigner !== expectedSigner) {
708
- throw new (0, _chunkUUE4HG2Hcjs.DimesContractError)(
708
+ throw new (0, _chunkDYPABUKCcjs.DimesContractError)(
709
709
  "invalid_signer",
710
710
  `Recovered signer ${recoveredSigner} does not match expected authority ${expectedSigner}`
711
711
  );
@@ -796,12 +796,12 @@ function firstLine(s) {
796
796
  }
797
797
  function formatContractError(err) {
798
798
  if (!err) {
799
- return new (0, _chunkUUE4HG2Hcjs.DimesContractError)("unknown", "Transaction failed.");
799
+ return new (0, _chunkDYPABUKCcjs.DimesContractError)("unknown", "Transaction failed.");
800
800
  }
801
801
  if (err instanceof _viem.BaseError) {
802
802
  const rejected = err.walk((e) => e instanceof _viem.UserRejectedRequestError);
803
803
  if (rejected) {
804
- return new (0, _chunkUUE4HG2Hcjs.DimesContractError)("UserRejected", "Transaction rejected in wallet.");
804
+ return new (0, _chunkDYPABUKCcjs.DimesContractError)("UserRejected", "Transaction rejected in wallet.");
805
805
  }
806
806
  const reverted = err.walk(
807
807
  (e) => e instanceof _viem.ContractFunctionRevertedError
@@ -812,12 +812,12 @@ function formatContractError(err) {
812
812
  if (errorName) {
813
813
  const fmt = friendlyByErrorName[errorName];
814
814
  const message = fmt ? fmt(args) : humanizeName(errorName);
815
- return new (0, _chunkUUE4HG2Hcjs.DimesContractError)(errorName, message);
815
+ return new (0, _chunkDYPABUKCcjs.DimesContractError)(errorName, message);
816
816
  }
817
817
  const raw = reverted.raw;
818
818
  const selector = raw && raw.length >= HEX_SELECTOR_LENGTH ? raw.slice(0, HEX_SELECTOR_LENGTH) : void 0;
819
819
  const selectorMessage = selector ? friendlyBySelector[selector] : void 0;
820
- return new (0, _chunkUUE4HG2Hcjs.DimesContractError)(
820
+ return new (0, _chunkDYPABUKCcjs.DimesContractError)(
821
821
  _nullishCoalesce(selector, () => ( "unknown_revert")),
822
822
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
823
823
  _nullishCoalesce(_nullishCoalesce(selectorMessage, () => ( reverted.shortMessage)), () => ( "Contract reverted."))
@@ -825,17 +825,17 @@ function formatContractError(err) {
825
825
  }
826
826
  const exec = err.walk((e) => e instanceof _viem.ContractFunctionExecutionError);
827
827
  if (_optionalChain([exec, 'optionalAccess', _5 => _5.shortMessage])) {
828
- return new (0, _chunkUUE4HG2Hcjs.DimesContractError)("execution_error", firstLine(exec.shortMessage));
828
+ return new (0, _chunkDYPABUKCcjs.DimesContractError)("execution_error", firstLine(exec.shortMessage));
829
829
  }
830
830
  if (err.shortMessage) {
831
- return new (0, _chunkUUE4HG2Hcjs.DimesContractError)("base_error", firstLine(err.shortMessage));
831
+ return new (0, _chunkDYPABUKCcjs.DimesContractError)("base_error", firstLine(err.shortMessage));
832
832
  }
833
- return new (0, _chunkUUE4HG2Hcjs.DimesContractError)("base_error", firstLine(err.message));
833
+ return new (0, _chunkDYPABUKCcjs.DimesContractError)("base_error", firstLine(err.message));
834
834
  }
835
835
  if (err instanceof Error) {
836
- return new (0, _chunkUUE4HG2Hcjs.DimesContractError)("error", firstLine(err.message));
836
+ return new (0, _chunkDYPABUKCcjs.DimesContractError)("error", firstLine(err.message));
837
837
  }
838
- return new (0, _chunkUUE4HG2Hcjs.DimesContractError)("unknown", "Transaction failed.");
838
+ return new (0, _chunkDYPABUKCcjs.DimesContractError)("unknown", "Transaction failed.");
839
839
  }
840
840
 
841
841
 
@@ -1,8 +1,8 @@
1
1
  import { Abi, Address, Hex } from 'viem';
2
2
  export { Address, Hex } from 'viem';
3
- import { O as Offer } from '../aliases-DzVxkXtK.cjs';
4
- import { D as DimesClient } from '../dimes-client-Bs6eTIvn.cjs';
5
- import { a as DimesContractError } from '../dimes-error-DxIoHQzj.cjs';
3
+ import { O as Offer } from '../aliases-BGqwpyE-.cjs';
4
+ import { D as DimesClient } from '../dimes-client-C2hT6mZ8.cjs';
5
+ import { a as DimesContractError } from '../dimes-error-BW0wd1ib.cjs';
6
6
 
7
7
  declare const vaultAbi: Abi;
8
8
  declare const erc20Abi: readonly [{
@@ -1,8 +1,8 @@
1
1
  import { Abi, Address, Hex } from 'viem';
2
2
  export { Address, Hex } from 'viem';
3
- import { O as Offer } from '../aliases-DzVxkXtK.js';
4
- import { D as DimesClient } from '../dimes-client-D88pW-Lm.js';
5
- import { a as DimesContractError } from '../dimes-error-BHVY6vDv.js';
3
+ import { O as Offer } from '../aliases-BGqwpyE-.js';
4
+ import { D as DimesClient } from '../dimes-client-DFAKtIeI.js';
5
+ import { a as DimesContractError } from '../dimes-error-IBJ5eff6.js';
6
6
 
7
7
  declare const vaultAbi: Abi;
8
8
  declare const erc20Abi: readonly [{
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DimesContractError,
3
3
  DimesError
4
- } from "../chunk-S65RABUT.mjs";
4
+ } from "../chunk-BVILILIV.mjs";
5
5
 
6
6
  // src/contract/vault-abi.json
7
7
  var vault_abi_default = {
@@ -1,10 +1,13 @@
1
- import { M as Market, C as CreateOfferParams, O as Offer, P as Position, c as ContractInfo, e as CustomerLimit } from './aliases-DzVxkXtK.js';
1
+ import { M as Market, C as CreateOfferParams, O as Offer, P as Position, A as PositionTransactions, c as ContractInfo, e as CustomerLimit } from './aliases-BGqwpyE-.cjs';
2
2
 
3
3
  declare const marketMovedCodes: Set<string>;
4
4
  type QuoteHint = {
5
5
  kind: "use-max-collateral";
6
6
  maxCollateralUsd: number;
7
7
  minCollateralUsd: number;
8
+ } | {
9
+ kind: "raise-collateral";
10
+ minCollateralUsd: number;
8
11
  } | {
9
12
  kind: "clamp-leverage";
10
13
  maxLeverageBps?: number;
@@ -17,6 +20,10 @@ type QuoteHint = {
17
20
  maxSlippageBps: number;
18
21
  } | {
19
22
  kind: "market-full";
23
+ } | {
24
+ kind: "insufficient-liquidity";
25
+ maxCollateralUsd: number;
26
+ minCollateralUsd: number;
20
27
  } | null;
21
28
  type Params = Record<string, unknown> | null | undefined;
22
29
  declare function quoteErrorHint(code: string | null, params: Params, context: {
@@ -28,7 +35,7 @@ type HintAdjustment = {
28
35
  fromValue: number;
29
36
  toValue: number;
30
37
  toLabel: string;
31
- reason: "max-collateral";
38
+ reason: "max-collateral" | "min-collateral";
32
39
  } | {
33
40
  field: "leverage";
34
41
  fromValue: number;
@@ -120,6 +127,7 @@ declare class DimesClient {
120
127
  promoteDraftQuote(draftId: string): Promise<Offer>;
121
128
  createQuote(params: CreateOfferParams): Promise<Offer>;
122
129
  getPositions(params?: GetPositionsParams): Promise<Position[]>;
130
+ getPositionTransactions(positionId: string): Promise<PositionTransactions>;
123
131
  cancelPosition(positionId: string): Promise<void>;
124
132
  getContractInfo(): Promise<ContractInfo>;
125
133
  getLimits(): Promise<CustomerLimit>;
@@ -1,10 +1,13 @@
1
- import { M as Market, C as CreateOfferParams, O as Offer, P as Position, c as ContractInfo, e as CustomerLimit } from './aliases-DzVxkXtK.cjs';
1
+ import { M as Market, C as CreateOfferParams, O as Offer, P as Position, A as PositionTransactions, c as ContractInfo, e as CustomerLimit } from './aliases-BGqwpyE-.js';
2
2
 
3
3
  declare const marketMovedCodes: Set<string>;
4
4
  type QuoteHint = {
5
5
  kind: "use-max-collateral";
6
6
  maxCollateralUsd: number;
7
7
  minCollateralUsd: number;
8
+ } | {
9
+ kind: "raise-collateral";
10
+ minCollateralUsd: number;
8
11
  } | {
9
12
  kind: "clamp-leverage";
10
13
  maxLeverageBps?: number;
@@ -17,6 +20,10 @@ type QuoteHint = {
17
20
  maxSlippageBps: number;
18
21
  } | {
19
22
  kind: "market-full";
23
+ } | {
24
+ kind: "insufficient-liquidity";
25
+ maxCollateralUsd: number;
26
+ minCollateralUsd: number;
20
27
  } | null;
21
28
  type Params = Record<string, unknown> | null | undefined;
22
29
  declare function quoteErrorHint(code: string | null, params: Params, context: {
@@ -28,7 +35,7 @@ type HintAdjustment = {
28
35
  fromValue: number;
29
36
  toValue: number;
30
37
  toLabel: string;
31
- reason: "max-collateral";
38
+ reason: "max-collateral" | "min-collateral";
32
39
  } | {
33
40
  field: "leverage";
34
41
  fromValue: number;
@@ -120,6 +127,7 @@ declare class DimesClient {
120
127
  promoteDraftQuote(draftId: string): Promise<Offer>;
121
128
  createQuote(params: CreateOfferParams): Promise<Offer>;
122
129
  getPositions(params?: GetPositionsParams): Promise<Position[]>;
130
+ getPositionTransactions(positionId: string): Promise<PositionTransactions>;
123
131
  cancelPosition(positionId: string): Promise<void>;
124
132
  getContractInfo(): Promise<ContractInfo>;
125
133
  getLimits(): Promise<CustomerLimit>;
@@ -1,4 +1,4 @@
1
- import { Q as QuoteHint } from './dimes-client-Bs6eTIvn.cjs';
1
+ import { Q as QuoteHint } from './dimes-client-C2hT6mZ8.cjs';
2
2
 
3
3
  declare class DimesError extends Error {
4
4
  readonly code: string;
@@ -1,4 +1,4 @@
1
- import { Q as QuoteHint } from './dimes-client-D88pW-Lm.js';
1
+ import { Q as QuoteHint } from './dimes-client-DFAKtIeI.js';
2
2
 
3
3
  declare class DimesError extends Error {
4
4
  readonly code: string;
package/dist/index.cjs CHANGED
@@ -4,17 +4,17 @@
4
4
 
5
5
 
6
6
 
7
- var _chunkJWAPH4GDcjs = require('./chunk-JWAPH4GD.cjs');
7
+ var _chunkCOSLZ5TMcjs = require('./chunk-COSLZ5TM.cjs');
8
8
 
9
9
 
10
10
 
11
11
 
12
12
 
13
13
 
14
- var _chunkUUE4HG2Hcjs = require('./chunk-UUE4HG2H.cjs');
14
+ var _chunkDYPABUKCcjs = require('./chunk-DYPABUKC.cjs');
15
15
 
16
16
 
17
- var _chunkZK56XS4Xcjs = require('./chunk-ZK56XS4X.cjs');
17
+ var _chunkUHQZSMUDcjs = require('./chunk-UHQZSMUD.cjs');
18
18
 
19
19
  // src/client/dimes-client.ts
20
20
  var _humps = require('humps');
@@ -59,7 +59,7 @@ async function throwFromResponse(response) {
59
59
  const message = _nullishCoalesce(_optionalChain([parsed, 'optionalAccess', _5 => _5.error, 'optionalAccess', _6 => _6.message]), () => ( `API error ${response.status}`));
60
60
  const rawParams = _optionalChain([parsed, 'optionalAccess', _7 => _7.error, 'optionalAccess', _8 => _8.params]);
61
61
  const params = rawParams ? _humps.camelizeKeys.call(void 0, rawParams) : null;
62
- throw new (0, _chunkUUE4HG2Hcjs.DimesApiError)({ status: response.status, code, type, message, params });
62
+ throw new (0, _chunkDYPABUKCcjs.DimesApiError)({ status: response.status, code, type, message, params });
63
63
  }
64
64
  var HttpClient = class {
65
65
 
@@ -170,6 +170,11 @@ var DimesClient = class {
170
170
  const query = params ? buildQueryFromEntries(Object.entries(params)) : "";
171
171
  return this.http.requestList(`/v1/prediction-markets/positions${query}`);
172
172
  }
173
+ async getPositionTransactions(positionId) {
174
+ return this.http.request(
175
+ `/v1/prediction-markets/positions/${encodeURIComponent(positionId)}/transactions`
176
+ );
177
+ }
173
178
  async cancelPosition(positionId) {
174
179
  await this.http.request(`/v1/prediction-markets/positions/${encodeURIComponent(positionId)}/cancel`, {
175
180
  method: "POST"
@@ -228,7 +233,7 @@ var ApiKeyAuth = (_class = class {
228
233
  });
229
234
  if (!response.ok) {
230
235
  const text = await response.text();
231
- throw new (0, _chunkUUE4HG2Hcjs.DimesError)("auth_token_failed", `Failed to obtain auth token (${response.status}): ${text}`);
236
+ throw new (0, _chunkDYPABUKCcjs.DimesError)("auth_token_failed", `Failed to obtain auth token (${response.status}): ${text}`);
232
237
  }
233
238
  const data = await response.json();
234
239
  this.jwt = data.token;
@@ -268,7 +273,7 @@ var JwtAuth = (_class2 = class {
268
273
  const response = await this.fetchFn(this.tokenUrl);
269
274
  if (!response.ok) {
270
275
  const text = await response.text();
271
- throw new (0, _chunkUUE4HG2Hcjs.DimesError)(
276
+ throw new (0, _chunkDYPABUKCcjs.DimesError)(
272
277
  "auth_token_failed",
273
278
  `Failed to fetch token from ${this.tokenUrl} (${response.status}): ${text}`
274
279
  );
@@ -464,5 +469,5 @@ function getOriginationFeeBreakdown(position) {
464
469
 
465
470
 
466
471
 
467
- exports.ApiKeyAuth = ApiKeyAuth; exports.DimesApiError = _chunkUUE4HG2Hcjs.DimesApiError; exports.DimesClient = DimesClient; exports.DimesContractError = _chunkUUE4HG2Hcjs.DimesContractError; exports.DimesError = _chunkUUE4HG2Hcjs.DimesError; exports.JwtAuth = JwtAuth; exports.buildQuoteParams = _chunkJWAPH4GDcjs.buildQuoteParams; exports.defaultSide = defaultSide; exports.executeQuote = _chunkJWAPH4GDcjs.executeQuote; exports.formatErrorMessage = _chunkUUE4HG2Hcjs.formatErrorMessage; exports.getOriginationFeeBreakdown = getOriginationFeeBreakdown; exports.getSidedEligibility = getSidedEligibility; exports.hintAdjustment = _chunkJWAPH4GDcjs.hintAdjustment; exports.isClosedPosition = isClosedPosition; exports.isFullyClosed = isFullyClosed; exports.isFullyOpen = isFullyOpen; exports.isOpenPosition = isOpenPosition; exports.leverageMaxBps = leverageMaxBps; exports.marketMovedCodes = _chunkJWAPH4GDcjs.marketMovedCodes; exports.maxLeverageBpsAtNotional = maxLeverageBpsAtNotional; exports.maxViableLeverageBpsForCollateral = maxViableLeverageBpsForCollateral; exports.positionEventTypes = _chunkZK56XS4Xcjs.positionEventTypes; exports.quoteErrorHint = _chunkJWAPH4GDcjs.quoteErrorHint; exports.rejectionReasonShort = rejectionReasonShort; exports.rejectionReasonText = rejectionReasonText; exports.resolveFriendlyMessage = _chunkUUE4HG2Hcjs.resolveFriendlyMessage;
472
+ exports.ApiKeyAuth = ApiKeyAuth; exports.DimesApiError = _chunkDYPABUKCcjs.DimesApiError; exports.DimesClient = DimesClient; exports.DimesContractError = _chunkDYPABUKCcjs.DimesContractError; exports.DimesError = _chunkDYPABUKCcjs.DimesError; exports.JwtAuth = JwtAuth; exports.buildQuoteParams = _chunkCOSLZ5TMcjs.buildQuoteParams; exports.defaultSide = defaultSide; exports.executeQuote = _chunkCOSLZ5TMcjs.executeQuote; exports.formatErrorMessage = _chunkDYPABUKCcjs.formatErrorMessage; exports.getOriginationFeeBreakdown = getOriginationFeeBreakdown; exports.getSidedEligibility = getSidedEligibility; exports.hintAdjustment = _chunkCOSLZ5TMcjs.hintAdjustment; exports.isClosedPosition = isClosedPosition; exports.isFullyClosed = isFullyClosed; exports.isFullyOpen = isFullyOpen; exports.isOpenPosition = isOpenPosition; exports.leverageMaxBps = leverageMaxBps; exports.marketMovedCodes = _chunkCOSLZ5TMcjs.marketMovedCodes; exports.maxLeverageBpsAtNotional = maxLeverageBpsAtNotional; exports.maxViableLeverageBpsForCollateral = maxViableLeverageBpsForCollateral; exports.positionEventTypes = _chunkUHQZSMUDcjs.positionEventTypes; exports.quoteErrorHint = _chunkCOSLZ5TMcjs.quoteErrorHint; exports.rejectionReasonShort = rejectionReasonShort; exports.rejectionReasonText = rejectionReasonText; exports.resolveFriendlyMessage = _chunkDYPABUKCcjs.resolveFriendlyMessage;
468
473
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/alexemery/bl/dimes-sdk/dist/index.cjs","../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"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;AClBA,8BAA+B;ADoB/B;AACA;AErBA;AAeA,IAAM,kBAAA,EAAoB,GAAA;AAC1B,IAAM,uBAAA,EAAyB,GAAA;AAC/B,IAAM,oBAAA,EAAsB,CAAA;AAC5B,IAAM,2BAAA,EAA6B,GAAA;AACnC,IAAM,uBAAA,EAAyB,GAAA;AAC/B,IAAM,eAAA,EAAiB,CAAA;AACvB,IAAM,cAAA,EAAgB,GAAA;AAEtB,SAAS,KAAA,CAAM,EAAA,EAA2B;AACxC,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAA,GAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACzD;AAEA,SAAS,iBAAA,CAAkB,MAAA,EAAuB,OAAA,EAAyB;AACzE,EAAA,MAAM,WAAA,EAAa,uBAAA,EAAyB,eAAA,GAAkB,OAAA;AAC9D,EAAA,GAAA,CAAI,CAAC,MAAA,EAAQ;AACX,IAAA,OAAO,UAAA;AAAA,EACT;AAEA,EAAA,MAAM,QAAA,EAAU,MAAA,CAAO,MAAM,CAAA;AAC7B,EAAA,GAAA,CAAI,CAAC,MAAA,CAAO,KAAA,CAAM,OAAO,EAAA,GAAK,QAAA,GAAW,CAAA,EAAG;AAC1C,IAAA,OAAO,QAAA,EAAU,aAAA;AAAA,EACnB;AAEA,EAAA,MAAM,OAAA,EAAS,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AAChC,EAAA,GAAA,CAAI,CAAC,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,EAAG;AACzB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAA,EAAS,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA;AAAA,EACxC;AAEA,EAAA,OAAO,UAAA;AACT;AAGA,MAAA,SAAe,iBAAA,CAAkB,QAAA,EAAoC;AACnE,EAAA,MAAM,QAAA,EAAU,MAAM,QAAA,CAAS,IAAA,CAAK,CAAA;AACpC,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,OAAA,EAAS,QAAA,EAAW,IAAA,CAAK,KAAA,CAAM,OAAO,EAAA,EAAqB,IAAA;AAAA,EAC7D,EAAA,UAAQ;AACN,IAAA,OAAA,EAAS,IAAA;AAAA,EACX;AAEA,EAAA,MAAM,KAAA,mCAAO,MAAA,2BAAQ,KAAA,6BAAO,MAAA,UAAQ,iBAAA;AACpC,EAAA,MAAM,KAAA,mCAAO,MAAA,6BAAQ,KAAA,6BAAO,MAAA,UAAQ,MAAA;AACpC,EAAA,MAAM,QAAA,mCAAU,MAAA,6BAAQ,KAAA,6BAAO,SAAA,UAAW,CAAA,UAAA,EAAa,QAAA,CAAS,MAAM,CAAA,GAAA;AACrC,EAAA;AACiD,EAAA;AAEnB,EAAA;AACjE;AAUwB;AACL,EAAA;AAEA,EAAA;AAEA,EAAA;AAEA,EAAA;AAEA,EAAA;AAEuB,EAAA;AACf,IAAA;AACH,IAAA;AAC4C,IAAA;AACxB,IAAA;AACU,IAAA;AACpD,EAAA;AAEyE,EAAA;AACxB,IAAA;AACP,IAAA;AACtB,MAAA;AACb,MAAA;AACU,MAAA;AACf,IAAA;AAE4D,IAAA;AACvD,MAAA;AACH,MAAA;AACD,IAAA;AAE+D,IAAA;AACtC,MAAA;AACwB,MAAA;AACQ,MAAA;AACnD,QAAA;AACoC,QAAA;AACxC,MAAA;AACH,IAAA;AAEoE,IAAA;AACX,MAAA;AACnB,MAAA;AAClC,QAAA;AACF,MAAA;AACmB,MAAA;AAC0B,MAAA;AACW,MAAA;AACnD,QAAA;AACiC,QAAA;AACrC,MAAA;AACH,IAAA;AAEkB,IAAA;AACgB,MAAA;AAClC,IAAA;AAEyC,IAAA;AAC3C,EAAA;AAE+E,EAAA;AACf,IAAA;AAChD,IAAA;AAChB,EAAA;AACF;AFrByE;AACA;AC3FJ;AACK,EAAA;AAC7C,EAAA;AAClB,IAAA;AACT,EAAA;AAEmC,EAAA;AACE,EAAA;AAC5B,IAAA;AAC6C,MAAA;AACtC,MAAA;AACd,IAAA;AACF,EAAA;AAE4B,EAAA;AAC9B;AAEyB;AACN,EAAA;AAEwB,EAAA;AACZ,IAAA;AACG,MAAA;AACd,MAAA;AACC,MAAA;AACK,MAAA;AACK,MAAA;AAC1B,IAAA;AACH,EAAA;AAE+E,EAAA;AACV,IAAA;AACiB,IAAA;AACtF,EAAA;AAEwD,EAAA;AACa,IAAA;AACrE,EAAA;AAEyE,EAAA;AACA,IAAA;AAC7D,MAAA;AACmC,MAAA;AAC5C,IAAA;AACH,EAAA;AAEgE,EAAA;AACY,IAAA;AAChE,MAAA;AACT,IAAA;AACH,EAAA;AAEoE,EAAA;AACD,IAAA;AACvD,MAAA;AACmC,MAAA;AAC5C,IAAA;AACH,EAAA;AAE4E,EAAA;AACP,IAAA;AACY,IAAA;AACjF,EAAA;AAE+D,EAAA;AACQ,IAAA;AAC3D,MAAA;AACT,IAAA;AACH,EAAA;AAEsD,EAAA;AACyB,IAAA;AAC/E,EAAA;AAEiD,EAAA;AACwB,IAAA;AACzE,EAAA;AACF;ADgFyE;AACA;AGtKzB;AACjB,iBAAA;AAET,kBAAA;AAE2B,kBAAA;AAE9B,EAAA;AAEA,EAAA;AAEA,EAAA;AAEA,EAAA;AAEuB,EAAA;AAChB,IAAA;AACO,IAAA;AACK,IAAA;AAC8B,IAAA;AAClE,EAAA;AAE2D,EAAA;AAC1B,IAAA;AACiB,IAAA;AAC3B,MAAA;AACrB,IAAA;AAC6C,IAAA;AAC/C,EAAA;AAEsC,EAAA;AACX,IAAA;AACZ,MAAA;AACX,MAAA;AACF,IAAA;AAEsC,IAAA;AAClC,IAAA;AACS,MAAA;AACX,IAAA;AACsB,MAAA;AACxB,IAAA;AACF,EAAA;AAE0C,EAAA;AACW,IAAA;AACzC,MAAA;AACC,MAAA;AACS,QAAA;AACoB,QAAA;AACtC,MAAA;AAC2D,MAAA;AAC5D,IAAA;AAEiB,IAAA;AACiB,MAAA;AACS,MAAA;AAC5C,IAAA;AAEkC,IAAA;AAClB,IAAA;AACmC,IAAA;AACrD,EAAA;AACF;AAO6C;AAC1B,EAAA;AAEA,EAAA;AAEY,kBAAA;AAET,kBAAA;AAE2B,kBAAA;AAEV,EAAA;AACX,IAAA;AACwC,IAAA;AAClE,EAAA;AAE2D,EAAA;AAC1B,IAAA;AACiB,IAAA;AAC3B,MAAA;AACrB,IAAA;AAC6C,IAAA;AAC/C,EAAA;AAEsC,EAAA;AACX,IAAA;AACZ,MAAA;AACX,MAAA;AACF,IAAA;AAEsC,IAAA;AAClC,IAAA;AACS,MAAA;AACX,IAAA;AACsB,MAAA;AACxB,IAAA;AACF,EAAA;AAE0C,EAAA;AACS,IAAA;AAE/B,IAAA;AACiB,MAAA;AACvB,MAAA;AACR,QAAA;AAC+D,QAAA;AACjE,MAAA;AACF,IAAA;AAEkC,IAAA;AAClB,IAAA;AACmC,IAAA;AACrD,EAAA;AACF;AH0IyE;AACA;AIzNV;AACzC,EAAA;AACtB;AAEmE;AAC9C,EAAA;AACrB;AAEgF;AACzB,EAAA;AAEjB,EAAA;AACtC;AJwNyE;AACA;AKvRH;AAC/C,EAAA;AACd,EAAA;AACA,IAAA;AACa,MAAA;AAC6B,MAAA;AAC/C,IAAA;AACI,IAAA;AACa,MAAA;AAC6B,MAAA;AAC9C,IAAA;AACF,EAAA;AACF;AAEwE;AACrB,EAAA;AACxC,IAAA;AACT,EAAA;AAC0B,EAAA;AACjB,IAAA;AACT,EAAA;AACyB,EAAA;AAChB,IAAA;AACT,EAAA;AACO,EAAA;AACT;AAEoE;AACpB,EAAA;AAChD;AAEsE;AACpB,EAAA;AAClD;AAE6E;AAChE,EAAA;AACF,IAAA;AACT,EAAA;AAIG,EAAA;AACuD,EAAA;AAC5D;AAE8E;AACjE,EAAA;AACF,IAAA;AACT,EAAA;AAG4B,EAAA;AAIrB,EAAA;AACT;AL4QyE;AACA;AMjVzD;AACA;AACD;AACC;AACK;AAEiC;AAIiB;AACvC,EAAA;AAC+C,EAAA;AACtE,EAAA;AAC2B,IAAA;AACA,IAAA;AACC,IAAA;AACC,IAAA;AACpC,EAAA;AACF;AAE8E;AAC1D,EAAA;AACW,IAAA;AAC7B,EAAA;AAC6C,EAAA;AACY,EAAA;AAC3D;AAEoF;AAC3D,EAAA;AACgB,EAAA;AAClB,EAAA;AACZ,IAAA;AACT,EAAA;AAC6B,EAAA;AACb,IAAA;AAChB,EAAA;AAC4B,EAAA;AACb,IAAA;AACf,EAAA;AACyC,EAAA;AACnB,IAAA;AACI,IAAA;AACR,IAAA;AACd,MAAA;AACF,IAAA;AAC0B,IAAA;AACuB,MAAA;AACd,MAAA;AACnC,IAAA;AACF,EAAA;AACa,EAAA;AACf;AAQkG;AACzC,EAAA;AACA,EAAA;AAC9C,IAAA;AACT,EAAA;AAC2C,EAAA;AACO,EAAA;AACV,EAAA;AACuB,EAAA;AACjE;AAS6G;AACpD,EAAA;AACI,EAAA;AAClD,IAAA;AACT,EAAA;AAEgD,EAAA;AACjB,EAAA;AACsC,EAAA;AAEjC,EAAA;AACT,IAAA;AACkB,IAAA;AACqB,IAAA;AACvD,MAAA;AACT,IAAA;AACF,EAAA;AACO,EAAA;AACT;AN4TyE;AACA;AOtZpB;AACnC,EAAA;AAClB;AAEwF;AACvD,EAAA;AACR,EAAA;AAC6B,EAAA;AAGG,EAAA;AAEF,EAAA;AAEC,EAAA;AACvB,EAAA;AACD,EAAA;AAEvB,EAAA;AACL,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACF,EAAA;AACF;APkZyE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/alexemery/bl/dimes-sdk/dist/index.cjs","sourcesContent":[null,"import { decamelizeKeys } from \"humps\";\nimport type { ContractInfo, CreateOfferParams, Market, Offer, Position, Paginated, CustomerLimit } 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 interface GetMarketsParams {\n cursor?: string;\n limit?: number;\n category?: string;\n status?: string;\n provider?: \"polymarket\" | \"kalshi\";\n}\n\nexport interface GetPositionsParams {\n cursor?: string;\n limit?: number;\n status?: \"open\" | \"closed\";\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 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","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 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 PositionUnwind = CamelizeKeys<Raw[\"CustomerPositionUnwind\"]>;\n\nexport type PositionUnwindList = CamelizeKeys<Raw[\"CustomerPositionUnwindList\"]>;\n\nexport type ContractInfo = CamelizeKeys<Raw[\"CustomerContractInfo\"]>;\n\nexport type CustomerLimit = CamelizeKeys<Raw[\"CustomerLimit\"]>;\n\nexport type CreateTokenResult = CamelizeKeys<Raw[\"CreateTokenResult\"]>;\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 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\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"]}
1
+ {"version":3,"sources":["/Users/alexemery/bl/dimes-sdk/dist/index.cjs","../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"],"names":[],"mappings":"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nC,IAAA;AACF,EAAA;AACa,EAAA;AACf;AAQkG;AACzC,EAAA;AACA,EAAA;AAC9C,IAAA;AACT,EAAA;AAC2C,EAAA;AACO,EAAA;AACV,EAAA;AACuB,EAAA;AACjE;AAS6G;AACpD,EAAA;AACI,EAAA;AAClD,IAAA;AACT,EAAA;AAEgD,EAAA;AACjB,EAAA;AACsC,EAAA;AAEjC,EAAA;AACT,IAAA;AACkB,IAAA;AACqB,IAAA;AACvD,MAAA;AACT,IAAA;AACF,EAAA;AACO,EAAA;AACT;ANiUyE;AACA;AO3ZpB;AACnC,EAAA;AAClB;AAEwF;AACvD,EAAA;AACR,EAAA;AAC6B,EAAA;AAGG,EAAA;AAEF,EAAA;AAEC,EAAA;AACvB,EAAA;AACD,EAAA;AAEvB,EAAA;AACL,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACF,EAAA;AACF;APuZyE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/alexemery/bl/dimes-sdk/dist/index.cjs","sourcesContent":[null,"import { decamelizeKeys } from \"humps\";\nimport type {\n ContractInfo,\n CreateOfferParams,\n CustomerLimit,\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 interface GetMarketsParams {\n cursor?: string;\n limit?: number;\n category?: string;\n status?: string;\n provider?: \"polymarket\" | \"kalshi\";\n}\n\nexport interface GetPositionsParams {\n cursor?: string;\n limit?: number;\n status?: \"open\" | \"closed\";\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","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 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 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 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\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"]}
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 GetMarketsParams, d as GetPositionsParams, H as HintAdjustment, J as JwtAuth, e as JwtAuthOptions, P as Paginated, Q as QuoteHint, h as hintAdjustment, m as marketMovedCodes, q as quoteErrorHint } from './dimes-client-Bs6eTIvn.cjs';
2
- export { D as DimesApiError, a as DimesContractError, b as DimesError } from './dimes-error-DxIoHQzj.cjs';
3
- import { C as CreateOfferParams, O as Offer, M as Market, P as Position } from './aliases-DzVxkXtK.cjs';
4
- export { a as CamelizeKeys, b as ClosedPosition, c as ContractInfo, d as CreateTokenResult, e as CustomerLimit, f as MarketFees, g as MarketLeverage, h as MarketMaxLeveragePerNotional, i as MarketPrices, j as MarketSidedEligibility, k as MarketSidedMaxLeveragePerNotional, l as OpenPosition, m as OriginationTier, n as PositionClosedFees, o as PositionCurrent, p as PositionEntry, q as PositionFailure, r as PositionOpenFees, s as PositionResult, t as PositionRisk, u as PositionTiming, v as PositionUnwind, w as PositionUnwindList, x as isClosedPosition, y as isOpenPosition, z as leverageMaxBps } from './aliases-DzVxkXtK.cjs';
5
- import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from './quote-CZqCqt8R.cjs';
6
- export { M as MarketMovedEvent, S as Side } from './quote-CZqCqt8R.cjs';
7
- export { P as PositionEvent, a as PositionEventType, p as positionEventTypes } from './types--ysRe5Os.cjs';
1
+ export { A as ApiKeyAuth, a as ApiKeyAuthOptions, b as AuthProvider, C as CorrectedField, D as DimesClient, c as DimesClientOptions, G as GetMarketsParams, d as GetPositionsParams, H as HintAdjustment, J as JwtAuth, e as JwtAuthOptions, P as Paginated, Q as QuoteHint, h as hintAdjustment, m as marketMovedCodes, q as quoteErrorHint } from './dimes-client-C2hT6mZ8.cjs';
2
+ export { D as DimesApiError, a as DimesContractError, b as DimesError } from './dimes-error-BW0wd1ib.cjs';
3
+ import { C as CreateOfferParams, O as Offer, M as Market, P as Position } from './aliases-BGqwpyE-.cjs';
4
+ export { a as CamelizeKeys, b as ClosedPosition, c as ContractInfo, d as CreateTokenResult, e as CustomerLimit, f as MarketFees, g as MarketLeverage, h as MarketMaxLeveragePerNotional, i as MarketPrices, j as MarketSidedEligibility, k as MarketSidedMaxLeveragePerNotional, l as OpenPosition, m as OriginationTier, n as PositionClosedFees, o as PositionCurrent, p as PositionEntry, q as PositionFailure, r as PositionOpenFees, s as PositionResult, t as PositionRisk, u as PositionTiming, v as PositionUnwind, w as PositionUnwindList, x as isClosedPosition, y as isOpenPosition, z as leverageMaxBps } from './aliases-BGqwpyE-.cjs';
5
+ import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from './quote-BcVJ0U0l.cjs';
6
+ export { M as MarketMovedEvent, S as Side } from './quote-BcVJ0U0l.cjs';
7
+ export { P as PositionEvent, a as PositionEventType, p as positionEventTypes } from './types-BwPF-kCK.cjs';
8
8
 
9
9
  type Params = Record<string, unknown> | null;
10
10
 
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 GetMarketsParams, d as GetPositionsParams, H as HintAdjustment, J as JwtAuth, e as JwtAuthOptions, P as Paginated, Q as QuoteHint, h as hintAdjustment, m as marketMovedCodes, q as quoteErrorHint } from './dimes-client-D88pW-Lm.js';
2
- export { D as DimesApiError, a as DimesContractError, b as DimesError } from './dimes-error-BHVY6vDv.js';
3
- import { C as CreateOfferParams, O as Offer, M as Market, P as Position } from './aliases-DzVxkXtK.js';
4
- export { a as CamelizeKeys, b as ClosedPosition, c as ContractInfo, d as CreateTokenResult, e as CustomerLimit, f as MarketFees, g as MarketLeverage, h as MarketMaxLeveragePerNotional, i as MarketPrices, j as MarketSidedEligibility, k as MarketSidedMaxLeveragePerNotional, l as OpenPosition, m as OriginationTier, n as PositionClosedFees, o as PositionCurrent, p as PositionEntry, q as PositionFailure, r as PositionOpenFees, s as PositionResult, t as PositionRisk, u as PositionTiming, v as PositionUnwind, w as PositionUnwindList, x as isClosedPosition, y as isOpenPosition, z as leverageMaxBps } from './aliases-DzVxkXtK.js';
5
- import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from './quote-Cy7ie8yT.js';
6
- export { M as MarketMovedEvent, S as Side } from './quote-Cy7ie8yT.js';
7
- export { P as PositionEvent, a as PositionEventType, p as positionEventTypes } from './types-BcUKsoEs.js';
1
+ export { A as ApiKeyAuth, a as ApiKeyAuthOptions, b as AuthProvider, C as CorrectedField, D as DimesClient, c as DimesClientOptions, G as GetMarketsParams, d as GetPositionsParams, H as HintAdjustment, J as JwtAuth, e as JwtAuthOptions, P as Paginated, Q as QuoteHint, h as hintAdjustment, m as marketMovedCodes, q as quoteErrorHint } from './dimes-client-DFAKtIeI.js';
2
+ export { D as DimesApiError, a as DimesContractError, b as DimesError } from './dimes-error-IBJ5eff6.js';
3
+ import { C as CreateOfferParams, O as Offer, M as Market, P as Position } from './aliases-BGqwpyE-.js';
4
+ export { a as CamelizeKeys, b as ClosedPosition, c as ContractInfo, d as CreateTokenResult, e as CustomerLimit, f as MarketFees, g as MarketLeverage, h as MarketMaxLeveragePerNotional, i as MarketPrices, j as MarketSidedEligibility, k as MarketSidedMaxLeveragePerNotional, l as OpenPosition, m as OriginationTier, n as PositionClosedFees, o as PositionCurrent, p as PositionEntry, q as PositionFailure, r as PositionOpenFees, s as PositionResult, t as PositionRisk, u as PositionTiming, v as PositionUnwind, w as PositionUnwindList, x as isClosedPosition, y as isOpenPosition, z as leverageMaxBps } from './aliases-BGqwpyE-.js';
5
+ import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from './quote-BVMZb0T8.js';
6
+ export { M as MarketMovedEvent, S as Side } from './quote-BVMZb0T8.js';
7
+ export { P as PositionEvent, a as PositionEventType, p as positionEventTypes } from './types-C7nWOxO-.js';
8
8
 
9
9
  type Params = Record<string, unknown> | null;
10
10
 
package/dist/index.mjs CHANGED
@@ -4,17 +4,17 @@ import {
4
4
  hintAdjustment,
5
5
  marketMovedCodes,
6
6
  quoteErrorHint
7
- } from "./chunk-EI5V5Z6G.mjs";
7
+ } from "./chunk-SGA6OZEU.mjs";
8
8
  import {
9
9
  DimesApiError,
10
10
  DimesContractError,
11
11
  DimesError,
12
12
  formatErrorMessage,
13
13
  resolveFriendlyMessage
14
- } from "./chunk-S65RABUT.mjs";
14
+ } from "./chunk-BVILILIV.mjs";
15
15
  import {
16
16
  positionEventTypes
17
- } from "./chunk-YUCGNELT.mjs";
17
+ } from "./chunk-4MO3HKMS.mjs";
18
18
 
19
19
  // src/client/dimes-client.ts
20
20
  import { decamelizeKeys } from "humps";
@@ -170,6 +170,11 @@ var DimesClient = class {
170
170
  const query = params ? buildQueryFromEntries(Object.entries(params)) : "";
171
171
  return this.http.requestList(`/v1/prediction-markets/positions${query}`);
172
172
  }
173
+ async getPositionTransactions(positionId) {
174
+ return this.http.request(
175
+ `/v1/prediction-markets/positions/${encodeURIComponent(positionId)}/transactions`
176
+ );
177
+ }
173
178
  async cancelPosition(positionId) {
174
179
  await this.http.request(`/v1/prediction-markets/positions/${encodeURIComponent(positionId)}/cancel`, {
175
180
  method: "POST"