@elizaos/plugin-polymarket-app 2.0.3-beta.6 → 2.0.3-beta.7

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.
Files changed (95) hide show
  1. package/dist/PolymarketAppView.d.ts +3 -0
  2. package/dist/PolymarketAppView.d.ts.map +1 -0
  3. package/dist/PolymarketAppView.helpers.d.ts +10 -0
  4. package/dist/PolymarketAppView.helpers.d.ts.map +1 -0
  5. package/dist/PolymarketAppView.helpers.js +30 -0
  6. package/dist/PolymarketAppView.helpers.js.map +1 -0
  7. package/dist/PolymarketAppView.interact.d.ts +3 -0
  8. package/dist/PolymarketAppView.interact.d.ts.map +1 -0
  9. package/dist/PolymarketAppView.interact.js +70 -0
  10. package/dist/PolymarketAppView.interact.js.map +1 -0
  11. package/dist/PolymarketAppView.js +704 -0
  12. package/dist/PolymarketAppView.js.map +1 -0
  13. package/dist/PolymarketPositionsPanel.d.ts +13 -0
  14. package/dist/PolymarketPositionsPanel.d.ts.map +1 -0
  15. package/dist/PolymarketPositionsPanel.js +349 -0
  16. package/dist/PolymarketPositionsPanel.js.map +1 -0
  17. package/dist/PolymarketView.d.ts +13 -0
  18. package/dist/PolymarketView.d.ts.map +1 -0
  19. package/dist/PolymarketView.js +58 -0
  20. package/dist/PolymarketView.js.map +1 -0
  21. package/dist/__fixtures__/contract.d.ts +9 -0
  22. package/dist/__fixtures__/contract.d.ts.map +1 -0
  23. package/dist/__fixtures__/contract.js +263 -0
  24. package/dist/__fixtures__/contract.js.map +1 -0
  25. package/dist/actions.d.ts +39 -0
  26. package/dist/actions.d.ts.map +1 -0
  27. package/dist/actions.js +661 -0
  28. package/dist/actions.js.map +1 -0
  29. package/dist/client.d.ts +25 -0
  30. package/dist/client.d.ts.map +1 -0
  31. package/dist/client.js +42 -0
  32. package/dist/client.js.map +1 -0
  33. package/dist/components/PolymarketSpatialView.d.ts +34 -0
  34. package/dist/components/PolymarketSpatialView.d.ts.map +1 -0
  35. package/dist/components/PolymarketSpatialView.js +248 -0
  36. package/dist/components/PolymarketSpatialView.js.map +1 -0
  37. package/dist/index.d.ts +14 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +24 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/orderbook.d.ts +15 -0
  42. package/dist/orderbook.d.ts.map +1 -0
  43. package/dist/orderbook.js +45 -0
  44. package/dist/orderbook.js.map +1 -0
  45. package/dist/plugin.d.ts +3 -0
  46. package/dist/plugin.d.ts.map +1 -0
  47. package/dist/plugin.js +108 -0
  48. package/dist/plugin.js.map +1 -0
  49. package/dist/polymarket-app.d.ts +4 -0
  50. package/dist/polymarket-app.d.ts.map +1 -0
  51. package/dist/polymarket-app.js +18 -0
  52. package/dist/polymarket-app.js.map +1 -0
  53. package/dist/polymarket-contracts.d.ts +162 -0
  54. package/dist/polymarket-contracts.d.ts.map +1 -0
  55. package/dist/polymarket-contracts.js +16 -0
  56. package/dist/polymarket-contracts.js.map +1 -0
  57. package/dist/polymarket-view-bundle.d.ts +3 -0
  58. package/dist/polymarket-view-bundle.d.ts.map +1 -0
  59. package/dist/polymarket-view-bundle.js +7 -0
  60. package/dist/polymarket-view-bundle.js.map +1 -0
  61. package/dist/provider-text.d.ts +5 -0
  62. package/dist/provider-text.d.ts.map +1 -0
  63. package/dist/provider-text.js +44 -0
  64. package/dist/provider-text.js.map +1 -0
  65. package/dist/provider.d.ts +3 -0
  66. package/dist/provider.d.ts.map +1 -0
  67. package/dist/provider.js +21 -0
  68. package/dist/provider.js.map +1 -0
  69. package/dist/register-routes.d.ts +2 -0
  70. package/dist/register-routes.d.ts.map +1 -0
  71. package/dist/register-routes.js +6 -0
  72. package/dist/register-routes.js.map +1 -0
  73. package/dist/register-terminal-view.d.ts +15 -0
  74. package/dist/register-terminal-view.d.ts.map +1 -0
  75. package/dist/register-terminal-view.js +25 -0
  76. package/dist/register-terminal-view.js.map +1 -0
  77. package/dist/register.d.ts +2 -0
  78. package/dist/register.d.ts.map +1 -0
  79. package/dist/register.js +17 -0
  80. package/dist/register.js.map +1 -0
  81. package/dist/routes.d.ts +7 -0
  82. package/dist/routes.d.ts.map +1 -0
  83. package/dist/routes.js +455 -0
  84. package/dist/routes.js.map +1 -0
  85. package/dist/ui.d.ts +6 -0
  86. package/dist/ui.d.ts.map +1 -0
  87. package/dist/ui.js +11 -0
  88. package/dist/ui.js.map +1 -0
  89. package/dist/usePolymarketState.d.ts +13 -0
  90. package/dist/usePolymarketState.d.ts.map +1 -0
  91. package/dist/usePolymarketState.js +59 -0
  92. package/dist/usePolymarketState.js.map +1 -0
  93. package/dist/views/bundle.js +535 -0
  94. package/dist/views/bundle.js.map +1 -0
  95. package/package.json +6 -6
