pmxt-core 2.53.0 → 2.54.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.
- package/dist/BaseExchange.d.ts +53 -2
- package/dist/BaseExchange.js +84 -0
- package/dist/exchanges/kalshi/api.d.ts +1 -1
- package/dist/exchanges/kalshi/api.js +1 -1
- package/dist/exchanges/limitless/api.d.ts +1 -1
- package/dist/exchanges/limitless/api.js +1 -1
- package/dist/exchanges/myriad/api.d.ts +1 -1
- package/dist/exchanges/myriad/api.js +1 -1
- package/dist/exchanges/opinion/api.d.ts +1 -1
- package/dist/exchanges/opinion/api.js +1 -1
- package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
- package/dist/exchanges/polymarket/api-clob.js +1 -1
- package/dist/exchanges/polymarket/api-data.d.ts +1 -1
- package/dist/exchanges/polymarket/api-data.js +1 -1
- package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
- package/dist/exchanges/polymarket/api-gamma.js +1 -1
- package/dist/exchanges/probable/api.d.ts +1 -1
- package/dist/exchanges/probable/api.js +1 -1
- package/dist/exchanges/probable/auth.d.ts +26 -0
- package/dist/exchanges/probable/auth.js +90 -0
- package/dist/exchanges/probable/index.d.ts +6 -0
- package/dist/exchanges/probable/index.js +22 -1
- package/dist/router/types.d.ts +52 -0
- package/dist/server/method-verbs.json +50 -0
- package/dist/server/openapi.yaml +140 -1
- package/package.json +3 -3
package/dist/BaseExchange.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { AxiosInstance } from 'axios';
|
|
|
2
2
|
import { SubscribedAddressSnapshot, SubscriptionOption } from './subscriber/base';
|
|
3
3
|
import { Balance, BuiltOrder, CandleInterval, CreateOrderParams, Order, OrderBook, Position, PriceCandle, Trade, UnifiedEvent, UnifiedMarket, UnifiedSeries, UserTrade } from './types';
|
|
4
4
|
import { ExecutionPriceResult } from './utils/math';
|
|
5
|
-
import type { FetchMarketMatchesParams, FetchMatchesParams, FetchEventMatchesParams, FetchArbitrageParams, FetchMatchedMarketsParams, FetchMatchedPricesParams, MatchResult, EventMatchResult, PriceComparison, ArbitrageOpportunity, MatchedMarketPair, MatchedPricePair } from './router/types';
|
|
5
|
+
import type { FetchMarketMatchesParams, FetchMatchesParams, FetchEventMatchesParams, FetchArbitrageParams, FetchMatchedMarketsParams, FetchMatchedPricesParams, MatchResult, EventMatchResult, PriceComparison, CompareMarketPricesParams, ArbitrageOpportunity, MatchedMarketPair, MatchedPricePair, AuthNonceResponse, AuthLoginResponse, AuthSession } from './router/types';
|
|
6
6
|
export interface ApiEndpoint {
|
|
7
7
|
/** HTTP verb for the endpoint (e.g. GET, POST). */
|
|
8
8
|
method: string;
|
|
@@ -383,11 +383,62 @@ export declare abstract class PredictionMarketExchange {
|
|
|
383
383
|
private _snapshot?;
|
|
384
384
|
private _eventSnapshot?;
|
|
385
385
|
private apiDescriptors;
|
|
386
|
+
protected _sessions: Map<string, AuthSession>;
|
|
386
387
|
constructor(credentials?: ExchangeCredentials, options?: ExchangeOptions);
|
|
387
388
|
private _rateLimit;
|
|
388
389
|
get rateLimit(): number;
|
|
389
390
|
set rateLimit(value: number);
|
|
390
391
|
abstract get name(): string;
|
|
392
|
+
/**
|
|
393
|
+
* Get a cryptographic nonce for Web3 login.
|
|
394
|
+
* @param walletAddress - The wallet address to authenticate
|
|
395
|
+
*/
|
|
396
|
+
getAuthNonce(walletAddress: string): Promise<AuthNonceResponse>;
|
|
397
|
+
/**
|
|
398
|
+
* Login with a signed nonce to obtain session credentials.
|
|
399
|
+
* @param walletAddress - The wallet address
|
|
400
|
+
* @param signature - The signature of the nonce message
|
|
401
|
+
* @param nonce - The nonce that was signed
|
|
402
|
+
*/
|
|
403
|
+
loginWithSignature(walletAddress: string, signature: string, nonce: string): Promise<AuthLoginResponse>;
|
|
404
|
+
/**
|
|
405
|
+
* Logout and invalidate the current session.
|
|
406
|
+
* @param walletAddress - The wallet address to logout (optional)
|
|
407
|
+
*/
|
|
408
|
+
logout(walletAddress?: string): Promise<void>;
|
|
409
|
+
/**
|
|
410
|
+
* Check if a session is active for the given wallet address.
|
|
411
|
+
* @param walletAddress - The wallet address to check
|
|
412
|
+
*/
|
|
413
|
+
isSessionActive(walletAddress: string): Promise<boolean>;
|
|
414
|
+
/**
|
|
415
|
+
* Get the stored session for a wallet address.
|
|
416
|
+
*
|
|
417
|
+
* SECURITY: This is an in-process helper only and is deliberately excluded
|
|
418
|
+
* from the HTTP/RPC server surface (see EXCLUDED_METHODS in
|
|
419
|
+
* scripts/generate-openapi.js). It returns session credentials (apiKey /
|
|
420
|
+
* apiSecret / passphrase), so it must never be reachable over the network,
|
|
421
|
+
* where the wallet address — a public value — would otherwise let any caller
|
|
422
|
+
* retrieve another user's secrets.
|
|
423
|
+
* @param walletAddress - The wallet address
|
|
424
|
+
*/
|
|
425
|
+
getSession(walletAddress: string): AuthSession | undefined;
|
|
426
|
+
/**
|
|
427
|
+
* Store a session in memory.
|
|
428
|
+
* @param walletAddress - The wallet address
|
|
429
|
+
* @param credentials - The session credentials
|
|
430
|
+
*/
|
|
431
|
+
protected storeSession(walletAddress: string, credentials: AuthLoginResponse): void;
|
|
432
|
+
/**
|
|
433
|
+
* Remove a session from memory.
|
|
434
|
+
* @param walletAddress - The wallet address
|
|
435
|
+
*/
|
|
436
|
+
protected removeSession(walletAddress: string): void;
|
|
437
|
+
/**
|
|
438
|
+
* Clean expired sessions from memory.
|
|
439
|
+
* Should be called periodically to prevent memory leaks.
|
|
440
|
+
*/
|
|
441
|
+
protected cleanExpiredSessions(): void;
|
|
391
442
|
/**
|
|
392
443
|
* Introspection getter: returns info about all implicit API methods.
|
|
393
444
|
*/
|
|
@@ -818,7 +869,7 @@ export declare abstract class PredictionMarketExchange {
|
|
|
818
869
|
* @param params - Match filter parameters (uses relation: 'identity' internally)
|
|
819
870
|
* @returns Array of price comparisons across venues
|
|
820
871
|
*/
|
|
821
|
-
compareMarketPrices(params:
|
|
872
|
+
compareMarketPrices(params: CompareMarketPricesParams): Promise<PriceComparison[]>;
|
|
822
873
|
/**
|
|
823
874
|
* Find related markets across venues. Discovers subset/superset market relationships
|
|
824
875
|
* where one market's outcome implies another, with live prices.
|
package/dist/BaseExchange.js
CHANGED
|
@@ -54,6 +54,7 @@ class PredictionMarketExchange {
|
|
|
54
54
|
_snapshot;
|
|
55
55
|
_eventSnapshot;
|
|
56
56
|
apiDescriptors = [];
|
|
57
|
+
_sessions = new Map();
|
|
57
58
|
constructor(credentials, options) {
|
|
58
59
|
this.credentials = credentials;
|
|
59
60
|
this._snapshotTTL = options?.snapshotTTL ?? 0;
|
|
@@ -128,6 +129,89 @@ class PredictionMarketExchange {
|
|
|
128
129
|
delay: 1,
|
|
129
130
|
});
|
|
130
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Get a cryptographic nonce for Web3 login.
|
|
134
|
+
* @param walletAddress - The wallet address to authenticate
|
|
135
|
+
*/
|
|
136
|
+
async getAuthNonce(walletAddress) {
|
|
137
|
+
throw new Error(`getAuthNonce not implemented for ${this.name}`);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Login with a signed nonce to obtain session credentials.
|
|
141
|
+
* @param walletAddress - The wallet address
|
|
142
|
+
* @param signature - The signature of the nonce message
|
|
143
|
+
* @param nonce - The nonce that was signed
|
|
144
|
+
*/
|
|
145
|
+
async loginWithSignature(walletAddress, signature, nonce) {
|
|
146
|
+
throw new Error(`loginWithSignature not implemented for ${this.name}`);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Logout and invalidate the current session.
|
|
150
|
+
* @param walletAddress - The wallet address to logout (optional)
|
|
151
|
+
*/
|
|
152
|
+
async logout(walletAddress) {
|
|
153
|
+
throw new Error(`logout not implemented for ${this.name}`);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Check if a session is active for the given wallet address.
|
|
157
|
+
* @param walletAddress - The wallet address to check
|
|
158
|
+
*/
|
|
159
|
+
async isSessionActive(walletAddress) {
|
|
160
|
+
const session = this._sessions.get(walletAddress);
|
|
161
|
+
if (!session)
|
|
162
|
+
return false;
|
|
163
|
+
if (session.credentials.expiresAt && session.credentials.expiresAt < Date.now()) {
|
|
164
|
+
this._sessions.delete(walletAddress);
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
return session.credentials.active !== false;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get the stored session for a wallet address.
|
|
171
|
+
*
|
|
172
|
+
* SECURITY: This is an in-process helper only and is deliberately excluded
|
|
173
|
+
* from the HTTP/RPC server surface (see EXCLUDED_METHODS in
|
|
174
|
+
* scripts/generate-openapi.js). It returns session credentials (apiKey /
|
|
175
|
+
* apiSecret / passphrase), so it must never be reachable over the network,
|
|
176
|
+
* where the wallet address — a public value — would otherwise let any caller
|
|
177
|
+
* retrieve another user's secrets.
|
|
178
|
+
* @param walletAddress - The wallet address
|
|
179
|
+
*/
|
|
180
|
+
getSession(walletAddress) {
|
|
181
|
+
return this._sessions.get(walletAddress);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Store a session in memory.
|
|
185
|
+
* @param walletAddress - The wallet address
|
|
186
|
+
* @param credentials - The session credentials
|
|
187
|
+
*/
|
|
188
|
+
storeSession(walletAddress, credentials) {
|
|
189
|
+
this._sessions.set(walletAddress, {
|
|
190
|
+
walletAddress,
|
|
191
|
+
credentials,
|
|
192
|
+
createdAt: Date.now(),
|
|
193
|
+
lastUsedAt: Date.now(),
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Remove a session from memory.
|
|
198
|
+
* @param walletAddress - The wallet address
|
|
199
|
+
*/
|
|
200
|
+
removeSession(walletAddress) {
|
|
201
|
+
this._sessions.delete(walletAddress);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Clean expired sessions from memory.
|
|
205
|
+
* Should be called periodically to prevent memory leaks.
|
|
206
|
+
*/
|
|
207
|
+
cleanExpiredSessions() {
|
|
208
|
+
const now = Date.now();
|
|
209
|
+
for (const [address, session] of this._sessions) {
|
|
210
|
+
if (session.credentials.expiresAt && session.credentials.expiresAt < now) {
|
|
211
|
+
this._sessions.delete(address);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
131
215
|
/**
|
|
132
216
|
* Introspection getter: returns info about all implicit API methods.
|
|
133
217
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/kalshi/Kalshi.yaml
|
|
3
|
-
* Generated at: 2026-07-18T01:
|
|
3
|
+
* Generated at: 2026-07-18T01:45:23.295Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const kalshiApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.kalshiApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/kalshi/Kalshi.yaml
|
|
6
|
-
* Generated at: 2026-07-18T01:
|
|
6
|
+
* Generated at: 2026-07-18T01:45:23.295Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.kalshiApiSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/limitless/Limitless.yaml
|
|
3
|
-
* Generated at: 2026-07-18T01:
|
|
3
|
+
* Generated at: 2026-07-18T01:45:23.334Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const limitlessApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.limitlessApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/limitless/Limitless.yaml
|
|
6
|
-
* Generated at: 2026-07-18T01:
|
|
6
|
+
* Generated at: 2026-07-18T01:45:23.334Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.limitlessApiSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/myriad/myriad.yaml
|
|
3
|
-
* Generated at: 2026-07-18T01:
|
|
3
|
+
* Generated at: 2026-07-18T01:45:23.349Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const myriadApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.myriadApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/myriad/myriad.yaml
|
|
6
|
-
* Generated at: 2026-07-18T01:
|
|
6
|
+
* Generated at: 2026-07-18T01:45:23.349Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.myriadApiSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/opinion/opinion-openapi.yaml
|
|
3
|
-
* Generated at: 2026-07-18T01:
|
|
3
|
+
* Generated at: 2026-07-18T01:45:23.354Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const opinionApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.opinionApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/opinion/opinion-openapi.yaml
|
|
6
|
-
* Generated at: 2026-07-18T01:
|
|
6
|
+
* Generated at: 2026-07-18T01:45:23.354Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.opinionApiSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketClobAPI.yaml
|
|
3
|
-
* Generated at: 2026-07-18T01:
|
|
3
|
+
* Generated at: 2026-07-18T01:45:23.304Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const polymarketClobSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.polymarketClobSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketClobAPI.yaml
|
|
6
|
-
* Generated at: 2026-07-18T01:
|
|
6
|
+
* Generated at: 2026-07-18T01:45:23.304Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.polymarketClobSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/Polymarket_Data_API.yaml
|
|
3
|
-
* Generated at: 2026-07-18T01:
|
|
3
|
+
* Generated at: 2026-07-18T01:45:23.315Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const polymarketDataSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.polymarketDataSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/Polymarket_Data_API.yaml
|
|
6
|
-
* Generated at: 2026-07-18T01:
|
|
6
|
+
* Generated at: 2026-07-18T01:45:23.315Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.polymarketDataSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketGammaAPI.yaml
|
|
3
|
-
* Generated at: 2026-07-18T01:
|
|
3
|
+
* Generated at: 2026-07-18T01:45:23.313Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const polymarketGammaSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.polymarketGammaSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketGammaAPI.yaml
|
|
6
|
-
* Generated at: 2026-07-18T01:
|
|
6
|
+
* Generated at: 2026-07-18T01:45:23.313Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.polymarketGammaSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/probable/probable.yaml
|
|
3
|
-
* Generated at: 2026-07-18T01:
|
|
3
|
+
* Generated at: 2026-07-18T01:45:23.342Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const probableApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.probableApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/probable/probable.yaml
|
|
6
|
-
* Generated at: 2026-07-18T01:
|
|
6
|
+
* Generated at: 2026-07-18T01:45:23.342Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.probableApiSpec = {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createClobClient } from '@prob/clob';
|
|
2
2
|
import { ExchangeCredentials } from '../../BaseExchange';
|
|
3
|
+
import { AuthNonceResponse, AuthLoginResponse } from '../../router/types';
|
|
3
4
|
/**
|
|
4
5
|
* Manages Probable authentication and CLOB client initialization.
|
|
5
6
|
* Requires a privateKey and pre-generated API key triplet (apiKey, apiSecret, passphrase).
|
|
@@ -12,3 +13,28 @@ export declare class ProbableAuth {
|
|
|
12
13
|
getClobClient(): ReturnType<typeof createClobClient>;
|
|
13
14
|
getAddress(): string;
|
|
14
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Get a nonce from Probable.
|
|
18
|
+
* Uses the implicit API endpoint 'getPublicApiV1AuthNonce'.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getAuthNonce(walletAddress: string, callApi: Function): Promise<AuthNonceResponse>;
|
|
21
|
+
/**
|
|
22
|
+
* Login to Probable with signature.
|
|
23
|
+
* Uses the implicit API endpoint 'postPublicApiV1AuthLogin'.
|
|
24
|
+
*/
|
|
25
|
+
export declare function loginWithSignature(walletAddress: string, signature: string, nonce: string, callApi: Function): Promise<AuthLoginResponse>;
|
|
26
|
+
/**
|
|
27
|
+
* Logout from Probable.
|
|
28
|
+
* Uses the implicit API endpoint 'postPublicApiV1AuthLogout'.
|
|
29
|
+
*/
|
|
30
|
+
export declare function logout(callApi: Function): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Verify L1 signature.
|
|
33
|
+
* Uses the implicit API endpoint 'postPublicApiV1AuthVerifyL1'.
|
|
34
|
+
*/
|
|
35
|
+
export declare function verifyL1(walletAddress: string, signature: string, callApi: Function): Promise<boolean>;
|
|
36
|
+
/**
|
|
37
|
+
* Verify L2 signature.
|
|
38
|
+
* Uses the implicit API endpoint 'postPublicApiV1AuthVerifyL2'.
|
|
39
|
+
*/
|
|
40
|
+
export declare function verifyL2(walletAddress: string, signature: string, callApi: Function): Promise<boolean>;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ProbableAuth = void 0;
|
|
4
|
+
exports.getAuthNonce = getAuthNonce;
|
|
5
|
+
exports.loginWithSignature = loginWithSignature;
|
|
6
|
+
exports.logout = logout;
|
|
7
|
+
exports.verifyL1 = verifyL1;
|
|
8
|
+
exports.verifyL2 = verifyL2;
|
|
4
9
|
const clob_1 = require("@prob/clob");
|
|
5
10
|
const accounts_1 = require("viem/accounts");
|
|
6
11
|
const viem_1 = require("viem");
|
|
@@ -69,3 +74,88 @@ class ProbableAuth {
|
|
|
69
74
|
}
|
|
70
75
|
}
|
|
71
76
|
exports.ProbableAuth = ProbableAuth;
|
|
77
|
+
/**
|
|
78
|
+
* Get a nonce from Probable.
|
|
79
|
+
* Uses the implicit API endpoint 'getPublicApiV1AuthNonce'.
|
|
80
|
+
*/
|
|
81
|
+
async function getAuthNonce(walletAddress, callApi) {
|
|
82
|
+
try {
|
|
83
|
+
const response = await callApi('getPublicApiV1AuthNonce', { address: walletAddress });
|
|
84
|
+
return {
|
|
85
|
+
nonce: response.nonce,
|
|
86
|
+
messageToSign: response.message || response.messageToSign,
|
|
87
|
+
expiresAt: response.expiresAt,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
throw new Error(`Failed to get Probable auth nonce: ${error.message}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Login to Probable with signature.
|
|
96
|
+
* Uses the implicit API endpoint 'postPublicApiV1AuthLogin'.
|
|
97
|
+
*/
|
|
98
|
+
async function loginWithSignature(walletAddress, signature, nonce, callApi) {
|
|
99
|
+
try {
|
|
100
|
+
const response = await callApi('postPublicApiV1AuthLogin', {
|
|
101
|
+
address: walletAddress,
|
|
102
|
+
signature,
|
|
103
|
+
nonce,
|
|
104
|
+
});
|
|
105
|
+
return {
|
|
106
|
+
apiKey: response.apiKey,
|
|
107
|
+
apiSecret: response.apiSecret,
|
|
108
|
+
passphrase: response.passphrase,
|
|
109
|
+
expiresAt: response.expiresAt,
|
|
110
|
+
active: true,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
throw new Error(`Failed to login to Probable: ${error.message}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Logout from Probable.
|
|
119
|
+
* Uses the implicit API endpoint 'postPublicApiV1AuthLogout'.
|
|
120
|
+
*/
|
|
121
|
+
async function logout(callApi) {
|
|
122
|
+
try {
|
|
123
|
+
await callApi('postPublicApiV1AuthLogout', {});
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
// Log but don't throw - logout should be best-effort
|
|
127
|
+
console.warn(`Failed to logout from Probable: ${error.message}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Verify L1 signature.
|
|
132
|
+
* Uses the implicit API endpoint 'postPublicApiV1AuthVerifyL1'.
|
|
133
|
+
*/
|
|
134
|
+
async function verifyL1(walletAddress, signature, callApi) {
|
|
135
|
+
try {
|
|
136
|
+
const response = await callApi('postPublicApiV1AuthVerifyL1', {
|
|
137
|
+
address: walletAddress,
|
|
138
|
+
signature,
|
|
139
|
+
});
|
|
140
|
+
return response.verified === true;
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Verify L2 signature.
|
|
148
|
+
* Uses the implicit API endpoint 'postPublicApiV1AuthVerifyL2'.
|
|
149
|
+
*/
|
|
150
|
+
async function verifyL2(walletAddress, signature, callApi) {
|
|
151
|
+
try {
|
|
152
|
+
const response = await callApi('postPublicApiV1AuthVerifyL2', {
|
|
153
|
+
address: walletAddress,
|
|
154
|
+
signature,
|
|
155
|
+
});
|
|
156
|
+
return response.verified === true;
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PredictionMarketExchange, MarketFetchParams, EventFetchParams, ExchangeCredentials, OHLCVParams, HistoryFilterParams, TradesParams, MyTradesParams } from '../../BaseExchange';
|
|
2
|
+
import { AuthNonceResponse, AuthLoginResponse } from '../../router/types';
|
|
2
3
|
import { UnifiedMarket, UnifiedEvent, OrderBook, PriceCandle, Trade, UserTrade, Order, Position, Balance, CreateOrderParams } from '../../types';
|
|
3
4
|
import { ProbableWebSocketConfig } from './websocket';
|
|
4
5
|
export declare class ProbableExchange extends PredictionMarketExchange {
|
|
@@ -14,6 +15,11 @@ export declare class ProbableExchange extends PredictionMarketExchange {
|
|
|
14
15
|
get name(): string;
|
|
15
16
|
protected mapImplicitApiError(error: any): any;
|
|
16
17
|
private ensureAuth;
|
|
18
|
+
getAuthNonce(walletAddress: string): Promise<AuthNonceResponse>;
|
|
19
|
+
loginWithSignature(walletAddress: string, signature: string, nonce: string): Promise<AuthLoginResponse>;
|
|
20
|
+
logout(walletAddress?: string): Promise<void>;
|
|
21
|
+
verifyL1(walletAddress: string, signature: string): Promise<boolean>;
|
|
22
|
+
verifyL2(walletAddress: string, signature: string): Promise<boolean>;
|
|
17
23
|
protected fetchMarketsImpl(params?: MarketFetchParams): Promise<UnifiedMarket[]>;
|
|
18
24
|
protected fetchEventsImpl(params: EventFetchParams): Promise<UnifiedEvent[]>;
|
|
19
25
|
/**
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ProbableExchange = void 0;
|
|
4
4
|
const BaseExchange_1 = require("../../BaseExchange");
|
|
5
5
|
const auth_1 = require("./auth");
|
|
6
|
+
const auth_2 = require("./auth");
|
|
6
7
|
const websocket_1 = require("./websocket");
|
|
7
8
|
const errors_1 = require("./errors");
|
|
8
9
|
const errors_2 = require("../../errors");
|
|
@@ -29,7 +30,7 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
29
30
|
this.rateLimit = 500;
|
|
30
31
|
this.wsConfig = wsConfig;
|
|
31
32
|
if (credentials?.privateKey && credentials?.apiKey && credentials?.apiSecret && credentials?.passphrase) {
|
|
32
|
-
this.auth = new
|
|
33
|
+
this.auth = new auth_2.ProbableAuth(credentials);
|
|
33
34
|
}
|
|
34
35
|
const probableBaseUrl = credentials?.baseUrl || process.env.PROBABLE_BASE_URL || utils_1.DEFAULT_BASE_URL;
|
|
35
36
|
const descriptor = (0, openapi_1.parseOpenApiSpec)(api_1.probableApiSpec, probableBaseUrl);
|
|
@@ -55,6 +56,26 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
55
56
|
}
|
|
56
57
|
return this.auth;
|
|
57
58
|
}
|
|
59
|
+
async getAuthNonce(walletAddress) {
|
|
60
|
+
return (0, auth_1.getAuthNonce)(walletAddress, this.callApi.bind(this));
|
|
61
|
+
}
|
|
62
|
+
async loginWithSignature(walletAddress, signature, nonce) {
|
|
63
|
+
const credentials = await (0, auth_1.loginWithSignature)(walletAddress, signature, nonce, this.callApi.bind(this));
|
|
64
|
+
this.storeSession(walletAddress, credentials);
|
|
65
|
+
return credentials;
|
|
66
|
+
}
|
|
67
|
+
async logout(walletAddress) {
|
|
68
|
+
await (0, auth_1.logout)(this.callApi.bind(this));
|
|
69
|
+
if (walletAddress) {
|
|
70
|
+
this.removeSession(walletAddress);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async verifyL1(walletAddress, signature) {
|
|
74
|
+
return (0, auth_1.verifyL1)(walletAddress, signature, this.callApi.bind(this));
|
|
75
|
+
}
|
|
76
|
+
async verifyL2(walletAddress, signature) {
|
|
77
|
+
return (0, auth_1.verifyL2)(walletAddress, signature, this.callApi.bind(this));
|
|
78
|
+
}
|
|
58
79
|
// --------------------------------------------------------------------------
|
|
59
80
|
// Market Data (fetcher -> normalizer)
|
|
60
81
|
// --------------------------------------------------------------------------
|
package/dist/router/types.d.ts
CHANGED
|
@@ -48,6 +48,19 @@ export interface ArbitrageOpportunity {
|
|
|
48
48
|
/** Match confidence score (0.0 to 1.0). */
|
|
49
49
|
confidence?: number;
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Parameters for comparing market prices across venues.
|
|
53
|
+
*/
|
|
54
|
+
export interface CompareMarketPricesParams {
|
|
55
|
+
/** The source market ID to compare against. */
|
|
56
|
+
marketId: string;
|
|
57
|
+
/** Optional list of target market IDs to compare with. If not provided, the router finds matches automatically. */
|
|
58
|
+
targetMarketIds?: string[];
|
|
59
|
+
/** Minimum price difference to return. */
|
|
60
|
+
minDifference?: number;
|
|
61
|
+
/** Maximum number of results to return. */
|
|
62
|
+
limit?: number;
|
|
63
|
+
}
|
|
51
64
|
export interface FetchMarketMatchesParams {
|
|
52
65
|
/** Keyword search across matched market titles. */
|
|
53
66
|
query?: string;
|
|
@@ -68,6 +81,45 @@ export interface FetchMarketMatchesParams {
|
|
|
68
81
|
/** Sort order. Browse mode only. */
|
|
69
82
|
sort?: 'confidence' | 'volume' | 'priceDifference';
|
|
70
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Response from /auth/nonce
|
|
86
|
+
*/
|
|
87
|
+
export interface AuthNonceResponse {
|
|
88
|
+
/** Random nonce to be signed */
|
|
89
|
+
nonce: string;
|
|
90
|
+
/** Human-readable message to sign */
|
|
91
|
+
messageToSign: string;
|
|
92
|
+
/** Optional expiry timestamp (milliseconds) */
|
|
93
|
+
expiresAt?: number;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Response from /auth/login
|
|
97
|
+
*/
|
|
98
|
+
export interface AuthLoginResponse {
|
|
99
|
+
/** API key for authenticated requests */
|
|
100
|
+
apiKey: string;
|
|
101
|
+
/** API secret for signing */
|
|
102
|
+
apiSecret: string;
|
|
103
|
+
/** Passphrase for trading */
|
|
104
|
+
passphrase?: string;
|
|
105
|
+
/** Session expiry timestamp (milliseconds) */
|
|
106
|
+
expiresAt?: number;
|
|
107
|
+
/** Whether session is active */
|
|
108
|
+
active?: boolean;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Session state stored in memory
|
|
112
|
+
*/
|
|
113
|
+
export interface AuthSession {
|
|
114
|
+
/** Wallet address that authenticated */
|
|
115
|
+
walletAddress: string;
|
|
116
|
+
/** Session credentials */
|
|
117
|
+
credentials: AuthLoginResponse;
|
|
118
|
+
/** When session was created (milliseconds) */
|
|
119
|
+
createdAt: number;
|
|
120
|
+
/** When session was last used (milliseconds) */
|
|
121
|
+
lastUsedAt: number;
|
|
122
|
+
}
|
|
71
123
|
/** @deprecated Use {@link FetchMarketMatchesParams} instead. */
|
|
72
124
|
export type FetchMatchesParams = FetchMarketMatchesParams;
|
|
73
125
|
export interface FetchEventMatchesParams {
|
|
@@ -1,4 +1,54 @@
|
|
|
1
1
|
{
|
|
2
|
+
"getAuthNonce": {
|
|
3
|
+
"verb": "post",
|
|
4
|
+
"args": [
|
|
5
|
+
{
|
|
6
|
+
"name": "walletAddress",
|
|
7
|
+
"kind": "string",
|
|
8
|
+
"optional": false
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
"loginWithSignature": {
|
|
13
|
+
"verb": "post",
|
|
14
|
+
"args": [
|
|
15
|
+
{
|
|
16
|
+
"name": "walletAddress",
|
|
17
|
+
"kind": "string",
|
|
18
|
+
"optional": false
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "signature",
|
|
22
|
+
"kind": "string",
|
|
23
|
+
"optional": false
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"name": "nonce",
|
|
27
|
+
"kind": "string",
|
|
28
|
+
"optional": false
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
"logout": {
|
|
33
|
+
"verb": "post",
|
|
34
|
+
"args": [
|
|
35
|
+
{
|
|
36
|
+
"name": "walletAddress",
|
|
37
|
+
"kind": "string",
|
|
38
|
+
"optional": true
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"isSessionActive": {
|
|
43
|
+
"verb": "post",
|
|
44
|
+
"args": [
|
|
45
|
+
{
|
|
46
|
+
"name": "walletAddress",
|
|
47
|
+
"kind": "string",
|
|
48
|
+
"optional": false
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
},
|
|
2
52
|
"loadMarkets": {
|
|
3
53
|
"verb": "post",
|
|
4
54
|
"args": [
|
package/dist/server/openapi.yaml
CHANGED
|
@@ -27,6 +27,145 @@ paths:
|
|
|
27
27
|
timestamp:
|
|
28
28
|
type: integer
|
|
29
29
|
format: int64
|
|
30
|
+
'/api/{exchange}/getAuthNonce':
|
|
31
|
+
post:
|
|
32
|
+
summary: Get Auth Nonce
|
|
33
|
+
operationId: getAuthNonce
|
|
34
|
+
parameters:
|
|
35
|
+
- $ref: '#/components/parameters/ExchangeParam'
|
|
36
|
+
requestBody:
|
|
37
|
+
content:
|
|
38
|
+
application/json:
|
|
39
|
+
schema:
|
|
40
|
+
title: GetAuthNonceRequest
|
|
41
|
+
type: object
|
|
42
|
+
properties:
|
|
43
|
+
args:
|
|
44
|
+
type: array
|
|
45
|
+
maxItems: 1
|
|
46
|
+
items:
|
|
47
|
+
type: string
|
|
48
|
+
minItems: 1
|
|
49
|
+
credentials:
|
|
50
|
+
$ref: '#/components/schemas/ExchangeCredentials'
|
|
51
|
+
required:
|
|
52
|
+
- args
|
|
53
|
+
responses:
|
|
54
|
+
'200':
|
|
55
|
+
description: Get Auth Nonce response
|
|
56
|
+
content:
|
|
57
|
+
application/json:
|
|
58
|
+
schema:
|
|
59
|
+
allOf:
|
|
60
|
+
- $ref: '#/components/schemas/BaseResponse'
|
|
61
|
+
- type: object
|
|
62
|
+
properties:
|
|
63
|
+
data:
|
|
64
|
+
type: object
|
|
65
|
+
description: Get a cryptographic nonce for Web3 login.
|
|
66
|
+
'/api/{exchange}/loginWithSignature':
|
|
67
|
+
post:
|
|
68
|
+
summary: Login With Signature
|
|
69
|
+
operationId: loginWithSignature
|
|
70
|
+
parameters:
|
|
71
|
+
- $ref: '#/components/parameters/ExchangeParam'
|
|
72
|
+
requestBody:
|
|
73
|
+
content:
|
|
74
|
+
application/json:
|
|
75
|
+
schema:
|
|
76
|
+
title: LoginWithSignatureRequest
|
|
77
|
+
type: object
|
|
78
|
+
properties:
|
|
79
|
+
args:
|
|
80
|
+
type: array
|
|
81
|
+
minItems: 3
|
|
82
|
+
maxItems: 3
|
|
83
|
+
items:
|
|
84
|
+
oneOf:
|
|
85
|
+
- type: string
|
|
86
|
+
- type: string
|
|
87
|
+
- type: string
|
|
88
|
+
credentials:
|
|
89
|
+
$ref: '#/components/schemas/ExchangeCredentials'
|
|
90
|
+
required:
|
|
91
|
+
- args
|
|
92
|
+
responses:
|
|
93
|
+
'200':
|
|
94
|
+
description: Login With Signature response
|
|
95
|
+
content:
|
|
96
|
+
application/json:
|
|
97
|
+
schema:
|
|
98
|
+
allOf:
|
|
99
|
+
- $ref: '#/components/schemas/BaseResponse'
|
|
100
|
+
- type: object
|
|
101
|
+
properties:
|
|
102
|
+
data:
|
|
103
|
+
type: object
|
|
104
|
+
description: Login with a signed nonce to obtain session credentials.
|
|
105
|
+
'/api/{exchange}/logout':
|
|
106
|
+
post:
|
|
107
|
+
summary: Logout
|
|
108
|
+
operationId: logout
|
|
109
|
+
parameters:
|
|
110
|
+
- $ref: '#/components/parameters/ExchangeParam'
|
|
111
|
+
requestBody:
|
|
112
|
+
content:
|
|
113
|
+
application/json:
|
|
114
|
+
schema:
|
|
115
|
+
title: LogoutRequest
|
|
116
|
+
type: object
|
|
117
|
+
properties:
|
|
118
|
+
args:
|
|
119
|
+
type: array
|
|
120
|
+
maxItems: 1
|
|
121
|
+
items:
|
|
122
|
+
type: string
|
|
123
|
+
credentials:
|
|
124
|
+
$ref: '#/components/schemas/ExchangeCredentials'
|
|
125
|
+
responses:
|
|
126
|
+
'200':
|
|
127
|
+
description: Logout response
|
|
128
|
+
content:
|
|
129
|
+
application/json:
|
|
130
|
+
schema:
|
|
131
|
+
$ref: '#/components/schemas/BaseResponse'
|
|
132
|
+
description: Logout and invalidate the current session.
|
|
133
|
+
'/api/{exchange}/isSessionActive':
|
|
134
|
+
post:
|
|
135
|
+
summary: Is Session Active
|
|
136
|
+
operationId: isSessionActive
|
|
137
|
+
parameters:
|
|
138
|
+
- $ref: '#/components/parameters/ExchangeParam'
|
|
139
|
+
requestBody:
|
|
140
|
+
content:
|
|
141
|
+
application/json:
|
|
142
|
+
schema:
|
|
143
|
+
title: IsSessionActiveRequest
|
|
144
|
+
type: object
|
|
145
|
+
properties:
|
|
146
|
+
args:
|
|
147
|
+
type: array
|
|
148
|
+
maxItems: 1
|
|
149
|
+
items:
|
|
150
|
+
type: string
|
|
151
|
+
minItems: 1
|
|
152
|
+
credentials:
|
|
153
|
+
$ref: '#/components/schemas/ExchangeCredentials'
|
|
154
|
+
required:
|
|
155
|
+
- args
|
|
156
|
+
responses:
|
|
157
|
+
'200':
|
|
158
|
+
description: Is Session Active response
|
|
159
|
+
content:
|
|
160
|
+
application/json:
|
|
161
|
+
schema:
|
|
162
|
+
allOf:
|
|
163
|
+
- $ref: '#/components/schemas/BaseResponse'
|
|
164
|
+
- type: object
|
|
165
|
+
properties:
|
|
166
|
+
data:
|
|
167
|
+
type: boolean
|
|
168
|
+
description: Check if a session is active for the given wallet address.
|
|
30
169
|
'/api/{exchange}/loadMarkets':
|
|
31
170
|
post:
|
|
32
171
|
summary: Load Markets
|
|
@@ -1758,7 +1897,7 @@ paths:
|
|
|
1758
1897
|
type: array
|
|
1759
1898
|
maxItems: 1
|
|
1760
1899
|
items:
|
|
1761
|
-
|
|
1900
|
+
type: object
|
|
1762
1901
|
minItems: 1
|
|
1763
1902
|
credentials:
|
|
1764
1903
|
$ref: '#/components/schemas/ExchangeCredentials'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmxt-core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.54.0",
|
|
4
4
|
"description": "Local sidecar API for supported prediction markets.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"test": "jest -c jest.config.js",
|
|
30
30
|
"server": "tsx watch src/server/index.ts",
|
|
31
31
|
"server:prod": "node dist/server/index.js",
|
|
32
|
-
"generate:sdk:python": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g python -o ../sdks/python/generated --package-name pmxt_internal --additional-properties=projectName=pmxt-internal,packageVersion=2.
|
|
33
|
-
"generate:sdk:typescript": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g typescript-fetch -o ../sdks/typescript/generated --additional-properties=npmName=pmxtjs,npmVersion=2.
|
|
32
|
+
"generate:sdk:python": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g python -o ../sdks/python/generated --package-name pmxt_internal --additional-properties=projectName=pmxt-internal,packageVersion=2.54.0,library=urllib3",
|
|
33
|
+
"generate:sdk:typescript": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g typescript-fetch -o ../sdks/typescript/generated --additional-properties=npmName=pmxtjs,npmVersion=2.54.0,supportsES6=true,typescriptThreePlus=true && node ../sdks/typescript/scripts/fix-generated.js",
|
|
34
34
|
"fetch:openapi": "node scripts/fetch-openapi-specs.js",
|
|
35
35
|
"extract:jsdoc": "node ../scripts/extract-jsdoc.js",
|
|
36
36
|
"generate:docs": "npm run extract:jsdoc && node ../scripts/generate-api-docs.js",
|