@qtsurfer/api-client 0.14.1 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -163,6 +163,174 @@ export const HalLinkSchema = {
163
163
  },
164
164
  } as const;
165
165
 
166
+ export const AccountSchema = {
167
+ type: "object",
168
+ description: `Your identity and tier limits. No database call behind this one — safe to fetch on every
169
+ page load. Live usage against these limits is a separate resource, \`GET /account/usage\`,
170
+ deliberately: usage changes on every upload/execution and costs a query to compute, this
171
+ one doesn't.
172
+ `,
173
+ required: [
174
+ "userId",
175
+ "tier",
176
+ "maxDatasets",
177
+ "maxDatasetBytes",
178
+ "maxTotalStorageBytes",
179
+ "_links",
180
+ ],
181
+ properties: {
182
+ userId: {
183
+ type: "string",
184
+ description: "Your account id — the JWT `sub` claim.",
185
+ example: "00000000-0000-0000-0000-000000000000",
186
+ },
187
+ tier: {
188
+ type: "string",
189
+ description: "Your current subscription tier.",
190
+ example: "free",
191
+ },
192
+ maxDatasets: {
193
+ type: "integer",
194
+ description: "Maximum number of active datasets your tier allows.",
195
+ example: 3,
196
+ },
197
+ maxDatasetBytes: {
198
+ type: "integer",
199
+ format: "int64",
200
+ description: "Maximum size, in bytes, of a single dataset version.",
201
+ example: 52428800,
202
+ },
203
+ maxTotalStorageBytes: {
204
+ type: "integer",
205
+ format: "int64",
206
+ description: `Maximum combined storage, in bytes, across every dataset, strategy-execution signal,
207
+ and registered strategy on your account — one shared pool, not a separate cap per
208
+ resource type, since they all compete for the same underlying storage. See \`GET
209
+ /account/usage\`'s \`storageBytesUsed\` for your current usage against this number.
210
+ `,
211
+ example: 104857600,
212
+ },
213
+ _links: {
214
+ $ref: "#/components/schemas/AccountLinks",
215
+ },
216
+ },
217
+ } as const;
218
+
219
+ export const AccountLinksSchema = {
220
+ description: "HAL `_links` for `GET /account`",
221
+ type: "object",
222
+ required: ["self", "usage"],
223
+ properties: {
224
+ self: {
225
+ allOf: [
226
+ {
227
+ $ref: "#/components/schemas/HalLink",
228
+ },
229
+ ],
230
+ description: "Link to this resource.",
231
+ },
232
+ usage: {
233
+ allOf: [
234
+ {
235
+ $ref: "#/components/schemas/HalLink",
236
+ },
237
+ ],
238
+ description: "Link to your live usage, `GET /account/usage`.",
239
+ },
240
+ },
241
+ } as const;
242
+
243
+ export const AccountUsageSchema = {
244
+ type: "object",
245
+ description: `Your live usage of the shared storage pool \`GET /account\`'s \`maxTotalStorageBytes\` caps.
246
+ Not guaranteed real-time — a just-completed upload or strategy execution may take a short
247
+ moment to be reflected here.
248
+ `,
249
+ required: [
250
+ "datasetsUsed",
251
+ "datasetBytesUsed",
252
+ "signalsUsed",
253
+ "signalBytesUsed",
254
+ "strategiesUsed",
255
+ "strategyBytesUsed",
256
+ "storageBytesUsed",
257
+ "_links",
258
+ ],
259
+ properties: {
260
+ datasetsUsed: {
261
+ type: "integer",
262
+ description:
263
+ "Active datasets counted — the same set `GET /account`'s `maxDatasets` limits.",
264
+ example: 2,
265
+ },
266
+ datasetBytesUsed: {
267
+ type: "integer",
268
+ format: "int64",
269
+ description: "Combined bytes of every active dataset's current version.",
270
+ example: 15728640,
271
+ },
272
+ signalsUsed: {
273
+ type: "integer",
274
+ description: "Recorded strategy-execution signal uploads.",
275
+ example: 1,
276
+ },
277
+ signalBytesUsed: {
278
+ type: "integer",
279
+ format: "int64",
280
+ description: "Combined bytes of every recorded signal upload.",
281
+ example: 524288,
282
+ },
283
+ strategiesUsed: {
284
+ type: "integer",
285
+ description: "Registered strategies (see `GET /strategies`).",
286
+ example: 4,
287
+ },
288
+ strategyBytesUsed: {
289
+ type: "integer",
290
+ format: "int64",
291
+ description: `Combined bytes of each registered strategy's source plus its latest compiled
292
+ bytecode. Superseded (non-latest) compilations aren't counted.
293
+ `,
294
+ example: 40960,
295
+ },
296
+ storageBytesUsed: {
297
+ type: "integer",
298
+ format: "int64",
299
+ description: `\`datasetBytesUsed + signalBytesUsed + strategyBytesUsed\` — the number checked
300
+ against \`GET /account\`'s \`maxTotalStorageBytes\`.
301
+ `,
302
+ example: 16293888,
303
+ },
304
+ _links: {
305
+ $ref: "#/components/schemas/AccountUsageLinks",
306
+ },
307
+ },
308
+ } as const;
309
+
310
+ export const AccountUsageLinksSchema = {
311
+ description: "HAL `_links` for `GET /account/usage`",
312
+ type: "object",
313
+ required: ["self", "account"],
314
+ properties: {
315
+ self: {
316
+ allOf: [
317
+ {
318
+ $ref: "#/components/schemas/HalLink",
319
+ },
320
+ ],
321
+ description: "Link to this resource.",
322
+ },
323
+ account: {
324
+ allOf: [
325
+ {
326
+ $ref: "#/components/schemas/HalLink",
327
+ },
328
+ ],
329
+ description: "Link to your tier limits, `GET /account`.",
330
+ },
331
+ },
332
+ } as const;
333
+
166
334
  export const InstrumentDetailSchema = {
167
335
  description:
168
336
  "Exchange instrument with per-data-type coverage and market info",
@@ -335,30 +503,20 @@ the dataset instead of its current one. Defaults to the dataset's current versio
335
503
  },
