polymarket-trader-mcp 1.0.1
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/.env.example +20 -0
- package/README.md +158 -0
- package/dist/db/queries.d.ts +93 -0
- package/dist/db/queries.d.ts.map +1 -0
- package/dist/db/queries.js +161 -0
- package/dist/db/queries.js.map +1 -0
- package/dist/db/schema.d.ts +3 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +88 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +124 -0
- package/dist/index.js.map +1 -0
- package/dist/services/backtester.d.ts +30 -0
- package/dist/services/backtester.d.ts.map +1 -0
- package/dist/services/backtester.js +96 -0
- package/dist/services/backtester.js.map +1 -0
- package/dist/services/budget-manager.d.ts +16 -0
- package/dist/services/budget-manager.d.ts.map +1 -0
- package/dist/services/budget-manager.js +42 -0
- package/dist/services/budget-manager.js.map +1 -0
- package/dist/services/conviction-scorer.d.ts +14 -0
- package/dist/services/conviction-scorer.d.ts.map +1 -0
- package/dist/services/conviction-scorer.js +88 -0
- package/dist/services/conviction-scorer.js.map +1 -0
- package/dist/services/leaderboard.d.ts +28 -0
- package/dist/services/leaderboard.d.ts.map +1 -0
- package/dist/services/leaderboard.js +45 -0
- package/dist/services/leaderboard.js.map +1 -0
- package/dist/services/market-filter.d.ts +19 -0
- package/dist/services/market-filter.d.ts.map +1 -0
- package/dist/services/market-filter.js +50 -0
- package/dist/services/market-filter.js.map +1 -0
- package/dist/services/market-resolver.d.ts +10 -0
- package/dist/services/market-resolver.d.ts.map +1 -0
- package/dist/services/market-resolver.js +28 -0
- package/dist/services/market-resolver.js.map +1 -0
- package/dist/services/position-tracker.d.ts +13 -0
- package/dist/services/position-tracker.d.ts.map +1 -0
- package/dist/services/position-tracker.js +152 -0
- package/dist/services/position-tracker.js.map +1 -0
- package/dist/services/price-history.d.ts +18 -0
- package/dist/services/price-history.d.ts.map +1 -0
- package/dist/services/price-history.js +46 -0
- package/dist/services/price-history.js.map +1 -0
- package/dist/services/price-service.d.ts +14 -0
- package/dist/services/price-service.d.ts.map +1 -0
- package/dist/services/price-service.js +62 -0
- package/dist/services/price-service.js.map +1 -0
- package/dist/services/smart-flow.d.ts +22 -0
- package/dist/services/smart-flow.d.ts.map +1 -0
- package/dist/services/smart-flow.js +91 -0
- package/dist/services/smart-flow.js.map +1 -0
- package/dist/services/trade-executor.d.ts +44 -0
- package/dist/services/trade-executor.d.ts.map +1 -0
- package/dist/services/trade-executor.js +153 -0
- package/dist/services/trade-executor.js.map +1 -0
- package/dist/services/trader-analyzer.d.ts +19 -0
- package/dist/services/trader-analyzer.d.ts.map +1 -0
- package/dist/services/trader-analyzer.js +100 -0
- package/dist/services/trader-analyzer.js.map +1 -0
- package/dist/services/wallet-monitor.d.ts +51 -0
- package/dist/services/wallet-monitor.d.ts.map +1 -0
- package/dist/services/wallet-monitor.js +192 -0
- package/dist/services/wallet-monitor.js.map +1 -0
- package/dist/services/wta-discovery.d.ts +29 -0
- package/dist/services/wta-discovery.d.ts.map +1 -0
- package/dist/services/wta-discovery.js +155 -0
- package/dist/services/wta-discovery.js.map +1 -0
- package/dist/tools/analyze-trader.d.ts +6 -0
- package/dist/tools/analyze-trader.d.ts.map +1 -0
- package/dist/tools/analyze-trader.js +28 -0
- package/dist/tools/analyze-trader.js.map +1 -0
- package/dist/tools/backtest-trader.d.ts +7 -0
- package/dist/tools/backtest-trader.d.ts.map +1 -0
- package/dist/tools/backtest-trader.js +39 -0
- package/dist/tools/backtest-trader.js.map +1 -0
- package/dist/tools/buy.d.ts +14 -0
- package/dist/tools/buy.d.ts.map +1 -0
- package/dist/tools/buy.js +48 -0
- package/dist/tools/buy.js.map +1 -0
- package/dist/tools/cancel-orders.d.ts +5 -0
- package/dist/tools/cancel-orders.d.ts.map +1 -0
- package/dist/tools/cancel-orders.js +26 -0
- package/dist/tools/cancel-orders.js.map +1 -0
- package/dist/tools/check-exits.d.ts +3 -0
- package/dist/tools/check-exits.d.ts.map +1 -0
- package/dist/tools/check-exits.js +14 -0
- package/dist/tools/check-exits.js.map +1 -0
- package/dist/tools/check-market.d.ts +8 -0
- package/dist/tools/check-market.d.ts.map +1 -0
- package/dist/tools/check-market.js +31 -0
- package/dist/tools/check-market.js.map +1 -0
- package/dist/tools/close-position.d.ts +8 -0
- package/dist/tools/close-position.d.ts.map +1 -0
- package/dist/tools/close-position.js +26 -0
- package/dist/tools/close-position.js.map +1 -0
- package/dist/tools/discover-flow.d.ts +8 -0
- package/dist/tools/discover-flow.d.ts.map +1 -0
- package/dist/tools/discover-flow.js +36 -0
- package/dist/tools/discover-flow.js.map +1 -0
- package/dist/tools/discover-markets.d.ts +14 -0
- package/dist/tools/discover-markets.d.ts.map +1 -0
- package/dist/tools/discover-markets.js +67 -0
- package/dist/tools/discover-markets.js.map +1 -0
- package/dist/tools/discover-traders.d.ts +15 -0
- package/dist/tools/discover-traders.d.ts.map +1 -0
- package/dist/tools/discover-traders.js +64 -0
- package/dist/tools/discover-traders.js.map +1 -0
- package/dist/tools/discover-wta.d.ts +7 -0
- package/dist/tools/discover-wta.d.ts.map +1 -0
- package/dist/tools/discover-wta.js +26 -0
- package/dist/tools/discover-wta.js.map +1 -0
- package/dist/tools/get-balance.d.ts +4 -0
- package/dist/tools/get-balance.d.ts.map +1 -0
- package/dist/tools/get-balance.js +21 -0
- package/dist/tools/get-balance.js.map +1 -0
- package/dist/tools/get-dashboard.d.ts +5 -0
- package/dist/tools/get-dashboard.d.ts.map +1 -0
- package/dist/tools/get-dashboard.js +57 -0
- package/dist/tools/get-dashboard.js.map +1 -0
- package/dist/tools/get-portfolio.d.ts +3 -0
- package/dist/tools/get-portfolio.d.ts.map +1 -0
- package/dist/tools/get-portfolio.js +45 -0
- package/dist/tools/get-portfolio.js.map +1 -0
- package/dist/tools/get-positions.d.ts +11 -0
- package/dist/tools/get-positions.d.ts.map +1 -0
- package/dist/tools/get-positions.js +34 -0
- package/dist/tools/get-positions.js.map +1 -0
- package/dist/tools/get-price-history.d.ts +13 -0
- package/dist/tools/get-price-history.d.ts.map +1 -0
- package/dist/tools/get-price-history.js +55 -0
- package/dist/tools/get-price-history.js.map +1 -0
- package/dist/tools/get-price.d.ts +8 -0
- package/dist/tools/get-price.d.ts.map +1 -0
- package/dist/tools/get-price.js +37 -0
- package/dist/tools/get-price.js.map +1 -0
- package/dist/tools/get-trade-history.d.ts +10 -0
- package/dist/tools/get-trade-history.d.ts.map +1 -0
- package/dist/tools/get-trade-history.js +32 -0
- package/dist/tools/get-trade-history.js.map +1 -0
- package/dist/tools/get-trader-positions.d.ts +7 -0
- package/dist/tools/get-trader-positions.d.ts.map +1 -0
- package/dist/tools/get-trader-positions.js +27 -0
- package/dist/tools/get-trader-positions.js.map +1 -0
- package/dist/tools/go-live.d.ts +8 -0
- package/dist/tools/go-live.d.ts.map +1 -0
- package/dist/tools/go-live.js +22 -0
- package/dist/tools/go-live.js.map +1 -0
- package/dist/tools/list-watchlist.d.ts +3 -0
- package/dist/tools/list-watchlist.d.ts.map +1 -0
- package/dist/tools/list-watchlist.js +16 -0
- package/dist/tools/list-watchlist.js.map +1 -0
- package/dist/tools/log-cycle.d.ts +24 -0
- package/dist/tools/log-cycle.d.ts.map +1 -0
- package/dist/tools/log-cycle.js +23 -0
- package/dist/tools/log-cycle.js.map +1 -0
- package/dist/tools/place-stink-bid.d.ts +10 -0
- package/dist/tools/place-stink-bid.d.ts.map +1 -0
- package/dist/tools/place-stink-bid.js +53 -0
- package/dist/tools/place-stink-bid.js.map +1 -0
- package/dist/tools/rebalance.d.ts +9 -0
- package/dist/tools/rebalance.d.ts.map +1 -0
- package/dist/tools/rebalance.js +79 -0
- package/dist/tools/rebalance.js.map +1 -0
- package/dist/tools/score-trader.d.ts +6 -0
- package/dist/tools/score-trader.d.ts.map +1 -0
- package/dist/tools/score-trader.js +28 -0
- package/dist/tools/score-trader.js.map +1 -0
- package/dist/tools/search-markets.d.ts +8 -0
- package/dist/tools/search-markets.d.ts.map +1 -0
- package/dist/tools/search-markets.js +44 -0
- package/dist/tools/search-markets.js.map +1 -0
- package/dist/tools/sell.d.ts +10 -0
- package/dist/tools/sell.d.ts.map +1 -0
- package/dist/tools/sell.js +46 -0
- package/dist/tools/sell.js.map +1 -0
- package/dist/tools/set-config.d.ts +13 -0
- package/dist/tools/set-config.d.ts.map +1 -0
- package/dist/tools/set-config.js +24 -0
- package/dist/tools/set-config.js.map +1 -0
- package/dist/tools/set-exit-rules.d.ts +9 -0
- package/dist/tools/set-exit-rules.d.ts.map +1 -0
- package/dist/tools/set-exit-rules.js +39 -0
- package/dist/tools/set-exit-rules.js.map +1 -0
- package/dist/tools/start-monitor.d.ts +9 -0
- package/dist/tools/start-monitor.d.ts.map +1 -0
- package/dist/tools/start-monitor.js +24 -0
- package/dist/tools/start-monitor.js.map +1 -0
- package/dist/tools/stop-monitor.d.ts +3 -0
- package/dist/tools/stop-monitor.d.ts.map +1 -0
- package/dist/tools/stop-monitor.js +14 -0
- package/dist/tools/stop-monitor.js.map +1 -0
- package/dist/tools/watch-market.d.ts +15 -0
- package/dist/tools/watch-market.d.ts.map +1 -0
- package/dist/tools/watch-market.js +68 -0
- package/dist/tools/watch-market.js.map +1 -0
- package/dist/tools/watch-wallet.d.ts +13 -0
- package/dist/tools/watch-wallet.d.ts.map +1 -0
- package/dist/tools/watch-wallet.js +30 -0
- package/dist/tools/watch-wallet.js.map +1 -0
- package/dist/utils/config.d.ts +22 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +40 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/fetch.d.ts +5 -0
- package/dist/utils/fetch.d.ts.map +1 -0
- package/dist/utils/fetch.js +57 -0
- package/dist/utils/fetch.js.map +1 -0
- package/dist/utils/license.d.ts +4 -0
- package/dist/utils/license.d.ts.map +1 -0
- package/dist/utils/license.js +49 -0
- package/dist/utils/license.js.map +1 -0
- package/dist/utils/logger.d.ts +10 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +23 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/tool-wrapper.d.ts +10 -0
- package/dist/utils/tool-wrapper.d.ts.map +1 -0
- package/dist/utils/tool-wrapper.js +15 -0
- package/dist/utils/tool-wrapper.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { setConfig as setDbConfig } from "../db/queries.js";
|
|
3
|
+
import { checkLicense, requirePro } from "../utils/license.js";
|
|
4
|
+
export const setConfigSchema = z.object({
|
|
5
|
+
key: z.enum(["daily_budget", "min_conviction"]),
|
|
6
|
+
value: z.string(),
|
|
7
|
+
});
|
|
8
|
+
export async function handleSetConfig(db, budgetManager, input) {
|
|
9
|
+
const isPro = await checkLicense();
|
|
10
|
+
if (!isPro) {
|
|
11
|
+
return requirePro("set_config");
|
|
12
|
+
}
|
|
13
|
+
setDbConfig(db, input.key, input.value);
|
|
14
|
+
if (input.key === "daily_budget") {
|
|
15
|
+
const newLimit = parseFloat(input.value);
|
|
16
|
+
if (isNaN(newLimit) || newLimit <= 0) {
|
|
17
|
+
return "Invalid budget value. Must be a positive number.";
|
|
18
|
+
}
|
|
19
|
+
budgetManager.setDailyLimit(newLimit);
|
|
20
|
+
return `Daily budget updated to $${newLimit}.`;
|
|
21
|
+
}
|
|
22
|
+
return `Config updated: ${input.key} = ${input.value}`;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=set-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set-config.js","sourceRoot":"","sources":["../../src/tools/set-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,SAAS,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;IAC/C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CAClB,CAAC,CAAC;AAIH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAqB,EAAE,aAA4B,EAAE,KAAqB;IAC9G,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;IACnC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,UAAU,CAAC,YAAY,CAAC,CAAC;IAClC,CAAC;IAED,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IAExC,IAAI,KAAK,CAAC,GAAG,KAAK,cAAc,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;YACrC,OAAO,kDAAkD,CAAC;QAC5D,CAAC;QACD,aAAa,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACtC,OAAO,4BAA4B,QAAQ,GAAG,CAAC;IACjD,CAAC;IAED,OAAO,mBAAmB,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import Database from "better-sqlite3";
|
|
3
|
+
export declare const setExitRulesSchema: z.ZodObject<{
|
|
4
|
+
trade_id: z.ZodNumber;
|
|
5
|
+
stop_loss: z.ZodOptional<z.ZodNumber>;
|
|
6
|
+
take_profit: z.ZodOptional<z.ZodNumber>;
|
|
7
|
+
}, z.core.$strip>;
|
|
8
|
+
export declare function handleSetExitRules(db: Database.Database, input: z.infer<typeof setExitRulesSchema>): Promise<string>;
|
|
9
|
+
//# sourceMappingURL=set-exit-rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set-exit-rules.d.ts","sourceRoot":"","sources":["../../src/tools/set-exit-rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAItC,eAAO,MAAM,kBAAkB;;;;iBAI7B,CAAC;AAEH,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CA+B1H"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { setExitRules } from "../db/queries.js";
|
|
3
|
+
import { checkLicense, requirePro } from "../utils/license.js";
|
|
4
|
+
export const setExitRulesSchema = z.object({
|
|
5
|
+
trade_id: z.number().int(),
|
|
6
|
+
stop_loss: z.number().min(0).max(1).optional().describe("Price at which to sell (stop-loss). E.g. 0.30 means sell if price drops to $0.30"),
|
|
7
|
+
take_profit: z.number().min(0).max(1).optional().describe("Price at which to sell (take-profit). E.g. 0.85 means sell if price rises to $0.85"),
|
|
8
|
+
});
|
|
9
|
+
export async function handleSetExitRules(db, input) {
|
|
10
|
+
const isPro = await checkLicense();
|
|
11
|
+
if (!isPro)
|
|
12
|
+
return requirePro("set_exit_rules");
|
|
13
|
+
if (!input.stop_loss && !input.take_profit) {
|
|
14
|
+
return "Provide at least one of `stop_loss` or `take_profit`. Values are market prices between 0 and 1.";
|
|
15
|
+
}
|
|
16
|
+
const trade = db.prepare("SELECT * FROM trades WHERE id = ? AND status IN ('simulated', 'executed')").get(input.trade_id);
|
|
17
|
+
if (!trade) {
|
|
18
|
+
return `No open position found with ID ${input.trade_id}. Use \`get_positions\` to see your open positions.`;
|
|
19
|
+
}
|
|
20
|
+
// Validate SL is below entry, TP is above entry
|
|
21
|
+
if (input.stop_loss && input.stop_loss >= trade.price) {
|
|
22
|
+
return `Stop-loss ($${input.stop_loss}) must be below entry price ($${trade.price.toFixed(2)}).`;
|
|
23
|
+
}
|
|
24
|
+
if (input.take_profit && input.take_profit <= trade.price) {
|
|
25
|
+
return `Take-profit ($${input.take_profit}) must be above entry price ($${trade.price.toFixed(2)}).`;
|
|
26
|
+
}
|
|
27
|
+
const updated = setExitRules(db, input.trade_id, input.stop_loss ?? null, input.take_profit ?? null);
|
|
28
|
+
if (!updated)
|
|
29
|
+
return "Failed to set exit rules. Position may have been closed.";
|
|
30
|
+
const parts = [];
|
|
31
|
+
if (input.stop_loss)
|
|
32
|
+
parts.push(`SL: $${input.stop_loss}`);
|
|
33
|
+
if (input.take_profit)
|
|
34
|
+
parts.push(`TP: $${input.take_profit}`);
|
|
35
|
+
return `Exit rules set for position #${input.trade_id} (${trade.market_slug}):\n` +
|
|
36
|
+
`Entry: $${trade.price.toFixed(2)} | ${parts.join(" | ")}\n` +
|
|
37
|
+
`Rules will be checked automatically on each monitor tick.`;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=set-exit-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set-exit-rules.js","sourceRoot":"","sources":["../../src/tools/set-exit-rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAC1B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kFAAkF,CAAC;IAC3I,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oFAAoF,CAAC;CAChJ,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAqB,EAAE,KAAyC;IACvG,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;IACnC,IAAI,CAAC,KAAK;QAAE,OAAO,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAEhD,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;QAC3C,OAAO,iGAAiG,CAAC;IAC3G,CAAC;IAED,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,2EAA2E,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAQ,CAAC;IACjI,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,kCAAkC,KAAK,CAAC,QAAQ,qDAAqD,CAAC;IAC/G,CAAC;IAED,gDAAgD;IAChD,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QACtD,OAAO,eAAe,KAAK,CAAC,SAAS,iCAAiC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACnG,CAAC;IACD,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC1D,OAAO,iBAAiB,KAAK,CAAC,WAAW,iCAAiC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACvG,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI,EAAE,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC;IACrG,IAAI,CAAC,OAAO;QAAE,OAAO,0DAA0D,CAAC;IAEhF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,KAAK,CAAC,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;IAC3D,IAAI,KAAK,CAAC,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IAE/D,OAAO,gCAAgC,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,WAAW,MAAM;QAC/E,WAAW,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI;QAC5D,2DAA2D,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import Database from "better-sqlite3";
|
|
3
|
+
import { WalletMonitor } from "../services/wallet-monitor.js";
|
|
4
|
+
export declare const startMonitorSchema: z.ZodObject<{
|
|
5
|
+
interval_seconds: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
export type StartMonitorInput = z.infer<typeof startMonitorSchema>;
|
|
8
|
+
export declare function handleStartMonitor(db: Database.Database, monitor: WalletMonitor, input: StartMonitorInput): Promise<string>;
|
|
9
|
+
//# sourceMappingURL=start-monitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-monitor.d.ts","sourceRoot":"","sources":["../../src/tools/start-monitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAI9D,eAAO,MAAM,kBAAkB;;iBAE7B,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEnE,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBjI"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getWatchlistCount } from "../db/queries.js";
|
|
3
|
+
import { checkLicense, requirePro } from "../utils/license.js";
|
|
4
|
+
export const startMonitorSchema = z.object({
|
|
5
|
+
interval_seconds: z.number().int().min(10).max(300).optional().default(30),
|
|
6
|
+
});
|
|
7
|
+
export async function handleStartMonitor(db, monitor, input) {
|
|
8
|
+
const isPro = await checkLicense();
|
|
9
|
+
if (!isPro) {
|
|
10
|
+
return requirePro("start_monitor");
|
|
11
|
+
}
|
|
12
|
+
const status = monitor.getStatus();
|
|
13
|
+
if (status.running) {
|
|
14
|
+
return "Monitor is already running.";
|
|
15
|
+
}
|
|
16
|
+
const walletCount = getWatchlistCount(db);
|
|
17
|
+
monitor.start(input.interval_seconds * 1000);
|
|
18
|
+
let msg = `Monitor started. Checking wallets every ${input.interval_seconds} seconds.`;
|
|
19
|
+
if (walletCount === 0) {
|
|
20
|
+
msg += "\n\n**Note:** Your watchlist is empty. Use `watch_wallet` to add traders or `discover_traders` to find top performers.";
|
|
21
|
+
}
|
|
22
|
+
return msg;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=start-monitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-monitor.js","sourceRoot":"","sources":["../../src/tools/start-monitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;CAC3E,CAAC,CAAC;AAIH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAqB,EAAE,OAAsB,EAAE,KAAwB;IAC9G,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;IACnC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,UAAU,CAAC,eAAe,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IACnC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,6BAA6B,CAAC;IACvC,CAAC;IAED,MAAM,WAAW,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAE7C,IAAI,GAAG,GAAG,2CAA2C,KAAK,CAAC,gBAAgB,WAAW,CAAC;IACvF,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;QACtB,GAAG,IAAI,wHAAwH,CAAC;IAClI,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop-monitor.d.ts","sourceRoot":"","sources":["../../src/tools/stop-monitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAG9D,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAY/E"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { checkLicense, requirePro } from "../utils/license.js";
|
|
2
|
+
export async function handleStopMonitor(monitor) {
|
|
3
|
+
const isPro = await checkLicense();
|
|
4
|
+
if (!isPro) {
|
|
5
|
+
return requirePro("stop_monitor");
|
|
6
|
+
}
|
|
7
|
+
const status = monitor.getStatus();
|
|
8
|
+
if (!status.running) {
|
|
9
|
+
return "Monitor is not running.";
|
|
10
|
+
}
|
|
11
|
+
monitor.stop();
|
|
12
|
+
return "Monitor stopped.";
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=stop-monitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop-monitor.js","sourceRoot":"","sources":["../../src/tools/stop-monitor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAsB;IAC5D,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;IACnC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,UAAU,CAAC,cAAc,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,yBAAyB,CAAC;IACnC,CAAC;IACD,OAAO,CAAC,IAAI,EAAE,CAAC;IACf,OAAO,kBAAkB,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import Database from "better-sqlite3";
|
|
3
|
+
export declare const watchMarketSchema: z.ZodObject<{
|
|
4
|
+
action: z.ZodDefault<z.ZodEnum<{
|
|
5
|
+
add: "add";
|
|
6
|
+
remove: "remove";
|
|
7
|
+
list: "list";
|
|
8
|
+
}>>;
|
|
9
|
+
condition_id: z.ZodOptional<z.ZodString>;
|
|
10
|
+
title: z.ZodOptional<z.ZodString>;
|
|
11
|
+
alert_below: z.ZodOptional<z.ZodNumber>;
|
|
12
|
+
alert_above: z.ZodOptional<z.ZodNumber>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
export declare function handleWatchMarket(db: Database.Database, input: z.infer<typeof watchMarketSchema>): Promise<string>;
|
|
15
|
+
//# sourceMappingURL=watch-market.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch-market.d.ts","sourceRoot":"","sources":["../../src/tools/watch-market.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAKtC,eAAO,MAAM,iBAAiB;;;;;;;;;;iBAM5B,CAAC;AAEH,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAoCxH"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { addMarketWatch, removeMarketWatch, getMarketWatchlist } from "../db/queries.js";
|
|
3
|
+
import { getMarketPriceByCondition } from "../services/price-service.js";
|
|
4
|
+
import { checkLicense, requirePro } from "../utils/license.js";
|
|
5
|
+
export const watchMarketSchema = z.object({
|
|
6
|
+
action: z.enum(["add", "remove", "list"]).default("list"),
|
|
7
|
+
condition_id: z.string().optional(),
|
|
8
|
+
title: z.string().optional(),
|
|
9
|
+
alert_below: z.number().min(0).max(1).optional().describe("Alert when price drops below this level"),
|
|
10
|
+
alert_above: z.number().min(0).max(1).optional().describe("Alert when price rises above this level"),
|
|
11
|
+
});
|
|
12
|
+
export async function handleWatchMarket(db, input) {
|
|
13
|
+
const isPro = await checkLicense();
|
|
14
|
+
if (!isPro)
|
|
15
|
+
return requirePro("watch_market");
|
|
16
|
+
if (input.action === "list") {
|
|
17
|
+
return renderWatchlist(db);
|
|
18
|
+
}
|
|
19
|
+
if (!input.condition_id) {
|
|
20
|
+
return "Please provide a `condition_id` to add or remove a market.";
|
|
21
|
+
}
|
|
22
|
+
if (input.action === "remove") {
|
|
23
|
+
removeMarketWatch(db, input.condition_id);
|
|
24
|
+
return `Removed market ${input.condition_id.slice(0, 12)}... from watchlist.`;
|
|
25
|
+
}
|
|
26
|
+
// Add — fetch current price
|
|
27
|
+
const priceInfo = await getMarketPriceByCondition(input.condition_id);
|
|
28
|
+
const currentPrice = priceInfo?.price ?? 0;
|
|
29
|
+
addMarketWatch(db, {
|
|
30
|
+
condition_id: input.condition_id,
|
|
31
|
+
token_id: priceInfo?.tokenId ?? null,
|
|
32
|
+
title: input.title ?? null,
|
|
33
|
+
slug: null,
|
|
34
|
+
alert_below: input.alert_below ?? null,
|
|
35
|
+
alert_above: input.alert_above ?? null,
|
|
36
|
+
last_price: currentPrice,
|
|
37
|
+
});
|
|
38
|
+
let msg = `Market added to watchlist: ${input.title ?? input.condition_id.slice(0, 12)}...\nCurrent price: $${currentPrice.toFixed(4)}`;
|
|
39
|
+
if (input.alert_below)
|
|
40
|
+
msg += `\nAlert below: $${input.alert_below}`;
|
|
41
|
+
if (input.alert_above)
|
|
42
|
+
msg += `\nAlert above: $${input.alert_above}`;
|
|
43
|
+
return msg;
|
|
44
|
+
}
|
|
45
|
+
async function renderWatchlist(db) {
|
|
46
|
+
const markets = getMarketWatchlist(db);
|
|
47
|
+
if (markets.length === 0) {
|
|
48
|
+
return "Market watchlist is empty. Use `watch_market` with action `add` and a `condition_id` to start watching.";
|
|
49
|
+
}
|
|
50
|
+
// Fetch current prices
|
|
51
|
+
let output = "## Market Watchlist\n\n";
|
|
52
|
+
output += "| # | Market | Last Price | Alert Below | Alert Above | Status |\n";
|
|
53
|
+
output += "|---|--------|------------|-------------|-------------|--------|\n";
|
|
54
|
+
for (let i = 0; i < markets.length; i++) {
|
|
55
|
+
const m = markets[i];
|
|
56
|
+
const priceInfo = await getMarketPriceByCondition(m.condition_id);
|
|
57
|
+
const current = priceInfo?.price ?? m.last_price ?? 0;
|
|
58
|
+
let status = "OK";
|
|
59
|
+
if (m.alert_below && current <= m.alert_below)
|
|
60
|
+
status = "BELOW ALERT";
|
|
61
|
+
if (m.alert_above && current >= m.alert_above)
|
|
62
|
+
status = "ABOVE ALERT";
|
|
63
|
+
const name = (m.title ?? m.condition_id.slice(0, 16) + "...").slice(0, 30);
|
|
64
|
+
output += `| ${i + 1} | ${name} | $${current.toFixed(4)} | ${m.alert_below ? "$" + m.alert_below : "-"} | ${m.alert_above ? "$" + m.alert_above : "-"} | ${status} |\n`;
|
|
65
|
+
}
|
|
66
|
+
return output;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=watch-market.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch-market.js","sourceRoot":"","sources":["../../src/tools/watch-market.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import Database from "better-sqlite3";
|
|
3
|
+
export declare const watchWalletSchema: z.ZodObject<{
|
|
4
|
+
address: z.ZodString;
|
|
5
|
+
alias: z.ZodOptional<z.ZodString>;
|
|
6
|
+
action: z.ZodDefault<z.ZodEnum<{
|
|
7
|
+
add: "add";
|
|
8
|
+
remove: "remove";
|
|
9
|
+
}>>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export type WatchWalletInput = z.infer<typeof watchWalletSchema>;
|
|
12
|
+
export declare function handleWatchWallet(db: Database.Database, input: WatchWalletInput): Promise<string>;
|
|
13
|
+
//# sourceMappingURL=watch-wallet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch-wallet.d.ts","sourceRoot":"","sources":["../../src/tools/watch-wallet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAItC,eAAO,MAAM,iBAAiB;;;;;;;iBAI5B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEjE,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBvG"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { addToWatchlist, removeFromWatchlist, getWatchlistCount } from "../db/queries.js";
|
|
3
|
+
import { checkLicense, requirePro } from "../utils/license.js";
|
|
4
|
+
export const watchWalletSchema = z.object({
|
|
5
|
+
address: z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid Ethereum address"),
|
|
6
|
+
alias: z.string().optional(),
|
|
7
|
+
action: z.enum(["add", "remove"]).default("add"),
|
|
8
|
+
});
|
|
9
|
+
export async function handleWatchWallet(db, input) {
|
|
10
|
+
if (input.action === "remove") {
|
|
11
|
+
removeFromWatchlist(db, input.address);
|
|
12
|
+
return `Removed ${input.address} from watchlist.`;
|
|
13
|
+
}
|
|
14
|
+
const isPro = await checkLicense();
|
|
15
|
+
const currentCount = getWatchlistCount(db);
|
|
16
|
+
if (!isPro && currentCount >= 3) {
|
|
17
|
+
return `Free tier is limited to 3 wallets. You have ${currentCount}. ${requirePro("watch_wallet")}`;
|
|
18
|
+
}
|
|
19
|
+
addToWatchlist(db, {
|
|
20
|
+
address: input.address,
|
|
21
|
+
alias: input.alias ?? null,
|
|
22
|
+
roi: 0,
|
|
23
|
+
volume: 0,
|
|
24
|
+
pnl: 0,
|
|
25
|
+
trade_count: 0,
|
|
26
|
+
});
|
|
27
|
+
const limitInfo = isPro ? "" : ` (${currentCount + 1}/3 free slots used)`;
|
|
28
|
+
return `Added ${input.alias ?? input.address} to watchlist.${limitInfo}`;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=watch-wallet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch-wallet.js","sourceRoot":"","sources":["../../src/tools/watch-wallet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,qBAAqB,EAAE,0BAA0B,CAAC;IAC5E,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;CACjD,CAAC,CAAC;AAIH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,EAAqB,EAAE,KAAuB;IACpF,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC9B,mBAAmB,CAAC,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO,WAAW,KAAK,CAAC,OAAO,kBAAkB,CAAC;IACpD,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;IACnC,MAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAE3C,IAAI,CAAC,KAAK,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QAChC,OAAO,+CAA+C,YAAY,KAAK,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;IACtG,CAAC;IAED,cAAc,CAAC,EAAE,EAAE;QACjB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI;QAC1B,GAAG,EAAE,CAAC;QACN,MAAM,EAAE,CAAC;QACT,GAAG,EAAE,CAAC;QACN,WAAW,EAAE,CAAC;KACf,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,YAAY,GAAG,CAAC,qBAAqB,CAAC;IAC1E,OAAO,SAAS,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,iBAAiB,SAAS,EAAE,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
declare const configSchema: z.ZodObject<{
|
|
3
|
+
POLY_PRIVATE_KEY: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
4
|
+
POLY_API_KEY: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
5
|
+
POLY_API_SECRET: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
6
|
+
POLY_API_PASSPHRASE: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
7
|
+
POLY_FUNDER_ADDRESS: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
8
|
+
DAILY_BUDGET: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
9
|
+
MIN_CONVICTION: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
10
|
+
COPY_MODE: z.ZodDefault<z.ZodEnum<{
|
|
11
|
+
preview: "preview";
|
|
12
|
+
live: "live";
|
|
13
|
+
}>>;
|
|
14
|
+
CHAIN_ID: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
15
|
+
MCP_LICENSE_KEY: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
export type Config = z.infer<typeof configSchema>;
|
|
18
|
+
export declare function getConfig(): Config;
|
|
19
|
+
export declare function hasLiveCredentials(): boolean;
|
|
20
|
+
export declare function validateLiveCredentials(): string[];
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;iBAWhB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAIlD,wBAAgB,SAAS,IAAI,MAAM,CAKlC;AAED,wBAAgB,kBAAkB,IAAI,OAAO,CAG5C;AAED,wBAAgB,uBAAuB,IAAI,MAAM,EAAE,CAQlD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import dotenv from "dotenv";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
dotenv.config();
|
|
4
|
+
const configSchema = z.object({
|
|
5
|
+
POLY_PRIVATE_KEY: z.string().optional().default(""),
|
|
6
|
+
POLY_API_KEY: z.string().optional().default(""),
|
|
7
|
+
POLY_API_SECRET: z.string().optional().default(""),
|
|
8
|
+
POLY_API_PASSPHRASE: z.string().optional().default(""),
|
|
9
|
+
POLY_FUNDER_ADDRESS: z.string().optional().default(""),
|
|
10
|
+
DAILY_BUDGET: z.coerce.number().positive().default(20),
|
|
11
|
+
MIN_CONVICTION: z.coerce.number().positive().default(3),
|
|
12
|
+
COPY_MODE: z.enum(["preview", "live"]).default("preview"),
|
|
13
|
+
CHAIN_ID: z.coerce.number().int().positive().default(137),
|
|
14
|
+
MCP_LICENSE_KEY: z.string().optional().default(""),
|
|
15
|
+
});
|
|
16
|
+
let _config = null;
|
|
17
|
+
export function getConfig() {
|
|
18
|
+
if (!_config) {
|
|
19
|
+
_config = configSchema.parse(process.env);
|
|
20
|
+
}
|
|
21
|
+
return _config;
|
|
22
|
+
}
|
|
23
|
+
export function hasLiveCredentials() {
|
|
24
|
+
const c = getConfig();
|
|
25
|
+
return !!(c.POLY_PRIVATE_KEY && c.POLY_API_KEY && c.POLY_API_SECRET && c.POLY_API_PASSPHRASE);
|
|
26
|
+
}
|
|
27
|
+
export function validateLiveCredentials() {
|
|
28
|
+
const c = getConfig();
|
|
29
|
+
const missing = [];
|
|
30
|
+
if (!c.POLY_PRIVATE_KEY)
|
|
31
|
+
missing.push("POLY_PRIVATE_KEY");
|
|
32
|
+
if (!c.POLY_API_KEY)
|
|
33
|
+
missing.push("POLY_API_KEY");
|
|
34
|
+
if (!c.POLY_API_SECRET)
|
|
35
|
+
missing.push("POLY_API_SECRET");
|
|
36
|
+
if (!c.POLY_API_PASSPHRASE)
|
|
37
|
+
missing.push("POLY_API_PASSPHRASE");
|
|
38
|
+
return missing;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACnD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC/C,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAClD,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACtD,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACtD,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACtD,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACvD,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;IACzD,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;IACzD,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;CACnD,CAAC,CAAC;AAIH,IAAI,OAAO,GAAkB,IAAI,CAAC;AAElC,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;IACtB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,eAAe,IAAI,CAAC,CAAC,mBAAmB,CAAC,CAAC;AAChG,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;IACtB,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,CAAC,CAAC,gBAAgB;QAAE,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC1D,IAAI,CAAC,CAAC,CAAC,YAAY;QAAE,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAClD,IAAI,CAAC,CAAC,CAAC,eAAe;QAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACxD,IAAI,CAAC,CAAC,CAAC,mBAAmB;QAAE,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAChE,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/utils/fetch.ts"],"names":[],"mappings":"AAOA,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,WAAW,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/D,OAAO,CAAC,QAAQ,CAAC,CA+CnB"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { log } from "./logger.js";
|
|
2
|
+
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
3
|
+
const DEFAULT_RETRIES = 2;
|
|
4
|
+
const BASE_DELAY_MS = 1_000;
|
|
5
|
+
const MAX_DELAY_MS = 30_000;
|
|
6
|
+
export async function fetchWithRetry(url, options) {
|
|
7
|
+
const retries = options?.retries ?? DEFAULT_RETRIES;
|
|
8
|
+
const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
9
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
10
|
+
try {
|
|
11
|
+
const controller = new AbortController();
|
|
12
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
13
|
+
const response = await fetch(url, {
|
|
14
|
+
...options,
|
|
15
|
+
signal: controller.signal,
|
|
16
|
+
});
|
|
17
|
+
clearTimeout(timer);
|
|
18
|
+
// Handle rate limiting — retry with backoff
|
|
19
|
+
if (response.status === 429) {
|
|
20
|
+
const retryAfter = parseRetryAfter(response.headers.get("retry-after"));
|
|
21
|
+
const delay = retryAfter ?? Math.min(BASE_DELAY_MS * 2 ** attempt, MAX_DELAY_MS);
|
|
22
|
+
if (attempt < retries) {
|
|
23
|
+
log("warn", `Rate limited (429) on ${url}, retrying in ${delay}ms...`);
|
|
24
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
log("error", `Rate limited (429) on ${url} after ${retries + 1} attempts`);
|
|
28
|
+
return response;
|
|
29
|
+
}
|
|
30
|
+
return response;
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
const isLast = attempt === retries;
|
|
34
|
+
const reason = err?.name === "AbortError" ? "timeout" : err?.message ?? "unknown";
|
|
35
|
+
if (isLast) {
|
|
36
|
+
log("error", `Fetch failed after ${retries + 1} attempts: ${url} (${reason})`);
|
|
37
|
+
throw err;
|
|
38
|
+
}
|
|
39
|
+
log("warn", `Fetch attempt ${attempt + 1} failed: ${url} (${reason}), retrying...`);
|
|
40
|
+
await new Promise((r) => setTimeout(r, BASE_DELAY_MS * (attempt + 1)));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Unreachable, but TypeScript needs it
|
|
44
|
+
throw new Error("Fetch failed");
|
|
45
|
+
}
|
|
46
|
+
function parseRetryAfter(header) {
|
|
47
|
+
if (!header)
|
|
48
|
+
return null;
|
|
49
|
+
const seconds = parseInt(header, 10);
|
|
50
|
+
if (!isNaN(seconds))
|
|
51
|
+
return seconds * 1000;
|
|
52
|
+
const date = Date.parse(header);
|
|
53
|
+
if (!isNaN(date))
|
|
54
|
+
return Math.max(0, date - Date.now());
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/utils/fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license.d.ts","sourceRoot":"","sources":["../../src/utils/license.ts"],"names":[],"mappings":"AAKA,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAkCrD;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMnD;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { log } from "./logger.js";
|
|
2
|
+
import { fetchWithRetry } from "./fetch.js";
|
|
3
|
+
let _isLicensed = null;
|
|
4
|
+
export async function checkLicense() {
|
|
5
|
+
if (_isLicensed !== null)
|
|
6
|
+
return _isLicensed;
|
|
7
|
+
const key = process.env.MCP_LICENSE_KEY;
|
|
8
|
+
if (!key) {
|
|
9
|
+
_isLicensed = false;
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
const response = await fetchWithRetry("https://mcp-marketplace.io/api/v1/verify-license", {
|
|
14
|
+
method: "POST",
|
|
15
|
+
headers: { "Content-Type": "application/json" },
|
|
16
|
+
body: JSON.stringify({ key, slug: "polymarket-trader-mcp" }),
|
|
17
|
+
retries: 1,
|
|
18
|
+
timeoutMs: 5_000,
|
|
19
|
+
});
|
|
20
|
+
if (!response.ok) {
|
|
21
|
+
throw new Error(`License API returned ${response.status}`);
|
|
22
|
+
}
|
|
23
|
+
const data = await response.json();
|
|
24
|
+
_isLicensed = data.valid === true;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// API unreachable — deny license unless explicit offline override is set
|
|
28
|
+
if (process.env.MCP_LICENSE_OFFLINE === "true") {
|
|
29
|
+
_isLicensed = true;
|
|
30
|
+
log("warn", "License API unreachable, offline override enabled");
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
_isLicensed = false;
|
|
34
|
+
log("warn", "License API unreachable, license denied. Set MCP_LICENSE_OFFLINE=true for offline use.");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return _isLicensed;
|
|
38
|
+
}
|
|
39
|
+
export function requirePro(toolName) {
|
|
40
|
+
const key = process.env.MCP_LICENSE_KEY;
|
|
41
|
+
if (key) {
|
|
42
|
+
return `"${toolName}" requires a valid Pro license. Your current license key was not accepted.\n\nVerify your key at https://mcp-marketplace.io/server/polymarket-trader-mcp or check your internet connection (the license server may be unreachable).`;
|
|
43
|
+
}
|
|
44
|
+
return `"${toolName}" is a Pro feature. Get a license at https://mcp-marketplace.io/server/polymarket-trader-mcp\n\nSet MCP_LICENSE_KEY in your environment to unlock Pro features.`;
|
|
45
|
+
}
|
|
46
|
+
export function resetLicenseCache() {
|
|
47
|
+
_isLicensed = null;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=license.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license.js","sourceRoot":"","sources":["../../src/utils/license.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,IAAI,WAAW,GAAmB,IAAI,CAAC;AAEvC,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI,WAAW,KAAK,IAAI;QAAE,OAAO,WAAW,CAAC;IAE7C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACxC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,WAAW,GAAG,KAAK,CAAC;QACpB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,kDAAkD,EAAE;YACxF,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC;YAC5D,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,KAAK;SACjB,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,wBAAwB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,WAAW,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;QACzE,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,MAAM,EAAE,CAAC;YAC/C,WAAW,GAAG,IAAI,CAAC;YACnB,GAAG,CAAC,MAAM,EAAE,mDAAmD,CAAC,CAAC;QACnE,CAAC;aAAM,CAAC;YACN,WAAW,GAAG,KAAK,CAAC;YACpB,GAAG,CAAC,MAAM,EAAE,wFAAwF,CAAC,CAAC;QACxG,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACxC,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,IAAI,QAAQ,qOAAqO,CAAC;IAC3P,CAAC;IACD,OAAO,IAAI,QAAQ,iKAAiK,CAAC;AACvL,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type LogLevel = "info" | "warn" | "error" | "trade" | "monitor";
|
|
2
|
+
export interface LogEntry {
|
|
3
|
+
timestamp: string;
|
|
4
|
+
level: LogLevel;
|
|
5
|
+
message: string;
|
|
6
|
+
data?: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export declare function log(level: LogLevel, message: string, data?: Record<string, unknown>): void;
|
|
9
|
+
export declare function getRecentLogs(count?: number): LogEntry[];
|
|
10
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;AAEvE,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAKD,wBAAgB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAgB1F;AAED,wBAAgB,aAAa,CAAC,KAAK,SAAK,GAAG,QAAQ,EAAE,CAEpD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const logs = [];
|
|
2
|
+
const MAX_LOGS = 500;
|
|
3
|
+
export function log(level, message, data) {
|
|
4
|
+
const now = new Date();
|
|
5
|
+
const localIso = new Date(now.getTime() - now.getTimezoneOffset() * 60_000).toISOString();
|
|
6
|
+
const entry = {
|
|
7
|
+
timestamp: localIso,
|
|
8
|
+
level,
|
|
9
|
+
message,
|
|
10
|
+
data,
|
|
11
|
+
};
|
|
12
|
+
logs.push(entry);
|
|
13
|
+
if (logs.length > MAX_LOGS) {
|
|
14
|
+
logs.splice(0, logs.length - MAX_LOGS);
|
|
15
|
+
}
|
|
16
|
+
// MCP uses stdout for JSON-RPC — all logs MUST go to stderr
|
|
17
|
+
const prefix = `[${entry.timestamp}] [${level.toUpperCase()}]`;
|
|
18
|
+
process.stderr.write(`${prefix} ${message}${data ? " " + JSON.stringify(data) : ""}\n`);
|
|
19
|
+
}
|
|
20
|
+
export function getRecentLogs(count = 50) {
|
|
21
|
+
return logs.slice(-count);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AASA,MAAM,IAAI,GAAe,EAAE,CAAC;AAC5B,MAAM,QAAQ,GAAG,GAAG,CAAC;AAErB,MAAM,UAAU,GAAG,CAAC,KAAe,EAAE,OAAe,EAAE,IAA8B;IAClF,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,iBAAiB,EAAE,GAAG,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1F,MAAM,KAAK,GAAa;QACtB,SAAS,EAAE,QAAQ;QACnB,KAAK;QACL,OAAO;QACP,IAAI;KACL,CAAC;IACF,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjB,IAAI,IAAI,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;QAC3B,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC;IACzC,CAAC;IACD,4DAA4D;IAC5D,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,SAAS,MAAM,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC;IAC/D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAK,GAAG,EAAE;IACtC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type McpResult = {
|
|
2
|
+
content: {
|
|
3
|
+
type: "text";
|
|
4
|
+
text: string;
|
|
5
|
+
}[];
|
|
6
|
+
};
|
|
7
|
+
/** Wraps an MCP tool callback with try-catch, returning a user-friendly error on failure */
|
|
8
|
+
export declare function safe(toolName: string, handler: (...args: any[]) => McpResult | Promise<McpResult>): (...args: any[]) => Promise<McpResult>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=tool-wrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-wrapper.d.ts","sourceRoot":"","sources":["../../src/utils/tool-wrapper.ts"],"names":[],"mappings":"AAEA,KAAK,SAAS,GAAG;IAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAAC;AAE/D,4FAA4F;AAC5F,wBAAgB,IAAI,CAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,GAC1D,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,SAAS,CAAC,CAUxC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { log } from "./logger.js";
|
|
2
|
+
/** Wraps an MCP tool callback with try-catch, returning a user-friendly error on failure */
|
|
3
|
+
export function safe(toolName, handler) {
|
|
4
|
+
return async (...args) => {
|
|
5
|
+
try {
|
|
6
|
+
return await handler(...args);
|
|
7
|
+
}
|
|
8
|
+
catch (err) {
|
|
9
|
+
const message = err?.message ?? String(err);
|
|
10
|
+
log("error", `Tool "${toolName}" failed: ${message}`);
|
|
11
|
+
return { content: [{ type: "text", text: `An error occurred while running "${toolName}". Please try again or check the event log for details.` }] };
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=tool-wrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-wrapper.js","sourceRoot":"","sources":["../../src/utils/tool-wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAIlC,4FAA4F;AAC5F,MAAM,UAAU,IAAI,CAClB,QAAgB,EAChB,OAA2D;IAE3D,OAAO,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;QAC9B,IAAI,CAAC;YACH,OAAO,MAAM,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,MAAM,OAAO,GAAG,GAAG,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;YAC5C,GAAG,CAAC,OAAO,EAAE,SAAS,QAAQ,aAAa,OAAO,EAAE,CAAC,CAAC;YACtD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,oCAAoC,QAAQ,yDAAyD,EAAE,CAAC,EAAE,CAAC;QAC/J,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|