@dimes-dot-fi/sdk 1.0.0 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,236 @@
1
+ <p align="center">
2
+ <strong>@dimes-dot-fi/sdk</strong>
3
+ </p>
4
+
5
+ <p align="center">
6
+ TypeScript SDK for building on <a href="https://dimes.fi">Dimes Multiply</a> — leveraged prediction markets.
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/@dimes-dot-fi/sdk"><img src="https://img.shields.io/npm/v/@dimes-dot-fi/sdk.svg" alt="npm version"></a>
11
+ <a href="https://www.npmjs.com/package/@dimes-dot-fi/sdk"><img src="https://img.shields.io/npm/dm/@dimes-dot-fi/sdk.svg" alt="npm downloads"></a>
12
+ <a href="https://github.com/nicktids"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="license"></a>
13
+ <a href="https://docs.dimes.fi"><img src="https://img.shields.io/badge/docs-dimes.fi-black.svg" alt="docs"></a>
14
+ </p>
15
+
16
+ ---
17
+
18
+ Dimes Multiply is a middle-layer protocol that lets trading terminals, wallets, and apps offer up to 10x leveraged exposure on prediction markets (Polymarket) without building internal leverage infrastructure. This SDK gives you a type-safe TypeScript client for the Multiply API, a quote engine with auto-correction, React hooks, and viem-compatible on-chain transaction builders.
19
+
20
+ ## Features
21
+
22
+ - **Full API client** — typed methods for markets, quotes, positions, and contract info with automatic camelCase conversion
23
+ - **Quote engine** — `executeQuote()` handles the draft → promote flow, retries on market-moved errors, and auto-corrects leverage/collateral/slippage
24
+ - **React hooks** — `useMarkets()`, `usePositions()`, `useQuote()`, `useContractInfo()`, and more — works with your existing TanStack Query setup
25
+ - **On-chain builders** — viem-compatible transaction data for `createPosition`, `approve`, and `requestClose`
26
+ - **Signature verification** — verify quote signatures against the contract-info endpoint with per-client caching
27
+ - **Auth management** — `ApiKeyAuth` auto-obtains and refreshes JWTs; `JwtAuth` for static or dynamic tokens
28
+ - **Error handling** — typed `DimesApiError` with friendly messages, structured hints, and programmatic correction suggestions
29
+ - **Tree-shakeable** — three entry points, ESM + CJS, zero runtime dependencies beyond `humps`
30
+
31
+ ## Install
32
+
33
+ ```bash
34
+ npm install @dimes-dot-fi/sdk
35
+ ```
36
+
37
+ ## Entry Points
38
+
39
+ | Import | What | Peer deps |
40
+ |--------|------|-----------|
41
+ | `@dimes-dot-fi/sdk` | Client, quote engine, errors, types | — |
42
+ | `@dimes-dot-fi/sdk/react` | React hooks + provider | `react`, `@tanstack/react-query` |
43
+ | `@dimes-dot-fi/sdk/contract` | Tx builders, signature verification | `viem` |
44
+
45
+ ## Quick Start
46
+
47
+ ### Client setup
48
+
49
+ Your backend holds the Dimes API key and exposes an endpoint that generates JWTs for your users (see [Authentication](https://docs.dimes.fi/for-developers/authentication)). Point `JwtAuth` at that endpoint — it fetches, caches, and auto-refreshes tokens:
50
+
51
+ ```typescript
52
+ import { DimesClient, JwtAuth } from "@dimes-dot-fi/sdk";
53
+
54
+ const client = new DimesClient({
55
+ auth: new JwtAuth({
56
+ tokenUrl: "https://your-backend.com/api/dimes-token",
57
+ }),
58
+ });
59
+ ```
60
+
61
+ For server-side (Node.js) where you hold the API key directly:
62
+
63
+ ```typescript
64
+ import { DimesClient, ApiKeyAuth } from "@dimes-dot-fi/sdk";
65
+
66
+ const client = new DimesClient({
67
+ auth: new ApiKeyAuth({
68
+ apiKey: process.env.DIMES_API_KEY,
69
+ walletAddress: "0x1234...abcd",
70
+ }),
71
+ });
72
+ ```
73
+
74
+ ### Browse markets
75
+
76
+ ```typescript
77
+ const { data: markets } = await client.getMarkets();
78
+ const market = await client.getMarket("will-btc-hit-100k-2026");
79
+
80
+ console.log(market.leverage.maxBps); // 100000 (10x)
81
+ ```
82
+
83
+ ### Execute a quote
84
+
85
+ ```typescript
86
+ import { executeQuote } from "@dimes-dot-fi/sdk";
87
+
88
+ const result = await executeQuote(client, {
89
+ marketTicker: "will-btc-hit-100k-2026",
90
+ side: "yes",
91
+ collateralUsd: 25,
92
+ leverageBps: 50000, // 5x
93
+ slippageBps: 300,
94
+ });
95
+
96
+ console.log(result.offer.entryPriceUsd);
97
+ console.log(result.corrections); // auto-applied adjustments, if any
98
+ ```
99
+
100
+ `executeQuote` handles the full lifecycle: creates a draft quote, promotes it, retries on market-moved errors, and auto-corrects parameters when the API suggests adjustments. Hook into each stage:
101
+
102
+ ```typescript
103
+ const result = await executeQuote(client, params, {
104
+ onDraftReady: (draft) => showPreview(draft),
105
+ onMarketMoved: (event) => showRetryNotice(event.retryCount),
106
+ onCorrection: (adj) => showAdjustment(adj.field, adj.toLabel),
107
+ maxRetries: 3,
108
+ });
109
+ ```
110
+
111
+ ### Open a position on-chain
112
+
113
+ ```typescript
114
+ import { buildCreatePositionTx, buildApproveTx, verifyOfferSignature } from "@dimes-dot-fi/sdk/contract";
115
+
116
+ // Verify the quote signature
117
+ await verifyOfferSignature(client, result.offer, userAddress);
118
+
119
+ // Build viem-compatible transactions
120
+ const approveTx = buildApproveTx(usdcAddress, vaultAddress, amount);
121
+ const createTx = buildCreatePositionTx(result.offer);
122
+
123
+ await walletClient.writeContract(approveTx);
124
+ await walletClient.writeContract(createTx);
125
+ ```
126
+
127
+ ### Close a position
128
+
129
+ ```typescript
130
+ import { buildRequestCloseTx } from "@dimes-dot-fi/sdk/contract";
131
+
132
+ const closeTx = buildRequestCloseTx(vaultAddress, positionKey);
133
+ await walletClient.writeContract(closeTx);
134
+ ```
135
+
136
+ ## React
137
+
138
+ ```tsx
139
+ import { DimesClient, JwtAuth } from "@dimes-dot-fi/sdk";
140
+ import { DimesProvider } from "@dimes-dot-fi/sdk/react";
141
+
142
+ const client = new DimesClient({
143
+ auth: new JwtAuth({ tokenUrl: "https://your-backend.com/api/dimes-token" }),
144
+ });
145
+
146
+ function App() {
147
+ return (
148
+ <QueryClientProvider client={queryClient}>
149
+ <DimesProvider client={client}>
150
+ <YourApp />
151
+ </DimesProvider>
152
+ </QueryClientProvider>
153
+ );
154
+ }
155
+ ```
156
+
157
+ All hooks accept optional `queryOptions` for full control over caching, polling, and `queryClient` selection:
158
+
159
+ ```tsx
160
+ import { useMarkets, usePositions, useQuote, useContractInfo } from "@dimes-dot-fi/sdk/react";
161
+
162
+ function Dashboard() {
163
+ const { data: markets } = useMarkets();
164
+ const { data: positions } = usePositions({ status: "open" });
165
+ const { data: contractInfo } = useContractInfo(); // cached, staleTime: Infinity
166
+ const { state, execute, reset } = useQuote();
167
+
168
+ // state.phase: "idle" | "loading-draft" | "draft-ready" | "promoting" | "promoted" | "error"
169
+ }
170
+ ```
171
+
172
+ ## Error Handling
173
+
174
+ ```typescript
175
+ import { DimesApiError, formatErrorMessage, quoteErrorHint, hintAdjustment } from "@dimes-dot-fi/sdk";
176
+
177
+ try {
178
+ await executeQuote(client, params);
179
+ } catch (err) {
180
+ if (err instanceof DimesApiError) {
181
+ // User-friendly message for any error code
182
+ console.log(formatErrorMessage(err.code, err.params));
183
+
184
+ // Programmatic correction hints for leverage/collateral/slippage errors
185
+ const hint = quoteErrorHint(err.code, err.params, { leverageBps: params.leverageBps });
186
+ const adj = hintAdjustment(hint, params);
187
+ if (adj) {
188
+ console.log(`Suggestion: adjust ${adj.field} to ${adj.toLabel}`);
189
+ }
190
+ }
191
+ }
192
+ ```
193
+
194
+ The SDK's HTTP client automatically retries on 429 (rate limit) with `Retry-After` support and refreshes auth on 401.
195
+
196
+ ## Sandbox
197
+
198
+ ```typescript
199
+ const client = new DimesClient({
200
+ baseUrl: "https://api-sandbox.dimes.fi",
201
+ auth: new ApiKeyAuth({
202
+ apiKey: "dm_sbx_skey_...",
203
+ walletAddress: "0x...",
204
+ }),
205
+ });
206
+ ```
207
+
208
+ Same API, same contracts, fake USDC. Get a sandbox key via the [Telegram link on dimes.fi](https://dimes.fi).
209
+
210
+ ## API Method Reference
211
+
212
+ | Endpoint | Method | React Hook |
213
+ |----------|--------|------------|
214
+ | `GET /markets` | `client.getMarkets()` | `useMarkets()` |
215
+ | `GET /markets/:ticker` | `client.getMarket(ticker)` | `useMarket(ticker)` |
216
+ | `GET /contract-info` | `client.getContractInfo()` | `useContractInfo()` |
217
+ | `GET /positions` | `client.getPositions()` | `usePositions()` |
218
+ | `GET /limits` | `client.getLimits()` | `useLimits()` |
219
+ | `POST /draft-quotes` | `client.createDraftQuote()` | — |
220
+ | `POST /promoted-quotes/:id` | `client.promoteDraftQuote()` | — |
221
+ | `POST /quotes` | `client.createQuote()` | — |
222
+ | Draft → Promote (full flow) | `executeQuote()` | `useQuote()` |
223
+ | Cancel position | `client.cancelPosition()` | `useCancelPosition()` |
224
+
225
+ ## Documentation
226
+
227
+ - [**Quickstart**](https://docs.dimes.fi/for-developers/quickstart) — end-to-end in 6 steps
228
+ - [**SDK Installation**](https://docs.dimes.fi/for-developers/sdk-installation) — setup, auth, and peer deps
229
+ - [**API Reference**](https://docs.dimes.fi/for-developers/api-reference) — full endpoint documentation
230
+ - [**Error Handling**](https://docs.dimes.fi/for-developers/error-handling) — error codes and structured hints
231
+ - [**On-Chain Integration**](https://docs.dimes.fi/for-developers/on-chain-integration) — wallet patterns and contract ABIs
232
+ - [**UI Guidelines**](https://docs.dimes.fi/for-developers/ui-guidelines) — leverage sliders, quote flow, position cards
233
+
234
+ ## License
235
+
236
+ MIT
@@ -1,7 +1,7 @@
1
1
  import { Abi, Address, Hex } from 'viem';
2
2
  export { Address, Hex } from 'viem';
3
- import { O as Offer, D as DimesClient } from '../dimes-client-BLIAuK4M.cjs';
4
- import { a as DimesContractError } from '../dimes-error-DxzsfQo6.cjs';
3
+ import { O as Offer, D as DimesClient } from '../dimes-client-C8wtMofm.cjs';
4
+ import { a as DimesContractError } from '../dimes-error-BfhINan2.cjs';
5
5
 
6
6
  declare const vaultAbi: Abi;
7
7
  declare const erc20Abi: readonly [{
@@ -1,7 +1,7 @@
1
1
  import { Abi, Address, Hex } from 'viem';
2
2
  export { Address, Hex } from 'viem';
3
- import { O as Offer, D as DimesClient } from '../dimes-client-BLIAuK4M.js';
4
- import { a as DimesContractError } from '../dimes-error-BtDMi3Kv.js';
3
+ import { O as Offer, D as DimesClient } from '../dimes-client-C8wtMofm.js';
4
+ import { a as DimesContractError } from '../dimes-error-DJTpDU75.js';
5
5
 
6
6
  declare const vaultAbi: Abi;
7
7
  declare const erc20Abi: readonly [{
@@ -1197,12 +1197,19 @@ declare class ApiKeyAuth implements AuthProvider {
1197
1197
  private fetchToken;
1198
1198
  }
1199
1199
  interface JwtAuthOptions {
1200
- token: string | (() => Promise<string>);
1200
+ tokenUrl: string;
1201
+ fetch?: typeof globalThis.fetch;
1201
1202
  }
1202
1203
  declare class JwtAuth implements AuthProvider {
1203
- private readonly tokenOrFn;
1204
+ private readonly fetchFn;
1205
+ private readonly tokenUrl;
1206
+ private jwt;
1207
+ private expiresAt;
1208
+ private refreshPromise;
1204
1209
  constructor(options: JwtAuthOptions);
1205
1210
  getHeaders(): Promise<Record<string, string>>;
1211
+ refresh(): Promise<void>;
1212
+ private fetchToken;
1206
1213
  }
1207
1214
 
1208
1215
  interface DimesClientOptions {
@@ -1197,12 +1197,19 @@ declare class ApiKeyAuth implements AuthProvider {
1197
1197
  private fetchToken;
1198
1198
  }
1199
1199
  interface JwtAuthOptions {
1200
- token: string | (() => Promise<string>);
1200
+ tokenUrl: string;
1201
+ fetch?: typeof globalThis.fetch;
1201
1202
  }
1202
1203
  declare class JwtAuth implements AuthProvider {
1203
- private readonly tokenOrFn;
1204
+ private readonly fetchFn;
1205
+ private readonly tokenUrl;
1206
+ private jwt;
1207
+ private expiresAt;
1208
+ private refreshPromise;
1204
1209
  constructor(options: JwtAuthOptions);
1205
1210
  getHeaders(): Promise<Record<string, string>>;
1211
+ refresh(): Promise<void>;
1212
+ private fetchToken;
1206
1213
  }
1207
1214
 
1208
1215
  interface DimesClientOptions {
@@ -1,4 +1,4 @@
1
- import { Q as QuoteHint } from './dimes-client-BLIAuK4M.cjs';
1
+ import { Q as QuoteHint } from './dimes-client-C8wtMofm.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-BLIAuK4M.js';
1
+ import { Q as QuoteHint } from './dimes-client-C8wtMofm.js';
2
2
 
3
3
  declare class DimesError extends Error {
4
4
  readonly code: string;
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
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; } var _class;
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; } var _class; var _class2;
2
2
 
3
3
 
4
4
 
@@ -232,16 +232,49 @@ var ApiKeyAuth = (_class = class {
232
232
  this.expiresAt = new Date(data.expires_at).getTime();
233
233
  }
234
234
  }, _class);
235
- var JwtAuth = class {
235
+ var JwtAuth = (_class2 = class {
236
236
 
237
- constructor(options) {
238
- this.tokenOrFn = options.token;
237
+
238
+ __init4() {this.jwt = null}
239
+ __init5() {this.expiresAt = 0}
240
+ __init6() {this.refreshPromise = null}
241
+ constructor(options) {;_class2.prototype.__init4.call(this);_class2.prototype.__init5.call(this);_class2.prototype.__init6.call(this);
242
+ this.tokenUrl = options.tokenUrl;
243
+ this.fetchFn = _nullishCoalesce(options.fetch, () => ( globalThis.fetch.bind(globalThis)));
239
244
  }
240
245
  async getHeaders() {
241
- const token = typeof this.tokenOrFn === "function" ? await this.tokenOrFn() : this.tokenOrFn;
242
- return { Authorization: `Bearer ${token}` };
246
+ const TOKEN_EXPIRY_BUFFER_MS = 3e4;
247
+ if (!this.jwt || Date.now() >= this.expiresAt - TOKEN_EXPIRY_BUFFER_MS) {
248
+ await this.refresh();
249
+ }
250
+ return { Authorization: `Bearer ${this.jwt}` };
243
251
  }
244
- };
252
+ async refresh() {
253
+ if (this.refreshPromise) {
254
+ await this.refreshPromise;
255
+ return;
256
+ }
257
+ this.refreshPromise = this.fetchToken();
258
+ try {
259
+ await this.refreshPromise;
260
+ } finally {
261
+ this.refreshPromise = null;
262
+ }
263
+ }
264
+ async fetchToken() {
265
+ const response = await this.fetchFn(this.tokenUrl);
266
+ if (!response.ok) {
267
+ const text = await response.text();
268
+ throw new (0, _chunkXXTTXLCTcjs.DimesError)(
269
+ "auth_token_failed",
270
+ `Failed to fetch token from ${this.tokenUrl} (${response.status}): ${text}`
271
+ );
272
+ }
273
+ const data = await response.json();
274
+ this.jwt = data.token;
275
+ this.expiresAt = new Date(data.expires_at).getTime();
276
+ }
277
+ }, _class2);
245
278
 
246
279
  // src/types/aliases.ts
247
280
  function isOpenPosition(p) {
@@ -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"],"names":[],"mappings":"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","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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const message = parsed?.error?.message ?? code ?? rawBody ?? `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 token: string | (() => Promise<string>);\n}\n\nexport class JwtAuth implements AuthProvider {\n private readonly tokenOrFn: string | (() => Promise<string>);\n\n constructor(options: JwtAuthOptions) {\n this.tokenOrFn = options.token;\n }\n\n public async getHeaders(): Promise<Record<string, string>> {\n const token = typeof this.tokenOrFn === \"function\" ? await this.tokenOrFn() : this.tokenOrFn;\n return { Authorization: `Bearer ${token}` };\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 MarketFees = CamelizeKeys<Raw[\"CustomerFees\"]>;\n\nexport type MarketPrices = CamelizeKeys<Raw[\"CustomerMarketPrices\"]>;\n\nexport type OriginationTier = CamelizeKeys<Raw[\"CustomerOriginationTier\"]>;\n\nexport type Offer = CamelizeKeys<Raw[\"ApiCustomerOffer\"]>;\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"]}
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"],"names":[],"mappings":"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","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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const message = parsed?.error?.message ?? code ?? rawBody ?? `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 MarketFees = CamelizeKeys<Raw[\"CustomerFees\"]>;\n\nexport type MarketPrices = CamelizeKeys<Raw[\"CustomerMarketPrices\"]>;\n\nexport type OriginationTier = CamelizeKeys<Raw[\"CustomerOriginationTier\"]>;\n\nexport type Offer = CamelizeKeys<Raw[\"ApiCustomerOffer\"]>;\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"]}
package/dist/index.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- import { C as CreateOfferParams, O as Offer } from './dimes-client-BLIAuK4M.cjs';
2
- export { A as ApiKeyAuth, a as ApiKeyAuthOptions, b as AuthProvider, c as CamelizeKeys, d as ClosedPosition, e as ContractInfo, f as CorrectedField, g as CreateTokenResult, h as CustomerLimit, D as DimesClient, i as DimesClientOptions, G as GetMarketsParams, j as GetPositionsParams, H as HintAdjustment, J as JwtAuth, k as JwtAuthOptions, M as Market, l as MarketFees, m as MarketLeverage, n as MarketPrices, o as OpenPosition, p as OriginationTier, P as Paginated, q as Position, r as PositionClosedFees, s as PositionCurrent, t as PositionEntry, u as PositionFailure, v as PositionOpenFees, w as PositionResult, x as PositionRisk, y as PositionTiming, z as PositionUnwind, B as PositionUnwindList, Q as QuoteHint, E as hintAdjustment, F as isClosedPosition, I as isOpenPosition, K as leverageMaxBps, L as marketMovedCodes, N as quoteErrorHint } from './dimes-client-BLIAuK4M.cjs';
3
- export { D as DimesApiError, a as DimesContractError, b as DimesError } from './dimes-error-DxzsfQo6.cjs';
4
- import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from './quote-ByZJRoPf.cjs';
5
- export { M as MarketMovedEvent, S as Side } from './quote-ByZJRoPf.cjs';
1
+ import { C as CreateOfferParams, O as Offer } from './dimes-client-C8wtMofm.cjs';
2
+ export { A as ApiKeyAuth, a as ApiKeyAuthOptions, b as AuthProvider, c as CamelizeKeys, d as ClosedPosition, e as ContractInfo, f as CorrectedField, g as CreateTokenResult, h as CustomerLimit, D as DimesClient, i as DimesClientOptions, G as GetMarketsParams, j as GetPositionsParams, H as HintAdjustment, J as JwtAuth, k as JwtAuthOptions, M as Market, l as MarketFees, m as MarketLeverage, n as MarketPrices, o as OpenPosition, p as OriginationTier, P as Paginated, q as Position, r as PositionClosedFees, s as PositionCurrent, t as PositionEntry, u as PositionFailure, v as PositionOpenFees, w as PositionResult, x as PositionRisk, y as PositionTiming, z as PositionUnwind, B as PositionUnwindList, Q as QuoteHint, E as hintAdjustment, F as isClosedPosition, I as isOpenPosition, K as leverageMaxBps, L as marketMovedCodes, N as quoteErrorHint } from './dimes-client-C8wtMofm.cjs';
3
+ export { D as DimesApiError, a as DimesContractError, b as DimesError } from './dimes-error-BfhINan2.cjs';
4
+ import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from './quote-CH01NmnL.cjs';
5
+ export { M as MarketMovedEvent, S as Side } from './quote-CH01NmnL.cjs';
6
6
 
7
7
  type Params = Record<string, unknown> | null;
8
8
 
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { C as CreateOfferParams, O as Offer } from './dimes-client-BLIAuK4M.js';
2
- export { A as ApiKeyAuth, a as ApiKeyAuthOptions, b as AuthProvider, c as CamelizeKeys, d as ClosedPosition, e as ContractInfo, f as CorrectedField, g as CreateTokenResult, h as CustomerLimit, D as DimesClient, i as DimesClientOptions, G as GetMarketsParams, j as GetPositionsParams, H as HintAdjustment, J as JwtAuth, k as JwtAuthOptions, M as Market, l as MarketFees, m as MarketLeverage, n as MarketPrices, o as OpenPosition, p as OriginationTier, P as Paginated, q as Position, r as PositionClosedFees, s as PositionCurrent, t as PositionEntry, u as PositionFailure, v as PositionOpenFees, w as PositionResult, x as PositionRisk, y as PositionTiming, z as PositionUnwind, B as PositionUnwindList, Q as QuoteHint, E as hintAdjustment, F as isClosedPosition, I as isOpenPosition, K as leverageMaxBps, L as marketMovedCodes, N as quoteErrorHint } from './dimes-client-BLIAuK4M.js';
3
- export { D as DimesApiError, a as DimesContractError, b as DimesError } from './dimes-error-BtDMi3Kv.js';
4
- import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from './quote-CgmTKnIZ.js';
5
- export { M as MarketMovedEvent, S as Side } from './quote-CgmTKnIZ.js';
1
+ import { C as CreateOfferParams, O as Offer } from './dimes-client-C8wtMofm.js';
2
+ export { A as ApiKeyAuth, a as ApiKeyAuthOptions, b as AuthProvider, c as CamelizeKeys, d as ClosedPosition, e as ContractInfo, f as CorrectedField, g as CreateTokenResult, h as CustomerLimit, D as DimesClient, i as DimesClientOptions, G as GetMarketsParams, j as GetPositionsParams, H as HintAdjustment, J as JwtAuth, k as JwtAuthOptions, M as Market, l as MarketFees, m as MarketLeverage, n as MarketPrices, o as OpenPosition, p as OriginationTier, P as Paginated, q as Position, r as PositionClosedFees, s as PositionCurrent, t as PositionEntry, u as PositionFailure, v as PositionOpenFees, w as PositionResult, x as PositionRisk, y as PositionTiming, z as PositionUnwind, B as PositionUnwindList, Q as QuoteHint, E as hintAdjustment, F as isClosedPosition, I as isOpenPosition, K as leverageMaxBps, L as marketMovedCodes, N as quoteErrorHint } from './dimes-client-C8wtMofm.js';
3
+ export { D as DimesApiError, a as DimesContractError, b as DimesError } from './dimes-error-DJTpDU75.js';
4
+ import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from './quote-_6hQton4.js';
5
+ export { M as MarketMovedEvent, S as Side } from './quote-_6hQton4.js';
6
6
 
7
7
  type Params = Record<string, unknown> | null;
8
8
 
package/dist/index.mjs CHANGED
@@ -233,13 +233,46 @@ var ApiKeyAuth = class {
233
233
  }
234
234
  };
235
235
  var JwtAuth = class {
236
- tokenOrFn;
236
+ fetchFn;
237
+ tokenUrl;
238
+ jwt = null;
239
+ expiresAt = 0;
240
+ refreshPromise = null;
237
241
  constructor(options) {
238
- this.tokenOrFn = options.token;
242
+ this.tokenUrl = options.tokenUrl;
243
+ this.fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);
239
244
  }
240
245
  async getHeaders() {
241
- const token = typeof this.tokenOrFn === "function" ? await this.tokenOrFn() : this.tokenOrFn;
242
- return { Authorization: `Bearer ${token}` };
246
+ const TOKEN_EXPIRY_BUFFER_MS = 3e4;
247
+ if (!this.jwt || Date.now() >= this.expiresAt - TOKEN_EXPIRY_BUFFER_MS) {
248
+ await this.refresh();
249
+ }
250
+ return { Authorization: `Bearer ${this.jwt}` };
251
+ }
252
+ async refresh() {
253
+ if (this.refreshPromise) {
254
+ await this.refreshPromise;
255
+ return;
256
+ }
257
+ this.refreshPromise = this.fetchToken();
258
+ try {
259
+ await this.refreshPromise;
260
+ } finally {
261
+ this.refreshPromise = null;
262
+ }
263
+ }
264
+ async fetchToken() {
265
+ const response = await this.fetchFn(this.tokenUrl);
266
+ if (!response.ok) {
267
+ const text = await response.text();
268
+ throw new DimesError(
269
+ "auth_token_failed",
270
+ `Failed to fetch token from ${this.tokenUrl} (${response.status}): ${text}`
271
+ );
272
+ }
273
+ const data = await response.json();
274
+ this.jwt = data.token;
275
+ this.expiresAt = new Date(data.expires_at).getTime();
243
276
  }
244
277
  };
245
278
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/dimes-client.ts","../src/client/http.ts","../src/client/auth.ts","../src/types/aliases.ts"],"sourcesContent":["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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const message = parsed?.error?.message ?? code ?? rawBody ?? `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 token: string | (() => Promise<string>);\n}\n\nexport class JwtAuth implements AuthProvider {\n private readonly tokenOrFn: string | (() => Promise<string>);\n\n constructor(options: JwtAuthOptions) {\n this.tokenOrFn = options.token;\n }\n\n public async getHeaders(): Promise<Record<string, string>> {\n const token = typeof this.tokenOrFn === \"function\" ? await this.tokenOrFn() : this.tokenOrFn;\n return { Authorization: `Bearer ${token}` };\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 MarketFees = CamelizeKeys<Raw[\"CustomerFees\"]>;\n\nexport type MarketPrices = CamelizeKeys<Raw[\"CustomerMarketPrices\"]>;\n\nexport type OriginationTier = CamelizeKeys<Raw[\"CustomerOriginationTier\"]>;\n\nexport type Offer = CamelizeKeys<Raw[\"ApiCustomerOffer\"]>;\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"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/client/dimes-client.ts","../src/client/http.ts","../src/client/auth.ts","../src/types/aliases.ts"],"sourcesContent":["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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const message = parsed?.error?.message ?? code ?? rawBody ?? `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 MarketFees = CamelizeKeys<Raw[\"CustomerFees\"]>;\n\nexport type MarketPrices = CamelizeKeys<Raw[\"CustomerMarketPrices\"]>;\n\nexport type OriginationTier = CamelizeKeys<Raw[\"CustomerOriginationTier\"]>;\n\nexport type Offer = CamelizeKeys<Raw[\"ApiCustomerOffer\"]>;\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"],"mappings":";;;;;;;;;;;;;;;;AAAA,SAAS,sBAAsB;;;ACA/B,SAAS,oBAAoC;AAe7C,IAAM,oBAAoB;AAC1B,IAAM,yBAAyB;AAC/B,IAAM,sBAAsB;AAC5B,IAAM,6BAA6B;AACnC,IAAM,yBAAyB;AAC/B,IAAM,iBAAiB;AACvB,IAAM,gBAAgB;AAEtB,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAEA,SAAS,kBAAkB,QAAuB,SAAyB;AACzE,QAAM,aAAa,yBAAyB,kBAAkB;AAC9D,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,OAAO,MAAM;AAC7B,MAAI,CAAC,OAAO,MAAM,OAAO,KAAK,WAAW,GAAG;AAC1C,WAAO,UAAU;AAAA,EACnB;AAEA,QAAM,SAAS,KAAK,MAAM,MAAM;AAChC,MAAI,CAAC,OAAO,MAAM,MAAM,GAAG;AACzB,WAAO,KAAK,IAAI,GAAG,SAAS,KAAK,IAAI,CAAC;AAAA,EACxC;AAEA,SAAO;AACT;AAGA,eAAe,kBAAkB,UAAoC;AACnE,QAAM,UAAU,MAAM,SAAS,KAAK;AACpC,MAAI;AACJ,MAAI;AACF,aAAS,UAAW,KAAK,MAAM,OAAO,IAAqB;AAAA,EAC7D,QAAQ;AACN,aAAS;AAAA,EACX;AAEA,QAAM,OAAO,QAAQ,OAAO,QAAQ;AACpC,QAAM,OAAO,QAAQ,OAAO,QAAQ;AAEpC,QAAM,UAAU,QAAQ,OAAO,WAAW,QAAQ,WAAW,aAAa,SAAS,MAAM;AACzF,QAAM,YAAY,QAAQ,OAAO;AACjC,QAAM,SAAS,YAAa,aAAa,SAAS,IAAgC;AAElF,QAAM,IAAI,cAAc,EAAE,QAAQ,SAAS,QAAQ,MAAM,MAAM,SAAS,OAAO,CAAC;AAClF;AAUO,IAAM,aAAN,MAAiB;AAAA,EACL;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEjB,YAAY,SAA4B;AACtC,SAAK,UAAU,QAAQ;AACvB,SAAK,OAAO,QAAQ;AACpB,SAAK,UAAU,QAAQ,SAAS,WAAW,MAAM,KAAK,UAAU;AAChE,SAAK,aAAa,QAAQ,cAAc;AACxC,SAAK,kBAAkB,QAAQ,mBAAmB;AAAA,EACpD;AAAA,EAEA,MAAa,QAAW,MAAc,SAAmC;AACvE,UAAM,cAAc,MAAM,KAAK,KAAK,WAAW;AAC/C,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,MAChB,GAAG;AAAA,MACH,GAAI,SAAS;AAAA,IACf;AAEA,QAAI,WAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAC1D,GAAG;AAAA,MACH;AAAA,IACF,CAAC;AAED,QAAI,SAAS,WAAW,qBAAqB,KAAK,KAAK,SAAS;AAC9D,YAAM,KAAK,KAAK,QAAQ;AACxB,YAAM,eAAe,MAAM,KAAK,KAAK,WAAW;AAChD,iBAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,QACtD,GAAG;AAAA,QACH,SAAS,EAAE,GAAG,SAAS,GAAG,aAAa;AAAA,MACzC,CAAC;AAAA,IACH;AAEA,aAAS,UAAU,GAAG,SAAS,WAAW,0BAA0B,UAAU,KAAK,YAAY,WAAW;AACxG,YAAM,UAAU,kBAAkB,SAAS,QAAQ,IAAI,aAAa,GAAG,OAAO;AAC9E,UAAI,UAAU,KAAK,iBAAiB;AAClC;AAAA,MACF;AACA,YAAM,MAAM,OAAO;AACnB,YAAM,YAAY,MAAM,KAAK,KAAK,WAAW;AAC7C,iBAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,QACtD,GAAG;AAAA,QACH,SAAS,EAAE,GAAG,SAAS,GAAG,UAAU;AAAA,MACtC,CAAC;AAAA,IACH;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,kBAAkB,QAAQ;AAAA,IAClC;AAEA,WAAO,aAAa,MAAM,SAAS,KAAK,CAAC;AAAA,EAC3C;AAAA,EAEA,MAAa,YAAe,MAAc,SAAqC;AAC7E,UAAM,SAAS,MAAM,KAAK,QAAuB,MAAM,OAAO;AAC9D,WAAO,OAAO;AAAA,EAChB;AACF;;;ADhHA,SAAS,sBAAsB,SAAsC;AACnE,QAAM,WAAW,QAAQ,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,UAAa,MAAM,IAAI;AACxE,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,IAAI,gBAAgB;AACnC,aAAW,CAAC,KAAK,KAAK,KAAK,UAAU;AACnC,WAAO;AAAA,MACL,IAAI,QAAQ,UAAU,CAAC,MAAM,IAAI,EAAE,YAAY,CAAC,EAAE;AAAA,MAClD,OAAO,KAAK;AAAA,IACd;AAAA,EACF;AAEA,SAAO,IAAI,OAAO,SAAS,CAAC;AAC9B;AAEO,IAAM,cAAN,MAAkB;AAAA,EACN;AAAA,EAEjB,YAAY,SAA6B;AACvC,SAAK,OAAO,IAAI,WAAW;AAAA,MACzB,SAAS,QAAQ,WAAW;AAAA,MAC5B,MAAM,QAAQ;AAAA,MACd,OAAO,QAAQ;AAAA,MACf,YAAY,QAAQ;AAAA,MACpB,iBAAiB,QAAQ;AAAA,IAC3B,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,WAAW,QAAuD;AAC7E,UAAM,QAAQ,SAAS,sBAAsB,OAAO,QAAQ,MAAM,CAAC,IAAI;AACvE,WAAO,KAAK,KAAK,QAA2B,iCAAiC,KAAK,EAAE;AAAA,EACtF;AAAA,EAEA,MAAa,UAAU,QAAiC;AACtD,WAAO,KAAK,KAAK,QAAgB,kCAAkC,mBAAmB,MAAM,CAAC,EAAE;AAAA,EACjG;AAAA,EAEA,MAAa,iBAAiB,QAA2C;AACvE,WAAO,KAAK,KAAK,QAAe,uCAAuC;AAAA,MACrE,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,eAAe,MAAM,CAAC;AAAA,IAC7C,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,kBAAkB,SAAiC;AAC9D,WAAO,KAAK,KAAK,QAAe,0CAA0C,mBAAmB,OAAO,CAAC,IAAI;AAAA,MACvG,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,YAAY,QAA2C;AAClE,WAAO,KAAK,KAAK,QAAe,iCAAiC;AAAA,MAC/D,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,eAAe,MAAM,CAAC;AAAA,IAC7C,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,aAAa,QAAkD;AAC1E,UAAM,QAAQ,SAAS,sBAAsB,OAAO,QAAQ,MAAM,CAAC,IAAI;AACvE,WAAO,KAAK,KAAK,YAAsB,mCAAmC,KAAK,EAAE;AAAA,EACnF;AAAA,EAEA,MAAa,eAAe,YAAmC;AAC7D,UAAM,KAAK,KAAK,QAAiB,oCAAoC,mBAAmB,UAAU,CAAC,WAAW;AAAA,MAC5G,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,kBAAyC;AACpD,WAAO,KAAK,KAAK,QAAsB,sCAAsC;AAAA,EAC/E;AAAA,EAEA,MAAa,YAAoC;AAC/C,WAAO,KAAK,KAAK,QAAuB,+BAA+B;AAAA,EACzE;AACF;;;AErFO,IAAM,aAAN,MAAyC;AAAA,EACtC,MAAqB;AAAA,EAErB,YAAY;AAAA,EAEZ,iBAAuC;AAAA,EAE9B;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,EAEjB,YAAY,SAA4B;AACtC,SAAK,SAAS,QAAQ;AACtB,SAAK,gBAAgB,QAAQ;AAC7B,SAAK,UAAU,QAAQ,WAAW;AAClC,SAAK,UAAU,QAAQ,SAAS,WAAW,MAAM,KAAK,UAAU;AAAA,EAClE;AAAA,EAEA,MAAa,aAA8C;AACzD,UAAM,yBAAyB;AAC/B,QAAI,CAAC,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK,YAAY,wBAAwB;AACtE,YAAM,KAAK,QAAQ;AAAA,IACrB;AACA,WAAO,EAAE,eAAe,UAAU,KAAK,GAAG,GAAG;AAAA,EAC/C;AAAA,EAEA,MAAa,UAAyB;AACpC,QAAI,KAAK,gBAAgB;AACvB,YAAM,KAAK;AACX;AAAA,IACF;AAEA,SAAK,iBAAiB,KAAK,WAAW;AACtC,QAAI;AACF,YAAM,KAAK;AAAA,IACb,UAAE;AACA,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAc,aAA4B;AACxC,UAAM,WAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,OAAO,iCAAiC;AAAA,MAClF,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,KAAK,MAAM;AAAA,MACtC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,gBAAgB,KAAK,cAAc,CAAC;AAAA,IAC7D,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,WAAW,qBAAqB,gCAAgC,SAAS,MAAM,MAAM,IAAI,EAAE;AAAA,IACvG;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,SAAK,MAAM,KAAK;AAChB,SAAK,YAAY,IAAI,KAAK,KAAK,UAAU,EAAE,QAAQ;AAAA,EACrD;AACF;AAOO,IAAM,UAAN,MAAsC;AAAA,EAC1B;AAAA,EAEA;AAAA,EAET,MAAqB;AAAA,EAErB,YAAY;AAAA,EAEZ,iBAAuC;AAAA,EAE/C,YAAY,SAAyB;AACnC,SAAK,WAAW,QAAQ;AACxB,SAAK,UAAU,QAAQ,SAAS,WAAW,MAAM,KAAK,UAAU;AAAA,EAClE;AAAA,EAEA,MAAa,aAA8C;AACzD,UAAM,yBAAyB;AAC/B,QAAI,CAAC,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK,YAAY,wBAAwB;AACtE,YAAM,KAAK,QAAQ;AAAA,IACrB;AACA,WAAO,EAAE,eAAe,UAAU,KAAK,GAAG,GAAG;AAAA,EAC/C;AAAA,EAEA,MAAa,UAAyB;AACpC,QAAI,KAAK,gBAAgB;AACvB,YAAM,KAAK;AACX;AAAA,IACF;AAEA,SAAK,iBAAiB,KAAK,WAAW;AACtC,QAAI;AACF,YAAM,KAAK;AAAA,IACb,UAAE;AACA,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAc,aAA4B;AACxC,UAAM,WAAW,MAAM,KAAK,QAAQ,KAAK,QAAQ;AAEjD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI;AAAA,QACR;AAAA,QACA,8BAA8B,KAAK,QAAQ,KAAK,SAAS,MAAM,MAAM,IAAI;AAAA,MAC3E;AAAA,IACF;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,SAAK,MAAM,KAAK;AAChB,SAAK,YAAY,IAAI,KAAK,KAAK,UAAU,EAAE,QAAQ;AAAA,EACrD;AACF;;;ACpFO,SAAS,eAAe,GAAgC;AAC7D,SAAO,aAAa;AACtB;AAEO,SAAS,iBAAiB,GAAkC;AACjE,SAAO,YAAY;AACrB;AAEO,SAAS,eAAe,KAAqB,MAA4B;AAC9E,QAAM,UAAU,SAAS,QAAQ,IAAI,YAAY,IAAI;AAErD,SAAO,WAAW,IAAI,UAAU,IAAI;AACtC;","names":[]}
@@ -1,4 +1,4 @@
1
- import { O as Offer, H as HintAdjustment } from './dimes-client-BLIAuK4M.cjs';
1
+ import { O as Offer, H as HintAdjustment } from './dimes-client-C8wtMofm.cjs';
2
2
 
3
3
  type Side = "yes" | "no";
4
4
  interface QuoteParams {
@@ -1,4 +1,4 @@
1
- import { O as Offer, H as HintAdjustment } from './dimes-client-BLIAuK4M.js';
1
+ import { O as Offer, H as HintAdjustment } from './dimes-client-C8wtMofm.js';
2
2
 
3
3
  type Side = "yes" | "no";
4
4
  interface QuoteParams {
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { D as DimesClient, O as Offer, H as HintAdjustment, M as Market, G as GetMarketsParams, P as Paginated, j as GetPositionsParams, q as Position, e as ContractInfo, h as CustomerLimit } from '../dimes-client-BLIAuK4M.cjs';
4
- import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from '../quote-ByZJRoPf.cjs';
3
+ import { D as DimesClient, O as Offer, H as HintAdjustment, M as Market, G as GetMarketsParams, P as Paginated, j as GetPositionsParams, q as Position, e as ContractInfo, h as CustomerLimit } from '../dimes-client-C8wtMofm.cjs';
4
+ import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from '../quote-CH01NmnL.cjs';
5
5
  import { UseQueryOptions, UseQueryResult, UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
6
6
 
7
7
  interface DimesProviderProps {
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { D as DimesClient, O as Offer, H as HintAdjustment, M as Market, G as GetMarketsParams, P as Paginated, j as GetPositionsParams, q as Position, e as ContractInfo, h as CustomerLimit } from '../dimes-client-BLIAuK4M.js';
4
- import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from '../quote-CgmTKnIZ.js';
3
+ import { D as DimesClient, O as Offer, H as HintAdjustment, M as Market, G as GetMarketsParams, P as Paginated, j as GetPositionsParams, q as Position, e as ContractInfo, h as CustomerLimit } from '../dimes-client-C8wtMofm.js';
4
+ import { Q as QuoteParams, a as QuoteOptions, b as QuoteResult } from '../quote-_6hQton4.js';
5
5
  import { UseQueryOptions, UseQueryResult, UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
6
6
 
7
7
  interface DimesProviderProps {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dimes-dot-fi/sdk",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "description": "TypeScript SDK for the Dimes prediction market API",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -106,6 +106,9 @@
106
106
  "access": "public"
107
107
  },
108
108
  "pnpm": {
109
- "onlyBuiltDependencies": ["esbuild", "unrs-resolver"]
109
+ "onlyBuiltDependencies": [
110
+ "esbuild",
111
+ "unrs-resolver"
112
+ ]
110
113
  }
111
114
  }