@quantish/agent 0.1.0 → 0.1.2

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 (2) hide show
  1. package/dist/index.js +155 -7
  2. package/package.json +1 -2
package/dist/index.js CHANGED
@@ -2566,7 +2566,150 @@ You can work with the local filesystem:
2566
2566
  - When writing code, follow existing patterns and conventions
2567
2567
  - For dangerous operations (rm, sudo), explain what you're doing
2568
2568
 
2569
- You help users build trading bots and agents by combining coding skills with trading capabilities.`;
2569
+ You help users build trading bots and agents by combining coding skills with trading capabilities.
2570
+
2571
+ ## Building Standalone Trading Bots
2572
+
2573
+ When users ask you to create trading bots or agents that run independently (not through this CLI), here's how to integrate with the Quantish MCP API:
2574
+
2575
+ ### MCP API Endpoint
2576
+ \`\`\`
2577
+ POST https://quantish-sdk-production.up.railway.app/mcp/execute
2578
+ \`\`\`
2579
+
2580
+ ### Authentication
2581
+ \`\`\`
2582
+ Header: x-api-key: <QUANTISH_API_KEY>
2583
+ \`\`\`
2584
+ The API key is stored in the user's environment as QUANTISH_API_KEY. Always read from env vars, never hardcode.
2585
+
2586
+ ### Request Format (JSON-RPC 2.0)
2587
+ \`\`\`javascript
2588
+ const response = await fetch('https://quantish-sdk-production.up.railway.app/mcp/execute', {
2589
+ method: 'POST',
2590
+ headers: {
2591
+ 'Content-Type': 'application/json',
2592
+ 'x-api-key': process.env.QUANTISH_API_KEY
2593
+ },
2594
+ body: JSON.stringify({
2595
+ jsonrpc: '2.0',
2596
+ method: 'tools/call',
2597
+ params: {
2598
+ name: 'tool_name',
2599
+ arguments: { /* tool args */ }
2600
+ },
2601
+ id: Date.now()
2602
+ })
2603
+ });
2604
+ \`\`\`
2605
+
2606
+ ### Response Format
2607
+ \`\`\`javascript
2608
+ // Success response structure:
2609
+ {
2610
+ "jsonrpc": "2.0",
2611
+ "result": {
2612
+ "content": [{
2613
+ "type": "text",
2614
+ "text": "{\\"key\\": \\"value\\"}" // JSON string - parse this!
2615
+ }]
2616
+ },
2617
+ "id": 123
2618
+ }
2619
+
2620
+ // Parse the inner JSON:
2621
+ const data = await response.json();
2622
+ const result = JSON.parse(data.result.content[0].text);
2623
+ \`\`\`
2624
+
2625
+ ### Key Trading Tools (require QUANTISH_API_KEY)
2626
+ - \`get_balances\`: Returns { usdc, nativeUsdc, matic } for EOA and Safe wallets
2627
+ - \`get_positions\`: Returns array of current share holdings with market info
2628
+ - \`place_order\`: Place order. Args: { conditionId, tokenId, side: "BUY"|"SELL", price: 0.01-0.99, size: number }
2629
+ - \`cancel_order\`: Cancel order. Args: { orderId }
2630
+ - \`get_orders\`: List orders. Args: { status?: "LIVE"|"FILLED"|"CANCELLED" }
2631
+ - \`get_orderbook\`: Get bids/asks. Args: { tokenId }
2632
+ - \`get_price\`: Get midpoint price. Args: { tokenId }
2633
+ - \`get_deposit_addresses\`: Get addresses to fund wallet
2634
+ - \`transfer_usdc\`: Send USDC. Args: { toAddress, amount }
2635
+
2636
+ ### Key Discovery Tools (free, no auth required)
2637
+ Discovery uses a different endpoint with an embedded public key:
2638
+ \`\`\`
2639
+ POST https://quantish.live/mcp/execute
2640
+ Header: X-API-Key: qm_ueQeqrmvZyHtR1zuVbLYkhx0fKyVAuV8
2641
+ \`\`\`
2642
+
2643
+ - \`search_markets\`: Find markets. Args: { query, limit?, platform?: "polymarket"|"kalshi"|"all" }
2644
+ - \`get_market_details\`: Get market info. Args: { platform, marketId }
2645
+ - \`get_trending_markets\`: Popular markets. Args: { limit?, platform? }
2646
+ - \`find_arbitrage\`: Find arb opportunities. Args: { minProfitPercent?, type? }
2647
+
2648
+ ### Important: Token IDs and Condition IDs
2649
+ When placing orders, you need:
2650
+ - \`conditionId\`: The market's condition ID (from market details)
2651
+ - \`tokenId\`: The specific outcome's token ID (YES or NO token from market.tokens array)
2652
+
2653
+ Example flow:
2654
+ 1. search_markets({ query: "bitcoin" }) \u2192 get market list
2655
+ 2. get_market_details({ platform: "polymarket", marketId: "..." }) \u2192 get tokens array
2656
+ 3. Extract tokenId for YES/NO outcome you want
2657
+ 4. place_order({ conditionId, tokenId, side: "BUY", price: 0.55, size: 100 })
2658
+
2659
+ ### Bot Code Template (Node.js)
2660
+ \`\`\`javascript
2661
+ #!/usr/bin/env node
2662
+ require('dotenv').config();
2663
+
2664
+ const MCP_URL = 'https://quantish-sdk-production.up.railway.app/mcp/execute';
2665
+ const API_KEY = process.env.QUANTISH_API_KEY;
2666
+
2667
+ async function callTool(name, args = {}) {
2668
+ const response = await fetch(MCP_URL, {
2669
+ method: 'POST',
2670
+ headers: {
2671
+ 'Content-Type': 'application/json',
2672
+ 'x-api-key': API_KEY
2673
+ },
2674
+ body: JSON.stringify({
2675
+ jsonrpc: '2.0',
2676
+ method: 'tools/call',
2677
+ params: { name, arguments: args },
2678
+ id: Date.now()
2679
+ })
2680
+ });
2681
+
2682
+ const data = await response.json();
2683
+ if (data.error) throw new Error(data.error.message);
2684
+
2685
+ try {
2686
+ return JSON.parse(data.result.content[0].text);
2687
+ } catch {
2688
+ return data.result.content[0].text;
2689
+ }
2690
+ }
2691
+
2692
+ // Example: Monitor price and alert
2693
+ async function monitorPrice(tokenId, threshold) {
2694
+ const result = await callTool('get_price', { tokenId });
2695
+ console.log(\`Price: \${result.mid}\`);
2696
+ if (parseFloat(result.mid) > threshold) {
2697
+ console.log('ALERT: Price crossed threshold!');
2698
+ }
2699
+ }
2700
+
2701
+ // Run every 60 seconds
2702
+ setInterval(() => monitorPrice(process.env.TOKEN_ID, 0.5), 60000);
2703
+ \`\`\`
2704
+
2705
+ ### Bot Best Practices
2706
+ 1. **Environment Variables**: Always use process.env for API keys
2707
+ 2. **Error Handling**: Wrap all API calls in try/catch
2708
+ 3. **Rate Limiting**: Poll at 30-60 second intervals minimum
2709
+ 4. **Logging**: Log all trades with timestamps for debugging
2710
+ 5. **Testing**: Test with small amounts first
2711
+ 6. **Graceful Shutdown**: Handle SIGINT to clean up
2712
+ 7. **.env.example**: Always create a template for required env vars`;
2570
2713
  var Agent = class {
2571
2714
  anthropic;
2572
2715
  mcpClient;
@@ -2774,6 +2917,7 @@ ${userMessage}`;
2774
2917
  const toolResults = [];
2775
2918
  for (const toolUse of toolUses) {
2776
2919
  this.config.onToolCall?.(toolUse.name, toolUse.input);
2920
+ await new Promise((resolve2) => setImmediate(resolve2));
2777
2921
  const { result, source } = await this.executeTool(
2778
2922
  toolUse.name,
2779
2923
  toolUse.input
@@ -3092,7 +3236,7 @@ import { useState, useCallback, useRef, useEffect } from "react";
3092
3236
  import { Box, Text, useApp, useInput } from "ink";
3093
3237
  import TextInput from "ink-text-input";
3094
3238
  import Spinner from "ink-spinner";
3095
- import { jsx, jsxs } from "react/jsx-runtime";
3239
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3096
3240
  function formatTokenCount(count) {
3097
3241
  if (count < 1e3) return String(count);
3098
3242
  if (count < 1e5) return `${(count / 1e3).toFixed(1)}k`;
@@ -3569,18 +3713,22 @@ Stopped ${count} background process${count > 1 ? "es" : ""}.`);
3569
3713
  msg.role === "system" && /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { color: "gray", italic: true, children: msg.content }) })