336
504
  cadence: {
337
505
  type: "string",
338
- description: `Output bar cadence for the prepared range. Defaults to the publisher's
339
- native cadence (\`1s\`); coarser cadences are produced on demand via
340
- resampling and stored alongside the native blob in cache. Coarser-than-
341
- source values must be exact multiples of the source cadence — invalid
342
- labels return \`400\`.
343
- `,
344
- enum: [
345
- "1s",
346
- "5s",
347
- "1m",
348
- "3m",
349
- "5m",
350
- "15m",
351
- "30m",
352
- "1h",
353
- "2h",
354
- "4h",
355
- "8h",
356
- "12h",
357
- "1d",
358
- "1w",
359
- "1q",
360
- ],
361
- default: "1s",
506
+ description: `Output bar cadence for the prepared range. Coarser cadences are produced on demand by
507
+ resampling the source and stored alongside the native blob in cache. A target finer
508
+ than the source, or not an exact multiple of it, returns \`400\`. What's accepted, and
509
+ what omitting it means, depends on the source:
510
+
511
+ * Managed exchange — one of \`1s\`, \`5s\`, \`1m\`, \`3m\`, \`5m\`, \`15m\`, \`30m\`, \`1h\`, \`2h\`,
512
+ \`4h\`, \`8h\`, \`12h\`, \`1d\`, \`1w\`, \`1q\`; any other label returns \`400\`. Omitted = \`1s\`,
513
+ the publisher's native cadence.
514
+ * Dataset (\`exchangeId: user\`) — omitted = the dataset version's own discovered
515
+ \`cadence\` (see \`DatasetVersion.cadence\`), served as-is. Any cadence equal to or
516
+ coarser than it and an exact multiple of it is accepted, including ones outside the
517
+ managed-exchange list (e.g. \`15s\`); an \`rt\` dataset can be resampled to any fixed
518
+ cadence.
519
+ `,
362
520
  },