@@ -0,0 +1,661 @@
1
+ import { Service } from "@elizaos/core";
2
+ import { resolveApiToken, resolveDesktopApiPort } from "@elizaos/shared";
3
+ const ACTION_TIMEOUT_MS = 15e3;
4
+ const PREDICTION_MARKET_SERVICE_TYPE = "prediction-market";
5
+ const POLYMARKET_CONTEXTS = ["finance", "crypto", "prediction-market"];
6
+ const POLYMARKET_ACTION_CONTEXTS = [
7
+ ...POLYMARKET_CONTEXTS,
8
+ "payments"
9
+ ];
10
+ const POLYMARKET_ACTION_NAME = "PREDICTION_MARKET";
11
+ const POLYMARKET_READ_COMPAT_NAME = "POLYMARKET_READ";
12
+ const POLYMARKET_PLACE_ORDER_COMPAT_NAME = "POLYMARKET_PLACE_ORDER";
13
+ function toCallbackData(data) {
14
+ return data;
15
+ }
16
+ const POLYMARKET_READ_KEYWORDS = [
17
+ "polymarket",
18
+ "prediction market",
19
+ "market",
20
+ "markets",
21
+ "orderbook",
22
+ "positions",
23
+ "odds",
24
+ "forecast",
25
+ "predicci\xF3n",
26
+ "mercado",
27
+ "pron\xF3stico",
28
+ "march\xE9",
29
+ "pr\xE9vision",
30
+ "prognose",
31
+ "markt",
32
+ "mercado",
33
+ "previs\xE3o",
34
+ "mercato",
35
+ "previsione",
36
+ "\u4E88\u6E2C\u5E02\u5834",
37
+ "\u30AA\u30C3\u30BA",
38
+ "\u9884\u6D4B\u5E02\u573A",
39
+ "\u8D54\u7387",
40
+ "\uC608\uCE21 \uC2DC\uC7A5",
41
+ "\uBC30\uB2F9"
42
+ ];
43
+ const POLYMARKET_TRADE_KEYWORDS = [
44
+ ...POLYMARKET_READ_KEYWORDS,
45
+ "buy",
46
+ "sell",
47
+ "trade",
48
+ "order",
49
+ "comprar",
50
+ "vender",
51
+ "orden",
52
+ "acheter",
53
+ "vendre",
54
+ "ordre",
55
+ "kaufen",
56
+ "verkaufen",
57
+ "auftrag",
58
+ "comprare",
59
+ "vendere",
60
+ "\u6CE8\u6587",
61
+ "\u8CB7\u3046",
62
+ "\u58F2\u308B",
63
+ "\u4E70\u5165",
64
+ "\u5356\u51FA",
65
+ "\u8BA2\u5355",
66
+ "\uB9E4\uC218",
67
+ "\uB9E4\uB3C4"
68
+ ];
69
+ const READ_KINDS = [
70
+ "status",
71
+ "markets",
72
+ "market",
73
+ "orderbook",
74
+ "positions"
75
+ ];
76
+ const POLYMARKET_OPS = ["read", "place_order"];
77
+ const POLYMARKET_READ_COMPAT_SIMILES = [
78
+ POLYMARKET_READ_COMPAT_NAME,
79
+ "POLYMARKET_STATUS",
80
+ "POLYMARKET_READINESS",
81
+ "POLYMARKET_HEALTH",
82
+ "POLYMARKET_GET_MARKETS",
83
+ "POLYMARKET_MARKETS",
84
+ "SEARCH_POLYMARKET_MARKETS",
85
+ "POLYMARKET_GET_MARKET",
86
+ "POLYMARKET_MARKET",
87
+ "POLYMARKET_MARKET_DETAILS",
88
+ "POLYMARKET_GET_ORDERBOOK",
89
+ "POLYMARKET_ORDERBOOK",
90
+ "POLYMARKET_QUOTE",
91
+ "POLYMARKET_TOKEN_INFO",
92
+ "POLYMARKET_GET_POSITIONS",
93
+ "POLYMARKET_POSITIONS",
94
+ "POLYMARKET_WALLET_POSITIONS"
95
+ ];
96
+ const POLYMARKET_PLACE_ORDER_COMPAT_SIMILES = [
97
+ POLYMARKET_PLACE_ORDER_COMPAT_NAME,
98
+ "POLYMARKET_TRADE",
99
+ "POLYMARKET_BUY",
100
+ "POLYMARKET_SELL"
101
+ ];
102
+ const POLYMARKET_READ_OP_ALIASES = /* @__PURE__ */ new Set([
103
+ ...READ_KINDS,
104
+ ...POLYMARKET_READ_COMPAT_SIMILES.map((name) => name.toLowerCase())
105
+ ]);
106
+ const POLYMARKET_PLACE_ORDER_OP_ALIASES = /* @__PURE__ */ new Set([
107
+ ...POLYMARKET_PLACE_ORDER_COMPAT_SIMILES.map((name) => name.toLowerCase()),
108
+ "trade",
109
+ "order",
110
+ "buy",
111
+ "sell"
112
+ ]);
113
+ function getApiBase() {
114
+ return `http://127.0.0.1:${resolveDesktopApiPort(process.env)}`;
115
+ }
116
+ function buildAuthHeaders() {
117
+ const token = resolveApiToken(process.env);
118
+ if (!token) return {};
119
+ return {
120
+ Authorization: /^Bearer\s+/i.test(token) ? token : `Bearer ${token}`
121
+ };
122
+ }
123
+ function readParam(options, key) {
124
+ const maybeOptions = options;
125
+ if (maybeOptions?.parameters && key in maybeOptions.parameters) {
126
+ return maybeOptions.parameters[key];
127
+ }
128
+ return options?.[key];
129
+ }
130
+ function readStringParam(options, key) {
131
+ const value = readParam(options, key);
132
+ return typeof value === "string" && value.trim() ? value.trim() : null;
133
+ }
134
+ function readNumberParam(options, key, fallback) {
135
+ const value = readParam(options, key);
136
+ const parsed = typeof value === "number" ? value : typeof value === "string" ? Number.parseInt(value, 10) : Number.NaN;
137
+ return Number.isFinite(parsed) ? parsed : fallback;
138
+ }
139
+ function readKind(options) {
140
+ const raw = readStringParam(options, "kind");
141
+ if (!raw) return null;
142
+ const normalized = raw.toLowerCase();
143
+ return READ_KINDS.includes(normalized) ? normalized : null;
144
+ }
145
+ function normalizeOp(value) {
146
+ if (typeof value !== "string") return null;
147
+ const normalized = value.trim().toLowerCase().replace(/[\s-]+/g, "_");
148
+ if (POLYMARKET_OPS.includes(normalized)) {
149
+ return normalized;
150
+ }
151
+ if (POLYMARKET_READ_OP_ALIASES.has(normalized)) {
152
+ return "read";
153
+ }
154
+ if (POLYMARKET_PLACE_ORDER_OP_ALIASES.has(normalized)) {
155
+ return "place_order";
156
+ }
157
+ return null;
158
+ }
159
+ function readOp(options) {
160
+ const rawOp = readStringParam(options, "action") ?? readStringParam(options, "subaction") ?? readStringParam(options, "op") ?? readStringParam(options, "operation") ?? readStringParam(options, "name");
161
+ const explicit = normalizeOp(rawOp);
162
+ if (explicit) return explicit;
163
+ if (readKind(options)) return "read";
164
+ if (readStringParam(options, "side") || readStringParam(options, "marketId") || readStringParam(options, "market_id") || readParam(options, "amount") !== void 0) {
165
+ return "place_order";
166
+ }
167
+ return null;
168
+ }
169
+ function hasSelectedContext(state, contexts = POLYMARKET_ACTION_CONTEXTS) {
170
+ const selected = /* @__PURE__ */ new Set();
171
+ const collect = (value) => {
172
+ if (!Array.isArray(value)) return;
173
+ for (const item of value) {
174
+ if (typeof item === "string") selected.add(item);
175
+ }
176
+ };
177
+ collect(
178
+ state?.values?.selectedContexts
179
+ );
180
+ collect(
181
+ state?.data?.selectedContexts
182
+ );
183
+ const contextObject = state?.data?.contextObject;
184
+ collect(contextObject?.trajectoryPrefix?.selectedContexts);
185
+ collect(contextObject?.metadata?.selectedContexts);
186
+ return contexts.some((context) => selected.has(context));
187
+ }
188
+ function hasKeywordIntent(message, state, keywords) {
189
+ const text = [
190
+ typeof message.content?.text === "string" ? message.content.text : "",
191
+ typeof state?.values?.recentMessages === "string" ? state.values.recentMessages : ""
192
+ ].join("\n").toLowerCase();
193
+ return keywords.some((keyword) => text.includes(keyword.toLowerCase()));
194
+ }
195
+ async function fetchPolymarketJson(path, options = {}) {
196
+ const response = await fetch(`${getApiBase()}${path}`, {
197
+ headers: { accept: "application/json", ...buildAuthHeaders() },
198
+ signal: AbortSignal.timeout(ACTION_TIMEOUT_MS)
199
+ });
200
+ const payload = await response.json().catch(() => null);
201
+ if (options.allowErrorStatus && payload !== null) {
202
+ return payload;
203
+ }
204
+ if (!response.ok) {
205
+ const message = payload && typeof payload === "object" && "error" in payload ? String(payload.error) : `Polymarket API request failed with ${response.status}`;
206
+ throw new Error(message);
207
+ }
208
+ return payload;
209
+ }
210
+ async function emit(callback, text, data) {
211
+ if (callback) {
212
+ await callback({
213
+ text,
214
+ actions: [POLYMARKET_ACTION_NAME],
215
+ data: toCallbackData(data)
216
+ });
217
+ }
218
+ return {
219
+ success: true,
220
+ text,
221
+ data: { actionName: POLYMARKET_ACTION_NAME, ...data }
222
+ };
223
+ }
224
+ async function emitFailure(callback, text, error, data) {
225
+ if (callback) {
226
+ await callback({
227
+ text,
228
+ actions: [POLYMARKET_ACTION_NAME],
229
+ data: toCallbackData(data)
230
+ });
231
+ }
232
+ return { success: false, text, error, data };
233
+ }
234
+ function marketLine(market) {
235
+ const price = market.bestBid || market.bestAsk ? ` bid ${market.bestBid ?? "n/a"} ask ${market.bestAsk ?? "n/a"}` : "";
236
+ const volume = market.volume24hr ? ` volume24h ${market.volume24hr}` : "";
237
+ return `- ${market.question ?? market.slug ?? market.id}${price}${volume}`;
238
+ }
239
+ function formatMarkets(markets) {
240
+ if (markets.length === 0) return "No active Polymarket markets found.";
241
+ return `Polymarket markets:
242
+ ${markets.slice(0, 12).map(marketLine).join("\n")}`;
243
+ }
244
+ function formatMarket(response) {
245
+ const market = response.market;
246
+ if (!market) return "No matching Polymarket market found.";
247
+ const tokens = market.clobTokenIds.length ? `
248
+ Token IDs: ${market.clobTokenIds.join(", ")}` : "";
249
+ const outcomes = market.outcomes.length ? `
250
+ Outcomes: ${market.outcomes.map((outcome) => `${outcome.name} ${outcome.price ?? "n/a"}`).join(", ")}` : "";
251
+ return `${market.question ?? market.slug ?? market.id}
252
+ Status: ${market.active ? "active" : "inactive"}, ${market.closed ? "closed" : "open"}
253
+ Best bid: ${market.bestBid ?? "n/a"}
254
+ Best ask: ${market.bestAsk ?? "n/a"}${outcomes}${tokens}`;
255
+ }
256
+ function formatOrderbook(orderbook) {
257
+ return [
258
+ `Polymarket orderbook for ${orderbook.tokenId}:`,
259
+ `Best bid: ${orderbook.bestBid ?? "n/a"} (${orderbook.bestBidSize ?? "n/a"})`,
260
+ `Best ask: ${orderbook.bestAsk ?? "n/a"} (${orderbook.bestAskSize ?? "n/a"})`,
261
+ `Spread: ${orderbook.spread ?? "n/a"}`,
262
+ `Midpoint: ${orderbook.midpoint ?? "n/a"}`,
263
+ `Depth: ${orderbook.bidLevels} bids, ${orderbook.askLevels} asks`
264
+ ].join("\n");
265
+ }
266
+ async function handleStatus(callback) {
267
+ const status = await fetchPolymarketJson(
268
+ "/api/polymarket/status"
269
+ );
270
+ const text = `Polymarket public reads: ${status.publicReads.ready ? "ready" : "not ready"}
271
+ Trading: ${status.trading.ready ? "ready" : "disabled"}
272
+ Credentials: ${status.trading.credentialsReady ? "present" : "missing"}${status.trading.reason ? `
273
+ Reason: ${status.trading.reason}` : ""}`;
274
+ return emit(callback, text, {
275
+ op: "read",
276
+ compatActionName: POLYMARKET_READ_COMPAT_NAME,
277
+ kind: "status",
278
+ status
279
+ });
280
+ }
281
+ async function handleMarkets(options, callback) {
282
+ const limit = Math.min(
283
+ 100,
284
+ Math.max(1, readNumberParam(options, "limit", 20))
285
+ );
286
+ const offset = Math.max(0, readNumberParam(options, "offset", 0));
287
+ const response = await fetchPolymarketJson(
288
+ `/api/polymarket/markets?limit=${limit}&offset=${offset}`
289
+ );
290
+ return emit(callback, formatMarkets(response.markets), {
291
+ op: "read",
292
+ compatActionName: POLYMARKET_READ_COMPAT_NAME,
293
+ kind: "markets",
294
+ markets: response.markets,
295
+ source: response.source
296
+ });
297
+ }
298
+ async function handleMarket(options, callback) {
299
+ const id = readStringParam(options, "id");
300
+ const slug = readStringParam(options, "slug");
301
+ if (!id && !slug) {
302
+ const text = "Provide a Polymarket market id or slug.";
303
+ return emitFailure(callback, text, "missing_market_identifier", {
304
+ actionName: POLYMARKET_ACTION_NAME,
305
+ op: "read",
306
+ compatActionName: POLYMARKET_READ_COMPAT_NAME,
307
+ kind: "market"
308
+ });
309
+ }
310
+ const query = new URLSearchParams();
311
+ if (id) query.set("id", id);
312
+ if (slug && !id) query.set("slug", slug);
313
+ const response = await fetchPolymarketJson(
314
+ `/api/polymarket/market?${query.toString()}`
315
+ );
316
+ return emit(callback, formatMarket(response), {
317
+ op: "read",
318
+ compatActionName: POLYMARKET_READ_COMPAT_NAME,
319
+ kind: "market",
320
+ market: response.market,
321
+ source: response.source
322
+ });
323
+ }
324
+ async function handleOrderbook(options, callback) {
325
+ const tokenId = readStringParam(options, "tokenId") ?? readStringParam(options, "token_id");
326
+ if (!tokenId) {
327
+ const text = "Provide a Polymarket CLOB token id.";
328
+ return emitFailure(callback, text, "missing_token_id", {
329
+ actionName: POLYMARKET_ACTION_NAME,
330
+ op: "read",
331
+ compatActionName: POLYMARKET_READ_COMPAT_NAME,
332
+ kind: "orderbook"
333
+ });
334
+ }
335
+ const response = await fetchPolymarketJson(
336
+ `/api/polymarket/orderbook?token_id=${encodeURIComponent(tokenId)}`
337
+ );
338
+ return emit(callback, formatOrderbook(response), {
339
+ op: "read",
340
+ compatActionName: POLYMARKET_READ_COMPAT_NAME,
341
+ kind: "orderbook",
342
+ orderbook: response
343
+ });
344
+ }
345
+ async function handlePositions(options, callback) {
346
+ const user = readStringParam(options, "user");
347
+ if (!user) {
348
+ const text2 = "Provide a wallet address for Polymarket positions.";
349
+ return emitFailure(callback, text2, "missing_wallet_address", {
350
+ actionName: POLYMARKET_ACTION_NAME,
351
+ op: "read",
352
+ compatActionName: POLYMARKET_READ_COMPAT_NAME,
353
+ kind: "positions"
354
+ });
355
+ }
356
+ const response = await fetchPolymarketJson(
357
+ `/api/polymarket/positions?user=${encodeURIComponent(user)}`
358
+ );
359
+ const text = response.positions.length === 0 ? "No Polymarket positions found for that wallet." : `Polymarket positions:
360
+ ${response.positions.slice(0, 12).map(
361
+ (position) => `- ${position.question ?? position.conditionId ?? "Market"}: ${position.outcome ?? "outcome"} size ${position.size ?? "n/a"} value ${position.currentValue ?? "n/a"}`
362
+ ).join("\n")}`;
363
+ return emit(callback, text, {
364
+ op: "read",
365
+ compatActionName: POLYMARKET_READ_COMPAT_NAME,
366
+ kind: "positions",
367
+ positions: response.positions,
368
+ source: response.source
369
+ });
370
+ }
371
+ async function handleReadOperation(options, callback) {
372
+ const kind = readKind(options);
373
+ if (!kind) {
374
+ const text = "Provide kind: status | markets | market | orderbook | positions.";
375
+ return emitFailure(callback, text, "missing_or_invalid_kind", {
376
+ actionName: POLYMARKET_ACTION_NAME,
377
+ op: "read",
378
+ compatActionName: POLYMARKET_READ_COMPAT_NAME,
379
+ availableKinds: [...READ_KINDS]
380
+ });
381
+ }
382
+ try {
383
+ switch (kind) {
384
+ case "status":
385
+ return await handleStatus(callback);
386
+ case "markets":
387
+ return await handleMarkets(options, callback);
388
+ case "market":
389
+ return await handleMarket(options, callback);
390
+ case "orderbook":
391
+ return await handleOrderbook(options, callback);
392
+ case "positions":
393
+ return await handlePositions(options, callback);
394
+ }
395
+ } catch (error) {
396
+ const text = error instanceof Error ? error.message : String(error);
397
+ return emitFailure(callback, text, text, {
398
+ actionName: POLYMARKET_ACTION_NAME,
399
+ op: "read",
400
+ compatActionName: POLYMARKET_READ_COMPAT_NAME,
401
+ kind
402
+ });
403
+ }
404
+ }
405
+ async function handlePlaceOrderOperation(callback) {
406
+ const response = await fetchPolymarketJson(
407
+ "/api/polymarket/orders",
408
+ { allowErrorStatus: true }
409
+ ).catch((error) => ({
410
+ enabled: false,
411
+ reason: error instanceof Error ? error.message : String(error),
412
+ requiredForTrading: []
413
+ }));
414
+ const text = `Polymarket order placement is disabled.
415
+ Reason: ${response.reason}${response.requiredForTrading.length ? `
416
+ Required env vars: ${response.requiredForTrading.join(", ")}` : ""}`;
417
+ return {
418
+ ...await emit(callback, text, {
419
+ op: "place_order",
420
+ compatActionName: POLYMARKET_PLACE_ORDER_COMPAT_NAME,
421
+ trading: response
422
+ }),
423
+ success: false,
424
+ error: response.reason
425
+ };
426
+ }
427
+ function normalizeProviderKey(value) {
428
+ return value.trim().toLowerCase().replace(/[\s_-]+/g, "");
429
+ }
430
+ function readTarget(options) {
431
+ return readStringParam(options, "target") ?? readStringParam(options, "provider") ?? "polymarket";
432
+ }
433
+ function createPolymarketProvider() {
434
+ return {
435
+ name: "polymarket",
436
+ aliases: ["poly-market", "clob"],
437
+ supportedSubactions: ["read", "place_order"],
438
+ description: "Polymarket public market reads, orderbook data, positions, and trading readiness.",
439
+ execute: async ({ options, op, callback }) => {
440
+ switch (op) {
441
+ case "read":
442
+ return await handleReadOperation(options, callback);
443
+ case "place_order":
444
+ return await handlePlaceOrderOperation(callback);
445
+ }
446
+ }
447
+ };
448
+ }
449
+ class PredictionMarketService extends Service {
450
+ static serviceType = PREDICTION_MARKET_SERVICE_TYPE;
451
+ capabilityDescription = "Prediction market provider registry; currently registers Polymarket";
452
+ providers = /* @__PURE__ */ new Map();
453
+ aliases = /* @__PURE__ */ new Map();
454
+ static async start(runtime) {
455
+ const service = new PredictionMarketService(runtime);
456
+ service.registerProvider(createPolymarketProvider());
457
+ return service;
458
+ }
459
+ registerProvider(provider) {
460
+ const key = normalizeProviderKey(provider.name);
461
+ this.providers.set(key, provider);
462
+ for (const alias of [provider.name, ...provider.aliases]) {
463
+ this.aliases.set(normalizeProviderKey(alias), key);
464
+ }
465
+ }
466
+ listProviders() {
467
+ return [...this.providers.values()].map((provider) => ({
468
+ name: provider.name,
469
+ aliases: [...provider.aliases],
470
+ supportedSubactions: [...provider.supportedSubactions],
471
+ description: provider.description
472
+ }));
473
+ }
474
+ async route(args) {
475
+ const target = args.target ?? "polymarket";
476
+ const key = this.aliases.get(normalizeProviderKey(target));
477
+ const provider = key ? this.providers.get(key) : void 0;
478
+ if (!provider) {
479
+ const text = `Unsupported prediction market provider "${target}".`;
480
+ const data = {
481
+ actionName: POLYMARKET_ACTION_NAME,
482
+ error: "UNSUPPORTED_PROVIDER",
483
+ providers: this.listProviders()
484
+ };
485
+ await args.callback?.({
486
+ text,
487
+ actions: [POLYMARKET_ACTION_NAME],
488
+ data: toCallbackData(data)
489
+ });
490
+ return {
491
+ success: false,
492
+ text,
493
+ error: "UNSUPPORTED_PROVIDER",
494
+ data
495
+ };
496
+ }
497
+ if (!provider.supportedSubactions.includes(args.op)) {
498
+ const text = `${provider.name} does not support ${args.op}.`;
499
+ await args.callback?.({
500
+ text,
501
+ actions: [POLYMARKET_ACTION_NAME],
502
+ data: {
503
+ actionName: POLYMARKET_ACTION_NAME,
504
+ error: "UNSUPPORTED_SUBACTION",
505
+ provider: provider.name
506
+ }
507
+ });
508
+ return {
509
+ success: false,
510
+ text,
511
+ error: "UNSUPPORTED_SUBACTION",
512
+ data: {
513
+ actionName: POLYMARKET_ACTION_NAME,
514
+ provider: provider.name
515
+ }
516
+ };
517
+ }
518
+ const result = await provider.execute(args);
519
+ return {
520
+ ...result,
521
+ data: {
522
+ ...result.data ?? {},
523
+ actionName: POLYMARKET_ACTION_NAME,
524
+ target: provider.name,
525
+ supportedProviders: this.listProviders()
526
+ }
527
+ };
528
+ }
529
+ async stop() {
530
+ this.providers.clear();
531
+ this.aliases.clear();
532
+ }
533
+ }
534
+ const polymarketAction = {
535
+ name: POLYMARKET_ACTION_NAME,
536
+ contexts: [...POLYMARKET_ACTION_CONTEXTS],
537
+ contextGate: { anyOf: [...POLYMARKET_ACTION_CONTEXTS] },
538
+ roleGate: { minRole: "USER" },
539
+ similes: [
540
+ ...POLYMARKET_READ_COMPAT_SIMILES,
541
+ ...POLYMARKET_PLACE_ORDER_COMPAT_SIMILES
542
+ ],
543
+ description: "Use registered prediction market providers. target selects the provider; Polymarket is registered today. action=read reads public state with kind: status, markets, market, orderbook, or positions. action=place_order reports trading readiness; signed order placement is disabled in this app integration.",
544
+ descriptionCompressed: "Prediction market router: target polymarket; action read or place_order.",
545
+ parameters: [
546
+ {
547
+ name: "target",
548
+ description: "Prediction market provider.",
549
+ required: false,
550
+ schema: { type: "string", enum: ["polymarket"], default: "polymarket" }
551
+ },
552
+ {
553
+ name: "action",
554
+ description: "Prediction market operation: read or place_order.",
555
+ required: false,
556
+ schema: { type: "string", enum: [...POLYMARKET_OPS] }
557
+ },
558
+ {
559
+ name: "subaction",
560
+ description: "Legacy alias for action. Accepts place-order as place_order.",
561
+ required: false,
562
+ schema: { type: "string", enum: [...POLYMARKET_OPS, "place-order"] }
563
+ },
564
+ {
565
+ name: "kind",
566
+ description: "read only: status | markets | market | orderbook | positions.",
567
+ required: false,
568
+ schema: { type: "string", enum: [...READ_KINDS] }
569
+ },
570
+ {
571
+ name: "limit",
572
+ description: "markets only: max markets (1-100).",
573
+ required: false,
574
+ schema: { type: "number", default: 20 }
575
+ },
576
+ {
577
+ name: "offset",
578
+ description: "markets only: result offset.",
579
+ required: false,
580
+ schema: { type: "number", default: 0 }
581
+ },
582
+ {
583
+ name: "id",
584
+ description: "market only: Polymarket Gamma market id.",
585
+ required: false,
586
+ schema: { type: "string" }
587
+ },
588
+ {
589
+ name: "slug",
590
+ description: "market only: Polymarket market slug.",
591
+ required: false,
592
+ schema: { type: "string" }
593
+ },
594
+ {
595
+ name: "tokenId",
596
+ description: "orderbook only: Polymarket CLOB token id.",
597
+ required: false,
598
+ schema: { type: "string" }
599
+ },
600
+ {
601
+ name: "user",
602
+ description: "positions only: wallet address.",
603
+ required: false,
604
+ schema: { type: "string" }
605
+ },
606
+ {
607
+ name: "side",
608
+ description: "place_order only: intended side, buy or sell.",
609
+ required: false,
610
+ schema: { type: "string", enum: ["buy", "sell"] }
611
+ },
612
+ {
613
+ name: "marketId",
614
+ description: "place_order only: Polymarket market id or condition id.",
615
+ required: false,
616
+ schema: { type: "string" }
617
+ },
618
+ {
619
+ name: "amount",
620
+ description: "place_order only: intended order amount.",
621
+ required: false,
622
+ schema: { type: "number" }
623
+ }
624
+ ],
625
+ validate: async (_runtime, message, state) => hasSelectedContext(state) || hasKeywordIntent(message, state, POLYMARKET_READ_KEYWORDS) || hasKeywordIntent(message, state, POLYMARKET_TRADE_KEYWORDS),
626
+ handler: async (runtime, _message, _state, options, callback) => {
627
+ const op = readOp(options);
628
+ if (!op) {
629
+ const text = "Provide action: read | place_order. For read, also provide kind: status | markets | market | orderbook | positions.";
630
+ return emitFailure(callback, text, "missing_or_invalid_op", {
631
+ actionName: POLYMARKET_ACTION_NAME,
632
+ availableActions: [...POLYMARKET_OPS]
633
+ });
634
+ }
635
+ const service = runtime.getService(
636
+ PREDICTION_MARKET_SERVICE_TYPE
637
+ );
638
+ if (!service || typeof service.route !== "function") {
639
+ const text = "Prediction market service is not available.";
640
+ return emitFailure(callback, text, "service_unavailable", {
641
+ actionName: POLYMARKET_ACTION_NAME
642
+ });
643
+ }
644
+ return service.route({
645
+ target: readTarget(options),
646
+ op,
647
+ options,
648
+ callback
649
+ });
650
+ }
651
+ };
652
+ const predictionMarketAction = polymarketAction;
653
+ const polymarketActions = [predictionMarketAction];
654
+ export {
655
+ PREDICTION_MARKET_SERVICE_TYPE,
656
+ PredictionMarketService,
657
+ polymarketAction,
658
+ polymarketActions,
659
+ predictionMarketAction
660
+ };
661
+ //# sourceMappingURL=actions.js.map