lpxpoly-mcp 1.0.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/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # lpxpoly-mcp
2
+
3
+ MCP server for [LPXPoly](https://lpxpoly.com) — AI-powered Polymarket prediction market analysis. Find mispriced markets, get edge opportunities, and analyze specific markets. Pay per analysis in Bitcoin sats via Lightning.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npx lpxpoly-mcp
9
+ ```
10
+
11
+ ## Setup
12
+
13
+ ### Get a Spend Token
14
+ 1. Go to [lightningprox.com](https://lightningprox.com)
15
+ 2. Pay a Lightning invoice to fund your balance
16
+ 3. Get your spend token
17
+ 4. ~50 sats per analysis
18
+
19
+ ### Claude Desktop
20
+
21
+ ```json
22
+ {
23
+ "mcpServers": {
24
+ "lpxpoly": {
25
+ "command": "npx",
26
+ "args": ["lpxpoly-mcp"],
27
+ "env": {
28
+ "LIGHTNINGPROX_SPEND_TOKEN": "your_token_here"
29
+ }
30
+ }
31
+ }
32
+ }
33
+ ```
34
+
35
+ **Config location:**
36
+ - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
37
+ - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
38
+ - Linux: `~/.config/claude/claude_desktop_config.json`
39
+
40
+ ## Tools
41
+
42
+ | Tool | Description |
43
+ |------|-------------|
44
+ | `get_edge_opportunities` | Find mispriced markets with AI edge |
45
+ | `analyze_market` | Deep analysis of a specific market |
46
+ | `get_top_markets` | Browse top markets by volume |
47
+ | `check_balance` | Check your Lightning balance |
48
+
49
+ ## Example Usage
50
+
51
+ ```
52
+ "Find edge opportunities on Polymarket"
53
+ → Returns top mispriced markets with AI probability vs market probability
54
+
55
+ "Analyze the Fed rate cut market"
56
+ → Returns AI assessment, reasoning, and recommended position
57
+
58
+ "What are the top crypto markets on Polymarket?"
59
+ → Returns top markets filtered by category
60
+ ```
61
+
62
+ ## Pricing
63
+
64
+ ~50 sats per analysis. Pay with Bitcoin Lightning. No subscription.
65
+
66
+ ## Part of the AIProx Ecosystem
67
+
68
+ LPXPoly is discoverable via the [AIProx](https://aiprox.dev) open agent registry:
69
+
70
+ ```bash
71
+ curl https://aiprox.dev/api/agents/lpxpoly
72
+ ```
73
+
74
+ - AIProx Registry: https://aiprox.dev
75
+ - LightningProx (Bitcoin Lightning AI): `npx lightningprox-mcp`
76
+ - SolanaProx (Solana USDC AI): `npx solanaprox-mcp`
77
+ - AIProx Registry: `npx aiprox-mcp`
78
+ - Autonomous agent demo: https://github.com/unixlamadev-spec/autonomous-agent-demo
79
+
80
+ Built by [LPX Digital Group LLC](https://lpxdigital.com)
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * LPXPoly MCP Server
4
+ * AI-powered Polymarket prediction market analysis
5
+ * Pay per analysis in Bitcoin sats via Lightning
6
+ */
7
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,240 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * LPXPoly MCP Server
5
+ * AI-powered Polymarket prediction market analysis
6
+ * Pay per analysis in Bitcoin sats via Lightning
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
10
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
11
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
12
+ const LPXPOLY_URL = process.env.LPXPOLY_URL || "https://lpxpoly.com";
13
+ const LIGHTNINGPROX_URL = process.env.LIGHTNINGPROX_URL || "https://lightningprox.com";
14
+ const SPEND_TOKEN = process.env.LIGHTNINGPROX_SPEND_TOKEN || "";
15
+ if (!SPEND_TOKEN) {
16
+ console.error("❌ LIGHTNINGPROX_SPEND_TOKEN environment variable is required");
17
+ console.error(" Get a spend token at lightningprox.com — pay with Bitcoin Lightning");
18
+ console.error(" Example: LIGHTNINGPROX_SPEND_TOKEN=your_token npx lpxpoly-mcp");
19
+ process.exit(1);
20
+ }
21
+ // ============================================================================
22
+ // TOOL DEFINITIONS
23
+ // ============================================================================
24
+ const tools = [
25
+ {
26
+ name: "get_edge_opportunities",
27
+ description: "Find mispriced Polymarket prediction markets where AI analysis disagrees with current market probability. Returns top edge opportunities with recommended positions.",
28
+ inputSchema: {
29
+ type: "object",
30
+ properties: {
31
+ min_edge: {
32
+ type: "number",
33
+ description: "Minimum edge percentage to include (default: 5)",
34
+ default: 5,
35
+ },
36
+ limit: {
37
+ type: "number",
38
+ description: "Maximum number of opportunities to return (default: 10)",
39
+ default: 10,
40
+ },
41
+ },
42
+ required: [],
43
+ },
44
+ },
45
+ {
46
+ name: "analyze_market",
47
+ description: "Get AI analysis of a specific Polymarket prediction market. Returns probability assessment, reasoning, and recommended position.",
48
+ inputSchema: {
49
+ type: "object",
50
+ properties: {
51
+ query: {
52
+ type: "string",
53
+ description: "Market question or search term (e.g. 'Fed rate cut March 2025', 'Trump approval rating')",
54
+ },
55
+ },
56
+ required: ["query"],
57
+ },
58
+ },
59
+ {
60
+ name: "check_balance",
61
+ description: "Check your LightningProx balance in sats. Required to pay for LPXPoly analyses.",
62
+ inputSchema: {
63
+ type: "object",
64
+ properties: {},
65
+ required: [],
66
+ },
67
+ },
68
+ {
69
+ name: "get_top_markets",
70
+ description: "Get the most active Polymarket markets by volume with current probabilities.",
71
+ inputSchema: {
72
+ type: "object",
73
+ properties: {
74
+ limit: {
75
+ type: "number",
76
+ description: "Number of markets to return (default: 10)",
77
+ default: 10,
78
+ },
79
+ category: {
80
+ type: "string",
81
+ description: "Filter by category (politics, crypto, sports, economics, etc.)",
82
+ },
83
+ },
84
+ required: [],
85
+ },
86
+ },
87
+ ];
88
+ // ============================================================================
89
+ // API HELPERS
90
+ // ============================================================================
91
+ async function callLPXPoly(endpoint, body) {
92
+ const res = await fetch(`${LPXPOLY_URL}${endpoint}`, {
93
+ method: "POST",
94
+ headers: {
95
+ "Content-Type": "application/json",
96
+ "X-Spend-Token": SPEND_TOKEN,
97
+ },
98
+ body: JSON.stringify(body),
99
+ });
100
+ if (!res.ok) {
101
+ if (res.status === 402) {
102
+ throw new Error(`Insufficient balance. Top up at ${LIGHTNINGPROX_URL} with Bitcoin Lightning.`);
103
+ }
104
+ const err = await res.text();
105
+ throw new Error(`LPXPoly API error (${res.status}): ${err}`);
106
+ }
107
+ return res.json();
108
+ }
109
+ async function getBalance() {
110
+ const res = await fetch(`${LIGHTNINGPROX_URL}/v1/balance`, {
111
+ headers: { "X-Spend-Token": SPEND_TOKEN },
112
+ });
113
+ if (!res.ok)
114
+ throw new Error(`Failed to fetch balance: ${res.statusText}`);
115
+ return res.json();
116
+ }
117
+ // ============================================================================
118
+ // MCP SERVER
119
+ // ============================================================================
120
+ const server = new index_js_1.Server({ name: "lpxpoly", version: "1.0.0" }, { capabilities: { tools: {} } });
121
+ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
122
+ return { tools };
123
+ });
124
+ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
125
+ const { name, arguments: args } = request.params;
126
+ try {
127
+ switch (name) {
128
+ case "get_edge_opportunities": {
129
+ const { min_edge, limit } = args;
130
+ const result = await callLPXPoly("/api/analyze", {
131
+ type: "edge",
132
+ min_edge: min_edge || 5,
133
+ limit: limit || 10,
134
+ });
135
+ const opportunities = result.opportunities || result;
136
+ if (!opportunities?.length) {
137
+ return {
138
+ content: [{ type: "text", text: "No edge opportunities found at this time." }],
139
+ };
140
+ }
141
+ const formatted = opportunities
142
+ .map((o, i) => `${i + 1}. ${o.question || o.market}\n Market: ${(o.market_prob * 100).toFixed(1)}% | AI: ${(o.ai_prob * 100).toFixed(1)}% | Edge: ${(o.edge * 100).toFixed(1)}%\n Recommendation: ${o.recommendation || (o.ai_prob > o.market_prob ? "YES" : "NO")}`)
143
+ .join("\n\n");
144
+ return {
145
+ content: [
146
+ {
147
+ type: "text",
148
+ text: `📊 LPXPoly Edge Opportunities\n\n${formatted}\n\n⚡ Powered by LPXPoly | lpxpoly.com`,
149
+ },
150
+ ],
151
+ };
152
+ }
153
+ case "analyze_market": {
154
+ const { query } = args;
155
+ const result = await callLPXPoly("/api/analyze", {
156
+ type: "market",
157
+ query,
158
+ });
159
+ return {
160
+ content: [
161
+ {
162
+ type: "text",
163
+ text: [
164
+ `📊 Market Analysis: ${query}`,
165
+ ``,
166
+ result.analysis || result.response || JSON.stringify(result, null, 2),
167
+ ``,
168
+ `⚡ Powered by LPXPoly | lpxpoly.com`,
169
+ ].join("\n"),
170
+ },
171
+ ],
172
+ };
173
+ }
174
+ case "check_balance": {
175
+ const balance = await getBalance();
176
+ return {
177
+ content: [
178
+ {
179
+ type: "text",
180
+ text: [
181
+ `⚡ LightningProx Balance`,
182
+ `Balance: ${balance.balance_sats} sats`,
183
+ `Estimated analyses remaining: ~${Math.floor(balance.balance_sats / 50)}`,
184
+ ``,
185
+ balance.balance_sats > 0
186
+ ? `✅ Ready for market analysis`
187
+ : `⚠️ No balance. Top up at ${LIGHTNINGPROX_URL}`,
188
+ ].join("\n"),
189
+ },
190
+ ],
191
+ };
192
+ }
193
+ case "get_top_markets": {
194
+ const { limit, category } = args;
195
+ const result = await callLPXPoly("/api/markets", {
196
+ limit: limit || 10,
197
+ category,
198
+ });
199
+ const markets = result.markets || result;
200
+ if (!markets?.length) {
201
+ return {
202
+ content: [{ type: "text", text: "No markets found." }],
203
+ };
204
+ }
205
+ const formatted = markets
206
+ .map((m, i) => `${i + 1}. ${m.question}\n Probability: ${(m.probability * 100).toFixed(1)}% | Volume: $${(m.volume || 0).toLocaleString()}`)
207
+ .join("\n\n");
208
+ return {
209
+ content: [
210
+ {
211
+ type: "text",
212
+ text: `📊 Top Polymarket Markets\n\n${formatted}\n\n⚡ Powered by LPXPoly | lpxpoly.com`,
213
+ },
214
+ ],
215
+ };
216
+ }
217
+ default:
218
+ throw new Error(`Unknown tool: ${name}`);
219
+ }
220
+ }
221
+ catch (error) {
222
+ return {
223
+ content: [{ type: "text", text: `❌ Error: ${error.message}` }],
224
+ isError: true,
225
+ };
226
+ }
227
+ });
228
+ // ============================================================================
229
+ // START
230
+ // ============================================================================
231
+ async function main() {
232
+ const transport = new stdio_js_1.StdioServerTransport();
233
+ await server.connect(transport);
234
+ console.error(`✅ LPXPoly MCP Server running | Token: ${SPEND_TOKEN.slice(0, 8)}...`);
235
+ }
236
+ main().catch((err) => {
237
+ console.error("Fatal error:", err);
238
+ process.exit(1);
239
+ });
240
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "lpxpoly-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for LPXPoly — AI-powered Polymarket prediction market analysis. Pay per analysis in Bitcoin sats via Lightning.",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "lpxpoly-mcp": "dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "dev": "ts-node src/index.ts",
12
+ "start": "node dist/index.js",
13
+ "prepare": "npm run build"
14
+ },
15
+ "keywords": [
16
+ "mcp",
17
+ "polymarket",
18
+ "prediction-markets",
19
+ "bitcoin",
20
+ "lightning",
21
+ "ai",
22
+ "trading",
23
+ "market-analysis",
24
+ "model-context-protocol",
25
+ "aiprox"
26
+ ],
27
+ "author": "LPX Digital Group LLC",
28
+ "license": "MIT",
29
+ "dependencies": {
30
+ "@modelcontextprotocol/sdk": "^1.0.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^20.0.0",
34
+ "typescript": "^5.0.0",
35
+ "ts-node": "^10.9.0"
36
+ },
37
+ "engines": {
38
+ "node": ">=18.0.0"
39
+ },
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "https://github.com/unixlamadev-spec/lpxpoly-mcp"
43
+ },
44
+ "homepage": "https://lpxpoly.com",
45
+ "bugs": {
46
+ "url": "https://github.com/unixlamadev-spec/lpxpoly-mcp/issues"
47
+ }
48
+ }
package/src/index.ts ADDED
@@ -0,0 +1,287 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * LPXPoly MCP Server
4
+ * AI-powered Polymarket prediction market analysis
5
+ * Pay per analysis in Bitcoin sats via Lightning
6
+ */
7
+
8
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
9
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
10
+ import {
11
+ CallToolRequestSchema,
12
+ ListToolsRequestSchema,
13
+ Tool,
14
+ } from "@modelcontextprotocol/sdk/types.js";
15
+
16
+ const LPXPOLY_URL = process.env.LPXPOLY_URL || "https://lpxpoly.com";
17
+ const LIGHTNINGPROX_URL = process.env.LIGHTNINGPROX_URL || "https://lightningprox.com";
18
+ const SPEND_TOKEN = process.env.LIGHTNINGPROX_SPEND_TOKEN || "";
19
+
20
+ if (!SPEND_TOKEN) {
21
+ console.error("❌ LIGHTNINGPROX_SPEND_TOKEN environment variable is required");
22
+ console.error(" Get a spend token at lightningprox.com — pay with Bitcoin Lightning");
23
+ console.error(" Example: LIGHTNINGPROX_SPEND_TOKEN=your_token npx lpxpoly-mcp");
24
+ process.exit(1);
25
+ }
26
+
27
+ // ============================================================================
28
+ // TOOL DEFINITIONS
29
+ // ============================================================================
30
+
31
+ const tools: Tool[] = [
32
+ {
33
+ name: "get_edge_opportunities",
34
+ description:
35
+ "Find mispriced Polymarket prediction markets where AI analysis disagrees with current market probability. Returns top edge opportunities with recommended positions.",
36
+ inputSchema: {
37
+ type: "object",
38
+ properties: {
39
+ min_edge: {
40
+ type: "number",
41
+ description: "Minimum edge percentage to include (default: 5)",
42
+ default: 5,
43
+ },
44
+ limit: {
45
+ type: "number",
46
+ description: "Maximum number of opportunities to return (default: 10)",
47
+ default: 10,
48
+ },
49
+ },
50
+ required: [],
51
+ },
52
+ },
53
+ {
54
+ name: "analyze_market",
55
+ description:
56
+ "Get AI analysis of a specific Polymarket prediction market. Returns probability assessment, reasoning, and recommended position.",
57
+ inputSchema: {
58
+ type: "object",
59
+ properties: {
60
+ query: {
61
+ type: "string",
62
+ description: "Market question or search term (e.g. 'Fed rate cut March 2025', 'Trump approval rating')",
63
+ },
64
+ },
65
+ required: ["query"],
66
+ },
67
+ },
68
+ {
69
+ name: "check_balance",
70
+ description:
71
+ "Check your LightningProx balance in sats. Required to pay for LPXPoly analyses.",
72
+ inputSchema: {
73
+ type: "object",
74
+ properties: {},
75
+ required: [],
76
+ },
77
+ },
78
+ {
79
+ name: "get_top_markets",
80
+ description:
81
+ "Get the most active Polymarket markets by volume with current probabilities.",
82
+ inputSchema: {
83
+ type: "object",
84
+ properties: {
85
+ limit: {
86
+ type: "number",
87
+ description: "Number of markets to return (default: 10)",
88
+ default: 10,
89
+ },
90
+ category: {
91
+ type: "string",
92
+ description: "Filter by category (politics, crypto, sports, economics, etc.)",
93
+ },
94
+ },
95
+ required: [],
96
+ },
97
+ },
98
+ ];
99
+
100
+ // ============================================================================
101
+ // API HELPERS
102
+ // ============================================================================
103
+
104
+ async function callLPXPoly(endpoint: string, body: any): Promise<any> {
105
+ const res = await fetch(`${LPXPOLY_URL}${endpoint}`, {
106
+ method: "POST",
107
+ headers: {
108
+ "Content-Type": "application/json",
109
+ "X-Spend-Token": SPEND_TOKEN,
110
+ },
111
+ body: JSON.stringify(body),
112
+ });
113
+
114
+ if (!res.ok) {
115
+ if (res.status === 402) {
116
+ throw new Error(
117
+ `Insufficient balance. Top up at ${LIGHTNINGPROX_URL} with Bitcoin Lightning.`
118
+ );
119
+ }
120
+ const err = await res.text();
121
+ throw new Error(`LPXPoly API error (${res.status}): ${err}`);
122
+ }
123
+
124
+ return res.json();
125
+ }
126
+
127
+ async function getBalance(): Promise<any> {
128
+ const res = await fetch(`${LIGHTNINGPROX_URL}/v1/balance`, {
129
+ headers: { "X-Spend-Token": SPEND_TOKEN },
130
+ });
131
+ if (!res.ok) throw new Error(`Failed to fetch balance: ${res.statusText}`);
132
+ return res.json();
133
+ }
134
+
135
+ // ============================================================================
136
+ // MCP SERVER
137
+ // ============================================================================
138
+
139
+ const server = new Server(
140
+ { name: "lpxpoly", version: "1.0.0" },
141
+ { capabilities: { tools: {} } }
142
+ );
143
+
144
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
145
+ return { tools };
146
+ });
147
+
148
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
149
+ const { name, arguments: args } = request.params;
150
+
151
+ try {
152
+ switch (name) {
153
+ case "get_edge_opportunities": {
154
+ const { min_edge, limit } = args as any;
155
+
156
+ const result = await callLPXPoly("/api/analyze", {
157
+ type: "edge",
158
+ min_edge: min_edge || 5,
159
+ limit: limit || 10,
160
+ });
161
+
162
+ const opportunities = result.opportunities || result;
163
+ if (!opportunities?.length) {
164
+ return {
165
+ content: [{ type: "text", text: "No edge opportunities found at this time." }],
166
+ };
167
+ }
168
+
169
+ const formatted = opportunities
170
+ .map(
171
+ (o: any, i: number) =>
172
+ `${i + 1}. ${o.question || o.market}\n Market: ${(o.market_prob * 100).toFixed(1)}% | AI: ${(o.ai_prob * 100).toFixed(1)}% | Edge: ${(o.edge * 100).toFixed(1)}%\n Recommendation: ${o.recommendation || (o.ai_prob > o.market_prob ? "YES" : "NO")}`
173
+ )
174
+ .join("\n\n");
175
+
176
+ return {
177
+ content: [
178
+ {
179
+ type: "text",
180
+ text: `📊 LPXPoly Edge Opportunities\n\n${formatted}\n\n⚡ Powered by LPXPoly | lpxpoly.com`,
181
+ },
182
+ ],
183
+ };
184
+ }
185
+
186
+ case "analyze_market": {
187
+ const { query } = args as any;
188
+
189
+ const result = await callLPXPoly("/api/analyze", {
190
+ type: "market",
191
+ query,
192
+ });
193
+
194
+ return {
195
+ content: [
196
+ {
197
+ type: "text",
198
+ text: [
199
+ `📊 Market Analysis: ${query}`,
200
+ ``,
201
+ result.analysis || result.response || JSON.stringify(result, null, 2),
202
+ ``,
203
+ `⚡ Powered by LPXPoly | lpxpoly.com`,
204
+ ].join("\n"),
205
+ },
206
+ ],
207
+ };
208
+ }
209
+
210
+ case "check_balance": {
211
+ const balance = await getBalance();
212
+
213
+ return {
214
+ content: [
215
+ {
216
+ type: "text",
217
+ text: [
218
+ `⚡ LightningProx Balance`,
219
+ `Balance: ${balance.balance_sats} sats`,
220
+ `Estimated analyses remaining: ~${Math.floor(balance.balance_sats / 50)}`,
221
+ ``,
222
+ balance.balance_sats > 0
223
+ ? `✅ Ready for market analysis`
224
+ : `⚠️ No balance. Top up at ${LIGHTNINGPROX_URL}`,
225
+ ].join("\n"),
226
+ },
227
+ ],
228
+ };
229
+ }
230
+
231
+ case "get_top_markets": {
232
+ const { limit, category } = args as any;
233
+
234
+ const result = await callLPXPoly("/api/markets", {
235
+ limit: limit || 10,
236
+ category,
237
+ });
238
+
239
+ const markets = result.markets || result;
240
+ if (!markets?.length) {
241
+ return {
242
+ content: [{ type: "text", text: "No markets found." }],
243
+ };
244
+ }
245
+
246
+ const formatted = markets
247
+ .map(
248
+ (m: any, i: number) =>
249
+ `${i + 1}. ${m.question}\n Probability: ${(m.probability * 100).toFixed(1)}% | Volume: $${(m.volume || 0).toLocaleString()}`
250
+ )
251
+ .join("\n\n");
252
+
253
+ return {
254
+ content: [
255
+ {
256
+ type: "text",
257
+ text: `📊 Top Polymarket Markets\n\n${formatted}\n\n⚡ Powered by LPXPoly | lpxpoly.com`,
258
+ },
259
+ ],
260
+ };
261
+ }
262
+
263
+ default:
264
+ throw new Error(`Unknown tool: ${name}`);
265
+ }
266
+ } catch (error: any) {
267
+ return {
268
+ content: [{ type: "text", text: `❌ Error: ${error.message}` }],
269
+ isError: true,
270
+ };
271
+ }
272
+ });
273
+
274
+ // ============================================================================
275
+ // START
276
+ // ============================================================================
277
+
278
+ async function main() {
279
+ const transport = new StdioServerTransport();
280
+ await server.connect(transport);
281
+ console.error(`✅ LPXPoly MCP Server running | Token: ${SPEND_TOKEN.slice(0, 8)}...`);
282
+ }
283
+
284
+ main().catch((err) => {
285
+ console.error("Fatal error:", err);
286
+ process.exit(1);
287
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": ["ES2020"],
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "resolveJsonModule": true,
13
+ "declaration": true,
14
+ "sourceMap": true
15
+ },
16
+ "include": ["src/**/*"],
17
+ "exclude": ["node_modules", "dist"]
18
+ }