@zebpay_rajesh/zebpay-mcp-server 0.1.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.
Potentially problematic release.
This version of @zebpay_rajesh/zebpay-mcp-server might be problematic. Click here for more details.
- package/.env.example +14 -0
- package/README.md +223 -0
- package/dist/__tests__/errors.test.d.ts +5 -0
- package/dist/__tests__/errors.test.js +147 -0
- package/dist/__tests__/errors.test.js.map +1 -0
- package/dist/__tests__/prompts.test.d.ts +1 -0
- package/dist/__tests__/prompts.test.js +73 -0
- package/dist/__tests__/prompts.test.js.map +1 -0
- package/dist/__tests__/resources.test.d.ts +1 -0
- package/dist/__tests__/resources.test.js +79 -0
- package/dist/__tests__/resources.test.js.map +1 -0
- package/dist/__tests__/validation.test.d.ts +15 -0
- package/dist/__tests__/validation.test.js +64 -0
- package/dist/__tests__/validation.test.js.map +1 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.js +81 -0
- package/dist/config.js.map +1 -0
- package/dist/http/httpClient.d.ts +40 -0
- package/dist/http/httpClient.js +341 -0
- package/dist/http/httpClient.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/errors.d.ts +21 -0
- package/dist/mcp/errors.js +214 -0
- package/dist/mcp/errors.js.map +1 -0
- package/dist/mcp/logging.d.ts +21 -0
- package/dist/mcp/logging.js +241 -0
- package/dist/mcp/logging.js.map +1 -0
- package/dist/mcp/prompts.d.ts +9 -0
- package/dist/mcp/prompts.js +165 -0
- package/dist/mcp/prompts.js.map +1 -0
- package/dist/mcp/resources.d.ts +9 -0
- package/dist/mcp/resources.js +125 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/tools_futures.d.ts +5 -0
- package/dist/mcp/tools_futures.js +694 -0
- package/dist/mcp/tools_futures.js.map +1 -0
- package/dist/mcp/tools_spot.d.ts +11 -0
- package/dist/mcp/tools_spot.js +2225 -0
- package/dist/mcp/tools_spot.js.map +1 -0
- package/dist/private/FuturesClient.d.ts +57 -0
- package/dist/private/FuturesClient.js +181 -0
- package/dist/private/FuturesClient.js.map +1 -0
- package/dist/private/SpotClient.d.ts +44 -0
- package/dist/private/SpotClient.js +201 -0
- package/dist/private/SpotClient.js.map +1 -0
- package/dist/private/ZebpayAPI.d.ts +19 -0
- package/dist/private/ZebpayAPI.js +172 -0
- package/dist/private/ZebpayAPI.js.map +1 -0
- package/dist/public/PublicClient.d.ts +79 -0
- package/dist/public/PublicClient.js +283 -0
- package/dist/public/PublicClient.js.map +1 -0
- package/dist/public/PublicFuturesClient.d.ts +27 -0
- package/dist/public/PublicFuturesClient.js +187 -0
- package/dist/public/PublicFuturesClient.js.map +1 -0
- package/dist/security/credentials.d.ts +42 -0
- package/dist/security/credentials.js +80 -0
- package/dist/security/credentials.js.map +1 -0
- package/dist/security/signing.d.ts +33 -0
- package/dist/security/signing.js +56 -0
- package/dist/security/signing.js.map +1 -0
- package/dist/types/responses.d.ts +130 -0
- package/dist/types/responses.js +6 -0
- package/dist/types/responses.js.map +1 -0
- package/dist/utils/cache.d.ts +29 -0
- package/dist/utils/cache.js +72 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/fileLogger.d.ts +10 -0
- package/dist/utils/fileLogger.js +81 -0
- package/dist/utils/fileLogger.js.map +1 -0
- package/dist/utils/metrics.d.ts +35 -0
- package/dist/utils/metrics.js +94 -0
- package/dist/utils/metrics.js.map +1 -0
- package/dist/utils/responseFormatter.d.ts +93 -0
- package/dist/utils/responseFormatter.js +268 -0
- package/dist/utils/responseFormatter.js.map +1 -0
- package/dist/validation/schemas.d.ts +70 -0
- package/dist/validation/schemas.js +48 -0
- package/dist/validation/schemas.js.map +1 -0
- package/dist/validation/validators.d.ts +28 -0
- package/dist/validation/validators.js +129 -0
- package/dist/validation/validators.js.map +1 -0
- package/docs/LOGGING.md +371 -0
- package/docs/zebpay-ai-trading-beginner.png +0 -0
- package/mcp-config.json.example +20 -0
- package/package.json +54 -0
- package/scripts/README.md +103 -0
- package/scripts/clear-logs.js +52 -0
- package/scripts/log-stats.js +264 -0
- package/scripts/log-viewer.js +288 -0
- package/server.json +31 -0
- package/src/__tests__/errors.test.ts +180 -0
- package/src/__tests__/prompts.test.ts +89 -0
- package/src/__tests__/resources.test.ts +95 -0
- package/src/__tests__/validation.test.ts +88 -0
- package/src/config.ts +108 -0
- package/src/http/httpClient.ts +398 -0
- package/src/index.ts +71 -0
- package/src/mcp/errors.ts +262 -0
- package/src/mcp/logging.ts +284 -0
- package/src/mcp/prompts.ts +206 -0
- package/src/mcp/resources.ts +163 -0
- package/src/mcp/tools_futures.ts +874 -0
- package/src/mcp/tools_spot.ts +2702 -0
- package/src/private/FuturesClient.ts +189 -0
- package/src/private/SpotClient.ts +250 -0
- package/src/private/ZebpayAPI.ts +205 -0
- package/src/public/PublicClient.ts +381 -0
- package/src/public/PublicFuturesClient.ts +228 -0
- package/src/security/credentials.ts +114 -0
- package/src/security/signing.ts +98 -0
- package/src/types/responses.ts +146 -0
- package/src/utils/cache.ts +90 -0
- package/src/utils/fileLogger.ts +88 -0
- package/src/utils/metrics.ts +135 -0
- package/src/utils/responseFormatter.ts +361 -0
- package/src/validation/schemas.ts +66 -0
- package/src/validation/validators.ts +189 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,2225 @@
|
|
|
1
|
+
/*
|
|
2
|
+
MCP tool registrations using the MCP SDK.
|
|
3
|
+
*/
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { withLogging } from "./logging.js";
|
|
6
|
+
import { validateSymbol, validateQuantity, validateClientOrderId, symbolSchema, quantitySchema } from "../validation/validators.js";
|
|
7
|
+
import { createInternalError, createInvalidParamsError } from "./errors.js";
|
|
8
|
+
import { formatResponse, formatBalanceResponse, formatTickerResponse, formatOrderResponse, formatOrderBookResponse, formatTradesResponse, formatKlinesResponse, generateCorrelationId } from "../utils/responseFormatter.js";
|
|
9
|
+
import { metricsCollector } from "../utils/metrics.js";
|
|
10
|
+
export function registerSpotTools(server, spot, // null if no credentials provided - tools still registered but will error if called
|
|
11
|
+
publicClient, config) {
|
|
12
|
+
console.error(`Registering SPOT tools - Authenticated tools will check credentials at runtime`);
|
|
13
|
+
// Always register authenticated tools - they will check credentials at runtime
|
|
14
|
+
console.error("Registering authenticated tools (spot trading, balances, orders)...");
|
|
15
|
+
try {
|
|
16
|
+
server.tool("zebpay_spot_placeMarketOrder", `Place a market order on Zebpay spot trading exchange with automatic currency conversion.
|
|
17
|
+
|
|
18
|
+
This tool executes an immediate buy or sell order at the current market price. Market orders are filled instantly at the best available price, unlike limit orders which wait for a specific price.
|
|
19
|
+
|
|
20
|
+
**When to use this tool:**
|
|
21
|
+
- User wants to buy or sell cryptocurrency immediately
|
|
22
|
+
- User needs to execute a trade quickly without waiting for a specific price
|
|
23
|
+
- User wants to convert one cryptocurrency to another or to fiat currency
|
|
24
|
+
|
|
25
|
+
**Important notes:**
|
|
26
|
+
- Market orders execute immediately at current market price
|
|
27
|
+
- Supports BOTH quote currency (INR) and base currency (BTC) specifications
|
|
28
|
+
- Automatic conversion using current market price when needed
|
|
29
|
+
- All quantities are trimmed to 6 decimal places
|
|
30
|
+
- Symbol format is typically BASE-QUOTE (e.g., BTC-INR means buying/selling Bitcoin with Indian Rupees)
|
|
31
|
+
|
|
32
|
+
**How conversion works:**
|
|
33
|
+
|
|
34
|
+
For BUY orders:
|
|
35
|
+
- User specifies quoteOrderAmount (100 INR) → Used directly as quoteOrderAmount
|
|
36
|
+
- User specifies amount (0.0001 BTC) → Converted: 0.0001 × market_price = INR value → Used as quoteOrderAmount
|
|
37
|
+
|
|
38
|
+
For SELL orders:
|
|
39
|
+
- User specifies amount (0.0005 BTC) → Used directly as amount
|
|
40
|
+
- User specifies quoteOrderAmount (200 INR) → Converted: 200 ÷ market_price = BTC quantity → Used as amount
|
|
41
|
+
|
|
42
|
+
**Example use cases:**
|
|
43
|
+
1. User says "Buy 100 INR worth of BTC" → Use symbol="BTC-INR", side="BUY", quoteOrderAmount="100"
|
|
44
|
+
2. User says "Sell 0.0005 BTC" → Use symbol="BTC-INR", side="SELL", amount="0.0005"
|
|
45
|
+
3. User says "Buy 0.0001 BTC" → Use symbol="BTC-INR", side="BUY", amount="0.0001" (auto-converts to INR)
|
|
46
|
+
4. User says "Sell 200 INR worth of BTC" → Use symbol="BTC-INR", side="SELL", quoteOrderAmount="200" (auto-converts to BTC)
|
|
47
|
+
|
|
48
|
+
**Example request (BUY with quote currency):**
|
|
49
|
+
{
|
|
50
|
+
"symbol": "BTC-INR",
|
|
51
|
+
"side": "BUY",
|
|
52
|
+
"quoteOrderAmount": "100"
|
|
53
|
+
}
|
|
54
|
+
→ Body sent to API: { symbol: "BTC-INR", side: "BUY", type: "MARKET", quoteOrderAmount: "100" }
|
|
55
|
+
|
|
56
|
+
**Example request (BUY with base currency - auto-converted):**
|
|
57
|
+
{
|
|
58
|
+
"symbol": "BTC-INR",
|
|
59
|
+
"side": "BUY",
|
|
60
|
+
"amount": "0.0001"
|
|
61
|
+
}
|
|
62
|
+
→ At market price 8900000: 0.0001 × 8900000 = 890 INR
|
|
63
|
+
→ Body sent to API: { symbol: "BTC-INR", side: "BUY", type: "MARKET", quoteOrderAmount: "890" }
|
|
64
|
+
|
|
65
|
+
**Example request (SELL with base currency):**
|
|
66
|
+
{
|
|
67
|
+
"symbol": "BTC-INR",
|
|
68
|
+
"side": "SELL",
|
|
69
|
+
"amount": "0.0005"
|
|
70
|
+
}
|
|
71
|
+
→ Body sent to API: { symbol: "BTC-INR", side: "SELL", type: "MARKET", amount: "0.0005" }
|
|
72
|
+
|
|
73
|
+
**Example request (SELL with quote currency - auto-converted):**
|
|
74
|
+
{
|
|
75
|
+
"symbol": "BTC-INR",
|
|
76
|
+
"side": "SELL",
|
|
77
|
+
"quoteOrderAmount": "200"
|
|
78
|
+
}
|
|
79
|
+
→ At market price 8900000: 200 ÷ 8900000 = 0.000022 BTC
|
|
80
|
+
→ Body sent to API: { symbol: "BTC-INR", side: "SELL", type: "MARKET", amount: "0.000022" }
|
|
81
|
+
|
|
82
|
+
**Example response:**
|
|
83
|
+
The tool returns order details including order ID, status, executed price, and quantity filled.
|
|
84
|
+
|
|
85
|
+
**Rate Limits:**
|
|
86
|
+
- Maximum 10 requests per second for authenticated endpoints
|
|
87
|
+
- Burst limit: 20 requests
|
|
88
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
89
|
+
- If rate limited, wait 1 second before retrying
|
|
90
|
+
|
|
91
|
+
**Related Tools:**
|
|
92
|
+
- Use zebpay_spot_getBalance before placing orders to check available funds
|
|
93
|
+
- Use zebpay_public_getTicker to check current market price before trading
|
|
94
|
+
- Use zebpay_public_getOrderBook to analyze market depth and liquidity`, {
|
|
95
|
+
symbol: symbolSchema.describe(`Trading pair symbol in format BASE-QUOTE.
|
|
96
|
+
Examples: "BTC-INR" (Bitcoin/Indian Rupees), "ETH-INR" (Ethereum/Indian Rupees), "BTC-USDT" (Bitcoin/Tether).
|
|
97
|
+
The symbol determines which market you're trading in. Always use uppercase currency codes separated by a hyphen.`),
|
|
98
|
+
side: z.enum(["BUY", "SELL"]).describe(`Order side determines whether you're buying or selling the base currency.
|
|
99
|
+
- "BUY": Purchase the base currency (e.g., buying BTC with BTC-INR pair)
|
|
100
|
+
- "SELL": Sell the base currency (e.g., selling BTC with BTC-INR pair)
|
|
101
|
+
Example: For symbol "BTC-INR", side "BUY" means buying Bitcoin with Indian Rupees.`),
|
|
102
|
+
quoteOrderAmount: quantitySchema.optional().describe(`Quote currency value as a string (use this OR amount, not both).
|
|
103
|
+
Use this when user specifies the order value in QUOTE currency (e.g., INR, USDT).
|
|
104
|
+
Examples:
|
|
105
|
+
- "100" for BTC-INR means 100 INR worth
|
|
106
|
+
- "50" for ETH-USDT means 50 USDT worth
|
|
107
|
+
For BUY orders: used directly in API body as quoteOrderAmount.
|
|
108
|
+
For SELL orders: will be converted to base currency amount using current market price.
|
|
109
|
+
Always provide as a string to avoid floating-point precision issues.`),
|
|
110
|
+
amount: quantitySchema.optional().describe(`Base currency amount as a string (use this OR quoteOrderAmount, not both).
|
|
111
|
+
Use this when user specifies the quantity in BASE currency (e.g., BTC, ETH).
|
|
112
|
+
Examples:
|
|
113
|
+
- "0.0005" for BTC-INR means 0.0005 BTC
|
|
114
|
+
- "0.1" for ETH-INR means 0.1 ETH
|
|
115
|
+
For SELL orders: used directly in API body as amount.
|
|
116
|
+
For BUY orders: will be converted to quote currency value using current market price.
|
|
117
|
+
Always provide as a string to avoid floating-point precision issues.`),
|
|
118
|
+
clientOrderId: z.string().min(1).max(36).optional().describe(`Optional custom identifier for tracking your order.
|
|
119
|
+
If provided, you can use this ID to reference the order later. Must be unique.
|
|
120
|
+
Must contain only letters, numbers, dots, colons, slashes, underscores, and hyphens, and be 1-36 characters long.
|
|
121
|
+
Example: "my-trade-2024-01-15-001" or "arbitrage-order-123"
|
|
122
|
+
If not provided, the exchange will generate an order ID automatically.`),
|
|
123
|
+
platform: z.string().optional().describe(`Optional platform identifier for the order.`),
|
|
124
|
+
}, withLogging("spot_placeMarketOrder", config.logLevel, async ({ symbol, side, quoteOrderAmount, amount, clientOrderId, platform }) => {
|
|
125
|
+
const correlationId = generateCorrelationId();
|
|
126
|
+
const startTime = Date.now();
|
|
127
|
+
// Check if credentials are available
|
|
128
|
+
if (!spot) {
|
|
129
|
+
metricsCollector.record("zebpay_spot_placeMarketOrder", Date.now() - startTime, false, "missing_credentials");
|
|
130
|
+
throw createInvalidParamsError("API credentials are required for this operation. Please provide ZEBPAY_API_KEY and ZEBPAY_API_SECRET headers or include credentials in initialization params.", {});
|
|
131
|
+
}
|
|
132
|
+
// Validate that at least one of quoteOrderAmount or amount is provided
|
|
133
|
+
if (!quoteOrderAmount && !amount) {
|
|
134
|
+
metricsCollector.record("zebpay_spot_placeMarketOrder", Date.now() - startTime, false, "validation_error");
|
|
135
|
+
throw createInvalidParamsError("Either quoteOrderAmount or amount must be provided for market orders.", { symbol, side });
|
|
136
|
+
}
|
|
137
|
+
// Validate that both are not provided
|
|
138
|
+
if (quoteOrderAmount && amount) {
|
|
139
|
+
metricsCollector.record("zebpay_spot_placeMarketOrder", Date.now() - startTime, false, "validation_error");
|
|
140
|
+
throw createInvalidParamsError("Cannot provide both quoteOrderAmount and amount. Please specify only one.", { symbol, side });
|
|
141
|
+
}
|
|
142
|
+
// Additional validation with helpful error messages
|
|
143
|
+
try {
|
|
144
|
+
validateSymbol(symbol);
|
|
145
|
+
if (quoteOrderAmount) {
|
|
146
|
+
validateQuantity(quoteOrderAmount);
|
|
147
|
+
}
|
|
148
|
+
if (amount) {
|
|
149
|
+
validateQuantity(amount);
|
|
150
|
+
}
|
|
151
|
+
if (clientOrderId) {
|
|
152
|
+
validateClientOrderId(clientOrderId);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
// Re-throw validation errors (they're already MCP errors)
|
|
157
|
+
metricsCollector.record("zebpay_spot_placeMarketOrder", Date.now() - startTime, false, "validation_error");
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
// Helper function to trim to 6 decimals
|
|
161
|
+
const trimToSixDecimals = (value) => {
|
|
162
|
+
const num = parseFloat(value);
|
|
163
|
+
// Round to 6 decimals and remove trailing zeros
|
|
164
|
+
const fixed = num.toFixed(6);
|
|
165
|
+
// Remove trailing zeros after decimal point, but keep at least one digit
|
|
166
|
+
return fixed.replace(/(\.\d*?)0+$/, '$1').replace(/\.$/, '');
|
|
167
|
+
};
|
|
168
|
+
let finalQuoteOrderAmount;
|
|
169
|
+
let finalAmount;
|
|
170
|
+
// Handle conversion based on side and provided parameter
|
|
171
|
+
if (side === "BUY") {
|
|
172
|
+
if (quoteOrderAmount) {
|
|
173
|
+
// User provided quote currency (INR) - use directly
|
|
174
|
+
finalQuoteOrderAmount = trimToSixDecimals(quoteOrderAmount.trim());
|
|
175
|
+
}
|
|
176
|
+
else if (amount) {
|
|
177
|
+
// User provided base currency (BTC) - need to convert to quote currency (INR)
|
|
178
|
+
// Get current market price
|
|
179
|
+
try {
|
|
180
|
+
const ticker = await publicClient.getTicker({ symbol: symbol.trim().toUpperCase() });
|
|
181
|
+
const currentPrice = parseFloat(ticker.lastPrice || ticker.price || "0");
|
|
182
|
+
if (currentPrice === 0) {
|
|
183
|
+
throw createInternalError("Unable to fetch current market price for conversion", { symbol });
|
|
184
|
+
}
|
|
185
|
+
// Convert: amount (BTC) * price = quoteOrderAmount (INR)
|
|
186
|
+
const baseAmount = parseFloat(amount.trim());
|
|
187
|
+
const convertedQuoteAmount = baseAmount * currentPrice;
|
|
188
|
+
finalQuoteOrderAmount = trimToSixDecimals(convertedQuoteAmount.toString());
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
metricsCollector.record("zebpay_spot_placeMarketOrder", Date.now() - startTime, false, "conversion_error");
|
|
192
|
+
throw error;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
// SELL order
|
|
198
|
+
if (amount) {
|
|
199
|
+
// User provided base currency (BTC) - use directly
|
|
200
|
+
finalAmount = trimToSixDecimals(amount.trim());
|
|
201
|
+
}
|
|
202
|
+
else if (quoteOrderAmount) {
|
|
203
|
+
// User provided quote currency (INR) - need to convert to base currency (BTC)
|
|
204
|
+
// Get current market price
|
|
205
|
+
try {
|
|
206
|
+
const ticker = await publicClient.getTicker({ symbol: symbol.trim().toUpperCase() });
|
|
207
|
+
const currentPrice = parseFloat(ticker.lastPrice || ticker.price || "0");
|
|
208
|
+
if (currentPrice === 0) {
|
|
209
|
+
throw createInternalError("Unable to fetch current market price for conversion", { symbol });
|
|
210
|
+
}
|
|
211
|
+
// Convert: quoteOrderAmount (INR) / price = amount (BTC)
|
|
212
|
+
const quoteAmount = parseFloat(quoteOrderAmount.trim());
|
|
213
|
+
const convertedBaseAmount = quoteAmount / currentPrice;
|
|
214
|
+
finalAmount = trimToSixDecimals(convertedBaseAmount.toString());
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
metricsCollector.record("zebpay_spot_placeMarketOrder", Date.now() - startTime, false, "conversion_error");
|
|
218
|
+
throw error;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const params = {
|
|
223
|
+
symbol: symbol.trim().toUpperCase(),
|
|
224
|
+
side,
|
|
225
|
+
...(finalQuoteOrderAmount && { quoteOrderAmount: finalQuoteOrderAmount }),
|
|
226
|
+
...(finalAmount && { amount: finalAmount }),
|
|
227
|
+
...(clientOrderId && { clientOrderId }),
|
|
228
|
+
...(platform && { platform }),
|
|
229
|
+
};
|
|
230
|
+
try {
|
|
231
|
+
const result = await spot.placeMarketOrder(params);
|
|
232
|
+
const durationMs = Date.now() - startTime;
|
|
233
|
+
metricsCollector.record("zebpay_spot_placeMarketOrder", durationMs, true);
|
|
234
|
+
return formatOrderResponse(result, {
|
|
235
|
+
correlationId,
|
|
236
|
+
executionTimeMs: durationMs,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
const durationMs = Date.now() - startTime;
|
|
241
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
242
|
+
metricsCollector.record("zebpay_spot_placeMarketOrder", durationMs, false, errorType);
|
|
243
|
+
// Re-throw MCP errors as-is, wrap others
|
|
244
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
245
|
+
throw error;
|
|
246
|
+
}
|
|
247
|
+
throw createInternalError(`Failed to place market order: ${error instanceof Error ? error.message : String(error)}`, { symbol, side, quoteOrderAmount, amount });
|
|
248
|
+
}
|
|
249
|
+
}));
|
|
250
|
+
console.error("Registered tool: zebpay_spot_placeMarketOrder");
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
console.error("Error registering spot_placeMarketOrder:", error);
|
|
254
|
+
}
|
|
255
|
+
// Limit order
|
|
256
|
+
try {
|
|
257
|
+
server.tool("zebpay_spot_placeLimitOrder", `Place a LIMIT order on Zebpay spot exchange with automatic currency conversion.
|
|
258
|
+
|
|
259
|
+
Use this to buy or sell at a specific price. The order rests on the order book until it can be filled at the specified price or better.
|
|
260
|
+
|
|
261
|
+
**Important notes:**
|
|
262
|
+
- Supports BOTH quote currency (INR) and base currency (BTC) specifications
|
|
263
|
+
- Automatic conversion using the provided limit price when needed
|
|
264
|
+
- All quantities are trimmed to 6 decimal places
|
|
265
|
+
- You must specify EITHER quoteOrderAmount OR amount (not both)
|
|
266
|
+
|
|
267
|
+
**How conversion works:**
|
|
268
|
+
|
|
269
|
+
For BUY orders:
|
|
270
|
+
- User specifies quoteOrderAmount (100 INR) → Used directly as quoteOrderAmount
|
|
271
|
+
- User specifies amount (0.0001 BTC) → Converted: 0.0001 × limit_price = INR value → Used as quoteOrderAmount
|
|
272
|
+
|
|
273
|
+
For SELL orders:
|
|
274
|
+
- User specifies amount (0.0005 BTC) → Used directly as amount
|
|
275
|
+
- User specifies quoteOrderAmount (200 INR) → Converted: 200 ÷ limit_price = BTC quantity → Used as amount
|
|
276
|
+
|
|
277
|
+
**Example use cases:**
|
|
278
|
+
1. User says "Buy 100 INR worth of BTC at 6000000" → Use quoteOrderAmount="100", price="6000000"
|
|
279
|
+
2. User says "Sell 0.0005 BTC at 6000000" → Use amount="0.0005", price="6000000"
|
|
280
|
+
3. User says "Buy 0.0001 BTC at 6000000" → Use amount="0.0001", price="6000000" (auto-converts to INR)
|
|
281
|
+
4. User says "Sell 200 INR worth at 6000000" → Use quoteOrderAmount="200", price="6000000" (auto-converts to BTC)
|
|
282
|
+
|
|
283
|
+
**Example:**
|
|
284
|
+
{
|
|
285
|
+
"symbol": "BTC-INR",
|
|
286
|
+
"side": "BUY",
|
|
287
|
+
"quoteOrderAmount": "100",
|
|
288
|
+
"price": "6000000",
|
|
289
|
+
"clientOrderId": "my-limit-1"
|
|
290
|
+
}
|
|
291
|
+
→ Body sent to API: { symbol: "BTC-INR", side: "BUY", type: "LIMIT", quoteOrderAmount: "100", price: "6000000" }`, {
|
|
292
|
+
symbol: symbolSchema.describe(`Trading pair symbol in format BASE-QUOTE, e.g., "BTC-INR", "ETH-USDT".`),
|
|
293
|
+
side: z.enum(["BUY", "SELL"]).describe(`Order side determines whether you're buying or selling the base currency.
|
|
294
|
+
- "BUY": Purchase the base currency at the specified limit price
|
|
295
|
+
- "SELL": Sell the base currency at the specified limit price`),
|
|
296
|
+
quoteOrderAmount: quantitySchema.optional().describe(`Quote currency value as a string (use this OR amount, not both).
|
|
297
|
+
Use this when user specifies the order value in QUOTE currency (e.g., INR, USDT).
|
|
298
|
+
Examples:
|
|
299
|
+
- "100" for BTC-INR means 100 INR worth
|
|
300
|
+
- "50" for ETH-USDT means 50 USDT worth
|
|
301
|
+
For BUY orders: used directly in API body as quoteOrderAmount.
|
|
302
|
+
For SELL orders: will be converted to base currency amount using the provided limit price.
|
|
303
|
+
Always provide as a string to avoid floating-point precision issues.`),
|
|
304
|
+
amount: quantitySchema.optional().describe(`Base currency amount as a string (use this OR quoteOrderAmount, not both).
|
|
305
|
+
Use this when user specifies the quantity in BASE currency (e.g., BTC, ETH).
|
|
306
|
+
Examples:
|
|
307
|
+
- "0.001" for BTC-INR means 0.001 BTC
|
|
308
|
+
- "0.1" for ETH-INR means 0.1 ETH
|
|
309
|
+
For SELL orders: used directly in API body as amount.
|
|
310
|
+
For BUY orders: will be converted to quote currency value using the provided limit price.
|
|
311
|
+
Always provide as a string to avoid floating-point precision issues.`),
|
|
312
|
+
price: quantitySchema.describe(`Limit price as a string in quote currency.
|
|
313
|
+
This is the price at which you want to buy or sell.
|
|
314
|
+
Example: "6000000" means 60,00,000 INR for BTC-INR pair.
|
|
315
|
+
Always provide as a string to preserve precision.`),
|
|
316
|
+
clientOrderId: z.string().min(1).max(36).optional().describe(`Optional custom identifier for tracking your order.
|
|
317
|
+
Must contain only letters, numbers, dots, colons, slashes, underscores, and hyphens, and be 1-36 characters long.
|
|
318
|
+
Example: "my-limit-order-123"`),
|
|
319
|
+
platform: z.string().optional().describe(`Optional platform identifier for the order.`),
|
|
320
|
+
}, withLogging("spot_placeLimitOrder", config.logLevel, async ({ symbol, side, quoteOrderAmount, amount, price, clientOrderId, platform }) => {
|
|
321
|
+
const correlationId = generateCorrelationId();
|
|
322
|
+
const startTime = Date.now();
|
|
323
|
+
if (!spot) {
|
|
324
|
+
metricsCollector.record("zebpay_spot_placeLimitOrder", Date.now() - startTime, false, "missing_credentials");
|
|
325
|
+
throw createInvalidParamsError("API credentials are required for this operation. Please provide ZEBPAY_API_KEY and ZEBPAY_API_SECRET.", {});
|
|
326
|
+
}
|
|
327
|
+
// Validate that at least one of quoteOrderAmount or amount is provided
|
|
328
|
+
if (!quoteOrderAmount && !amount) {
|
|
329
|
+
metricsCollector.record("zebpay_spot_placeLimitOrder", Date.now() - startTime, false, "validation_error");
|
|
330
|
+
throw createInvalidParamsError("Either quoteOrderAmount or amount must be provided for limit orders.", { symbol, side });
|
|
331
|
+
}
|
|
332
|
+
// Validate that both are not provided
|
|
333
|
+
if (quoteOrderAmount && amount) {
|
|
334
|
+
metricsCollector.record("zebpay_spot_placeLimitOrder", Date.now() - startTime, false, "validation_error");
|
|
335
|
+
throw createInvalidParamsError("Cannot provide both quoteOrderAmount and amount. Please specify only one.", { symbol, side });
|
|
336
|
+
}
|
|
337
|
+
try {
|
|
338
|
+
validateSymbol(symbol);
|
|
339
|
+
validateQuantity(price);
|
|
340
|
+
if (quoteOrderAmount) {
|
|
341
|
+
validateQuantity(quoteOrderAmount);
|
|
342
|
+
}
|
|
343
|
+
if (amount) {
|
|
344
|
+
validateQuantity(amount);
|
|
345
|
+
}
|
|
346
|
+
if (clientOrderId) {
|
|
347
|
+
validateClientOrderId(clientOrderId);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
catch (error) {
|
|
351
|
+
metricsCollector.record("zebpay_spot_placeLimitOrder", Date.now() - startTime, false, "validation_error");
|
|
352
|
+
throw error;
|
|
353
|
+
}
|
|
354
|
+
// Helper function to trim to 6 decimals
|
|
355
|
+
const trimToSixDecimals = (value) => {
|
|
356
|
+
const num = parseFloat(value);
|
|
357
|
+
// Round to 6 decimals and remove trailing zeros
|
|
358
|
+
const fixed = num.toFixed(6);
|
|
359
|
+
// Remove trailing zeros after decimal point, but keep at least one digit
|
|
360
|
+
return fixed.replace(/(\.\d*?)0+$/, '$1').replace(/\.$/, '');
|
|
361
|
+
};
|
|
362
|
+
let finalQuoteOrderAmount;
|
|
363
|
+
let finalAmount;
|
|
364
|
+
const limitPrice = parseFloat(price.trim());
|
|
365
|
+
if (limitPrice === 0) {
|
|
366
|
+
metricsCollector.record("zebpay_spot_placeLimitOrder", Date.now() - startTime, false, "validation_error");
|
|
367
|
+
throw createInvalidParamsError("Price must be greater than 0", { symbol, side, price });
|
|
368
|
+
}
|
|
369
|
+
// Handle conversion based on side and provided parameter
|
|
370
|
+
if (side === "BUY") {
|
|
371
|
+
if (quoteOrderAmount) {
|
|
372
|
+
// User provided quote currency (INR) - use directly
|
|
373
|
+
finalQuoteOrderAmount = trimToSixDecimals(quoteOrderAmount.trim());
|
|
374
|
+
}
|
|
375
|
+
else if (amount) {
|
|
376
|
+
// User provided base currency (BTC) - convert to quote currency (INR) using limit price
|
|
377
|
+
const baseAmount = parseFloat(amount.trim());
|
|
378
|
+
const convertedQuoteAmount = baseAmount * limitPrice;
|
|
379
|
+
finalQuoteOrderAmount = trimToSixDecimals(convertedQuoteAmount.toString());
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
// SELL order
|
|
384
|
+
if (amount) {
|
|
385
|
+
// User provided base currency (BTC) - use directly
|
|
386
|
+
finalAmount = trimToSixDecimals(amount.trim());
|
|
387
|
+
}
|
|
388
|
+
else if (quoteOrderAmount) {
|
|
389
|
+
// User provided quote currency (INR) - convert to base currency (BTC) using limit price
|
|
390
|
+
const quoteAmount = parseFloat(quoteOrderAmount.trim());
|
|
391
|
+
const convertedBaseAmount = quoteAmount / limitPrice;
|
|
392
|
+
finalAmount = trimToSixDecimals(convertedBaseAmount.toString());
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
const params = {
|
|
396
|
+
symbol: symbol.trim().toUpperCase(),
|
|
397
|
+
side,
|
|
398
|
+
...(finalQuoteOrderAmount && { quoteOrderAmount: finalQuoteOrderAmount }),
|
|
399
|
+
...(finalAmount && { amount: finalAmount }),
|
|
400
|
+
price: price.trim(),
|
|
401
|
+
...(clientOrderId && { clientOrderId }),
|
|
402
|
+
...(platform && { platform }),
|
|
403
|
+
};
|
|
404
|
+
try {
|
|
405
|
+
const result = await spot.placeLimitOrder(params);
|
|
406
|
+
const durationMs = Date.now() - startTime;
|
|
407
|
+
metricsCollector.record("zebpay_spot_placeLimitOrder", durationMs, true);
|
|
408
|
+
return formatOrderResponse(result, {
|
|
409
|
+
correlationId,
|
|
410
|
+
executionTimeMs: durationMs,
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
catch (error) {
|
|
414
|
+
const durationMs = Date.now() - startTime;
|
|
415
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
416
|
+
metricsCollector.record("zebpay_spot_placeLimitOrder", durationMs, false, errorType);
|
|
417
|
+
if (error && typeof error === "object" && "code" in error)
|
|
418
|
+
throw error;
|
|
419
|
+
throw createInternalError(`Failed to place limit order: ${error instanceof Error ? error.message : String(error)}`, { symbol, side, quoteOrderAmount, amount, price });
|
|
420
|
+
}
|
|
421
|
+
}));
|
|
422
|
+
console.error("Registered tool: zebpay_spot_placeLimitOrder");
|
|
423
|
+
}
|
|
424
|
+
catch (error) {
|
|
425
|
+
console.error("Error registering zebpay_spot_placeLimitOrder:", error);
|
|
426
|
+
}
|
|
427
|
+
try {
|
|
428
|
+
server.tool("zebpay_spot_getBalance", `Fetch the user's spot trading account balance from Zebpay exchange.
|
|
429
|
+
|
|
430
|
+
This tool retrieves the current balance of cryptocurrencies and fiat currencies in the user's spot trading account. Use this before placing orders to check available funds.
|
|
431
|
+
|
|
432
|
+
**When to use this tool:**
|
|
433
|
+
- User asks about their account balance or available funds
|
|
434
|
+
- Before placing a buy order to verify sufficient funds
|
|
435
|
+
- User wants to check holdings of specific cryptocurrencies
|
|
436
|
+
- User asks "How much BTC do I have?" or "What's my balance?"
|
|
437
|
+
|
|
438
|
+
**Important notes:**
|
|
439
|
+
- Returns balances for all currencies by default
|
|
440
|
+
- Can filter to specific currencies using the currencies parameter
|
|
441
|
+
- Shows both available balance and any locked/held balance
|
|
442
|
+
- Balance is returned in the account's native format
|
|
443
|
+
|
|
444
|
+
**Example use cases:**
|
|
445
|
+
1. User says "Check my balance" → Call without currencies parameter to get all balances
|
|
446
|
+
2. User says "How much Bitcoin do I have?" → Use currencies="BTC" to filter
|
|
447
|
+
3. Before buying BTC → Check INR balance with currencies="INR"
|
|
448
|
+
4. User wants to see multiple currencies → Use currencies="BTC,ETH,INR"
|
|
449
|
+
|
|
450
|
+
**Example request (all balances):**
|
|
451
|
+
{}
|
|
452
|
+
|
|
453
|
+
**Example request (filtered):**
|
|
454
|
+
{
|
|
455
|
+
"currencies": "BTC,ETH,INR"
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
**Example response:**
|
|
459
|
+
Returns an object with balance information including available amounts, locked amounts, and currency codes for each currency in the account.
|
|
460
|
+
|
|
461
|
+
**Rate Limits:**
|
|
462
|
+
- Maximum 10 requests per second for authenticated endpoints
|
|
463
|
+
- Burst limit: 20 requests
|
|
464
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
465
|
+
- If rate limited, wait 1 second before retrying
|
|
466
|
+
|
|
467
|
+
**Related Tools:**
|
|
468
|
+
- Use before zebpay_spot_placeMarketOrder to verify sufficient funds
|
|
469
|
+
- Use zebpay_public_getTicker to check current prices for balance calculations
|
|
470
|
+
- Access balance as a resource via zebpay://account/balance`, {
|
|
471
|
+
currencies: z.string().optional().describe(`Optional comma-separated list of currency codes to filter the balance response.
|
|
472
|
+
If not provided, returns balances for all currencies in the account.
|
|
473
|
+
Format: "CURRENCY1,CURRENCY2,CURRENCY3" (no spaces, uppercase currency codes).
|
|
474
|
+
Examples:
|
|
475
|
+
- "BTC" (only Bitcoin balance)
|
|
476
|
+
- "BTC,ETH" (Bitcoin and Ethereum balances)
|
|
477
|
+
- "BTC,ETH,INR" (Bitcoin, Ethereum, and Indian Rupees balances)
|
|
478
|
+
- undefined or omit parameter (all currencies)
|
|
479
|
+
Use this to get specific currency balances when the user asks about particular assets.`),
|
|
480
|
+
}, withLogging("zebpay_spot_getBalance", config.logLevel, async ({ currencies }) => {
|
|
481
|
+
const correlationId = generateCorrelationId();
|
|
482
|
+
const startTime = Date.now();
|
|
483
|
+
// Check if credentials are available
|
|
484
|
+
if (!spot) {
|
|
485
|
+
metricsCollector.record("zebpay_spot_getBalance", Date.now() - startTime, false, "missing_credentials");
|
|
486
|
+
throw createInvalidParamsError("API credentials are required for this operation. Please provide ZEBPAY_API_KEY and ZEBPAY_API_SECRET headers or include credentials in initialization params.", {});
|
|
487
|
+
}
|
|
488
|
+
try {
|
|
489
|
+
const result = await spot.getBalance(currencies);
|
|
490
|
+
const durationMs = Date.now() - startTime;
|
|
491
|
+
metricsCollector.record("zebpay_spot_getBalance", durationMs, true);
|
|
492
|
+
return formatBalanceResponse(result, {
|
|
493
|
+
correlationId,
|
|
494
|
+
executionTimeMs: durationMs,
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
catch (error) {
|
|
498
|
+
const durationMs = Date.now() - startTime;
|
|
499
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
500
|
+
metricsCollector.record("zebpay_spot_getBalance", durationMs, false, errorType);
|
|
501
|
+
throw error;
|
|
502
|
+
}
|
|
503
|
+
}));
|
|
504
|
+
console.error("Registered tool: zebpay_spot_getBalance");
|
|
505
|
+
}
|
|
506
|
+
catch (error) {
|
|
507
|
+
console.error("Error registering spot_getBalance:", error);
|
|
508
|
+
}
|
|
509
|
+
try {
|
|
510
|
+
server.tool("zebpay_spot_getExchangeFee", `Get exchange fee details for a specific trading pair and order side.
|
|
511
|
+
|
|
512
|
+
This tool retrieves the maker and taker fee rates for a specific trading pair, including GST and TDS information. Use this to understand the fees that will be applied to your trades.
|
|
513
|
+
|
|
514
|
+
**When to use this tool:**
|
|
515
|
+
- User wants to know the trading fees for a specific pair
|
|
516
|
+
- User needs to calculate the cost of a trade before placing an order
|
|
517
|
+
- User wants to understand maker vs taker fee rates
|
|
518
|
+
- User needs to check GST and TDS percentages
|
|
519
|
+
|
|
520
|
+
**Important notes:**
|
|
521
|
+
- Requires authentication (API credentials)
|
|
522
|
+
- Returns maker fee rate (for limit orders that add liquidity)
|
|
523
|
+
- Returns taker fee rate (for orders that take liquidity immediately)
|
|
524
|
+
- Fee rates are typically in percentage format
|
|
525
|
+
- GST and TDS information is included in the response
|
|
526
|
+
|
|
527
|
+
**Example use cases:**
|
|
528
|
+
1. User says "What are the fees for BTC-INR?" → Use symbol="BTC-INR", side="BUY" (or "SELL")
|
|
529
|
+
2. User wants to know trading costs before buying ETH → Use symbol="ETH-INR", side="BUY"
|
|
530
|
+
|
|
531
|
+
**Example request:**
|
|
532
|
+
{
|
|
533
|
+
"symbol": "BTC-INR",
|
|
534
|
+
"side": "BUY"
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
**Example response:**
|
|
538
|
+
Returns fee details including maker/taker fee rates, whether fees are percentage-based, GST, and TDS.
|
|
539
|
+
|
|
540
|
+
Endpoint: GET /api/v2/ex/tradefee?symbol=SYMBOL&side=SIDE`, {
|
|
541
|
+
symbol: symbolSchema.describe(`Trading pair symbol in format BASE-QUOTE (required).
|
|
542
|
+
Examples: "BTC-INR", "ETH-INR", "BTC-USDT".`),
|
|
543
|
+
side: z.enum(["BUY", "SELL"]).describe(`Order side (required).
|
|
544
|
+
- "BUY": Get fees for buy orders
|
|
545
|
+
- "SELL": Get fees for sell orders`),
|
|
546
|
+
}, withLogging("zebpay_spot_getExchangeFee", config.logLevel, async ({ symbol, side }) => {
|
|
547
|
+
const correlationId = generateCorrelationId();
|
|
548
|
+
const startTime = Date.now();
|
|
549
|
+
if (!spot) {
|
|
550
|
+
metricsCollector.record("zebpay_spot_getExchangeFee", Date.now() - startTime, false, "missing_credentials");
|
|
551
|
+
throw createInvalidParamsError("API credentials are required for this operation. Please provide ZEBPAY_API_KEY and ZEBPAY_API_SECRET.", {});
|
|
552
|
+
}
|
|
553
|
+
try {
|
|
554
|
+
validateSymbol(symbol);
|
|
555
|
+
}
|
|
556
|
+
catch (error) {
|
|
557
|
+
metricsCollector.record("zebpay_spot_getExchangeFee", Date.now() - startTime, false, "validation_error");
|
|
558
|
+
throw error;
|
|
559
|
+
}
|
|
560
|
+
try {
|
|
561
|
+
const result = await spot.getExchangeFee({
|
|
562
|
+
symbol: symbol.trim().toUpperCase(),
|
|
563
|
+
side,
|
|
564
|
+
});
|
|
565
|
+
const durationMs = Date.now() - startTime;
|
|
566
|
+
metricsCollector.record("zebpay_spot_getExchangeFee", durationMs, true);
|
|
567
|
+
return formatResponse(result, {
|
|
568
|
+
correlationId,
|
|
569
|
+
executionTimeMs: durationMs,
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
catch (error) {
|
|
573
|
+
const durationMs = Date.now() - startTime;
|
|
574
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
575
|
+
metricsCollector.record("zebpay_spot_getExchangeFee", durationMs, false, errorType);
|
|
576
|
+
throw error;
|
|
577
|
+
}
|
|
578
|
+
}));
|
|
579
|
+
console.error("Registered tool: zebpay_spot_getExchangeFee");
|
|
580
|
+
}
|
|
581
|
+
catch (error) {
|
|
582
|
+
console.error("Error registering zebpay_spot_getExchangeFee:", error);
|
|
583
|
+
}
|
|
584
|
+
// Public API tools (always available, no credentials required)
|
|
585
|
+
console.error("Registering public tools (market data, tickers, order books)...");
|
|
586
|
+
try {
|
|
587
|
+
server.tool("zebpay_public_getAllTickers", `Get ticker/price information for all trading pairs on Zebpay exchange.
|
|
588
|
+
|
|
589
|
+
This tool retrieves the current market price, 24h statistics, and trading volume for all available trading pairs. No authentication required.
|
|
590
|
+
|
|
591
|
+
**When to use this tool:**
|
|
592
|
+
- User asks to see all market prices
|
|
593
|
+
- User wants to check prices for multiple trading pairs
|
|
594
|
+
- User says "Show me all prices" or "List all tickers"
|
|
595
|
+
- User wants an overview of all market data
|
|
596
|
+
|
|
597
|
+
**Important notes:**
|
|
598
|
+
- Returns ticker data for all trading pairs including last price, bid/ask, 24h high/low, volume
|
|
599
|
+
- Uses endpoint: api/v2/market/allTickers
|
|
600
|
+
- No authentication required - this is public market data
|
|
601
|
+
|
|
602
|
+
**Example use cases:**
|
|
603
|
+
1. User says "Show me all prices" → Call without parameters
|
|
604
|
+
2. User wants market overview → Use this tool
|
|
605
|
+
3. User asks "List all tickers" → Use this tool
|
|
606
|
+
|
|
607
|
+
**Example request:**
|
|
608
|
+
{}
|
|
609
|
+
|
|
610
|
+
**Example response:**
|
|
611
|
+
Returns ticker data for all trading pairs with current price, 24h statistics, trading volume, and price changes.
|
|
612
|
+
|
|
613
|
+
**Rate Limits:**
|
|
614
|
+
- Maximum 20 requests per second for public endpoints
|
|
615
|
+
- Burst limit: 40 requests
|
|
616
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
617
|
+
- Public endpoints have higher rate limits than authenticated endpoints
|
|
618
|
+
|
|
619
|
+
**Related Tools:**
|
|
620
|
+
- Use zebpay_public_getTicker for a specific trading pair
|
|
621
|
+
- Use zebpay_public_getOrderBook to see market depth
|
|
622
|
+
- Access all tickers as a resource via zebpay://market/tickers`, {}, withLogging("zebpay_public_getAllTickers", config.logLevel, async () => {
|
|
623
|
+
const correlationId = generateCorrelationId();
|
|
624
|
+
const startTime = Date.now();
|
|
625
|
+
try {
|
|
626
|
+
const result = await publicClient.getAllTickers();
|
|
627
|
+
const durationMs = Date.now() - startTime;
|
|
628
|
+
metricsCollector.record("zebpay_public_getAllTickers", durationMs, true);
|
|
629
|
+
return formatResponse(result, {
|
|
630
|
+
toolName: "zebpay_public_getAllTickers",
|
|
631
|
+
correlationId,
|
|
632
|
+
executionTimeMs: durationMs,
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
catch (error) {
|
|
636
|
+
const durationMs = Date.now() - startTime;
|
|
637
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
638
|
+
metricsCollector.record("zebpay_public_getAllTickers", durationMs, false, errorType);
|
|
639
|
+
throw error;
|
|
640
|
+
}
|
|
641
|
+
}));
|
|
642
|
+
console.error("Registered tool: zebpay_public_getAllTickers");
|
|
643
|
+
}
|
|
644
|
+
catch (error) {
|
|
645
|
+
console.error("Error registering public_getAllTickers:", error);
|
|
646
|
+
}
|
|
647
|
+
try {
|
|
648
|
+
server.tool("zebpay_public_getTicker", `Get ticker/price information for a specific trading pair on Zebpay exchange.
|
|
649
|
+
|
|
650
|
+
This tool retrieves the current market price, 24h statistics, and trading volume for a specific trading pair. No authentication required.
|
|
651
|
+
|
|
652
|
+
**When to use this tool:**
|
|
653
|
+
- User asks about current price of a specific cryptocurrency
|
|
654
|
+
- User wants to check market price or price changes for a symbol
|
|
655
|
+
- User asks "What's the price of BTC?" or "Show me ETH price"
|
|
656
|
+
- User wants ticker data for a specific trading pair
|
|
657
|
+
|
|
658
|
+
**Important notes:**
|
|
659
|
+
- Returns ticker data including last price, bid/ask, 24h high/low, volume
|
|
660
|
+
- Requires a specific symbol parameter
|
|
661
|
+
- Uses endpoint: api/v2/market/ticker?symbol={symbol}
|
|
662
|
+
- No authentication required - this is public market data
|
|
663
|
+
|
|
664
|
+
**Example use cases:**
|
|
665
|
+
1. User says "What's the price of Bitcoin?" → Use symbol="BTC-INR"
|
|
666
|
+
2. User asks "How much is ETH?" → Use symbol="ETH-INR"
|
|
667
|
+
3. User wants BTC price → Use symbol="BTC-INR"
|
|
668
|
+
|
|
669
|
+
**Example request:**
|
|
670
|
+
{
|
|
671
|
+
"symbol": "BTC-INR"
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
**Example response:**
|
|
675
|
+
Returns ticker data with current price, 24h statistics, trading volume, and price changes for the specified symbol.
|
|
676
|
+
|
|
677
|
+
**Rate Limits:**
|
|
678
|
+
- Maximum 20 requests per second for public endpoints
|
|
679
|
+
- Burst limit: 40 requests
|
|
680
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
681
|
+
- Public endpoints have higher rate limits than authenticated endpoints
|
|
682
|
+
|
|
683
|
+
**Related Tools:**
|
|
684
|
+
- Use zebpay_public_getAllTickers to get prices for all pairs at once
|
|
685
|
+
- Use zebpay_public_getOrderBook to see market depth and liquidity
|
|
686
|
+
- Use zebpay_public_getTrades to see recent trading activity
|
|
687
|
+
- Use before zebpay_spot_placeMarketOrder to check current market price`, {
|
|
688
|
+
symbol: symbolSchema.describe(`Trading pair symbol in format BASE-QUOTE (required).
|
|
689
|
+
Examples: "BTC-INR" (Bitcoin/Indian Rupees), "ETH-INR" (Ethereum/Indian Rupees), "BTC-USDT" (Bitcoin/Tether).
|
|
690
|
+
The symbol determines which market's ticker to retrieve.
|
|
691
|
+
Always use uppercase currency codes separated by a hyphen.`),
|
|
692
|
+
}, withLogging("zebpay_public_getTicker", config.logLevel, async ({ symbol }) => {
|
|
693
|
+
const correlationId = generateCorrelationId();
|
|
694
|
+
const startTime = Date.now();
|
|
695
|
+
try {
|
|
696
|
+
validateSymbol(symbol);
|
|
697
|
+
}
|
|
698
|
+
catch (error) {
|
|
699
|
+
metricsCollector.record("zebpay_public_getTicker", Date.now() - startTime, false, "validation_error");
|
|
700
|
+
throw error;
|
|
701
|
+
}
|
|
702
|
+
try {
|
|
703
|
+
const result = await publicClient.getTicker({ symbol: symbol.trim().toUpperCase() });
|
|
704
|
+
const durationMs = Date.now() - startTime;
|
|
705
|
+
metricsCollector.record("zebpay_public_getTicker", durationMs, true);
|
|
706
|
+
return formatTickerResponse(result, {
|
|
707
|
+
correlationId,
|
|
708
|
+
executionTimeMs: durationMs,
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
catch (error) {
|
|
712
|
+
const durationMs = Date.now() - startTime;
|
|
713
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
714
|
+
metricsCollector.record("zebpay_public_getTicker", durationMs, false, errorType);
|
|
715
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
716
|
+
throw error;
|
|
717
|
+
}
|
|
718
|
+
throw createInternalError(`Failed to get ticker: ${error instanceof Error ? error.message : String(error)}`, { symbol });
|
|
719
|
+
}
|
|
720
|
+
}));
|
|
721
|
+
console.error("Registered tool: zebpay_public_getTicker");
|
|
722
|
+
}
|
|
723
|
+
catch (error) {
|
|
724
|
+
console.error("Error registering public_getTicker:", error);
|
|
725
|
+
}
|
|
726
|
+
try {
|
|
727
|
+
server.tool("zebpay_public_getOrderBook", `Get order book (market depth) for a trading pair on Zebpay exchange.
|
|
728
|
+
|
|
729
|
+
This tool retrieves the current buy and sell orders (bids and asks) for a specific trading pair, showing market depth and liquidity. No authentication required.
|
|
730
|
+
|
|
731
|
+
**When to use this tool:**
|
|
732
|
+
- User asks about order book or market depth
|
|
733
|
+
- User wants to see buy/sell orders for a trading pair
|
|
734
|
+
- User asks "Show me the order book for BTC" or "What's the market depth?"
|
|
735
|
+
- Before placing a large order to check liquidity
|
|
736
|
+
|
|
737
|
+
**Important notes:**
|
|
738
|
+
- Shows bids (buy orders) and asks (sell orders) with prices and quantities
|
|
739
|
+
- Can limit the depth using the limit parameter
|
|
740
|
+
- Uses endpoint: api/v2/market/orderbook?symbol={symbol}&limit={limit}
|
|
741
|
+
- No authentication required - this is public market data
|
|
742
|
+
|
|
743
|
+
**Example use cases:**
|
|
744
|
+
1. User says "Show me order book for BTC" → Use symbol="BTC-INR"
|
|
745
|
+
2. User wants to check market depth → Use symbol with optional limit
|
|
746
|
+
3. User asks "What are the current buy and sell orders?" → Use symbol parameter
|
|
747
|
+
|
|
748
|
+
**Example request:**
|
|
749
|
+
{
|
|
750
|
+
"symbol": "BTC-INR",
|
|
751
|
+
"limit": 10
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
**Example response:**
|
|
755
|
+
Returns order book data with bids (buy orders) and asks (sell orders), showing price levels and quantities at each level.
|
|
756
|
+
|
|
757
|
+
**Rate Limits:**
|
|
758
|
+
- Maximum 20 requests per second for public endpoints
|
|
759
|
+
- Burst limit: 40 requests
|
|
760
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
761
|
+
- Lower limit values return faster responses
|
|
762
|
+
|
|
763
|
+
**Related Tools:**
|
|
764
|
+
- Use zebpay_public_getTicker to get current price summary
|
|
765
|
+
- Use zebpay_public_getOrderBookTicker for lightweight best bid/ask prices
|
|
766
|
+
- Use zebpay_public_getTrades to see recent executed trades
|
|
767
|
+
- Use before placing large orders to assess market liquidity`, {
|
|
768
|
+
symbol: symbolSchema.describe(`Trading pair symbol in format BASE-QUOTE (required).
|
|
769
|
+
Examples: "BTC-INR" (Bitcoin/Indian Rupees), "ETH-INR" (Ethereum/Indian Rupees).
|
|
770
|
+
The symbol determines which market's order book to retrieve.
|
|
771
|
+
Always use uppercase currency codes separated by a hyphen.`),
|
|
772
|
+
limit: z.number().int().positive().optional().describe(`Optional limit for the number of price levels to return (positive integer).
|
|
773
|
+
**Default behavior:** If not provided, returns default depth (usually 100 levels).
|
|
774
|
+
**Performance:** Lower limits return fewer levels but provide faster responses.
|
|
775
|
+
**Examples:** 10 (top 10 bids/asks), 20 (top 20 bids/asks), 100 (full depth).
|
|
776
|
+
**Use case:** Use lower limits for quick overview, higher limits for detailed market depth analysis.`),
|
|
777
|
+
}, withLogging("zebpay_public_getOrderBook", config.logLevel, async ({ symbol, limit }) => {
|
|
778
|
+
const correlationId = generateCorrelationId();
|
|
779
|
+
const startTime = Date.now();
|
|
780
|
+
try {
|
|
781
|
+
validateSymbol(symbol);
|
|
782
|
+
}
|
|
783
|
+
catch (error) {
|
|
784
|
+
metricsCollector.record("zebpay_public_getOrderBook", Date.now() - startTime, false, "validation_error");
|
|
785
|
+
throw error;
|
|
786
|
+
}
|
|
787
|
+
try {
|
|
788
|
+
const result = await publicClient.getOrderBook({ symbol: symbol.trim().toUpperCase(), limit });
|
|
789
|
+
const durationMs = Date.now() - startTime;
|
|
790
|
+
metricsCollector.record("zebpay_public_getOrderBook", durationMs, true);
|
|
791
|
+
return formatOrderBookResponse(result, {
|
|
792
|
+
toolName: "zebpay_public_getOrderBook",
|
|
793
|
+
correlationId,
|
|
794
|
+
executionTimeMs: durationMs,
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
catch (error) {
|
|
798
|
+
const durationMs = Date.now() - startTime;
|
|
799
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
800
|
+
metricsCollector.record("zebpay_public_getOrderBook", durationMs, false, errorType);
|
|
801
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
802
|
+
throw error;
|
|
803
|
+
}
|
|
804
|
+
throw createInternalError(`Failed to get order book: ${error instanceof Error ? error.message : String(error)}`, { symbol, limit });
|
|
805
|
+
}
|
|
806
|
+
}));
|
|
807
|
+
console.error("Registered tool: zebpay_public_getOrderBook");
|
|
808
|
+
}
|
|
809
|
+
catch (error) {
|
|
810
|
+
console.error("Error registering public_getOrderBook:", error);
|
|
811
|
+
}
|
|
812
|
+
try {
|
|
813
|
+
server.tool("zebpay_public_getOrderBookTicker", `Get order book ticker for a trading pair on Zebpay exchange.
|
|
814
|
+
|
|
815
|
+
This tool retrieves the best bid and ask prices (ticker) from the order book for a specific trading pair. This is a lightweight endpoint that returns only the top-of-book prices without the full order book depth. No authentication required.
|
|
816
|
+
|
|
817
|
+
**When to use this tool:**
|
|
818
|
+
- User asks about best bid/ask prices
|
|
819
|
+
- User wants to see the current best buy and sell prices
|
|
820
|
+
- User asks "What's the best bid and ask for BTC?" or "Show me the order book ticker"
|
|
821
|
+
- User wants a quick price check without full order book data
|
|
822
|
+
|
|
823
|
+
**Important notes:**
|
|
824
|
+
- Returns best bid (highest buy order) and best ask (lowest sell order) prices
|
|
825
|
+
- Lightweight endpoint - faster than full order book
|
|
826
|
+
- Uses endpoint: api/v2/market/orderbook/ticker?symbol={symbol}
|
|
827
|
+
- No authentication required - this is public market data
|
|
828
|
+
|
|
829
|
+
**Example use cases:**
|
|
830
|
+
1. User says "Show me best bid/ask for BTC" → Use symbol="BTC-INR"
|
|
831
|
+
2. User wants quick price check → Use this tool instead of full order book
|
|
832
|
+
3. User asks "What are the current best prices?" → Use symbol parameter
|
|
833
|
+
|
|
834
|
+
**Example request:**
|
|
835
|
+
{
|
|
836
|
+
"symbol": "BTC-INR"
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
**Example response:**
|
|
840
|
+
Returns order book ticker data with best bid price, best ask price, and related market information.
|
|
841
|
+
|
|
842
|
+
**Rate Limits:**
|
|
843
|
+
- Maximum 20 requests per second for public endpoints
|
|
844
|
+
- Burst limit: 40 requests
|
|
845
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
846
|
+
- This is a lightweight endpoint, faster than full order book
|
|
847
|
+
|
|
848
|
+
**Related Tools:**
|
|
849
|
+
- Use zebpay_public_getOrderBook for full market depth
|
|
850
|
+
- Use zebpay_public_getTicker for comprehensive price information
|
|
851
|
+
- Use for quick price checks before trading`, {
|
|
852
|
+
symbol: symbolSchema.describe(`Trading pair symbol in format BASE-QUOTE (required).
|
|
853
|
+
Examples: "BTC-INR" (Bitcoin/Indian Rupees), "ETH-INR" (Ethereum/Indian Rupees).
|
|
854
|
+
The symbol determines which market's order book ticker to retrieve.
|
|
855
|
+
Always use uppercase currency codes separated by a hyphen.`),
|
|
856
|
+
}, withLogging("zebpay_public_getOrderBookTicker", config.logLevel, async ({ symbol }) => {
|
|
857
|
+
const correlationId = generateCorrelationId();
|
|
858
|
+
const startTime = Date.now();
|
|
859
|
+
try {
|
|
860
|
+
validateSymbol(symbol);
|
|
861
|
+
}
|
|
862
|
+
catch (error) {
|
|
863
|
+
metricsCollector.record("zebpay_public_getOrderBookTicker", Date.now() - startTime, false, "validation_error");
|
|
864
|
+
throw error;
|
|
865
|
+
}
|
|
866
|
+
try {
|
|
867
|
+
const result = await publicClient.getOrderBookTicker({ symbol: symbol.trim().toUpperCase() });
|
|
868
|
+
const durationMs = Date.now() - startTime;
|
|
869
|
+
metricsCollector.record("zebpay_public_getOrderBookTicker", durationMs, true);
|
|
870
|
+
return formatResponse(result, {
|
|
871
|
+
toolName: "zebpay_public_getOrderBookTicker",
|
|
872
|
+
correlationId,
|
|
873
|
+
executionTimeMs: durationMs,
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
catch (error) {
|
|
877
|
+
const durationMs = Date.now() - startTime;
|
|
878
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
879
|
+
metricsCollector.record("zebpay_public_getOrderBookTicker", durationMs, false, errorType);
|
|
880
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
881
|
+
throw error;
|
|
882
|
+
}
|
|
883
|
+
throw createInternalError(`Failed to get order book ticker: ${error instanceof Error ? error.message : String(error)}`, { symbol });
|
|
884
|
+
}
|
|
885
|
+
}));
|
|
886
|
+
console.error("Registered tool: zebpay_public_getOrderBookTicker");
|
|
887
|
+
}
|
|
888
|
+
catch (error) {
|
|
889
|
+
console.error("Error registering public_getOrderBookTicker:", error);
|
|
890
|
+
}
|
|
891
|
+
try {
|
|
892
|
+
server.tool("zebpay_public_getTrades", `Get recent trades/transactions for a trading pair on Zebpay exchange.
|
|
893
|
+
|
|
894
|
+
This tool retrieves the most recent trades executed on the exchange for a specific trading pair, showing price, quantity, and time. Supports pagination for accessing older trades. No authentication required.
|
|
895
|
+
|
|
896
|
+
**When to use this tool:**
|
|
897
|
+
- User asks about recent trades or transaction history
|
|
898
|
+
- User wants to see recent market activity
|
|
899
|
+
- User asks "Show me recent BTC trades" or "What trades happened?"
|
|
900
|
+
- User wants to analyze trading activity
|
|
901
|
+
- User wants to paginate through historical trades
|
|
902
|
+
|
|
903
|
+
**Important notes:**
|
|
904
|
+
- Shows recent trades with price, quantity, side (buy/sell), and timestamp
|
|
905
|
+
- Can limit the number of trades returned per page
|
|
906
|
+
- Supports pagination with the page parameter
|
|
907
|
+
- Uses endpoint: api/v2/market/trades?symbol={symbol}&limit={limit}&page={page}
|
|
908
|
+
- No authentication required - this is public market data
|
|
909
|
+
|
|
910
|
+
**Example use cases:**
|
|
911
|
+
1. User says "Show me recent BTC trades" → Use symbol="BTC-INR"
|
|
912
|
+
2. User wants to see market activity → Use symbol with optional limit
|
|
913
|
+
3. User asks "What trades happened recently?" → Use symbol parameter
|
|
914
|
+
4. User wants page 2 of trades → Use symbol="BTC-INR", limit=50, page=2
|
|
915
|
+
|
|
916
|
+
**Example request:**
|
|
917
|
+
{
|
|
918
|
+
"symbol": "BTC-INR",
|
|
919
|
+
"limit": 50,
|
|
920
|
+
"page": 1
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
**Example response:**
|
|
924
|
+
Returns array of recent trades with price, quantity, side (buy/sell), and timestamp for each trade.
|
|
925
|
+
|
|
926
|
+
**Rate Limits:**
|
|
927
|
+
- Maximum 20 requests per second for public endpoints
|
|
928
|
+
- Burst limit: 40 requests
|
|
929
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
930
|
+
- Use pagination (page parameter) to access historical trades efficiently
|
|
931
|
+
|
|
932
|
+
**Related Tools:**
|
|
933
|
+
- Use zebpay_public_getTicker to get current price summary
|
|
934
|
+
- Use zebpay_public_getOrderBook to see pending orders
|
|
935
|
+
- Use zebpay_public_getKlines for historical price analysis`, {
|
|
936
|
+
symbol: symbolSchema.describe(`Trading pair symbol in format BASE-QUOTE (required).
|
|
937
|
+
Examples: "BTC-INR" (Bitcoin/Indian Rupees), "ETH-INR" (Ethereum/Indian Rupees).
|
|
938
|
+
The symbol determines which market's trades to retrieve.
|
|
939
|
+
Always use uppercase currency codes separated by a hyphen.`),
|
|
940
|
+
limit: z.number().int().positive().optional().describe(`Optional limit for the number of recent trades to return per page (positive integer).
|
|
941
|
+
**Default behavior:** If not provided, returns default number (usually 100 trades).
|
|
942
|
+
**Performance:** Lower limits return fewer trades but provide faster responses.
|
|
943
|
+
**Examples:** 10 (last 10 trades), 50 (last 50 trades), 100 (last 100 trades).
|
|
944
|
+
**Use case:** Combine with page parameter for pagination. Use lower limits for quick market activity overview.`),
|
|
945
|
+
page: z.number().int().positive().optional().describe(`Optional page number for pagination (positive integer, starts from 1).
|
|
946
|
+
**Default behavior:** If not provided, returns the first page of results (page 1).
|
|
947
|
+
**Pagination:** Use this to access older trades beyond the first page.
|
|
948
|
+
**Examples:** 1 (first page), 2 (second page), 3 (third page).
|
|
949
|
+
**Use case:** Combine with limit parameter to control how many trades per page. Use page=1 for most recent trades, higher page numbers for historical data.`),
|
|
950
|
+
}, withLogging("zebpay_public_getTrades", config.logLevel, async ({ symbol, limit, page }) => {
|
|
951
|
+
const correlationId = generateCorrelationId();
|
|
952
|
+
const startTime = Date.now();
|
|
953
|
+
try {
|
|
954
|
+
validateSymbol(symbol);
|
|
955
|
+
}
|
|
956
|
+
catch (error) {
|
|
957
|
+
metricsCollector.record("zebpay_public_getTrades", Date.now() - startTime, false, "validation_error");
|
|
958
|
+
throw error;
|
|
959
|
+
}
|
|
960
|
+
try {
|
|
961
|
+
const result = await publicClient.getTrades({ symbol: symbol.trim().toUpperCase(), limit, page });
|
|
962
|
+
const durationMs = Date.now() - startTime;
|
|
963
|
+
metricsCollector.record("zebpay_public_getTrades", durationMs, true);
|
|
964
|
+
return formatTradesResponse(result, {
|
|
965
|
+
toolName: "zebpay_public_getTrades",
|
|
966
|
+
correlationId,
|
|
967
|
+
executionTimeMs: durationMs,
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
catch (error) {
|
|
971
|
+
const durationMs = Date.now() - startTime;
|
|
972
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
973
|
+
metricsCollector.record("zebpay_public_getTrades", durationMs, false, errorType);
|
|
974
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
975
|
+
throw error;
|
|
976
|
+
}
|
|
977
|
+
throw createInternalError(`Failed to get trades: ${error instanceof Error ? error.message : String(error)}`, { symbol, limit, page });
|
|
978
|
+
}
|
|
979
|
+
}));
|
|
980
|
+
console.error("Registered tool: zebpay_public_getTrades");
|
|
981
|
+
}
|
|
982
|
+
catch (error) {
|
|
983
|
+
console.error("Error registering public_getTrades:", error);
|
|
984
|
+
}
|
|
985
|
+
try {
|
|
986
|
+
server.tool("zebpay_public_getKlines", `Get candlestick/K-line data for a trading pair on Zebpay exchange.
|
|
987
|
+
|
|
988
|
+
This tool retrieves historical price data in candlestick format (OHLCV: Open, High, Low, Close, Volume) for charting and analysis. Requires a time range to be specified. Supports optional filtering by category. No authentication required.
|
|
989
|
+
|
|
990
|
+
**When to use this tool:**
|
|
991
|
+
- User asks about price history or charts
|
|
992
|
+
- User wants to analyze price trends over time
|
|
993
|
+
- User asks "Show me BTC price history" or "What was the price last week?"
|
|
994
|
+
- User wants candlestick data for technical analysis
|
|
995
|
+
- User wants spot or futures market data
|
|
996
|
+
|
|
997
|
+
**Important notes:**
|
|
998
|
+
- Returns OHLCV (Open, High, Low, Close, Volume) data
|
|
999
|
+
- Supports different time intervals (1m, 5m, 15m, 1h, 1d, etc.)
|
|
1000
|
+
- Requires startTime and endTime to specify the time range (in seconds since epoch)
|
|
1001
|
+
- Supports optional category parameter to specify market type (e.g., "spot")
|
|
1002
|
+
- Uses endpoint: api/v2/market/klines?symbol={symbol}&interval={interval}&startTime={startTime}&endTime={endTime}&category={category}
|
|
1003
|
+
- No authentication required - this is public market data
|
|
1004
|
+
|
|
1005
|
+
**Example use cases:**
|
|
1006
|
+
1. User says "Show me BTC price history" → Use symbol="BTC-INR", interval="1h", startTime and endTime
|
|
1007
|
+
2. User wants daily charts → Use interval="1d" with time range
|
|
1008
|
+
3. User asks "What was the price last week?" → Use interval="1d" with time range
|
|
1009
|
+
4. User wants spot market data → Use category="spot"
|
|
1010
|
+
|
|
1011
|
+
**Example request:**
|
|
1012
|
+
{
|
|
1013
|
+
"symbol": "BTC-INR",
|
|
1014
|
+
"interval": "15m",
|
|
1015
|
+
"startTime": 1756634020,
|
|
1016
|
+
"endTime": 1756740279,
|
|
1017
|
+
"category": "spot"
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
**Example response:**
|
|
1021
|
+
Returns array of candlestick data with open, high, low, close prices and volume for each time period.
|
|
1022
|
+
|
|
1023
|
+
**Rate Limits:**
|
|
1024
|
+
- Maximum 20 requests per second for public endpoints
|
|
1025
|
+
- Burst limit: 40 requests
|
|
1026
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
1027
|
+
- Larger time ranges may require multiple requests with pagination
|
|
1028
|
+
|
|
1029
|
+
**Related Tools:**
|
|
1030
|
+
- Use zebpay_public_getTicker for current price information
|
|
1031
|
+
- Use zebpay_public_getTrades to see recent trading activity
|
|
1032
|
+
- Use zebpay_public_getOrderBook to analyze current market depth
|
|
1033
|
+
- Combine with zebpay_public_getTicker for comprehensive market analysis`, {
|
|
1034
|
+
symbol: symbolSchema.describe(`Trading pair symbol in format BASE-QUOTE (required).
|
|
1035
|
+
Examples: "BTC-INR" (Bitcoin/Indian Rupees), "ETH-INR" (Ethereum/Indian Rupees).
|
|
1036
|
+
The symbol determines which market's data to retrieve.
|
|
1037
|
+
Always use uppercase currency codes separated by a hyphen.`),
|
|
1038
|
+
interval: z.string().min(1).describe(`Time interval for each candlestick (required).
|
|
1039
|
+
Common intervals: "1m" (1 minute), "5m" (5 minutes), "15m" (15 minutes), "1h" (1 hour), "4h" (4 hours), "1d" (1 day), "1w" (1 week).
|
|
1040
|
+
The interval determines the granularity of the price data.
|
|
1041
|
+
Examples: "1m" for minute-by-minute data, "1d" for daily data.`),
|
|
1042
|
+
startTime: z.number().describe(`Start timestamp in seconds since epoch (required).
|
|
1043
|
+
Returns candlesticks starting from this time.
|
|
1044
|
+
Use with endTime to get data for a specific time range.
|
|
1045
|
+
Example: 1756634020`),
|
|
1046
|
+
endTime: z.number().describe(`End timestamp in seconds since epoch (required).
|
|
1047
|
+
Returns candlesticks up to this time.
|
|
1048
|
+
Use with startTime to get data for a specific time range.
|
|
1049
|
+
Example: 1756740279`),
|
|
1050
|
+
limit: z.number().int().positive().optional().describe(`Optional limit for the number of candlesticks to return (positive integer).
|
|
1051
|
+
**Default behavior:** If not provided, returns default number (usually 500 candlesticks).
|
|
1052
|
+
**Performance:** Lower limits return fewer data points but provide faster responses.
|
|
1053
|
+
**Examples:** 100 (last 100 candles), 500 (last 500 candles).
|
|
1054
|
+
**Use case:** Use lower limits for quick price history overview, higher limits for detailed technical analysis. Consider time range (startTime/endTime) when setting limit.`),
|
|
1055
|
+
category: z.string().optional().describe(`Optional category parameter to specify market type (string).
|
|
1056
|
+
**Default behavior:** If not provided, returns default market data.
|
|
1057
|
+
**Common values:** "spot" (spot trading market).
|
|
1058
|
+
**Use case:** Use this to filter data by market category. For spot trading analysis, use category="spot".`),
|
|
1059
|
+
}, withLogging("zebpay_public_getKlines", config.logLevel, async ({ symbol, interval, limit, startTime, endTime, category }) => {
|
|
1060
|
+
const correlationId = generateCorrelationId();
|
|
1061
|
+
const executionStartTime = Date.now();
|
|
1062
|
+
try {
|
|
1063
|
+
validateSymbol(symbol);
|
|
1064
|
+
}
|
|
1065
|
+
catch (error) {
|
|
1066
|
+
metricsCollector.record("zebpay_public_getKlines", Date.now() - executionStartTime, false, "validation_error");
|
|
1067
|
+
throw error;
|
|
1068
|
+
}
|
|
1069
|
+
try {
|
|
1070
|
+
const result = await publicClient.getKlines({
|
|
1071
|
+
symbol: symbol.trim().toUpperCase(),
|
|
1072
|
+
interval,
|
|
1073
|
+
startTime,
|
|
1074
|
+
endTime,
|
|
1075
|
+
limit,
|
|
1076
|
+
category,
|
|
1077
|
+
});
|
|
1078
|
+
const durationMs = Date.now() - executionStartTime;
|
|
1079
|
+
metricsCollector.record("zebpay_public_getKlines", durationMs, true);
|
|
1080
|
+
return formatKlinesResponse(result, {
|
|
1081
|
+
toolName: "zebpay_public_getKlines",
|
|
1082
|
+
correlationId,
|
|
1083
|
+
executionTimeMs: durationMs,
|
|
1084
|
+
});
|
|
1085
|
+
}
|
|
1086
|
+
catch (error) {
|
|
1087
|
+
const durationMs = Date.now() - executionStartTime;
|
|
1088
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
1089
|
+
metricsCollector.record("zebpay_public_getKlines", durationMs, false, errorType);
|
|
1090
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
1091
|
+
throw error;
|
|
1092
|
+
}
|
|
1093
|
+
throw createInternalError(`Failed to get klines: ${error instanceof Error ? error.message : String(error)}`, { symbol, interval, startTime, endTime });
|
|
1094
|
+
}
|
|
1095
|
+
}));
|
|
1096
|
+
console.error("Registered tool: zebpay_public_getKlines");
|
|
1097
|
+
}
|
|
1098
|
+
catch (error) {
|
|
1099
|
+
console.error("Error registering public_getKlines:", error);
|
|
1100
|
+
}
|
|
1101
|
+
try {
|
|
1102
|
+
server.tool("zebpay_public_getExchangeInfo", `Get exchange information including trading rules, symbols, and filters.
|
|
1103
|
+
|
|
1104
|
+
This tool retrieves general information about the Zebpay exchange, including available trading pairs, trading rules, order limits, and other exchange metadata. No authentication required.
|
|
1105
|
+
|
|
1106
|
+
**When to use this tool:**
|
|
1107
|
+
- User asks about available trading pairs
|
|
1108
|
+
- User wants to know exchange rules or limits
|
|
1109
|
+
- User asks "What pairs can I trade?" or "What are the trading rules?"
|
|
1110
|
+
- User needs to check symbol information before trading
|
|
1111
|
+
|
|
1112
|
+
**Important notes:**
|
|
1113
|
+
- Returns exchange-wide information including all trading pairs
|
|
1114
|
+
- Includes trading rules, filters, and limits
|
|
1115
|
+
- No authentication required - this is public exchange information
|
|
1116
|
+
|
|
1117
|
+
**Example use cases:**
|
|
1118
|
+
1. User says "What pairs are available?" → Call without parameters
|
|
1119
|
+
2. User wants to check trading rules → Call to get exchange info
|
|
1120
|
+
3. User asks "What can I trade?" → Use this tool
|
|
1121
|
+
|
|
1122
|
+
**Example request:**
|
|
1123
|
+
{}
|
|
1124
|
+
|
|
1125
|
+
**Example response:**
|
|
1126
|
+
Returns exchange information including available symbols, trading rules, order limits, and other exchange metadata.
|
|
1127
|
+
|
|
1128
|
+
**Rate Limits:**
|
|
1129
|
+
- Maximum 20 requests per second for public endpoints
|
|
1130
|
+
- Burst limit: 40 requests
|
|
1131
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
1132
|
+
- This data changes infrequently, consider caching results
|
|
1133
|
+
|
|
1134
|
+
**Related Tools:**
|
|
1135
|
+
- Use zebpay_public_getCurrencies to see supported currencies
|
|
1136
|
+
- Use zebpay_public_getAllTickers to see all available trading pairs
|
|
1137
|
+
- Access exchange info as a resource via zebpay://exchange/info`, {}, withLogging("zebpay_public_getExchangeInfo", config.logLevel, async () => {
|
|
1138
|
+
const correlationId = generateCorrelationId();
|
|
1139
|
+
const startTime = Date.now();
|
|
1140
|
+
try {
|
|
1141
|
+
const result = await publicClient.getExchangeInfo();
|
|
1142
|
+
const durationMs = Date.now() - startTime;
|
|
1143
|
+
metricsCollector.record("zebpay_public_getExchangeInfo", durationMs, true);
|
|
1144
|
+
return formatResponse(result, {
|
|
1145
|
+
toolName: "zebpay_public_getExchangeInfo",
|
|
1146
|
+
correlationId,
|
|
1147
|
+
executionTimeMs: durationMs,
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
catch (error) {
|
|
1151
|
+
const durationMs = Date.now() - startTime;
|
|
1152
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
1153
|
+
metricsCollector.record("zebpay_public_getExchangeInfo", durationMs, false, errorType);
|
|
1154
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
1155
|
+
throw error;
|
|
1156
|
+
}
|
|
1157
|
+
throw createInternalError(`Failed to get exchange info: ${error instanceof Error ? error.message : String(error)}`, {});
|
|
1158
|
+
}
|
|
1159
|
+
}));
|
|
1160
|
+
console.error("Registered tool: zebpay_public_getExchangeInfo");
|
|
1161
|
+
}
|
|
1162
|
+
catch (error) {
|
|
1163
|
+
console.error("Error registering public_getExchangeInfo:", error);
|
|
1164
|
+
}
|
|
1165
|
+
try {
|
|
1166
|
+
server.tool("zebpay_public_getCurrencies", `Get list of supported currencies and tokens on Zebpay exchange.
|
|
1167
|
+
|
|
1168
|
+
This tool retrieves a comprehensive list of all supported currencies and tokens, including their details such as precision, type (crypto/fiat), withdrawal/deposit settings, supported blockchain chains, fees, and limits. No authentication required.
|
|
1169
|
+
|
|
1170
|
+
**When to use this tool:**
|
|
1171
|
+
- User asks about supported currencies or tokens
|
|
1172
|
+
- User wants to see what currencies are available
|
|
1173
|
+
- User asks "What currencies does Zebpay support?" or "List all currencies"
|
|
1174
|
+
- User needs to check withdrawal/deposit limits or fees
|
|
1175
|
+
- User wants to verify if a specific currency is supported
|
|
1176
|
+
- User needs information about supported blockchain chains for a currency
|
|
1177
|
+
|
|
1178
|
+
**Important notes:**
|
|
1179
|
+
- Returns detailed information about each currency including:
|
|
1180
|
+
- Currency code, name, and full name
|
|
1181
|
+
- Precision and type (crypto/fiat)
|
|
1182
|
+
- Withdrawal and deposit settings
|
|
1183
|
+
- Supported blockchain chains with fees and limits
|
|
1184
|
+
- Contract addresses for tokens
|
|
1185
|
+
- Address validation regex patterns
|
|
1186
|
+
- Uses endpoint: api/v2/ex/currencies
|
|
1187
|
+
- No authentication required - this is public exchange information
|
|
1188
|
+
|
|
1189
|
+
**Example use cases:**
|
|
1190
|
+
1. User says "What currencies are supported?" → Call without parameters
|
|
1191
|
+
2. User wants to check BTC details → Use this tool to find BTC information
|
|
1192
|
+
3. User asks "Can I deposit ETH?" → Use this tool to check ETH deposit settings
|
|
1193
|
+
4. User wants withdrawal fees → Use this tool to see fees for each chain
|
|
1194
|
+
5. User asks "What chains support USDT?" → Use this tool to see USDT chain details
|
|
1195
|
+
|
|
1196
|
+
**Example request:**
|
|
1197
|
+
{}
|
|
1198
|
+
|
|
1199
|
+
**Example response:**
|
|
1200
|
+
Returns array of currency objects with details including:
|
|
1201
|
+
- currency: Currency code (e.g., "BTC")
|
|
1202
|
+
- name: Currency name
|
|
1203
|
+
- fullName: Full currency name (e.g., "Bitcoin")
|
|
1204
|
+
- precision: Decimal precision
|
|
1205
|
+
- type: Currency type (e.g., "crypto")
|
|
1206
|
+
- isDebitEnabled: Whether debit is enabled
|
|
1207
|
+
- chains: Array of supported blockchain chains with:
|
|
1208
|
+
- chainName: Name of the blockchain
|
|
1209
|
+
- withdrawalMinSize: Minimum withdrawal amount
|
|
1210
|
+
- depositMinSize: Minimum deposit amount
|
|
1211
|
+
- withdrawalFee: Fee for withdrawals
|
|
1212
|
+
- isWithdrawEnabled: Whether withdrawals are enabled
|
|
1213
|
+
- isDepositEnabled: Whether deposits are enabled
|
|
1214
|
+
- contractAddress: Contract address (for tokens)
|
|
1215
|
+
- withdrawPrecision: Withdrawal precision
|
|
1216
|
+
- maxWithdraw: Maximum withdrawal amount
|
|
1217
|
+
- maxDeposit: Maximum deposit amount
|
|
1218
|
+
- needTag: Whether tag/memo is required
|
|
1219
|
+
- chainId: Chain identifier
|
|
1220
|
+
- AddressRegex: Address validation regex pattern
|
|
1221
|
+
|
|
1222
|
+
**Rate Limits:**
|
|
1223
|
+
- Maximum 20 requests per second for public endpoints
|
|
1224
|
+
- Burst limit: 40 requests
|
|
1225
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
1226
|
+
- This data changes infrequently, consider caching results
|
|
1227
|
+
|
|
1228
|
+
**Related Tools:**
|
|
1229
|
+
- Use zebpay_public_getExchangeInfo to see trading pairs and rules
|
|
1230
|
+
- Access currencies as a resource via zebpay://currencies`, {}, withLogging("zebpay_public_getCurrencies", config.logLevel, async () => {
|
|
1231
|
+
const correlationId = generateCorrelationId();
|
|
1232
|
+
const startTime = Date.now();
|
|
1233
|
+
try {
|
|
1234
|
+
const result = await publicClient.getCurrencies();
|
|
1235
|
+
const durationMs = Date.now() - startTime;
|
|
1236
|
+
metricsCollector.record("zebpay_public_getCurrencies", durationMs, true);
|
|
1237
|
+
return formatResponse(result, {
|
|
1238
|
+
toolName: "zebpay_public_getCurrencies",
|
|
1239
|
+
correlationId,
|
|
1240
|
+
executionTimeMs: durationMs,
|
|
1241
|
+
});
|
|
1242
|
+
}
|
|
1243
|
+
catch (error) {
|
|
1244
|
+
const durationMs = Date.now() - startTime;
|
|
1245
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
1246
|
+
metricsCollector.record("zebpay_public_getCurrencies", durationMs, false, errorType);
|
|
1247
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
1248
|
+
throw error;
|
|
1249
|
+
}
|
|
1250
|
+
throw createInternalError(`Failed to get currencies: ${error instanceof Error ? error.message : String(error)}`, {});
|
|
1251
|
+
}
|
|
1252
|
+
}));
|
|
1253
|
+
console.error("Registered tool: zebpay_public_getCurrencies");
|
|
1254
|
+
}
|
|
1255
|
+
catch (error) {
|
|
1256
|
+
console.error("Error registering public_getCurrencies:", error);
|
|
1257
|
+
}
|
|
1258
|
+
// Spot private tools: cancel and query orders
|
|
1259
|
+
try {
|
|
1260
|
+
server.tool("zebpay_spot_cancelOrdersBySymbol", `Cancel all open orders for a given symbol on Zebpay spot exchange.
|
|
1261
|
+
|
|
1262
|
+
Endpoint: DELETE /api/v2/ex/orders?symbol=SYMBOL×tamp=...`, {
|
|
1263
|
+
symbol: symbolSchema.describe(`Trading pair symbol in format BASE-QUOTE, e.g., "BTC-INR".`),
|
|
1264
|
+
}, withLogging("zebpay_spot_cancelOrdersBySymbol", config.logLevel, async ({ symbol }) => {
|
|
1265
|
+
const correlationId = generateCorrelationId();
|
|
1266
|
+
const startTime = Date.now();
|
|
1267
|
+
if (!spot) {
|
|
1268
|
+
metricsCollector.record("zebpay_spot_cancelOrdersBySymbol", Date.now() - startTime, false, "missing_credentials");
|
|
1269
|
+
throw createInvalidParamsError("API credentials are required for this operation. Please provide ZEBPAY_API_KEY and ZEBPAY_API_SECRET.", {});
|
|
1270
|
+
}
|
|
1271
|
+
try {
|
|
1272
|
+
validateSymbol(symbol);
|
|
1273
|
+
}
|
|
1274
|
+
catch (error) {
|
|
1275
|
+
metricsCollector.record("zebpay_spot_cancelOrdersBySymbol", Date.now() - startTime, false, "validation_error");
|
|
1276
|
+
throw error;
|
|
1277
|
+
}
|
|
1278
|
+
try {
|
|
1279
|
+
const result = await spot.cancelOrdersBySymbol(symbol.trim().toUpperCase());
|
|
1280
|
+
const durationMs = Date.now() - startTime;
|
|
1281
|
+
metricsCollector.record("zebpay_spot_cancelOrdersBySymbol", durationMs, true);
|
|
1282
|
+
return formatResponse(result, {
|
|
1283
|
+
correlationId,
|
|
1284
|
+
executionTimeMs: durationMs,
|
|
1285
|
+
});
|
|
1286
|
+
}
|
|
1287
|
+
catch (error) {
|
|
1288
|
+
const durationMs = Date.now() - startTime;
|
|
1289
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
1290
|
+
metricsCollector.record("zebpay_spot_cancelOrdersBySymbol", durationMs, false, errorType);
|
|
1291
|
+
throw error;
|
|
1292
|
+
}
|
|
1293
|
+
}));
|
|
1294
|
+
console.error("Registered tool: zebpay_spot_cancelOrdersBySymbol");
|
|
1295
|
+
}
|
|
1296
|
+
catch (error) {
|
|
1297
|
+
console.error("Error registering zebpay_spot_cancelOrdersBySymbol:", error);
|
|
1298
|
+
}
|
|
1299
|
+
try {
|
|
1300
|
+
server.tool("zebpay_spot_cancelAllOrders", `Cancel all open user orders on Zebpay spot exchange.
|
|
1301
|
+
|
|
1302
|
+
Endpoint: DELETE /api/v2/ex/orders/cancelAll?timestamp=...`, {}, withLogging("zebpay_spot_cancelAllOrders", config.logLevel, async () => {
|
|
1303
|
+
const correlationId = generateCorrelationId();
|
|
1304
|
+
const startTime = Date.now();
|
|
1305
|
+
if (!spot) {
|
|
1306
|
+
metricsCollector.record("zebpay_spot_cancelAllOrders", Date.now() - startTime, false, "missing_credentials");
|
|
1307
|
+
throw createInvalidParamsError("API credentials are required for this operation. Please provide ZEBPAY_API_KEY and ZEBPAY_API_SECRET.", {});
|
|
1308
|
+
}
|
|
1309
|
+
try {
|
|
1310
|
+
const result = await spot.cancelAllOrders();
|
|
1311
|
+
const durationMs = Date.now() - startTime;
|
|
1312
|
+
metricsCollector.record("zebpay_spot_cancelAllOrders", durationMs, true);
|
|
1313
|
+
return formatResponse(result, {
|
|
1314
|
+
correlationId,
|
|
1315
|
+
executionTimeMs: durationMs,
|
|
1316
|
+
});
|
|
1317
|
+
}
|
|
1318
|
+
catch (error) {
|
|
1319
|
+
const durationMs = Date.now() - startTime;
|
|
1320
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
1321
|
+
metricsCollector.record("zebpay_spot_cancelAllOrders", durationMs, false, errorType);
|
|
1322
|
+
throw error;
|
|
1323
|
+
}
|
|
1324
|
+
}));
|
|
1325
|
+
console.error("Registered tool: zebpay_spot_cancelAllOrders");
|
|
1326
|
+
}
|
|
1327
|
+
catch (error) {
|
|
1328
|
+
console.error("Error registering zebpay_spot_cancelAllOrders:", error);
|
|
1329
|
+
}
|
|
1330
|
+
try {
|
|
1331
|
+
server.tool("zebpay_spot_getOrderFills", `Get trade fills for a specific order.
|
|
1332
|
+
|
|
1333
|
+
Endpoint: GET /api/v2/ex/order/fills/?orderId=ID×tamp=...`, {
|
|
1334
|
+
orderId: z.string().min(1).describe(`Order ID as a non-empty string.`),
|
|
1335
|
+
}, withLogging("zebpay_spot_getOrderFills", config.logLevel, async ({ orderId }) => {
|
|
1336
|
+
const correlationId = generateCorrelationId();
|
|
1337
|
+
const startTime = Date.now();
|
|
1338
|
+
if (!spot) {
|
|
1339
|
+
metricsCollector.record("zebpay_spot_getOrderFills", Date.now() - startTime, false, "missing_credentials");
|
|
1340
|
+
throw createInvalidParamsError("API credentials are required for this operation. Please provide ZEBPAY_API_KEY and ZEBPAY_API_SECRET.", {});
|
|
1341
|
+
}
|
|
1342
|
+
if (!orderId || typeof orderId !== "string" || orderId.trim().length === 0) {
|
|
1343
|
+
metricsCollector.record("zebpay_spot_getOrderFills", Date.now() - startTime, false, "validation_error");
|
|
1344
|
+
throw createInvalidParamsError("Invalid orderId: must be a non-empty string.", { orderId });
|
|
1345
|
+
}
|
|
1346
|
+
try {
|
|
1347
|
+
const result = await spot.getOrderFills(orderId.trim());
|
|
1348
|
+
const durationMs = Date.now() - startTime;
|
|
1349
|
+
metricsCollector.record("zebpay_spot_getOrderFills", durationMs, true);
|
|
1350
|
+
return formatResponse(result, {
|
|
1351
|
+
correlationId,
|
|
1352
|
+
executionTimeMs: durationMs,
|
|
1353
|
+
});
|
|
1354
|
+
}
|
|
1355
|
+
catch (error) {
|
|
1356
|
+
const durationMs = Date.now() - startTime;
|
|
1357
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
1358
|
+
metricsCollector.record("zebpay_spot_getOrderFills", durationMs, false, errorType);
|
|
1359
|
+
throw error;
|
|
1360
|
+
}
|
|
1361
|
+
}));
|
|
1362
|
+
console.error("Registered tool: zebpay_spot_getOrderFills");
|
|
1363
|
+
}
|
|
1364
|
+
catch (error) {
|
|
1365
|
+
console.error("Error registering zebpay_spot_getOrderFills:", error);
|
|
1366
|
+
}
|
|
1367
|
+
try {
|
|
1368
|
+
server.tool("zebpay_spot_getOrders", `Get orders with optional filtering from Zebpay spot exchange.
|
|
1369
|
+
|
|
1370
|
+
This tool retrieves a list of orders based on the specified symbol and optional filters such as status, pagination, and time range.
|
|
1371
|
+
|
|
1372
|
+
**When to use this tool:**
|
|
1373
|
+
- User wants to see their active, filled, or cancelled orders
|
|
1374
|
+
- User needs to check order history for a specific trading pair
|
|
1375
|
+
- User wants to paginate through their order list
|
|
1376
|
+
- User needs to filter orders by time range
|
|
1377
|
+
|
|
1378
|
+
**Important notes:**
|
|
1379
|
+
- The symbol parameter is required
|
|
1380
|
+
- Default status filter is ACTIVE if not specified
|
|
1381
|
+
- Default pagination is page 1 with 20 records per page
|
|
1382
|
+
- Time filters (startTime, endTime) are in milliseconds
|
|
1383
|
+
- Returns paginated results with total count information
|
|
1384
|
+
|
|
1385
|
+
**Example use cases:**
|
|
1386
|
+
1. User says "Show me my active BTC orders" → Use symbol="BTC-INR", status="ACTIVE"
|
|
1387
|
+
2. User says "Get all my filled ETH orders" → Use symbol="ETH-INR", status="FILLED"
|
|
1388
|
+
3. User wants to see order history with pagination → Use currentPage and pageSize parameters
|
|
1389
|
+
|
|
1390
|
+
**Example request:**
|
|
1391
|
+
{
|
|
1392
|
+
"symbol": "BTC-INR",
|
|
1393
|
+
"status": "ACTIVE",
|
|
1394
|
+
"currentPage": 1,
|
|
1395
|
+
"pageSize": 20
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
**Example response:**
|
|
1399
|
+
Returns paginated order list with details including orderId, symbol, side, type, amount, price, status, filled amount, fees, and timestamps.
|
|
1400
|
+
|
|
1401
|
+
Endpoint: GET /api/v2/ex/orders`, {
|
|
1402
|
+
symbol: symbolSchema.describe(`Trading pair symbol in format BASE-QUOTE (required).
|
|
1403
|
+
Examples: "BTC-INR", "ETH-INR", "BTC-USDT".`),
|
|
1404
|
+
status: z.enum(["ACTIVE", "FILLED", "CANCELLED"]).optional().describe(`Order status filter (optional).
|
|
1405
|
+
- "ACTIVE": Open/pending orders
|
|
1406
|
+
- "FILLED": Completed orders
|
|
1407
|
+
- "CANCELLED": Cancelled orders
|
|
1408
|
+
Default: "ACTIVE" if not specified.`),
|
|
1409
|
+
currentPage: z.number().int().positive().optional().describe(`Current page number for pagination (optional).
|
|
1410
|
+
Must be a positive integer. Default: 1.`),
|
|
1411
|
+
pageSize: z.number().int().positive().optional().describe(`Number of records per page (optional).
|
|
1412
|
+
Must be a positive integer. Default: 20.`),
|
|
1413
|
+
startTime: z.number().int().positive().optional().describe(`Start time filter in milliseconds (optional).
|
|
1414
|
+
Unix timestamp in milliseconds. Only returns orders created after this time.`),
|
|
1415
|
+
endTime: z.number().int().positive().optional().describe(`End time filter in milliseconds (optional).
|
|
1416
|
+
Unix timestamp in milliseconds. Only returns orders created before this time.`),
|
|
1417
|
+
}, withLogging("zebpay_spot_getOrders", config.logLevel, async ({ symbol, status, currentPage, pageSize, startTime, endTime }) => {
|
|
1418
|
+
const correlationId = generateCorrelationId();
|
|
1419
|
+
const startTimeMs = Date.now();
|
|
1420
|
+
if (!spot) {
|
|
1421
|
+
metricsCollector.record("zebpay_spot_getOrders", Date.now() - startTimeMs, false, "missing_credentials");
|
|
1422
|
+
throw createInvalidParamsError("API credentials are required for this operation. Please provide ZEBPAY_API_KEY and ZEBPAY_API_SECRET.", {});
|
|
1423
|
+
}
|
|
1424
|
+
try {
|
|
1425
|
+
validateSymbol(symbol);
|
|
1426
|
+
}
|
|
1427
|
+
catch (error) {
|
|
1428
|
+
metricsCollector.record("zebpay_spot_getOrders", Date.now() - startTimeMs, false, "validation_error");
|
|
1429
|
+
throw error;
|
|
1430
|
+
}
|
|
1431
|
+
const params = {
|
|
1432
|
+
symbol: symbol.trim().toUpperCase(),
|
|
1433
|
+
};
|
|
1434
|
+
if (status) {
|
|
1435
|
+
params.status = status;
|
|
1436
|
+
}
|
|
1437
|
+
if (currentPage !== undefined) {
|
|
1438
|
+
params.currentPage = currentPage;
|
|
1439
|
+
}
|
|
1440
|
+
if (pageSize !== undefined) {
|
|
1441
|
+
params.pageSize = pageSize;
|
|
1442
|
+
}
|
|
1443
|
+
if (startTime !== undefined) {
|
|
1444
|
+
params.startTime = startTime;
|
|
1445
|
+
}
|
|
1446
|
+
if (endTime !== undefined) {
|
|
1447
|
+
params.endTime = endTime;
|
|
1448
|
+
}
|
|
1449
|
+
try {
|
|
1450
|
+
const result = await spot.getOrders(params);
|
|
1451
|
+
const durationMs = Date.now() - startTimeMs;
|
|
1452
|
+
metricsCollector.record("zebpay_spot_getOrders", durationMs, true);
|
|
1453
|
+
return formatResponse(result, {
|
|
1454
|
+
correlationId,
|
|
1455
|
+
executionTimeMs: durationMs,
|
|
1456
|
+
});
|
|
1457
|
+
}
|
|
1458
|
+
catch (error) {
|
|
1459
|
+
const durationMs = Date.now() - startTimeMs;
|
|
1460
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
1461
|
+
metricsCollector.record("zebpay_spot_getOrders", durationMs, false, errorType);
|
|
1462
|
+
throw error;
|
|
1463
|
+
}
|
|
1464
|
+
}));
|
|
1465
|
+
console.error("Registered tool: zebpay_spot_getOrders");
|
|
1466
|
+
}
|
|
1467
|
+
catch (error) {
|
|
1468
|
+
console.error("Error registering zebpay_spot_getOrders:", error);
|
|
1469
|
+
}
|
|
1470
|
+
try {
|
|
1471
|
+
server.tool("zebpay_spot_getOrderById", `Get order details by order ID.
|
|
1472
|
+
|
|
1473
|
+
Endpoint: GET /api/v2/ex/order?orderId=ID×tamp=...`, {
|
|
1474
|
+
orderId: z.string().min(1).describe(`Order ID as a non-empty string.`),
|
|
1475
|
+
}, withLogging("zebpay_spot_getOrderById", config.logLevel, async ({ orderId }) => {
|
|
1476
|
+
const correlationId = generateCorrelationId();
|
|
1477
|
+
const startTime = Date.now();
|
|
1478
|
+
if (!spot) {
|
|
1479
|
+
metricsCollector.record("zebpay_spot_getOrderById", Date.now() - startTime, false, "missing_credentials");
|
|
1480
|
+
throw createInvalidParamsError("API credentials are required for this operation. Please provide ZEBPAY_API_KEY and ZEBPAY_API_SECRET.", {});
|
|
1481
|
+
}
|
|
1482
|
+
if (!orderId || typeof orderId !== "string" || orderId.trim().length === 0) {
|
|
1483
|
+
metricsCollector.record("zebpay_spot_getOrderById", Date.now() - startTime, false, "validation_error");
|
|
1484
|
+
throw createInvalidParamsError("Invalid orderId: must be a non-empty string.", { orderId });
|
|
1485
|
+
}
|
|
1486
|
+
try {
|
|
1487
|
+
const result = await spot.getOrderById(orderId.trim());
|
|
1488
|
+
const durationMs = Date.now() - startTime;
|
|
1489
|
+
metricsCollector.record("zebpay_spot_getOrderById", durationMs, true);
|
|
1490
|
+
return formatOrderResponse(result, {
|
|
1491
|
+
correlationId,
|
|
1492
|
+
executionTimeMs: durationMs,
|
|
1493
|
+
});
|
|
1494
|
+
}
|
|
1495
|
+
catch (error) {
|
|
1496
|
+
const durationMs = Date.now() - startTime;
|
|
1497
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
1498
|
+
metricsCollector.record("zebpay_spot_getOrderById", durationMs, false, errorType);
|
|
1499
|
+
throw error;
|
|
1500
|
+
}
|
|
1501
|
+
}));
|
|
1502
|
+
console.error("Registered tool: zebpay_spot_getOrderById");
|
|
1503
|
+
}
|
|
1504
|
+
catch (error) {
|
|
1505
|
+
console.error("Error registering zebpay_spot_getOrderById:", error);
|
|
1506
|
+
}
|
|
1507
|
+
try {
|
|
1508
|
+
server.tool("zebpay_spot_cancelOrderById", `Cancel a specific order by ID.
|
|
1509
|
+
|
|
1510
|
+
Endpoint: DELETE /api/v2/ex/order?orderId=ID×tamp=...`, {
|
|
1511
|
+
orderId: z.string().min(1).describe(`Order ID as a non-empty string.`),
|
|
1512
|
+
}, withLogging("zebpay_spot_cancelOrderById", config.logLevel, async ({ orderId }) => {
|
|
1513
|
+
const correlationId = generateCorrelationId();
|
|
1514
|
+
const startTime = Date.now();
|
|
1515
|
+
if (!spot) {
|
|
1516
|
+
metricsCollector.record("zebpay_spot_cancelOrderById", Date.now() - startTime, false, "missing_credentials");
|
|
1517
|
+
throw createInvalidParamsError("API credentials are required for this operation. Please provide ZEBPAY_API_KEY and ZEBPAY_API_SECRET.", {});
|
|
1518
|
+
}
|
|
1519
|
+
if (!orderId || typeof orderId !== "string" || orderId.trim().length === 0) {
|
|
1520
|
+
metricsCollector.record("zebpay_spot_cancelOrderById", Date.now() - startTime, false, "validation_error");
|
|
1521
|
+
throw createInvalidParamsError("Invalid orderId: must be a non-empty string.", { orderId });
|
|
1522
|
+
}
|
|
1523
|
+
try {
|
|
1524
|
+
const result = await spot.cancelOrderById(orderId.trim());
|
|
1525
|
+
const durationMs = Date.now() - startTime;
|
|
1526
|
+
metricsCollector.record("zebpay_spot_cancelOrderById", durationMs, true);
|
|
1527
|
+
return formatResponse(result, {
|
|
1528
|
+
correlationId,
|
|
1529
|
+
executionTimeMs: durationMs,
|
|
1530
|
+
});
|
|
1531
|
+
}
|
|
1532
|
+
catch (error) {
|
|
1533
|
+
const durationMs = Date.now() - startTime;
|
|
1534
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
1535
|
+
metricsCollector.record("zebpay_spot_cancelOrderById", durationMs, false, errorType);
|
|
1536
|
+
throw error;
|
|
1537
|
+
}
|
|
1538
|
+
}));
|
|
1539
|
+
console.error("Registered tool: zebpay_spot_cancelOrderById");
|
|
1540
|
+
}
|
|
1541
|
+
catch (error) {
|
|
1542
|
+
console.error("Error registering zebpay_spot_cancelOrderById:", error);
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
/**
|
|
1546
|
+
* Register ONLY public Zebpay tools for market data.
|
|
1547
|
+
* Use this for HTTP streamable transport where you want a public-only server.
|
|
1548
|
+
*/
|
|
1549
|
+
export function registerPublicToolsOnly(server, publicClient, config) {
|
|
1550
|
+
console.error("Registering public market-data tools...");
|
|
1551
|
+
try {
|
|
1552
|
+
server.tool("zebpay_public_getAllTickers", `Get ticker/price information for all trading pairs on Zebpay exchange.
|
|
1553
|
+
|
|
1554
|
+
This tool retrieves the current market price, 24h statistics, and trading volume for all available trading pairs. No authentication required.
|
|
1555
|
+
|
|
1556
|
+
**When to use this tool:**
|
|
1557
|
+
- User asks to see all market prices
|
|
1558
|
+
- User wants to check prices for multiple trading pairs
|
|
1559
|
+
- User says "Show me all prices" or "List all tickers"
|
|
1560
|
+
- User wants an overview of all market data
|
|
1561
|
+
|
|
1562
|
+
**Important notes:**
|
|
1563
|
+
- Returns ticker data for all trading pairs including last price, bid/ask, 24h high/low, volume
|
|
1564
|
+
- Uses endpoint: api/v2/market/allTickers
|
|
1565
|
+
- No authentication required - this is public market data
|
|
1566
|
+
|
|
1567
|
+
**Example use cases:**
|
|
1568
|
+
1. User says "Show me all prices" → Call without parameters
|
|
1569
|
+
2. User wants market overview → Use this tool
|
|
1570
|
+
3. User asks "List all tickers" → Use this tool
|
|
1571
|
+
|
|
1572
|
+
**Example request:**
|
|
1573
|
+
{}
|
|
1574
|
+
|
|
1575
|
+
**Example response:**
|
|
1576
|
+
Returns ticker data for all trading pairs with current price, 24h statistics, trading volume, and price changes.
|
|
1577
|
+
|
|
1578
|
+
**Rate Limits:**
|
|
1579
|
+
- Maximum 20 requests per second for public endpoints
|
|
1580
|
+
- Burst limit: 40 requests
|
|
1581
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
1582
|
+
- Public endpoints have higher rate limits than authenticated endpoints
|
|
1583
|
+
|
|
1584
|
+
**Related Tools:**
|
|
1585
|
+
- Use zebpay_public_getTicker for a specific trading pair
|
|
1586
|
+
- Use zebpay_public_getOrderBook to see market depth
|
|
1587
|
+
- Access all tickers as a resource via zebpay://market/tickers`, {}, withLogging("zebpay_public_getAllTickers", config.logLevel, async () => {
|
|
1588
|
+
const correlationId = generateCorrelationId();
|
|
1589
|
+
const startTime = Date.now();
|
|
1590
|
+
try {
|
|
1591
|
+
const result = await publicClient.getAllTickers();
|
|
1592
|
+
const durationMs = Date.now() - startTime;
|
|
1593
|
+
metricsCollector.record("zebpay_public_getAllTickers", durationMs, true);
|
|
1594
|
+
return formatResponse(result, {
|
|
1595
|
+
toolName: "zebpay_public_getAllTickers",
|
|
1596
|
+
correlationId,
|
|
1597
|
+
executionTimeMs: durationMs,
|
|
1598
|
+
});
|
|
1599
|
+
}
|
|
1600
|
+
catch (error) {
|
|
1601
|
+
const durationMs = Date.now() - startTime;
|
|
1602
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
1603
|
+
metricsCollector.record("zebpay_public_getAllTickers", durationMs, false, errorType);
|
|
1604
|
+
throw error;
|
|
1605
|
+
}
|
|
1606
|
+
}));
|
|
1607
|
+
console.error("Registered tool: zebpay_public_getAllTickers");
|
|
1608
|
+
}
|
|
1609
|
+
catch (error) {
|
|
1610
|
+
console.error("Error registering public_getAllTickers:", error);
|
|
1611
|
+
}
|
|
1612
|
+
try {
|
|
1613
|
+
server.tool("zebpay_public_getTicker", `Get ticker/price information for a specific trading pair on Zebpay exchange.
|
|
1614
|
+
|
|
1615
|
+
This tool retrieves the current market price, 24h statistics, and trading volume for a specific trading pair. No authentication required.
|
|
1616
|
+
|
|
1617
|
+
**When to use this tool:**
|
|
1618
|
+
- User asks about current price of a specific cryptocurrency
|
|
1619
|
+
- User wants to check market price or price changes for a symbol
|
|
1620
|
+
- User asks "What's the price of BTC?" or "Show me ETH price"
|
|
1621
|
+
- User wants ticker data for a specific trading pair
|
|
1622
|
+
|
|
1623
|
+
**Important notes:**
|
|
1624
|
+
- Returns ticker data including last price, bid/ask, 24h high/low, volume
|
|
1625
|
+
- Requires a specific symbol parameter
|
|
1626
|
+
- Uses endpoint: api/v2/market/ticker?symbol={symbol}
|
|
1627
|
+
- No authentication required - this is public market data
|
|
1628
|
+
|
|
1629
|
+
**Example use cases:**
|
|
1630
|
+
1. User says "What's the price of Bitcoin?" → Use symbol="BTC-INR"
|
|
1631
|
+
2. User asks "How much is ETH?" → Use symbol="ETH-INR"
|
|
1632
|
+
3. User wants BTC price → Use symbol="BTC-INR"
|
|
1633
|
+
|
|
1634
|
+
**Example request:**
|
|
1635
|
+
{
|
|
1636
|
+
"symbol": "BTC-INR"
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
**Example response:**
|
|
1640
|
+
Returns ticker data with current price, 24h statistics, trading volume, and price changes for the specified symbol.
|
|
1641
|
+
|
|
1642
|
+
**Rate Limits:**
|
|
1643
|
+
- Maximum 20 requests per second for public endpoints
|
|
1644
|
+
- Burst limit: 40 requests
|
|
1645
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
1646
|
+
- Public endpoints have higher rate limits than authenticated endpoints
|
|
1647
|
+
|
|
1648
|
+
**Related Tools:**
|
|
1649
|
+
- Use zebpay_public_getAllTickers to get prices for all pairs at once
|
|
1650
|
+
- Use zebpay_public_getOrderBook to see market depth and liquidity
|
|
1651
|
+
- Use zebpay_public_getTrades to see recent trading activity
|
|
1652
|
+
- Use before zebpay_spot_placeMarketOrder to check current market price`, {
|
|
1653
|
+
symbol: symbolSchema.describe(`Trading pair symbol in format BASE-QUOTE (required).
|
|
1654
|
+
Examples: "BTC-INR" (Bitcoin/Indian Rupees), "ETH-INR" (Ethereum/Indian Rupees), "BTC-USDT" (Bitcoin/Tether).
|
|
1655
|
+
The symbol determines which market's ticker to retrieve.
|
|
1656
|
+
Always use uppercase currency codes separated by a hyphen.`),
|
|
1657
|
+
}, withLogging("zebpay_public_getTicker", config.logLevel, async ({ symbol }) => {
|
|
1658
|
+
const correlationId = generateCorrelationId();
|
|
1659
|
+
const startTime = Date.now();
|
|
1660
|
+
try {
|
|
1661
|
+
validateSymbol(symbol);
|
|
1662
|
+
}
|
|
1663
|
+
catch (error) {
|
|
1664
|
+
metricsCollector.record("zebpay_public_getTicker", Date.now() - startTime, false, "validation_error");
|
|
1665
|
+
throw error;
|
|
1666
|
+
}
|
|
1667
|
+
try {
|
|
1668
|
+
const result = await publicClient.getTicker({ symbol: symbol.trim().toUpperCase() });
|
|
1669
|
+
const durationMs = Date.now() - startTime;
|
|
1670
|
+
metricsCollector.record("zebpay_public_getTicker", durationMs, true);
|
|
1671
|
+
return formatTickerResponse(result, {
|
|
1672
|
+
correlationId,
|
|
1673
|
+
executionTimeMs: durationMs,
|
|
1674
|
+
});
|
|
1675
|
+
}
|
|
1676
|
+
catch (error) {
|
|
1677
|
+
const durationMs = Date.now() - startTime;
|
|
1678
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
1679
|
+
metricsCollector.record("zebpay_public_getTicker", durationMs, false, errorType);
|
|
1680
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
1681
|
+
throw error;
|
|
1682
|
+
}
|
|
1683
|
+
throw createInternalError(`Failed to get ticker: ${error instanceof Error ? error.message : String(error)}`, { symbol });
|
|
1684
|
+
}
|
|
1685
|
+
}));
|
|
1686
|
+
console.error("Registered tool: zebpay_public_getTicker");
|
|
1687
|
+
}
|
|
1688
|
+
catch (error) {
|
|
1689
|
+
console.error("Error registering public_getTicker:", error);
|
|
1690
|
+
}
|
|
1691
|
+
try {
|
|
1692
|
+
server.tool("zebpay_public_getOrderBook", `Get order book (market depth) for a trading pair on Zebpay exchange.
|
|
1693
|
+
|
|
1694
|
+
This tool retrieves the current buy and sell orders (bids and asks) for a specific trading pair, showing market depth and liquidity. No authentication required.
|
|
1695
|
+
|
|
1696
|
+
**When to use this tool:**
|
|
1697
|
+
- User asks about order book or market depth
|
|
1698
|
+
- User wants to see buy/sell orders for a trading pair
|
|
1699
|
+
- User asks "Show me the order book for BTC" or "What's the market depth?"
|
|
1700
|
+
- Before placing a large order to check liquidity
|
|
1701
|
+
|
|
1702
|
+
**Important notes:**
|
|
1703
|
+
- Shows bids (buy orders) and asks (sell orders) with prices and quantities
|
|
1704
|
+
- Can limit the depth using the limit parameter
|
|
1705
|
+
- Uses endpoint: api/v2/market/orderbook?symbol={symbol}&limit={limit}
|
|
1706
|
+
- No authentication required - this is public market data
|
|
1707
|
+
|
|
1708
|
+
**Example use cases:**
|
|
1709
|
+
1. User says "Show me order book for BTC" → Use symbol="BTC-INR"
|
|
1710
|
+
2. User wants to check market depth → Use symbol with optional limit
|
|
1711
|
+
3. User asks "What are the current buy and sell orders?" → Use symbol parameter
|
|
1712
|
+
|
|
1713
|
+
**Example request:**
|
|
1714
|
+
{
|
|
1715
|
+
"symbol": "BTC-INR",
|
|
1716
|
+
"limit": 10
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
**Example response:**
|
|
1720
|
+
Returns order book data with bids (buy orders) and asks (sell orders), showing price levels and quantities at each level.
|
|
1721
|
+
|
|
1722
|
+
**Rate Limits:**
|
|
1723
|
+
- Maximum 20 requests per second for public endpoints
|
|
1724
|
+
- Burst limit: 40 requests
|
|
1725
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
1726
|
+
- Lower limit values return faster responses
|
|
1727
|
+
|
|
1728
|
+
**Related Tools:**
|
|
1729
|
+
- Use zebpay_public_getTicker to get current price summary
|
|
1730
|
+
- Use zebpay_public_getOrderBookTicker for lightweight best bid/ask prices
|
|
1731
|
+
- Use zebpay_public_getTrades to see recent executed trades
|
|
1732
|
+
- Use before placing large orders to assess market liquidity`, {
|
|
1733
|
+
symbol: symbolSchema.describe(`Trading pair symbol in format BASE-QUOTE (required).
|
|
1734
|
+
Examples: "BTC-INR" (Bitcoin/Indian Rupees), "ETH-INR" (Ethereum/Indian Rupees).
|
|
1735
|
+
The symbol determines which market's order book to retrieve.
|
|
1736
|
+
Always use uppercase currency codes separated by a hyphen.`),
|
|
1737
|
+
limit: z.number().int().positive().optional().describe(`Optional limit for the number of price levels to return (positive integer).
|
|
1738
|
+
**Default behavior:** If not provided, returns default depth (usually 100 levels).
|
|
1739
|
+
**Performance:** Lower limits return fewer levels but provide faster responses.
|
|
1740
|
+
**Examples:** 10 (top 10 bids/asks), 20 (top 20 bids/asks), 100 (full depth).
|
|
1741
|
+
**Use case:** Use lower limits for quick overview, higher limits for detailed market depth analysis.`),
|
|
1742
|
+
}, withLogging("zebpay_public_getOrderBook", config.logLevel, async ({ symbol, limit }) => {
|
|
1743
|
+
const correlationId = generateCorrelationId();
|
|
1744
|
+
const startTime = Date.now();
|
|
1745
|
+
try {
|
|
1746
|
+
validateSymbol(symbol);
|
|
1747
|
+
}
|
|
1748
|
+
catch (error) {
|
|
1749
|
+
metricsCollector.record("zebpay_public_getOrderBook", Date.now() - startTime, false, "validation_error");
|
|
1750
|
+
throw error;
|
|
1751
|
+
}
|
|
1752
|
+
try {
|
|
1753
|
+
const result = await publicClient.getOrderBook({ symbol: symbol.trim().toUpperCase(), limit });
|
|
1754
|
+
const durationMs = Date.now() - startTime;
|
|
1755
|
+
metricsCollector.record("zebpay_public_getOrderBook", durationMs, true);
|
|
1756
|
+
return formatOrderBookResponse(result, {
|
|
1757
|
+
toolName: "zebpay_public_getOrderBook",
|
|
1758
|
+
correlationId,
|
|
1759
|
+
executionTimeMs: durationMs,
|
|
1760
|
+
});
|
|
1761
|
+
}
|
|
1762
|
+
catch (error) {
|
|
1763
|
+
const durationMs = Date.now() - startTime;
|
|
1764
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
1765
|
+
metricsCollector.record("zebpay_public_getOrderBook", durationMs, false, errorType);
|
|
1766
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
1767
|
+
throw error;
|
|
1768
|
+
}
|
|
1769
|
+
throw createInternalError(`Failed to get order book: ${error instanceof Error ? error.message : String(error)}`, { symbol, limit });
|
|
1770
|
+
}
|
|
1771
|
+
}));
|
|
1772
|
+
console.error("Registered tool: zebpay_public_getOrderBook");
|
|
1773
|
+
}
|
|
1774
|
+
catch (error) {
|
|
1775
|
+
console.error("Error registering public_getOrderBook:", error);
|
|
1776
|
+
}
|
|
1777
|
+
try {
|
|
1778
|
+
server.tool("zebpay_public_getOrderBookTicker", `Get order book ticker for a trading pair on Zebpay exchange.
|
|
1779
|
+
|
|
1780
|
+
This tool retrieves the best bid and ask prices (ticker) from the order book for a specific trading pair. This is a lightweight endpoint that returns only the top-of-book prices without the full order book depth. No authentication required.
|
|
1781
|
+
|
|
1782
|
+
**When to use this tool:**
|
|
1783
|
+
- User asks about best bid/ask prices
|
|
1784
|
+
- User wants to see the current best buy and sell prices
|
|
1785
|
+
- User asks "What's the best bid and ask for BTC?" or "Show me the order book ticker"
|
|
1786
|
+
- User wants a quick price check without full order book data
|
|
1787
|
+
|
|
1788
|
+
**Important notes:**
|
|
1789
|
+
- Returns best bid (highest buy order) and best ask (lowest sell order) prices
|
|
1790
|
+
- Lightweight endpoint - faster than full order book
|
|
1791
|
+
- Uses endpoint: api/v2/market/orderbook/ticker?symbol={symbol}
|
|
1792
|
+
- No authentication required - this is public market data
|
|
1793
|
+
|
|
1794
|
+
**Example use cases:**
|
|
1795
|
+
1. User says "Show me best bid/ask for BTC" → Use symbol="BTC-INR"
|
|
1796
|
+
2. User wants quick price check → Use this tool instead of full order book
|
|
1797
|
+
3. User asks "What are the current best prices?" → Use symbol parameter
|
|
1798
|
+
|
|
1799
|
+
**Example request:**
|
|
1800
|
+
{
|
|
1801
|
+
"symbol": "BTC-INR"
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
**Example response:**
|
|
1805
|
+
Returns order book ticker data with best bid price, best ask price, and related market information.
|
|
1806
|
+
|
|
1807
|
+
**Rate Limits:**
|
|
1808
|
+
- Maximum 20 requests per second for public endpoints
|
|
1809
|
+
- Burst limit: 40 requests
|
|
1810
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
1811
|
+
- This is a lightweight endpoint, faster than full order book
|
|
1812
|
+
|
|
1813
|
+
**Related Tools:**
|
|
1814
|
+
- Use zebpay_public_getOrderBook for full market depth
|
|
1815
|
+
- Use zebpay_public_getTicker for comprehensive price information
|
|
1816
|
+
- Use for quick price checks before trading`, {
|
|
1817
|
+
symbol: symbolSchema.describe(`Trading pair symbol in format BASE-QUOTE (required).
|
|
1818
|
+
Examples: "BTC-INR" (Bitcoin/Indian Rupees), "ETH-INR" (Ethereum/Indian Rupees).
|
|
1819
|
+
The symbol determines which market's order book ticker to retrieve.
|
|
1820
|
+
Always use uppercase currency codes separated by a hyphen.`),
|
|
1821
|
+
}, withLogging("zebpay_public_getOrderBookTicker", config.logLevel, async ({ symbol }) => {
|
|
1822
|
+
const correlationId = generateCorrelationId();
|
|
1823
|
+
const startTime = Date.now();
|
|
1824
|
+
try {
|
|
1825
|
+
validateSymbol(symbol);
|
|
1826
|
+
}
|
|
1827
|
+
catch (error) {
|
|
1828
|
+
metricsCollector.record("zebpay_public_getOrderBookTicker", Date.now() - startTime, false, "validation_error");
|
|
1829
|
+
throw error;
|
|
1830
|
+
}
|
|
1831
|
+
try {
|
|
1832
|
+
const result = await publicClient.getOrderBookTicker({ symbol: symbol.trim().toUpperCase() });
|
|
1833
|
+
const durationMs = Date.now() - startTime;
|
|
1834
|
+
metricsCollector.record("zebpay_public_getOrderBookTicker", durationMs, true);
|
|
1835
|
+
return formatResponse(result, {
|
|
1836
|
+
toolName: "zebpay_public_getOrderBookTicker",
|
|
1837
|
+
correlationId,
|
|
1838
|
+
executionTimeMs: durationMs,
|
|
1839
|
+
});
|
|
1840
|
+
}
|
|
1841
|
+
catch (error) {
|
|
1842
|
+
const durationMs = Date.now() - startTime;
|
|
1843
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
1844
|
+
metricsCollector.record("zebpay_public_getOrderBookTicker", durationMs, false, errorType);
|
|
1845
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
1846
|
+
throw error;
|
|
1847
|
+
}
|
|
1848
|
+
throw createInternalError(`Failed to get order book ticker: ${error instanceof Error ? error.message : String(error)}`, { symbol });
|
|
1849
|
+
}
|
|
1850
|
+
}));
|
|
1851
|
+
console.error("Registered tool: zebpay_public_getOrderBookTicker");
|
|
1852
|
+
}
|
|
1853
|
+
catch (error) {
|
|
1854
|
+
console.error("Error registering public_getOrderBookTicker:", error);
|
|
1855
|
+
}
|
|
1856
|
+
try {
|
|
1857
|
+
server.tool("zebpay_public_getTrades", `Get recent trades/transactions for a trading pair on Zebpay exchange.
|
|
1858
|
+
|
|
1859
|
+
This tool retrieves the most recent trades executed on the exchange for a specific trading pair, showing price, quantity, and time. Supports pagination for accessing older trades. No authentication required.
|
|
1860
|
+
|
|
1861
|
+
**When to use this tool:**
|
|
1862
|
+
- User asks about recent trades or transaction history
|
|
1863
|
+
- User wants to see recent market activity
|
|
1864
|
+
- User asks "Show me recent BTC trades" or "What trades happened?"
|
|
1865
|
+
- User wants to analyze trading activity
|
|
1866
|
+
- User wants to paginate through historical trades
|
|
1867
|
+
|
|
1868
|
+
**Important notes:**
|
|
1869
|
+
- Shows recent trades with price, quantity, side (buy/sell), and timestamp
|
|
1870
|
+
- Can limit the number of trades returned per page
|
|
1871
|
+
- Supports pagination with the page parameter
|
|
1872
|
+
- Uses endpoint: api/v2/market/trades?symbol={symbol}&limit={limit}&page={page}
|
|
1873
|
+
- No authentication required - this is public market data
|
|
1874
|
+
|
|
1875
|
+
**Example use cases:**
|
|
1876
|
+
1. User says "Show me recent BTC trades" → Use symbol="BTC-INR"
|
|
1877
|
+
2. User wants to see market activity → Use symbol with optional limit
|
|
1878
|
+
3. User asks "What trades happened recently?" → Use symbol parameter
|
|
1879
|
+
4. User wants page 2 of trades → Use symbol="BTC-INR", limit=50, page=2
|
|
1880
|
+
|
|
1881
|
+
**Example request:**
|
|
1882
|
+
{
|
|
1883
|
+
"symbol": "BTC-INR",
|
|
1884
|
+
"limit": 50,
|
|
1885
|
+
"page": 1
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1888
|
+
**Example response:**
|
|
1889
|
+
Returns array of recent trades with price, quantity, side (buy/sell), and timestamp for each trade.
|
|
1890
|
+
|
|
1891
|
+
**Rate Limits:**
|
|
1892
|
+
- Maximum 20 requests per second for public endpoints
|
|
1893
|
+
- Burst limit: 40 requests
|
|
1894
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
1895
|
+
- Use pagination (page parameter) to access historical trades efficiently
|
|
1896
|
+
|
|
1897
|
+
**Related Tools:**
|
|
1898
|
+
- Use zebpay_public_getTicker to get current price summary
|
|
1899
|
+
- Use zebpay_public_getOrderBook to see pending orders
|
|
1900
|
+
- Use zebpay_public_getKlines for historical price analysis`, {
|
|
1901
|
+
symbol: symbolSchema.describe(`Trading pair symbol in format BASE-QUOTE (required).
|
|
1902
|
+
Examples: "BTC-INR" (Bitcoin/Indian Rupees), "ETH-INR" (Ethereum/Indian Rupees).
|
|
1903
|
+
The symbol determines which market's trades to retrieve.
|
|
1904
|
+
Always use uppercase currency codes separated by a hyphen.`),
|
|
1905
|
+
limit: z.number().int().positive().optional().describe(`Optional limit for the number of recent trades to return per page (positive integer).
|
|
1906
|
+
**Default behavior:** If not provided, returns default number (usually 100 trades).
|
|
1907
|
+
**Performance:** Lower limits return fewer trades but provide faster responses.
|
|
1908
|
+
**Examples:** 10 (last 10 trades), 50 (last 50 trades), 100 (last 100 trades).
|
|
1909
|
+
**Use case:** Combine with page parameter for pagination. Use lower limits for quick market activity overview.`),
|
|
1910
|
+
page: z.number().int().positive().optional().describe(`Optional page number for pagination (positive integer, starts from 1).
|
|
1911
|
+
**Default behavior:** If not provided, returns the first page of results (page 1).
|
|
1912
|
+
**Pagination:** Use this to access older trades beyond the first page.
|
|
1913
|
+
**Examples:** 1 (first page), 2 (second page), 3 (third page).
|
|
1914
|
+
**Use case:** Combine with limit parameter to control how many trades per page. Use page=1 for most recent trades, higher page numbers for historical data.`),
|
|
1915
|
+
}, withLogging("zebpay_public_getTrades", config.logLevel, async ({ symbol, limit, page }) => {
|
|
1916
|
+
const correlationId = generateCorrelationId();
|
|
1917
|
+
const startTime = Date.now();
|
|
1918
|
+
try {
|
|
1919
|
+
validateSymbol(symbol);
|
|
1920
|
+
}
|
|
1921
|
+
catch (error) {
|
|
1922
|
+
metricsCollector.record("zebpay_public_getTrades", Date.now() - startTime, false, "validation_error");
|
|
1923
|
+
throw error;
|
|
1924
|
+
}
|
|
1925
|
+
try {
|
|
1926
|
+
const result = await publicClient.getTrades({ symbol: symbol.trim().toUpperCase(), limit, page });
|
|
1927
|
+
const durationMs = Date.now() - startTime;
|
|
1928
|
+
metricsCollector.record("zebpay_public_getTrades", durationMs, true);
|
|
1929
|
+
return formatTradesResponse(result, {
|
|
1930
|
+
toolName: "zebpay_public_getTrades",
|
|
1931
|
+
correlationId,
|
|
1932
|
+
executionTimeMs: durationMs,
|
|
1933
|
+
});
|
|
1934
|
+
}
|
|
1935
|
+
catch (error) {
|
|
1936
|
+
const durationMs = Date.now() - startTime;
|
|
1937
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
1938
|
+
metricsCollector.record("zebpay_public_getTrades", durationMs, false, errorType);
|
|
1939
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
1940
|
+
throw error;
|
|
1941
|
+
}
|
|
1942
|
+
throw createInternalError(`Failed to get trades: ${error instanceof Error ? error.message : String(error)}`, { symbol, limit, page });
|
|
1943
|
+
}
|
|
1944
|
+
}));
|
|
1945
|
+
console.error("Registered tool: zebpay_public_getTrades");
|
|
1946
|
+
}
|
|
1947
|
+
catch (error) {
|
|
1948
|
+
console.error("Error registering public_getTrades:", error);
|
|
1949
|
+
}
|
|
1950
|
+
try {
|
|
1951
|
+
server.tool("zebpay_public_getKlines", `Get candlestick/K-line data for a trading pair on Zebpay exchange.
|
|
1952
|
+
|
|
1953
|
+
This tool retrieves historical price data in candlestick format (OHLCV: Open, High, Low, Close, Volume) for charting and analysis. Requires a time range to be specified. Supports optional filtering by category. No authentication required.
|
|
1954
|
+
|
|
1955
|
+
**When to use this tool:**
|
|
1956
|
+
- User asks about price history or charts
|
|
1957
|
+
- User wants to analyze price trends over time
|
|
1958
|
+
- User asks "Show me BTC price history" or "What was the price last week?"
|
|
1959
|
+
- User wants candlestick data for technical analysis
|
|
1960
|
+
- User wants spot or futures market data
|
|
1961
|
+
|
|
1962
|
+
**Important notes:**
|
|
1963
|
+
- Returns OHLCV (Open, High, Low, Close, Volume) data
|
|
1964
|
+
- Supports different time intervals (1m, 5m, 15m, 1h, 1d, etc.)
|
|
1965
|
+
- Requires startTime and endTime to specify the time range (in seconds since epoch)
|
|
1966
|
+
- Supports optional category parameter to specify market type (e.g., "spot")
|
|
1967
|
+
- Uses endpoint: api/v2/market/klines?symbol={symbol}&interval={interval}&startTime={startTime}&endTime={endTime}&category={category}
|
|
1968
|
+
- No authentication required - this is public market data
|
|
1969
|
+
|
|
1970
|
+
**Example use cases:**
|
|
1971
|
+
1. User says "Show me BTC price history" → Use symbol="BTC-INR", interval="1h", startTime and endTime
|
|
1972
|
+
2. User wants daily charts → Use interval="1d" with time range
|
|
1973
|
+
3. User asks "What was the price last week?" → Use interval="1d" with time range
|
|
1974
|
+
4. User wants spot market data → Use category="spot"
|
|
1975
|
+
|
|
1976
|
+
**Example request:**
|
|
1977
|
+
{
|
|
1978
|
+
"symbol": "BTC-INR",
|
|
1979
|
+
"interval": "15m",
|
|
1980
|
+
"startTime": 1756634020,
|
|
1981
|
+
"endTime": 1756740279,
|
|
1982
|
+
"category": "spot"
|
|
1983
|
+
}
|
|
1984
|
+
|
|
1985
|
+
**Example response:**
|
|
1986
|
+
Returns array of candlestick data with open, high, low, close prices and volume for each time period.
|
|
1987
|
+
|
|
1988
|
+
**Rate Limits:**
|
|
1989
|
+
- Maximum 20 requests per second for public endpoints
|
|
1990
|
+
- Burst limit: 40 requests
|
|
1991
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
1992
|
+
- Larger time ranges may require multiple requests with pagination
|
|
1993
|
+
|
|
1994
|
+
**Related Tools:**
|
|
1995
|
+
- Use zebpay_public_getTicker for current price information
|
|
1996
|
+
- Use zebpay_public_getTrades to see recent trading activity
|
|
1997
|
+
- Use zebpay_public_getOrderBook to analyze current market depth
|
|
1998
|
+
- Combine with zebpay_public_getTicker for comprehensive market analysis`, {
|
|
1999
|
+
symbol: symbolSchema.describe(`Trading pair symbol in format BASE-QUOTE (required).
|
|
2000
|
+
Examples: "BTC-INR" (Bitcoin/Indian Rupees), "ETH-INR" (Ethereum/Indian Rupees).
|
|
2001
|
+
The symbol determines which market's data to retrieve.
|
|
2002
|
+
Always use uppercase currency codes separated by a hyphen.`),
|
|
2003
|
+
interval: z.string().min(1).describe(`Time interval for each candlestick (required).
|
|
2004
|
+
Common intervals: "1m" (1 minute), "5m" (5 minutes), "15m" (15 minutes), "1h" (1 hour), "4h" (4 hours), "1d" (1 day), "1w" (1 week).
|
|
2005
|
+
The interval determines the granularity of the price data.
|
|
2006
|
+
Examples: "1m" for minute-by-minute data, "1d" for daily data.`),
|
|
2007
|
+
startTime: z.number().describe(`Start timestamp in seconds since epoch (required).
|
|
2008
|
+
Returns candlesticks starting from this time.
|
|
2009
|
+
Use with endTime to get data for a specific time range.
|
|
2010
|
+
Example: 1756634020`),
|
|
2011
|
+
endTime: z.number().describe(`End timestamp in seconds since epoch (required).
|
|
2012
|
+
Returns candlesticks up to this time.
|
|
2013
|
+
Use with startTime to get data for a specific time range.
|
|
2014
|
+
Example: 1756740279`),
|
|
2015
|
+
limit: z.number().int().positive().optional().describe(`Optional limit for the number of candlesticks to return (positive integer).
|
|
2016
|
+
**Default behavior:** If not provided, returns default number (usually 500 candlesticks).
|
|
2017
|
+
**Performance:** Lower limits return fewer data points but provide faster responses.
|
|
2018
|
+
**Examples:** 100 (last 100 candles), 500 (last 500 candles).
|
|
2019
|
+
**Use case:** Use lower limits for quick price history overview, higher limits for detailed technical analysis. Consider time range (startTime/endTime) when setting limit.`),
|
|
2020
|
+
category: z.string().optional().describe(`Optional category parameter to specify market type (string).
|
|
2021
|
+
**Default behavior:** If not provided, returns default market data.
|
|
2022
|
+
**Common values:** "spot" (spot trading market).
|
|
2023
|
+
**Use case:** Use this to filter data by market category. For spot trading analysis, use category="spot".`),
|
|
2024
|
+
}, withLogging("zebpay_public_getKlines", config.logLevel, async ({ symbol, interval, limit, startTime, endTime, category }) => {
|
|
2025
|
+
const correlationId = generateCorrelationId();
|
|
2026
|
+
const executionStartTime = Date.now();
|
|
2027
|
+
try {
|
|
2028
|
+
validateSymbol(symbol);
|
|
2029
|
+
}
|
|
2030
|
+
catch (error) {
|
|
2031
|
+
metricsCollector.record("zebpay_public_getKlines", Date.now() - executionStartTime, false, "validation_error");
|
|
2032
|
+
throw error;
|
|
2033
|
+
}
|
|
2034
|
+
try {
|
|
2035
|
+
const result = await publicClient.getKlines({
|
|
2036
|
+
symbol: symbol.trim().toUpperCase(),
|
|
2037
|
+
interval,
|
|
2038
|
+
startTime,
|
|
2039
|
+
endTime,
|
|
2040
|
+
limit,
|
|
2041
|
+
category,
|
|
2042
|
+
});
|
|
2043
|
+
const durationMs = Date.now() - executionStartTime;
|
|
2044
|
+
metricsCollector.record("zebpay_public_getKlines", durationMs, true);
|
|
2045
|
+
return formatKlinesResponse(result, {
|
|
2046
|
+
toolName: "zebpay_public_getKlines",
|
|
2047
|
+
correlationId,
|
|
2048
|
+
executionTimeMs: durationMs,
|
|
2049
|
+
});
|
|
2050
|
+
}
|
|
2051
|
+
catch (error) {
|
|
2052
|
+
const durationMs = Date.now() - executionStartTime;
|
|
2053
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
2054
|
+
metricsCollector.record("zebpay_public_getKlines", durationMs, false, errorType);
|
|
2055
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
2056
|
+
throw error;
|
|
2057
|
+
}
|
|
2058
|
+
throw createInternalError(`Failed to get klines: ${error instanceof Error ? error.message : String(error)}`, { symbol, interval, startTime, endTime });
|
|
2059
|
+
}
|
|
2060
|
+
}));
|
|
2061
|
+
console.error("Registered tool: zebpay_public_getKlines");
|
|
2062
|
+
}
|
|
2063
|
+
catch (error) {
|
|
2064
|
+
console.error("Error registering public_getKlines:", error);
|
|
2065
|
+
}
|
|
2066
|
+
try {
|
|
2067
|
+
server.tool("zebpay_public_getExchangeInfo", `Get exchange information including trading rules, symbols, and filters.
|
|
2068
|
+
|
|
2069
|
+
This tool retrieves general information about the Zebpay exchange, including available trading pairs, trading rules, order limits, and other exchange metadata. No authentication required.
|
|
2070
|
+
|
|
2071
|
+
**When to use this tool:**
|
|
2072
|
+
- User asks about available trading pairs
|
|
2073
|
+
- User wants to know exchange rules or limits
|
|
2074
|
+
- User asks "What pairs can I trade?" or "What are the trading rules?"
|
|
2075
|
+
- User needs to check symbol information before trading
|
|
2076
|
+
|
|
2077
|
+
**Important notes:**
|
|
2078
|
+
- Returns exchange-wide information including all trading pairs
|
|
2079
|
+
- Includes trading rules, filters, and limits
|
|
2080
|
+
- No authentication required - this is public exchange information
|
|
2081
|
+
|
|
2082
|
+
**Example use cases:**
|
|
2083
|
+
1. User says "What pairs are available?" → Call without parameters
|
|
2084
|
+
2. User wants to check trading rules → Call to get exchange info
|
|
2085
|
+
3. User asks "What can I trade?" → Use this tool
|
|
2086
|
+
|
|
2087
|
+
**Example request:**
|
|
2088
|
+
{}
|
|
2089
|
+
|
|
2090
|
+
**Example response:**
|
|
2091
|
+
Returns exchange information including available symbols, trading rules, order limits, and other exchange metadata.
|
|
2092
|
+
|
|
2093
|
+
**Rate Limits:**
|
|
2094
|
+
- Maximum 20 requests per second for public endpoints
|
|
2095
|
+
- Burst limit: 40 requests
|
|
2096
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
2097
|
+
- This data changes infrequently, consider caching results
|
|
2098
|
+
|
|
2099
|
+
**Related Tools:**
|
|
2100
|
+
- Use zebpay_public_getCurrencies to see supported currencies
|
|
2101
|
+
- Use zebpay_public_getAllTickers to see all available trading pairs
|
|
2102
|
+
- Access exchange info as a resource via zebpay://exchange/info`, {}, withLogging("zebpay_public_getExchangeInfo", config.logLevel, async () => {
|
|
2103
|
+
const correlationId = generateCorrelationId();
|
|
2104
|
+
const startTime = Date.now();
|
|
2105
|
+
try {
|
|
2106
|
+
const result = await publicClient.getExchangeInfo();
|
|
2107
|
+
const durationMs = Date.now() - startTime;
|
|
2108
|
+
metricsCollector.record("zebpay_public_getExchangeInfo", durationMs, true);
|
|
2109
|
+
return formatResponse(result, {
|
|
2110
|
+
toolName: "zebpay_public_getExchangeInfo",
|
|
2111
|
+
correlationId,
|
|
2112
|
+
executionTimeMs: durationMs,
|
|
2113
|
+
});
|
|
2114
|
+
}
|
|
2115
|
+
catch (error) {
|
|
2116
|
+
const durationMs = Date.now() - startTime;
|
|
2117
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
2118
|
+
metricsCollector.record("zebpay_public_getExchangeInfo", durationMs, false, errorType);
|
|
2119
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
2120
|
+
throw error;
|
|
2121
|
+
}
|
|
2122
|
+
throw createInternalError(`Failed to get exchange info: ${error instanceof Error ? error.message : String(error)}`, {});
|
|
2123
|
+
}
|
|
2124
|
+
}));
|
|
2125
|
+
console.error("Registered tool: zebpay_public_getExchangeInfo");
|
|
2126
|
+
}
|
|
2127
|
+
catch (error) {
|
|
2128
|
+
console.error("Error registering public_getExchangeInfo:", error);
|
|
2129
|
+
}
|
|
2130
|
+
try {
|
|
2131
|
+
server.tool("zebpay_public_getCurrencies", `Get list of supported currencies and tokens on Zebpay exchange.
|
|
2132
|
+
|
|
2133
|
+
This tool retrieves a comprehensive list of all supported currencies and tokens, including their details such as precision, type (crypto/fiat), withdrawal/deposit settings, supported blockchain chains, fees, and limits. No authentication required.
|
|
2134
|
+
|
|
2135
|
+
**When to use this tool:**
|
|
2136
|
+
- User asks about supported currencies or tokens
|
|
2137
|
+
- User wants to see what currencies are available
|
|
2138
|
+
- User asks "What currencies does Zebpay support?" or "List all currencies"
|
|
2139
|
+
- User needs to check withdrawal/deposit limits or fees
|
|
2140
|
+
- User wants to verify if a specific currency is supported
|
|
2141
|
+
- User needs information about supported blockchain chains for a currency
|
|
2142
|
+
|
|
2143
|
+
**Important notes:**
|
|
2144
|
+
- Returns detailed information about each currency including:
|
|
2145
|
+
- Currency code, name, and full name
|
|
2146
|
+
- Precision and type (crypto/fiat)
|
|
2147
|
+
- Withdrawal and deposit settings
|
|
2148
|
+
- Supported blockchain chains with fees and limits
|
|
2149
|
+
- Contract addresses for tokens
|
|
2150
|
+
- Address validation regex patterns
|
|
2151
|
+
- Uses endpoint: api/v2/ex/currencies
|
|
2152
|
+
- No authentication required - this is public exchange information
|
|
2153
|
+
|
|
2154
|
+
**Example use cases:**
|
|
2155
|
+
1. User says "What currencies are supported?" → Call without parameters
|
|
2156
|
+
2. User wants to check BTC details → Use this tool to find BTC information
|
|
2157
|
+
3. User asks "Can I deposit ETH?" → Use this tool to check ETH deposit settings
|
|
2158
|
+
4. User wants withdrawal fees → Use this tool to see fees for each chain
|
|
2159
|
+
5. User asks "What chains support USDT?" → Use this tool to see USDT chain details
|
|
2160
|
+
|
|
2161
|
+
**Example request:**
|
|
2162
|
+
{}
|
|
2163
|
+
|
|
2164
|
+
**Example response:**
|
|
2165
|
+
Returns array of currency objects with details including:
|
|
2166
|
+
- currency: Currency code (e.g., "BTC")
|
|
2167
|
+
- name: Currency name
|
|
2168
|
+
- fullName: Full currency name (e.g., "Bitcoin")
|
|
2169
|
+
- precision: Decimal precision
|
|
2170
|
+
- type: Currency type (e.g., "crypto")
|
|
2171
|
+
- isDebitEnabled: Whether debit is enabled
|
|
2172
|
+
- chains: Array of supported blockchain chains with:
|
|
2173
|
+
- chainName: Name of the blockchain
|
|
2174
|
+
- withdrawalMinSize: Minimum withdrawal amount
|
|
2175
|
+
- depositMinSize: Minimum deposit amount
|
|
2176
|
+
- withdrawalFee: Fee for withdrawals
|
|
2177
|
+
- isWithdrawEnabled: Whether withdrawals are enabled
|
|
2178
|
+
- isDepositEnabled: Whether deposits are enabled
|
|
2179
|
+
- contractAddress: Contract address (for tokens)
|
|
2180
|
+
- withdrawPrecision: Withdrawal precision
|
|
2181
|
+
- maxWithdraw: Maximum withdrawal amount
|
|
2182
|
+
- maxDeposit: Maximum deposit amount
|
|
2183
|
+
- needTag: Whether tag/memo is required
|
|
2184
|
+
- chainId: Chain identifier
|
|
2185
|
+
- AddressRegex: Address validation regex pattern
|
|
2186
|
+
|
|
2187
|
+
**Rate Limits:**
|
|
2188
|
+
- Maximum 20 requests per second for public endpoints
|
|
2189
|
+
- Burst limit: 40 requests
|
|
2190
|
+
- Rate limit headers (X-RateLimit-*) are included in responses
|
|
2191
|
+
- This data changes infrequently, consider caching results
|
|
2192
|
+
|
|
2193
|
+
**Related Tools:**
|
|
2194
|
+
- Use zebpay_public_getExchangeInfo to see trading pairs and rules
|
|
2195
|
+
- Access currencies as a resource via zebpay://currencies`, {}, withLogging("zebpay_public_getCurrencies", config.logLevel, async () => {
|
|
2196
|
+
const correlationId = generateCorrelationId();
|
|
2197
|
+
const startTime = Date.now();
|
|
2198
|
+
try {
|
|
2199
|
+
const result = await publicClient.getCurrencies();
|
|
2200
|
+
const durationMs = Date.now() - startTime;
|
|
2201
|
+
metricsCollector.record("zebpay_public_getCurrencies", durationMs, true);
|
|
2202
|
+
return formatResponse(result, {
|
|
2203
|
+
toolName: "zebpay_public_getCurrencies",
|
|
2204
|
+
correlationId,
|
|
2205
|
+
executionTimeMs: durationMs,
|
|
2206
|
+
});
|
|
2207
|
+
}
|
|
2208
|
+
catch (error) {
|
|
2209
|
+
const durationMs = Date.now() - startTime;
|
|
2210
|
+
const errorType = error && typeof error === "object" && "code" in error ? String(error.code) : "unknown";
|
|
2211
|
+
metricsCollector.record("zebpay_public_getCurrencies", durationMs, false, errorType);
|
|
2212
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
2213
|
+
throw error;
|
|
2214
|
+
}
|
|
2215
|
+
throw createInternalError(`Failed to get currencies: ${error instanceof Error ? error.message : String(error)}`, {});
|
|
2216
|
+
}
|
|
2217
|
+
}));
|
|
2218
|
+
console.error("Registered tool: zebpay_public_getCurrencies");
|
|
2219
|
+
}
|
|
2220
|
+
catch (error) {
|
|
2221
|
+
console.error("Error registering public_getCurrencies:", error);
|
|
2222
|
+
}
|
|
2223
|
+
console.error("✓ Public-only tool registration complete.");
|
|
2224
|
+
}
|
|
2225
|
+
//# sourceMappingURL=tools_spot.js.map
|