3570
3714
  ] }, i)) }),
3571
3715
  currentToolCalls.length > 0 && /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 1, marginLeft: 2, children: currentToolCalls.map((tc, i) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
3572
- /* @__PURE__ */ jsxs(Box, { children: [
3573
- tc.pending ? /* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
3574
- /* @__PURE__ */ jsx(Spinner, { type: "dots" }),
3716
+ /* @__PURE__ */ jsx(Box, { children: tc.pending ? /* @__PURE__ */ jsxs(Fragment, { children: [
3717
+ /* @__PURE__ */ jsx(Text, { color: "yellow", children: /* @__PURE__ */ jsx(Spinner, { type: "dots" }) }),
3718
+ /* @__PURE__ */ jsxs(Text, { color: "cyan", bold: true, children: [
3575
3719
  " ",
3576
3720
  tc.name
3577
- ] }) : /* @__PURE__ */ jsxs(Text, { color: tc.success ? "blue" : "red", children: [
3721
+ ] }),
3722
+ /* @__PURE__ */ jsx(Text, { color: "gray", children: formatArgs(tc.args) }),
3723
+ /* @__PURE__ */ jsx(Text, { color: "yellow", dimColor: true, children: " Running..." })
3724
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
3725
+ /* @__PURE__ */ jsxs(Text, { color: tc.success ? "green" : "red", children: [
3578
3726
  tc.success ? "\u2713" : "\u2717",
3579
3727
  " ",
3580
3728
  tc.name
3581
3729
  ] }),
3582
3730
  /* @__PURE__ */ jsx(Text, { color: "gray", children: formatArgs(tc.args) })
3583
- ] }),
3731
+ ] }) }),
3584
3732
  !tc.pending && tc.result && /* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsxs(Text, { color: "gray", dimColor: true, children: [
3585
3733
  "\u2192 ",
3586
3734
  formatResult(tc.result, 100)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantish/agent",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "AI-powered agent for building trading bots on Polymarket",
5
5
  "type": "module",
6
6
  "bin": {
@@ -65,4 +65,3 @@
65
65
  "typescript": "^5.7.2"
66
66
  }
67
67
  }
68
-