pmxtjs 2.51.0 → 2.51.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/generated/src/apis/DefaultApi.d.ts +28 -0
- package/dist/esm/generated/src/apis/DefaultApi.js +28 -0
- package/dist/esm/index.d.ts +3 -2
- package/dist/esm/index.js +3 -2
- package/dist/esm/pmxt/client.d.ts +21 -3
- package/dist/esm/pmxt/client.js +48 -18
- package/dist/esm/pmxt/escrow.js +109 -10
- package/dist/esm/pmxt/server-manager.js +5 -3
- package/dist/generated/src/apis/DefaultApi.d.ts +28 -0
- package/dist/generated/src/apis/DefaultApi.js +28 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -1
- package/dist/pmxt/client.d.ts +21 -3
- package/dist/pmxt/client.js +48 -17
- package/dist/pmxt/escrow.js +109 -10
- package/dist/pmxt/server-manager.js +5 -3
- package/generated/docs/DefaultApi.md +56 -56
- package/generated/package.json +1 -1
- package/generated/src/apis/DefaultApi.ts +28 -0
- package/index.ts +3 -2
- package/package.json +2 -2
- package/pmxt/client.ts +61 -17
- package/pmxt/escrow.ts +131 -11
- package/pmxt/server-manager.ts +5 -3
|
@@ -2601,6 +2601,7 @@ export const BuildOrderOperationExchangeEnum = {
|
|
|
2601
2601
|
Hyperliquid: 'hyperliquid',
|
|
2602
2602
|
Suibets: 'suibets',
|
|
2603
2603
|
Rain: 'rain',
|
|
2604
|
+
Hunch: 'hunch',
|
|
2604
2605
|
Mock: 'mock',
|
|
2605
2606
|
Router: 'router'
|
|
2606
2607
|
} as const;
|
|
@@ -2624,6 +2625,7 @@ export const CancelOrderOperationExchangeEnum = {
|
|
|
2624
2625
|
Hyperliquid: 'hyperliquid',
|
|
2625
2626
|
Suibets: 'suibets',
|
|
2626
2627
|
Rain: 'rain',
|
|
2628
|
+
Hunch: 'hunch',
|
|
2627
2629
|
Mock: 'mock',
|
|
2628
2630
|
Router: 'router'
|
|
2629
2631
|
} as const;
|
|
@@ -2647,6 +2649,7 @@ export const CloseOperationExchangeEnum = {
|
|
|
2647
2649
|
Hyperliquid: 'hyperliquid',
|
|
2648
2650
|
Suibets: 'suibets',
|
|
2649
2651
|
Rain: 'rain',
|
|
2652
|
+
Hunch: 'hunch',
|
|
2650
2653
|
Mock: 'mock',
|
|
2651
2654
|
Router: 'router'
|
|
2652
2655
|
} as const;
|
|
@@ -2677,6 +2680,7 @@ export const CreateOrderOperationExchangeEnum = {
|
|
|
2677
2680
|
Hyperliquid: 'hyperliquid',
|
|
2678
2681
|
Suibets: 'suibets',
|
|
2679
2682
|
Rain: 'rain',
|
|
2683
|
+
Hunch: 'hunch',
|
|
2680
2684
|
Mock: 'mock',
|
|
2681
2685
|
Router: 'router'
|
|
2682
2686
|
} as const;
|
|
@@ -2700,6 +2704,7 @@ export const FetchAllOrdersExchangeEnum = {
|
|
|
2700
2704
|
Hyperliquid: 'hyperliquid',
|
|
2701
2705
|
Suibets: 'suibets',
|
|
2702
2706
|
Rain: 'rain',
|
|
2707
|
+
Hunch: 'hunch',
|
|
2703
2708
|
Mock: 'mock',
|
|
2704
2709
|
Router: 'router'
|
|
2705
2710
|
} as const;
|
|
@@ -2742,6 +2747,7 @@ export const FetchBalanceExchangeEnum = {
|
|
|
2742
2747
|
Hyperliquid: 'hyperliquid',
|
|
2743
2748
|
Suibets: 'suibets',
|
|
2744
2749
|
Rain: 'rain',
|
|
2750
|
+
Hunch: 'hunch',
|
|
2745
2751
|
Mock: 'mock',
|
|
2746
2752
|
Router: 'router'
|
|
2747
2753
|
} as const;
|
|
@@ -2765,6 +2771,7 @@ export const FetchClosedOrdersExchangeEnum = {
|
|
|
2765
2771
|
Hyperliquid: 'hyperliquid',
|
|
2766
2772
|
Suibets: 'suibets',
|
|
2767
2773
|
Rain: 'rain',
|
|
2774
|
+
Hunch: 'hunch',
|
|
2768
2775
|
Mock: 'mock',
|
|
2769
2776
|
Router: 'router'
|
|
2770
2777
|
} as const;
|
|
@@ -2788,6 +2795,7 @@ export const FetchEventExchangeEnum = {
|
|
|
2788
2795
|
Hyperliquid: 'hyperliquid',
|
|
2789
2796
|
Suibets: 'suibets',
|
|
2790
2797
|
Rain: 'rain',
|
|
2798
|
+
Hunch: 'hunch',
|
|
2791
2799
|
Mock: 'mock',
|
|
2792
2800
|
Router: 'router'
|
|
2793
2801
|
} as const;
|
|
@@ -2858,6 +2866,7 @@ export const FetchEventsExchangeEnum = {
|
|
|
2858
2866
|
Hyperliquid: 'hyperliquid',
|
|
2859
2867
|
Suibets: 'suibets',
|
|
2860
2868
|
Rain: 'rain',
|
|
2869
|
+
Hunch: 'hunch',
|
|
2861
2870
|
Mock: 'mock',
|
|
2862
2871
|
Router: 'router'
|
|
2863
2872
|
} as const;
|
|
@@ -2909,6 +2918,7 @@ export const FetchEventsPaginatedExchangeEnum = {
|
|
|
2909
2918
|
Hyperliquid: 'hyperliquid',
|
|
2910
2919
|
Suibets: 'suibets',
|
|
2911
2920
|
Rain: 'rain',
|
|
2921
|
+
Hunch: 'hunch',
|
|
2912
2922
|
Mock: 'mock',
|
|
2913
2923
|
Router: 'router'
|
|
2914
2924
|
} as const;
|
|
@@ -2960,6 +2970,7 @@ export const FetchMarketExchangeEnum = {
|
|
|
2960
2970
|
Hyperliquid: 'hyperliquid',
|
|
2961
2971
|
Suibets: 'suibets',
|
|
2962
2972
|
Rain: 'rain',
|
|
2973
|
+
Hunch: 'hunch',
|
|
2963
2974
|
Mock: 'mock',
|
|
2964
2975
|
Router: 'router'
|
|
2965
2976
|
} as const;
|
|
@@ -3039,6 +3050,7 @@ export const FetchMarketsExchangeEnum = {
|
|
|
3039
3050
|
Hyperliquid: 'hyperliquid',
|
|
3040
3051
|
Suibets: 'suibets',
|
|
3041
3052
|
Rain: 'rain',
|
|
3053
|
+
Hunch: 'hunch',
|
|
3042
3054
|
Mock: 'mock',
|
|
3043
3055
|
Router: 'router'
|
|
3044
3056
|
} as const;
|
|
@@ -3090,6 +3102,7 @@ export const FetchMarketsPaginatedExchangeEnum = {
|
|
|
3090
3102
|
Hyperliquid: 'hyperliquid',
|
|
3091
3103
|
Suibets: 'suibets',
|
|
3092
3104
|
Rain: 'rain',
|
|
3105
|
+
Hunch: 'hunch',
|
|
3093
3106
|
Mock: 'mock',
|
|
3094
3107
|
Router: 'router'
|
|
3095
3108
|
} as const;
|
|
@@ -3151,6 +3164,7 @@ export const FetchMyTradesExchangeEnum = {
|
|
|
3151
3164
|
Hyperliquid: 'hyperliquid',
|
|
3152
3165
|
Suibets: 'suibets',
|
|
3153
3166
|
Rain: 'rain',
|
|
3167
|
+
Hunch: 'hunch',
|
|
3154
3168
|
Mock: 'mock',
|
|
3155
3169
|
Router: 'router'
|
|
3156
3170
|
} as const;
|
|
@@ -3174,6 +3188,7 @@ export const FetchOHLCVExchangeEnum = {
|
|
|
3174
3188
|
Hyperliquid: 'hyperliquid',
|
|
3175
3189
|
Suibets: 'suibets',
|
|
3176
3190
|
Rain: 'rain',
|
|
3191
|
+
Hunch: 'hunch',
|
|
3177
3192
|
Mock: 'mock',
|
|
3178
3193
|
Router: 'router'
|
|
3179
3194
|
} as const;
|
|
@@ -3197,6 +3212,7 @@ export const FetchOpenOrdersExchangeEnum = {
|
|
|
3197
3212
|
Hyperliquid: 'hyperliquid',
|
|
3198
3213
|
Suibets: 'suibets',
|
|
3199
3214
|
Rain: 'rain',
|
|
3215
|
+
Hunch: 'hunch',
|
|
3200
3216
|
Mock: 'mock',
|
|
3201
3217
|
Router: 'router'
|
|
3202
3218
|
} as const;
|
|
@@ -3220,6 +3236,7 @@ export const FetchOrderExchangeEnum = {
|
|
|
3220
3236
|
Hyperliquid: 'hyperliquid',
|
|
3221
3237
|
Suibets: 'suibets',
|
|
3222
3238
|
Rain: 'rain',
|
|
3239
|
+
Hunch: 'hunch',
|
|
3223
3240
|
Mock: 'mock',
|
|
3224
3241
|
Router: 'router'
|
|
3225
3242
|
} as const;
|
|
@@ -3243,6 +3260,7 @@ export const FetchOrderBookExchangeEnum = {
|
|
|
3243
3260
|
Hyperliquid: 'hyperliquid',
|
|
3244
3261
|
Suibets: 'suibets',
|
|
3245
3262
|
Rain: 'rain',
|
|
3263
|
+
Hunch: 'hunch',
|
|
3246
3264
|
Mock: 'mock',
|
|
3247
3265
|
Router: 'router'
|
|
3248
3266
|
} as const;
|
|
@@ -3274,6 +3292,7 @@ export const FetchOrderBooksOperationExchangeEnum = {
|
|
|
3274
3292
|
Hyperliquid: 'hyperliquid',
|
|
3275
3293
|
Suibets: 'suibets',
|
|
3276
3294
|
Rain: 'rain',
|
|
3295
|
+
Hunch: 'hunch',
|
|
3277
3296
|
Mock: 'mock',
|
|
3278
3297
|
Router: 'router'
|
|
3279
3298
|
} as const;
|
|
@@ -3297,6 +3316,7 @@ export const FetchPositionsExchangeEnum = {
|
|
|
3297
3316
|
Hyperliquid: 'hyperliquid',
|
|
3298
3317
|
Suibets: 'suibets',
|
|
3299
3318
|
Rain: 'rain',
|
|
3319
|
+
Hunch: 'hunch',
|
|
3300
3320
|
Mock: 'mock',
|
|
3301
3321
|
Router: 'router'
|
|
3302
3322
|
} as const;
|
|
@@ -3348,6 +3368,7 @@ export const FetchSeriesExchangeEnum = {
|
|
|
3348
3368
|
Hyperliquid: 'hyperliquid',
|
|
3349
3369
|
Suibets: 'suibets',
|
|
3350
3370
|
Rain: 'rain',
|
|
3371
|
+
Hunch: 'hunch',
|
|
3351
3372
|
Mock: 'mock',
|
|
3352
3373
|
Router: 'router'
|
|
3353
3374
|
} as const;
|
|
@@ -3371,6 +3392,7 @@ export const FetchTradesExchangeEnum = {
|
|
|
3371
3392
|
Hyperliquid: 'hyperliquid',
|
|
3372
3393
|
Suibets: 'suibets',
|
|
3373
3394
|
Rain: 'rain',
|
|
3395
|
+
Hunch: 'hunch',
|
|
3374
3396
|
Mock: 'mock',
|
|
3375
3397
|
Router: 'router'
|
|
3376
3398
|
} as const;
|
|
@@ -3394,6 +3416,7 @@ export const FilterEventsOperationExchangeEnum = {
|
|
|
3394
3416
|
Hyperliquid: 'hyperliquid',
|
|
3395
3417
|
Suibets: 'suibets',
|
|
3396
3418
|
Rain: 'rain',
|
|
3419
|
+
Hunch: 'hunch',
|
|
3397
3420
|
Mock: 'mock',
|
|
3398
3421
|
Router: 'router'
|
|
3399
3422
|
} as const;
|
|
@@ -3417,6 +3440,7 @@ export const FilterMarketsOperationExchangeEnum = {
|
|
|
3417
3440
|
Hyperliquid: 'hyperliquid',
|
|
3418
3441
|
Suibets: 'suibets',
|
|
3419
3442
|
Rain: 'rain',
|
|
3443
|
+
Hunch: 'hunch',
|
|
3420
3444
|
Mock: 'mock',
|
|
3421
3445
|
Router: 'router'
|
|
3422
3446
|
} as const;
|
|
@@ -3440,6 +3464,7 @@ export const GetExecutionPriceOperationExchangeEnum = {
|
|
|
3440
3464
|
Hyperliquid: 'hyperliquid',
|
|
3441
3465
|
Suibets: 'suibets',
|
|
3442
3466
|
Rain: 'rain',
|
|
3467
|
+
Hunch: 'hunch',
|
|
3443
3468
|
Mock: 'mock',
|
|
3444
3469
|
Router: 'router'
|
|
3445
3470
|
} as const;
|
|
@@ -3463,6 +3488,7 @@ export const GetExecutionPriceDetailedOperationExchangeEnum = {
|
|
|
3463
3488
|
Hyperliquid: 'hyperliquid',
|
|
3464
3489
|
Suibets: 'suibets',
|
|
3465
3490
|
Rain: 'rain',
|
|
3491
|
+
Hunch: 'hunch',
|
|
3466
3492
|
Mock: 'mock',
|
|
3467
3493
|
Router: 'router'
|
|
3468
3494
|
} as const;
|
|
@@ -3486,6 +3512,7 @@ export const LoadMarketsOperationExchangeEnum = {
|
|
|
3486
3512
|
Hyperliquid: 'hyperliquid',
|
|
3487
3513
|
Suibets: 'suibets',
|
|
3488
3514
|
Rain: 'rain',
|
|
3515
|
+
Hunch: 'hunch',
|
|
3489
3516
|
Mock: 'mock',
|
|
3490
3517
|
Router: 'router'
|
|
3491
3518
|
} as const;
|
|
@@ -3509,6 +3536,7 @@ export const SubmitOrderOperationExchangeEnum = {
|
|
|
3509
3536
|
Hyperliquid: 'hyperliquid',
|
|
3510
3537
|
Suibets: 'suibets',
|
|
3511
3538
|
Rain: 'rain',
|
|
3539
|
+
Hunch: 'hunch',
|
|
3512
3540
|
Mock: 'mock',
|
|
3513
3541
|
Router: 'router'
|
|
3514
3542
|
} as const;
|
package/index.ts
CHANGED
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
import { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Suibets, Rain, Mock } from "./pmxt/client.js";
|
|
22
|
+
import { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Suibets, Rain, Hunch, Mock } from "./pmxt/client.js";
|
|
23
23
|
import { Router } from "./pmxt/router.js";
|
|
24
24
|
import { ServerManager } from "./pmxt/server-manager.js";
|
|
25
25
|
import { FeedClient } from "./pmxt/feed-client.js";
|
|
26
26
|
import * as models from "./pmxt/models.js";
|
|
27
27
|
import * as errors from "./pmxt/errors.js";
|
|
28
28
|
|
|
29
|
-
export { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Suibets, Rain, Mock, PolymarketOptions } from "./pmxt/client.js";
|
|
29
|
+
export { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Suibets, Rain, Hunch, Mock, PolymarketOptions } from "./pmxt/client.js";
|
|
30
30
|
export { FeedClient } from "./pmxt/feed-client.js";
|
|
31
31
|
export type { Ticker, Tickers, OHLCV, Market as FeedMarket, OracleRound, FeedClientOptions } from "./pmxt/feed-client.js";
|
|
32
32
|
export { Router } from "./pmxt/router.js";
|
|
@@ -98,6 +98,7 @@ const pmxt = {
|
|
|
98
98
|
SuiBets,
|
|
99
99
|
Suibets,
|
|
100
100
|
Rain,
|
|
101
|
+
Hunch,
|
|
101
102
|
Mock,
|
|
102
103
|
Router,
|
|
103
104
|
ServerManager,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmxtjs",
|
|
3
|
-
"version": "2.51.
|
|
3
|
+
"version": "2.51.2",
|
|
4
4
|
"description": "Unified prediction market data API - The ccxt for prediction markets",
|
|
5
5
|
"author": "PMXT Contributors",
|
|
6
6
|
"repository": {
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"unified"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"pmxt-core": "2.51.
|
|
46
|
+
"pmxt-core": "2.51.2",
|
|
47
47
|
"ws": "^8.18.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
package/pmxt/client.ts
CHANGED
|
@@ -52,7 +52,7 @@ import {
|
|
|
52
52
|
import { ServerManager } from "./server-manager.js";
|
|
53
53
|
import { buildArgsWithOptionalOptions } from "./args.js";
|
|
54
54
|
import { PmxtError, fromServerError, InvalidOrder, NotSupported } from "./errors.js";
|
|
55
|
-
import { LOCAL_URL, resolvePmxtBaseUrl } from "./constants.js";
|
|
55
|
+
import { ENV, LOCAL_URL, resolvePmxtBaseUrl } from "./constants.js";
|
|
56
56
|
import { SidecarWsClient } from "./ws-client.js";
|
|
57
57
|
import { logger } from "./logger.js";
|
|
58
58
|
|
|
@@ -351,6 +351,7 @@ export abstract class Exchange {
|
|
|
351
351
|
private _wsClient: SidecarWsClient | null = null;
|
|
352
352
|
/** Sticky flag: true if the sidecar /ws endpoint is unavailable. */
|
|
353
353
|
private _wsUnsupported: boolean = false;
|
|
354
|
+
private readonly _useSidecarLockBaseUrl: boolean;
|
|
354
355
|
|
|
355
356
|
constructor(exchangeName: string, options: ExchangeOptions = {}) {
|
|
356
357
|
this.exchangeName = exchangeName.toLowerCase();
|
|
@@ -370,6 +371,11 @@ export abstract class Exchange {
|
|
|
370
371
|
const baseUrl = resolved.baseUrl;
|
|
371
372
|
this.pmxtApiKey = resolved.pmxtApiKey;
|
|
372
373
|
this.isHosted = resolved.isHosted;
|
|
374
|
+
const hasBaseUrlOverride = Boolean(
|
|
375
|
+
options.baseUrl ||
|
|
376
|
+
(typeof process !== "undefined" && process.env[ENV.BASE_URL]),
|
|
377
|
+
);
|
|
378
|
+
this._useSidecarLockBaseUrl = !this.isHosted && !hasBaseUrlOverride;
|
|
373
379
|
|
|
374
380
|
// Hosted trading bridge: if the caller passed a privateKey but no
|
|
375
381
|
// explicit signer, lazily wrap it in an EthersSigner so that
|
|
@@ -417,16 +423,18 @@ export abstract class Exchange {
|
|
|
417
423
|
try {
|
|
418
424
|
await this.serverManager.ensureServerRunning();
|
|
419
425
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
426
|
+
if (this._useSidecarLockBaseUrl) {
|
|
427
|
+
// Get the actual port the server is running on
|
|
428
|
+
// (may differ from default if default port was busy)
|
|
429
|
+
const actualPort = this.serverManager.getRunningPort();
|
|
430
|
+
const newBaseUrl = `http://localhost:${actualPort}`;
|
|
424
431
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
432
|
+
// Update API client with actual base URL
|
|
433
|
+
this.config = new Configuration({
|
|
434
|
+
basePath: newBaseUrl,
|
|
435
|
+
});
|
|
436
|
+
this.api = new DefaultApi(this.config);
|
|
437
|
+
}
|
|
430
438
|
} catch (error) {
|
|
431
439
|
const msg =
|
|
432
440
|
`Failed to start PMXT server: ${error instanceof Error ? error.message : error}\n\n` +
|
|
@@ -511,12 +519,12 @@ export abstract class Exchange {
|
|
|
511
519
|
/**
|
|
512
520
|
* Resolve the current sidecar base URL.
|
|
513
521
|
*
|
|
514
|
-
*
|
|
515
|
-
*
|
|
516
|
-
*
|
|
522
|
+
* Hosted mode and explicit baseUrl clients keep the configured basePath.
|
|
523
|
+
* Default local clients re-read the lock-file port on every call so they
|
|
524
|
+
* pick up sidecar restarts that land on a different port.
|
|
517
525
|
*/
|
|
518
526
|
private resolveBaseUrl(): string {
|
|
519
|
-
if (this.isHosted) return this.config.basePath;
|
|
527
|
+
if (this.isHosted || !this._useSidecarLockBaseUrl) return this.config.basePath;
|
|
520
528
|
const port = this.serverManager.getRunningPort();
|
|
521
529
|
return `http://localhost:${port}`;
|
|
522
530
|
}
|
|
@@ -1225,7 +1233,10 @@ export abstract class Exchange {
|
|
|
1225
1233
|
const route = HOSTED_METHOD_ROUTES.get("fetchOrder")!;
|
|
1226
1234
|
const path = formatRoutePath(route, { order_id: orderId });
|
|
1227
1235
|
const data = await _tradingRequest(this, { method: route.method, path });
|
|
1228
|
-
|
|
1236
|
+
const payload = data && typeof data === "object" && "order" in data
|
|
1237
|
+
? (data as { order: unknown }).order
|
|
1238
|
+
: data;
|
|
1239
|
+
return orderFromV0(payload as Record<string, unknown>);
|
|
1229
1240
|
}
|
|
1230
1241
|
try {
|
|
1231
1242
|
const args: any[] = [];
|
|
@@ -1325,6 +1336,9 @@ export abstract class Exchange {
|
|
|
1325
1336
|
|
|
1326
1337
|
async fetchClosedOrders(params?: OrderHistoryParams): Promise<Order[]> {
|
|
1327
1338
|
await this.initPromise;
|
|
1339
|
+
if (this.isHosted) {
|
|
1340
|
+
throw new NotSupported("fetchClosedOrders is not available in hosted trading mode.");
|
|
1341
|
+
}
|
|
1328
1342
|
try {
|
|
1329
1343
|
const args: any[] = [];
|
|
1330
1344
|
if (params !== undefined) args.push(params);
|
|
@@ -1351,6 +1365,9 @@ export abstract class Exchange {
|
|
|
1351
1365
|
|
|
1352
1366
|
async fetchAllOrders(params?: OrderHistoryParams): Promise<Order[]> {
|
|
1353
1367
|
await this.initPromise;
|
|
1368
|
+
if (this.isHosted) {
|
|
1369
|
+
throw new NotSupported("fetchAllOrders is not available in hosted trading mode.");
|
|
1370
|
+
}
|
|
1354
1371
|
try {
|
|
1355
1372
|
const args: any[] = [];
|
|
1356
1373
|
if (params !== undefined) args.push(params);
|
|
@@ -1382,7 +1399,9 @@ export abstract class Exchange {
|
|
|
1382
1399
|
const route = HOSTED_METHOD_ROUTES.get("fetchPositions")!;
|
|
1383
1400
|
const path = formatRoutePath(route, { address: resolvedAddress });
|
|
1384
1401
|
const data = await _tradingRequest(this, { method: route.method, path });
|
|
1385
|
-
const list = Array.isArray(data)
|
|
1402
|
+
const list: unknown[] = Array.isArray(data)
|
|
1403
|
+
? data
|
|
1404
|
+
: (data && Array.isArray((data as any).positions) ? (data as any).positions : []);
|
|
1386
1405
|
return list.map((p) => positionFromV0(p as Record<string, unknown>));
|
|
1387
1406
|
}
|
|
1388
1407
|
try {
|
|
@@ -1416,7 +1435,9 @@ export abstract class Exchange {
|
|
|
1416
1435
|
const route = HOSTED_METHOD_ROUTES.get("fetchBalance")!;
|
|
1417
1436
|
const path = formatRoutePath(route, { address: resolvedAddress });
|
|
1418
1437
|
const data = await _tradingRequest(this, { method: route.method, path });
|
|
1419
|
-
const list = Array.isArray(data)
|
|
1438
|
+
const list: unknown[] = Array.isArray(data)
|
|
1439
|
+
? data
|
|
1440
|
+
: (data && Array.isArray((data as any).balances) ? (data as any).balances : []);
|
|
1420
1441
|
return list.map((b) => balanceFromV0(b as Record<string, unknown>));
|
|
1421
1442
|
}
|
|
1422
1443
|
try {
|
|
@@ -3048,6 +3069,16 @@ export interface PolymarketOptions {
|
|
|
3048
3069
|
|
|
3049
3070
|
/** Optional signature type */
|
|
3050
3071
|
signatureType?: 'eoa' | 'poly-proxy' | 'gnosis-safe' | number;
|
|
3072
|
+
|
|
3073
|
+
/**
|
|
3074
|
+
* EVM wallet address used for hosted reads/writes.
|
|
3075
|
+
*/
|
|
3076
|
+
walletAddress?: string;
|
|
3077
|
+
|
|
3078
|
+
/**
|
|
3079
|
+
* External signer used for hosted writes.
|
|
3080
|
+
*/
|
|
3081
|
+
signer?: Signer;
|
|
3051
3082
|
}
|
|
3052
3083
|
|
|
3053
3084
|
export class Polymarket extends Exchange {
|
|
@@ -3402,6 +3433,19 @@ export class Rain extends Exchange {
|
|
|
3402
3433
|
}
|
|
3403
3434
|
}
|
|
3404
3435
|
|
|
3436
|
+
|
|
3437
|
+
/**
|
|
3438
|
+
* Hunch exchange client.
|
|
3439
|
+
*
|
|
3440
|
+
* Hunch is a crypto-native prediction market. Reads are unauthenticated;
|
|
3441
|
+
* trading requires an EVM private key.
|
|
3442
|
+
*/
|
|
3443
|
+
export class Hunch extends Exchange {
|
|
3444
|
+
constructor(options: ExchangeOptions = {}) {
|
|
3445
|
+
super("hunch", options);
|
|
3446
|
+
}
|
|
3447
|
+
}
|
|
3448
|
+
|
|
3405
3449
|
/**
|
|
3406
3450
|
* Mock exchange client.
|
|
3407
3451
|
*
|
package/pmxt/escrow.ts
CHANGED
|
@@ -16,6 +16,99 @@ import {
|
|
|
16
16
|
HostedClientLike,
|
|
17
17
|
resolveWalletAddress,
|
|
18
18
|
} from "./hosted-routing";
|
|
19
|
+
import { ValidationError } from "./errors";
|
|
20
|
+
|
|
21
|
+
const APPROVAL_TOKENS = new Set(["usdc", "ctf"]);
|
|
22
|
+
const WITHDRAW_ACTIONS = new Set(["request", "claim", "cancel"]);
|
|
23
|
+
const USDC_SCALE = 1_000_000n;
|
|
24
|
+
|
|
25
|
+
function isDecimalTokenId(token: string): boolean {
|
|
26
|
+
return /^[0-9]+$/.test(token);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function normalizeApprovalToken(token: string): string {
|
|
30
|
+
if (typeof token !== "string") {
|
|
31
|
+
throw new ValidationError(
|
|
32
|
+
"token must be 'usdc', 'ctf', or a decimal CTF token_id string",
|
|
33
|
+
"token",
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const candidate = token.trim();
|
|
38
|
+
const normalized = candidate.toLowerCase();
|
|
39
|
+
if (APPROVAL_TOKENS.has(normalized)) {
|
|
40
|
+
return normalized;
|
|
41
|
+
}
|
|
42
|
+
if (isDecimalTokenId(candidate)) {
|
|
43
|
+
return candidate;
|
|
44
|
+
}
|
|
45
|
+
throw new ValidationError(
|
|
46
|
+
"token must be 'usdc', 'ctf', or a decimal CTF token_id string",
|
|
47
|
+
"token",
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function normalizeAmountWei(amountWei: bigint | undefined): string | undefined {
|
|
52
|
+
if (amountWei === undefined) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
if (typeof amountWei !== "bigint") {
|
|
56
|
+
throw new ValidationError("amount_wei must be a non-negative integer", "amount_wei");
|
|
57
|
+
}
|
|
58
|
+
if (amountWei < 0n) {
|
|
59
|
+
throw new ValidationError("amount_wei must be non-negative", "amount_wei");
|
|
60
|
+
}
|
|
61
|
+
return amountWei.toString();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function validateUsdcDecimal(value: string, field: string): void {
|
|
65
|
+
const match = /^([0-9]+)(?:\.([0-9]+))?$/.exec(value);
|
|
66
|
+
if (!match) {
|
|
67
|
+
throw new ValidationError(`${field} must be a finite positive number`, field);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const fractional = match[2] ?? "";
|
|
71
|
+
if (fractional.length > 6) {
|
|
72
|
+
throw new ValidationError(
|
|
73
|
+
`${field} precision exceeds 6 decimals; max precision for USDC is 0.000001`,
|
|
74
|
+
field,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const scaled = BigInt(match[1]) * USDC_SCALE + BigInt(fractional.padEnd(6, "0"));
|
|
79
|
+
if (scaled <= 0n) {
|
|
80
|
+
throw new ValidationError(`${field} must be positive`, field);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function normalizeUsdcAmount(value: number | string | bigint, field: string = "amount"): number | string {
|
|
85
|
+
if (typeof value === "bigint") {
|
|
86
|
+
if (value <= 0n) {
|
|
87
|
+
throw new ValidationError(`${field} must be positive`, field);
|
|
88
|
+
}
|
|
89
|
+
return value.toString();
|
|
90
|
+
}
|
|
91
|
+
if (typeof value === "number") {
|
|
92
|
+
if (!Number.isFinite(value)) {
|
|
93
|
+
throw new ValidationError(`${field} must be a finite positive number`, field);
|
|
94
|
+
}
|
|
95
|
+
validateUsdcDecimal(String(value), field);
|
|
96
|
+
return value;
|
|
97
|
+
}
|
|
98
|
+
if (typeof value === "string") {
|
|
99
|
+
const trimmed = value.trim();
|
|
100
|
+
validateUsdcDecimal(trimmed, field);
|
|
101
|
+
return trimmed;
|
|
102
|
+
}
|
|
103
|
+
throw new ValidationError(`${field} must be a finite positive number`, field);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function normalizeWithdrawAction(action: string): "request" | "claim" | "cancel" {
|
|
107
|
+
if (typeof action === "string" && WITHDRAW_ACTIONS.has(action)) {
|
|
108
|
+
return action as "request" | "claim" | "cancel";
|
|
109
|
+
}
|
|
110
|
+
throw new ValidationError("action must be 'request', 'claim', or 'cancel'", "action");
|
|
111
|
+
}
|
|
19
112
|
|
|
20
113
|
export class Escrow {
|
|
21
114
|
constructor(private readonly client: HostedClientLike) {}
|
|
@@ -25,13 +118,16 @@ export class Escrow {
|
|
|
25
118
|
* `amountWei` is omitted, the server returns an unlimited approval.
|
|
26
119
|
*/
|
|
27
120
|
async approveTx(token: string, amountWei?: bigint): Promise<unknown> {
|
|
121
|
+
const address = resolveWalletAddress(this.client);
|
|
122
|
+
const approvalAmount = normalizeAmountWei(amountWei);
|
|
28
123
|
const route = HOSTED_METHOD_ROUTES.get("escrowApproveTx")!;
|
|
29
124
|
return _tradingRequest(this.client, {
|
|
30
125
|
method: route.method,
|
|
31
126
|
path: route.path,
|
|
32
127
|
body: {
|
|
33
|
-
token,
|
|
34
|
-
|
|
128
|
+
token: normalizeApprovalToken(token),
|
|
129
|
+
user_address: address,
|
|
130
|
+
...(approvalAmount === undefined ? {} : { amount_wei: approvalAmount }),
|
|
35
131
|
},
|
|
36
132
|
});
|
|
37
133
|
}
|
|
@@ -41,12 +137,15 @@ export class Escrow {
|
|
|
41
137
|
* grid). Accepts number, decimal string, or BigInt in micro-units.
|
|
42
138
|
*/
|
|
43
139
|
async depositTx(amount: number | string | bigint): Promise<unknown> {
|
|
140
|
+
const address = resolveWalletAddress(this.client);
|
|
44
141
|
const route = HOSTED_METHOD_ROUTES.get("escrowDepositTx")!;
|
|
45
142
|
return _tradingRequest(this.client, {
|
|
46
143
|
method: route.method,
|
|
47
144
|
path: route.path,
|
|
48
145
|
body: {
|
|
49
|
-
|
|
146
|
+
token: "usdc",
|
|
147
|
+
amount: normalizeUsdcAmount(amount),
|
|
148
|
+
user_address: address,
|
|
50
149
|
},
|
|
51
150
|
});
|
|
52
151
|
}
|
|
@@ -60,17 +159,34 @@ export class Escrow {
|
|
|
60
159
|
action: "request" | "claim" | "cancel",
|
|
61
160
|
amount?: number | string | bigint,
|
|
62
161
|
): Promise<unknown> {
|
|
162
|
+
const normalizedAction = normalizeWithdrawAction(action);
|
|
163
|
+
const address = resolveWalletAddress(this.client);
|
|
63
164
|
const route = HOSTED_METHOD_ROUTES.get("escrowWithdrawTx")!;
|
|
64
|
-
|
|
65
|
-
amount === undefined
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
165
|
+
if (normalizedAction === "request") {
|
|
166
|
+
if (amount === undefined) {
|
|
167
|
+
throw new ValidationError("amount is required when action='request'", "amount");
|
|
168
|
+
}
|
|
169
|
+
return _tradingRequest(this.client, {
|
|
170
|
+
method: route.method,
|
|
171
|
+
path: route.path,
|
|
172
|
+
body: {
|
|
173
|
+
action: normalizedAction,
|
|
174
|
+
token: "usdc",
|
|
175
|
+
amount: normalizeUsdcAmount(amount),
|
|
176
|
+
user_address: address,
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
if (amount !== undefined) {
|
|
181
|
+
throw new ValidationError(
|
|
182
|
+
`amount must be omitted when action='${normalizedAction}'`,
|
|
183
|
+
"amount",
|
|
184
|
+
);
|
|
185
|
+
}
|
|
70
186
|
return _tradingRequest(this.client, {
|
|
71
187
|
method: route.method,
|
|
72
188
|
path: route.path,
|
|
73
|
-
body: { action,
|
|
189
|
+
body: { action: normalizedAction, token: "usdc", user_address: address },
|
|
74
190
|
});
|
|
75
191
|
}
|
|
76
192
|
|
|
@@ -82,12 +198,16 @@ export class Escrow {
|
|
|
82
198
|
opts: { include?: string; address?: string } = {},
|
|
83
199
|
): Promise<unknown> {
|
|
84
200
|
const address = resolveWalletAddress(this.client, opts.address);
|
|
201
|
+
const include = (opts.include ?? "pending,events").trim();
|
|
202
|
+
if (!include) {
|
|
203
|
+
throw new ValidationError("include must not be empty", "include");
|
|
204
|
+
}
|
|
85
205
|
const route = HOSTED_METHOD_ROUTES.get("escrowWithdrawals")!;
|
|
86
206
|
const path = formatRoutePath(route, { address });
|
|
87
207
|
return _tradingRequest(this.client, {
|
|
88
208
|
method: route.method,
|
|
89
209
|
path,
|
|
90
|
-
params: { include
|
|
210
|
+
params: { include },
|
|
91
211
|
});
|
|
92
212
|
}
|
|
93
213
|
}
|
package/pmxt/server-manager.ts
CHANGED
|
@@ -103,13 +103,15 @@ export class ServerManager {
|
|
|
103
103
|
* Check if the server is running.
|
|
104
104
|
*/
|
|
105
105
|
async isServerRunning(): Promise<boolean> {
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
const info = this.getServerInfo();
|
|
107
|
+
if (!info?.port) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
108
110
|
|
|
109
111
|
try {
|
|
110
112
|
// Use native fetch to check health on the actual running port
|
|
111
113
|
// This avoids issues where this.api is configured with the wrong port
|
|
112
|
-
const response = await fetch(`http://localhost:${port}/health`, {
|
|
114
|
+
const response = await fetch(`http://localhost:${info.port}/health`, {
|
|
113
115
|
signal: AbortSignal.timeout(5_000),
|
|
114
116
|
});
|
|
115
117
|
if (response.ok) {
|