363
521
  },
364
522
  example: {
@@ -379,14 +537,15 @@ export const JobStateSchema = {
379
537
  description:
380
538
  "Identifier for the job's execution context. Its current shape is a colon-delimited string encoding the data source type, an internal user id, the exchange, the job id, and the instrument — but that structure is not a committed contract and may change without notice. Treat it as an opaque token: store and pass it back, don't parse it.",
381
539
  example:
382
- "jctx:ticker:76b90203-03c2-46f6-b366-9944f167e818:binance:5ikyamio8b3v9wcnfxztzg:btc/usdt:0vicnz3thzhrqvfczks1pu",
540
+ "jctx:ticker:00000000-0000-0000-0000-000000000000:binance:5ikyamio8b3v9wcnfxztzg:btc/usdt:0vicnz3thzhrqvfczks1pu",
383
541
  },
384
542
  status: {
385
543
  type: "string",
386
544
  description: `Current status of the job. Treat \`Completed | Aborted | Failed\` as
387
545
  terminal; \`New | Started\` mean keep polling. A single-instrument prepare
388
546
  is always terminal (\`Completed\`) — decide from
389
- \`PrepareJobState.coverageRatio\`, not by polling.
547
+ \`PrepareJobState.coverageRatio\` (or \`dataFrom\`/\`dataTo\` against an \`rt\` dataset,
548
+ which has no ratio), not by polling.
390
549
  `,
391
550
  enum: ["New", "Started", "Completed", "Aborted", "Failed"],
392
551
  example: "Completed",
@@ -433,8 +592,10 @@ walked hour by hour: \`totalHours\`/\`hoursWithData\`/\`hoursWithoutData\`. Agai
433
592
  dataset-backed prepare (\`exchangeId: user\`), coverage is reported on the dataset's own
434
593
  cadence grid instead — hour-walking a daily dataset would report \`1/24\` and read as
435
594
  broken — via \`cadence\`/\`gaps\`/\`largestGapSteps\`; \`totalHours\`/\`hoursWithData\`/
436
- \`hoursWithoutData\` are absent in that case. \`dataFrom\`/\`dataTo\`/\`coverageRatio\` are present
437
- either way, computed accordingly.
595
+ \`hoursWithoutData\` are absent in that case. \`dataFrom\`/\`dataTo\` are present either way, and
596
+ \`coverageRatio\` too, computed accordingly — except against a dataset whose \`cadence\` is \`rt\`:
597
+ with no fixed step there is no expected row count to measure against, so \`coverageRatio\`
598
+ is absent and \`gaps\`/\`largestGapSteps\` are \`0\`.
438
599
  `,
439
600
  allOf: [
440
601
  {
@@ -466,7 +627,8 @@ either way, computed accordingly.
466
627
  \`totalHours\` is 0), the fraction of hours in the requested range that have served
467
628
  data. Against a dataset (\`exchangeId: user\`): \`rows / expectedStepsAtCadence\`
468
629
  over the dataset version's own range — echoing what ingest computed once, not
469
- recomputed against a narrower prepare request.
630
+ recomputed against a narrower prepare request. Absent for an \`rt\` dataset (no
631
+ fixed step, so no expected row count).
470
632
  `,
471
633
  example: 0.994,
472
634
  },
@@ -486,22 +648,23 @@ a dataset-backed prepare.
486
648
  },
487
649
  cadence: {
488
650
  type: "string",
489
- description: `The dataset version's own discovered cadence (e.g. \`1m\`, \`1h\`). Only present for a
490
- dataset-backed prepare (\`exchangeId: user\`).
651
+ description: `The dataset version's own discovered cadence — a fixed grid (e.g. \`1m\`, \`1h\`) or
652
+ \`rt\` (see \`DatasetVersion.cadence\`). Only present for a dataset-backed prepare
653
+ (\`exchangeId: user\`).
491
654
  `,
492
655
  example: "1m",
493
656
  },
494
657
  gaps: {
495
658
  type: "integer",
496
659
  description: `Number of gaps in the dataset version at its own cadence, as discovered at ingest
497
- time. Only present for a dataset-backed prepare.
660
+ time. \`0\` for \`rt\`. Only present for a dataset-backed prepare.
498
661
  `,
499
662
  example: 0,
500
663
  },
501
664
  largestGapSteps: {
502
665
  type: "integer",
503
- description: `The largest gap in the dataset version, in units of its own cadence step. Only
504
- present for a dataset-backed prepare.
666
+ description: `The largest gap in the dataset version, in units of its own cadence step. \`0\` for
667
+ \`rt\`. Only present for a dataset-backed prepare.
505
668
  `,
506
669
  example: 0,
507
670
  },
@@ -654,7 +817,7 @@ export const SweepBaseConfigSchema = {
654
817
  type: "number",
655
818
  format: "double",
656
819
  exclusiveMinimum: 0,
657
- default: 10000,
820
+ default: 100,
658
821
  },
659
822
  feeRate: {
660
823
  type: "number",
@@ -1969,11 +2132,12 @@ export const DatasetSchema = {
1969
2132
  description: `A dataset's own metadata — not its data. \`currentVersionId\` is what a prepare against
1970
2133
  \`exchangeId: user\` reads by default; see \`DatasetVersion\` for what a version carries.
1971
2134
 
1972
- \`from\`/\`to\`/\`cadence\` mirror that current version's own discovered range and cadence, so
1973
- you don't need a second call to \`GET /datasets/{datasetId}/uploads/{uploadId}\` just to see
1974
- what a dataset covers. Absent until a version exists.
2135
+ \`from\`/\`to\`/\`cadence\`/\`timestampUnit\`/\`bytes\`/\`rows\`/\`gaps\`/\`largestGapSteps\` mirror that
2136
+ current version's own discovered range, cadence, timestamp unit and metrics, so you don't
2137
+ need a second call to \`GET /datasets/{datasetId}/uploads/{uploadId}\` just to see what a
2138
+ dataset covers.
1975
2139
  `,
1976
- required: ["datasetId", "name", "type", "instrument", "createdAt"],
2140
+ required: ["datasetId", "name", "type", "instrument", "createdAt", "status"],
1977
2141
  properties: {
1978
2142
  datasetId: {
1979
2143
  type: "string",
@@ -1987,8 +2151,11 @@ what a dataset covers. Absent until a version exists.
1987
2151
  },
1988
2152
  type: {
1989
2153
  type: "string",
1990
- enum: ["ticker"],
1991
- description: "Always `ticker` in v1.",
2154
+ enum: ["ticker", "klines"],
2155
+ description: `\`ticker\` for an upload or a \`dex\` import with no \`cadence\` requested (native per-trade
2156
+ data). \`klines\` for a \`dex\` import that requested a candle \`cadence\` — pre-aggregated
2157
+ bars rather than raw ticks. Purely informational; both shapes are read the same way.
2158
+ `,
1992
2159
  example: "ticker",
1993
2160
  },
1994
2161
  instrument: {
@@ -2032,11 +2199,61 @@ a version exists.
2032
2199
  },
2033
2200
  cadence: {
2034
2201
  type: "string",
2035
- description: `\`currentVersionId\`'s own discovered bar cadence (e.g. \`1s\`, \`1m\`, \`1h\`). Absent until a
2036
- version exists.
2202
+ description: `\`currentVersionId\`'s own discovered cadence — a fixed grid (e.g. \`1s\`, \`1m\`, \`1h\`) or
2203
+ \`rt\` (see \`DatasetVersion.cadence\`). Absent until a version exists.
2037
2204
  `,
2038
2205
  example: "1m",
2039
2206
  },
2207
+ timestampUnit: {
2208
+ type: "string",
2209
+ enum: ["iso", "s", "ms", "us"],
2210
+ description: `\`currentVersionId\`'s own timestamp unit (see \`DatasetVersion.timestampUnit\`) — decode
2211
+ the \`timestamp\` column of \`dataUrl\`'s file accordingly. Present only when \`status\` is
2212
+ \`ready\`.
2213
+ `,
2214
+ example: "iso",
2215
+ },
2216
+ status: {
2217
+ type: "string",
2218
+ enum: ["ready", "failed", "pending"],
2219
+ description: `* \`ready\` — \`currentVersionId\` is set; \`from\`/\`to\`/\`cadence\`/\`bytes\`/\`rows\`/\`gaps\`/
2220
+ \`largestGapSteps\` describe it.
2221
+ * \`failed\` — the most recent upload/import attempt failed. \`currentVersionId\` and the
2222
+ fields above are absent — there is nothing to read yet. See \`error\`.
2223
+ * \`pending\` — nothing has ever been attempted (just created, or an upload was never
2224
+ finalized).
2225
+ `,
2226
+ example: "ready",
2227
+ },
2228
+ bytes: {
2229
+ type: "integer",
2230
+ description: `Size of \`currentVersionId\`'s own stored file. Present only when \`status\` is \`ready\` —
2231
+ see \`DatasetVersion.bytes\` for what it measures exactly.
2232
+ `,
2233
+ example: 4831022,
2234
+ },
2235
+ rows: {
2236
+ type: "integer",
2237
+ description: `\`currentVersionId\`'s own row count. Present only when \`status\` is \`ready\`.`,
2238
+ example: 86400,
2239
+ },
2240
+ gaps: {
2241
+ type: "integer",
2242
+ description: `\`currentVersionId\`'s own gap count at its discovered cadence. Present only when \`status\` is \`ready\`.`,
2243
+ example: 0,
2244
+ },
2245
+ largestGapSteps: {
2246
+ type: "integer",
2247
+ description: `\`currentVersionId\`'s own largest gap, in units of its discovered cadence step. Present only when \`status\` is \`ready\`.`,
2248
+ example: 0,
2249
+ },
2250
+ error: {
2251
+ type: "string",
2252
+ description: `A human-readable reason the most recent upload/import attempt failed. Present only
2253
+ when \`status\` is \`failed\`.
2254
+ `,
2255
+ example: "line 3: column 'close' is not a number: not-a-number",
2256
+ },
2040
2257
  },
2041
2258
  } as const;
2042
2259
 
@@ -2066,8 +2283,9 @@ session, not in one shot like a browser upload.
2066
2283
  enum: ["lastra", "parquet"],
2067
2284
  description: `Which format \`dataUrl\` is actually in — check this rather than assuming it
2068
2285
  matches how you uploaded it. \`lastra\` — our native columnar format — for a CSV (or
2069
- gzip/zip of one) upload, always converted on ingest. \`parquet\` for a parquet
2070
- upload, stored as-is today.
2286
+ gzip/zip of one) upload, always converted on ingest, or for a lastra upload,
2287
+ stored as-is (the value alone doesn't tell you which). \`parquet\` for a parquet
2288
+ upload, also stored as-is today.
2071
2289
  `,
2072
2290
  example: "lastra",
2073
2291
  },
@@ -2202,7 +2420,13 @@ not declared by the caller.
2202
2420
  },
2203
2421
  cadence: {
2204
2422
  type: "string",
2205
- description: "The discovered bar cadence (e.g. `1s`, `1m`, `1h`).",
2423
+ description: `The cadence discovered from the data's own timestamps. Either a fixed grid — \`1s\`,
2424
+ \`5s\`, \`15s\`, \`1m\`, \`5m\`, \`15m\`, \`30m\`, \`1h\`, \`4h\`, \`1d\` — when at least half the
2425
+ intervals between consecutive rows fall on that step (small clock jitter tolerated), or
2426
+ \`rt\`: native data at the rate it was captured, each row at its own timestamp with no
2427
+ fixed step — per-trade on-chain swaps, block-spaced or sub-second ticks, irregular
2428
+ intervals. An \`rt\` dataset can be resampled to any fixed cadence at prepare time.
2429
+ `,
2206
2430
  example: "1s",
2207
2431
  },
2208
2432
  timestampUnit: {
@@ -2215,12 +2439,14 @@ numeric values fell in (seconds, millis, or micros).
2215
2439
  },
2216
2440
  gaps: {
2217
2441
  type: "integer",
2218
- description: "Number of gaps at the discovered cadence.",
2442
+ description:
2443
+ "Number of gaps at the discovered cadence. Always `0` for `rt`.",
2219
2444
  example: 0,
2220
2445
  },
2221
2446
  largestGapSteps: {
2222
2447
  type: "integer",
2223
- description: "The largest gap, in units of the discovered cadence step.",
2448
+ description:
2449
+ "The largest gap, in units of the discovered cadence step. Always `0` for `rt`.",
2224
2450
  example: 0,
2225
2451
  },
2226
2452
  dataUrl: {
@@ -2238,8 +2464,9 @@ an extended viewing session, not in one shot like a browser upload.
2238
2464
  enum: ["lastra", "parquet"],
2239
2465
  description: `Which format \`dataUrl\` is actually in — check this rather than assuming it matches
2240
2466
  how you uploaded it. \`lastra\` — our native columnar format — for a CSV (or gzip/zip
2241
- of one) upload, always converted on ingest. \`parquet\` for a parquet upload, stored
2242
- as-is today.
2467
+ of one) upload, always converted on ingest, or for a lastra upload, stored as-is
2468
+ (the value alone doesn't tell you which). \`parquet\` for a parquet upload, also
2469
+ stored as-is today.
2243
2470
  `,
2244
2471
  example: "lastra",
2245
2472
  },
@@ -2274,6 +2501,209 @@ that can itself age out — see the \`404\` case on \`GET .../uploads/{uploadId}
2274
2501
  type: "string",
2275
2502
  description: "The ingest job id, while `status` is `ingesting`.",
2276
2503
  },
2504
+ error: {
2505
+ type: "string",
2506
+ description: `A human-readable reason, present when \`status\` is \`failed\` (e.g. bad CSV contract,
2507
+ mixed timestamp units, a \`.zip\` with no file inside or more than one). Durably
2508
+ recorded alongside the failure itself, so it stays available however long after the
2509
+ fact you poll — not tied to how recently the failure happened.
2510
+ `,
2511
+ example: "line 3: column 'close' is not a number: not-a-number",
2512
+ },
2513
+ version: {
2514
+ allOf: [
2515
+ {
2516
+ $ref: "#/components/schemas/DatasetVersion",
2517
+ },
2518
+ ],
2519
+ description: "Present when `status` is `ready` or `failed`.",
2520
+ },
2521
+ },
2522
+ } as const;
2523
+
2524
+ export const DatasetImportRequestSchema = {
2525
+ type: "object",
2526
+ description: `\`POST /datasets/imports\`'s request body. A common block plus one type-specific block,
2527
+ selected by \`type\` — \`dex\` is the only value today.
2528
+ `,
2529
+ required: ["name", "instrument", "from", "to", "type"],
2530
+ properties: {
2531
+ name: {
2532
+ type: "string",
2533
+ description: "A name unique among your datasets. `409` if already taken.",
2534
+ example: "weth-usdc-week",
2535
+ },
2536
+ instrument: {
2537
+ $ref: "#/components/schemas/Instrument",
2538
+ },
2539
+ from: {
2540
+ type: "string",
2541
+ format: "date-time",
2542
+ description:
2543
+ "Start of the range to fetch, inclusive. Must be before `to`.",
2544
+ example: "2026-08-01T00:00:00Z",
2545
+ },
2546
+ to: {
2547
+ type: "string",
2548
+ format: "date-time",
2549
+ description: `End of the range to fetch, exclusive. The total span is capped by your tier — a
2550
+ request wider than that ceiling is \`400\`, regardless of source type.
2551
+ `,
2552
+ example: "2026-08-08T00:00:00Z",
2553
+ },
2554
+ cadence: {
2555
+ type: "string",
2556
+ enum: ["1s", "1m", "5m"],
2557
+ description: `Optional. Omitted/blank keeps native per-trade event cadence — each swap at its own
2558
+ timestamp, so the resulting version's \`cadence\` is \`rt\` unless the swaps happen to sit
2559
+ on a fixed grid (see \`DatasetVersion.cadence\`). Set to \`1s\`, \`1m\` or
2560
+ \`5m\` instead to get pre-aggregated candles at that width rather than raw trades (the
2561
+ resulting dataset's \`type\` becomes \`klines\`); any other value is \`400\`. Not every
2562
+ network supports every cadence — an unsupported combination fails asynchronously, not
2563
+ at request time (see \`DatasetImportState.error\`).
2564
+ `,
2565
+ },
2566
+ type: {
2567
+ type: "string",
2568
+ enum: ["dex"],
2569
+ description: "The source to fetch from. `dex` is the only value today.",
2570
+ example: "dex",
2571
+ },
2572
+ dex: {
2573
+ $ref: "#/components/schemas/DatasetImportDexRequest",
2574
+ },
2575
+ },
2576
+ } as const;
2577
+
2578
+ export const DatasetImportDexRequestSchema = {
2579
+ type: "object",
2580
+ description: `The \`dex\` source's own fields — required when \`type\` is \`dex\`. \`id\`/\`version\` are required
2581
+ for a plain (native-cadence) import; both are ignored if the top-level \`cadence\` requested
2582
+ pre-aggregated candles instead, since that path needs neither a protocol nor a version
2583
+ distinction.
2584
+ `,
2585
+ required: ["network", "contract"],
2586
+ properties: {
2587
+ network: {
2588
+ type: "string",
2589
+ enum: ["ethereum", "robinhood"],
2590
+ description: "Which chain the pool/pair lives on.",
2591
+ example: "ethereum",
2592
+ },
2593
+ id: {
2594
+ type: "string",
2595
+ enum: ["uniswap"],
2596
+ description: `Which on-chain DEX protocol \`contract\` implements. Required unless the top-level
2597
+ \`cadence\` requested pre-aggregated candles, in which case it's ignored.
2598
+ `,
2599
+ example: "uniswap",
2600
+ },
2601
+ version: {
2602
+ type: "string",
2603
+ enum: ["v2", "v3"],
2604
+ description: `Uniswap version the pool/pair contract implements. Required unless the top-level
2605
+ \`cadence\` requested pre-aggregated candles, in which case it's ignored.
2606
+ `,
2607
+ example: "v3",
2608
+ },
2609
+ contract: {
2610
+ type: "string",
2611
+ description: "The pool (v3) or pair (v2) contract address.",
2612
+ example: "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
2613
+ },
2614
+ factory: {
2615
+ type: "string",
2616
+ description: `The factory that deployed \`contract\`. Optional — when omitted, it is discovered
2617
+ on-chain from \`contract\` itself at fetch time. Supply it explicitly only if you
2618
+ already know it, or the pool/pair belongs to a factory other than the canonical one
2619
+ for \`network\`/\`version\`. Either way, the pool/pair is validated against whichever
2620
+ factory is used before anything is fetched — a wrong or unrelated factory fails the
2621
+ import rather than silently fetching from the wrong pool. Ignored if the top-level
2622
+ \`cadence\` requested pre-aggregated candles.
2623
+ `,
2624
+ },
2625
+ },
2626
+ example: {
2627
+ network: "ethereum",
2628
+ id: "uniswap",
2629
+ version: "v3",
2630
+ contract: "0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
2631
+ },
2632
+ } as const;
2633
+
2634
+ export const DatasetImportCreatedSchema = {
2635
+ type: "object",
2636
+ description:
2637
+ "The response to `POST /datasets/imports` — the dataset now exists, and its fetch has started.",
2638
+ required: ["datasetId", "importId", "jobId", "status"],
2639
+ properties: {
2640
+ datasetId: {
2641
+ type: "string",
2642
+ description:
2643
+ "Opaque id of the newly created dataset — same id space as `POST /datasets`.",
2644
+ example: "ds_3f9a1c2e7b0d4a5f",
2645
+ },
2646
+ importId: {
2647
+ type: "string",
2648
+ description: `Identifies this import. Pass to \`GET /datasets/{datasetId}/imports/{importId}\` to poll
2649
+ it — there is no separate "finalize" step the way an upload has.
2650
+ `,
2651
+ example: "imp_01j9z1x2y3z4a5b6c7d8e9f0g1",
2652
+ },
2653
+ jobId: {
2654
+ type: "string",
2655
+ description: "The fetch/ingest job id.",
2656
+ example:
2657
+ "dataset-import:00000000-.../ds_3f9a1c2e7b0d4a5f:imp_01j9z1x2y3z4a5b6c7d8e9f0g1",
2658
+ },
2659
+ status: {
2660
+ type: "string",
2661
+ enum: ["fetching"],
2662
+ description:
2663
+ "Always `fetching` in this response — the fetch has only just started.",
2664
+ example: "fetching",
2665
+ },
2666
+ },
2667
+ } as const;
2668
+
2669
+ export const DatasetImportStateSchema = {
2670
+ type: "object",
2671
+ description: `Progress of one import, from fetching through ingest. \`fetching\` is the one status only an
2672
+ import ever reports — an upload's file already exists by the time you can poll it; an
2673
+ import's doesn't, until this source finishes fetching it.
2674
+ `,
2675
+ required: ["importId", "status"],
2676
+ properties: {
2677
+ importId: {
2678
+ type: "string",
2679
+ example: "imp_01j9z1x2y3z4a5b6c7d8e9f0g1",
2680
+ },
2681
+ status: {
2682
+ type: "string",
2683
+ enum: ["fetching", "ingesting", "ready", "failed"],
2684
+ description: `* \`fetching\` — reading from the source; nothing staged yet.
2685
+ * \`ingesting\` — fetch complete, staged, and re-entered the same ingest chain an
2686
+ upload uses; the worker is parsing and validating it.
2687
+ * \`ready\` — ingested successfully. \`version\` carries the result.
2688
+ * \`failed\` — the fetch or the ingest that followed it was rejected. \`error\` names why.
2689
+ `,
2690
+ example: "ready",
2691
+ },
2692
+ jobId: {
2693
+ type: "string",
2694
+ description:
2695
+ "The fetch/ingest job id, while `status` is `fetching` or `ingesting`.",
2696
+ },
2697
+ error: {
2698
+ type: "string",
2699
+ description: `A human-readable reason, present when \`status\` is \`failed\` — an unresolvable
2700
+ pool/pair, no data in the requested range, a range older than the configured source
2701
+ retains, the fetch exceeding your tier's time ceiling, or any of
2702
+ \`DatasetUploadState.error\`'s own ingest-side reasons once fetching hands off to it.
2703
+ Durably recorded, same as on the upload path.
2704
+ `,
2705
+ example: "Import exceeded the tier's 12 minute ceiling",
2706
+ },
2277
2707
  version: {
2278
2708
  allOf: [
2279
2709
  {