pmxt-core 1.0.0-b2 → 1.0.0-b3
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.
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resetCache = resetCache;
|
|
6
7
|
exports.fetchMarkets = fetchMarkets;
|
|
7
8
|
const axios_1 = __importDefault(require("axios"));
|
|
8
9
|
const utils_1 = require("./utils");
|
|
@@ -36,12 +37,17 @@ async function fetchActiveEvents(targetMarketCount) {
|
|
|
36
37
|
totalMarketCount += (event.markets || []).length;
|
|
37
38
|
}
|
|
38
39
|
// Early termination: if we have enough markets, stop fetching
|
|
39
|
-
|
|
40
|
+
// Use 1.5x multiplier to ensure we have enough for sorting/filtering
|
|
41
|
+
if (totalMarketCount >= targetMarketCount * 1.5) {
|
|
40
42
|
break;
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
cursor = response.data.cursor;
|
|
44
46
|
page++;
|
|
47
|
+
// Additional safety: if no target specified, limit to reasonable number of pages
|
|
48
|
+
if (!targetMarketCount && page >= 10) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
45
51
|
}
|
|
46
52
|
catch (e) {
|
|
47
53
|
console.error(`Error fetching Kalshi page ${page}:`, e);
|
|
@@ -67,18 +73,44 @@ async function fetchSeriesMap() {
|
|
|
67
73
|
return new Map();
|
|
68
74
|
}
|
|
69
75
|
}
|
|
76
|
+
// Simple in-memory cache to avoid redundant API calls within a short period
|
|
77
|
+
let cachedEvents = null;
|
|
78
|
+
let cachedSeriesMap = null;
|
|
79
|
+
let lastCacheTime = 0;
|
|
80
|
+
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
|
|
81
|
+
// Export a function to reset the cache (useful for testing)
|
|
82
|
+
function resetCache() {
|
|
83
|
+
cachedEvents = null;
|
|
84
|
+
cachedSeriesMap = null;
|
|
85
|
+
lastCacheTime = 0;
|
|
86
|
+
}
|
|
70
87
|
async function fetchMarkets(params) {
|
|
71
88
|
const limit = params?.limit || 50;
|
|
89
|
+
const now = Date.now();
|
|
72
90
|
try {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
91
|
+
let events;
|
|
92
|
+
let seriesMap;
|
|
93
|
+
if (cachedEvents && cachedSeriesMap && (now - lastCacheTime < CACHE_TTL)) {
|
|
94
|
+
events = cachedEvents;
|
|
95
|
+
seriesMap = cachedSeriesMap;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// Fetch active events with nested markets
|
|
99
|
+
// We also fetch Series metadata to get tags (tags are on Series, not Event)
|
|
100
|
+
const [allEvents, fetchedSeriesMap] = await Promise.all([
|
|
101
|
+
fetchActiveEvents(limit),
|
|
102
|
+
fetchSeriesMap()
|
|
103
|
+
]);
|
|
104
|
+
events = allEvents;
|
|
105
|
+
seriesMap = fetchedSeriesMap;
|
|
106
|
+
cachedEvents = allEvents;
|
|
107
|
+
cachedSeriesMap = fetchedSeriesMap;
|
|
108
|
+
lastCacheTime = now;
|
|
109
|
+
}
|
|
79
110
|
// Extract ALL markets from all events
|
|
80
111
|
const allMarkets = [];
|
|
81
|
-
|
|
112
|
+
// ... rest of the logic
|
|
113
|
+
for (const event of events) {
|
|
82
114
|
// Enrich event with tags from Series
|
|
83
115
|
if (event.series_ticker && seriesMap.has(event.series_ticker)) {
|
|
84
116
|
// If event has no tags or empty tags, use series tags
|
package/dist/server/app.js
CHANGED
|
@@ -8,8 +8,8 @@ const express_1 = __importDefault(require("express"));
|
|
|
8
8
|
const cors_1 = __importDefault(require("cors"));
|
|
9
9
|
const polymarket_1 = require("../exchanges/polymarket");
|
|
10
10
|
const kalshi_1 = require("../exchanges/kalshi");
|
|
11
|
-
// Singleton instances for local usage
|
|
12
|
-
const
|
|
11
|
+
// Singleton instances for local usage (when no credentials provided)
|
|
12
|
+
const defaultExchanges = {
|
|
13
13
|
polymarket: null,
|
|
14
14
|
kalshi: null
|
|
15
15
|
};
|
|
@@ -22,17 +22,26 @@ async function startServer(port) {
|
|
|
22
22
|
res.json({ status: 'ok', timestamp: Date.now() });
|
|
23
23
|
});
|
|
24
24
|
// API endpoint: POST /api/:exchange/:method
|
|
25
|
-
// Body: { args: any[] }
|
|
25
|
+
// Body: { args: any[], credentials?: ExchangeCredentials }
|
|
26
26
|
app.post('/api/:exchange/:method', async (req, res, next) => {
|
|
27
27
|
try {
|
|
28
28
|
const exchangeName = req.params.exchange.toLowerCase();
|
|
29
29
|
const methodName = req.params.method;
|
|
30
30
|
const args = Array.isArray(req.body.args) ? req.body.args : [];
|
|
31
|
+
const credentials = req.body.credentials;
|
|
31
32
|
// 1. Get or Initialize Exchange
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
// If credentials are provided, create a new instance for this request
|
|
34
|
+
// Otherwise, use the singleton instance
|
|
35
|
+
let exchange;
|
|
36
|
+
if (credentials && (credentials.privateKey || credentials.apiKey)) {
|
|
37
|
+
exchange = createExchange(exchangeName, credentials);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
if (!defaultExchanges[exchangeName]) {
|
|
41
|
+
defaultExchanges[exchangeName] = createExchange(exchangeName);
|
|
42
|
+
}
|
|
43
|
+
exchange = defaultExchanges[exchangeName];
|
|
34
44
|
}
|
|
35
|
-
const exchange = exchanges[exchangeName];
|
|
36
45
|
// 2. Validate Method
|
|
37
46
|
if (typeof exchange[methodName] !== 'function') {
|
|
38
47
|
res.status(404).json({ success: false, error: `Method '${methodName}' not found on ${exchangeName}` });
|
|
@@ -59,19 +68,19 @@ async function startServer(port) {
|
|
|
59
68
|
});
|
|
60
69
|
return app.listen(port);
|
|
61
70
|
}
|
|
62
|
-
function createExchange(name) {
|
|
71
|
+
function createExchange(name, credentials) {
|
|
63
72
|
switch (name) {
|
|
64
73
|
case 'polymarket':
|
|
65
74
|
return new polymarket_1.PolymarketExchange({
|
|
66
|
-
privateKey: process.env.POLYMARKET_PK || process.env.POLYMARKET_PRIVATE_KEY,
|
|
67
|
-
apiKey: process.env.POLYMARKET_API_KEY,
|
|
68
|
-
apiSecret: process.env.POLYMARKET_API_SECRET,
|
|
69
|
-
passphrase: process.env.POLYMARKET_PASSPHRASE
|
|
75
|
+
privateKey: credentials?.privateKey || process.env.POLYMARKET_PK || process.env.POLYMARKET_PRIVATE_KEY,
|
|
76
|
+
apiKey: credentials?.apiKey || process.env.POLYMARKET_API_KEY,
|
|
77
|
+
apiSecret: credentials?.apiSecret || process.env.POLYMARKET_API_SECRET,
|
|
78
|
+
passphrase: credentials?.passphrase || process.env.POLYMARKET_PASSPHRASE
|
|
70
79
|
});
|
|
71
80
|
case 'kalshi':
|
|
72
81
|
return new kalshi_1.KalshiExchange({
|
|
73
|
-
apiKey: process.env.KALSHI_API_KEY,
|
|
74
|
-
privateKey: process.env.KALSHI_PRIVATE_KEY
|
|
82
|
+
apiKey: credentials?.apiKey || process.env.KALSHI_API_KEY,
|
|
83
|
+
privateKey: credentials?.privateKey || process.env.KALSHI_PRIVATE_KEY
|
|
75
84
|
});
|
|
76
85
|
default:
|
|
77
86
|
throw new Error(`Unknown exchange: ${name}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmxt-core",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-b3",
|
|
4
4
|
"description": "pmxt is a unified prediction market data API. The ccxt for prediction markets.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"test": "jest -c jest.config.js",
|
|
29
29
|
"server": "tsx watch src/server/index.ts",
|
|
30
30
|
"server:prod": "node dist/server/index.js",
|
|
31
|
-
"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=1.0.
|
|
32
|
-
"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=1.0.0-
|
|
31
|
+
"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=1.0.0b3,library=urllib3",
|
|
32
|
+
"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=1.0.0-b3,supportsES6=true,typescriptThreePlus=true",
|
|
33
33
|
"generate:docs": "node ../scripts/generate-api-docs.js",
|
|
34
34
|
"generate:sdk:all": "npm run generate:sdk:python && npm run generate:sdk:typescript && npm run generate:docs"
|
|
35
35
|
},
|